You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jaxme-dev@ws.apache.org by jo...@apache.org on 2004/09/06 16:51:58 UTC

cvs commit: ws-jaxme/src/js/org/apache/ws/jaxme/js/util JavaParser.java

jochen      2004/09/06 07:51:58

  Modified:    src/js/org/apache/ws/jaxme/js/pattern ant.properties
                        InterfaceDescription.java Ant.java
                        ProxyGenerator.java
               src/js/org/apache/ws/jaxme/js/util JavaParser.java
  Added:       src/js/org/apache/ws/jaxme/js/pattern SourceReflector.java
                        CompiledClassReflector.java Reflector.java
               src/js/org/apache/ws/jaxme/js/apps XmlRpcCaller.java
                        XmlRpcClientGenerator.java
  Log:
  Added the client generator for Apache XML-RPC.
  
  Revision  Changes    Path
  1.3       +1 -0      ws-jaxme/src/js/org/apache/ws/jaxme/js/pattern/ant.properties
  
  Index: ant.properties
  ===================================================================
  RCS file: /home/cvs/ws-jaxme/src/js/org/apache/ws/jaxme/js/pattern/ant.properties,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ant.properties	23 Jul 2004 07:18:09 -0000	1.2
  +++ ant.properties	6 Sep 2004 14:51:57 -0000	1.3
  @@ -20,3 +20,4 @@
   chainGenerator=org.apache.ws.jaxme.js.pattern.Ant$AntChainGenerator
   versionGenerator=org.apache.ws.jaxme.js.pattern.Ant$AntVersionGenerator
   linkChecker=org.apache.ws.jaxme.js.util.AntLinkChecker
  +xmlRpcGenerator=org.apache.ws.jaxme.js.pattern.Ant$XmlRpcGenerator
  \ No newline at end of file
  
  
  
  1.2       +24 -155   ws-jaxme/src/js/org/apache/ws/jaxme/js/pattern/InterfaceDescription.java
  
  Index: InterfaceDescription.java
  ===================================================================
  RCS file: /home/cvs/ws-jaxme/src/js/org/apache/ws/jaxme/js/pattern/InterfaceDescription.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- InterfaceDescription.java	5 Sep 2004 15:42:26 -0000	1.1
  +++ InterfaceDescription.java	6 Sep 2004 14:51:57 -0000	1.2
  @@ -1,20 +1,9 @@
   package org.apache.ws.jaxme.js.pattern;
   
  -import java.io.IOException;
  -import java.io.InputStreamReader;
  -import java.lang.reflect.Method;
  -import java.lang.reflect.Modifier;
   import java.net.URL;
  -import java.util.Iterator;
   
  -import org.apache.ws.jaxme.js.JavaMethod;
  -import org.apache.ws.jaxme.js.JavaQNameImpl;
   import org.apache.ws.jaxme.js.JavaSource;
   import org.apache.ws.jaxme.js.JavaSourceFactory;
  -import org.apache.ws.jaxme.js.util.JavaParser;
  -
  -import antlr.RecognitionException;
  -import antlr.TokenStreamException;
   
   
   /** The <code>InterfaceDescription</code> is used by the
  @@ -33,140 +22,6 @@
    * </ol
    */
   public class InterfaceDescription {
  -      private class IDJavaSource {
  -      	  private final JavaSource js;
  -      	
  -      	  /** Creates a new instance of IDJavaSource, storing
  -      	   * information about the given Java source file
  -      	   * <code>pInterfaceName</code>.
  -      	   * @throws TokenStreamException An error occured in the Java lexer.
  -      	   * @throws RecognitionException An error occured in the Java parser.
  -      	   * @throws IllegalArgumentException The class is not an interface
  -      	   */
  -      	  public IDJavaSource(String pInterfaceName)
  -      	          throws IOException, RecognitionException, TokenStreamException {
  -      	  	  JavaSourceFactory jsf = new JavaSourceFactory();
  -      	  	  JavaParser jp = new JavaParser(jsf);
  -      	  	  ClassLoader[] classLoaders = getClassLoaders();
  -      	  	  String resource = pInterfaceName.replace('.', '/') + ".class";
  -      	  	  URL url = null;
  -      	  	  for (int i = 0;  i < classLoaders.length;  i++) {
  -      	  	  	  url = classLoaders[i].getResource(pInterfaceName);
  -      	  	  	  if (url != null) {
  -      	  	  		  break;
  -      	  	  	  }
  -      	  	  }
  -      	  	  if (url == null) {
  -      	  	  	  throw new IOException("Failed to locate resource " + resource
  -      	  	  	  		                + " in class path.");
  -      	  	  }
  -      	  	  jp.parse(new InputStreamReader(url.openStream()));
  -      	  	  
  -      	  	  String className = pInterfaceName;
  -      	  	  int offset = className.lastIndexOf('.');
  -      	  	  if (offset >= 0) {
  -      	  	  	  className = pInterfaceName.substring(offset+1);
  -      	  	  }
  -      	  	  JavaSource myjs = null;
  -      	  	  for (Iterator iter = jsf.getJavaSources();  iter.hasNext();  ) {
  -      	  	  	  JavaSource source = (JavaSource) iter.next();
  -      	  	  	  if (source.getQName().getClassName().equals(className)) {
  -      	  	  		  myjs = source;
  -      	  	  		  break;
  -      	  	  	  }
  -      	  	  }
  -      	  	  if (myjs == null) {
  -      	  	  	  throw new IllegalStateException("Class " + className
  -      	  	  	  		                          + " not found in parsed Java file "
  -												  + url);
  -      	  	  }
  -      	  	  js = myjs;
  -      	  	  if (!js.isInterface()) {
  -      	  	  	  throw new IllegalArgumentException("Class " + js.getQName()
  -      	  	  	  		                             + " is not an interface.");
  -      	  	  }
  -      	  }
  -
  -      	  /** Returns the generated instance of {@link JavaSource}.
  -      	   */
  -          public JavaSource getJavaSource() {
  -      	  	  return js;
  -      	  }
  -      }
  -
  -      private class IDReflection {
  -      	  private final Class interfaceClass;
  -      	
  -      	  /** Creates a new instance of IDReflection, storing
  -      	   * information about the given, compiled class
  -      	   * <code>pInterfaceName</code>.
  -      	   * @throws ClassNotFoundException The class could not be loaded
  -      	   * @throws IllegalArgumentException The class is not an interface
  -      	   */
  -      	  public IDReflection(String pInterfaceName) throws ClassNotFoundException {
  -      	  	  ClassLoader[] classLoaders = getClassLoaders();
  -      	  	  Class c = null;
  -      	  	  ClassNotFoundException ex = null;
  -      	  	  for (int i = 0;  c == null  &&  i < classLoaders.length;  i++) {
  -      	  	  	  try {
  -      	  	  	  	  c = classLoaders[i].loadClass(pInterfaceName);
  -      	  	  	  } catch (ClassNotFoundException e) {
  -      	  	  	  	  if (ex == null) {
  -      	  	  	  	  	  ex = e;
  -      	  	  	  	  }
  -      	  	  	  }
  -      	  	  }
  -      	  	  if (c == null) {
  -      	  	  	  if (ex == null) {
  -      	  	  	  	  ex = new ClassNotFoundException("Unable to load class: " + pInterfaceName);
  -      	  	  	  }
  -      	  	  	  throw ex;
  -      	  	  }
  -      	  	  interfaceClass = c;
  -      	  	  if (!interfaceClass.isInterface()) {
  -      	  	  	  throw new IllegalArgumentException("The class " + c.getName()
  -      	  	  	  		                             + " is not an interface.");
  -      	  	  }
  -      	  }
  -
  -          /** <p>Converts the given {@link Method} into an instance of
  -           * {@link JavaSource}.</p>
  -           */
  -          protected JavaMethod getMethod(JavaSource pSource, Method pMethod) {
  -          	  JavaMethod method = pSource.newJavaMethod(pMethod.getName(),
  -          	  		                                    JavaQNameImpl.getInstance(pMethod.getReturnType()),
  -          			                                    JavaSource.PUBLIC);
  -          	  Class[] classes = pMethod.getParameterTypes();
  -          	  for (int i = 0;  i < classes.length;  i++) {
  -          	  	  method.addParam(classes[i], "arg" + i);
  -          	  }
  -          	  Class[] exceptions = pMethod.getExceptionTypes();
  -              for (int i = 0;  i < exceptions.length;  i++) {
  -              	  method.addThrows(exceptions[i]);
  -              }
  -          	  return method;
  -          }
  -
  -      	  /** Reads the interface methods and converts them
  -           * into an instance of {@link JavaSource}.
  -		   */
  -      	  public JavaSource getJavaSource() {
  -              JavaSource js = new JavaSourceFactory().newJavaSource(JavaQNameImpl.getInstance(interfaceClass.getName()));
  -      	  	  Method[] methods = interfaceClass.getMethods();
  -              for (int i = 0;  i < methods.length;  i++) {
  -              	  Method m = methods[i];
  -                  if (!Modifier.isPublic(m.getModifiers())) {
  -                  	  continue;
  -                  }
  -                  if (Modifier.isStatic(m.getModifiers())) {
  -                  	  continue;
  -                  }
  -                  getMethod(js, m);
  -              }
  -              return js;
  -      	  }
  -      }
  -      
         private boolean isMandatory = true;
         private String interfaceName;
         private String type;
  @@ -175,7 +30,7 @@
         private ClassLoader[] getClassLoaders() {
         	  return new ClassLoader[]{
         		  Thread.currentThread().getContextClassLoader(),
  -			  IDReflection.class.getClassLoader(),
  +			  getClass().getClassLoader(),
   			  ClassLoader.getSystemClassLoader()
         	  };
         }
  @@ -254,19 +109,33 @@
         	  String mode = getType();
         	  if (mode == null  ||  "Reflection".equals(mode)) {
         	  	  try {
  -      	  	  	  IDReflection idReflection = new IDReflection(getInterface());
  -      	  	  	  return idReflection.getJavaSource();
  +                  ClassLoader[] cls = getClassLoaders();
  +                  for (int i = 0;  i < cls.length;  i++) {
  +                  	  if (cls[i] == null) {
  +                          continue;
  +                  	  }
  +                      
  +                      Class c = cls[i].loadClass(getInterface());
  +                      if (c != null) {
  +                      	  return new CompiledClassReflector(c).getJavaSource(new JavaSourceFactory());
  +                      }
  +                  }
         	  	  } catch (Exception e) {
  -      	  	  	  ex = e;
  +                  if (ex == null) {
  +                	  ex = e;
  +                  }
         	  	  }
         	  }
         	  if (mode == null  ||  "Source".equals(mode)) {
  -      	  	  try {
  -      	  		  IDJavaSource idJavaSource = new IDJavaSource(getInterface());
  -      	  		  return idJavaSource.getJavaSource();
  -      	  	  } catch (Exception e) {
  -      	  	  	  if (ex != null) {
  -      	  	  	  	  ex = e;
  +      	  	  ClassLoader[] cls = getClassLoaders();
  +      	  	  for (int i = 0;  i < cls.length;  i++) {
  +                  if (cls[i] == null) {
  +                  	  continue;
  +                  }
  +      	  	  	  URL url = cls[i].getResource(getInterface().replace('.', '/') + ".class");
  +      	  	  	  if (url != null) {
  +      	  	  	  	  SourceReflector reflector = new SourceReflector(url);
  +      	  	  	  	  return reflector.getJavaSource(new JavaSourceFactory());
         	  	  	  }
         	  	  }
         	  }
  
  
  
  1.6       +174 -5    ws-jaxme/src/js/org/apache/ws/jaxme/js/pattern/Ant.java
  
  Index: Ant.java
  ===================================================================
  RCS file: /home/cvs/ws-jaxme/src/js/org/apache/ws/jaxme/js/pattern/Ant.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Ant.java	5 Sep 2004 15:42:26 -0000	1.5
  +++ Ant.java	6 Sep 2004 14:51:57 -0000	1.6
  @@ -32,6 +32,7 @@
   import org.apache.ws.jaxme.js.JavaQNameImpl;
   import org.apache.ws.jaxme.js.JavaSource;
   import org.apache.ws.jaxme.js.JavaSourceFactory;
  +import org.apache.ws.jaxme.js.apps.XmlRpcClientGenerator;
   import org.apache.ws.jaxme.js.pattern.VersionGenerator.TableInfo;
   import org.apache.ws.jaxme.logging.AntProjectLoggerFactory;
   import org.apache.ws.jaxme.logging.LoggerAccess;
  @@ -46,7 +47,9 @@
   
   import org.apache.tools.ant.AntClassLoader;
   import org.apache.tools.ant.BuildException;
  +import org.apache.tools.ant.DirectoryScanner;
   import org.apache.tools.ant.Task;
  +import org.apache.tools.ant.types.FileSet;
   import org.apache.tools.ant.types.Path;
   
   
  @@ -62,18 +65,33 @@
       private boolean settingLoggerFactory = true;
       private String classpathRef;
       private Path classpath;
  +    /** Sets, whether the Ant task initializes its own logger factory.
  +     * Defaults to true.
  +     */
       public void setSettingLoggerFactory(boolean pSettingLoggerFactory) {
         settingLoggerFactory = pSettingLoggerFactory;
       }
  +    /** Returns, whether the Ant task initializes its own logger factory.
  +     * Defaults to true.
  +     */
       public boolean isSettingLoggerFactory() {
         return settingLoggerFactory;
       }
  +    /** Sets, the destination directory, where sources are being generated to.
  +     * Defaults to the current directory.
  +     */
       public void setDestDir(File pDir) {
         destDir = pDir;
       }
  +    /** Sets, the destination directory, where sources are being generated to.
  +     * Defaults to the current directory.
  +     */
       public File getDestDir() {
          return destDir;
       }
  +    /** Sets a classpath reference, being used to load compiled classes
  +     * or ressources.
  +     */
       public void setClasspathRef(String pRef) {
       	if(classpath != null) {
       		throw new BuildException("The 'classpathRef' attribute and the nested 'classpath' element are mutually exclusive.",
  @@ -81,9 +99,15 @@
           }
           classpathRef = pRef;
       }
  +    /** Returns a classpath reference, being used to load compiled classes
  +     * or ressources.
  +     */
       public String getClasspathRef() {
       	return classpathRef;
       }
  +    /** Sets a classpath, being used to load compiled classes
  +     * or ressources.
  +     */
       public void addClasspath(Path pClasspath) {
       	if (classpath != null) {
       		throw new BuildException("Multiple nested 'classpath' elements are forbidden.", getLocation());
  @@ -94,6 +118,9 @@
           }
           classpath = pClasspath;
       }
  +    /** Returns a classpath, being used to load compiled classes
  +     * or ressources.
  +     */
       public Path getClasspath() {
       	return classpath;
       }
  @@ -101,7 +128,11 @@
        */
       public void finish() {
       }
  -    public abstract void doExecute();
  +    /** Abstract method, which is invoked to do the real work.
  +     * @throws Exception
  +     */
  +    public abstract void doExecute() throws Exception;
  +
       public void execute() {
         if (isSettingLoggerFactory()) {
           LoggerFactory loggerFactory = LoggerAccess.getLoggerFactory();
  @@ -136,6 +167,10 @@
         try {
             finish();
             doExecute();
  +      } catch (BuildException e) {
  +      	  throw e;
  +      } catch (Exception e) {
  +      	  throw new BuildException(e, getLocation());
         } finally {
         	  if (acl != null) {
         	  	  acl.resetThreadContextLoader();
  @@ -146,6 +181,8 @@
   
     protected abstract static class BasicAntTask extends ReallyBasicAntTask {
       private JavaQName targetClass;
  +    /** Sets the name of the class being generated.
  +     */
       public void setTargetClass(String pTargetClass) {
   	   targetClass = getJavaQName(pTargetClass);
       }
  @@ -154,6 +191,8 @@
   		    throw new BuildException("The attribute 'targetClass' must be set.");
   		  }
   	  }
  +      /** Abstract method, which is invoked to generate the target class.
  +       */
   	  public abstract void generate(JavaSourceFactory pFactory, JavaQName pTargetClass)
   	      throws Exception;
   	  public void doExecute() {
  @@ -219,15 +258,22 @@
       }
     }
   
  +  /** Ant task for generating typesafe enumerations.
  +   */
     public static class AntTypesafeEnumerationGenerator extends BasicAntTask {
   	  private List items = new ArrayList();
   	  private boolean isAddingEquals = true;
   
  -    public void setAddingEquals(boolean pAddingEquals) {
  +      /** Sets whether the equals and hashCode methods are being
  +       * generated. Defaults to true.
  +       */ 
  +	  public void setAddingEquals(boolean pAddingEquals) {
   	 	  isAddingEquals = pAddingEquals;
  -    }
  +	  }
   
  -    public TypesafeEnumerationGenerator.Item createItem() {
  +      /** Creates a new, nested item.
  +       */ 
  +	  public TypesafeEnumerationGenerator.Item createItem() {
   	 	  TypesafeEnumerationGenerator.Item item = new TypesafeEnumerationGenerator.Item();
   	 	  items.add(item);
   	 	  return item;
  @@ -250,8 +296,13 @@
       }
     }
   
  +  /** Ant task for the {@link org.apache.ws.jaxme.js.pattern.ChainGenerator}.
  +   */
     public static class AntChainGenerator extends ReallyBasicAntTask {
        private List chains = new ArrayList();
  +     /** Creates a new, nested element with another chain being
  +      * generated.
  +      */
        public ChainGenerator createChain() {
           ChainGenerator chain = new ChainGenerator();
           chains.add(chain);
  @@ -281,21 +332,45 @@
        }
     }
   
  +  /** Ant task for the {@link org.apache.ws.jaxme.js.pattern.VersionGenerator}
  +   */
     public static class AntVersionGenerator extends BasicAntTask {
       private String driver, url, user, password, schema, verColumn;
       private List tables;
       private boolean isGeneratingLogging;
   
  +    /** Returns the JDBC driver.
  +     */
       public String getDriver() { return driver; }
  +    /** Sets the JDBC driver.
  +     */
       public void setDriver(String pDriver) { driver = pDriver; }
  +    /** Returns the JDBC password.
  +     */
       public String getPassword() { return password; }
  +    /** Sets the JDBC password.
  +     */
       public void setPassword(String pPassword) { password = pPassword; }
  +    /** Returns the JDBC URL.
  +     */
       public String getUrl() { return url; }
  +    /** Sets the JDBC URL.
  +     */
       public void setUrl(String pUrl) { url = pUrl; }
  +    /** Returns the JDBC user.
  +     */
       public String getUser() { return user; }
  +    /** Sets the JDBC user.
  +     */
       public void setUser(String pUser) { user = pUser; }
  +    /** Returns the database schema name.
  +     */
       public String getSchema() { return schema; }
  +    /** Sets the database schema name.
  +     */
       public void setSchema(String pSchema) { schema = pSchema; }
  +    /** Sets the table list; the table names are separated with white space.
  +     */
       public void setTables(String pTables) {
         tables = new ArrayList();
         for (StringTokenizer st = new StringTokenizer(pTables);  st.hasMoreTokens();  ) {
  @@ -303,18 +378,28 @@
           tables.add(tableName);
         }
       }
  +    /** Returns the table list.
  +     */
       public List getTables() {
         return tables;
       }
  +    /** Sets the column with the version number.
  +     */
       public void setVerColumn(String pColumn) {
         verColumn = pColumn;
       }
  +    /** Returns the column with the version number.
  +     */
       public String getVerColumn() {
         return verColumn;
       }
  +    /** Sets whether logging statements are being generated.
  +     */
       public void setGeneratingLogging(boolean pGeneratingLogging) {
         isGeneratingLogging = pGeneratingLogging;
       }
  +    /** Returns whether logging statements are being generated.
  +     */
       public boolean isGeneratingLogging() {
         return isGeneratingLogging;
       }
  @@ -448,4 +533,88 @@
         versionGenerator.getCloneMethod(js);
       }
     }
  +
  +    /** An ant task for the {@link org.apache.ws.jaxme.js.apps.XmlRpcClientGenerator}.
  +     */
  +    public static class XmlRpcGenerator extends ReallyBasicAntTask {
  +    	private final List serverClasses = new ArrayList();
  +        private String dispatcher;
  +        private String targetPackage;
  +
  +        /** Sets the target package.
  +         */
  +        public void setTargetPackage(String pPackage) {
  +        	targetPackage = pPackage;
  +        }
  +
  +        /** Returns the target package.
  +         */
  +        public String getTargetPackage() {
  +            return targetPackage;
  +        }
  +
  +        /** Sets the name of the dispatcher class.
  +         */
  +        public void setDispatcher(String pDispatcher) {
  +        	dispatcher = pDispatcher;
  +        }
  +
  +        /** Returns the name of the dispatcher class.
  +         */
  +        public String getDispatcher() {
  +        	return dispatcher;
  +        }
  +
  +        /** Creates a new, nested element with a {@link FileSet} of
  +         * server side classes, for which client stubs are being
  +         * generated.
  +         */
  +        public FileSet createServerClasses() {
  +            FileSet fs = (FileSet) getProject().createDataType("fileset");
  +            serverClasses.add(fs);
  +            return fs;
  +        }
  +
  +        public void finish() {
  +            super.finish();
  +            if (targetPackage == null) {
  +            	throw new BuildException("Missing 'targetPackage' attribute",
  +                                         getLocation());
  +            }
  +            if (serverClasses.size() == 0) {
  +            	throw new BuildException("Missing nested element 'serverClasses'",
  +                                         getLocation());
  +            }
  +        }
  +
  +		public void doExecute() throws Exception {
  +            JavaSourceFactory jsf = new JavaSourceFactory();
  +            XmlRpcClientGenerator gen = new XmlRpcClientGenerator(jsf, getTargetPackage());
  +            for (int i = 0;  i < serverClasses.size();  i++) {
  +            	FileSet fs = (FileSet) serverClasses.get(i);
  +                DirectoryScanner ds = fs.getDirectoryScanner(getProject());
  +                String[] files = ds.getIncludedFiles();
  +                for (int j = 0;  j < files.length;  j++) {
  +                    String s = files[i];
  +                    Reflector r;
  +                    if (s.endsWith(".class")) {
  +                        s = s.substring(0, s.length() - ".class".length());
  +                        r = new CompiledClassReflector(s.replace('/', '.'), Thread.currentThread().getContextClassLoader());
  +                    } else if (s.endsWith(".java")) {
  +                        r = new SourceReflector(new File(ds.getBasedir(), s));
  +                    } else {
  +                    	throw new BuildException("Unknown extension in file name: " + s
  +                                                 + ", expected .class or .java",
  +                                                 getLocation());
  +                    }
  +                    JavaSource js = r.getJavaSource(new JavaSourceFactory());
  +                    gen.addClass(js);
  +                }
  +            }
  +            if (getDispatcher() != null) {
  +            	gen.getDispatcher(JavaQNameImpl.getInstance(getDispatcher(), true));
  +            }
  +            jsf.write(getDestDir());
  +		}
  +    }
   }
  
  
  
  1.7       +6 -0      ws-jaxme/src/js/org/apache/ws/jaxme/js/pattern/ProxyGenerator.java
  
  Index: ProxyGenerator.java
  ===================================================================
  RCS file: /home/cvs/ws-jaxme/src/js/org/apache/ws/jaxme/js/pattern/ProxyGenerator.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ProxyGenerator.java	5 Sep 2004 15:42:26 -0000	1.6
  +++ ProxyGenerator.java	6 Sep 2004 14:51:57 -0000	1.7
  @@ -162,6 +162,12 @@
           JavaMethod[] methods = pInterface.getMethods();
   		for (int i = 0;  i < methods.length;  i++) {
   			JavaMethod method = methods[i];
  +            if (method.isStatic()) {
  +            	continue;
  +            }
  +            if (!JavaSource.PUBLIC.equals(method.getProtection())) {
  +            	continue;
  +            }
   			MethodKey key = new MethodKey(method);
   			JavaMethod existingMethod = (JavaMethod) pGeneratedMethods.get(key);
   			if (existingMethod == null) {
  
  
  
  1.1                  ws-jaxme/src/js/org/apache/ws/jaxme/js/pattern/SourceReflector.java
  
  Index: SourceReflector.java
  ===================================================================
  package org.apache.ws.jaxme.js.pattern;
  
  import java.io.File;
  import java.io.FileReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.io.Reader;
  import java.net.URL;
  import java.util.List;
  
  import org.apache.ws.jaxme.js.JavaSource;
  import org.apache.ws.jaxme.js.JavaSourceFactory;
  import org.apache.ws.jaxme.js.util.JavaParser;
  
  import antlr.RecognitionException;
  import antlr.TokenStreamException;
  
  
  /** Reflector for gathering information about a Java
   * source file.
   */
  public class SourceReflector implements Reflector {
      private final File file;
      private final URL url;
  
  	/** Creates a new <code>SourceReflector</code>, which
       * is going to read the Java source file <code>pFile</code>.
  	 */
  	public SourceReflector(File pFile) {
  		file = pFile;
          url = null;
  	}
  
      /** Creates a new <code>SourceReflector</code>, which
       * is going to read the Java source file from <code>pURL</code>.
       */
  	public SourceReflector(URL pURL) {
  		file = null;
          url = pURL;
  	}
  
  	public JavaSource getJavaSource(final JavaSourceFactory pFactory)
              throws RecognitionException, TokenStreamException, IOException {
  		Reader r;
          String name;
          if (file == null) {
              name = url.toExternalForm();
              r = new InputStreamReader(url.openStream());
          } else {
              name = file.getAbsolutePath();
              r = new FileReader(file);
          }
          List result = new JavaParser(pFactory).parse(r);
          if (result.size() > 1) {
              throw new RecognitionException("The Java source file contained multiple classes.");
          }
          if (result.size() > 1) {
          	throw new RecognitionException("The Java source file contained multiple classes.");
          }
          return (JavaSource) result.get(0);
  	}
  
  }
  
  
  
  1.1                  ws-jaxme/src/js/org/apache/ws/jaxme/js/pattern/CompiledClassReflector.java
  
  Index: CompiledClassReflector.java
  ===================================================================
  package org.apache.ws.jaxme.js.pattern;
  
  import java.lang.reflect.Method;
  
  import org.apache.ws.jaxme.js.JavaMethod;
  import org.apache.ws.jaxme.js.JavaQNameImpl;
  import org.apache.ws.jaxme.js.JavaSource;
  import org.apache.ws.jaxme.js.JavaSourceFactory;
  
  
  /** Reflector for gathering information on a compiled class.
   */
  public class CompiledClassReflector implements Reflector {
  	private final Class compiledClass;
  
  	/** Creates a new instance of <code>CompiledClassReflector</code>,
  	 * reading information from the given class.
  	 * @param pClass
  	 */
  	public CompiledClassReflector(Class pClass) {
  		compiledClass = pClass;
  	}
  	
  	/** Creates a new instance of <code>CompiledClassReflector</code>,
  	 * which loads the class named <code>pName</code> through
  	 * {@link ClassLoader pClassLoader}.
  	 */
  	public CompiledClassReflector(String pName, ClassLoader pClassLoader)
  	        throws ClassNotFoundException {
  		this(pClassLoader.loadClass(pName));
  	}
  	
  	/** <p>Converts the given {@link Method} into an instance of
  	 * {@link JavaSource}.</p>
  	 */
  	protected JavaMethod getMethod(JavaSource pSource, Method pMethod) {
  		JavaMethod method = pSource.newJavaMethod(pMethod.getName(),
  				                                  JavaQNameImpl.getInstance(pMethod.getReturnType()),
  												  JavaSource.PUBLIC);
  		Class[] classes = pMethod.getParameterTypes();
  		for (int i = 0;  i < classes.length;  i++) {
  			method.addParam(classes[i], "arg" + i);
  		}
  		Class[] exceptions = pMethod.getExceptionTypes();
  		for (int i = 0;  i < exceptions.length;  i++) {
  			method.addThrows(exceptions[i]);
  		}
  		return method;
  	}
  	
  	/** Returns the compiled class being used to gather information.
  	 */
  	public Class getCompiledClass() {
  		return compiledClass;
  	}
  	
  	/** Reads the interface methods and converts them
  	 * into an instance of {@link JavaSource}.
  	 */
  	public JavaSource getJavaSource(JavaSourceFactory pFactory) {
          Class c = getCompiledClass();
  		JavaSource js = new JavaSourceFactory().newJavaSource(JavaQNameImpl.getInstance(c.getName()));
  		Method[] methods = c.getMethods();
  		for (int i = 0;  i < methods.length;  i++) {
  			Method m = methods[i];
  			getMethod(js, m);
  		}
  		return js;
  	}
  }
  
  
  
  1.1                  ws-jaxme/src/js/org/apache/ws/jaxme/js/pattern/Reflector.java
  
  Index: Reflector.java
  ===================================================================
  package org.apache.ws.jaxme.js.pattern;
  
  import org.apache.ws.jaxme.js.JavaSource;
  import org.apache.ws.jaxme.js.JavaSourceFactory;
  
  
  /** The <code>Reflector</code> obtains informations on a certain
   * class by converting it into an instance of {@link JavaSource}.
   */
  public interface Reflector {
  	/** Returns the converted information.
  	 */
      public JavaSource getJavaSource(JavaSourceFactory pFactory) throws Exception;
  }
  
  
  
  1.1                  ws-jaxme/src/js/org/apache/ws/jaxme/js/apps/XmlRpcCaller.java
  
  Index: XmlRpcCaller.java
  ===================================================================
  package org.apache.ws.jaxme.js.apps;
  
  import java.util.Vector;
  
  
  /** Interface being implemented by the actual XML-RPC caller.
   * The main purpose of delegating this to an interface, is the
   * separation between generated classes and things like
   * authentication, server location, and so on.
   */
  public interface XmlRpcCaller {
  	/** Call the server, invoking the method named <code>pName</code>,
       * passing the arguments given by <code>pVector</code>.
  	 */
      public Object xmlRpcCall(String pName, Vector pVector);
  }
  
  
  
  1.1                  ws-jaxme/src/js/org/apache/ws/jaxme/js/apps/XmlRpcClientGenerator.java
  
  Index: XmlRpcClientGenerator.java
  ===================================================================
  package org.apache.ws.jaxme.js.apps;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.Vector;
  
  import org.apache.ws.jaxme.js.DirectAccessible;
  import org.apache.ws.jaxme.js.JavaConstructor;
  import org.apache.ws.jaxme.js.JavaField;
  import org.apache.ws.jaxme.js.JavaInnerClass;
  import org.apache.ws.jaxme.js.JavaMethod;
  import org.apache.ws.jaxme.js.JavaQName;
  import org.apache.ws.jaxme.js.JavaQNameImpl;
  import org.apache.ws.jaxme.js.JavaSource;
  import org.apache.ws.jaxme.js.JavaSourceFactory;
  import org.apache.ws.jaxme.js.LocalJavaField;
  import org.apache.ws.jaxme.js.Parameter;
  
  
  /** This class generates clients for Apache XML-RPC.
   * The basic idea goes as follows:
   * <ol>
   *   <li>Provide a class implementing the interface {@link XmlRpcCaller}.</li>
   *   <li>Provide a server side class being called via XML-RPC. The class
   *     must have a public default constructor, should be stateless, and
   *     all callable methods must be public instance methods.</li>
   *   <li>Run the generator, specifying a target package.</li>
   * </ol>
   * On the client, use the generated class, as if it were the server
   * side class.
   */
  public class XmlRpcClientGenerator {
      private final JavaSourceFactory factory;
      private final String targetPackage;
      private final Map methods = new HashMap();
  
      /** Creates a new instance with the given factory and target package.
       */
      public XmlRpcClientGenerator(JavaSourceFactory pFactory, String pTargetPackage) {
      	factory = pFactory;
          targetPackage = pTargetPackage;
      }
  
      /** Returns the factory, that was submitted to the constructor.
       */
      public JavaSourceFactory getFactory() { return factory; }
  
      /** Returns the target package, that was submitted to the constructor.
       */
      public String getTargetPackage() { return targetPackage; }
  
      /** Generates a name for the method <code>pMethod</code> and
       * adds it to the map {@link #methods}, the name being the
       * key.
       * @return The generated name.
       */
      protected String addMethod(JavaMethod pMethod) {
      	String className = pMethod.getJavaSource().getQName().toString();
          String methodName = pMethod.getName();
          for (int i = 0;  ;  i++) {
          	String name = className + "-" + methodName;
              if (i > 0) {
              	name += i;
              }
              if (!methods.containsKey(name)) {
              	methods.put(name, pMethod);
                  return name;
              }
          }
      }
  
      /** Converts the result value <code>pValue</code> into the
       * requested type <code>pType</code>.
       */
      protected Object getResultValue(JavaMethod pMethod, JavaQName pType, Object pValue) {
      	if (JavaQNameImpl.BYTE.equals(pType)) {
      		return new Object[]{"((", Byte.class, ") ", pValue, ").byteValue()"};
          } else if (JavaQNameImpl.SHORT.equals(pType)) {
              return new Object[]{"((", Short.class, ") ", pValue, ").shortValue()"};
          } else if (JavaQNameImpl.INT.equals(pType)) {
              return new Object[]{"((", Integer.class, ") ", pValue, ").intValue()"};
          } else if (JavaQNameImpl.LONG.equals(pType)) {
              return new Object[]{"((", Long.class, ") ", pValue, ").longValue()"};
          } else if (JavaQNameImpl.FLOAT.equals(pType)) {
              return new Object[]{"((", Float.class, ") ", pValue, ").floatValue()"};
          } else if (JavaQNameImpl.DOUBLE.equals(pType)) {
              return new Object[]{"((", Double.class, ") ", pValue, ").doubleValue()"};
          } else if (pType.isArray()) {
              LocalJavaField resultV = pMethod.newJavaField(Vector.class);
              pMethod.addLine(resultV, " = ", pValue, ";");
              pMethod.addIf(resultV , " == null");
              pMethod.addLine("return null;");
              pMethod.addElse();
              LocalJavaField resultA = pMethod.newJavaField(pType);
              resultA.addLine(pType.getInstanceClass(), "[", resultV, ".size()]");
              DirectAccessible i = pMethod.addForArray(resultA);
              Object element = new Object[]{resultV, ".elementAt(", i, ")"};
              pMethod.addLine(resultA, "[", i, "] = ", getResultValue(pMethod, pType.getInstanceClass(), element), ";");
              pMethod.addEndFor();
              return resultA;
          } else if (JavaQNameImpl.getInstance(Object.class).equals(pType)) {
              return pValue;
          } else {
          	return new Object[]{"(", pType, ") ", pValue};
          }
      }
  
      /** Converts the given input <code>pValue</code> with type
       * <code>pType</code> into a valid XML-RPC type.
       */
      protected Object getInputValue(JavaMethod pMethod, JavaQName pType, Object pValue) {
          if (pType.equals(JavaQNameImpl.BOOLEAN)) {
          	return new Object[]{pValue, " ? ", Boolean.class, ".TRUE : ", Boolean.class, ".FALSE"};
          } else if (pType.equals(JavaQNameImpl.BYTE)) {
              return new Object[]{"new ", Byte.class, "(", pValue, ")"};
          } else if (pType.equals(JavaQNameImpl.SHORT)) {
              return new Object[]{"new ", Short.class, "(", pValue, ")"};
          } else if (pType.equals(JavaQNameImpl.INT)) {
              return new Object[]{"new ", Integer.class, "(", pValue, ")"};
          } else if (pType.equals(JavaQNameImpl.LONG)) {
              return new Object[]{"new ", Long.class, "(", pValue, ")"};
          } else if (pType.equals(JavaQNameImpl.FLOAT)) {
              return new Object[]{"new ", Float.class, "(", pValue, ")"};
          } else if (pType.equals(JavaQNameImpl.DOUBLE)) {
              return new Object[]{"new ", Double.class, "(", pValue, ")"};
          } else if (pType.isArray()) {
              if (!(pValue instanceof DirectAccessible)) {
              	LocalJavaField val = pMethod.newJavaField(pType);
                  val.addLine(pValue);
                  pValue = val;
              }
              LocalJavaField v = pMethod.newJavaField(Vector.class);
              pMethod.addIf(pValue, " == null");
              pMethod.addLine(v, " = null");
              pMethod.addElse();
              pMethod.addLine(v, " = new ", Vector.class, "();");
              DirectAccessible i = pMethod.addForArray(pValue);
              Object element = new Object[]{pValue, "[", i, "]"};
              pMethod.addLine(v, ".add(", getInputValue(pMethod, pType.getInstanceClass(), element), ");");
              pMethod.addEndFor();
              pMethod.addEndIf();
              return v;
          } else {
              return pValue;
          }
      }
  
      /** Generates a method, invoking method <code>pMethod</code> using
       * the name <code>pName</code>.
       */
      protected JavaMethod getMethod(JavaSource pJs, JavaField pCaller,
                                     String pName, JavaMethod pMethod) {
          JavaMethod jm = pJs.newJavaMethod(pMethod);
          LocalJavaField v = jm.newJavaField(Vector.class);
          Parameter[] params = jm.getParams();
          for (int i = 0;  i < params.length;  i++) {
          	Parameter p = params[i];
              jm.addLine(v, ".add(", getInputValue(jm, p.getType(), p), ");");
          }
          Object result = new Object[]{pCaller, ".xmlRpcCall(",
          		                     JavaSource.getQuoted(pName), ", ", v, ")"};
          if (JavaQNameImpl.VOID.equals(jm.getType())) {
              jm.addLine(result, ";");
          } else {
          	jm.addLine("return ", getResultValue(jm, jm.getType(), result), ";");
          }
          return jm;
      }
  
      protected JavaField getXmlRpcCaller(JavaSource pJs) {
      	JavaField jf = pJs.newJavaField("caller", XmlRpcCaller.class, JavaSource.PRIVATE);
          jf.setFinal(true);
          return jf;
      }
  
      protected JavaConstructor getConstructor(JavaSource pJs, JavaField jf) {
          JavaConstructor jcon = pJs.newJavaConstructor(JavaSource.PUBLIC);
          Parameter param = jcon.addParam(XmlRpcCaller.class, "pCaller");
          jcon.addLine(jf, " = ", param, ";");
          return jcon;
      }
  
      /** Returns, whether a remote method call is generated for method
       * <code>pMethod</code>. The default implementation returns true,
       * if the method is public and not static.
       */
      protected boolean isMethodGenerated(JavaMethod pMethod) {
      	return JavaSource.PUBLIC.equals(pMethod.getProtection())
            &&  !pMethod.isStatic();
      }
  
      /** Creates a new client class, which is invoking the given
       * server side class <code>pSource</code>.
       */
      public JavaSource addClass(JavaSource pSource) {
          JavaSource js = getFactory().newJavaSource(JavaQNameImpl.getInstance(getTargetPackage(), pSource.getQName().getClassName()), JavaSource.PUBLIC);
          JavaField jf = getXmlRpcCaller(js);
          getConstructor(js, jf);
          JavaMethod[] methods = pSource.getMethods();
          for (int i = 0;  i < methods.length;  i++) {
              JavaMethod m = methods[i];
              if (isMethodGenerated(m)) {
              	String name = addMethod(m);
              	getMethod(js, jf, name, m);
              }
          }
          return js;
      }
  
      /** Generates the abstract invoker class.
       */
      public JavaSource getInvokerClass(JavaSource pSource) {
          JavaInnerClass invoker = pSource.newJavaInnerClass("Invoker", JavaSource.PUBLIC);
          invoker.setType(JavaSource.INTERFACE);
          JavaMethod jm = invoker.newJavaMethod("invoke", Object.class, JavaSource.PUBLIC);
          jm.addThrows(Throwable.class);
          return invoker;
      }
  
      /** Creates the field with the {@link Map} of invokers.
       */
      protected JavaField getInvokerMap(JavaSource pSource) {
      	JavaField result = pSource.newJavaField("map", Map.class, JavaSource.PRIVATE);
      	result.addLine("new ", HashMap.class, "()");
          return result;
      }
  
      /** Creates a new invoker class for the given method.
       */
      protected JavaSource getInvoker(JavaSource pSource, JavaMethod pMethod, JavaQName pInvoker, int pNum) {
          JavaInnerClass js = pSource.newJavaInnerClass("Invoker" + pNum, JavaSource.PUBLIC);
          js.setStatic(true);
          js.addImplements(pInvoker);
          JavaMethod jm = js.newJavaMethod("invoke", Object.class, JavaSource.PUBLIC);
          Parameter param = jm.addParam(Vector.class, "params");
          JavaQName[] classes = pMethod.getExceptions();
          for (int i = 0;  i < classes.length;  i++) {
          	jm.addThrows(classes[i]);
          }
          Parameter[] params = pMethod.getParams();
          List args = new ArrayList();
          for (int i = 0;  i < params.length;  i++) {
          	if (i > 0) {
          		args.add(", ");
              }
              Parameter p = params[i];
              args.add(getResultValue(jm, p.getType(), new Object[]{param, ".elementAt(" + i + ")"}));
          }
          Object o = new Object[]{"new ", pMethod.getJavaSource().getQName(), "().",
          		                pMethod.getName(), "(", args, ")"};
          if (JavaQNameImpl.VOID.equals(pMethod.getType())) {
          	jm.addLine(o, ";");
              jm.addLine("return null;");
          } else {
              jm.addLine("return ", getInputValue(jm, pMethod.getType(), o), ";");
          }
          return js;
      }
  
      /** Creates the dispatchers constructor.
       */
      public JavaConstructor getDispatcherConstructor(JavaSource pSource,
                                                      JavaField pMap,
                                                      JavaQName pInvoker) {
          JavaConstructor con = pSource.newJavaConstructor(JavaSource.PUBLIC);
          int num = 0;
          for (Iterator iter = methods.entrySet().iterator();  iter.hasNext();  ) {
              Map.Entry entry = (Map.Entry) iter.next();
              String name = (String) entry.getKey();
              JavaMethod method = (JavaMethod) entry.getValue();
              JavaSource innerClass = getInvoker(pSource, method, pInvoker, num++);
              con.addLine(pMap, ".put(", JavaSource.getQuoted(name), ", new ", innerClass.getQName(), "())");
          }
          return con;
      }
  
      /** Creates the dispatcher class. Make sure, that this method
       * is invoked <em>after</em> {@link #addClass(JavaSource)}!
       * @param pQName Fully qualified class name of the dispatcher class.
       */
      public JavaSource getDispatcher(JavaQName pQName) {
      	JavaSource js = getFactory().newJavaSource(pQName);
          JavaSource invoker = getInvokerClass(js);
          JavaField map = getInvokerMap(js);
          getDispatcherConstructor(js, map, invoker.getQName());
          return js;
      }
  }
  
  
  
  1.4       +14 -9     ws-jaxme/src/js/org/apache/ws/jaxme/js/util/JavaParser.java
  
  Index: JavaParser.java
  ===================================================================
  RCS file: /home/cvs/ws-jaxme/src/js/org/apache/ws/jaxme/js/util/JavaParser.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- JavaParser.java	3 Sep 2004 00:44:02 -0000	1.3
  +++ JavaParser.java	6 Sep 2004 14:51:58 -0000	1.4
  @@ -6,7 +6,6 @@
   import java.io.Reader;
   import java.io.Serializable;
   import java.util.ArrayList;
  -import java.util.Iterator;
   import java.util.List;
   import java.util.StringTokenizer;
   
  @@ -36,6 +35,7 @@
   public class JavaParser implements Serializable, Cloneable {
   	private final JavaSourceFactory factory;
       private final List importStatements = new ArrayList();
  +    private final List generatedClasses = new ArrayList();
       private String packageName;
   
   	/** <p>Creates a new instance of <code>JavaParser</code>,
  @@ -65,16 +65,18 @@
       }
   
       /** <p>Parses the given file.</p>
  +     * @return List of classes, that have been read.
        */
  -    public void parse(File pFile) throws RecognitionException, TokenStreamException, FileNotFoundException {
  -    	parse(new FileReader(pFile));
  +    public List parse(File pFile) throws RecognitionException, TokenStreamException, FileNotFoundException {
  +    	return parse(new FileReader(pFile));
       }
   
       /** <p>Parses the input read from the given
        * {@link Reader} <code>pReader</code>.</p>
  +     * @return List of classes, that have been read.
        */
  -    public void parse(Reader pReader) throws RecognitionException, TokenStreamException {
  -    	parse(new JavaLexer(pReader));
  +    public List parse(Reader pReader) throws RecognitionException, TokenStreamException {
  +    	return parse(new JavaLexer(pReader));
       }
   
       private void showAST(int pLevel, AST pAST) {
  @@ -93,9 +95,10 @@
           importStatements.clear();
       }
   
  -    /** <p>Parses the given {@link TokenStream} <code>pStream</code>.</p>
  +    /** Parses the given {@link TokenStream} <code>pStream</code>.
  +     * @return List of classes, that have been read.
        */
  -    public void parse(TokenStream pStream) throws RecognitionException, TokenStreamException {
  +    public List parse(TokenStream pStream) throws RecognitionException, TokenStreamException {
       	reset();
           JavaRecognizer parser = new JavaRecognizer(pStream);
       	parser.compilationUnit();
  @@ -103,6 +106,7 @@
       		//showAST(0, ast);
               parseAST(ast);
           }
  +        return generatedClasses;
       }
   
       private void parsePackageName(AST pAST) {
  @@ -159,7 +163,6 @@
               throw new IllegalStateException("Missing class name");
           }
           String className = parseIdentifier(classNameAST);
  -        JavaSource js;
           if (pOuterClass == null) {
               String packageName = getPackageName();
               JavaQName qName;
  @@ -168,7 +171,9 @@
               } else {
                   qName = JavaQNameImpl.getInstance(packageName, className);
               }
  -            return factory.newJavaSource(qName, JavaSource.DEFAULT_PROTECTION);
  +            JavaSource js = factory.newJavaSource(qName, JavaSource.DEFAULT_PROTECTION);
  +            generatedClasses.add(js);
  +            return js;
           } else {
               return pOuterClass.newJavaInnerClass(className, JavaSource.DEFAULT_PROTECTION);
           }
  
  
  

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