You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by mr...@apache.org on 2005/09/14 18:21:05 UTC
svn commit: r280879 [5/16] - in /struts/sandbox/trunk/ti: ./
jars/compiler-apt/ jars/compiler-apt/src/ jars/compiler-apt/src/java/
jars/compiler-apt/src/java/org/ jars/compiler-apt/src/java/org/apache/
jars/compiler-apt/src/java/org/apache/ti/ jars/com...
Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/AnnotationGrammar.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/AnnotationGrammar.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/AnnotationGrammar.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/AnnotationGrammar.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,414 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.compiler.internal;
+
+import org.apache.ti.compiler.internal.typesystem.declaration.AnnotationInstance;
+import org.apache.ti.compiler.internal.typesystem.declaration.AnnotationTypeElementDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.AnnotationValue;
+import org.apache.ti.compiler.internal.typesystem.declaration.Declaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.MemberDeclaration;
+import org.apache.ti.compiler.internal.typesystem.env.AnnotationProcessorEnvironment;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * Our base class for customizable annotation tag grammars. It has stock behavior for basic
+ * things like making sure required attributes exist, and provides plugin points for more
+ * complex checks.
+ */
+public abstract class AnnotationGrammar
+ implements JpfLanguageConstants {
+
+ /**
+ * If this tag requires a particular runtime version...
+ */
+ private String _requiredRuntimeVersion = null;
+ private RuntimeVersionChecker _runtimeVersionChecker;
+ private AnnotationProcessorEnvironment _env;
+ private Diagnostics _diagnostics;
+ private Map _memberGrammars = new HashMap();
+ private Map _memberArrayGrammars = new HashMap();
+ private Map _memberTypes = new HashMap();
+
+
+ /**
+ * @param requiredRuntimeVersion causes an error to be produced if the version in the manifest of beehive-netui-pageflow.jar
+ * is not high enough.
+ */
+ protected AnnotationGrammar(AnnotationProcessorEnvironment env, Diagnostics diags, String requiredRuntimeVersion,
+ RuntimeVersionChecker runtimeVersionChecker) {
+ _env = env;
+ _diagnostics = diags;
+ _runtimeVersionChecker = runtimeVersionChecker;
+ _requiredRuntimeVersion = requiredRuntimeVersion;
+ }
+
+ public final AnnotationProcessorEnvironment getEnv() {
+ return _env;
+ }
+
+ public Diagnostics getDiagnostics() {
+ return _diagnostics;
+ }
+
+ public final Object check(AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
+ MemberDeclaration classMember)
+ throws FatalCompileTimeException {
+ return check(annotation, parentAnnotations, classMember, -1);
+ }
+
+ public final Object check(AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
+ MemberDeclaration classMember, int annotationArrayIndex)
+ throws FatalCompileTimeException {
+ if (! beginCheck(annotation, parentAnnotations, classMember)) return null;
+
+ Map valuesPresent = annotation.getElementValues();
+ HashSet wasPresent = new HashSet();
+ HashMap checkResults = new HashMap();
+
+ if (parentAnnotations == null) parentAnnotations = new AnnotationInstance[0];
+ int oldLen = parentAnnotations.length;
+ AnnotationInstance[] parentsIncludingMe = new AnnotationInstance[oldLen + 1];
+ System.arraycopy(parentAnnotations, 0, parentsIncludingMe, 0, oldLen);
+ parentsIncludingMe[oldLen] = annotation;
+
+ for (Iterator ii = valuesPresent.entrySet().iterator(); ii.hasNext();) {
+ Map.Entry i = (Map.Entry) ii.next();
+ AnnotationTypeElementDeclaration decl = (AnnotationTypeElementDeclaration) i.getKey();
+ AnnotationValue value = (AnnotationValue) i.getValue();
+ String memberName = decl.getSimpleName();
+
+ wasPresent.add(memberName);
+ onCheckMember(decl, value, annotation, parentAnnotations, classMember);
+ Object grammarOrType = null;
+
+ if ((grammarOrType = _memberGrammars.get(memberName)) != null) {
+ AnnotationGrammar childGrammar = (AnnotationGrammar) grammarOrType;
+
+ if (childGrammar != null) // it will be non-null unless there are other, more basic, errors
+ {
+ Object result =
+ childGrammar.check((AnnotationInstance) value.getValue(), parentsIncludingMe, classMember);
+
+ if (result != null) {
+ checkResults.put(memberName, result);
+ }
+ }
+ } else if ((grammarOrType = _memberArrayGrammars.get(memberName)) != null) {
+ AnnotationGrammar arrayGrammar = (AnnotationGrammar) grammarOrType;
+
+ if (arrayGrammar != null) {
+ List annotations = CompilerUtils.getAnnotationArray(value);
+
+ for (int j = 0; j < annotations.size(); ++j) {
+ AnnotationInstance ann = (AnnotationInstance) annotations.get(j);
+ arrayGrammar.check(ann, parentsIncludingMe, classMember, j);
+ }
+ }
+ } else {
+ AnnotationMemberType memberType = (AnnotationMemberType) _memberTypes.get(memberName);
+
+ if (memberType != null) // it will be non-null unless there are other, more basic, errors
+ {
+ Object result =
+ memberType.check(decl, value, parentsIncludingMe, classMember, annotationArrayIndex);
+ if (result != null) checkResults.put(memberName, result);
+ }
+ }
+ }
+
+ return endCheck(annotation, parentAnnotations, classMember, wasPresent, checkResults);
+ }
+
+ public final boolean beginCheck(AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
+ MemberDeclaration classMember)
+ throws FatalCompileTimeException {
+ //
+ // First check to see if there's a required runtime version.
+ //
+ if (! _runtimeVersionChecker.checkRuntimeVersion(_requiredRuntimeVersion, annotation, _diagnostics,
+ "error.required-runtime-version-annotation", null)) {
+ return false;
+ }
+
+ return onBeginCheck(annotation, parentAnnotations, classMember); // for derived classes
+ }
+
+ protected void addError(Declaration element, String key) {
+ getDiagnostics().addError(element, key, null);
+ }
+
+ protected void addError(Declaration element, String key, Object[] args) {
+ getDiagnostics().addErrorArrayArgs(element, key, args);
+ }
+
+ protected void addError(Declaration element, String key, Object arg) {
+ getDiagnostics().addError(element, key, arg);
+ }
+
+ protected void addError(Declaration element, String key, Object arg1, Object arg2) {
+ getDiagnostics().addError(element, key, arg1, arg2);
+ }
+
+ protected void addError(Declaration element, String key, Object arg1, Object arg2, Object arg3) {
+ getDiagnostics().addError(element, key, arg1, arg2, arg3);
+ }
+
+ protected void addError(AnnotationValue element, String key) {
+ getDiagnostics().addError(element, key, null);
+ }
+
+ protected void addError(AnnotationValue element, String key, Object[] args) {
+ getDiagnostics().addErrorArrayArgs(element, key, args);
+ }
+
+ protected void addError(AnnotationValue element, String key, Object arg1) {
+ getDiagnostics().addError(element, key, arg1);
+ }
+
+ protected void addError(AnnotationValue element, String key, Object arg1, Object arg2) {
+ getDiagnostics().addError(element, key, arg1, arg2);
+ }
+
+ protected void addError(AnnotationValue element, String key, Object arg1, Object arg2, Object arg3) {
+ getDiagnostics().addError(element, key, arg1, arg2, arg3);
+ }
+
+ protected void addError(AnnotationInstance element, String key) {
+ getDiagnostics().addError(element, key, null);
+ }
+
+ protected void addError(AnnotationInstance element, String key, Object[] args) {
+ getDiagnostics().addErrorArrayArgs(element, key, args);
+ }
+
+ protected void addError(AnnotationInstance element, String key, Object arg1) {
+ getDiagnostics().addError(element, key, arg1);
+ }
+
+ protected void addError(AnnotationInstance element, String key, Object arg1, Object arg2) {
+ getDiagnostics().addError(element, key, arg1, arg2);
+ }
+
+ protected void addError(AnnotationInstance element, String key, Object arg1, Object arg2, Object arg3) {
+ getDiagnostics().addError(element, key, arg1, arg2, arg3);
+ }
+
+ protected void addWarning(Declaration element, String key) {
+ getDiagnostics().addWarning(element, key, null);
+ }
+
+ protected void addWarning(Declaration element, String key, Object[] args) {
+ getDiagnostics().addWarningArrayArgs(element, key, args);
+ }
+
+ protected void addWarning(Declaration element, String key, Object arg) {
+ getDiagnostics().addWarning(element, key, arg);
+ }
+
+ protected void addWarning(Declaration element, String key, Object arg1, Object arg2) {
+ getDiagnostics().addWarning(element, key, arg1, arg2);
+ }
+
+ protected void addWarning(Declaration element, String key, Object arg1, Object arg2, Object arg3) {
+ getDiagnostics().addWarning(element, key, arg1, arg2, arg3);
+ }
+
+ protected void addWarning(AnnotationValue element, String key) {
+ getDiagnostics().addWarning(element, key, null);
+ }
+
+ protected void addWarning(AnnotationValue element, String key, Object[] args) {
+ getDiagnostics().addWarningArrayArgs(element, key, args);
+ }
+
+ protected void addWarning(AnnotationValue element, String key, Object arg1) {
+ getDiagnostics().addWarning(element, key, arg1);
+ }
+
+ protected void addWarning(AnnotationValue element, String key, Object arg1, Object arg2) {
+ getDiagnostics().addWarning(element, key, arg1, arg2);
+ }
+
+ protected void addWarning(AnnotationValue element, String key, Object arg1, Object arg2, Object arg3) {
+ getDiagnostics().addWarning(element, key, arg1, arg2, arg3);
+ }
+
+ protected void addWarning(AnnotationInstance element, String key) {
+ getDiagnostics().addWarning(element, key, null);
+ }
+
+ protected void addWarning(AnnotationInstance element, String key, Object[] args) {
+ getDiagnostics().addWarningArrayArgs(element, key, args);
+ }
+
+ protected void addWarning(AnnotationInstance element, String key, Object arg1) {
+ getDiagnostics().addWarning(element, key, arg1);
+ }
+
+ protected void addWarning(AnnotationInstance element, String key, Object arg1, Object arg2) {
+ getDiagnostics().addWarning(element, key, arg1, arg2);
+ }
+
+ protected void addWarning(AnnotationInstance element, String key, Object arg1, Object arg2, Object arg3) {
+ getDiagnostics().addWarning(element, key, arg1, arg2, arg3);
+ }
+
+ /**
+ * @return a result (any Object) that will be passed back to the parent checker. May be null</code>.
+ */
+ public final Object endCheck(AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
+ MemberDeclaration classMember, Set wasPresent, Map checkResults) {
+ //
+ // Check mutually-exclusive attributes and child annotations.
+ //
+ String[][] mutuallyExclusiveAttrs = getMutuallyExclusiveAttrs();
+ for (int i = 0; mutuallyExclusiveAttrs != null && i < mutuallyExclusiveAttrs.length; ++i) {
+ String alreadyFound = null;
+
+ for (int j = 0; j < mutuallyExclusiveAttrs[i].length; ++j) {
+ String thisAttr = mutuallyExclusiveAttrs[i][j];
+
+ if (wasPresent.contains(thisAttr)) {
+ if (alreadyFound == null) {
+ alreadyFound = thisAttr;
+ } else {
+ String errorKey = "error.atmost-one-may-exist-" + mutuallyExclusiveAttrs[i].length;
+ getDiagnostics().addErrorArrayArgs(annotation, errorKey, mutuallyExclusiveAttrs[i]);
+ }
+ }
+ }
+ }
+
+ //
+ // Check required attributes and child annotations.
+ //
+ String[][] requiredAttrs = getRequiredAttrs();
+ for (int i = 0; requiredAttrs != null && i < requiredAttrs.length; ++i) {
+ boolean foundOne = false;
+
+ for (int j = 0; j < requiredAttrs[i].length; ++j) {
+ String thisAttr = requiredAttrs[i][j];
+
+ if (wasPresent.contains(thisAttr)) {
+ foundOne = true;
+ break;
+ }
+ }
+
+ if (! foundOne) {
+ String errorKey = "error.atleast-one-must-exist-" + requiredAttrs[i].length;
+ getDiagnostics().addErrorArrayArgs(annotation, errorKey, requiredAttrs[i]);
+ }
+ }
+
+ //
+ // Check inter-dependencies for attributes and child annotations.
+ //
+ String[][] attrDependencies = getAttrDependencies();
+ for (int i = 0; attrDependencies != null && i < attrDependencies.length; ++i) {
+ String thisAttr = attrDependencies[i][0];
+
+ if (wasPresent.contains(thisAttr)) {
+ boolean foundOne = false;
+
+ for (int j = 1; j < attrDependencies[i].length; ++j) {
+ if (wasPresent.contains(attrDependencies[i][j])) {
+ foundOne = true;
+ break;
+ }
+ }
+
+ if (! foundOne) {
+ String key = "error.attr-dependency-not-found-" + (attrDependencies[i].length - 1);
+ getDiagnostics().addErrorArrayArgs(annotation, key, attrDependencies[i]);
+ }
+ }
+ }
+
+ return onEndCheck(annotation, parentAnnotations, classMember, checkResults); // for derived classes
+ }
+
+ protected boolean onBeginCheck(AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
+ MemberDeclaration classMember)
+ throws FatalCompileTimeException {
+ return true;
+ }
+
+ /**
+ * @param checkResults map of member-name (String) -> result-from-checking (Object)
+ * @return a result (any Object) that will be passed back to the parent checker. May be null</code>.
+ */
+ protected Object onEndCheck(AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
+ MemberDeclaration classMember, Map checkResults) {
+ return null;
+ }
+
+ protected void onCheckMember(AnnotationTypeElementDeclaration memberDecl, AnnotationValue member,
+ AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
+ MemberDeclaration classMember) {
+ }
+
+ /**
+ * Each entry in this array (a String[]) lists mutually exclusive attributes.
+ */
+ public String[][] getMutuallyExclusiveAttrs() {
+ return null;
+ }
+
+ /**
+ * Each entry in this array (a String[]) lists attributes of which one must exist in this tag.
+ */
+ public String[][] getRequiredAttrs() {
+ return null;
+ }
+
+ /**
+ * Each entry in this array (a String[]) is an array whose first element is an attribute that
+ * requires at least one of the subsequent elements to exist as an attribute.
+ */
+ public String[][] getAttrDependencies() {
+ return null;
+ }
+
+ protected void addMemberGrammar(String memberName, AnnotationGrammar grammar) {
+ _memberGrammars.put(memberName, grammar);
+ }
+
+ protected void addMemberArrayGrammar(String memberName, AnnotationGrammar grammar) {
+ _memberArrayGrammars.put(memberName, grammar);
+ }
+
+ protected void addMemberType(String memberName, AnnotationMemberType type) {
+ _memberTypes.put(memberName, type);
+ }
+
+ public String getRequiredRuntimeVersion() {
+ return _requiredRuntimeVersion;
+ }
+
+ public RuntimeVersionChecker getRuntimeVersionChecker() {
+ return _runtimeVersionChecker;
+ }
+}
Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/AnnotationMemberType.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/AnnotationMemberType.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/AnnotationMemberType.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/AnnotationMemberType.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.compiler.internal;
+
+import org.apache.ti.compiler.internal.typesystem.declaration.AnnotationInstance;
+import org.apache.ti.compiler.internal.typesystem.declaration.AnnotationTypeElementDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.AnnotationValue;
+import org.apache.ti.compiler.internal.typesystem.declaration.Declaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.MemberDeclaration;
+import org.apache.ti.compiler.internal.typesystem.env.AnnotationProcessorEnvironment;
+
+
+public class AnnotationMemberType
+ implements JpfLanguageConstants {
+
+ /**
+ * set if this entire attribute type requires a particular runtime version.
+ */
+ private String _requiredRuntimeVersion = null;
+ private AnnotationGrammar _parentGrammar;
+ private AnnotationMemberType _nextInChain;
+
+
+ public AnnotationMemberType(String requiredRuntimeVersion, AnnotationGrammar parentGrammar) {
+ _requiredRuntimeVersion = requiredRuntimeVersion;
+ _parentGrammar = parentGrammar;
+ }
+
+ public AnnotationMemberType(String requiredRuntimeVersion, AnnotationGrammar parentGrammar,
+ AnnotationMemberType nextInChain) {
+ this(requiredRuntimeVersion, parentGrammar);
+ _nextInChain = nextInChain;
+ }
+
+ /**
+ * @return a result (any Object) that will be passed back to the parent checker. May be null</code>.
+ */
+ public final Object check(AnnotationTypeElementDeclaration valueDecl, AnnotationValue value,
+ AnnotationInstance[] parentAnnotations, MemberDeclaration classMember,
+ int annotationArrayIndex)
+ throws FatalCompileTimeException {
+ //
+ // First check to see if this attribute requires a particular runtime version.
+ //
+ String valueName = valueDecl.getSimpleName();
+ Diagnostics diags = _parentGrammar.getDiagnostics();
+ _parentGrammar.getRuntimeVersionChecker().checkRuntimeVersion(
+ _requiredRuntimeVersion, value, diags, "error.required-runtime-version-attribute", null);
+
+ // for derived classes
+ Object retVal = onCheck(valueDecl, value, parentAnnotations, classMember, annotationArrayIndex);
+ if (_nextInChain != null) {
+ return _nextInChain.check(valueDecl, value, parentAnnotations, classMember, annotationArrayIndex);
+ }
+ return retVal;
+ }
+
+ /**
+ * @return a result (any Object) that will be passed back to the parent checker. May be null</code>.
+ */
+ public Object onCheck(AnnotationTypeElementDeclaration valueDecl, AnnotationValue member,
+ AnnotationInstance[] parentAnnotations, MemberDeclaration classMember,
+ int annotationArrayIndex)
+ throws FatalCompileTimeException {
+ return null;
+ }
+
+ protected void addError(Declaration element, String key) {
+ _parentGrammar.addError(element, key, null);
+ }
+
+ protected void addError(Declaration element, String key, Object[] args) {
+ _parentGrammar.addError(element, key, args);
+ }
+
+ protected void addError(Declaration element, String key, Object arg) {
+ _parentGrammar.addError(element, key, new Object[]{arg});
+ }
+
+ protected void addError(Declaration element, String key, Object arg1, Object arg2) {
+ _parentGrammar.addError(element, key, new Object[]{arg1, arg2});
+ }
+
+ protected void addError(Declaration element, String key, Object arg1, Object arg2, Object arg3) {
+ _parentGrammar.addError(element, key, new Object[]{arg1, arg2, arg3});
+ }
+
+ protected void addError(AnnotationValue element, String key) {
+ _parentGrammar.addError(element, key, null);
+ }
+
+ protected void addError(AnnotationValue element, String key, Object[] args) {
+ _parentGrammar.addError(element, key, args);
+ }
+
+ protected void addError(AnnotationValue element, String key, Object arg1) {
+ _parentGrammar.addError(element, key, new Object[]{arg1});
+ }
+
+ protected void addError(AnnotationValue element, String key, Object arg1, Object arg2) {
+ _parentGrammar.addError(element, key, new Object[]{arg1, arg2});
+ }
+
+ protected void addError(AnnotationValue element, String key, Object arg1, Object arg2, Object arg3) {
+ _parentGrammar.addError(element, key, new Object[]{arg1, arg2, arg3});
+ }
+
+ protected void addError(AnnotationInstance element, String key) {
+ _parentGrammar.addError(element, key, null);
+ }
+
+ protected void addError(AnnotationInstance element, String key, Object[] args) {
+ _parentGrammar.addError(element, key, args);
+ }
+
+ protected void addError(AnnotationInstance element, String key, Object arg1) {
+ _parentGrammar.addError(element, key, new Object[]{arg1});
+ }
+
+ protected void addError(AnnotationInstance element, String key, Object arg1, Object arg2) {
+ _parentGrammar.addError(element, key, new Object[]{arg1, arg2});
+ }
+
+ protected void addError(AnnotationInstance element, String key, Object arg1, Object arg2, Object arg3) {
+ _parentGrammar.addError(element, key, new Object[]{arg1, arg2, arg3});
+ }
+
+ protected void addWarning(Declaration element, String key) {
+ _parentGrammar.addWarning(element, key, null);
+ }
+
+ protected void addWarning(Declaration element, String key, Object[] args) {
+ _parentGrammar.addWarning(element, key, args);
+ }
+
+ protected void addWarning(Declaration element, String key, Object arg) {
+ _parentGrammar.addWarning(element, key, new Object[]{arg});
+ }
+
+ protected void addWarning(Declaration element, String key, Object arg1, Object arg2) {
+ _parentGrammar.addWarning(element, key, new Object[]{arg1, arg2});
+ }
+
+ protected void addWarning(Declaration element, String key, Object arg1, Object arg2, Object arg3) {
+ _parentGrammar.addWarning(element, key, new Object[]{arg1, arg2, arg3});
+ }
+
+ protected void addWarning(AnnotationValue element, String key) {
+ _parentGrammar.addWarning(element, key, null);
+ }
+
+ protected void addWarning(AnnotationValue element, String key, Object[] args) {
+ _parentGrammar.addWarning(element, key, args);
+ }
+
+ protected void addWarning(AnnotationValue element, String key, Object arg1) {
+ _parentGrammar.addWarning(element, key, new Object[]{arg1});
+ }
+
+ protected void addWarning(AnnotationValue element, String key, Object arg1, Object arg2) {
+ _parentGrammar.addWarning(element, key, new Object[]{arg1, arg2});
+ }
+
+ protected void addWarning(AnnotationValue element, String key, Object arg1, Object arg2, Object arg3) {
+ _parentGrammar.addWarning(element, key, new Object[]{arg1, arg2, arg3});
+ }
+
+ protected void addWarning(AnnotationInstance element, String key) {
+ _parentGrammar.addWarning(element, key, null);
+ }
+
+ protected void addWarning(AnnotationInstance element, String key, Object[] args) {
+ _parentGrammar.addWarning(element, key, args);
+ }
+
+ protected void addWarning(AnnotationInstance element, String key, Object arg1) {
+ _parentGrammar.addWarning(element, key, new Object[]{arg1});
+ }
+
+ protected void addWarning(AnnotationInstance element, String key, Object arg1, Object arg2) {
+ _parentGrammar.addWarning(element, key, new Object[]{arg1, arg2});
+ }
+
+ protected void addWarning(AnnotationInstance element, String key, Object arg1, Object arg2, Object arg3) {
+ _parentGrammar.addWarning(element, key, new Object[]{arg1, arg2, arg3});
+ }
+
+ protected AnnotationGrammar getParentGrammar() {
+ return _parentGrammar;
+ }
+
+ protected final AnnotationProcessorEnvironment getEnv() {
+ return _parentGrammar.getEnv();
+ }
+
+ protected final Diagnostics getDiagnostics() {
+ return _parentGrammar.getDiagnostics();
+ }
+}
Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/AnnotationToXML.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/AnnotationToXML.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/AnnotationToXML.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/AnnotationToXML.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.compiler.internal;
+
+import org.apache.ti.compiler.internal.model.XWorkModuleConfigModel;
+import org.apache.ti.compiler.internal.typesystem.declaration.AnnotationInstance;
+import org.apache.ti.compiler.internal.typesystem.declaration.AnnotationTypeElementDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.AnnotationValue;
+import org.apache.ti.compiler.internal.typesystem.declaration.MemberDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.TypeDeclaration;
+import org.apache.ti.compiler.internal.typesystem.env.AnnotationProcessorEnvironment;
+import org.apache.ti.compiler.internal.typesystem.type.TypeInstance;
+import org.apache.ti.schema.annotations.AnnotatedElement;
+import org.apache.ti.schema.annotations.AnnotationAttribute;
+import org.apache.ti.schema.annotations.ProcessedAnnotation;
+import org.apache.ti.schema.annotations.ProcessedAnnotationsDocument;
+import org.apache.xmlbeans.XmlOptions;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class AnnotationToXML {
+
+ private static final String ANNOTATIONS_FILE_PREFIX = "annotations-";
+
+ private ProcessedAnnotationsDocument _doc;
+ private TypeDeclaration _typeDecl;
+
+ public AnnotationToXML(TypeDeclaration typeDecl) {
+ _doc = ProcessedAnnotationsDocument.Factory.newInstance();
+ _typeDecl = typeDecl;
+ ProcessedAnnotationsDocument.ProcessedAnnotations pa = _doc.addNewProcessedAnnotations();
+ pa.setTypeName(typeDecl.getQualifiedName());
+ }
+
+ public void include(MemberDeclaration memberDecl, AnnotationInstance annotation) {
+ AnnotatedElement element = _doc.getProcessedAnnotations().addNewAnnotatedElement();
+ String name = memberDecl instanceof TypeDeclaration
+ ? ((TypeDeclaration) memberDecl).getQualifiedName()
+ : memberDecl.getSimpleName();
+ element.setElementName(name);
+ ProcessedAnnotation xmlAnnotation = element.addNewAnnotation();
+ include(xmlAnnotation, annotation);
+ }
+
+ private void include(ProcessedAnnotation xmlAnnotation, AnnotationInstance annotation) {
+ xmlAnnotation.setAnnotationName(annotation.getAnnotationType().getAnnotationTypeDeclaration().getQualifiedName());
+
+ Map elementValues = annotation.getElementValues();
+
+ for (Iterator i = elementValues.entrySet().iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ AnnotationTypeElementDeclaration elementDecl = (AnnotationTypeElementDeclaration) entry.getKey();
+ AnnotationValue annotationValue = (AnnotationValue) entry.getValue();
+
+ String name = elementDecl.getSimpleName();
+ Object value = annotationValue.getValue();
+ AnnotationAttribute xmlAttr = xmlAnnotation.addNewAnnotationAttribute();
+ xmlAttr.setAttributeName(name);
+
+ if (value instanceof List) {
+ for (Iterator j = ((List) value).iterator(); j.hasNext();) {
+ Object o = j.next();
+ assert o instanceof AnnotationValue : o.getClass().getName();
+ Object listVal = ((AnnotationValue) o).getValue();
+
+ // we only handle lists of annotations at the moment
+ assert listVal instanceof AnnotationInstance : listVal.getClass().getName();
+ include(xmlAttr.addNewAnnotationValue(), (AnnotationInstance) listVal);
+ }
+ } else {
+ // we only support a few types at the moment
+ assert value instanceof TypeInstance || value instanceof String : value.getClass().getName();
+ xmlAttr.setStringValue1(value.toString());
+ }
+ }
+ }
+
+ public void writeXml(Diagnostics diagnostics, AnnotationProcessorEnvironment env) {
+ String typeName = _typeDecl.getQualifiedName();
+ int lastDot = typeName.lastIndexOf('.');
+ String baseName = ANNOTATIONS_FILE_PREFIX + typeName.substring(lastDot + 1);
+ String containingPackage = lastDot != -1 ? typeName.substring(0, lastDot) : null;
+ String outputFilePath = XWorkModuleConfigModel.getOutputFilePath(baseName, containingPackage);
+ File outputFile = new File(outputFilePath);
+
+ try {
+ XmlOptions options = new XmlOptions();
+ options.setSavePrettyPrint();
+ PrintWriter writer = env.getFiler().createTextFile(outputFile);
+ try {
+ _doc.save(writer, options);
+ }
+ finally {
+ writer.close();
+ }
+ }
+ catch (IOException e) {
+ diagnostics.addError(_typeDecl, "error.could-not-generate", outputFilePath, e.getMessage());
+ }
+ }
+}
Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/BaseChecker.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/BaseChecker.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/BaseChecker.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/BaseChecker.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.compiler.internal;
+
+import org.apache.ti.compiler.internal.typesystem.declaration.ClassDeclaration;
+import org.apache.ti.compiler.internal.typesystem.env.AnnotationProcessorEnvironment;
+
+import java.util.Map;
+
+public abstract class BaseChecker {
+
+ private AnnotationProcessorEnvironment _env;
+ private Diagnostics _diagnostics;
+ private RuntimeVersionChecker _runtimeVersionChecker;
+ private SourceFileInfo _sourceFileInfo;
+
+ protected BaseChecker(AnnotationProcessorEnvironment env, SourceFileInfo sourceFileInfo, Diagnostics diagnostics) {
+ _env = env;
+ _diagnostics = diagnostics;
+ _sourceFileInfo = sourceFileInfo;
+ }
+
+ public Map check(ClassDeclaration jclass)
+ throws FatalCompileTimeException {
+ setRuntimeVersionChecker(new RuntimeVersionChecker());
+ return onCheck(jclass);
+ }
+
+ public abstract Map onCheck(ClassDeclaration jclass)
+ throws FatalCompileTimeException;
+
+ protected AnnotationProcessorEnvironment getEnv() {
+ return _env;
+ }
+
+ protected Diagnostics getDiagnostics() {
+ return _diagnostics;
+ }
+
+ protected RuntimeVersionChecker getRuntimeVersionChecker() {
+ return _runtimeVersionChecker;
+ }
+
+ protected void setRuntimeVersionChecker(RuntimeVersionChecker runtimeVersionChecker) {
+ _runtimeVersionChecker = runtimeVersionChecker;
+ }
+
+ protected SourceFileInfo getSourceFileInfo() {
+ return _sourceFileInfo;
+ }
+}
Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/BaseGenerator.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/BaseGenerator.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/BaseGenerator.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/BaseGenerator.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.compiler.internal;
+
+import org.apache.ti.compiler.internal.typesystem.declaration.ClassDeclaration;
+import org.apache.ti.compiler.internal.typesystem.env.AnnotationProcessorEnvironment;
+
+public abstract class BaseGenerator {
+
+ private AnnotationProcessorEnvironment _env;
+ private Diagnostics _diagnostics;
+ private SourceFileInfo _sourceFileInfo;
+
+
+ protected BaseGenerator(AnnotationProcessorEnvironment env, SourceFileInfo sourceFileInfo, Diagnostics diagnostics) {
+ _env = env;
+ _diagnostics = diagnostics;
+ _sourceFileInfo = sourceFileInfo;
+ }
+
+ public abstract void generate(ClassDeclaration publicClass)
+ throws FatalCompileTimeException;
+
+ protected AnnotationProcessorEnvironment getEnv() {
+ return _env;
+ }
+
+ protected Diagnostics getDiagnostics() {
+ return _diagnostics;
+ }
+
+ protected SourceFileInfo getSourceFileInfo() {
+ return _sourceFileInfo;
+ }
+}
Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/CompilerUtils.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/CompilerUtils.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/CompilerUtils.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/CompilerUtils.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,1125 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.compiler.internal;
+
+import org.apache.ti.compiler.internal.typesystem.declaration.*;
+import org.apache.ti.compiler.internal.typesystem.env.AnnotationProcessorEnvironment;
+import org.apache.ti.compiler.internal.typesystem.env.Filer;
+import org.apache.ti.compiler.internal.typesystem.env.Messager;
+import org.apache.ti.compiler.internal.typesystem.type.ArrayType;
+import org.apache.ti.compiler.internal.typesystem.type.ClassType;
+import org.apache.ti.compiler.internal.typesystem.type.DeclaredType;
+import org.apache.ti.compiler.internal.typesystem.type.InterfaceType;
+import org.apache.ti.compiler.internal.typesystem.type.ReferenceType;
+import org.apache.ti.compiler.internal.typesystem.type.TypeInstance;
+import org.apache.ti.compiler.internal.typesystem.type.TypeVariable;
+import org.apache.ti.compiler.internal.typesystem.util.SourcePosition;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+public class CompilerUtils
+ implements JpfLanguageConstants {
+
+ private static final String ERROR_STRING = "<error>";
+ private static final TypeDeclaration ERROR_TYPE_DECLARATION = new ErrorTypeDeclaration();
+
+ public static boolean isJpfAnnotation(AnnotationInstance annotation, String unqualifiedName) {
+ String annotationName = getDeclaration(annotation.getAnnotationType()).getQualifiedName();
+ return annotationName.equals(ANNOTATION_QUALIFIER + unqualifiedName);
+ }
+
+ public static AnnotationInstance getAnnotation(ClassDeclaration decl, String unqualifiedName, boolean inherited) {
+ if (! inherited) return getAnnotation(decl, unqualifiedName);
+
+ do {
+ AnnotationInstance ann = getAnnotation(decl, unqualifiedName);
+ if (ann != null) return ann;
+ ClassType superType = decl.getSuperclass();
+ TypeDeclaration superTypeDecl = getDeclaration(superType);
+ decl = superTypeDecl instanceof ClassDeclaration ? (ClassDeclaration) superTypeDecl : null;
+ } while (decl != null);
+
+ return null;
+ }
+
+ public static AnnotationInstance getAnnotation(Declaration element, String unqualifiedName) {
+ return getAnnotationFullyQualified(element, ANNOTATION_QUALIFIER + unqualifiedName);
+ }
+
+ public static AnnotationInstance getAnnotationFullyQualified(Declaration element, String fullyQualifiedName) {
+ AnnotationInstance[] annotations = element.getAnnotationInstances();
+
+ for (int ii = 0; ii < annotations.length; ii++) {
+ AnnotationInstance i = annotations[ii];
+ String iName = getDeclaration(i.getAnnotationType()).getQualifiedName();
+ if (fullyQualifiedName.equals(iName)) return i;
+ }
+
+ return null;
+ }
+
+ public static AnnotationValue getAnnotationValue(Declaration element, String annotationName, String valueName) {
+ AnnotationInstance ann = getAnnotation(element, annotationName);
+ return ann != null ? getAnnotationValue(ann, valueName, true) : null;
+ }
+
+ /**
+ * If the given annotation exists, assert that the given member is not null</code>, and return it; otherwise,
+ * if the given annotation does not exist, return null</code>.
+ */
+ private static AnnotationValue assertAnnotationValue(Declaration element, String annotationName, String valueName,
+ boolean defaultIsNull) {
+ AnnotationInstance ann = getAnnotation(element, annotationName);
+
+ if (ann == null) {
+ return null;
+ } else {
+ return getAnnotationValue(ann, valueName, defaultIsNull);
+ }
+ }
+
+ public static String getStringValue(Declaration element, String annotationName, String memberName,
+ boolean defaultIsNull) {
+ return (String) getValue(element, annotationName, memberName, defaultIsNull);
+ }
+
+ public static AnnotationValue getAnnotationValue(AnnotationInstance annotation, String memberName,
+ boolean defaultIsNull) {
+ Map valuesPresent = annotation.getElementValues();
+
+ for (Iterator ii = valuesPresent.entrySet().iterator(); ii.hasNext();) {
+ Map.Entry i = (Map.Entry) ii.next();
+ if (memberName.equals(((AnnotationTypeElementDeclaration) i.getKey()).getSimpleName())) {
+ return (AnnotationValue) i.getValue();
+ }
+ }
+
+ //
+ // We didn't find it. If necessary, look for the default value.
+ //
+ if (defaultIsNull) return null;
+
+ AnnotationTypeDeclaration typeDecl = annotation.getAnnotationType().getAnnotationTypeDeclaration();
+ if (typeDecl == null) return null; // type declaration is null in the case of error type
+
+ AnnotationTypeElementDeclaration[] members = typeDecl.getAnnotationMembers();
+ for (int i = 0; i < members.length; i++) {
+ AnnotationTypeElementDeclaration member = members[i];
+ if (memberName.equals(member.getSimpleName())) return member.getDefaultValue();
+
+ }
+
+ assert false : "Member " + memberName + " not found on annotation type " + getQualifiedName(annotation);
+ return null;
+ }
+
+ public static List getStringArrayValue(Declaration element, String annotationName, String memberName,
+ boolean defaultIsNull) {
+ AnnotationValue value = assertAnnotationValue(element, annotationName, memberName, defaultIsNull);
+ if (value == null) return null;
+ ArrayList ret = new ArrayList();
+ getValues(value, ret, false);
+ return ret;
+ }
+
+ public static Boolean getBooleanValue(Declaration element, String annotationName, String memberName,
+ boolean defaultIsNull) {
+ AnnotationValue value = assertAnnotationValue(element, annotationName, memberName, defaultIsNull);
+ return value != null ? (Boolean) value.getValue() : null;
+ }
+
+ public static String getString(AnnotationInstance annotation, String memberName, boolean defaultIsNull) {
+ AnnotationValue value = getAnnotationValue(annotation, memberName, defaultIsNull);
+ return value != null ? (String) value.getValue() : (defaultIsNull ? null : "");
+ }
+
+ public static TypeInstance getTypeInstance(AnnotationInstance annotation, String memberName, boolean defaultIsNull) {
+ AnnotationValue value = getAnnotationValue(annotation, memberName, defaultIsNull);
+ if (value == null) return null;
+ Object typeInstance = value.getValue();
+ if (isErrorString(typeInstance)) return new ErrorTypeInstance();
+ return (TypeInstance) typeInstance;
+ }
+
+ public static String getEnumFieldName(AnnotationInstance annotation, String memberName, boolean defaultIsNull) {
+ AnnotationValue value = getAnnotationValue(annotation, memberName, defaultIsNull);
+ return value != null ? getEnumFieldName(value) : null;
+ }
+
+ public static List getStringArray(AnnotationInstance annotation, String memberName, boolean defaultIsNull) {
+ AnnotationValue value = getAnnotationValue(annotation, memberName, defaultIsNull);
+ if (value == null) return null;
+ ArrayList ret = new ArrayList();
+ getValues(value, ret, false);
+ return ret;
+ }
+
+ public static DeclaredType getDeclaredType(AnnotationInstance annotation, String memberName, boolean defaultIsNull) {
+ return (DeclaredType) getReferenceType(annotation, memberName, defaultIsNull);
+ }
+
+ public static ReferenceType getReferenceType(AnnotationInstance annotation, String memberName, boolean defaultIsNull) {
+ AnnotationValue value = getAnnotationValue(annotation, memberName, defaultIsNull);
+
+ // If the type is the string "<error>", it means that there is already an error related to the type itself.
+ if (value != null && isErrorString(value.getValue())) return null;
+
+ return value != null ? (ReferenceType) value.getValue() : null;
+ }
+
+ public static Integer getInteger(AnnotationInstance annotation, String memberName, boolean defaultIsNull) {
+ AnnotationValue value = getAnnotationValue(annotation, memberName, defaultIsNull);
+ if (value == null) return defaultIsNull ? null : new Integer(0);
+ Object result = value.getValue();
+
+ if (result instanceof String) {
+ assert isErrorString(result) : result;
+ return new Integer(0);
+ }
+
+ return (Integer) value.getValue();
+ }
+
+ public static boolean isErrorString(Object str) {
+ return ERROR_STRING.equals(str);
+ }
+
+ public static Long getLong(AnnotationInstance annotation, String memberName, boolean defaultIsNull) {
+ AnnotationValue value = getAnnotationValue(annotation, memberName, defaultIsNull);
+ if (value == null) return defaultIsNull ? null : new Long(0);
+ Object result = value.getValue();
+
+ if (result instanceof String) {
+ assert result.equals(ERROR_STRING) : result;
+ return new Long(0);
+ }
+
+ return (Long) value.getValue();
+ }
+
+ public static Float getFloat(AnnotationInstance annotation, String memberName, boolean defaultIsNull) {
+ AnnotationValue value = getAnnotationValue(annotation, memberName, defaultIsNull);
+ if (value == null) return defaultIsNull ? null : new Float(0);
+ Object result = value.getValue();
+
+ if (result instanceof String) {
+ assert result.equals(ERROR_STRING) : result;
+ return new Float(0);
+ }
+
+ return (Float) value.getValue();
+ }
+
+ public static Double getDouble(AnnotationInstance annotation, String memberName, boolean defaultIsNull) {
+ AnnotationValue value = getAnnotationValue(annotation, memberName, defaultIsNull);
+ if (value == null) return defaultIsNull ? null : new Double(0);
+ Object result = value.getValue();
+
+ if (result instanceof String) {
+ assert result.equals(ERROR_STRING) : result;
+ return new Double(0);
+ }
+
+ return (Double) value.getValue();
+ }
+
+ public static Boolean getBoolean(AnnotationInstance annotation, String memberName, boolean defaultIsNull) {
+ AnnotationValue value = getAnnotationValue(annotation, memberName, defaultIsNull);
+ if (value == null) return defaultIsNull ? null : Boolean.FALSE;
+ Object result = value.getValue();
+
+ if (result instanceof String) {
+ assert result.equals(ERROR_STRING) : result;
+ return Boolean.FALSE;
+ }
+
+ return (Boolean) value.getValue();
+ }
+
+ public static Object getValue(Declaration element, String annotationName, String memberName, boolean defaultIsNull) {
+ AnnotationValue value = assertAnnotationValue(element, annotationName, memberName, defaultIsNull);
+ return value != null ? value.getValue() : null;
+ }
+
+ public static List getAnnotationArrayValue(Declaration element, String annotationName,
+ String memberName, boolean defaultIsNull) {
+ AnnotationValue value = assertAnnotationValue(element, annotationName, memberName, defaultIsNull);
+ if (value == null) return null;
+ ArrayList ret = new ArrayList();
+ getValues(value, ret, true);
+ return ret;
+ }
+
+ public static List getAnnotationArray(AnnotationInstance annotation, String memberName,
+ boolean defaultIsNull) {
+ AnnotationValue value = getAnnotationValue(annotation, memberName, defaultIsNull);
+ return getAnnotationArray(value);
+ }
+
+ public static List getAnnotationArray(AnnotationValue value) {
+ if (value == null) return null;
+ ArrayList ret = new ArrayList();
+ getValues(value, ret, true);
+ return ret;
+ }
+
+ private static void getValues(AnnotationValue arrayValue, List translatedValues, boolean weedOutErrorType) {
+ List values = (List) arrayValue.getValue();
+ for (Iterator ii = values.iterator(); ii.hasNext();) {
+ Object i = ii.next();
+ Object value = i instanceof AnnotationValue ? ((AnnotationValue) i).getValue() : i;
+ if (! weedOutErrorType || ! isErrorString(value)) translatedValues.add(value);
+ }
+ }
+
+ public static String getQualifiedName(AnnotationInstance annotation) {
+ return getDeclaration(annotation.getAnnotationType()).getQualifiedName();
+ }
+
+ public static String getSimpleName(AnnotationInstance annotation) {
+ return getDeclaration(annotation.getAnnotationType()).getSimpleName();
+ }
+
+ public static AnnotationInstance getAnnotation(AnnotationInstance annotation, String memberName, boolean defaultIsNull) {
+ AnnotationValue value = getAnnotationValue(annotation, memberName, defaultIsNull);
+ return value != null ? (AnnotationInstance) value.getValue() : null;
+ }
+
+ public static MethodDeclaration getClassMethod(TypeDeclaration jclass, String methodName, String desiredAnnotation) {
+ return getClassMethod(jclass, methodName, desiredAnnotation, false);
+ }
+
+ private static MethodDeclaration getClassMethod(TypeDeclaration type, String methodName, String desiredAnnotation,
+ boolean onlyPublicOrProtected) {
+ if (! (type instanceof ClassDeclaration)) return null;
+
+ ClassDeclaration jclass = (ClassDeclaration) type;
+ MethodDeclaration[] methods = jclass.getMethods();
+
+ for (int i = 0; i < methods.length; i++) {
+ MethodDeclaration method = methods[i];
+ if (! onlyPublicOrProtected || method.hasModifier(Modifier.PROTECTED)
+ || method.hasModifier(Modifier.PUBLIC)) {
+ if (methodName.equals(method.getSimpleName())
+ && (desiredAnnotation == null || getAnnotation(method, desiredAnnotation) != null)) {
+ return method;
+ }
+ }
+ }
+
+ ClassType superclass = jclass.getSuperclass();
+
+ if (superclass != null) {
+ return getClassMethod(getDeclaration(superclass), methodName, desiredAnnotation, true);
+ }
+
+ return null;
+ }
+
+ public static FieldDeclaration getClassField(TypeDeclaration jclass, String fieldName, String desiredAnnotation) {
+ return getClassField(jclass, fieldName, desiredAnnotation, false);
+ }
+
+ private static FieldDeclaration getClassField(TypeDeclaration type, String fieldName, String desiredAnnotation,
+ boolean onlyPublicOrProtected) {
+ if (! (type instanceof ClassDeclaration)) return null;
+
+ ClassDeclaration jclass = (ClassDeclaration) type;
+ FieldDeclaration[] fields = jclass.getFields();
+
+ for (int i = 0; i < fields.length; i++) {
+ FieldDeclaration field = fields[i];
+ if (! onlyPublicOrProtected || field.hasModifier(Modifier.PROTECTED)
+ || field.hasModifier(Modifier.PUBLIC)) {
+ if (fieldName.equals(field.getSimpleName())
+ && (desiredAnnotation == null || getAnnotation(field, desiredAnnotation) != null)) {
+ return field;
+ }
+ }
+ }
+
+ ClassType superclass = jclass.getSuperclass();
+
+ if (superclass != null) {
+ return getClassField(getDeclaration(superclass), fieldName, desiredAnnotation, true);
+ }
+
+ return null;
+ }
+
+ public static MethodDeclaration[] getClassMethods(TypeDeclaration jclass, String desiredAnnotation) {
+ Collection results = new ArrayList();
+ getClassMethods(jclass, desiredAnnotation, false, results);
+ return (MethodDeclaration[]) results.toArray(new MethodDeclaration[ results.size() ]);
+ }
+
+ private static void getClassMethods(TypeDeclaration type, String desiredAnnotation, boolean onlyPublicOrPrivate,
+ Collection results) {
+ if (! (type instanceof ClassDeclaration)) return;
+
+ ClassDeclaration jclass = (ClassDeclaration) type;
+ MethodDeclaration[] methods = jclass.getMethods();
+
+ for (int i = 0; i < methods.length; i++) {
+ MethodDeclaration method = methods[i];
+
+ if (! onlyPublicOrPrivate || method.hasModifier(Modifier.PROTECTED)
+ || method.hasModifier(Modifier.PUBLIC)) {
+ if (desiredAnnotation == null || getAnnotation(method, desiredAnnotation) != null) {
+ boolean isDuplicate = false;
+
+ //
+ // Make sure we're not adding a duplicate method -- one that was already overridden.
+ //
+ if (onlyPublicOrPrivate) {
+ ParameterDeclaration[] methodParams = method.getParameters();
+
+ for (Iterator j = results.iterator(); j.hasNext();) {
+ MethodDeclaration existingMethod = (MethodDeclaration) j.next();
+
+ if (existingMethod.getSimpleName().equals(method.getSimpleName())) {
+ ParameterDeclaration[] existingMethodParams = existingMethod.getParameters();
+
+ if (existingMethodParams.length == methodParams.length) {
+ isDuplicate = true;
+
+ for (int k = 0; k < existingMethodParams.length; ++k) {
+ ParameterDeclaration existingMethodParam = existingMethodParams[k];
+ ParameterDeclaration methodParam = methodParams[k];
+
+ if (! existingMethodParam.getType().equals(methodParam.getType())) {
+ isDuplicate = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (! isDuplicate) results.add(method);
+ }
+ }
+ }
+
+ ClassType superclass = jclass.getSuperclass();
+
+ if (superclass != null && ! getDeclaration(superclass).getQualifiedName().startsWith("java.lang.")) {
+ getClassMethods(getDeclaration(superclass), desiredAnnotation, true, results);
+ }
+ }
+
+ public static Collection getClassFields(TypeDeclaration jclass) {
+ Collection results = new ArrayList();
+ getClassFields(jclass, false, results);
+ return results;
+ }
+
+ private static void getClassFields(TypeDeclaration type, boolean onlyPublicOrPrivate,
+ Collection results) {
+ if (! (type instanceof ClassDeclaration)) return;
+
+ ClassDeclaration jclass = (ClassDeclaration) type;
+ FieldDeclaration[] fields = jclass.getFields();
+
+ for (int i = 0; i < fields.length; i++) {
+ FieldDeclaration field = fields[i];
+ if (! onlyPublicOrPrivate || field.hasModifier(Modifier.PROTECTED) || field.hasModifier(Modifier.PUBLIC)) {
+ results.add(field);
+ }
+ }
+
+ ClassType superclass = jclass.getSuperclass();
+ if (superclass != null) getClassFields(getDeclaration(superclass), true, results);
+ }
+
+ public static Collection getClassNestedTypes(TypeDeclaration jclass) {
+ Collection results = new ArrayList();
+ getClassNestedTypes(jclass, false, results);
+ return results;
+ }
+
+ private static void getClassNestedTypes(TypeDeclaration type, boolean onlyPublicOrPrivate,
+ Collection results) {
+ if (! (type instanceof ClassDeclaration)) return;
+
+ ClassDeclaration jclass = (ClassDeclaration) type;
+ TypeDeclaration[] nestedTypes = jclass.getNestedTypes();
+
+ for (int i = 0; i < nestedTypes.length; i++) {
+ TypeDeclaration nestedType = nestedTypes[i];
+ if (! onlyPublicOrPrivate || nestedType.hasModifier(Modifier.PROTECTED)
+ || nestedType.hasModifier(Modifier.PUBLIC)) {
+ results.add(nestedType);
+ }
+ }
+
+ ClassType superclass = jclass.getSuperclass();
+ if (superclass != null) getClassNestedTypes(getDeclaration(superclass), true, results);
+ }
+
+ /**
+ * Get a Class.forName-able string for the given type signature.
+ *
+ * @todo make this pluggable
+ */
+ public static String getFormClassName(TypeDeclaration jclass, AnnotationProcessorEnvironment env) {
+ if (isAssignableFrom(APACHE_XMLOBJECT_CLASS_NAME, jclass, env)) {
+ return XML_FORM_CLASS_NAME;
+ } else {
+ return getLoadableName(jclass);
+ }
+ }
+
+ public static String getFormClassName(DeclaredType jclass, AnnotationProcessorEnvironment env) {
+ return getFormClassName(getDeclaration(jclass), env);
+ }
+
+ public static boolean isAbsoluteURL(String path) {
+ try {
+ return new URI(path).getScheme() != null;
+ }
+ catch (URISyntaxException e) {
+ return false;
+ }
+ }
+
+ public static boolean isAssignableFrom(String className, TypeInstance type, AnnotationProcessorEnvironment env) {
+ if (! (type instanceof DeclaredType)) return false;
+ return isAssignableFrom(className, getDeclaration((DeclaredType) type), env);
+ }
+
+ public static boolean isAssignableFrom(TypeDeclaration base, TypeDeclaration typeDecl) {
+ if (base != null && typeDecl != null) {
+ if (typesAreEqual(typeDecl, base)) return true;
+
+ if (typeDecl instanceof ClassDeclaration) {
+ ClassType superclass = ((ClassDeclaration) typeDecl).getSuperclass();
+ if (superclass != null && isAssignableFrom(base, getDeclaration(superclass))) return true;
+ }
+
+ InterfaceType[] superInterfaces = typeDecl.getSuperinterfaces();
+ for (int i = 0; i < superInterfaces.length; i++) {
+ InterfaceType superInterface = superInterfaces[i];
+ if (isAssignableFrom(base, getDeclaration(superInterface))) return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static boolean isAssignableFrom(TypeInstance base, TypeDeclaration cl) {
+ if (! (base instanceof DeclaredType)) return false;
+ return isAssignableFrom(getDeclaration((DeclaredType) base), cl);
+ }
+
+ public static boolean isAssignableFrom(TypeDeclaration base, TypeInstance cl) {
+ if (! (cl instanceof DeclaredType)) return false;
+ return isAssignableFrom(base, getDeclaration((DeclaredType) cl));
+ }
+
+ public static boolean isAssignableFrom(String className, TypeDeclaration cl, AnnotationProcessorEnvironment env) {
+ TypeDeclaration base = env.getTypeDeclaration(className);
+ return isAssignableFrom(base, cl);
+ }
+
+ public static boolean isOfClass(TypeInstance type, String className, AnnotationProcessorEnvironment env) {
+ if (! (type instanceof DeclaredType)) return false;
+ return typesAreEqual(getDeclaration((DeclaredType) type), env.getTypeDeclaration(className));
+ }
+
+ public static boolean typesAreEqual(TypeDeclaration t1, TypeDeclaration t2) {
+ assert t1 != null;
+ if (t2 == null) return false;
+ return t1.getQualifiedName().equals(t2.getQualifiedName());
+ }
+
+ public static TypeDeclaration getOuterClass(MemberDeclaration classMember) {
+ return classMember instanceof ClassDeclaration
+ ? (ClassDeclaration) classMember
+ : classMember.getDeclaringType();
+ }
+
+ public static TypeDeclaration getOutermostClass(MemberDeclaration classMember) {
+ TypeDeclaration containingClass;
+ while ((containingClass = classMember.getDeclaringType()) != null) {
+ classMember = containingClass;
+ }
+
+ assert classMember instanceof ClassDeclaration : classMember.getClass().getName();
+ return (ClassDeclaration) classMember;
+ }
+
+ public static boolean hasDefaultConstructor(TypeDeclaration jclass) {
+ if (! (jclass instanceof ClassDeclaration)) return false;
+
+ ConstructorDeclaration[] constructors = ((ClassDeclaration) jclass).getConstructors();
+
+ for (int i = 0; i < constructors.length; i++) {
+ ConstructorDeclaration ctor = constructors[i];
+ if (ctor.getParameters().length == 0) return true;
+ }
+
+ return false;
+ }
+
+ private static Declaration findElement(Collection elements, String elementName) {
+ for (Iterator ii = elements.iterator(); ii.hasNext();) {
+ Object element = ii.next();
+ Declaration decl = (Declaration) element;
+ if (decl.getSimpleName().equals(elementName)) return decl;
+ }
+
+ return null;
+ }
+
+ public static FieldDeclaration findField(TypeDeclaration jclass, String fieldName) {
+ return (FieldDeclaration) findElement(getClassFields(jclass), fieldName);
+ }
+
+ public static ClassDeclaration findInnerClass(TypeDeclaration jclass, String innerClassName) {
+ return (ClassDeclaration) findElement(getClassNestedTypes(jclass), innerClassName);
+ }
+
+ public static String getEnumFieldName(AnnotationValue enumMember) {
+ if (enumMember == null || enumMember.getValue() == null)
+ return "";
+ else
+ return enumMember.getValue().toString();
+ }
+
+ /**
+ * Get the qualified name of the given class, with '$' used to separate inner classes; the returned string can be
+ * used with Class.forName().
+ */
+ public static String getLoadableName(TypeDeclaration jclass) {
+ TypeDeclaration containingClass = jclass.getDeclaringType();
+
+ if (containingClass == null) {
+ return jclass.getQualifiedName();
+ } else {
+ return getLoadableName(containingClass) + '$' + jclass.getSimpleName();
+ }
+ }
+
+ public static String getLoadableName(DeclaredType jclass) {
+ return getLoadableName(getDeclaration(jclass));
+ }
+
+ public static File getSourceFile(TypeDeclaration decl, boolean mustBeNonNull) {
+ decl = getOutermostClass(decl);
+ SourcePosition position = decl.getPosition();
+ if (mustBeNonNull) assert position != null : "no source file for " + decl.toString();
+ return position != null ? position.file() : null;
+ }
+
+ public static class ExtendedAnnotationProcessorEnvironment
+ implements AnnotationProcessorEnvironment {
+
+ private AnnotationProcessorEnvironment _env;
+ private boolean _useEqualsToCompareAnnotations;
+ private HashMap _attributes;
+
+ public ExtendedAnnotationProcessorEnvironment(AnnotationProcessorEnvironment env,
+ boolean useEqualsToCompareAnnotations) {
+ _env = env;
+ _useEqualsToCompareAnnotations = useEqualsToCompareAnnotations;
+ }
+
+ public boolean useEqualsToCompareAnnotations() {
+ return _useEqualsToCompareAnnotations;
+ }
+
+ public Map getOptions() {
+ return _env.getOptions();
+ }
+
+ public Messager getMessager() {
+ return _env.getMessager();
+ }
+
+ public Filer getFiler() {
+ return _env.getFiler();
+ }
+
+ public TypeDeclaration[] getSpecifiedTypeDeclarations() {
+ return _env.getSpecifiedTypeDeclarations();
+ }
+
+ public TypeDeclaration getTypeDeclaration(String s) {
+ return _env.getTypeDeclaration(s);
+ }
+
+ public Declaration[] getDeclarationsAnnotatedWith(AnnotationTypeDeclaration annotationTypeDeclaration) {
+ return _env.getDeclarationsAnnotatedWith(annotationTypeDeclaration);
+ }
+
+ public void setAttribute(String propertyName, Object value) {
+ if (_attributes == null) _attributes = new HashMap();
+ _attributes.put(propertyName, value);
+ }
+
+ public Object getAttribute(String propertyName) {
+ return _attributes != null ? _attributes.get(propertyName) : null;
+ }
+ }
+
+ public static boolean annotationsAreEqual(AnnotationInstance a1, AnnotationInstance a2, boolean allowExactDuplicates,
+ AnnotationProcessorEnvironment env) {
+ assert a1 != null;
+ if (a2 == null) return false;
+
+ //
+ // TODO: This entire method is a workaround for a bug in APT where an annotation may not equal itelf.
+ // If this behavior changes, we want to rely on equals(), not this deep comparison, which is more expensive
+ // and wrong if the two annotations 'look' exactly the same.
+ //
+ if (! allowExactDuplicates
+ && env instanceof ExtendedAnnotationProcessorEnvironment
+ && ((ExtendedAnnotationProcessorEnvironment) env).useEqualsToCompareAnnotations()) {
+ return a1.equals(a2);
+ }
+
+ Map vals1 = a1.getElementValues();
+ Map vals2 = a2.getElementValues();
+
+ if (vals1.size() != vals2.size()) return false;
+
+
+ Iterator ents1 = vals1.entrySet().iterator();
+ Iterator ents2 = vals2.entrySet().iterator();
+ while (ents1.hasNext()) {
+ Map.Entry entry1 = (Map.Entry) ents1.next();
+ Map.Entry entry2 = (Map.Entry) ents2.next();
+
+ if (! ((AnnotationTypeElementDeclaration) entry1.getKey()).getSimpleName().equals(((AnnotationTypeElementDeclaration) entry2.getKey()).getSimpleName())) return false;
+ Object val1 = ((AnnotationValue) entry1.getValue()).getValue();
+ Object val2 = ((AnnotationValue) entry2.getValue()).getValue();
+
+ if (val1 instanceof Collection) {
+ if (! (val2 instanceof Collection)) return false;
+ Collection list1 = (Collection) val1;
+ Collection list2 = (Collection) val2;
+ if (list1.size() != list2.size()) return false;
+ Iterator j1 = list1.iterator();
+ Iterator j2 = list2.iterator();
+
+ while (j1.hasNext()) {
+ Object o1 = ((AnnotationValue) j1.next()).getValue();
+ Object o2 = ((AnnotationValue) j2.next()).getValue();
+
+ if (o1 instanceof AnnotationInstance) {
+ if (! (o2 instanceof AnnotationInstance)) return false;
+ if (! annotationsAreEqual((AnnotationInstance) o1, (AnnotationInstance) o2, allowExactDuplicates, env)) return false;
+ } else {
+ if (! o1.equals(o2)) return false;
+ }
+ }
+ } else if (val1 instanceof AnnotationInstance) {
+ if (! (val2 instanceof AnnotationInstance)) return false;
+ if (! annotationsAreEqual((AnnotationInstance) val1, (AnnotationInstance) val2, allowExactDuplicates, env)) return false;
+ } else if (! val1.equals(val2)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static class BeanPropertyDescriptor {
+
+ private String _propertyName;
+ private String _type;
+
+ public BeanPropertyDescriptor(String propertyName, String type) {
+ _propertyName = propertyName;
+ _type = type;
+ }
+
+ public String getPropertyName() {
+ return _propertyName;
+ }
+
+ public String getType() {
+ return _type;
+ }
+ }
+
+ public static class BeanPropertyDeclaration
+ extends BeanPropertyDescriptor {
+
+ private MethodDeclaration _getter;
+
+
+ public BeanPropertyDeclaration(String propertyName, String type, MethodDeclaration getter) {
+ super(propertyName, type);
+ _getter = getter;
+ }
+
+ public MethodDeclaration getGetter() {
+ return _getter;
+ }
+ }
+
+ public static BeanPropertyDeclaration getBeanProperty(MethodDeclaration method) {
+ if (method.hasModifier(Modifier.PUBLIC) && ! method.hasModifier(Modifier.STATIC)) {
+ String returnType = method.getReturnType().toString();
+
+ if (! returnType.equals("void") && method.getParameters().length == 0) {
+ String methodName = method.getSimpleName();
+ String propertyName = null;
+
+ if (methodName.startsWith(GETTER_PREFIX) && methodName.length() > GETTER_PREFIX.length()) {
+ propertyName = methodName.substring(GETTER_PREFIX.length());
+ } else if (methodName.startsWith(BOOLEAN_GETTER_PREFIX) && returnType.equals("boolean")
+ && methodName.length() > BOOLEAN_GETTER_PREFIX.length()) {
+ propertyName = methodName.substring(BOOLEAN_GETTER_PREFIX.length());
+ }
+
+ if (propertyName != null) {
+ //
+ // If the first two letters are uppercase, we don't change the first character to lowercase.
+ // This is so that something like getURI has a property name of 'URI' (see JavaBeans spec).
+ //
+ if (propertyName.length() == 1) {
+ propertyName = propertyName.toLowerCase();
+ } else if (! Character.isUpperCase(propertyName.charAt(1))) {
+ propertyName = Character.toLowerCase(propertyName.charAt(0)) + propertyName.substring(1);
+ }
+
+ return new BeanPropertyDeclaration(propertyName, returnType, method);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public static Collection getBeanProperties(ClassDeclaration type, boolean getInheritedProperties) {
+ MethodDeclaration[] methods = getInheritedProperties ? getClassMethods(type, null) : type.getMethods();
+ ArrayList ret = new ArrayList();
+
+ for (int i = 0; i < methods.length; i++) {
+ MethodDeclaration method = methods[i];
+
+ if (method.hasModifier(Modifier.PUBLIC)) {
+ BeanPropertyDeclaration bpd = getBeanProperty(method);
+ if (bpd != null) ret.add(bpd);
+ }
+ }
+
+ return ret;
+ }
+
+ public static boolean isPageFlowClass(ClassDeclaration jclass, AnnotationProcessorEnvironment env) {
+ return getAnnotation(jclass, CONTROLLER_TAG_NAME) != null && isAssignableFrom(JPF_BASE_CLASS, jclass, env);
+ }
+
+ public static String removeFileExtension(String uri) {
+ int lastDot = uri.lastIndexOf('.');
+ return uri.substring(0, lastDot);
+ }
+
+ public static TypeDeclaration inferTypeFromPath(String webappRelativePath, AnnotationProcessorEnvironment env) {
+ assert webappRelativePath.startsWith("/") : webappRelativePath;
+ String className = removeFileExtension(webappRelativePath.substring(1));
+ return env.getTypeDeclaration(className.replace('/', '.'));
+ }
+
+ public static TypeDeclaration getDeclaration(DeclaredType type) {
+ return type != null ? type.getDeclaration() : ERROR_TYPE_DECLARATION;
+ }
+
+ private static class ErrorTypeInstance
+ implements TypeInstance {
+
+ public String toString() {
+ return ERROR_STRING;
+ }
+ }
+
+ private static class ErrorTypeDeclaration
+ implements TypeDeclaration {
+
+ private static final InterfaceType[] SUPERINTERFACES = new InterfaceType[0];
+ private static final FieldDeclaration[] FIELDS = new FieldDeclaration[0];
+ private static final MethodDeclaration[] METHODS = new MethodDeclaration[0];
+ private static final TypeDeclaration[] NESTED_TYPES = new TypeDeclaration[0];
+ private static final AnnotationInstance[] ANNOTATIONS = new AnnotationInstance[0];
+
+ public PackageDeclaration getPackage() {
+ throw new IllegalStateException("not implemented ");
+ }
+
+ public String getQualifiedName() {
+ return ERROR_STRING;
+ }
+
+ /*
+ public Collection getFormalTypeParameters()
+ {
+ return Collections.EMPTY_LIST;
+ }
+ */
+
+ public InterfaceType[] getSuperinterfaces() {
+ return SUPERINTERFACES;
+ }
+
+ public FieldDeclaration[] getFields() {
+ return FIELDS;
+ }
+
+ public MethodDeclaration[] getMethods() {
+ return METHODS;
+ }
+
+ public TypeDeclaration[] getNestedTypes() {
+ return NESTED_TYPES;
+ }
+
+ public TypeDeclaration getDeclaringType() {
+ return null;
+ }
+
+ public String getDocComment() {
+ throw new IllegalStateException("not implemented ");
+ }
+
+ public AnnotationInstance[] getAnnotationInstances() {
+ return ANNOTATIONS;
+ }
+
+ /*
+ public Annotation getAnnotation( Class s )
+ {
+ throw new IllegalStateException( "not implemented " );
+ }
+ */
+
+ public Set getModifiers() {
+ return Collections.EMPTY_SET;
+ }
+
+ public String getSimpleName() {
+ return getQualifiedName();
+ }
+
+ public SourcePosition getPosition() {
+ throw new IllegalStateException("not implemented ");
+ }
+
+ public boolean hasModifier(Modifier modifier) {
+ return false;
+ }
+
+ /*
+ public void accept( DeclarationVisitor declarationVisitor )
+ {
+ throw new IllegalStateException( "not implemented " );
+ }
+ */
+ }
+
+ /**
+ * This is the same logic that we have in the runtime, in PageFlowRequestProcessor. Can't share the code, though.
+ */
+ public static boolean isAbsoluteURI(String uri) {
+ //
+ // This method needs to be fast, so it can't use java.net.URI.
+ //
+ if (uri.length() == 0 || uri.charAt(0) == '/') return false;
+
+ for (int i = 0, len = uri.length(); i < len; ++i) {
+ char c = uri.charAt(i);
+
+ if (c == ':') {
+ return true;
+ } else if (c == '/') {
+ return false;
+ }
+ }
+
+ return false;
+ }
+
+ public static TypeInstance getArrayBaseType(ArrayType arrayType) {
+ TypeInstance baseType = arrayType;
+
+ do {
+ baseType = ((ArrayType) baseType).getComponentType();
+ } while (baseType instanceof ArrayType);
+
+ return baseType;
+ }
+
+ public static final class Mutable {
+
+ private Object _val = null;
+
+ public Mutable() {
+ }
+
+ public Mutable(Object val) {
+ _val = val;
+ }
+
+ public void set(Object val) {
+ _val = val;
+ }
+
+ public Object get() {
+ return _val;
+ }
+ }
+
+ public static TypeInstance getGenericBoundsType(TypeInstance type) {
+ if (type instanceof TypeVariable) {
+ ReferenceType[] bounds = ((TypeVariable) type).getDeclaration().getBounds();
+ return bounds.length > 0 ? bounds[0] : type;
+ }
+
+ return type;
+ }
+
+ public static File getFileRelativeToSourceFile(TypeDeclaration outerClass, String relativePath,
+ AnnotationProcessorEnvironment env)
+ throws FatalCompileTimeException {
+ assert relativePath.length() > 0;
+
+ //
+ // If it starts with '/', just find the webapp-relative file.
+ //
+ if (relativePath.charAt(0) == '/') return getWebappRelativeFile(relativePath, true, env);
+
+ //
+ // Look for the file relative to the source directory of the given class.
+ //
+ File sourceFile = getSourceFile(outerClass, false);
+ File desiredParentDir = sourceFile.getAbsoluteFile().getParentFile();
+ File retVal = new File(desiredParentDir, relativePath);
+
+ //
+ // If we still haven't found it, construct a webapp-relative path and look for the file relative to the webapp.
+ //
+ if (! retVal.exists()) {
+ PackageDeclaration jpfPackage = outerClass.getPackage();
+ return getWebappRelativeFile(getPathRelativeToPackage(relativePath, jpfPackage), true, env);
+ }
+
+ return retVal;
+ }
+
+ public static String getPathRelativeToPackage(String relativePath, PackageDeclaration packageDecl) {
+ if (packageDecl != null) {
+ String packageName = packageDecl.getQualifiedName();
+ if (packageName.length() > 0) return '/' + packageName.replace('.', '/') + '/' + relativePath;
+ }
+
+ return '/' + relativePath;
+ }
+
+ public static File getWebappRelativeFile(String webappRelativePath, boolean lookInSourceRoots,
+ AnnotationProcessorEnvironment env)
+ throws FatalCompileTimeException {
+ //
+ // Look for the file out in the web-addressable portion of the webapp.
+ //
+ assert webappRelativePath.startsWith("/") : webappRelativePath;
+ String[] webContentRoots = getWebContentRoots(env);
+
+ for (int i = 0; i < webContentRoots.length; i++) {
+ String webContentRoot = webContentRoots[i];
+ File retVal = new File(webContentRoot + webappRelativePath);
+ if (retVal.exists()) return retVal;
+ }
+
+ //
+ // If appropriate, look for the file under all the source roots.
+ //
+ if (lookInSourceRoots) {
+ String[] webSourceRoots = getWebSourceRoots(env);
+
+ for (int i = 0; i < webSourceRoots.length; i++) {
+ String webSourceRoot = webSourceRoots[i];
+ File webSourceRelativeFile = new File(webSourceRoot + webappRelativePath);
+ if (webSourceRelativeFile.exists()) return webSourceRelativeFile;
+ }
+ }
+
+ return null;
+ }
+
+ public static String[] getWebSourceRoots(AnnotationProcessorEnvironment env)
+ throws FatalCompileTimeException {
+ return (String[]) getOption("-sourcepath", true, env);
+ }
+
+ public static String[] getWebContentRoots(AnnotationProcessorEnvironment env)
+ throws FatalCompileTimeException {
+ return (String[]) getOption("-Aweb.content.root", true, env);
+ }
+
+ private static Object getOption(String optionName, boolean isList, AnnotationProcessorEnvironment env)
+ throws MissingOptionException {
+ Object cached = env.getAttribute(optionName);
+ if (cached != null) return cached;
+
+ Map options = env.getOptions();
+ String value = (String) options.get(optionName);
+
+ if (value == null) {
+ // TODO: there appears to be a bug in APT where both the key/value are contained in the key
+ String aptOption = optionName + '=';
+ for (Iterator i = options.keySet().iterator(); i.hasNext();) {
+ String key = (String) i.next();
+
+ if (key.startsWith(aptOption)) {
+ value = key.substring(aptOption.length());
+ break;
+ }
+ }
+ }
+
+ if (value == null) throw new MissingOptionException(optionName);
+
+ Object retVal = value;
+
+ if (isList) {
+ String[] values = ((String) retVal).trim().split(File.pathSeparator);
+ for (int i = 0; i < values.length; i++) {
+ values[i] = values[i].trim();
+ }
+ retVal = values;
+ }
+
+ env.setAttribute(optionName, retVal);
+ return retVal;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org