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 2eea489b6..96f41c9c4 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
@@ -2,10 +2,12 @@ package org.apache.openjpa.persistence.meta;
import static javax.lang.model.SourceVersion.RELEASE_6;
+import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
@@ -24,7 +26,11 @@ import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.persistence.metamodel.TypesafeMetamodel;
import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.persistence.util.SourceCode;
@@ -59,12 +65,12 @@ import org.apache.openjpa.persistence.util.SourceCode;
"javax.persistence.Entity",
"javax.persistence.Embeddable",
"javax.persistence.MappedSuperclass" })
-@SupportedOptions( { "log" })
+@SupportedOptions( { "log", "out" })
@SupportedSourceVersion(RELEASE_6)
public class AnnotationProcessor6 extends AbstractProcessor {
private SourceAnnotationHandler handler;
-
+ private CompileTimeLogger logger;
private static Localizer _loc =
Localizer.forPackage(AnnotationProcessor6.class);
private static final String UNDERSCORE = "_";
@@ -143,6 +149,7 @@ public class AnnotationProcessor6 extends AbstractProcessor {
super.init(processingEnv);
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
_loc.get("mmg-tool-banner").getMessage());
+ logger = new CompileTimeLogger(processingEnv);
handler = new SourceAnnotationHandler(processingEnv);
}
@@ -248,17 +255,21 @@ public class AnnotationProcessor6 extends AbstractProcessor {
private PrintWriter createSourceFile(String metaClass, TypeElement e)
throws IOException {
- Filer filer = processingEnv.getFiler();
- JavaFileObject javaFile = filer.createSourceFile(metaClass, e);
- log(_loc.get("mmg-process", javaFile.toUri()).getMessage());
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager mgr = compiler.getStandardFileManager(null,
+ null, null);
+ String srcOutput = processingEnv.getOptions().get("out");
+ if (srcOutput != null) {
+ mgr.setLocation(StandardLocation.SOURCE_OUTPUT,
+ Collections.singletonList(new File(srcOutput)));
+ }
+
+ JavaFileObject javaFile = mgr.getJavaFileForOutput(
+ StandardLocation.SOURCE_OUTPUT,
+ metaClass, JavaFileObject.Kind.SOURCE, null);
+ logger.info(_loc.get("mmg-process", javaFile.toUri()).getMessage());
OutputStream out = javaFile.openOutputStream();
PrintWriter writer = new PrintWriter(out);
return writer;
}
-
- private void log(String msg) {
- if (!processingEnv.getOptions().containsKey("log"))
- return;
- processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, msg);
- }
}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/CompileTimeLogger.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/CompileTimeLogger.java
new file mode 100644
index 000000000..ae59a744b
--- /dev/null
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/CompileTimeLogger.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.openjpa.persistence.meta;
+
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.tools.Diagnostic;
+
+/**
+ * Simple logger sets log level from javac compilers annotation processing
+ * options -Alog=TRACE|INFO|WARN|ERROR
and uses the processing
+ * environment to determine the log output stream.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class CompileTimeLogger {
+ private static enum Level {TRACE, INFO, WARN, ERROR};
+ private int logLevel;
+ private Messager messager;
+ public CompileTimeLogger(ProcessingEnvironment env) {
+ String level = env.getOptions().get("log");
+ if ("trace".equalsIgnoreCase(level))
+ logLevel = Level.TRACE.ordinal();
+ else if ("info".equalsIgnoreCase(level))
+ logLevel = Level.INFO.ordinal();
+ else if ("warn".equalsIgnoreCase(level))
+ logLevel = Level.WARN.ordinal();
+ else if ("error".equalsIgnoreCase(level))
+ logLevel = Level.ERROR.ordinal();
+ else {
+ logLevel = Level.INFO.ordinal();
+ warn("mmg-bad-log");
+ }
+ messager = env.getMessager();
+
+ }
+
+ public void info(String message) {
+ log(Level.INFO, message, Diagnostic.Kind.NOTE);
+ }
+
+ public void trace(String message) {
+ log(Level.TRACE, message, Diagnostic.Kind.NOTE);
+ }
+
+ public void warn(String message) {
+ log(Level.WARN, message, Diagnostic.Kind.MANDATORY_WARNING);
+ }
+
+ public void error(String message) {
+ log(Level.ERROR, message, Diagnostic.Kind.ERROR);
+ }
+
+ private void log(Level level, String message, Diagnostic.Kind kind) {
+ if (logLevel <= level.ordinal()) {
+ messager.printMessage(kind, message);
+ }
+ }
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/SourceAnnotationHandler.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/SourceAnnotationHandler.java
index 7fdea978a..711b70520 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/SourceAnnotationHandler.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/SourceAnnotationHandler.java
@@ -49,8 +49,8 @@ import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
-import javax.tools.Diagnostic;
import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.AccessCode;
import org.apache.openjpa.util.UserException;
/**
@@ -65,7 +65,7 @@ public class SourceAnnotationHandler
implements MetadataProcessor {
private final ProcessingEnvironment processingEnv;
-
+ private final CompileTimeLogger logger;
/**
* Set of Inclusion Filters based on member type, access type or transient
* annotations. Used to determine the subset of available field/method that
@@ -91,10 +91,16 @@ public class SourceAnnotationHandler
public SourceAnnotationHandler(ProcessingEnvironment processingEnv) {
super();
this.processingEnv = processingEnv;
+ this.logger = new CompileTimeLogger(processingEnv);
}
- public int determineTypeAccess(TypeElement t) {
- return 0;
+ public int determineTypeAccess(TypeElement type) {
+ AccessType access = getExplicitAccessType(type);
+ boolean isExplicit = access != null;
+ return isExplicit ? access == AccessType.FIELD
+ ? AccessCode.EXPLICIT | AccessCode.FIELD
+ : AccessCode.EXPLICIT | AccessCode.PROPERTY
+ : getImplicitAccessType(type);
}
public int determineMemberAccess(Element m) {
@@ -116,13 +122,13 @@ public class SourceAnnotationHandler
*/
public Set getPersistentMembers(TypeElement type) {
- AccessType access = getExplicitAccessType(type);
- boolean isExplicit = access != null;
-
- return isExplicit ? access == AccessType.FIELD
- ? getFieldAccessPersistentMembers(type)
- : getPropertyAccessPersistentMembers(type)
- : getDefaultAccessPersistentMembers(type);
+ int access = determineTypeAccess(type);
+ if (AccessCode.isExplicit(access)) {
+ return AccessCode.isField(access)
+ ? getFieldAccessPersistentMembers(type)
+ : getPropertyAccessPersistentMembers(type);
+ }
+ return getDefaultAccessPersistentMembers(type, access);
}
/**
@@ -159,8 +165,26 @@ public class SourceAnnotationHandler
fieldAccessFilter), getters);
}
- private Set getDefaultAccessPersistentMembers(TypeElement type) {
+ private Set getDefaultAccessPersistentMembers(TypeElement type,
+ int access) {
Set result = new HashSet();
+ List extends Element> allMembers = type.getEnclosedElements();
+ if (AccessCode.isField(access)) {
+ Set allFields = (Set)
+ filter(allMembers, fieldFilter, nonTransientFilter);
+ result.addAll(allFields);
+ } else {
+ Set allMethods = (Set)
+ filter(allMembers, methodFilter, nonTransientFilter);
+ Set getters = filter(allMethods, getterFilter);
+ Set setters = filter(allMethods, setterFilter);
+ getters = matchGetterAndSetter(getters, setters);
+ result.addAll(getters);
+ }
+ return result;
+ }
+
+ private int getImplicitAccessType(TypeElement type) {
List extends Element> allMembers = type.getEnclosedElements();
Set allFields = (Set)
filter(allMembers, fieldFilter, nonTransientFilter);
@@ -168,9 +192,9 @@ public class SourceAnnotationHandler
filter(allMembers, methodFilter, nonTransientFilter);
Set annotatedFields = filter(allFields,
- annotatedFilter);
+ annotatedFilter);
Set getters = filter(allMethods, getterFilter,
- annotatedFilter);
+ annotatedFilter);
Set setters = filter(allMethods, setterFilter);
getters = matchGetterAndSetter(getters, setters);
@@ -180,15 +204,16 @@ public class SourceAnnotationHandler
if (isFieldAccess && isPropertyAccess) {
throw new UserException(_loc.get("access-mixed", type,
toString(annotatedFields), toString(getters)));
- }
+ }
if (isFieldAccess) {
- result.addAll(annotatedFields);
+ return AccessCode.FIELD;
} else if (isPropertyAccess) {
- result.addAll(getters);
+ return AccessCode.PROPERTY;
} else {
- warn(_loc.get("access-none", type).toString());
+ TypeElement superType = getPersistentSupertype(type);
+ return (superType == null)
+ ? AccessCode.FIELD : determineTypeAccess(superType);
}
- return result;
}
Set merge(Set extends Element> a, Set extends Element> b) {
@@ -236,7 +261,7 @@ public class SourceAnnotationHandler
break;
}
if (!matched) {
- warn(_loc.get("getter-unmatched", getter,
+ logger.warn(_loc.get("getter-unmatched", getter,
getter.getEnclosingElement()).toString());
unmatched.add(getter);
}
@@ -424,16 +449,6 @@ public class SourceAnnotationHandler
.append(mirror.toString()).toString();
}
- private void log(String msg) {
- if (!processingEnv.getOptions().containsKey("log"))
- return;
- processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, msg);
- }
-
- private void warn(String msg) {
- processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, msg);
- }
-
String getPersistentMemberName(Element e) {
return isMethod(e) ? extractFieldName((ExecutableElement)e)
: e.getSimpleName().toString();