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 [6/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/Diagnostics.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/Diagnostics.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/Diagnostics.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/Diagnostics.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,174 @@
+/*
+ * 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.AnnotationValue;
+import org.apache.ti.compiler.internal.typesystem.declaration.Declaration;
+import org.apache.ti.compiler.internal.typesystem.env.AnnotationProcessorEnvironment;
+
+public abstract class Diagnostics {
+
+    private AnnotationProcessorEnvironment _env;
+    private boolean _hasErrors = false;
+
+    protected Diagnostics(AnnotationProcessorEnvironment env) {
+        _env = env;
+    }
+
+    public void addError(Declaration decl, String messageKey) {
+        addErrorArrayArgs(decl, messageKey, null);
+    }
+
+    public void addError(Declaration decl, String messageKey, Object arg) {
+        addErrorArrayArgs(decl, messageKey, new Object[]{arg});
+    }
+
+    public void addError(Declaration decl, String messageKey, Object arg1, Object arg2) {
+        addErrorArrayArgs(decl, messageKey, new Object[]{arg1, arg2});
+    }
+
+    public void addError(Declaration decl, String messageKey, Object arg1, Object arg2, Object arg3) {
+        addErrorArrayArgs(decl, messageKey, new Object[]{arg1, arg2, arg3});
+    }
+
+    public void addErrorArrayArgs(Declaration decl, String messageKey, Object[] args) {
+        _env.getMessager().printError(decl.getPosition(), getResourceString(messageKey, args));
+        _hasErrors = true;
+    }
+
+    public void addErrorNoPosition(String messageKey, Object[] args) {
+        _env.getMessager().printError(getResourceString(messageKey, args));
+    }
+
+    public void addError(AnnotationInstance ann, String messageKey) {
+        addErrorArrayArgs(ann, messageKey, null);
+    }
+
+    public void addError(AnnotationInstance ann, String messageKey, Object arg) {
+        addErrorArrayArgs(ann, messageKey, new Object[]{arg});
+    }
+
+    public void addError(AnnotationInstance ann, String messageKey, Object arg1, Object arg2) {
+        addErrorArrayArgs(ann, messageKey, new Object[]{arg1, arg2});
+    }
+
+    public void addError(AnnotationInstance ann, String messageKey, Object arg1, Object arg2, Object arg3) {
+        addErrorArrayArgs(ann, messageKey, new Object[]{arg1, arg2, arg3});
+    }
+
+    public void addErrorArrayArgs(AnnotationInstance ann, String messageKey, Object[] args) {
+        _env.getMessager().printError(ann.getPosition(), getResourceString(messageKey, args));
+        _hasErrors = true;
+    }
+
+    public void addError(AnnotationValue value, String messageKey) {
+        addErrorArrayArgs(value, messageKey, null);
+    }
+
+    public void addError(AnnotationValue value, String messageKey, Object arg) {
+        addErrorArrayArgs(value, messageKey, new Object[]{arg});
+    }
+
+    public void addError(AnnotationValue value, String messageKey, Object arg1, Object arg2) {
+        addErrorArrayArgs(value, messageKey, new Object[]{arg1, arg2});
+    }
+
+    public void addError(AnnotationValue value, String messageKey, Object arg1, Object arg2, Object arg3) {
+        addErrorArrayArgs(value, messageKey, new Object[]{arg1, arg2, arg3});
+    }
+
+    public void addErrorArrayArgs(AnnotationValue value, String messageKey, Object[] args) {
+        _env.getMessager().printError(value.getPosition(), getResourceString(messageKey, args));
+        _hasErrors = true;
+    }
+
+    public void addWarning(Declaration decl, String messageKey) {
+        addWarningArrayArgs(decl, messageKey, null);
+    }
+
+    public void addWarning(Declaration decl, String messageKey, Object arg) {
+        addWarningArrayArgs(decl, messageKey, new Object[]{arg});
+    }
+
+    public void addWarning(Declaration decl, String messageKey, Object arg1, Object arg2) {
+        addWarningArrayArgs(decl, messageKey, new Object[]{arg1, arg2});
+    }
+
+    public void addWarning(Declaration decl, String messageKey, Object arg1, Object arg2, Object arg3) {
+        addWarningArrayArgs(decl, messageKey, new Object[]{arg1, arg2, arg3});
+    }
+
+    public void addWarningArrayArgs(Declaration decl, String messageKey, Object[] args) {
+        _env.getMessager().printWarning(decl.getPosition(), getResourceString(messageKey, args));
+    }
+
+    public void addWarning(AnnotationInstance ann, String messageKey) {
+        addWarningArrayArgs(ann, messageKey, null);
+    }
+
+    public void addWarning(AnnotationInstance ann, String messageKey, Object arg) {
+        addWarningArrayArgs(ann, messageKey, new Object[]{arg});
+    }
+
+    public void addWarning(AnnotationInstance ann, String messageKey, Object arg1, Object arg2) {
+        addWarningArrayArgs(ann, messageKey, new Object[]{arg1, arg2});
+    }
+
+    public void addWarning(AnnotationInstance ann, String messageKey, Object arg1, Object arg2, Object arg3) {
+        addWarningArrayArgs(ann, messageKey, new Object[]{arg1, arg2, arg3});
+    }
+
+    public void addWarningArrayArgs(AnnotationInstance ann, String messageKey, Object[] args) {
+        _env.getMessager().printWarning(ann.getPosition(), getResourceString(messageKey, args));
+    }
+
+    public void addWarning(AnnotationValue value, String messageKey) {
+        addWarningArrayArgs(value, messageKey, null);
+    }
+
+    public void addWarning(AnnotationValue value, String messageKey, Object arg) {
+        addWarningArrayArgs(value, messageKey, new Object[]{arg});
+    }
+
+    public void addWarning(AnnotationValue value, String messageKey, Object arg1, Object arg2) {
+        addWarningArrayArgs(value, messageKey, new Object[]{arg1, arg2});
+    }
+
+    public void addWarning(AnnotationValue value, String messageKey, Object arg1, Object arg2, Object arg3) {
+        addWarningArrayArgs(value, messageKey, new Object[]{arg1, arg2, arg3});
+    }
+
+    public void addWarningArrayArgs(AnnotationValue value, String messageKey, Object[] args) {
+        _env.getMessager().printWarning(value.getPosition(), getResourceString(messageKey, args));
+    }
+
+    protected abstract String getResourceString(String key, Object[] args);
+
+    public boolean hasErrors() {
+        return _hasErrors;
+    }
+
+    protected void setHasErrors(boolean hadErrors) {
+        _hasErrors = hadErrors;
+    }
+
+    protected AnnotationProcessorEnvironment getAnnotationProcessorEnvironment() {
+        return _env;
+    }
+}

Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FacesBackingChecker.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FacesBackingChecker.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FacesBackingChecker.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FacesBackingChecker.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,73 @@
+/*
+* 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.grammar.CommandHandlerGrammar;
+import org.apache.ti.compiler.internal.typesystem.declaration.ClassDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.MethodDeclaration;
+import org.apache.ti.compiler.internal.typesystem.env.AnnotationProcessorEnvironment;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class FacesBackingChecker
+        extends BaseChecker
+        implements JpfLanguageConstants {
+
+    public FacesBackingChecker(AnnotationProcessorEnvironment env, FacesBackingInfo fbInfo, Diagnostics diags) {
+        super(env, fbInfo, diags);
+    }
+
+    public Map onCheck(ClassDeclaration jclass)
+            throws FatalCompileTimeException {
+        if (! CompilerUtils.isAssignableFrom(FACES_BACKING_BEAN_CLASS, jclass, getEnv())) {
+            getDiagnostics().addError(jclass, "error.does-not-extend-base", FACES_BACKING_BEAN_CLASS);
+            return null;
+        }
+
+        ClassDeclaration[] packageClasses = jclass.getPackage().getClasses();
+        ClassDeclaration jpfClass = null;
+
+        for (int i = 0; i < packageClasses.length; i++) {
+            ClassDeclaration classDecl = packageClasses[i];
+            if (CompilerUtils.isPageFlowClass(classDecl, getEnv())) jpfClass = classDecl;
+        }
+
+        FlowControllerInfo fcInfo = new FlowControllerInfo(jpfClass);
+        fcInfo.startBuild(getEnv(), jpfClass);
+
+        CommandHandlerGrammar chg =
+                new CommandHandlerGrammar(getEnv(), getDiagnostics(), getRuntimeVersionChecker(), jpfClass, fcInfo);
+        MethodDeclaration[] methods = CompilerUtils.getClassMethods(jclass, COMMAND_HANDLER_TAG_NAME);
+
+        for (int i = 0; i < methods.length; i++) {
+            MethodDeclaration method = methods[i];
+            getFBSourceFileInfo().addCommandHandler(method.getSimpleName());
+            chg.check(CompilerUtils.getAnnotation(method, COMMAND_HANDLER_TAG_NAME), null, method);
+        }
+
+        Map checkResultMap = new HashMap();
+        checkResultMap.put(JpfLanguageConstants.ExtraInfoKeys.facesBackingInfo, getSourceFileInfo());
+        return checkResultMap;
+    }
+
+    protected FacesBackingInfo getFBSourceFileInfo() {
+        return (FacesBackingInfo) super.getSourceFileInfo();
+    }
+}

Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FacesBackingGenerator.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FacesBackingGenerator.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FacesBackingGenerator.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FacesBackingGenerator.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,56 @@
+/*
+ * 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.ClassDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.MethodDeclaration;
+import org.apache.ti.compiler.internal.typesystem.env.AnnotationProcessorEnvironment;
+
+public class FacesBackingGenerator
+        extends BaseGenerator
+        implements JpfLanguageConstants {
+
+    public FacesBackingGenerator(AnnotationProcessorEnvironment env, SourceFileInfo sourceFileInfo, Diagnostics diagnostics) {
+        super(env, sourceFileInfo, diagnostics);
+    }
+
+    public void generate(ClassDeclaration publicClass)
+            throws FatalCompileTimeException {
+        AnnotationInstance facesBackingAnnotation = CompilerUtils.getAnnotation(publicClass, FACES_BACKING_TAG_NAME);
+        assert facesBackingAnnotation != null;  // checker should enforce this
+        AnnotationToXML atx = new AnnotationToXML(publicClass);
+
+        // Add the class-level @Jpf.FacesBacking annotation.
+        atx.include(publicClass, facesBackingAnnotation);
+
+        // For each method, add the @Jpf.CommandHandler annotation.
+        MethodDeclaration[] methods = CompilerUtils.getClassMethods(publicClass, COMMAND_HANDLER_TAG_NAME);
+        for (int i = 0; i < methods.length; i++) {
+            MethodDeclaration method = methods[i];
+            AnnotationInstance commandHandlerAnn = CompilerUtils.getAnnotation(method, COMMAND_HANDLER_TAG_NAME);
+            atx.include(method, commandHandlerAnn);
+        }
+
+        // Add @Jpf.SharedFlowField, @Jpf.PageFlowField, @Control.
+        FlowControllerGenerator.includeFieldAnnotations(atx, publicClass, PAGE_FLOW_FIELD_TAG_NAME);
+
+        // Write the file.
+        atx.writeXml(getDiagnostics(), getEnv());
+    }
+}

Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FacesBackingInfo.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FacesBackingInfo.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FacesBackingInfo.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FacesBackingInfo.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,40 @@
+/*
+ * 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 java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FacesBackingInfo
+        extends SourceFileInfo {
+
+    private List _commandHandlers = new ArrayList();
+
+    public FacesBackingInfo(File sourceFile, String className) {
+        super(sourceFile, className);
+    }
+
+    public List getCommandHandlers() {
+        return _commandHandlers;
+    }
+
+    void addCommandHandler(String commandHandlerName) {
+        _commandHandlers.add(commandHandlerName);
+    }
+}

Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FatalCompileTimeException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FatalCompileTimeException.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FatalCompileTimeException.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FatalCompileTimeException.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+public abstract class FatalCompileTimeException
+        extends Exception {
+
+    protected FatalCompileTimeException(String message) {
+        super(message);
+    }
+
+    public abstract void printDiagnostic(Diagnostics diagnostics);
+}

Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FlowControllerChecker.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FlowControllerChecker.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FlowControllerChecker.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FlowControllerChecker.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,602 @@
+/*
+ * 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.genmodel.GenXWorkModuleConfigModel;
+import org.apache.ti.compiler.internal.grammar.ActionGrammar;
+import org.apache.ti.compiler.internal.grammar.ExceptionHandlerGrammar;
+import org.apache.ti.compiler.internal.grammar.WebappPathType;
+import org.apache.ti.compiler.internal.processor.SilentDiagnostics;
+import org.apache.ti.compiler.internal.typesystem.declaration.AnnotationInstance;
+import org.apache.ti.compiler.internal.typesystem.declaration.AnnotationValue;
+import org.apache.ti.compiler.internal.typesystem.declaration.ClassDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.FieldDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.MethodDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.Modifier;
+import org.apache.ti.compiler.internal.typesystem.declaration.PackageDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.ParameterDeclaration;
+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.ClassType;
+import org.apache.ti.compiler.internal.typesystem.type.TypeInstance;
+import org.apache.xmlbeans.XmlException;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+public abstract class FlowControllerChecker
+        extends BaseChecker
+        implements JpfLanguageConstants {
+
+    private AnnotationGrammar _controllerGrammar;
+    private AnnotationGrammar _actionGrammar;
+    private AnnotationGrammar _exceptionHandlerGrammar;
+    private AnnotationGrammar _actionGrammarSilentDiagnostics;
+    private AnnotationGrammar _exceptionHandlerGrammarSilentDiagnostics;
+    private FormBeanChecker _formBeanChecker;
+    private Map _checkResultMap;
+
+    protected FlowControllerChecker(AnnotationProcessorEnvironment env, FlowControllerInfo fcInfo, Diagnostics diags) {
+        super(env, fcInfo, diags);
+    }
+
+    protected void doAdditionalClassChecks(ClassDeclaration jpfClass) {
+    }
+
+    protected Map getCheckResultMap() {
+        return _checkResultMap;
+    }
+
+    protected abstract String getDesiredBaseClass(ClassDeclaration jclass);
+
+    protected abstract AnnotationGrammar getControllerGrammar();
+
+    public Map onCheck(ClassDeclaration jclass)
+            throws FatalCompileTimeException {
+        FlowControllerInfo fcInfo = getFCSourceFileInfo();
+
+        _checkResultMap = new HashMap();
+        _controllerGrammar = getControllerGrammar();
+        _actionGrammar = new ActionGrammar(getEnv(), getDiagnostics(), getRuntimeVersionChecker(), fcInfo);
+        _exceptionHandlerGrammar =
+                new ExceptionHandlerGrammar(getEnv(), getDiagnostics(), getRuntimeVersionChecker(), fcInfo);
+        _formBeanChecker = new FormBeanChecker(getEnv(), getDiagnostics());
+
+        SilentDiagnostics silentDiagnostics = new SilentDiagnostics();
+        _actionGrammarSilentDiagnostics = new ActionGrammar(getEnv(), silentDiagnostics, getRuntimeVersionChecker(), fcInfo);
+        _exceptionHandlerGrammarSilentDiagnostics =
+                new ExceptionHandlerGrammar(getEnv(), silentDiagnostics, getRuntimeVersionChecker(), fcInfo);
+
+        fcInfo.startBuild(getEnv(), jclass);
+
+        try {
+            return onCheckInternal(jclass);
+        }
+        finally {
+            fcInfo.endBuild();
+        }
+    }
+
+    private Map onCheckInternal(ClassDeclaration jclass)
+            throws FatalCompileTimeException {
+        FlowControllerInfo fcInfo = getFCSourceFileInfo();
+
+        //
+        // Check the base class.
+        //
+        String desiredBaseClass = getDesiredBaseClass(jclass);
+        if (desiredBaseClass != null && ! CompilerUtils.isAssignableFrom(desiredBaseClass, jclass, getEnv())) {
+            getDiagnostics().addError(jclass, "error.does-not-extend-base", desiredBaseClass);
+        }
+
+        //
+        // Check the annotations on the class.
+        //
+        startCheckClass(jclass);
+
+        //
+        // Check the fields.  Note that we're checking public and protected inherited fields, too.
+        //
+        Collection fields = CompilerUtils.getClassFields(jclass);
+
+        for (Iterator ii = fields.iterator(); ii.hasNext();) {
+            FieldDeclaration field = (FieldDeclaration) ii.next();
+            checkField(field, jclass);
+        }
+
+        //
+        // Check the methods.  Note that we're checking public and protected inherited methods, too.
+        //
+        MethodDeclaration[] methods = CompilerUtils.getClassMethods(jclass, null);
+
+        for (int i = 0; i < methods.length; i++) {
+            MethodDeclaration method = methods[i];
+            TypeDeclaration declaringType = method.getDeclaringType();
+
+            //
+            // Only add diagnostics if the method is in this class, or if it's inherited from a class that's *not* on
+            // sourcepath (i.e., its SourcePosition is null).
+            //
+            if (declaringType.equals(jclass) || declaringType.getPosition() == null) {
+                checkMethod(method, jclass, _actionGrammar, _exceptionHandlerGrammar);
+            } else {
+                //
+                // We still want to run the checks, which aggregate information into the FlowControllerInfo.  We just
+                // don't want diagnostics to be printed.
+                //
+                checkMethod(method, jclass, _actionGrammarSilentDiagnostics, _exceptionHandlerGrammarSilentDiagnostics);
+            }
+        }
+
+        //
+        // Check the inner classes.
+        //
+        Collection innerTypes = CompilerUtils.getClassNestedTypes(jclass);
+
+        for (Iterator ii = innerTypes.iterator(); ii.hasNext();) {
+            TypeDeclaration innerType = (TypeDeclaration) ii.next();
+            if (innerType instanceof ClassDeclaration) checkInnerClass((ClassDeclaration) innerType);
+        }
+
+        //
+        // Run additional .jpf- or .app-specific checks.
+        //
+        doAdditionalClassChecks(jclass);
+
+        //
+        // Runtime performance enhancement: enable saving of previous-page and previous-action information based on
+        // whether there were Forwards that contained navigateTo attributes.
+        //
+        enableNavigateTo(jclass, fcInfo.getMergedControllerAnnotation(), fcInfo);
+        Map sharedFlowTypes = fcInfo.getSharedFlowTypes();
+
+        if (sharedFlowTypes != null) {
+            for (Iterator ii = sharedFlowTypes.values().iterator(); ii.hasNext();) {
+                TypeDeclaration sharedFlowType = (TypeDeclaration) ii.next();
+                //
+                // Saving of previous-page/previous-action info must be enabled if any of the referenced shared flows
+                // use this feature.
+                //
+                enableNavigateTo(sharedFlowType, new MergedControllerAnnotation(sharedFlowType), fcInfo);
+            }
+        }
+
+        endCheckClass(jclass);
+        _checkResultMap.put(JpfLanguageConstants.ExtraInfoKeys.flowControllerInfo, fcInfo);
+        return _checkResultMap;
+    }
+
+    private static void enableNavigateTo(TypeDeclaration flowControllerClass, MergedControllerAnnotation controllerAnn,
+                                         FlowControllerInfo fcInfo) {
+        //
+        // Look through Forwards and SimpleActions in the Controller annotation.
+        //
+        enableNavigateTo(controllerAnn.getForwards(), fcInfo);
+        enableNavigateTo(controllerAnn.getSimpleActions(), fcInfo);
+
+        //
+        // Look through Forwards on Action and ExceptionHandler methods.
+        //
+        MethodDeclaration[] methods = CompilerUtils.getClassMethods(flowControllerClass, null);
+
+        for (int i = 0; i < methods.length; i++) {
+            MethodDeclaration method = methods[i];
+            AnnotationInstance ann = CompilerUtils.getAnnotation(method, ACTION_TAG_NAME);
+
+            if (ann != null) {
+                enableNavigateTo(CompilerUtils.getAnnotation(ann, VALIDATION_ERROR_FORWARD_ATTR, true), fcInfo);
+            }
+
+            if (ann == null) ann = CompilerUtils.getAnnotation(method, EXCEPTION_HANDLER_TAG_NAME);
+            if (ann != null) enableNavigateTo(CompilerUtils.getAnnotationArray(ann, FORWARDS_ATTR, true), fcInfo);
+        }
+    }
+
+    private static void enableNavigateTo(Collection childAnnotations, FlowControllerInfo fcInfo) {
+        if (childAnnotations != null) {
+            for (Iterator ii = childAnnotations.iterator(); ii.hasNext();) {
+                AnnotationInstance childAnnotation = (AnnotationInstance) ii.next();
+                enableNavigateTo(childAnnotation, fcInfo);
+            }
+        }
+    }
+
+    private static void enableNavigateTo(AnnotationInstance ann, FlowControllerInfo fcInfo) {
+        if (ann == null) return;
+        String val = CompilerUtils.getEnumFieldName(ann, NAVIGATE_TO_ATTR, true);
+
+        if (val != null) {
+            if (val.equals(NAVIGATE_TO_CURRENT_PAGE_STR) || val.equals(NAVIGATE_TO_PREVIOUS_PAGE_STR)) {
+                fcInfo.enableNavigateToPage();
+            } else if (val.equals(NAVIGATE_TO_PREVIOUS_ACTION_STR)) {
+                fcInfo.enableNavigateToAction();
+            }
+        }
+    }
+
+    protected void endCheckClass(ClassDeclaration jclass) {
+    }
+
+    protected abstract GenXWorkModuleConfigModel createStrutsApp(ClassDeclaration jclass)
+            throws XmlException, IOException, FatalCompileTimeException;
+
+    protected void startCheckClass(ClassDeclaration jclass)
+            throws FatalCompileTimeException {
+        //
+        // Check for basic things like writability of the struts-config file.
+        //
+        GenXWorkModuleConfigModel strutsApp = null;
+        File strutsConfigFile = null;
+
+        //
+        // Make sure we can write to the struts-config XML file.
+        //
+        try {
+            strutsApp = createStrutsApp(jclass);
+            strutsConfigFile = strutsApp.getStrutsConfigFile();
+        }
+        catch (XmlException e) {
+            // will be reported at generate time
+        }
+        catch (IOException e) {
+            // will be reported at generate time
+        }
+
+        if (strutsConfigFile != null) {
+            File parentDir = strutsConfigFile.getParentFile();
+
+            getFCSourceFileInfo().addReferencedFile(strutsConfigFile);
+
+            if (strutsConfigFile.exists() && strutsApp != null && ! strutsApp.canWrite()) {
+                getDiagnostics().addError(jclass, "error.struts-config-not-writable", strutsConfigFile);
+            }
+        }
+
+        getRuntimeVersionChecker().checkRuntimeVersion(VERSION_8_SP2_STRING, jclass, getDiagnostics(),
+                "warning.runtime-version", null);
+
+        //
+        // Check the Jpf.Controller annotation on this class.
+        //
+        AnnotationInstance controllerAnnotation = CompilerUtils.getAnnotation(jclass, CONTROLLER_TAG_NAME);
+        if (controllerAnnotation != null) _controllerGrammar.check(controllerAnnotation, null, jclass);
+
+        //
+        // Check relative paths on Jpf.Catch, Jpf.Forward, and Jpf.SimpleAction annotations on superclasses.
+        // If inheritLocalPaths is set to true on @Jpf.Controller, then we don't need to do this check, since
+        // inherited paths will always resolve.
+        //
+        if (! getFCSourceFileInfo().getMergedControllerAnnotation().isInheritLocalPaths()) {
+            checkInheritedRelativePaths(jclass);
+        }
+    }
+
+    /**
+     * Check relative paths in annotations inherited from a base class.
+     */
+    private void checkInheritedRelativePaths(ClassDeclaration jclass)
+            throws FatalCompileTimeException {
+        for (ClassType type = jclass.getSuperclass();
+             type != null && CompilerUtils.isAssignableFrom(FLOWCONTROLLER_BASE_CLASS, type, getEnv());
+             type = type.getSuperclass()) {
+            TypeDeclaration decl = CompilerUtils.getDeclaration(type);
+
+            //
+            // Check simple actions in the Controller annotation.
+            //
+            List simpleActions =
+                    CompilerUtils.getAnnotationArrayValue(decl, CONTROLLER_TAG_NAME, SIMPLE_ACTIONS_ATTR, true);
+
+            if (simpleActions != null) {
+                for (Iterator j = simpleActions.iterator(); j.hasNext();) {
+                    AnnotationInstance i = (AnnotationInstance) j.next();
+                    checkRelativePath(i, PATH_ATTR, jclass, decl, false);
+                    List conditionalForwards = CompilerUtils.getAnnotationArray(i, CONDITIONAL_FORWARDS_ATTR, true);
+
+                    if (conditionalForwards != null) {
+                        for (Iterator k = conditionalForwards.iterator(); k.hasNext();) {
+                            AnnotationInstance ann = (AnnotationInstance) k.next();
+                            checkRelativePath(ann, PATH_ATTR, jclass, decl, false);
+                        }
+                    }
+                }
+            }
+
+            //
+            // Check Forwards in the Controller annotation.
+            //
+            List forwards = CompilerUtils.getAnnotationArrayValue(decl, CONTROLLER_TAG_NAME, FORWARDS_ATTR, true);
+
+            if (forwards != null) {
+                for (Iterator ii = forwards.iterator(); ii.hasNext();) {
+                    AnnotationInstance i = (AnnotationInstance) ii.next();
+                    checkRelativePath(i, PATH_ATTR, jclass, decl, false);
+                }
+            }
+
+            //
+            // Check Catches in the Controller annotation.
+            //
+            List catches = CompilerUtils.getAnnotationArrayValue(decl, CONTROLLER_TAG_NAME, CATCHES_ATTR, true);
+
+            if (catches != null) {
+                for (Iterator j = catches.iterator(); j.hasNext();) {
+                    AnnotationInstance i = (AnnotationInstance) j.next();
+                    checkRelativePath(i, PATH_ATTR, jclass, decl, false);
+                }
+            }
+
+            //
+            // Check strutsMerge and validatorMerge in the Controller annotation.
+            //
+            AnnotationInstance controllerAnnotation = CompilerUtils.getAnnotation(decl, CONTROLLER_TAG_NAME);
+
+            if (controllerAnnotation != null) {
+                checkRelativePath(controllerAnnotation, VALIDATOR_MERGE_ATTR, jclass, decl, true);
+            }
+
+            //
+            // Check Forwards and Catches on action methods and exception-handler methods.
+            //
+            MethodDeclaration[] methods = decl.getMethods();
+            for (int i = 0; i < methods.length; i++) {
+                MethodDeclaration method = methods[i];
+                AnnotationInstance ann = CompilerUtils.getAnnotation(method, ACTION_TAG_NAME);
+                if (ann == null) ann = CompilerUtils.getAnnotation(method, EXCEPTION_HANDLER_TAG_NAME);
+
+                if (ann != null) {
+                    List methodForwards = CompilerUtils.getAnnotationArray(ann, FORWARDS_ATTR, true);
+                    String methodName = method.getSimpleName();
+
+                    if (methodForwards != null) {
+                        for (Iterator j = methodForwards.iterator(); j.hasNext();) {
+                            AnnotationInstance methodForward = (AnnotationInstance) j.next();
+                            checkRelativePath(methodName, methodForward, PATH_ATTR, jclass, decl, false);
+                        }
+                    }
+
+                    List methodCatches = CompilerUtils.getAnnotationArray(ann, CATCHES_ATTR, true);
+
+                    if (methodCatches != null) {
+                        for (Iterator j = methodCatches.iterator(); j.hasNext();) {
+                            AnnotationInstance methodCatch = (AnnotationInstance) j.next();
+                            checkRelativePath(methodName, methodCatch, PATH_ATTR, jclass, decl, false);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void checkRelativePath(AnnotationInstance ann, String memberName, TypeDeclaration jclass,
+                                   TypeDeclaration baseType, boolean isError)
+            throws FatalCompileTimeException {
+        if (ann != null) {
+            AnnotationValue pathVal = CompilerUtils.getAnnotationValue(ann, memberName, true);
+
+            if (pathVal != null) {
+                String path = (String) pathVal.getValue();
+
+                if (path.charAt(0) != '/' && ! WebappPathType.relativePathExists(path, jclass, getEnv())) {
+                    String[] args = {
+                            path,
+                            ANNOTATION_INTERFACE_PREFIX + ann.getAnnotationType().getDeclaration().getSimpleName(),
+                            baseType.getQualifiedName()
+                    };
+
+                    if (isError) {
+                        getDiagnostics().addErrorArrayArgs(ann, "message.inherited-file-not-found", args);
+                    } else {
+                        getDiagnostics().addWarningArrayArgs(ann, "message.inherited-file-not-found", args);
+                    }
+                }
+            }
+        }
+    }
+
+    private void checkRelativePath(String methodName, AnnotationInstance ann, String memberName,
+                                   TypeDeclaration jclass, TypeDeclaration baseType, boolean isError)
+            throws FatalCompileTimeException {
+        if (ann != null) {
+            AnnotationValue pathVal = CompilerUtils.getAnnotationValue(ann, memberName, true);
+
+            if (pathVal != null) {
+                String path = (String) pathVal.getValue();
+
+                if (path.charAt(0) != '/' && ! WebappPathType.relativePathExists(path, jclass, getEnv())) {
+                    String[] args = {
+                            path,
+                            ANNOTATION_INTERFACE_PREFIX + ann.getAnnotationType().getDeclaration().getSimpleName(),
+                            methodName,
+                            baseType.getQualifiedName()
+                    };
+
+                    if (isError) {
+                        getDiagnostics().addErrorArrayArgs(jclass, "message.method-inherited-file-not-found", args);
+                    } else {
+                        getDiagnostics().addWarningArrayArgs(jclass, "message.method-inherited-file-not-found", args);
+                    }
+                }
+            }
+        }
+    }
+
+
+    protected void checkField(FieldDeclaration field, TypeDeclaration jclass) {
+        //
+        // Only warn about nonserializable member data that's defined in this particular class.
+        //
+        if (CompilerUtils.typesAreEqual(jclass, field.getDeclaringType())) {
+            TypeInstance type = field.getType();
+
+            if (! field.hasModifier(Modifier.TRANSIENT) && ! field.hasModifier(Modifier.STATIC)
+                    && type instanceof ClassType
+                    && ! CompilerUtils.isAssignableFrom(SERIALIZABLE_CLASS_NAME, type, getEnv())) {
+                getDiagnostics().addWarning(field, "warning.nonserializable-member-data");
+            }
+        }
+    }
+
+    protected void checkMethod(MethodDeclaration method, ClassDeclaration jclass,
+                               AnnotationGrammar actionGrammar, AnnotationGrammar exceptionHandlerGrammar)
+            throws FatalCompileTimeException {
+        AnnotationInstance[] annotations = method.getAnnotationInstances();
+
+        for (int i = 0; i < annotations.length; i++) {
+            AnnotationInstance annotation = annotations[i];
+            String annotationName = CompilerUtils.getDeclaration(annotation.getAnnotationType()).getSimpleName();
+
+            if (annotationName.equals(ACTION_TAG_NAME)) {
+                actionGrammar.check(annotation, null, method);
+
+                if (! CompilerUtils.isAssignableFrom(FORWARD_CLASS_NAME, method.getReturnType(), getEnv())
+                        && ! CompilerUtils.isAssignableFrom(STRING_CLASS_NAME, method.getReturnType(), getEnv())) {
+                    getDiagnostics().addError(method, "error.method-wrong-return-type", FORWARD_CLASS_NAME,
+                            STRING_CLASS_NAME);
+                }
+            } else if (annotationName.equals(EXCEPTION_HANDLER_TAG_NAME)) {
+                exceptionHandlerGrammar.check(annotation, null, method);
+                checkExceptionHandlerMethod(method);
+            }
+        }
+    }
+
+    protected void checkInnerClass(ClassDeclaration innerClass)
+            throws FatalCompileTimeException {
+        _formBeanChecker.check(innerClass);
+    }
+
+    private void checkExceptionHandlerMethod(MethodDeclaration method) {
+        if (! CompilerUtils.isAssignableFrom(FORWARD_CLASS_NAME, method.getReturnType(), getEnv())
+                && ! CompilerUtils.isAssignableFrom(STRING_CLASS_NAME, method.getReturnType(), getEnv())) {
+            getDiagnostics().addError(method, "error.method-wrong-return-type", FORWARD_CLASS_NAME, STRING_CLASS_NAME);
+        }
+
+        ParameterDeclaration[] parameters = method.getParameters();
+
+        if (parameters.length == 2) {
+            if (! CompilerUtils.isAssignableFrom(THROWABLE_CLASS_NAME, parameters[0].getType(), getEnv())) {
+                getDiagnostics().addError(method, "error.exception-method-wrong-exception-arg", THROWABLE_CLASS_NAME);
+            }
+
+            checkExceptionHandlerArgType(method, parameters, 1, STRING_CLASS_NAME);
+        } else {
+            getDiagnostics().addError(method, "error.exception-method-wrong-arg-count", new Integer(2));
+        }
+    }
+
+    private void checkExceptionHandlerArgType(MethodDeclaration method, ParameterDeclaration[] parameters,
+                                              int index, String className) {
+        if (! CompilerUtils.isOfClass(parameters[index].getType(), className, getEnv())) {
+            getDiagnostics().addError(method, "error.exception-method-wrong-arg-type", new Integer(index + 1),
+                    className);
+        }
+    }
+
+    protected void checkForOverlappingClasses(ClassDeclaration jpfClass, String baseClass, String fileExtension,
+                                              String errorKey) {
+        File jpfFile = CompilerUtils.getSourceFile(jpfClass, true);
+        File parentDir = jpfFile.getParentFile();
+        PackageDeclaration pkg = jpfClass.getPackage();
+        ClassDeclaration[] packageClasses = pkg.getClasses();
+        Set overlapping = new HashSet();
+        List overlappingFiles = new ArrayList();
+
+        //
+        // First go through the other classes in this package to look for other classes of this type.  Only one per
+        // directory is allowed.
+        //
+        for (int i = 0; i < packageClasses.length; i++) {
+            ClassDeclaration classDecl = packageClasses[i];
+            if (CompilerUtils.getAnnotation(classDecl, CONTROLLER_TAG_NAME) != null
+                    && CompilerUtils.isAssignableFrom(baseClass, classDecl, getEnv())) {
+                File file = CompilerUtils.getSourceFile(classDecl, false);
+
+                //
+                // Add the dependency if it's a different file and if the file exists (it may have been deleted
+                // sometime after the list of classes in this package got built.
+                //
+                if (! jpfFile.equals(file) && file != null && file.exists()) {
+                    overlapping.add(file.getName());
+                    overlappingFiles.add(file);
+                }
+            }
+        }
+
+        //
+        // Additionally, we'll go through the parent directory to make sure there are no other files of this type. 
+        // This is a double-check for the case where duplicate files have the same class names inside them, which means
+        // that iterating through the list of package classes is hit or miss (only one of them will show up, and it may
+        // be this class or the duplicate class).
+        //
+        File[] peers = parentDir.listFiles(new ExtensionFileFilter(fileExtension));
+
+        if (peers != null)    // make sure the directory hasn't been deleted while we're running
+        {
+            for (int i = 0; i < peers.length; i++) {
+                File peer = peers[i];
+                if (! peer.equals(jpfFile)) {
+                    String name = peer.getName();
+
+                    if (! overlapping.contains(name)) {
+                        overlapping.add(name);
+                        overlappingFiles.add(peer);
+                    }
+                }
+            }
+        }
+
+        int len = overlapping.size();
+        if (len > 0) {
+            if (len > 3) {
+                getDiagnostics().addErrorArrayArgs(jpfClass, errorKey, overlapping.toArray());
+            } else {
+                getDiagnostics().addErrorArrayArgs(jpfClass, errorKey + len, overlapping.toArray());
+            }
+        }
+
+        getCheckResultMap().put(JpfLanguageConstants.ExtraInfoKeys.overlappingPageFlowFiles, overlappingFiles);
+    }
+
+    private static class ExtensionFileFilter implements FilenameFilter {
+
+        private String _extension;
+
+        public ExtensionFileFilter(String extension) {
+            _extension = extension;
+        }
+
+        public boolean accept(File dir, String name) {
+            return name.endsWith(_extension);
+        }
+    }
+
+    protected FlowControllerInfo getFCSourceFileInfo() {
+        return (FlowControllerInfo) super.getSourceFileInfo();
+    }
+}

Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FlowControllerGenerator.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FlowControllerGenerator.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FlowControllerGenerator.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FlowControllerGenerator.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,158 @@
+/*
+ * 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.genmodel.GenValidationModel;
+import org.apache.ti.compiler.internal.genmodel.GenXWorkModuleConfigModel;
+import org.apache.ti.compiler.internal.typesystem.declaration.AnnotationInstance;
+import org.apache.ti.compiler.internal.typesystem.declaration.ClassDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.FieldDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.TypeDeclaration;
+import org.apache.ti.compiler.internal.typesystem.env.AnnotationProcessorEnvironment;
+import org.apache.xmlbeans.XmlException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+
+
+abstract class FlowControllerGenerator
+        extends BaseGenerator {
+
+    private static long _compilerJarTimestamp = -1;
+    private static final boolean ALWAYS_GENERATE = true;  // TODO: this turns stale checking off.  Do we need it?
+    private static final String CONTROL_ANNOTATION = JpfLanguageConstants.TI_PACKAGE + ".controls.api.bean.Control";
+
+    protected FlowControllerGenerator(AnnotationProcessorEnvironment env, FlowControllerInfo fcInfo,
+                                      Diagnostics diagnostics) {
+        super(env, fcInfo, diagnostics);
+    }
+
+    protected abstract GenXWorkModuleConfigModel createStrutsApp(ClassDeclaration cl)
+            throws XmlException, IOException, FatalCompileTimeException;
+
+    public void generate(ClassDeclaration publicClass) {
+        GenXWorkModuleConfigModel app = null;
+        getFCSourceFileInfo().startBuild(getEnv(), publicClass);
+
+        try {
+            // Write the Struts config XML, and the Validator config XML if appropriate.
+            app = createStrutsApp(publicClass);
+            GenValidationModel validationModel = new GenValidationModel(publicClass, app, getEnv());
+
+            if (! validationModel.isEmpty()) {
+                app.setValidationModel(validationModel);
+                validationModel.writeToFile();
+            }
+
+            generateStrutsConfig(app, publicClass);
+
+            // First, write out XML for any fields annotated with @Jpf.SharedFlowField or @Control.
+            writeFieldAnnotations(publicClass, app);
+        }
+        catch (FatalCompileTimeException e) {
+            e.printDiagnostic(getDiagnostics());
+        }
+        catch (Exception e) {
+            e.printStackTrace();    // @TODO log
+            assert e instanceof XmlException || e instanceof IOException || e instanceof FileNotFoundException
+                    : e.getClass().getName();
+            getDiagnostics().addError(publicClass, "error.could-not-generate",
+                    app != null ? app.getStrutsConfigFile() : null, e.getMessage());
+        }
+        finally {
+            getFCSourceFileInfo().endBuild();
+        }
+    }
+
+    private void writeFieldAnnotations(ClassDeclaration classDecl, GenXWorkModuleConfigModel app)
+            throws FatalCompileTimeException {
+        AnnotationToXML atx = new AnnotationToXML(classDecl);
+
+        if (includeFieldAnnotations(atx, classDecl, null)) {
+            atx.writeXml(getDiagnostics(), getEnv());
+        }
+    }
+
+    static boolean includeFieldAnnotations(AnnotationToXML atx, TypeDeclaration typeDecl, String additionalAnnotation) {
+        Collection fields = CompilerUtils.getClassFields(typeDecl);
+        boolean hasFieldAnnotations = false;
+
+        if (fields.size() > 0) {
+            for (Iterator i = fields.iterator(); i.hasNext();) {
+                FieldDeclaration field = (FieldDeclaration) i.next();
+                AnnotationInstance fieldAnnotation =
+                        CompilerUtils.getAnnotation(field, JpfLanguageConstants.SHARED_FLOW_FIELD_TAG_NAME);
+
+                if (fieldAnnotation == null) {
+                    fieldAnnotation = CompilerUtils.getAnnotationFullyQualified(field, CONTROL_ANNOTATION);
+                }
+
+                if (fieldAnnotation == null && additionalAnnotation != null) {
+                    fieldAnnotation = CompilerUtils.getAnnotation(field, additionalAnnotation);
+                }
+
+                if (fieldAnnotation != null) {
+                    atx.include(field, fieldAnnotation);
+                    hasFieldAnnotations = true;
+                }
+            }
+        }
+
+        return hasFieldAnnotations;
+    }
+
+    protected void generateStrutsConfig(GenXWorkModuleConfigModel app, ClassDeclaration publicClass) {
+        File strutsConfigFile = null;
+
+        try {
+            strutsConfigFile = app.getStrutsConfigFile();
+
+            if (ALWAYS_GENERATE || app.isStale()) {
+                // @TODO logger.info( "Writing Struts module: " + _strutsConfig.getStrutsConfigFile() );
+                app.writeToFile();
+            } else if (_compilerJarTimestamp > strutsConfigFile.lastModified()) {
+                // @TODO logger.info( _compilerJarName + " has been updated; writing Struts module "
+                //          + _strutsConfig.getStrutsConfigFile() );
+                app.writeToFile();
+            } else {
+                // @TODO logger.info( "Struts module " + _strutsConfig.getStrutsConfigFile() + " is up-to-date." );
+            }
+        }
+        catch (FatalCompileTimeException e) {
+            e.printDiagnostic(getDiagnostics());
+        }
+        catch (Exception e) {
+            e.printStackTrace();    // @TODO get rid of this
+            assert e instanceof FileNotFoundException
+                    || e instanceof IOException
+                    || e instanceof XmlException
+                    : e.getClass().getName();
+
+            getDiagnostics().addError(publicClass, "error.could-not-generate",
+                    strutsConfigFile != null ? strutsConfigFile.getPath() : null,
+                    e.getMessage());
+        }
+    }
+
+    protected FlowControllerInfo getFCSourceFileInfo() {
+        return (FlowControllerInfo) super.getSourceFileInfo();
+    }
+}

Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FlowControllerInfo.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FlowControllerInfo.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FlowControllerInfo.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FlowControllerInfo.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,290 @@
+/*
+ * 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.ClassDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.FieldDeclaration;
+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.DeclaredType;
+import org.apache.ti.compiler.internal.typesystem.type.TypeInstance;
+
+import java.io.File;
+import java.util.*;
+
+
+public class FlowControllerInfo
+        extends SourceFileInfo
+        implements JpfLanguageConstants {
+
+    private static final ActionInfo[] EMPTY_ACTION_INFO_ARRAY = new ActionInfo[0];
+
+    private Set _actions = new HashSet();
+    private Set _returnActions = null;
+    private Map _sharedFlowTypes = Collections.EMPTY_MAP;
+    private Map _sharedFlowTypeNames = Collections.EMPTY_MAP;
+    private Map _sharedFlowFiles = Collections.EMPTY_MAP;
+    private List _referencedFiles = new ArrayList();
+    private boolean _isBuilding = false;
+    private Map _messageBundlesByName = new HashMap();
+    private boolean _navigateToActionEnabled = false;
+    private boolean _navigateToPageEnabled = false;
+    private boolean _isNested;
+    private MergedControllerAnnotation _mergedControllerAnnotation;
+
+
+    public static class ActionInfo {
+
+        private String _name;
+        private String _beanType = null;
+
+        public ActionInfo(String name) {
+            _name = name;
+        }
+
+        public ActionInfo(String name, String beanType) {
+            _name = name;
+            _beanType = beanType;
+        }
+
+        public void setBeanType(String beanType) {
+            _beanType = beanType;
+        }
+
+        public String getName() {
+            return _name;
+        }
+
+        public String getBeanType() {
+            return _beanType;
+        }
+
+        public boolean equals(Object o) {
+            if (o == null || ! (o instanceof ActionInfo)) {
+                return false;
+            }
+
+            ActionInfo other = (ActionInfo) o;
+            if (! _name.equals(other.getName())) return false;
+            String otherBeanType = other.getBeanType();
+            return ((_beanType == null && otherBeanType == null)
+                    || (_beanType != null && otherBeanType != null && _beanType.equals(otherBeanType)));
+        }
+
+        public int hashCode() {
+            int nameHash = _name.hashCode();
+            if (_beanType == null) return nameHash;
+            return nameHash != 0 ? _beanType.hashCode() % nameHash : _beanType.hashCode();
+        }
+    }
+
+
+    public FlowControllerInfo(ClassDeclaration jclass) {
+        super(CompilerUtils.getSourceFile(jclass, true), jclass.getQualifiedName());
+    }
+
+    void startBuild(AnnotationProcessorEnvironment env, ClassDeclaration jclass) {
+        _isBuilding = true;
+        _mergedControllerAnnotation = new MergedControllerAnnotation(jclass);
+        _isNested = _mergedControllerAnnotation.isNested();
+        setSharedFlowInfo(env);
+    }
+
+    void endBuild() {
+        _isBuilding = false;
+        _sharedFlowTypes = null;    // don't hang onto ClassDeclarations
+        _mergedControllerAnnotation = null;
+    }
+
+    public ActionInfo[] getActions() {
+        return (ActionInfo[]) _actions.toArray(new ActionInfo[ _actions.size() ]);
+    }
+
+    public boolean isNested() {
+        return _isNested;
+    }
+
+    public ActionInfo[] getReturnActions() {
+        if (_returnActions == null) {
+            return EMPTY_ACTION_INFO_ARRAY;
+        }
+
+        return (ActionInfo[]) _returnActions.toArray(new ActionInfo[ _returnActions.size() ]);
+    }
+
+    public String getFormBeanType(String actionName) {
+        String bestType = null;
+
+        for (Iterator ii = _actions.iterator(); ii.hasNext();) {
+            ActionInfo actionInfo = (ActionInfo) ii.next();
+            if (actionInfo.getName().equals(actionName)) {
+                String beanType = actionInfo.getBeanType();
+
+                //
+                // In the case of overloaded actions, the non-form-bean action takes precedence.  Otherwise,
+                // we look at the bean type names in alphabetical order.
+                //
+                if (beanType == null) return null;
+                else if (bestType == null) bestType = beanType;
+                else if (beanType.compareTo(bestType) < 0) bestType = beanType;
+            }
+        }
+
+        return bestType;
+    }
+
+    int countReturnActions() {
+        return _returnActions != null ? _returnActions.size() : 0;
+    }
+
+    public void addAction(String actionName, String formBeanType) {
+        _actions.add(new ActionInfo(actionName, formBeanType));
+    }
+
+    public void addReturnAction(String returnActionName, String formBeanType) {
+        if (_returnActions == null) _returnActions = new HashSet();
+        _returnActions.add(new ActionInfo(returnActionName, formBeanType));
+    }
+
+    /**
+     * Get a list of referenced files (files that appear in Jpf.Forward paths).
+     */
+    public List getReferencedFiles() {
+        return _referencedFiles;
+    }
+
+    public void addReferencedFile(File file) {
+        if (! file.equals(getSourceFile())) {
+            _referencedFiles.add(file);
+        }
+    }
+
+    private void setSharedFlowInfo(AnnotationProcessorEnvironment env) {
+        //
+        // First, find all referenced Shared Flow types.
+        //
+        _sharedFlowTypes = new LinkedHashMap();
+
+        Collection sharedFlowRefs = _mergedControllerAnnotation.getSharedFlowRefs();
+
+        if (sharedFlowRefs != null) {
+            for (Iterator i = sharedFlowRefs.iterator(); i.hasNext();) {
+                AnnotationInstance sharedFlowRef = (AnnotationInstance) i.next();
+                String name = CompilerUtils.getString(sharedFlowRef, NAME_ATTR, true);
+                TypeInstance type = CompilerUtils.getTypeInstance(sharedFlowRef, TYPE_ATTR, true);
+
+                if (type instanceof DeclaredType)   // if it's not a DeclaredType, the error will be caught elsewhere.
+                {
+                    TypeDeclaration typeDecl = ((DeclaredType) type).getDeclaration();
+
+                    if (typeDecl != null)     // If the declaration is null, it's an error type.
+                    {
+                        _sharedFlowTypes.put(name, typeDecl);
+                    }
+                }
+            }
+        }
+
+        _sharedFlowTypeNames = new LinkedHashMap();
+        _sharedFlowFiles = new LinkedHashMap();
+
+        for (Iterator i = _sharedFlowTypes.entrySet().iterator(); i.hasNext();) {
+            Map.Entry entry = (Map.Entry) i.next();
+            TypeDeclaration type = (TypeDeclaration) entry.getValue();
+            _sharedFlowTypeNames.put(entry.getKey(), type.getQualifiedName());
+            File file = CompilerUtils.getSourceFile(type, false);
+
+            if (file != null) {
+                _sharedFlowFiles.put(entry.getKey(), file);
+                _referencedFiles.add(file);
+            }
+        }
+    }
+
+    public Map getSharedFlowTypes() {
+        assert _isBuilding : "use getSharedFlowTypeNames after check or generate phases";
+        return _sharedFlowTypes;
+    }
+
+    public Map getSharedFlowTypeNames() {
+        return _sharedFlowTypeNames;
+    }
+
+    public MergedControllerAnnotation getMergedControllerAnnotation() {
+        assert _isBuilding : "only valid during the check or generate phases";
+        return _mergedControllerAnnotation;
+    }
+
+    public Map getMessageBundlesByName() {
+        return _messageBundlesByName;
+    }
+
+    public void addMessageBundle(String bundleName, String bundlePath) {
+        _messageBundlesByName.put(bundleName, bundlePath);
+    }
+
+    public String getControllerClassName() {
+        return getClassName();
+    }
+
+    public Map getSharedFlowFiles() {
+        return _sharedFlowFiles;
+    }
+
+    public void enableNavigateToAction() {
+        _navigateToActionEnabled = true;
+    }
+
+    public void enableNavigateToPage() {
+        _navigateToPageEnabled = true;
+    }
+
+    public boolean isNavigateToActionEnabled() {
+        return _navigateToActionEnabled;
+    }
+
+    public boolean isNavigateToPageEnabled() {
+        return _navigateToPageEnabled;
+    }
+
+    /**
+     * Add a return-action from an annotation.
+     *
+     * @return the form bean type, or null</code> if there is no form bean.
+     */
+    public TypeInstance addReturnAction(String returnActionName, AnnotationInstance annotation, TypeDeclaration outerType) {
+        TypeInstance formBeanType = CompilerUtils.getTypeInstance(annotation, OUTPUT_FORM_BEAN_TYPE_ATTR, true);
+
+        if (formBeanType == null) {
+            String memberFieldName = CompilerUtils.getString(annotation, OUTPUT_FORM_BEAN_ATTR, true);
+
+            if (memberFieldName != null) {
+                FieldDeclaration field = CompilerUtils.findField(outerType, memberFieldName);
+                if (field != null) formBeanType = field.getType();
+            }
+        }
+
+        String formTypeName =
+                formBeanType != null && formBeanType instanceof DeclaredType
+                        ? CompilerUtils.getDeclaration((DeclaredType) formBeanType).getQualifiedName()
+                        : null;
+        addReturnAction(returnActionName, formTypeName);
+        return formBeanType;
+    }
+}

Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FormBeanChecker.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FormBeanChecker.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FormBeanChecker.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/FormBeanChecker.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,129 @@
+/*
+ * 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.grammar.ValidatablePropertyGrammar;
+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.ClassDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.MemberDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.MethodDeclaration;
+import org.apache.ti.compiler.internal.typesystem.declaration.Modifier;
+import org.apache.ti.compiler.internal.typesystem.env.AnnotationProcessorEnvironment;
+
+import java.util.Map;
+
+
+public class FormBeanChecker
+        extends BaseChecker
+        implements JpfLanguageConstants {
+
+    public FormBeanChecker(AnnotationProcessorEnvironment env, Diagnostics diags) {
+        super(env, null, diags);
+    }
+
+    public Map onCheck(ClassDeclaration jclass)
+            throws FatalCompileTimeException {
+        GetterValidatablePropertyGrammar validatablePropertyGrammar = new GetterValidatablePropertyGrammar();
+        boolean isFormBeanClass = CompilerUtils.getAnnotation(jclass, FORM_BEAN_TAG_NAME, true) != null;
+
+        //
+        // Look for ValidationField annotations on the methods; if there are some present, then we consider this
+        // a form bean class, even if it's not annotated as such.
+        //
+        MethodDeclaration[] methods = CompilerUtils.getClassMethods(jclass, null);
+
+        for (int i = 0; i < methods.length; i++) {
+            MethodDeclaration method = methods[i];
+            isFormBeanClass |=
+                    checkValidationAnnotation(method, VALIDATABLE_PROPERTY_TAG_NAME, validatablePropertyGrammar);
+            // We don't currently support validation rule annotations directly on getter methods.
+            /*
+            hasOne |= checkValidationAnnotation( method, LOCALE_RULES_ATTR, _validationLocaleRulesGrammar );
+            hasOne |= checkValidationAnnotation( method, VALIDATE_REQUIRED_TAG_NAME, _baseValidationRuleGrammar );
+            hasOne |= checkValidationAnnotation( method, VALIDATE_RANGE_TAG_NAME, _validateRangeGrammar );
+            hasOne |= checkValidationAnnotation( method, VALIDATE_MIN_LENGTH_TAG_NAME, _baseValidationRuleGrammar );
+            hasOne |= checkValidationAnnotation( method, VALIDATE_MAX_LENGTH_TAG_NAME, _baseValidationRuleGrammar );
+            hasOne |= checkValidationAnnotation( method, VALIDATE_CREDIT_CARD_TAG_NAME, _baseValidationRuleGrammar );
+            hasOne |= checkValidationAnnotation( method, VALIDATE_EMAIL_TAG_NAME, _baseValidationRuleGrammar );
+            hasOne |= checkValidationAnnotation( method, VALIDATE_MASK_TAG_NAME, _baseValidationRuleGrammar );
+            hasOne |= checkValidationAnnotation( method, VALIDATE_DATE_TAG_NAME, _baseValidationRuleGrammar );
+            hasOne |= checkValidationAnnotation( method, VALIDATE_TYPE_TAG_NAME, _validateTypeGrammar );
+            */
+        }
+
+        //
+        // Make sure form bean subclasses are public static, and that they have default constructors.
+        //
+        if (isFormBeanClass) {
+            if (jclass.getDeclaringType() != null && ! jclass.hasModifier(Modifier.STATIC)) {
+                getDiagnostics().addError(jclass, "error.form-not-static");
+            }
+
+            if (! jclass.hasModifier(Modifier.PUBLIC)) {
+                getDiagnostics().addError(jclass, "error.form-not-public");
+            }
+
+            if (! CompilerUtils.hasDefaultConstructor(jclass)) {
+                getDiagnostics().addError(jclass, "error.form-no-default-constructor");
+            }
+        }
+
+        return null;
+    }
+
+    private boolean checkValidationAnnotation(MethodDeclaration method, String annotationTagName,
+                                              AnnotationGrammar grammar)
+            throws FatalCompileTimeException {
+        AnnotationInstance annotation = CompilerUtils.getAnnotation(method, annotationTagName);
+
+        if (annotation != null) {
+            if (CompilerUtils.getBeanProperty(method) == null) {
+                getDiagnostics().addError(annotation, "error.validation-field-on-non-getter");
+            }
+
+            grammar.check(annotation, null, method);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    private class GetterValidatablePropertyGrammar
+            extends ValidatablePropertyGrammar {
+
+        public GetterValidatablePropertyGrammar() {
+            super(FormBeanChecker.this.getEnv(), FormBeanChecker.this.getDiagnostics(),
+                    FormBeanChecker.this.getRuntimeVersionChecker());
+        }
+
+        public String[][] getRequiredAttrs() {
+            return null;  // This override causes the 'propertyName' attribute *not* to be required
+        }
+
+        protected void onCheckMember(AnnotationTypeElementDeclaration memberDecl, AnnotationValue member,
+                                     AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
+                                     MemberDeclaration classMember) {
+            if (memberDecl.getSimpleName().equals(PROPERTY_NAME_ATTR)) {
+                addError(member, "error.validatable-field-property-name-not-allowed", PROPERTY_NAME_ATTR);
+            }
+        }
+    }
+}

Added: struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/JpfLanguageConstants.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/JpfLanguageConstants.java?rev=280879&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/JpfLanguageConstants.java (added)
+++ struts/sandbox/trunk/ti/jars/core/src/java/org/apache/ti/compiler/internal/JpfLanguageConstants.java Wed Sep 14 09:20:05 2005
@@ -0,0 +1,233 @@
+/*
+ * 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;
+
+public interface JpfLanguageConstants {
+
+    public static final String TI_PACKAGE = "org.apache.ti";
+    public static final String PAGEFLOW_PACKAGE = TI_PACKAGE + ".pageflow";
+    public static final String PAGEFLOW_XWORK_PACKAGE = PAGEFLOW_PACKAGE + ".xwork";
+    public static final String PAGEFLOW_INTERNAL_PACKAGE = PAGEFLOW_PACKAGE + ".internal";
+    public static final String ANNOTATIONS_CLASSNAME = PAGEFLOW_PACKAGE + ".annotations.ti";
+
+    public static final String ACTION_TAG_NAME = "action";
+    public static final String SIMPLE_ACTION_TAG_NAME = "simpleAction";
+    public static final String EXCEPTION_HANDLER_TAG_NAME = "exceptionHandler";
+    public static final String FORWARD_TAG_NAME = "forward";
+    public static final String CATCH_TAG_NAME = "handleException";
+    public static final String CONTROLLER_TAG_NAME = "controller";
+    public static final String MESSAGE_BUNDLE_TAG_NAME = "messageBundle";
+    public static final String VIEW_PROPERTIES_TAG_NAME = "viewProperties";
+    public static final String VALIDATION_LOCALE_RULES_TAG_NAME = "validationLocaleRules";
+    public static final String VALIDATION_BEAN_TAG_NAME = "validationBean";
+    public static final String VALIDATABLE_PROPERTY_TAG_NAME = "validatableProperty";
+    public static final String VALIDATABLE_BEAN_TAG_NAME = "validatableBean";
+    public static final String FORM_BEAN_TAG_NAME = "formBean";
+    public static final String ACTION_OUTPUT_TAG_NAME = "actionOutput";
+    public static final String CONDITIONAL_FORWARD_TAG_NAME = "conditionalForward";
+    public static final String FACES_BACKING_TAG_NAME = "facesBacking";
+    public static final String COMMAND_HANDLER_TAG_NAME = "commandHandler";
+    public static final String RAISE_ACTION_TAG_NAME = "raiseAction";
+    public static final String SHARED_FLOW_REF_TAG_NAME = "sharedFlowRef";
+    public static final String SHARED_FLOW_FIELD_TAG_NAME = "sharedFlowField";
+    public static final String PAGE_FLOW_FIELD_TAG_NAME = "pageFlowField";
+
+    public static final String VALIDATE_REQUIRED_TAG_NAME = "validateRequired";
+    public static final String VALIDATE_RANGE_TAG_NAME = "validateRange";
+    public static final String VALIDATE_MIN_LENGTH_TAG_NAME = "validateMinLength";
+    public static final String VALIDATE_MAX_LENGTH_TAG_NAME = "validateMaxLength";
+    public static final String VALIDATE_CREDIT_CARD_TAG_NAME = "validateCreditCard";
+    public static final String VALIDATE_EMAIL_TAG_NAME = "validateEmail";
+    public static final String VALIDATE_MASK_TAG_NAME = "validateMask";
+    public static final String VALIDATE_DATE_TAG_NAME = "validateDate";
+    public static final String VALIDATE_TYPE_TAG_NAME = "validateType";
+    public static final String VALIDATE_VALID_WHEN_TAG_NAME = "validateValidWhen";
+    public static final String VALIDATE_CUSTOM_RULE_TAG_NAME = "validateCustomRule";
+    public static final String MESSAGE_ARG_TAG_NAME = "messageArg";
+    public static final String VALIDATE_CUSTOM_VARIABLE_TAG_NAME = "validateCustomVariable";
+
+    public static final String BEGIN_ACTION_NAME = "begin";
+    public static final String JPF_FILE_EXTENSION = "jpf";
+    public static final String FACES_BACKING_FILE_EXTENSION = "jsfb";
+    public static final String JAVA_FILE_EXTENSION = "java";
+    public static final String JSP_FILE_EXTENSION = "jsp";
+    public static final String XJSP_FILE_EXTENSION = "jspx";
+    public static final String ACTION_EXTENSION = "do";
+    public static final String JPF_FILE_EXTENSION_DOT = '.' + JPF_FILE_EXTENSION;
+    public static final String ACTION_EXTENSION_DOT = '.' + ACTION_EXTENSION;
+    public static final String JAVA_FILE_EXTENSION_DOT = '.' + JAVA_FILE_EXTENSION;
+    public static final String FACES_BACKING_FILE_EXTENSION_DOT = '.' + FACES_BACKING_FILE_EXTENSION;
+    public static final String SHARED_FLOW_FILE_EXTENSION = "jpfs";
+    public static final String SHARED_FLOW_FILE_EXTENSION_DOT = '.' + SHARED_FLOW_FILE_EXTENSION;
+    public static final String SHARED_FLOW_CLASSNAME = "SharedFlowController";
+    public static final String PAGE_FLOW_CONFIG_FILE_BASENAME = "pageflow";
+    public static final String SHARED_FLOW_CONFIG_FILE_BASENAME = "sharedflow";
+    public static final String FLOWCONTROLLER_BASE_CLASS = PAGEFLOW_PACKAGE + ".FlowController";
+    public static final String JPF_BASE_CLASS = PAGEFLOW_PACKAGE + ".PageFlowController";
+    public static final String SHARED_FLOW_BASE_CLASS = PAGEFLOW_PACKAGE + ".SharedFlowController";
+    public static final String FACES_BACKING_BEAN_CLASS = PAGEFLOW_PACKAGE + ".FacesBackingBean";
+    public static final String FLOW_CONTROLLER_ACTION_CLASS = PAGEFLOW_INTERNAL_PACKAGE + ".FlowControllerAction";
+    public static final String WEBINF_DIR_NAME = "WEB-INF";
+    public static final String WEBINF_SRC_PATH = '/' + WEBINF_DIR_NAME + "/src";
+    public static final String ANNOTATION_QUALIFIER = ANNOTATIONS_CLASSNAME + '.';
+    public static final String ANNOTATION_INTERFACE_PREFIX = "ti.";
+    public static final String NAVIGATE_TO_ENUM = "NavigateTo";
+    public static final String DEFAULT_VALIDATION_MESSAGE_BUNDLE = PAGEFLOW_PACKAGE + ".validation.defaultMessages";
+    public static final String DEFAULT_VALIDATION_MESSAGE_BUNDLE_NAME = "_defaultMsgs";
+    public static final String DEFAULT_SIMPLE_ACTION_FORWARD_NAME = "_defaultForward";
+
+    public static final String NESTED_ATTR = "nested";
+    public static final String LONGLIVED_ATTR = "longLived";
+    public static final String VALIDATOR_VERSION_ATTR = "validatorVersion";
+    public static final String VALIDATOR_MERGE_ATTR = "validatorMerge";
+    public static final String CUSTOM_VALIDATOR_CONFIGS_ATTR = "customValidatorConfigs";
+    public static final String TILES_DEFINITIONS_CONFIGS_ATTR = "tilesDefinitionsConfigs";
+    public static final String LOGIN_REQUIRED_ATTR = "loginRequired";
+    public static final String ROLES_ALLOWED_ATTR = "rolesAllowed";
+    public static final String NAME_ATTR = "name";
+    public static final String PATH_ATTR = "path";
+    public static final String TILES_DEFINITION_ATTR = "tilesDefinition";
+    public static final String OUTPUT_FORM_BEAN_TYPE_ATTR = "outputFormBeanType";
+    public static final String OUTPUT_FORM_BEAN_ATTR = "outputFormBean";
+    public static final String NAVIGATE_TO_ATTR = "navigateTo";
+    public static final String RETURN_ACTION_ATTR = "returnAction";
+    public static final String MESSAGE_ATTR = "message";
+    public static final String MESSAGE_KEY_ATTR = "messageKey";
+    public static final String MESSAGE_ARGS_ATTR = "messageArgs";
+    public static final String ARG_ATTR = "arg";
+    public static final String ARG_KEY_ATTR = "argKey";
+    public static final String POSITION_ATTR = "position";
+    public static final String DISPLAY_NAME_ATTR = "displayName";
+    public static final String DISPLAY_NAME_KEY_ATTR = "displayNameKey";
+    public static final String METHOD_ATTR = "method";
+    public static final String TYPE_ATTR = "type";
+    public static final String REDIRECT_ATTR = "redirect";
+    public static final String EXTERNAL_REDIRECT_ATTR = "externalRedirect";
+    public static final String BUNDLE_PATH_ATTR = "bundlePath";
+    public static final String BUNDLE_NAME_ATTR = "bundleName";
+    public static final String ACTION_OUTPUTS_ATTR = "actionOutputs";
+    public static final String REQUIRED_ATTR = "required";
+    public static final String USE_FORM_BEAN_ATTR = "useFormBean";
+    public static final String USE_FORM_BEAN_TYPE_ATTR = "useFormBeanType";
+    public static final String READONLY_ATTR = "readOnly";
+    public static final String INHERIT_LOCAL_PATHS_ATTR = "inheritLocalPaths";
+    public static final String RESTORE_QUERY_STRING_ATTR = "restoreQueryString";
+    public static final String VALUE_ATTR = "value";
+    public static final String MESSAGE_BUNDLES_ATTR = "messageBundles";
+    public static final String FORWARDS_ATTR = "forwards";
+    public static final String CATCHES_ATTR = "handleExceptions";
+    public static final String VALIDATION_ERROR_FORWARD_ATTR = "validationErrorForward";
+    public static final String DO_VALIDATION_ATTR = "doValidation";
+    public static final String LANGUAGE_ATTR = "language";
+    public static final String COUNTRY_ATTR = "country";
+    public static final String VARIANT_ATTR = "variant";
+    public static final String VALIDATE_REQUIRED_ATTR = "validateRequired";
+    public static final String VALIDATE_RANGE_ATTR = "validateRange";
+    public static final String VALIDATE_MIN_LENGTH_ATTR = "validateMinLength";
+    public static final String VALIDATE_MAX_LENGTH_ATTR = "validateMaxLength";
+    public static final String VALIDATE_CREDIT_CARD_ATTR = "validateCreditCard";
+    public static final String VALIDATE_EMAIL_ATTR = "validateEmail";
+    public static final String VALIDATE_MASK_ATTR = "validateMask";
+    public static final String VALIDATE_DATE_ATTR = "validateDate";
+    public static final String VALIDATE_TYPE_ATTR = "validateType";
+    public static final String VALIDATE_VALID_WHEN_ATTR = "validateValidWhen";
+    public static final String VALIDATE_CUSTOM_ATTR = "validateCustomRules";
+    public static final String VALIDATABLE_PROPERTIES_ATTR = "validatableProperties";
+    public static final String MESSAGE_BUNDLE_ATTR = "messageBundle";
+    public static final String APPLY_TO_UNHANDLED_LOCALES_ATTR = "applyToUnhandledLocales";
+    public static final String VALIDATION_BEANS_ATTR = "validationBeans";
+    public static final String ACTION_ATTR = "action";
+    public static final String RAISE_ACTIONS_ATTR = "raiseActions";
+    public static final String MULTIPART_HANDLER_ATTR = "multipartHandler";
+    public static final String SHARED_FLOW_REFS_ATTR = "sharedFlowRefs";
+    public static final String PREVENT_DOUBLE_SUBMIT_ATTR = "preventDoubleSubmit";
+    public static final String FORWARD_REF_ATTR = "forwardRef";
+    public static final String TYPE_HINT_ATTR = "typeHint";
+
+    public static final String MIN_INT_ATTR = "minInt";
+    public static final String MAX_INT_ATTR = "maxInt";
+    public static final String MIN_FLOAT_ATTR = "minFloat";
+    public static final String MAX_FLOAT_ATTR = "maxFloat";
+    public static final String CHARS_ATTR = "chars";
+    public static final String STRICT_ATTR = "strict";
+    public static final String REGEX_ATTR = "regex";
+    public static final String PATTERN_ATTR = "pattern";
+    public static final String PROPERTY_NAME_ATTR = "propertyName";
+    public static final String LOCALE_RULES_ATTR = "localeRules";
+    public static final String VALIDATABLE_BEANS_ATTR = "validatableBeans";
+    public static final String KEY_ATTR = "key";
+    public static final String SIMPLE_ACTIONS_ATTR = "simpleActions";
+    public static final String CONDITION_ATTR = "condition";
+    public static final String CONDITIONAL_FORWARDS_ATTR = "conditionalForwards";
+    public static final String RULE_ATTR = "rule";
+    public static final String VARIABLES_ATTR = "variables";
+
+    public static final String FORWARD_CLASS_NAME = PAGEFLOW_PACKAGE + ".Forward";
+    public static final String PAGEFLOW_FORM_CLASS_NAME = PAGEFLOW_PACKAGE + ".FormData";
+    public static final String BEA_XMLOBJECT_CLASS_NAME = "com.bea.xml.XmlObject";
+    public static final String APACHE_XMLOBJECT_CLASS_NAME = "org.apache.xmlbeans.XmlObject";
+    public static final String XML_FORM_CLASS_NAME = PAGEFLOW_PACKAGE + ".internal.XmlBeanActionForm";
+    public static final String STRING_CLASS_NAME = String.class.getName();
+    public static final String THROWABLE_CLASS_NAME = Throwable.class.getName();
+    public static final String OBJECT_CLASS_NAME = Object.class.getName();
+    public static final String SERIALIZABLE_CLASS_NAME = "java.io.Serializable";
+
+    public static final String NAVIGATE_TO_CURRENT_PAGE_STR = "currentPage";
+    public static final String NAVIGATE_TO_PREVIOUS_PAGE_STR = "previousPage";
+    public static final String NAVIGATE_TO_PREVIOUS_ACTION_STR = "previousAction";
+
+    public static final String MULTIPART_HANDLER_DISABLED_STR = "disabled";
+    public static final String MULTIPART_HANDLER_MEMORY_STR = "memory";
+    public static final String MULTIPART_HANDLER_DISK_STR = "disk";
+
+    public static final String STRUTS_PACKAGE = "org.apache.struts";
+    public static final String COMMONS_MULTIPART_HANDLER_CLASSNAME = STRUTS_PACKAGE + ".upload.CommonsMultipartRequestHandler";
+
+    public static final String VALIDATOR_VERSION_ONE_ZERO_STR = "oneZero";
+    public static final String VALIDATOR_VERSION_ONE_ONE_STR = "oneOne";
+
+    public static final String ARRAY_TYPE_SUFFIX = "[]";
+    public static final String GETTER_PREFIX = "get";
+    public static final String BOOLEAN_GETTER_PREFIX = "is";
+
+    public static final String RUNTIME_VERSION_ATTRIBUTE = "PageFlow-Runtime-Version";
+
+    public static final String VERSION_8_SP2_STRING = "2";
+    public static final String VERSION_9_0_STRING = "3";
+
+    public static class ExtraInfoKeys {
+
+        public static final Integer flowControllerInfo = new Integer(0);
+        public static final Integer facesBackingInfo = new Integer(1);
+        public static final Integer overlappingPageFlowFiles = new Integer(2);
+
+        private Integer _val;
+
+        public ExtraInfoKeys(Integer val) {
+            _val = val;
+        }
+
+        public boolean equals(Object val) {
+            return _val.equals(val);
+        }
+
+        public Integer getVal() {
+            return _val;
+        }
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org