Gerrit 2.11 backward compatibility support

Provide support for all Gerrit versions back to Ver. 2.11 with:
- Java 7 compatibility
- Both File and Path-based PluginPath implementations

Change-Id: I7824243d9439291e55c6c8390b78e43ad3ed9767
diff --git a/build.sbt b/build.sbt
index 715539a..5c2df1c 100644
--- a/build.sbt
+++ b/build.sbt
@@ -6,7 +6,9 @@
 
 scalaVersion := "2.11.8"
 
-val scalatraV = "2.5.+"
+val scalatraV = "2.4.+"
+
+resolvers += Resolver.mavenLocal
 
 libraryDependencies ++= Seq(
   // provided by gerrit
@@ -26,8 +28,14 @@
 
 assemblyJarName in assembly := s"$pluginName.jar"
 
+scalacOptions += "-target:jvm-1.7"
+
+javacOptions ++= Seq("-source", "1.7", "-target", "1.7")
+
 packageOptions in (Compile, packageBin) +=  {
   Package.ManifestAttributes(
     "Gerrit-ApiType" -> "plugin",
-    "Gerrit-PluginName" -> pluginName)
+    "Gerrit-PluginName" -> pluginName,
+    "Gerrit-HttpModule" -> "com.googlesource.gerrit.plugins.support.HttpModule"
+  )
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/support/annotations/PluginDataPath.java b/src/main/java/com/googlesource/gerrit/plugins/support/annotations/PluginDataPath.java
new file mode 100644
index 0000000..7530a12
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/support/annotations/PluginDataPath.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.googlesource.gerrit.plugins.support.annotations;
+
+import com.google.inject.BindingAnnotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Local path where a plugin can store its own private data.
+ * <p>
+ * A plugin or extension may receive this string by Guice injection to discover
+ * a path where it can store configuration or other data that is private.
+ * Differently from the Gerrit @PluginData annotation, this automatically
+ * convert any underlying @PluginData annotation to a Path, regardless of
+ * the version of Gerrit used.
+ */
+@Target({ElementType.PARAMETER, ElementType.FIELD})
+@Retention(RUNTIME)
+@BindingAnnotation
+public @interface PluginDataPath {
+}
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/GerritSupportServlet.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/GerritSupportServlet.scala
index be70f84..382c978 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/support/GerritSupportServlet.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/GerritSupportServlet.scala
@@ -29,7 +29,6 @@
 import scala.util.{Failure, Success}
 
 @Singleton
-@Export("/collect*")
 class GerritSupportServlet @Inject() (val processor: RequestProcessor,
                                       bundleFactory: SupportBundleFile,
                                       mimeDetector: ExtensionMimeDetector,
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/HttpModule.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/HttpModule.scala
new file mode 100644
index 0000000..92d0289
--- /dev/null
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/HttpModule.scala
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.googlesource.gerrit.plugins.support
+
+import java.nio.file.Path
+
+import com.google.inject.Scopes
+import com.google.inject.servlet.ServletModule
+import com.googlesource.gerrit.plugins.support.annotations.PluginDataPath
+
+class HttpModule extends ServletModule {
+
+  override def configureServlets() {
+    bind(classOf[Path]).annotatedWith(classOf[PluginDataPath])
+      .toProvider(classOf[PluginDataPathProvider])
+      .in(Scopes.SINGLETON)
+
+    serve("/collect*").`with`(classOf[GerritSupportServlet])
+  }
+}
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/PluginDataPathProvider.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/PluginDataPathProvider.scala
new file mode 100644
index 0000000..9f5375a
--- /dev/null
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/PluginDataPathProvider.scala
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.googlesource.gerrit.plugins.support
+
+import java.io.File
+import java.nio.file.Path
+
+import com.google.gerrit.extensions.annotations.PluginData
+import com.google.inject.{Inject, Injector, Key, Provider}
+
+import scala.util.Try
+
+class PluginDataPathProvider @Inject()(val injector: Injector) extends Provider[Path] {
+  override def get(): Path = Try {
+    injector.getInstance(Key.get(classOf[Path], classOf[PluginData]))
+  }.orElse {
+    Try {
+      injector.getInstance(Key.get(classOf[File], classOf[PluginData]))
+    }.map(_.toPath)
+  }.get
+}
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/RequestProcessor.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/RequestProcessor.scala
index 2278970..5277fc2 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/support/RequestProcessor.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/RequestProcessor.scala
@@ -14,21 +14,20 @@
 
 package com.googlesource.gerrit.plugins.support
 
-import com.google.gson.{Gson, JsonObject}
+import com.google.gson.{Gson, JsonElement, JsonObject}
 import com.google.inject.{Inject, Injector, Singleton}
 
 import scala.collection.JavaConverters._
 import scala.util.Try
 
 @Singleton
-class RequestProcessor @Inject()(injector: Injector,
+class RequestProcessor @Inject()(val zipped: SupportBundleBuilder,
                                  gson: Gson,
                                  commandFactory: GerritSupportCommandFactory) {
 
   def processRequest(body: String): Try[SupportBundleBuilder] = {
     Try {
-      val requestJson = gson.fromJson(body, classOf[JsonObject])
-      val zipped: SupportBundleBuilder = injector.getInstance(classOf[SupportBundleBuilder])
+      val requestJson = gson.fromJson(body, classOf[JsonElement]).getAsJsonObject
 
       try {
         requestJson
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/SupportBundle.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/SupportBundle.scala
index 89aea04..345acfd 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/support/SupportBundle.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/SupportBundle.scala
@@ -22,15 +22,15 @@
 import java.util.UUID
 import java.util.zip.{ZipEntry, ZipOutputStream}
 
-import com.google.gerrit.extensions.annotations.PluginData
 import com.google.gson.Gson
 import com.google.inject.Inject
+import com.googlesource.gerrit.plugins.support.annotations.PluginDataPath
 import org.joda.time.DateTime
 import org.joda.time.format.DateTimeFormat
 
 import scala.util.{Failure, Success, Try}
 
-class SupportBundleFile @Inject()(@PluginData val pluginData: Path) {
+class SupportBundleFile @Inject()(@PluginDataPath val pluginData: Path) {
 
   import SupportBundle._
 
@@ -47,7 +47,7 @@
   }
 }
 
-class SupportBundleBuilder @Inject()(@PluginData val directory: Path, gson: Gson) {
+class SupportBundleBuilder @Inject()(@PluginDataPath val directory: Path, gson: Gson) {
 
   import SupportBundle._