Added:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/compiler/xdoclet/typesystem/impl/type/TypeVariableImpl.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/compiler/xdoclet/typesystem/impl/type/TypeVariableImpl.java?view=auto&rev=157713
==============================================================================
---
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/compiler/xdoclet/typesystem/impl/type/TypeVariableImpl.java
(added)
+++
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/compiler/xdoclet/typesystem/impl/type/TypeVariableImpl.java
Tue Mar 15 23:14:32 2005
@@ -0,0 +1,39 @@
+/*
+ * 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.beehive.netui.compiler.xdoclet.typesystem.impl.type;
+
+import
org.apache.beehive.netui.compiler.typesystem.declaration.TypeParameterDeclaration;
+import org.apache.beehive.netui.compiler.typesystem.type.TypeVariable;
+
+public class TypeVariableImpl
+ extends ReferenceTypeImpl
+ implements TypeVariable
+{
+ public TypeVariableImpl()
+ {
+ super( null );
+ assert false : "NYI";
+ throw new UnsupportedOperationException( "NYI" );
+ }
+
+ public TypeParameterDeclaration getDeclaration()
+ {
+ assert false : "NYI";
+ throw new UnsupportedOperationException( "NYI" );
+ }
+}
Propchange:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/compiler/xdoclet/typesystem/impl/type/TypeVariableImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/compiler/xdoclet/typesystem/impl/type/VoidTypeImpl.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/compiler/xdoclet/typesystem/impl/type/VoidTypeImpl.java?view=auto&rev=157713
==============================================================================
---
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/compiler/xdoclet/typesystem/impl/type/VoidTypeImpl.java
(added)
+++
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/compiler/xdoclet/typesystem/impl/type/VoidTypeImpl.java
Tue Mar 15 23:14:32 2005
@@ -0,0 +1,31 @@
+/*
+ * 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.beehive.netui.compiler.xdoclet.typesystem.impl.type;
+
+import org.apache.beehive.netui.compiler.typesystem.type.VoidType;
+import xjavadoc.XClass;
+
+public class VoidTypeImpl
+ extends TypeMirrorImpl
+ implements VoidType
+{
+ public VoidTypeImpl( XClass delegate )
+ {
+ super( delegate );
+ }
+}
Propchange:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/compiler/xdoclet/typesystem/impl/type/VoidTypeImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/tasks/SourceCopy.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/tasks/SourceCopy.java?view=auto&rev=157713
==============================================================================
---
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/tasks/SourceCopy.java
(added)
+++
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/tasks/SourceCopy.java
Tue Mar 15 23:14:32 2005
@@ -0,0 +1,133 @@
+package org.apache.beehive.netui.tasks;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Copy;
+
+import java.util.Enumeration;
+import java.io.*;
+
+/**
+ * Extend the default ant copy task to do some verification on java and
pageflow source files.
+ */
+public class SourceCopy extends Copy
+{
+ protected static final String PACKAGE = "package";
+
+ /**
+ * Override doFileOperations to verify things that a source file's
+ * package name is the same as directory name.
+ *
+ * Note: we are not checking that anything named .jpf extends
PageFlowController because
+ * that would require more advanced source parsing; the netui doclet task
handles this by
+ * making sure that if we find a class that extends PageFlowController,
there is a corresponding
+ * jpf file.
+ */
+ protected void doFileOperations()
+ {
+ if (fileCopyMap.size() > 0)
+ {
+ log("Verifying " + fileCopyMap.size()
+ + " source file" + (fileCopyMap.size() == 1 ? "" : "s")
+ + " before copy");
+
+
+ Enumeration e = fileCopyMap.keys();
+ while (e.hasMoreElements())
+ {
+ String fromFile = (String) e.nextElement();
+
+ if ( !fromFile.endsWith( ".java" ) && !fromFile.endsWith(
".jpf" ) &&
+ !fromFile.endsWith( ".app" ) )
+ continue;
+
+ try
+ {
+ File sourceFile = new File( fromFile );
+ if ( sourceFile.exists() && sourceFile.isFile() )
+ {
+ String packageName = getPackage( sourceFile );
+ if ( packageName != null && packageName.length() > 0 )
+ {
+ String path = sourceFile.getParentFile().getPath();
+ path = path.replace( File.separatorChar, '.' );
+ if ( !path.endsWith( packageName ) )
+ {
+ throw new BuildException( "File " + fromFile +
" failed verification because its package (" +
+ packageName + ") differs from its
directory location. This will cause errors with the pageflow compiler." );
+ }
+ }
+ }
+ }
+ catch (Exception ioe)
+ {
+ String msg = "Failed to verify " + fromFile
+ + " due to " + ioe.getMessage();
+ throw new BuildException(msg, ioe, getLocation());
+ }
+ }
+ }
+
+ super.doFileOperations();
+ }
+
+ /**
+ * Get the package name of a java source file. This just does some really
basic parsing to find
+ * the first line that starts with "package", and then returns the rest of
that line before the
+ * first semicolon. It won't catch any possible way that a package could
be specified (after a comment,
+ * with line breaks, etc) but it's a good-faith effort to determine the
package name. If no package
+ * name is found, the file will be skipped during the verification process.
+ * @param sourceFile
+ * @return
+ * @throws IOException
+ */
+ protected String getPackage(File sourceFile)
+ throws IOException
+ {
+ BufferedReader in = null;
+ String packageName = null;
+ String encoding = getEncoding();
+
+ try
+ {
+ if (encoding == null)
+ {
+ in = new BufferedReader(new FileReader(sourceFile));
+ }
+ else
+ {
+ in = new BufferedReader(new InputStreamReader(
+ new FileInputStream(sourceFile),
+ encoding));
+ }
+
+ String line = in.readLine();
+ while (line != null)
+ {
+ if (line.length() != 0)
+ {
+ line = line.trim();
+ if (line.startsWith(PACKAGE))
+ {
+ int semi = line.indexOf(";");
+ if ( semi != -1 )
+ {
+ packageName = line.substring(PACKAGE.length() + 1,
semi);
+ packageName = packageName.trim();
+ }
+ break;
+ }
+ }
+ line = in.readLine();
+ }
+ }
+ finally
+ {
+ if (in != null)
+ {
+ in.close();
+ }
+ }
+
+ return packageName;
+ }
+}
Propchange:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/tasks/SourceCopy.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/Messages.properties
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/Messages.properties?view=auto&rev=157713
==============================================================================
---
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/Messages.properties
(added)
+++
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/Messages.properties
Tue Mar 15 23:14:32 2005
@@ -0,0 +1,9 @@
+compiler.build.failed = \n\nPage Flow build failed; see errors above.
+compiler.build.results = \n\n----->{0} error(s) and {1} warning(s) found in
{2}:
+compiler.warning = warning:
+compiler.line = (line {0})
+
+error.no-parent-annotation = There is no valid parent annotation for @{0}.
+error.no-such-member = There is no member "{0}" on annotation @{1}.
+error.invalid-enum-value = "{0}" is not a valid value for attribute {1}.
Valid values are:{2}.
+error.unknown-class = Unrecognized type {0} for attribute {1}.
Propchange:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/Messages.properties
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiBuildException.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiBuildException.java?view=auto&rev=157713
==============================================================================
---
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiBuildException.java
(added)
+++
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiBuildException.java
Tue Mar 15 23:14:32 2005
@@ -0,0 +1,23 @@
+package org.apache.beehive.netui.xdoclet;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Extension of ant's BuildException that does not print a stack trace. This
is used to
+ * signal ant that the build has failed from the doclet task, but without the
+ * XJavaDocTask superclass printing out a stacktrace, so that pageflow build
error messages
+ * will be easier to find.
+ */
+public class NetuiBuildException extends BuildException
+{
+
+ public NetuiBuildException()
+ {
+ super();
+ }
+
+ public void printStackTrace()
+ {
+ // no-op so we won't let XJavaDocTask print out a stack when the build
fails
+ }
+}
Propchange:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiBuildException.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiDocletTask.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiDocletTask.java?view=auto&rev=157713
==============================================================================
---
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiDocletTask.java
(added)
+++
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiDocletTask.java
Tue Mar 15 23:14:32 2005
@@ -0,0 +1,195 @@
+package org.apache.beehive.netui.xdoclet;
+
+import org.apache.beehive.netui.compiler.typesystem.util.SourcePosition;
+import org.apache.tools.ant.BuildException;
+import xdoclet.DocletTask;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Netui XDoclet task
+ *
+ * @ant.element name="netuidoclet" display-name="NetUI Task"
+ */
+public class NetuiDocletTask extends DocletTask
+{
+ private static HashMap _buildMessages = new HashMap(); // String
filename -> List messages
+
+ private static File _webappRoot = null;
+
+
+
+ /**
+ * @throws BuildException
+ *
+ */
+ protected void start() throws BuildException
+ {
+ try
+ {
+ assert _webappRoot != null; // should have been set in the ant
task
+ super.start();
+ }
+ finally
+ {
+ _webappRoot = null;
+
+ // list any warnings and errors
+ boolean overallError = false;
+ if ( _buildMessages != null )
+ {
+ Iterator i = _buildMessages.keySet().iterator();
+
+ while ( i.hasNext() )
+ {
+ String sourceFile = ( String ) i.next();
+ List messages = ( List ) _buildMessages.get( sourceFile );
+ int errorCount = 0;
+ int warningCount = 0;
+
+ for ( Iterator j = messages.iterator(); j.hasNext(); )
+ {
+ BuildMessage message = ( BuildMessage ) j.next();
+ System.err.println();
+ System.err.print( sourceFile );
+ System.err.print( ": " );
+
+ if ( message.getLine() > 0 )
+ {
+ String[] args = { Integer.valueOf(
message.getLine() ).toString() };
+ System.err.println(
XDocletCompilerUtils.getMessage( "compiler.line", args ) );
+ }
+
+ if ( message.isError() )
+ {
+ overallError = true;
+ ++errorCount;
+ }
+ else
+ {
+ System.err.print( XDocletCompilerUtils.getMessage(
"compiler.warning", null ) );
+ ++warningCount;
+ }
+
+ System.err.println( message.getMessage() );
+ }
+
+ System.err.println( XDocletCompilerUtils.getMessage(
"compiler.build.results",
+ new String[]{
Integer.valueOf( errorCount ).toString(),
+
Integer.valueOf( warningCount ).toString(),
+ sourceFile }
) );
+ }
+ }
+
+ _buildMessages = null;
+
+ if ( overallError )
+ {
+ System.err.println( XDocletCompilerUtils.getMessage(
"compiler.build.failed", null ) );
+ throw new NetuiBuildException();
+ }
+ }
+ }
+
+ public static void addError( String error, SourcePosition sourcePosition )
+ {
+ assert sourcePosition != null;
+ String sourceFilePath = sourcePosition.file().getPath();
+ int line = sourcePosition.line();
+ addError( error, sourceFilePath, line );
+ }
+
+ public static void addError( String error, String sourceFile, int line )
+ {
+ List messages = ( List ) _buildMessages.get( sourceFile );
+
+ if ( messages == null )
+ {
+ messages = new ArrayList();
+ _buildMessages.put( sourceFile, messages );
+ }
+
+ messages.add( new BuildMessage( error, line, true ) );
+ }
+
+ public static void addWarning( String warning, SourcePosition
sourcePosition )
+ {
+ assert sourcePosition != null;
+ String sourceFilePath = sourcePosition.file().getPath();
+ int line = sourcePosition.line();
+ addWarning( warning, sourceFilePath, line );
+ }
+
+ public static void addWarning( String warning, String sourceFile, int line
)
+ {
+ List messages = ( List ) _buildMessages.get( sourceFile );
+
+ if ( messages == null )
+ {
+ messages = new ArrayList();
+ _buildMessages.put( sourceFile, messages );
+ }
+
+ messages.add( new BuildMessage( warning, line, false ) );
+ }
+
+ private static class BuildMessage
+ {
+ private String _message;
+ private boolean _error;
+ private int _line;
+
+ public BuildMessage( String message, int line, boolean error )
+ {
+ _message = message;
+ _error = error;
+ _line = line;
+ }
+
+ public final String getMessage()
+ {
+ return _message;
+ }
+
+ public final boolean isError()
+ {
+ return _error;
+ }
+
+ public final int getLine()
+ {
+ return _line;
+ }
+ }
+
+ /**
+ * Called by superclass before start() is called
+ *
+ * @throws BuildException Describe the exception
+ */
+ protected void validateOptions() throws BuildException
+ {
+ // we don't support the destdir attribute; so if it's null, just fake
it so super won't
+ // fail validation
+ if ( getDestDir() == null )
+ {
+ setDestDir( new File( "bogus" ) );
+ }
+ super.validateOptions();
+ }
+
+ public void setWebappRoot( File file )
+ {
+ _webappRoot = file;
+ }
+
+ public static File getWebappRoot()
+ {
+ return _webappRoot;
+ }
+
+}
Propchange:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiDocletTask.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiSubTask.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiSubTask.java?view=auto&rev=157713
==============================================================================
---
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiSubTask.java
(added)
+++
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiSubTask.java
Tue Mar 15 23:14:32 2005
@@ -0,0 +1,1349 @@
+package org.apache.beehive.netui.xdoclet;
+
+import org.apache.beehive.netui.compiler.processor.PageFlowAnnotationProcessor;
+import
org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationTypeDeclaration;
+import
org.apache.beehive.netui.compiler.typesystem.env.AnnotationProcessorEnvironment;
+import
org.apache.beehive.netui.compiler.xdoclet.typesystem.impl.declaration.DeclarationImpl;
+import
org.apache.beehive.netui.compiler.xdoclet.typesystem.impl.env.AnnotationProcessorEnvironmentImpl;
+import xdoclet.DocletContext;
+import xdoclet.SubTask;
+import xdoclet.XDocletException;
+import xjavadoc.SourceClass;
+import xjavadoc.XJavaDoc;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+
+/**
+ * XJavaDoc subtask to run through a set of pageflows in a webapp and generate
struts-config files for them.
+ * This uses a lot of the generic compiler model objects and xml generation
code fom com.bea.netui.pageflow.model.
+ *
+ * @ant.element display-name="Netui" name="netui"
parent="org.apache.beehive.netui.xdoclet.NetuiDocletTask"
+ */
+public class NetuiSubTask extends SubTask
+{
+ private SourceClass _currentSourceClass;
+
+ /**
+ * Main entry point for xjavadoc tasks. Here we iterate through all the
classes found by
+ * xjavadoc and process the ones that we recognize as pageflows.
+ *
+ * @throws XDocletException
+ */
+ public void execute() throws XDocletException
+ {
+ /*
+ if ( DocletContext.getInstance().isVerbose() )
+ System.out.println( CompilerUtil.genMessage(
"compiler.info.gen.location",
+ new String[] {getDestDir().getPath()} ) );
+ */
+ Collection classes = getXJavaDoc().getSourceClasses();
+
+ /*
+ // issue a warning if xjavadoc didn't find any classes at all
+ if ( classes.size() == 0 )
+ {
+ System.out.println( CompilerUtil.genMessage( "no.classes.found" )
);
+ return;
+ }
+
+ _pageflowCount = 0;
+ */
+
+ Iterator iter = classes.iterator();
+ while ( iter.hasNext() )
+ {
+ SourceClass sourceClass = ( SourceClass ) iter.next();
+ AnnotationProcessorEnvironment env =
AnnotationProcessorEnvironmentImpl.get( getContext(), this, sourceClass );
+ AnnotationTypeDeclaration[] decls =
DeclarationImpl.getAllAnnotations(); // TODO: filter appropriately
+
+ PageFlowAnnotationProcessor pfap = new
PageFlowAnnotationProcessor( decls, env );
+
+ try
+ {
+ _currentSourceClass = sourceClass;
+ pfap.process();
+ }
+ finally
+ {
+ _currentSourceClass = null;
+ }
+ /*
+
+ for ( Iterator i = c.getMethods().iterator(); i.hasNext(); )
+ {
+ XMethod method = ( XMethod ) i.next();
+ XDoc doc = method.getDoc();
+ System.err.println( " method " + method.getName() + ": " +
method.getReturnType().getType().getName() + " : " + method.getModifiers() );
+ List tags = doc.getTags();
+ for ( Iterator j = tags.iterator(); j.hasNext(); )
+ {
+ XTag tag = ( XTag ) j.next();
+ System.err.println( " " + tag.getName() + ": " +
tag.getValue() );
+
+ Collection attrs = tag.getAttributeNames();
+ for ( Iterator k = attrs.iterator(); k.hasNext(); )
+ {
+ String attrName = ( String ) k.next();
+ System.err.println( " " + attrName + ": " +
tag.getAttributeValue( attrName ) );
+ }
+ }
+ }
+ */
+
+ /*
+ if ( c.isA( PAGEFLOW_CLASS_NAME, true ) )
+ processJpf( c, false );
+ else if ( c.isA( GLOBALAPP_BASE_CLASS_NAME, true ) )
+ processJpf( c, true );
+ else
+ {
+ // workaround for needing to import explicit types - if the
pageflow package
+ // was imported, and we extend the right class name, go for it.
+ List pkgs = c.getImportedPackages();
+ Iterator pkgIter = pkgs.iterator();
+ boolean found = false;
+ while ( pkgIter.hasNext() )
+ {
+ XPackage pkg = (XPackage) pkgIter.next();
+ if ( pkg.getName().equals( PAGEFLOW_PACKAGE ) )
+ {
+ found = true;
+ break;
+ }
+ }
+
+ boolean isJpf = false;
+ if ( found )
+ {
+ XClass superClass = c.getSuperclass();
+ if ( superClass.getName().equals(
PAGEFLOW_SHORT_CLASS_NAME ) )
+ {
+ isJpf = true;
+ processJpf( c, false );
+ }
+ else if ( superClass.getName().equals(
GLOBALAPP_SHORT_CLASS_NAME ) )
+ {
+ isJpf = true;
+ processJpf( c, true );
+ }
+ }
+
+ if ( !isJpf && !c.isInner() )
+ {
+ // this is not a pageflow class, make sure it did not come
from a .jpf file
+ try
+ {
+ File sourceFile = new File(
((SourceClass)c).getFile().getPath() );
+ File f = XDocletStrutsApp.getOriginalJpfSourceFile(
sourceFile.getName(), c, false );
+ if ( f.exists() )
+ {
+ CompilerUtil.error( f.toString(),
CompilerUtil.genMessage( "pageflow.error.does-not-extend-base", new String[]
{PAGEFLOW_CLASS_NAME} ) );
+ }
+ f = XDocletStrutsApp.getOriginalJpfSourceFile(
sourceFile.getName(), c, true );
+ if ( f.exists() )
+ {
+ CompilerUtil.error( f.toString(),
CompilerUtil.genMessage( "pageflow.error.does-not-extend-base", new String[]
{GLOBALAPP_BASE_CLASS_NAME} ) );
+ }
+ }
+ catch ( NoWebInfDirectoryException e )
+ {
+ // ignore
+ }
+ }
+ }
+ */
+ }
+ }
+
+ /*
+ protected void processJpf( XClass jpfClass, boolean global )
+ throws XDocletException
+ {
+ _pageflowCount++;
+ try
+ {
+ File webappRoot = XDocletStrutsApp.getWebappRootFromJpf();
+ File strutsConfigDir = new File( webappRoot + STRUTS_OUTPUT_DIR );
+ if ( !strutsConfigDir.exists() )
+ {
+ strutsConfigDir.mkdirs();
+ }
+
+ _isGlobal = global;
+ StringBuffer configFileName = new StringBuffer();
+ if ( _isGlobal )
+ {
+ configFileName.append( STRUTS_CONFIG_PREFIX )
+ .append( GLOBALAPP_MODULE_NAME )
+ .append( STRUTS_CONFIG_EXTENSION );
+ }
+ else
+ {
+ XPackage pkg = jpfClass.getContainingPackage();
+ if ( !pkg.isDefaultPackage() )
+ {
+ configFileName.append( STRUTS_CONFIG_PREFIX );
+ configFileName.append( pkg.getName().replace( '.', '-' ) );
+ configFileName.append( STRUTS_CONFIG_EXTENSION );
+ }
+ else
+ {
+ configFileName.append( ROOT_STRUTS_CONFIG );
+ }
+ }
+ File strutsConfigFile = new File( strutsConfigDir,
configFileName.toString() );
+
+ // note: webapp root is not used in this situation
+ _strutsApp = new XDocletStrutsApp(
jpfClass.getContainingPackage().getName(), strutsConfigFile,
+ webappRoot.getPath(), jpfClass, global );
+ _strutsApp.setJpfSourceFile( new File(
((SourceClass)jpfClass).getFile().getPath() ) );
+
+ if ( DocletContext.getInstance().isVerbose() )
+ {
+ System.out.println( CompilerUtil.genMessage(
"compiler.info.gen.file",
+ new String[] { configFileName.toString(),
jpfClass.getQualifiedName() } ) );
+ System.out.println( CompilerUtil.genMessage(
"compiler.info.original.jpf",
+ new String[]
{_strutsApp.getOriginalJpfSourceFile().getPath()} ) );
+ }
+
+ File originalJpf = _strutsApp.getOriginalJpfSourceFile();
+ File jpfParentDir = originalJpf.getParentFile();
+ String jpfName = originalJpf.getName();
+
+ if ( global )
+ {
+ // if global, make sure the file name is correct and it's in
the right place
+ if ( !jpfName.equals( GLOBALAPP_FILENAME ) )
+ CompilerUtil.error(
"pageflow.error.global-app-wrong-name", (String[])null );
+
+ XPackage pkg = jpfClass.getContainingPackage();
+ String pkgName = pkg.getName();
+ if ( !pkgName.equals( GLOBALAPP_PACKAGE ) )
+ CompilerUtil.error( "pageflow.error.wrong-package", new
String[] {GLOBALAPP_PACKAGE} );
+
+ String fullGlobalPath = _strutsApp.getWebappRootPath() +
File.separatorChar + GLOBALAPP_SOURCE_DIR;
+ String myPath = jpfParentDir.getPath();
+ if ( !myPath.equals( fullGlobalPath ) || !originalJpf.exists()
)
+ CompilerUtil.error( "pageflow.error.global-app-wrong-dir",
+ new String[] { GLOBALAPP_FILENAME,
GLOBALAPP_SOURCE_DIR } );
+ }
+ else
+ {
+ //otherwise make sure it's a jpf file
+ if ( !jpfName.endsWith( PAGEFLOW_EXTENSION ) ||
!originalJpf.exists() )
+ CompilerUtil.error( "compiler.error.wrong.extension",
(String[])null );
+
+ // then check for other pageflows in the package
+ String[] otherFiles = jpfParentDir.list();
+ List otherJpfs = new ArrayList();
+ for ( int i=0; i<otherFiles.length; i++ )
+ {
+ if ( otherFiles[i].endsWith( PAGEFLOW_EXTENSION ) &&
!otherFiles[i].equals( jpfName ) )
+ otherJpfs.add( otherFiles[i] );
+ }
+ if ( otherJpfs.size() == 1 )
+ CompilerUtil.error(
"pageflow.error.overlapping-pageflows1",
+ new String[] { (String)otherJpfs.get(0) } );
+ else if ( otherJpfs.size() == 2 )
+ CompilerUtil.error(
"pageflow.error.overlapping-pageflows2",
+ new String[] { (String)otherJpfs.get(0),
(String)otherJpfs.get(1) } );
+ else if ( otherJpfs.size() == 3 )
+ CompilerUtil.error(
"pageflow.error.overlapping-pageflows3",
+ new String[] { (String)otherJpfs.get(0),
(String)otherJpfs.get(1), (String)otherJpfs.get(2) } );
+ else if ( otherJpfs.size() > 3 )
+ CompilerUtil.error( "pageflow.error.overlapping-pageflows",
+ new String[] { (String)otherJpfs.get(0),
(String)otherJpfs.get(1), (String)otherJpfs.get(2) } );
+ }
+
+ // we are catching and ignoring NetuiDocletException so that the
compiler will
+ // continue to process and accumulate errors.
+ try
+ { checkTagPlacement( jpfClass ); }
+ catch ( NetuiDocletException e ) { }
+
+ try
+ { processController( jpfClass ); }
+ catch ( NetuiDocletException e ) { }
+
+ try
+ { processFormBeans( jpfClass ); }
+ catch ( NetuiDocletException e ) { }
+
+ try
+ { processActions( jpfClass ); }
+ catch ( NetuiDocletException e ) { }
+
+ // check for an explicit alternate location for the generated file
+ // for root or global controller only
+ if ( global || jpfClass.getContainingPackage().isDefaultPackage() )
+ {
+ String alternateLocation = getAlternateLocation(
_strutsApp.getWebappRootPath(),
+ _strutsApp.getStrutsConfigFile() );
+ if ( alternateLocation != null )
+ {
+ if ( DocletContext.getInstance().isVerbose() )
+ {
+ System.out.println( "Using alternate config file
location: " + alternateLocation );
+ }
+ _strutsApp.setStrutsConfigFile( new File(
_strutsApp.getWebappRootPath() + alternateLocation ) );
+ }
+ }
+
+ // write out the config file if we haven't gotten any errors
+ if ( !NetuiDocletTask.hasErrors(
_strutsApp.getOriginalJpfSourceFile().toString() ) )
+ _strutsApp.writeToSource();
+ }
+ catch ( NetuiDocletException e )
+ {
+ // ignore, an error was added to the task
+ }
+ catch ( NoWebInfDirectoryException e )
+ {
+ CompilerUtil.error( e.getMessage() );
+ }
+ catch ( Exception e )
+ {
+ throw new XDocletException(e, e.getMessage() );
+ }
+ finally
+ {
+ _strutsApp = null;
+ _exceptionHandlers = null;
+ _isGlobal = false;
+ }
+ }
+
+ public void checkTagPlacement(XClass jpfClass)
+ throws XDocletException
+ {
+ checkTagPlacement( jpfClass.getDoc(), TAG_NAMESPACE,
PageflowTags.VALID_CLASS_TAGS );
+
+ List fields = jpfClass.getFields();
+ Iterator fieldIter = fields.iterator();
+ while ( fieldIter.hasNext() )
+ {
+ XField field = (XField) fieldIter.next();
+ checkTagPlacement( field.getDoc(), TAG_NAMESPACE,
PageflowTags.VALID_FIELD_TAGS );
+ }
+
+ List methods = jpfClass.getMethods();
+ Iterator methodIter = methods.iterator();
+ while ( methodIter.hasNext() )
+ {
+ XMethod method = (XMethod) methodIter.next();
+ XDoc doc = method.getDoc();
+ checkTagPlacement( doc, TAG_NAMESPACE,
PageflowTags.VALID_METHOD_TAGS );
+
+ // make sure any methods with a forward tag are really actions or
exception handlers
+ XTag fwdTag = doc.getTag( FORWARD_TAG_FULL_NAME );
+ if ( fwdTag != null )
+ {
+ XTag actionTag = doc.getTag( ACTION_TAG_FULL_NAME );
+ if ( actionTag == null )
+ {
+ XTag exTag = doc.getTag( EXCEPTION_HANDLER_TAG_FULL_NAME );
+ if ( exTag == null )
+ {
+ CompilerUtil.error( fwdTag,
"pageflow.error.inappropriate-forward-tag",
+ new String[] { FORWARD_TAG_FULL_NAME,
ACTION_TAG_FULL_NAME,
+ EXCEPTION_HANDLER_TAG_FULL_NAME
} );
+ }
+ }
+ }
+ }
+ }
+
+ private void checkTagPlacement( XDoc doc, String namespace, String[] valid
)
+ throws XDocletException
+ {
+ // XTags are namespaced with a '.', not a ':'
+ String nsDot = namespace + ".";
+ int nsDotLength = nsDot.length();
+ List validList = Arrays.asList( valid );
+
+ List allTags = doc.getTags();
+ Iterator iter = allTags.iterator();
+ while( iter.hasNext() )
+ {
+ XTag tag = (XTag) iter.next();
+ if ( tag.getName().startsWith( nsDot ) )
+ {
+ String tagName = tag.getName().substring( nsDotLength );
+ if ( !validList.contains( tagName ) )
+ {
+ try
+ { CompilerUtil.error( tag,
"compiler.error.invalid.tag.location", new String[] {tag.getName()} ); }
+ catch ( NetuiDocletException e )
+ { } // we want to continue here
+ }
+ }
+ }
+ }
+
+ public void processController( XClass jpfClass )
+ throws XDocletException
+ {
+ XTag jpfTag = jpfClass.getDoc().getTag( CONTROLLER_TAG_FULL_NAME );
+ if ( jpfTag != null )
+ {
+ // this tag isn't required, but validate it if it's there
+ PageflowTags.CONTROLLER_TAG_GRAMMAR.validateTag( jpfTag, jpfClass
);
+ _strutsApp.setStrutsMerge( jpfTag.getAttributeValue(
STRUTSMERGE_ATTR ) );
+
+ // if nested, check for a fwd with return-action
+ if ( "true".equals( jpfTag.getAttributeValue( NESTED_ATTR ) ) )
+ {
+ _strutsApp.setNestedPageFlow( true );
+
+ List fwdTags = jpfClass.getMethodTags( FORWARD_TAG_FULL_NAME,
false );
+ boolean foundReturnAction = atLeastOneTagHasAttribute(
fwdTags, RETURN_ACTION_ATTR );
+ if ( !foundReturnAction )
+ {
+ // check the global forwards if we still didn't find one
+ fwdTags = jpfClass.getDoc().getTags( FORWARD_TAG_FULL_NAME
);
+ foundReturnAction = atLeastOneTagHasAttribute( fwdTags,
RETURN_ACTION_ATTR );
+ }
+ if ( !foundReturnAction )
+ {
+ // last chance, check for a validation-error-forward
+ fwdTags = jpfClass.getMethodTags(
VALIDATION_ERROR_FORWARD_TAG_FULL_NAME, false );
+ foundReturnAction = atLeastOneTagHasAttribute( fwdTags,
RETURN_ACTION_ATTR );
+ }
+ if ( !foundReturnAction )
+ CompilerUtil.error( jpfTag,
"pageflow.error.no-return-action", null );
+ }
+ }
+
+ // check for a begin action
+ if ( !_isGlobal )
+ {
+ boolean foundBegin = false;
+ List methods = jpfClass.getMethods();
+ Iterator iter = methods.iterator();
+ while ( !foundBegin && iter.hasNext() )
+ {
+ XMethod method = (XMethod) iter.next();
+ if ( method.getName().equals( BEGIN_ACTION_NAME ) )
+ {
+ XTag tag = method.getDoc().getTag(ACTION_TAG_FULL_NAME);
+ if ( tag != null )
+ foundBegin = true;
+ }
+ }
+ if ( !foundBegin )
+ CompilerUtil.error( jpfTag, "pageflow.error.no-begin-action",
null );
+ }
+
+ // check for invalid tags
+ List fields = jpfClass.getFields();
+ Iterator fieldIter = fields.iterator();
+ while ( fieldIter.hasNext() )
+ {
+ XField field = (XField) fieldIter.next();
+ XDoc doc = field.getDoc();
+ for ( int i=0; i<INVALID_FIELD_TAGS.length; i++ )
+ {
+ if ( doc.hasTag( INVALID_FIELD_TAGS[i] ) )
+ {
+ XTag badTag = doc.getTag( INVALID_FIELD_TAGS[i] );
+ CompilerUtil.error( badTag,
"compiler.error.portable.notsupported",
+ new String[] {INVALID_FIELD_TAGS[i]} );
+ }
+ }
+
+ // also check for non-transient/static/serializable fields
+ if ( !field.isTransient() && !field.isStatic() &&
+ !field.getType().isImplementingInterface(
SERIALIZABLE_INTERFACE_NAME, true ) )
+ {
+ CompilerUtil.warning( field,
"pageflow.warning.nonserializable-member-data", null );
+ }
+ }
+
+
+ // process the message resource tags
+ List tags = jpfClass.getDoc().getTags( MESSAGE_RESOURCES_TAG_FULL_NAME
);
+ Iterator tagIter = tags.iterator();
+ while ( tagIter.hasNext() )
+ {
+ XTag tag = (XTag) tagIter.next();
+ PageflowTags.MSG_RES_TAG_GRAMMAR.validateTag( tag, jpfClass );
+ String resources = tag.getAttributeValue( RESOURCES_ATTR );
+ String key = tag.getAttributeValue( KEY_ATTR );
+ MessageResourcesModel mr = new MessageResourcesModel( resources,
_strutsApp );
+ mr.setKey( key );
+ mr.setReturnNull( false );
+ _strutsApp.addMessageResources( mr );
+ }
+
+ // add global forwards and catches
+ checkForwardConflicts( jpfClass, jpfClass );
+ addForwards( jpfClass, _strutsApp, jpfClass );
+ addCatches( jpfClass, _strutsApp, jpfClass );
+ }
+
+ public void processActions( XClass jpfClass )
+ throws XDocletException
+ {
+ List methods = jpfClass.getMethods();
+ Iterator methodIter = methods.iterator();
+ while ( methodIter.hasNext() )
+ {
+ XMethod method = (XMethod) methodIter.next();
+ XTag actionTag = method.getDoc().getTag( ACTION_TAG_FULL_NAME );
+ if ( actionTag != null )
+ {
+ PageflowTags.ACTION_TAG_GRAMMAR.validateTag( actionTag,
jpfClass );
+ List params = method.getParameters();
+ FormBeanModel formBean = null;
+ XClass paramType = null;
+ if ( params.size() > 0 )
+ {
+ XParameter param = (XParameter) params.get(0);
+ paramType = param.getType();
+ boolean ok = true;
+ if ( params.size() > 1 )
+ ok = false;
+ if ( ok )
+ {
+ if ( !paramType.isA( FORM_CLASS_NAME, true ) )
+ ok = false;
+ }
+ if ( !ok )
+ CompilerUtil.error( actionTag,
"pageflow.error.action-method-wrong-arg",
+ new String[] {FORM_CLASS_NAME} );
+
+ // if this action takes a form we haven't seen yet, add it
to the map
+ String formType = CompilerUtil.getQualifiedName(
param.getType() );
+ formBean = _strutsApp.getFormBeanByType( formType );
+ if ( formBean == null )
+ {
+ formBean = addFormBean( param.getType() );
+ }
+
+ }
+
+ // check the return type
+ XClass returnClass = method.getReturnType().getType();
+ if ( !returnClass.isA( FORWARD_CLASS_NAME, true ) )
+ CompilerUtil.error( actionTag,
"pageflow.error.method-wrong-return-type",
+ new String[] {FORWARD_CLASS_NAME} );
+
+ ActionModel action = new ActionModel( "/" + method.getName(),
_strutsApp );
+ action.setType( jpfClass.getQualifiedName() );
+ if ( formBean != null )
+ action.setFormBeanName( formBean.getName() );
+ action.setRoles( getActionRoles( actionTag, jpfClass ) );
+ action.setScope( actionTag.getAttributeValue( "scope" ) ); //
TODO: constant?
+
+ Boolean readonly = null;
+ String readonlyVal = actionTag.getAttributeValue(
READONLY_ATTR );
+ if ( readonlyVal != null )
+ {
+ readonly = new Boolean( readonlyVal );
+ }
+ else
+ {
+ readonlyVal = getControllerAttribute( jpfClass,
READONLY_ATTR );
+ if ( readonlyVal != null && readonlyVal.equalsIgnoreCase(
"true" ) )
+ {
+ readonly = new Boolean( true );
+ }
+ }
+ action.setReadonly( readonly != null ? readonly.booleanValue()
: false );
+
+ String formMember = actionTag.getAttributeValue( FORM_ATTR );
+ if ( formMember != null )
+ {
+ // make sure the action is not readonly
+ if ( readonly != null && readonly.booleanValue() )
+ {
+ CompilerUtil.error( actionTag,
"pageflow.error.readonly-writable-field-member",
+ new String[] { FORM_ATTR } );
+ }
+
+ // need to get the fully qualified type of the field
+ XField formField = jpfClass.getField( formMember );
+ if ( formField == null )
+ CompilerUtil.error( actionTag,
"pageflow.error.unresolved-field",
+ new String[] { formMember } );
+ XClass formClass = formField.getType();
+ if ( !formClass.isA( FORM_CLASS_NAME, true ) )
+ CompilerUtil.error( actionTag,
"pageflow.error.wrong-field-type",
+ new String[] { formMember, FORM_CLASS_NAME } );
+
+ // if we have a valid form attribute, make sure we take a
parameter of the same type
+ if ( formBean == null || paramType == null ||
+ !paramType.isA( formClass.getQualifiedName(), true
) )
+ {
+ CompilerUtil.error( actionTag,
"pageflow.error.action-mismatched-form",
+ new String[] { formMember, formClass.getName()
} );
+ }
+
+ action.setFormMember( formMember);
+ }
+
+ Boolean loginRequired = null;
+ String loginRequiredVal = actionTag.getAttributeValue(
LOGIN_REQUIRED_ATTR );
+ if ( loginRequiredVal != null )
+ {
+ loginRequired = new Boolean( loginRequiredVal );
+ }
+ else
+ {
+ loginRequiredVal = getControllerAttribute( jpfClass,
LOGIN_REQUIRED_ATTR );
+ if ( loginRequiredVal != null &&
loginRequiredVal.equalsIgnoreCase( "true" ) )
+ {
+ loginRequired = new Boolean( true );
+ }
+ }
+ action.setLoginRequired( loginRequired != null ?
loginRequired.booleanValue() : false );
+
+ checkForwardConflicts( method, jpfClass );
+ addForwards( method, action, jpfClass );
+ addCatches( method, action, jpfClass );
+
+ // if we have a validation-error-page see if we need to make a
new forward for it
+ String validationErrorPage = actionTag.getAttributeValue(
VALIDATION_ERROR_PAGE_ATTR );
+ if ( validationErrorPage != null )
+ {
+ String inputFwd = null;
+ List fwdTags = method.getDoc().getTags(
FORWARD_TAG_FULL_NAME );
+ Iterator fwdTagIter = fwdTags.iterator();
+ boolean found = false;
+ while ( !found && fwdTagIter.hasNext() )
+ {
+ XTag tag = (XTag) fwdTagIter.next();
+ String fwdPath = tag.getAttributeValue( PATH_ATTR );
+ if ( fwdPath != null && fwdPath.equals(
validationErrorPage ) )
+ {
+ inputFwd = tag.getAttributeValue( NAME_ATTR );
+ found = true;
+ }
+ }
+
+ if ( !found )
+ {
+ inputFwd = VALIDATION_ERROR_PAGE_FWD_NAME;
+ ForwardModel forward = new ForwardModel( inputFwd,
+ getValidPath(validationErrorPage), _strutsApp
);
+ warnIfPathNotFound(actionTag, validationErrorPage);
+ action.addForward( forward );
+ }
+
+ action.setInput( inputFwd );
+ }
+
+ // add a validation-error-forward if there is one, and make
sure there is only one
+ XTag errorFwd = method.getDoc().getTag(
VALIDATION_ERROR_FORWARD_TAG_FULL_NAME );
+ if ( errorFwd != null )
+ {
+
PageflowTags.VALIDATION_ERROR_FORWARD_TAG_GRAMMAR.validateTag( errorFwd,
jpfClass );
+
+ // also check for other regular forwards with the same name
+ String name = errorFwd.getAttributeValue( NAME_ATTR );
+ List otherFwds = method.getDoc().getTags(
FORWARD_TAG_FULL_NAME );
+ Iterator iter = otherFwds.iterator();
+ while ( iter.hasNext() )
+ {
+ XTag otherFwd = (XTag) iter.next();
+ String otherName = otherFwd.getAttributeValue(
NAME_ATTR );
+ if ( otherName != null && otherName.equals( name ) )
+ CompilerUtil.error( errorFwd,
"compiler.error.duplicate.errorFwd.fwd",
+ new String[] {name} );
+ }
+
+ List fwdList = new ArrayList();
+ fwdList.add( errorFwd );
+ addForwards( method, action, jpfClass, fwdList, null, null
);
+ action.setInput( name );
+ }
+
+ _strutsApp.addActionMapping( action );
+ }
+ }
+ }
+
+ protected List addForwards( XProgramElement xpe, ForwardContainer
container, XClass jpfClass )
+ throws XDocletException
+ {
+ XDoc doc = xpe.getDoc();
+
+ // get explicit forward tags for this element
+ List forwardTags = doc.getTags( FORWARD_TAG_FULL_NAME );
+ List otherForwards = addForwards( xpe, container, jpfClass,
forwardTags, null, null );
+
+ // get forwards from exception-handler methods referenced in jpf:catch
tags
+ forwardTags = new ArrayList();
+ List exTags = doc.getTags( CATCH_TAG_FULL_NAME );
+ Map handlers = getExceptionHandlers( jpfClass );
+ Iterator exIter = exTags.iterator();
+ while ( exIter.hasNext() )
+ {
+ XTag exTag = (XTag) exIter.next();
+ String methodName = exTag.getAttributeValue( METHOD_ATTR );
+ if ( methodName != null )
+ {
+ XMethod handler = (XMethod) handlers.get( methodName );
+ if ( handler == null )
+ CompilerUtil.error( exTag,
"pageflow.error.unresolved-exception-handler",
+ new String[] { methodName } );
+
+ List handlerFwdTags = handler.getDoc().getTags(
FORWARD_TAG_FULL_NAME );
+ addForwards( xpe, container, jpfClass, handlerFwdTags,
handler.getName(), otherForwards );
+ }
+ }
+
+ return otherForwards;
+ }
+
+ protected List addForwards( XProgramElement xpe, ForwardContainer
container,
+ XClass jpfClass, List forwardTags, String
handler, List currentForwards )
+ throws XDocletException
+ {
+ if ( currentForwards == null )
+ currentForwards = new ArrayList();
+
+ // see if we're in a nested pageflow
+ XTag jpfTag = jpfClass.getDoc().getTag( CONTROLLER_TAG_FULL_NAME );
+ boolean nested = false;
+ if ( jpfTag != null )
+ {
+ String nestedValue = jpfTag.getAttributeValue( NESTED_ATTR );
+ nested = new Boolean( nestedValue ).booleanValue();
+ }
+
+ // iterate over all the forwards and process them
+ Iterator fwdIter = forwardTags.iterator();
+ while ( fwdIter.hasNext() )
+ {
+ XTag fwdTag = (XTag)fwdIter.next();
+ PageflowTags.FORWARD_TAG_GRAMMAR.validateTag( fwdTag, jpfClass );
+ String name = fwdTag.getAttributeValue( NAME_ATTR );
+
+ String path = fwdTag.getAttributeValue( PATH_ATTR );
+ warnIfPathNotFound( fwdTag, path );
+
+ ForwardModel forward = new ForwardModel( name, getValidPath(path),
_strutsApp );
+
+ if ( handler != null )
+ {
+ forward.setComment( "forward \"" + forward.getName() + "\"" +
" from exception-handler " + handler ); // @TODOsp1 I18N the comment
+ }
+
+ String redirect = fwdTag.getAttributeValue( REDIRECT_ATTR );
+ if ( redirect == null )
+ forward.setRedirect( false, false );
+ else
+ forward.setRedirect( new Boolean( redirect ).booleanValue(),
true );
+
+ forward.setContextRelative( path != null && path.startsWith( "/" )
);
+ String returnTo = fwdTag.getAttributeValue( RETURN_TO_ATTR );
+ if ( returnTo != null )
+ {
+ if ( returnTo.equals( RETURN_TO_PAGE_LEGACY_STR ) ||
+ returnTo.equals( RETURN_TO_CURRENT_PAGE_STR ) ||
+ returnTo.equals( RETURN_TO_PREVIOUS_PAGE_STR ) )
+ forward.setReturnToPage( true );
+ else if ( returnTo.equals( RETURN_TO_ACTION_LEGACY_STR ) ||
+ returnTo.equals( RETURN_TO_PREVIOUS_ACTION_STR ) )
+ forward.setReturnToAction( true );
+ forward.setPath( returnTo );
+ }
+ String returnAction = fwdTag.getAttributeValue( RETURN_ACTION_ATTR
);
+ if ( returnAction != null )
+ {
+ // make sure we're in a nested pageflow
+ if ( !nested )
+ {
+ CompilerUtil.error( fwdTag,
"pageflow.error.only-valid-in-nested",
+ new String[] { RETURN_ACTION_ATTR } );
+ }
+
+ // make sure this is a valid java identifier
+ if ( !isJavaIdentifier( returnAction ) )
+ CompilerUtil.error( fwdTag,
"pageflow.error.attr-java-identifier",
+ new String[] { RETURN_ACTION_ATTR } );
+
+ forward.setIsNestedReturn( true );
+ forward.setPath( returnAction );
+
+ // only check return form member/type for a return action
+ String returnFormType = fwdTag.getAttributeValue(
RETURN_FORM_TYPE_ATTR );
+ if ( returnFormType != null )
+ {
+ XClass q = jpfClass.qualify( returnFormType );
+ if ( q == null || q.getClass().getName().endsWith(
"UnknownClass" ) )
+ CompilerUtil.error( fwdTag,
"pageflow.error.unresolved-type", new String[] {returnFormType} );
+ if ( !q.isA( FORM_CLASS_NAME, true ) )
+ CompilerUtil.error( fwdTag,
"compiler.error.wrong.type", new String[] {returnFormType, FORM_CLASS_NAME} );
+ forward.setReturnFormType( CompilerUtil.getQualifiedName(
q ) );
+ }
+
+ String returnFormMember = fwdTag.getAttributeValue(
RETURN_FORM_ATTR );
+ if ( returnFormMember != null )
+ {
+ // need to get the fully qualified type of the field
+ XField returnFormField = jpfClass.getField(
returnFormMember );
+ if ( returnFormField == null )
+ CompilerUtil.error( fwdTag,
"pageflow.error.unresolved-field",
+ new String[] { returnFormMember } );
+ XClass returnFormClass = returnFormField.getType();
+ if ( !returnFormClass.isA( FORM_CLASS_NAME, true ) )
+ CompilerUtil.error( fwdTag,
"pageflow.error.wrong-field-type",
+ new String[] { returnFormMember,
FORM_CLASS_NAME } );
+ String returnFormClassName =
CompilerUtil.getQualifiedName( returnFormClass );
+ forward.setReturnFormType( returnFormClassName );
+ forward.setReturnFormMember( returnFormMember );
+ }
+ }
+
+ container.addForward( forward );
+ currentForwards.add( fwdTag );
+ }
+
+ return currentForwards;
+ }
+
+ public void addCatches( XProgramElement xpe, ExceptionContainer container,
XClass jpfClass )
+ throws XDocletException
+ {
+ XDoc doc = xpe.getDoc();
+ List exTags = doc.getTags( CATCH_TAG_FULL_NAME );
+ Map handlers = getExceptionHandlers( jpfClass );
+ Iterator exIter = exTags.iterator();
+ while ( exIter.hasNext() )
+ {
+ XTag exTag = (XTag) exIter.next();
+ PageflowTags.CATCH_TAG_GRAMMAR.validateTag( exTag, jpfClass );
+ String typeAttr = exTag.getAttributeValue( TYPE_ATTR );
+
+ // xjavadoc sometimes does not understand '$' to denote inner
classes, '.' is safer
+ typeAttr = typeAttr.replace( '$', '.' );
+ XClass q = jpfClass.qualify( typeAttr );
+
+ if ( q == null || q.getClass().getName().endsWith( "UnknownClass"
) )
+ {
+ // sometimes an inner class will not resolve correctly without
the package name,
+ // so try again, assuming the exception is in the same package
as the jpf
+ XPackage pkg = jpfClass.getContainingPackage();
+ q = jpfClass.qualify( pkg.getName() + "." + typeAttr );
+
+ if ( q == null || q.getClass().getName().endsWith(
"UnknownClass" ) )
+ CompilerUtil.error( exTag,
"pageflow.error.unresolved-type", new String[] {typeAttr} );
+ }
+ if ( !q.isA( THROWABLE_CLASS_NAME, true ) )
+ CompilerUtil.error( exTag, "compiler.error.wrong.type", new
String[] {typeAttr, THROWABLE_CLASS_NAME} );
+ String type = CompilerUtil.getQualifiedName( q );
+
+ String pathAttr = exTag.getAttributeValue( PATH_ATTR );
+ warnIfPathNotFound( exTag, pathAttr );
+ String path = null;
+ if ( pathAttr != null )
+ path = getValidPath( pathAttr );
+ String handler = exTag.getAttributeValue( METHOD_ATTR );
+ if ( handler != null )
+ {
+ // check that the method handles the right exception type
+ XMethod method = (XMethod) handlers.get( handler );
+ if ( method == null )
+ CompilerUtil.error( exTag,
"pageflow.error.unresolved-exception-handler",
+ new String[] { handler } );
+ XParameter firstParam =
(XParameter)method.getParameters().get(0);
+ if ( !q.isA( firstParam.getType().getQualifiedName() ) )
+ CompilerUtil.error( exTag,
"pageflow.error.incompatible-exception-handler",
+ new String[] { handler, q.getQualifiedName() } );
+ }
+ String key = exTag.getAttributeValue( MESSAGE_KEY_ATTR );
+ String message = exTag.getAttributeValue( MESSAGE_ATTR );
+
+ ExceptionModel ex = new ExceptionModel( type, path, handler,
message, key, _strutsApp );
+ container.addException( ex );
+ }
+ }
+
+ protected Map getExceptionHandlers( XClass jpfClass )
+ throws XDocletException
+ {
+ if ( _exceptionHandlers == null )
+ {
+ _exceptionHandlers = new HashMap();
+ List methods = jpfClass.getMethods();
+ Iterator iter = methods.iterator();
+ while ( iter.hasNext() )
+ {
+ XMethod method = (XMethod) iter.next();
+ XTag exTag = method.getDoc().getTag(
EXCEPTION_HANDLER_TAG_FULL_NAME );
+ if ( exTag != null )
+ {
+ PageflowTags.EX_HANDLER_TAG_GRAMMAR.validateTag( exTag,
jpfClass );
+
+ // make sure there is no catch tag on the exception handler
+ XTag catchTag = method.getDoc().getTag(
CATCH_TAG_FULL_NAME );
+ if ( catchTag != null )
+ {
+ CompilerUtil.error( exTag,
"pageflow.error.exception-handler-catch",
+ new String[] { CATCH_TAG_FULL_NAME } );
+ }
+
+ // now check parameters on the handler method
+ List params = method.getParameters();
+ if ( params.size() != 4 )
+ {
+ CompilerUtil.error( exTag,
"pageflow.error.exception-method-wrong-arg-count", new String[] {"4"} );
+ }
+ else
+ {
+ if ( !((XParameter)params.get(0)).getType().isA(
THROWABLE_CLASS_NAME, true ) )
+ CompilerUtil.error( exTag,
"pageflow.error.exception-method-wrong-exception-arg",
+ new String[] { THROWABLE_CLASS_NAME } );
+ else if ( !((XParameter)params.get(1)).getType().isA(
STRING_CLASS_NAME ) )
+ CompilerUtil.error( exTag,
"pageflow.error.exception-method-wrong-arg-type",
+ new String[] { "2", STRING_CLASS_NAME } );
+ else if ( !((XParameter)params.get(2)).getType().isA(
STRING_CLASS_NAME ) )
+ CompilerUtil.error( exTag,
"pageflow.error.exception-method-wrong-arg-type",
+ new String[] { "3", STRING_CLASS_NAME } );
+ else if ( !((XParameter)params.get(3)).getType().isA(
FORM_CLASS_NAME, true ) )
+ CompilerUtil.error( exTag,
"pageflow.error.exception-method-wrong-arg-type2",
+ new String[] { "4", FORM_CLASS_NAME,
NETUI_FORM_CLASS_NAME } );
+ }
+
+ // check the return type
+ XClass returnClass = method.getReturnType().getType();
+ if ( !returnClass.isA( FORWARD_CLASS_NAME, true ) )
+ CompilerUtil.error( exTag,
"pageflow.error.method-wrong-return-type",
+ new String[] {FORWARD_CLASS_NAME} );
+
+ if ( _exceptionHandlers.get( method.getName() ) != null )
+ {
+ CompilerUtil.error( exTag,
"pageflow.error.duplicate-exception-handler", null );
+ }
+ _exceptionHandlers.put( method.getName(), method );
+ }
+ }
+ }
+ return _exceptionHandlers;
+ }
+
+ protected String getControllerAttribute( XClass jpfClass, String attrName )
+ throws XDocletException
+ {
+ String value = null;
+ XTag jpfTag = jpfClass.getDoc().getTag( CONTROLLER_TAG_FULL_NAME );
+ if ( jpfTag != null )
+ {
+ value = jpfTag.getAttributeValue( attrName );
+ }
+ return value;
+ }
+
+ protected String getActionRoles( XTag actionTag, XClass jpfClass )
+ {
+ String rolesAllowed = null;
+ String actionRolesAllowed = actionTag.getAttributeValue(
ROLES_ALLOWED_ATTR );
+
+ String jpfRolesAllowed = null;
+ XTag jpfTag = jpfClass.getDoc().getTag( CONTROLLER_TAG_FULL_NAME );
+ if ( jpfTag != null )
+ jpfRolesAllowed = jpfTag.getAttributeValue( ROLES_ALLOWED_ATTR );
+
+ if ( actionRolesAllowed != null || jpfRolesAllowed != null )
+ {
+ if ( actionRolesAllowed == null && jpfRolesAllowed != null )
+ {
+ rolesAllowed = jpfRolesAllowed;
+ }
+ else if ( actionRolesAllowed != null && jpfRolesAllowed == null )
+ {
+ rolesAllowed = actionRolesAllowed;
+ }
+ else
+ {
+ // merge the lists
+ List roles = new ArrayList();
+ StringBuffer buf = new StringBuffer();
+ StringTokenizer actionSt = new StringTokenizer(
actionRolesAllowed );
+ while ( actionSt.hasMoreElements() )
+ {
+ roles.add( actionSt.nextToken() );
+ }
+ StringTokenizer jpfSt = new StringTokenizer( jpfRolesAllowed );
+ while ( jpfSt.hasMoreElements() )
+ {
+ String role = jpfSt.nextToken();
+ if ( !roles.contains( role ) )
+ roles.add( role );
+ }
+ for ( int i=0; i<roles.size(); i++ )
+ {
+ if ( i>0 )
+ buf.append( "," );
+ buf.append( (String)roles.get(i) );
+ }
+ rolesAllowed = buf.toString();
+ }
+ }
+ return rolesAllowed;
+ }
+
+ public void processFormBeans( XClass jpfClass )
+ throws XDocletException
+ {
+ List formBeans = new ArrayList();
+
+ // get the form bean inner classes
+ List innerClasses = jpfClass.getInnerClasses();
+ Iterator innerIter = innerClasses.iterator();
+ while ( innerIter.hasNext() )
+ {
+ XClass innerClass = (XClass)innerIter.next();
+ if ( innerClass.isA( FORM_CLASS_NAME, true ) )
+ formBeans.add( innerClass );
+ }
+
+ Iterator formIter = formBeans.iterator();
+ while ( formIter.hasNext() )
+ {
+ XClass formClass = (XClass)formIter.next();
+ addFormBean( formClass );
+ }
+ }
+
+ private FormBeanModel addFormBean( XClass formClass )
+ {
+ String formType = CompilerUtil.getQualifiedName( formClass );
+ String formBeanName = _strutsApp.getFormNameForType( formType );
+ FormBeanModel formBean = new FormBeanModel( formBeanName, formType,
_strutsApp );
+ _strutsApp.addFormBean( formBean );
+ return formBean;
+ }
+
+ private void checkForwardConflicts( XProgramElement xpe, XClass jpfClass )
+ throws XDocletException
+ {
+ XDoc doc = xpe.getDoc();
+
+ // get explicit forward tags for this element
+ List elementFwdTags = doc.getTags( FORWARD_TAG_FULL_NAME );
+
+ // get forwards from any handlers
+ Map handlerForwards = getForwardsFromCatches( xpe, jpfClass );
+
+ // if this is not the controller class itself, add all the global
forwards
+ // to a separate map; we need them to check local forwards for name
conflicts,
+ // but not to check forwards from handlers for forward conflicts
+ Map combinedForwards = new HashMap();
+ combinedForwards.putAll( handlerForwards );
+ if ( xpe != jpfClass )
+ {
+ combinedForwards.putAll( getForwardsFromCatches( jpfClass,
jpfClass ) );
+ }
+
+ // check name conflicts between explicit forwards and forwards from
handlers
+ // NOTE: doing all these nested loops to keep track of what handler's
forwards
+ // are being considered so that we can fill out the error
message correctly
+ Iterator fwdTagIter = elementFwdTags.iterator();
+ while ( fwdTagIter.hasNext() )
+ {
+ XTag tag = (XTag) fwdTagIter.next();
+ String name = tag.getAttributeValue( NAME_ATTR );
+
+ Iterator handlerIter = combinedForwards.keySet().iterator();
+ while ( handlerIter.hasNext() )
+ {
+ XTag handlerTag = (XTag)handlerIter.next();
+ String handler = handlerTag.getAttributeValue( METHOD_ATTR );
+ List handlerFwdTags = (List)combinedForwards.get( handlerTag );
+
+ Iterator handlerFwdIter = handlerFwdTags.iterator();
+ while ( handlerFwdIter.hasNext() )
+ {
+ XTag handlerFwdTag = (XTag) handlerFwdIter.next();
+ String otherName = handlerFwdTag.getAttributeValue(
NAME_ATTR );
+ if ( name.equals( otherName ) )
+ {
+// pageflow.error.duplicate-attr2 = Duplicate {0} tag
on method {3} (referenced from {4}) with {1}="{2}".
+ CompilerUtil.error( tag,
"pageflow.error.duplicate-attr2",
+ new String[] { FORWARD_TAG_NAME, NAME_ATTR,
name, handler, CATCH_TAG_FULL_NAME } );
+ }
+ }
+ }
+ }
+
+ // check conflicts between forwards on handlers: for each handler on
this program element,
+ // check each of its forwards against the list of forwards from other
handlers
+ Iterator handlerIter = handlerForwards.keySet().iterator();
+ while ( handlerIter.hasNext() )
+ {
+ XTag handlerTag = (XTag)handlerIter.next();
+ String handler = handlerTag.getAttributeValue( METHOD_ATTR );
+ List handlerFwdTags = (List)handlerForwards.get( handlerTag );
+
+ Iterator handlerFwdIter = handlerFwdTags.iterator();
+ while ( handlerFwdIter.hasNext() )
+ {
+ XTag tag = (XTag) handlerFwdIter.next();
+
+ Iterator otherHandlers = handlerForwards.keySet().iterator();
+ while ( otherHandlers.hasNext() )
+ {
+ XTag otherHandlerTag = (XTag) otherHandlers.next();
+ String otherHandler = otherHandlerTag.getAttributeValue(
METHOD_ATTR );
+ if ( !handler.equals( otherHandler ) )
+ {
+ List otherHandlerFwdTags = (List)handlerForwards.get(
otherHandlerTag );
+// pageflow.error.duplicate-exception-handler-forwards
= \
+// The specified exception-handler method {0} contains
a forward named "{2}" which conflicts with a forward in \
+// exception-handler {1}.
+ String conflictingFwd = findConflictingForward( tag,
otherHandlerFwdTags );
+ if ( conflictingFwd != null )
+ CompilerUtil.error( handlerTag,
"pageflow.error.duplicate-exception-handler-forwards",
+ new String[] { handler, otherHandler,
conflictingFwd } );
+ }
+ }
+ }
+ }
+
+
+ }
+
+ private Map getForwardsFromCatches( XProgramElement xpe, XClass jpfClass )
+ throws XDocletException
+ {
+ Map handlers = getExceptionHandlers( jpfClass );
+ Map forwards = new HashMap();
+
+ XDoc doc = xpe.getDoc();
+
+ // TODO: refactor to share code with addForwards?
+ List catchTags = doc.getTags( CATCH_TAG_FULL_NAME );
+
+ Iterator iter = catchTags.iterator();
+ while ( iter.hasNext() )
+ {
+ XTag tag = (XTag) iter.next();
+ String handlerName = tag.getAttributeValue( METHOD_ATTR );
+ if ( handlerName != null )
+ {
+ XMethod handler = (XMethod)handlers.get( handlerName );
+
+ if ( handler == null )
+ CompilerUtil.error( tag,
"pageflow.error.unresolved-exception-handler",
+ new String[] { handlerName } );
+
+ List handlerFwdTags = handler.getDoc().getTags(
FORWARD_TAG_FULL_NAME );
+ forwards.put( tag, handlerFwdTags );
+ }
+ }
+
+ return forwards;
+ }
+
+ private String findConflictingForward(XTag fwdTag, List currentForwards)
+ {
+ if ( currentForwards.size() == 0 )
+ return null;
+
+ String name = fwdTag.getAttributeValue( NAME_ATTR );
+ Collection attrs = fwdTag.getAttributeNames();
+ Iterator iter = currentForwards.iterator();
+ while ( iter.hasNext() )
+ {
+ XTag otherTag = (XTag) iter.next();
+ String otherName = otherTag.getAttributeValue( NAME_ATTR );
+
+ // only check forwards of the same name
+ if ( otherName.equals( name ) )
+ {
+ Collection otherAttrs = otherTag.getAttributeNames();
+
+ // if they have different number of attributes, they are
conflicting
+ if ( otherAttrs.size() != attrs.size() )
+ return name;
+
+ Iterator attrIter = attrs.iterator();
+ while ( attrIter.hasNext() )
+ {
+ String attr = (String)attrIter.next();
+ String value = fwdTag.getAttributeValue( attr );
+ String otherValue = otherTag.getAttributeValue( attr );
+
+ // as soon as we find a difference, we have a conflict
+ if ( otherValue == null || !otherValue.equals( value ) )
+ return name;
+ }
+ }
+ }
+ return null;
+ }
+
+ private void warnIfPathNotFound( XTag tag, String path )
+ {
+ if ( path == null || isAbsoluteURL(path) ||
+ ( !path.endsWith(JSP_EXTENSION) &&
!path.endsWith(HTM_EXTENSION) &&
+ !path.endsWith(HTML_EXTENSION) &&
!path.endsWith(PAGEFLOW_EXTENSION) ) )
+ return;
+
+ String base = null;
+ if ( path.startsWith( "/" ) )
+ {
+ base = _strutsApp.getWebappRootPath();
+ }
+ else
+ {
+ try
+ {
+ base = _strutsApp.getOriginalJpfSourceFile().getParent();
+ }
+ catch ( Exception e )
+ {
+ //ignore
+ }
+ }
+
+ if ( base != null )
+ {
+ File test = new File( base + File.separatorChar + path );
+ if ( !test.exists() )
+ CompilerUtil.warning( tag, "pageflow.warning.file-not-found",
new String[] { path } );
+ }
+ }
+
+ private String getValidPath( String path )
+ {
+ String result = null;
+
+ if ( path == null || path.length() == 0 )
+ result = "";
+ else if ( path.startsWith( "/" ) || isAbsoluteURL( path ) )
+ result = path;
+ else
+ result = "/" + path;
+ return result;
+ }
+
+ public static boolean isAbsoluteURL( String path )
+ {
+ try
+ {
+ return new URI( path ).getScheme() != null;
+ }
+ catch ( URISyntaxException e )
+ {
+ // ignore
+ }
+
+ return false;
+ }
+
+ public static boolean isJavaIdentifier(String s)
+ {
+ if (s.length() == 0 || !Character.isJavaIdentifierStart(s.charAt(0)))
+ {
+ return false;
+ }
+ for (int i=1; i<s.length(); i++)
+ {
+ if (!Character.isJavaIdentifierPart(s.charAt(i)))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public XDocletStrutsApp getStrutsApp() { return _strutsApp; }
+
+ private String getAlternateLocation( String webappRootPath, File file )
+ throws XDocletException
+ {
+ File webXmlFile = new File( webappRootPath + "/" + WEBINF_DIR_NAME +
"/web.xml" );
+
+ try
+ {
+ WebAppDocument webXml = WebAppDocument.Factory.parse( webXmlFile );
+ WebAppDocument.WebApp.Servlet[] servlets =
webXml.getWebApp().getServletArray();
+
+ for ( int i = 0; i < servlets.length; i++ )
+ {
+ WebAppDocument.WebApp.Servlet servlet = servlets[i];
+
+ if ( servlet.getServletName().equals( "action" ) )
+ {
+ InitParamType[] initParams = servlet.getInitParamArray();
+
+ for ( int j = 0; j < initParams.length; j++ )
+ {
+ String paramValue = initParams[j].getParamValue();
+
+ //
+ // If the referenced struts-config file has the same
name as the file
+ // we're going to generate, use the referenced file
(its location may be
+ // different than our default location).
+ //
+ if ( paramValue.indexOf( file.getName() ) != -1 )
+ {
+ //
+ // This may be a comma-separated list of files.
Find the right one.
+ //
+ if ( paramValue.indexOf( "," ) != -1 )
+ {
+ String[] files = paramValue.split( "," );
+ for ( int k = 0; k < files.length; ++k )
+ {
+ if ( files[k].indexOf( file.getName() ) !=
-1 )
+ {
+ return files[k].trim();
+ }
+ }
+ }
+ else
+ {
+ return paramValue;
+ }
+ }
+ }
+ }
+ }
+ }
+ catch ( Exception e )
+ {
+ CompilerUtil.error( "Could not read web.xml at " + webXmlFile + ":
" + e.getMessage() );
+ }
+
+ return null;
+ }
+
+ private boolean atLeastOneTagHasAttribute( List tags, String attribute )
+ {
+ Iterator tagIter = tags.iterator();
+ boolean foundTag = false;
+ while ( !foundTag && tagIter.hasNext() )
+ {
+ XTag fwdTag = (XTag) tagIter.next();
+ if ( fwdTag.getAttributeValue( attribute ) != null )
+ foundTag = true;
+ }
+ return foundTag;
+ }
+ */
+
+
+ public static NetuiSubTask get()
+ {
+ SubTask subtask = DocletContext.getInstance().getActiveSubTask();
+ assert subtask instanceof NetuiSubTask : subtask.getClass().getName();
+ return ( NetuiSubTask ) subtask;
+ }
+
+ public XJavaDoc getXJavaDoc()
+ {
+ return super.getXJavaDoc();
+ }
+
+ public SourceClass getCurrentSourceClass()
+ {
+ return _currentSourceClass;
+ }
+}
Propchange:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/NetuiSubTask.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/XDocletCompilerUtils.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/XDocletCompilerUtils.java?view=auto&rev=157713
==============================================================================
---
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/XDocletCompilerUtils.java
(added)
+++
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/XDocletCompilerUtils.java
Tue Mar 15 23:14:32 2005
@@ -0,0 +1,95 @@
+/*
+ * 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.beehive.netui.xdoclet;
+
+import org.apache.beehive.netui.compiler.typesystem.util.SourcePosition;
+import xjavadoc.SourceClass;
+import xjavadoc.XClass;
+import xjavadoc.XJavaDoc;
+import xjavadoc.XPackage;
+
+import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ResourceBundle;
+
+public class XDocletCompilerUtils
+{
+ private static final ResourceBundle MESSAGES =
+ ResourceBundle.getBundle(
XDocletCompilerUtils.class.getPackage().getName() + ".Messages" );
+
+ public static void addError( SourcePosition sourcePosition, String
messageKey, String[] args )
+ {
+ assert sourcePosition != null;
+ String message = getMessage( messageKey, args );
+ NetuiDocletTask.addError( message, sourcePosition );
+ }
+
+ public static void addWarning( SourcePosition sourcePosition, String
messageKey, String[] args )
+ {
+ assert sourcePosition != null;
+ String message = getMessage( messageKey, args );
+ NetuiDocletTask.addWarning( message, sourcePosition );
+ }
+
+ public static String getMessage( String messageKey, String[] args )
+ {
+ String message = MESSAGES.getString( messageKey );
+ if ( args != null ) message = MessageFormat.format( message, args );
+ return message;
+ }
+
+ public static XClass getXClass( String typeName )
+ {
+ if ( typeName.endsWith( ".class" ) ) typeName = typeName.substring( 0,
typeName.length() - 6 );
+ XJavaDoc xJavaDoc = NetuiSubTask.get().getXJavaDoc();
+ XClass type = xJavaDoc.getXClass( typeName );
+ if ( isUnknownClass( type ) ) type = xJavaDoc.getXClass( "java.lang."
+ typeName );
+
+ //
+ // If it's still unknown, try to resolve it against imports in the
current source file.
+ //
+ if ( isUnknownClass( type ) && typeName.indexOf( '.' ) == -1 )
+ {
+ SourceClass sourceClass =
NetuiSubTask.get().getCurrentSourceClass();
+ List importedClasses = sourceClass.getImportedClasses();
+
+ for ( Iterator i = importedClasses.iterator(); i.hasNext(); )
+ {
+ XClass importedClass = ( XClass ) i.next();
+ if ( importedClass.getName().equals( typeName ) ) return
importedClass;
+ }
+
+ List importedPackages = sourceClass.getImportedPackages();
+
+ for ( Iterator i = importedPackages.iterator(); i.hasNext(); )
+ {
+ XPackage importedPackage = ( XPackage ) i.next();
+ type = xJavaDoc.getXClass( importedPackage.getName() + '.' +
typeName );
+ if ( ! isUnknownClass( type ) ) return type;
+ }
+ }
+
+ return type;
+ }
+
+ public static boolean isUnknownClass( XClass xclass )
+ {
+ return xclass == null || xclass.getClass().getName().equals(
"xjavadoc.UnknownClass" );
+ }
+}
Propchange:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/XDocletCompilerUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/XDocletUtils.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/XDocletUtils.java?view=auto&rev=157713
==============================================================================
---
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/XDocletUtils.java
(added)
+++
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/XDocletUtils.java
Tue Mar 15 23:14:32 2005
@@ -0,0 +1,36 @@
+/*
+ * 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.beehive.netui.xdoclet;
+
+import xjavadoc.XClass;
+import xjavadoc.XProgramElement;
+
+public class XDocletUtils
+{
+ public static XClass getOutermostClass( XProgramElement element )
+ {
+ XClass containingClass;
+ while ( ( containingClass = element.getContainingClass() ) != null )
+ {
+ element = containingClass;
+ }
+
+ assert element instanceof XClass : element.getClass().getName();
+ return ( XClass ) element;
+ }
+}
Propchange:
incubator/beehive/trunk/netui/src/compiler-xdoclet/org/apache/beehive/netui/xdoclet/XDocletUtils.java
------------------------------------------------------------------------------
svn:eol-style = native