Merge pull request #87 from jbonofre/OPENJPA-2889

[OPENJPA-2889] Align commons-pool2 bundle version in Karaf features repository with the actual one
diff --git a/openjpa-persistence/pom.xml b/openjpa-persistence/pom.xml
index 684a26b..481d334 100644
--- a/openjpa-persistence/pom.xml
+++ b/openjpa-persistence/pom.xml
@@ -60,5 +60,10 @@
             <version>4.2.0</version>
             <scope>provided</scope>
         </dependency>
+        <!-- annotation javax.annotation.Generated -->
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
     </dependencies>
 </project>
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AnnotationProcessor6.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AnnotationProcessor6.java
index d9d521a..1087444 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AnnotationProcessor6.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AnnotationProcessor6.java
@@ -99,7 +99,8 @@
                     "openjpa.source",
                     "openjpa.naming",
                     "openjpa.header",
-                    "openjpa.metamodel"
+                    "openjpa.metamodel",
+                    "openjpa.addGeneratedAnnotation"
                   })
 
 public class AnnotationProcessor6 extends AbstractProcessor {
@@ -111,6 +112,9 @@
     private boolean active;
     private static Localizer _loc =  Localizer.forPackage(AnnotationProcessor6.class);
     private SourceVersion supportedSourceVersion;
+    private String addGeneratedOption;
+    private Class<?> generatedAnnotation;
+    private Date generationDate;
 
     /**
      * Category of members as per JPA 2.0 type system.
@@ -213,6 +217,8 @@
         setNamingPolicy();
         setHeader();
         handler = new SourceAnnotationHandler(processingEnv, logger);
+        setAddGeneratedAnnotation();
+        this.generationDate = new Date();
     }
 
     /**
@@ -311,10 +317,27 @@
         SourceCode.Class cls = source.getTopLevelClass();
         cls.addAnnotation(StaticMetamodel.class.getName())
             .addArgument("value", originalClass + ".class", false);
-        if (generatedSourceVersion >= 6) {
-            cls.addAnnotation(Generated.class.getName())
-            .addArgument("value", this.getClass().getName())
-            .addArgument("date", new Date().toString());
+
+        switch (this.addGeneratedOption) {
+            case "false":
+                return;
+
+            case "force":
+                cls.addAnnotation(javax.annotation.Generated.class.getName())
+                        .addArgument("value", this.getClass().getName())
+                        .addArgument("date", this.generationDate.toString());
+                break;
+
+            case "auto":
+                // fall through
+            default:
+                // only add the annotation if it is on the classpath for Java 6+.
+                if (generatedAnnotation != null && generatedSourceVersion >= 6) {
+                    cls.addAnnotation(generatedAnnotation.getName())
+                            .addArgument("value", this.getClass().getName())
+                            .addArgument("date", this.generationDate.toString());
+                }
+                break;
         }
     }
 
@@ -379,6 +402,21 @@
         }
     }
 
+    private void setAddGeneratedAnnotation() {
+        this.addGeneratedOption = getOptionValue("openjpa.addGeneratedAnnotation");
+
+        if (this.addGeneratedOption == null) {
+            this.addGeneratedOption = "auto";
+        }
+
+        // only add the annotation if it is on the classpath for Java 6+.
+        try {
+            this.generatedAnnotation = Class.forName("javax.annotation.Generated", false, null);
+        } catch (ClassNotFoundException generatedNotFoundEx) {
+            logger.trace(_loc.get("mmg-annotation-not-found"));
+        }
+    }
+
     /**
      * Creates a file where source code of the given metaClass will be written.
      *
diff --git a/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/meta/localizer.properties b/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/meta/localizer.properties
index 291cb37..9a597c3 100644
--- a/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/meta/localizer.properties
+++ b/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/meta/localizer.properties
@@ -36,6 +36,8 @@
 field-unrecognized: Field "{0}" is not recognized by its type code "{1}" to \
     be included in the meta model.
 getter-unmatched: Getter method "{0}" in "{1}" has no matching setter method.
+mmg-annotation-not-found: Annotation javax.annotation.Generated not found in \
+    the classpath. It will not be added to generated static metamodels.
 mmg-tool-banner: Starting OpenJPA Annotation Processor for Metamodel Generation
 mmg-process: Generating canonical metamodel source code "{0}"
 mmg-process-error: Error while generating metamodel for "{0}". See exception \
diff --git a/openjpa-project/src/doc/manual/jpa_overview_criteria.xml b/openjpa-project/src/doc/manual/jpa_overview_criteria.xml
index 98e09b7..d15a863 100644
--- a/openjpa-project/src/doc/manual/jpa_overview_criteria.xml
+++ b/openjpa-project/src/doc/manual/jpa_overview_criteria.xml
@@ -202,6 +202,16 @@
                By default, adds an OpenJPA proprietary text as comment block.
              </para>
         </listitem>
+        <listitem>
+            <para>
+                -Aopenjpa.addGeneratedAnnotation=auto|force|false : Configure whether the annotation
+                <code>javax.annotation.Generated</code> should be added to the generated metamodel classes.
+                This annotation is not available on Java 9 upwards unless the <code>javax.annotation-api</code>
+                is in the classpath.
+                The default is <code>auto</code>. Set to <code>force</code> to add the annotation even if it is
+                not in the classpath or to <code>false</code> to never add it to the generated class.
+            </para>
+        </listitem>
     </itemizedlist>
        </para>
     </section>
diff --git a/pom.xml b/pom.xml
index 5685d7d..d80484e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1795,6 +1795,12 @@
                 <version>2.2.1</version>
             </dependency>
             <dependency>
+                <groupId>javax.annotation</groupId>
+                <artifactId>javax.annotation-api</artifactId>
+                <version>1.3.2</version>
+                <scope>provided</scope>
+            </dependency>
+            <dependency>
                 <groupId>com.sun.xml.bind</groupId>
                 <artifactId>jaxb-impl</artifactId>
                 <version>2.2.1</version>