From: Xu?n B. <med...@us...> - 2002-06-08 00:49:42
|
Update of /cvsroot/ozone/ozone/server/src/org/ozoneDB/tools/OPP In directory usw-pr-cvs1:/tmp/cvs-serv14848/server/src/org/ozoneDB/tools/OPP Modified Files: OPP.java ProxyGenerator.java Log Message: Merge with OzoneEnhanced Index: OPP.java =================================================================== RCS file: /cvsroot/ozone/ozone/server/src/org/ozoneDB/tools/OPP/OPP.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- OPP.java 26 Apr 2002 16:17:46 -0000 1.3 +++ OPP.java 8 Jun 2002 00:49:39 -0000 1.4 @@ -224,8 +224,7 @@ Class cl = Class.forName(arg); ProxyGenerator generator = new ProxyGenerator(cl, methodPattern, outputDirName, quiet, cache); - generator.searchUpdateMethods(searchInterfaceSource); - generator.generateSource(); + generator.generateSource(searchInterfaceSource); if (compileSource) { generator.compileSource(); Index: ProxyGenerator.java =================================================================== RCS file: /cvsroot/ozone/ozone/server/src/org/ozoneDB/tools/OPP/ProxyGenerator.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- ProxyGenerator.java 17 Apr 2002 09:29:39 -0000 1.2 +++ ProxyGenerator.java 8 Jun 2002 00:49:39 -0000 1.3 @@ -13,6 +13,9 @@ import java.util.Hashtable; import java.util.TreeMap; import java.util.Enumeration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; //import org.apache.regexp.*; import org.ozoneDB.DxLib.*; import org.ozoneDB.OzoneCompatible; @@ -23,7 +26,12 @@ /** + * + * I'd like to support static inner classes as OzoneObjects, but where should the proxy classes defined? + * Within the the proxy class of the enclosing class? If so, what if the enclosing class is not OzoneCompatible? + * * @author <a href="http://www.softwarebuero.de/">SMB</a> + * @author <a href="http://www.medium.net/">Medium.net</a> * @version $Revision$Date$ */ class ProxyGenerator { @@ -103,6 +111,10 @@ args[2] = jvmClassPath; args[3] = proxyFileName; Process process = Runtime.getRuntime().exec( args ); + + // Eating compiler output is required to avoid pipe stalls, but this code requires Medium.net classes which are not GPL. That's why this is commented out. +// com.mn.io.stream.StreamConnector.synchronizedProcessConnect(process.getInputStream(),process.getErrorStream(),System.out,1024,process); + process.waitFor(); if (process.exitValue() != 0) { OPPHelper.warnMsg( proxyFileName, 0, "Unable to compile the generated source code!" ); @@ -111,19 +123,28 @@ } } + public void generateClassSource(Class cl) throws Exception { + makeLocalHeader(); + makeCtors(); + makeCreateMethods(); + makeMethods(); + checkMethodLists(); + + + out.print( " }\n" ); + } - public void generateSource() { + public void generateSource(boolean searchInterfaceSource) { try { - File proxyFile = new File(proxyFileName); - File parentFile = proxyFile.getParentFile(); - if (parentFile != null) - parentFile.mkdirs(); - out = new PrintWriter( new FileOutputStream( proxyFileName ) ); - makeHeader(); - makeCtors(); - makeMethods(); - checkMethodLists(); - out.print( " }\n" ); + searchUpdateMethods(searchInterfaceSource); + + File proxyFile = new File(proxyFileName); + File parentFile = proxyFile.getParentFile(); + if (parentFile != null) + parentFile.mkdirs(); + out = new PrintWriter(new FileOutputStream(proxyFileName)); + makeGlobalHeader(); + generateClassSource(cl); } catch (Exception e) { System.out.println( OPPHelper.classFileBasename( cl ) + ".java:0: " + e.getMessage() ); e.printStackTrace(); @@ -142,7 +163,7 @@ } - public void makeHeader() throws Exception { + public void makeGlobalHeader() throws Exception { out.print( "// Proxy class generated by ozone's OPP ($Revision$).\n" ); out.print( "// DO NOT EDIT!\n" ); out.print( "\n" ); @@ -154,6 +175,9 @@ out.print( "import org.ozoneDB.core.ObjectID;\n" ); out.print( "import org.ozoneDB.core.Lock;\n" ); out.print( "import org.ozoneDB.core.ResultConverter;\n" ); + } + + public void makeLocalHeader() throws Exception { out.print( "\n" ); out.print( "/**\n" ); @@ -212,13 +236,17 @@ out.print( " super (oid, link);\n" ); out.print( " }\n" ); - java.lang.reflect.Constructor[] ctors = cl.getDeclaredConstructors(); - for (int i = 0; i < ctors.length; i++) { - makeCtor( ctors[i] ); - } + if (false) { + java.lang.reflect.Constructor[] ctors = cl.getDeclaredConstructors(); + for (int i = 0; i < ctors.length; i++) { + makeCtor( ctors[i] ); + } + } } + + public void makeCtor( Constructor ctor ) throws Exception { // string buffer to build the signatur of this method StringBuffer signaturBuf = new StringBuffer( "" ); @@ -300,6 +328,179 @@ } + protected String determineProxyInterface() { + Class[] ifs = cl.getInterfaces(); + + for (int i = 0, c = 0; i < ifs.length; i++) { + // filter methods that are not inherited from a OzoneRemote + // interface +// System.out.println("determineProxyInterface(): checking "+ifs[i]+"."); + + if (OzoneRemote.class.isAssignableFrom( ifs[i] )) { + + return ifs[i].getName(); + } + } + + return determineProxyInterfaceDeep(cl); + } + + protected String determineProxyInterfaceDeep(Class of) { + Class[] ifs = of.getInterfaces(); + ArrayList list = new ArrayList(Arrays.asList(ifs)); + + if (false) { + Class superclass = of.getSuperclass(); + + if (superclass!=null) { + list.add(superclass); + } + } + + for (Iterator i = list.iterator(); i.hasNext();) { + Class testClass = (Class) i.next(); + + // filter methods that are not inherited from a OzoneRemote + // interface +// System.out.println("determineProxyInterface(): checking "+testClass+"."); + + if (OzoneRemote.class.isAssignableFrom(testClass)) { + + return testClass.getName(); + } else { + String interfaceName = determineProxyInterfaceDeep(testClass); + + if (interfaceName!=null) { + return interfaceName; + } + } + } + + return null; + } + + public void makeCreateMethods() throws Exception { + + java.lang.reflect.Constructor[] ctors = cl.getDeclaredConstructors(); + for (int i = 0; i < ctors.length; i++) { + makeCreateMethod( ctors[i] ); + } + } + + protected void makeCreateMethod( Constructor ctor ) throws Exception { + // string buffer to build the signatur of this method + StringBuffer signaturBuf = new StringBuffer( "" ); + + signaturBuf.append( " public static "); + + String proxyInterface = determineProxyInterface(); + + signaturBuf.append(proxyInterface); + signaturBuf.append(" createObject("); + + + // argumente in declaration schreiben + Class[] args = ctor.getParameterTypes(); + + for (int i = 0; i < args.length; i++) { + if (i != 0) { + signaturBuf.append( ", " ); + } + signaturBuf.append( typecodeForClass( args[i] ) + " arg" + i ); + } + + if (args.length!=0) { + signaturBuf.append(","); + } + + signaturBuf.append("OzoneInterface link)"); + + + out.print( "\n\n" ); + out.print( signaturBuf.toString() ); + + //exceptions in declaration schreiben + Class[] excs = ctor.getExceptionTypes(); + for (int i = 0; i < excs.length; i++) { + out.print( i == 0 ? " throws " : ", " ); + out.print( excs[i].getName() ); + } + out.print( " {\n" ); + + // the actual code of the method + out.print( " try {\n" ); + out.print( " /*\n" ); + out.print( " if (link == null)\n" ); + out.print( " throw new TransactionExc (\"Thread has not yet joined a transaction.\");\n" ); + out.print( " */\n" ); + out.print( " \n" ); + + //array of arguments + out.print( " Object[] args = {" ); + for (int i = 0; i < args.length; i++) { + out.print( i > 0 ? ", " : "" ); + if (args[i].isPrimitive()) { + out.print( "new " + OPPHelper.wrappercodeForPrimitive( args[i] ) + "(arg" + i + ")" ); + } else { + out.print( "arg" + i ); + } + } + out.print( "};\n" ); + + String sig = OPPHelper.signature( ctor.getParameterTypes() ); + out.print( " OzoneProxy proxy = link.createObject (\"" + cl.getName() + + "\", OzoneInterface.Public, null, " + sig + ", args);\n" ); + out.print( " \n" ); + out.print( " return ("+proxyInterface+") proxy;\n" ); + + //exceptions + boolean alreadyCatched = false; + if (false) { + for (int i = 0; i < excs.length; i++) { + out.print( " } catch (" + excs[i].getName() + " e) {\n" ); + out.print( " e.fillInStackTrace();\n" ); + out.print( " throw e;\n" ); + // out.print (" throw (" + excs[i].getName() + ")e.fillInStackTrace(); }\n"); + if (excs[i].getName().equals( "java.lang.RuntimeException" )) { + alreadyCatched = true; + } + } + } else { + if (true||excs.length>0) { + out.print(" } catch (ExceptionInOzoneObjectException e) {\n"); + out.print(" Throwable ee = e.getCause();\n"); + out.print(" \n"); + for (int i = 0; i < excs.length; i++) { + out.print(" if (ee instanceof "+excs[i].getName()+ ") {\n" ); + out.print(" throw ("+excs[i].getName()+ ") ee;\n" ); + out.print(" }\n" ); + out.print(" \n" ); + } + + out.print(" // Hope that the compiler is not so smart and detect these statements as unreachable if these exceptions are already matched above\n" ); + out.print(" if (ee instanceof RuntimeException) {\n" ); + out.print(" throw (RuntimeException) ee;\n" ); + out.print(" }\n" ); + out.print(" \n" ); + out.print(" if (ee instanceof Error) {\n" ); + out.print(" throw (Error) ee;\n" ); + out.print(" }\n" ); + out.print(" \n" ); + out.print(" throw e; // Unhandled exception.\n"); + } + } + if (!alreadyCatched) { + out.print( " } catch (RuntimeException e) {\n" ); + if (OPP.printStackTrace) { + out.print( " e.printStackTrace(System.out);\n" ); + } + out.print( " e.fillInStackTrace();\n" ); + out.print( " throw new UnexpectedException(e.toString());\n" ); + } + out.print( " }\n" ); + out.print( " }\n" ); + } + public void makeMethods() throws Exception { Class[] ifs = cl.getInterfaces(); for (int i = 0; i < ifs.length; i++) { @@ -337,7 +538,7 @@ // string buffer to build the signatur of this method StringBuffer signaturBuf = new StringBuffer( "" ); - signaturBuf.append( " public " + typecodeForClass( m.getReturnType() ) + " " + m.getName() + " (" ); + signaturBuf.append( " public " + typecodeForClass( m.getReturnType() ) + " " + m.getName() + "(" ); //argumente in declaration schreiben Class[] args = m.getParameterTypes(); @@ -380,29 +581,30 @@ // code to directly invoke the target method if (cache) { - out.print( " Object target = link.fetch (this, " + (update + out.print(" Object target = link.fetch (this, " + (update ? "Lock.LEVEL_WRITE" : "Lock.LEVEL_READ") + ");\n" ); - out.print( " if (target != null) {\n" ); + out.print("\n"); + out.print(" if (target!=null) {\n" ); // convert arguments if needed for (int i = 0; i < args.length; i++) { if (!args[i].isPrimitive()) { out.print( " arg" + i + " = (" + typecodeForClass( args[i] ) - + ")ResultConverter.substituteOzoneCompatibles (arg" + i + ");\n" ); + + ") ResultConverter.substituteOzoneCompatibles(arg" + i + ");\n" ); } } if (!m.getReturnType().getName().equals( "void" )) { if (!m.getReturnType().isPrimitive()) { out.print( " return (" + typecodeForClass( m.getReturnType() ) - + ")ResultConverter.substituteOzoneCompatibles (((" + cl.getName() + ")target)." + + ") ResultConverter.substituteOzoneCompatibles(((" + cl.getName() + ") target)." + m.getName() + "(" ); } else { - out.print( " return ((" + cl.getName() + ")target)." + m.getName() + "(" ); + out.print( " return ((" + cl.getName() + ") target)." + m.getName() + "(" ); } } else { - out.print( " ((" + cl.getName() + ")target)." + m.getName() + "(" ); + out.print( " ((" + cl.getName() + ") target)." + m.getName() + "(" ); } for (int i = 0; i < args.length; i++) { @@ -415,12 +617,11 @@ } } out.print( ");\n" ); - out.print( " }\n" ); - out.print( " else {\n" ); + out.print( " } else {\n" ); } //array of arguments - out.print( " Object[] args = {" ); + out.print( " Object[] args = {" ); for (int i = 0; i < args.length; i++) { out.print( i > 0 ? ", " : "" ); if (args[i].isPrimitive()) { @@ -431,7 +632,7 @@ } out.print( "};\n" ); - out.print( " Object result = link.invoke (this, " + OPPHelper.methodArrayIndex( methods, + out.print( " Object result = link.invoke(this, " + OPPHelper.methodArrayIndex( methods, m ) + ", args, " + (update ? "Lock.LEVEL_WRITE" : "Lock.LEVEL_READ") + ");\n" ); @@ -443,60 +644,86 @@ out.print( " return " + OPPHelper.returncodeForPrimitive( m.getReturnType(), "result" ) + ";\n" ); } else { - out.print( " return (" + typecodeForClass( m.getReturnType() ) + ")result;\n" ); + out.print( " return (" + typecodeForClass( m.getReturnType() ) + ") result;\n" ); } } if (cache) { - out.print( " }\n" ); + out.print( " }\n" ); } - out.print( " }\n" ); // user defined exceptions boolean excAlreadyCatched = false; - boolean rtAlreadyCatched = false; - for (int i = 0; i < excs.length; i++) { - out.print( " catch (" + excs[i].getName() + " e) {\n" ); - if (OPP.printStackTrace) { - out.print( " e.printStackTrace (System.out);\n" ); - } - out.print( " e.fillInStackTrace();\n" ); - out.print( " throw e;\n" ); - out.print( " }\n" ); - // out.print (" throw (" + excs[i].getName() + ")e.fillInStackTrace(); }\n"); - - if (excs[i].getName().equals( "java.lang.Exception" )) { - excAlreadyCatched = true; - } - if (excs[i].getName().equals( "java.lang.RuntimeException" )) { - rtAlreadyCatched = true; - } - } + boolean rtAlreadyCatched = false; + + if (false) { + for (int i = 0; i < excs.length; i++) { + out.print( " catch (" + excs[i].getName() + " e) {\n" ); + if (OPP.printStackTrace) { + out.print( " e.printStackTrace(System.out);\n" ); + } + out.print( " e.fillInStackTrace();\n" ); + out.print( " throw e;\n" ); + out.print( " }\n" ); + // out.print (" throw (" + excs[i].getName() + ")e.fillInStackTrace(); }\n"); + + if (excs[i].getName().equals( "java.lang.Exception" )) { + excAlreadyCatched = true; + } + if (excs[i].getName().equals( "java.lang.RuntimeException" )) { + rtAlreadyCatched = true; + } + } + } else { + if (true||excs.length>0) { + out.print(" } catch (ExceptionInOzoneObjectException e) {\n"); + out.print(" Throwable ee = e.getCause();\n"); + out.print(" \n"); + + for (int i = 0; i < excs.length; i++) { + out.print(" if (ee instanceof "+excs[i].getName()+ ") {\n" ); + out.print(" throw ("+excs[i].getName()+ ") ee;\n" ); + out.print(" }\n" ); + out.print(" \n" ); + } + + out.print(" // Hope that the compiler is not so smart and detect these statements as unreachable if these exceptions are already matched above\n" ); + out.print(" if (ee instanceof RuntimeException) {\n" ); + out.print(" throw (RuntimeException) ee;\n" ); + out.print(" }\n" ); + out.print(" \n" ); + out.print(" if (ee instanceof Error) {\n" ); + out.print(" throw (Error) ee;\n" ); + out.print(" }\n" ); + out.print(" \n" ); + out.print(" throw e; // Unhandled exception.\n"); + } + } + // runtime exceptions if (!rtAlreadyCatched && !excAlreadyCatched) { - out.print( " catch (RuntimeException e) {\n" ); + out.print( " } catch (RuntimeException e) {\n" ); if (OPP.printStackTrace) { - out.print( " e.printStackTrace (System.out);\n" ); + out.print( " e.printStackTrace(System.out);\n" ); } out.print( " e.fillInStackTrace();\n" ); out.print( " throw e;\n" ); - out.print( " }\n" ); } // all exceptions left if (!excAlreadyCatched) { - out.print( " catch (Exception e) {\n" ); + out.print( " } catch (Exception e) {\n" ); if (OPP.printStackTrace) { - out.print( " e.printStackTrace (System.out);\n" ); + out.print( " e.printStackTrace(System.out);\n" ); } out.print( " e.fillInStackTrace();\n" ); out.print( " throw new UnexpectedException (e.toString());\n" ); - out.print( " }\n" ); } out.print( " }\n" ); + out.print( " }\n" ); // save proceeded methods doneMethodsIf.put( signaturStr, m.getName() ); @@ -507,8 +734,8 @@ * Gives the Java source code for the type of the specified class. */ protected String typecodeForClass( Class cl ) throws Exception { - String name = cl.getName(); - String ret = ""; + + String ret; // // primitive type // if (name.length() == 1) { @@ -526,17 +753,29 @@ // array if (cl.isArray()) { + StringBuffer b = new StringBuffer(); + while (cl.isArray()) { - ret = ret + "[]"; + b.append("[]"); cl = cl.getComponentType(); } - ret = cl.getName() + ret; + b.insert(0,getSourcecodeClassName(cl)); + ret = b.toString(); } else { - // normal reference and primitive types - ret = name; + // norgetSourcecodeClassName(cl)reference and primitive types + ret = getSourcecodeClassName(cl); } return ret; } - + + + /** + Returns the name of the class in the way it is used within source code. + This is similar to the internal class name with the exception that names of inner + classes separate between class levels not by '$' but by '.'. + */ + protected static String getSourcecodeClassName(Class cl) { + return cl.getName().replace('$','.'); + } } |