jkesselm 00/10/26 15:01:49
Modified: java/src/org/apache/xalan/processor
CompiledStylesheetBundle.java
CompilingStylesheetHandler.java
Log:
Take advantage of generalized compilation routine
Revision Changes Path
1.5 +35 -12
xml-xalan/java/src/org/apache/xalan/processor/CompiledStylesheetBundle.java
Index: CompiledStylesheetBundle.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/processor/CompiledStylesheetBundle.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- CompiledStylesheetBundle.java 2000/10/25 21:26:24 1.4
+++ CompiledStylesheetBundle.java 2000/10/26 22:01:46 1.5
@@ -191,20 +191,26 @@
int start=fullname.lastIndexOf(".");
String packagename=fullname.substring(0,start);
String shortname=fullname.substring(start+1);
- // Where to copy the classfile from.
- // TODO: Can we get the bytes direct from the
Class object???
- String source=
-
packageNameToDirectory(packagename,outdir,File.separator)
- +shortname+".class";
// Where to write the class within the
jar/zipfile's
// directory structure
String sink=
packageNameToDirectory(packagename,"","/")
+shortname+".class";
-
ze=new java.util.zip.ZipEntry(sink);
zf.putNextEntry(ze);
+
+ // Where to copy the classfile from.
+ // TODO: I'd really like a solution that reads
the bytecodes
+ // from the existing Class, rather than going
back to the
+ // .class file, to save disk activity and
simplify this code.
+ // Haven't yet found a portable solution. Can't
use getResource
+ // since it explicitly disallows classes; can't
access the
+ // classloader since some environments return
it as null..
+ String source=
+
packageNameToDirectory(packagename,outdir,File.separator)
+ +shortname+".class";
java.io.FileInputStream fis=new
java.io.FileInputStream(source);
+
// Need to count how many bytes are
transferred; the ZipEntry
// does _NOT_ set itself automatically.
int count=0;
@@ -287,7 +293,8 @@
try
{
// Create the custom classloader which will consult the
bundle
- java.lang.ClassLoader cl=new
ZipfileClassLoader(filename);
+ // TODO: Ponder whether to cache ZipfileClassLoader
+ java.lang.ClassLoader cl=new
ZipfileClassLoader(filename,false);
// Read the .ser file from the bundle, via that
classloader
is=cl.getResourceAsStream("Stylesheet.ser");
// Read objects from the .ser, loading from bundle if
necessary
@@ -356,18 +363,28 @@
class ZipfileClassLoader extends ClassLoader
{
java.util.zip.ZipFile zip=null;
+ java.util.Hashtable cache;
/** Constructor.
* TODO: Should we be able to load from stream as well as
string?
* That would require a preload solution or a random-access
stream...
* OK for our simple case where we know we're going to use
everything
* eventually, not so hot for others.
+ * <p>
+ * There's an open question here re caching. Fact is, the custom
+ * classes in a compiled stylesheet are currently used once per
+ * load of that stylesheet, so the cache wouldn't buy us much.
+ * And if we cache, we also have to think about when to
_release_
+ * the cached objects. So I'm making this optional...
*
* @param String filename Name of the zipfile to be read
+ * @param boolean cached True iff you want classes cached for
reuse
*/
- public ZipfileClassLoader(String filename) throws
java.io.IOException
+ public ZipfileClassLoader(String filename, boolean cached)
throws java.io.IOException
{
zip=new java.util.zip.ZipFile(filename);
+ if(cached==true)
+ cache=new java.util.Hashtable();
}
/** Find a class within the Zipfile. Note that this does not
_resolve_
@@ -404,7 +421,7 @@
* @return byte[] with full contents of "file".
*/
private byte[] loadClassData(String name)
- {
+ {
int start=name.lastIndexOf(".");
String packagename=name.substring(0,start);
String shortname=name.substring(start+1);
@@ -449,9 +466,15 @@
public synchronized Class loadClass(String name, boolean
resolve)
throws ClassNotFoundException
{
- Class c=findClass(name);
- if(c!=null && resolve==true)
- resolveClass(c);
+ Class c=(cache==null)? null : (Class)cache.get(name);
+ if(c==null)
+ {
+ c=findClass(name);
+ if(c!=null && resolve==true)
+ resolveClass(c);
+ if(cache!=null)
+ cache.put(name,c);
+ }
return c;
}
1.12 +15 -91
xml-xalan/java/src/org/apache/xalan/processor/CompilingStylesheetHandler.java
Index: CompilingStylesheetHandler.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/processor/CompilingStylesheetHandler.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- CompilingStylesheetHandler.java 2000/10/25 21:26:24 1.11
+++ CompilingStylesheetHandler.java 2000/10/26 22:01:47 1.12
@@ -208,19 +208,19 @@
Java code. That code is then compiled and instantiated
to produce a new "equivalent" object, which can be used
to replace the original Template.
-
+ <p>
Note that the compiled Template may have to reference
children that we don't yet know how to compile. This
is done by copying references to those kids into a vector,
and having the generated code invoke them via offsets
in that vector.
-
+ <p>
At this time, the compiler's rather simpleminded. No
common subexpression extraction is performed, and no
attempt is made to optimize across stylesheets. We're
just flattening some of the code and reorganizing it
into direct SAX invocations.
-
+ <p>
Literal result elements become SAX begin/endElement
Context-insensitive attributes become literal assignment
to the attribute trees.
@@ -869,6 +869,7 @@
// would be found in (possibly relative). However, "."
// is treated as being found in itself rather than in "..".
// TODO: ***** A more elegant version of this should be moved into
org.apache.xalan.utils.synthetic.Class?
+ // TODO: Should we use a classloader rather than std. classpath?
Class compileSyntheticClass(org.apache.xalan.utils.synthetic.Class tClass,
String classLocation)
{
Class resolved=null;
@@ -914,76 +915,20 @@
return null;
}
- // Compile
+ // Try to pick up the same classpath we're executing under. That
+ // ought to include everything in Xalan and the parser...
String classpath=System.getProperty ("java.class.path");
- boolean debug=true;// *****
- boolean generateDebug=true;// *****
- //com.ibm.cs.util.JavaUtils.setDebug(generateDebug);
-
- boolean compileOK=false;
- boolean internalCompile=true;
- String javac=System.getProperty("xalan.javac","javac");
- if("msvj_workaround".equals(javac))
- internalCompile=false;
+ // TODO: These should probably be exposed as params or properties.
+ boolean debug=true;
+ boolean generateDebug=true;
+
+ // Run the compilation. Encapsulates the fallbacks and
+ // workarounds needed to achieve this in various environments.
+ JavaUtils.setDebug(generateDebug);
+ boolean compileOK=
+ JavaUtils.JDKcompile(filename,classpath);
- if(internalCompile)
- {
- // ***** Part of the BSF package.
- // This is actually supposed to go through the whole routine of
trying
- // to call the JDK directly (via the 1.2 options, then via
undocumented
- // 1.1 calls), then fall back on command line if necessary.
- // But I'm having some odd problems with it right now under
- // both VisualCafe and VisualJ++.
- compileOK = JavaUtils.JDKcompile(filename,classpath);
- }
- else
- {
- try
- {
- // ***** LAUNCH PROBLEMS
- // Microsoft Visual J++ has a number of problems, from
- // insisting on running the .exec() via a shell that has
- // only the NT "system" environment, to truncating the
- // parameters passed to their JView tool, to having trouble
- // launghing the compiler directly. Hence the following
- // ugliness with propertie and workarounds
- String extraClassPath="";
- if("msvj_workaround".equals(javac))
- {
- javac="cmd /c
D:\\LOCAL\\APPS\\SUN\\JDK1.2.2\\BIN\\JAVAC.EXE";
- extraClassPath=".;d:\\user\\apache\\xml-xalan\\xerces.jar;";
- }
- else
- {
-
extraClassPath=System.getProperty("xalan.classpathprefix","");
- }
- String cmd=""
- +" "+javac
- +" -g"
- // +" -verbose"
- +" -classpath "+extraClassPath+";"+classpath
- +" "+filename
- ;
- Process p;
- // Used this when trying to figure out why javac wouldn't run
- if(false)
- {
- System.out.println(cmd);
- p=Runtime.getRuntime().exec("cmd /c start /wait set path");
- compileOK=(waitHardFor(p)==0);
- }
- p=Runtime.getRuntime().exec(cmd);
- compileOK=(waitHardFor(p)==0);
- }
- catch(java.io.IOException e)
- {
- System.err.println("ERR: javac failed for "+
- tClass.getName());
- e.printStackTrace();
- }
- }
-
if (compileOK)
{
if(debug)
@@ -1094,25 +1039,4 @@
return className;
}
- /** Subroutine: Like p.waitFor, but discards the InterruptedException
- * and goes right back into a wait.
- * @param Process p to be waited for
- * @return the exitValue() of the process.
- */
- int waitHardFor(Process p)
- {
- boolean done=false;
- while(!done)
- try
- {
- p.waitFor();
- done=true;
- }
- catch(InterruptedException e)
- {
- System.out.println("(Process wait interrupted, resuming)");
- }
- int ev=p.exitValue(); // Pause for debugging...
- return ev;
- }
}