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