sboag 01/01/29 03:52:56
Modified: java/src/org/apache/xalan/transformer TransformerImpl.java
Log:
Main change is introduction of m_reentryGuard, which
is used to synchronize on TrAX API functions which can mutate,
to guard against mutation during a transformation.
Revision Changes Path
1.77 +119 -97
xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java
Index: TransformerImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -r1.76 -r1.77
--- TransformerImpl.java 2001/01/24 16:13:05 1.76
+++ TransformerImpl.java 2001/01/29 11:52:54 1.77
@@ -171,6 +171,10 @@
public class TransformerImpl extends Transformer
implements Runnable, TransformState
{
+ // Synch object to gaurd against setting values from the TrAX interface
+ // or reentry while the transform is going on.
+ private Boolean m_reentryGuard = new Boolean(true);
+
/**
* True if the parser events should be on the main thread,
* false if not. Experemental. Can not be set right now.
@@ -214,24 +218,18 @@
/** A pool of ResultTreeHandlers, for serialization of a subtree to text.
* Please note that each of these also holds onto a Text Serializer. */
private ObjectPool m_textResultHandlerObjectPool =
- new ObjectPool(org.apache.xalan.transformer.ResultTreeHandler.class);
+ new ObjectPool("org.apache.xalan.transformer.ResultTreeHandler");
/** Related to m_textResultHandlerObjectPool, this is a pool of
* StringWriters, which are passed to the Text Serializers.
* (I'm not sure if this is really needed any more. -sb) */
private ObjectPool m_stringWriterObjectPool =
- new ObjectPool(java.io.StringWriter.class);
+ new ObjectPool("java.io.StringWriter");
/** A static text format object, which can be used over and
* over to create the text serializers. */
- private static OutputProperties m_textformat;
+ private OutputProperties m_textformat = new OutputProperties(Method.Text);
- static
- {
- // Synchronize??
- m_textformat = new OutputProperties(Method.Text);
- }
-
// Commenteded out in response to problem reported by
// Nicola Brown <[EMAIL PROTECTED]>
// /**
@@ -347,7 +345,7 @@
* If the the transform is on the secondary thread, we
* need to know when it is done, so we can return.
*/
- boolean m_isTransformDone = false;
+ private boolean m_isTransformDone = false;
private boolean m_hasBeenReset = false;
@@ -756,17 +754,20 @@
public void setOutputProperty(String name, String value)
throws IllegalArgumentException
{
- // Get the output format that was set by the user, otherwise get the
- // output format from the stylesheet.
- if(null == m_outputFormat)
+ synchronized(m_reentryGuard)
{
- m_outputFormat =
(OutputProperties)getStylesheet().getOutputComposed().clone();
+ // Get the output format that was set by the user, otherwise get the
+ // output format from the stylesheet.
+ if(null == m_outputFormat)
+ {
+ m_outputFormat =
(OutputProperties)getStylesheet().getOutputComposed().clone();
+ }
+
+ if(!m_outputFormat.isLegalPropertyKey(name))
+ throw new IllegalArgumentException("output property not recognized:
"+name);
+
+ m_outputFormat.setProperty(name, value);
}
-
- if(!m_outputFormat.isLegalPropertyKey(name))
- throw new IllegalArgumentException("output property not recognized:
"+name);
-
- m_outputFormat.setProperty(name, value);
}
/**
@@ -783,20 +784,23 @@
*/
public void setOutputProperties(Properties oformat)
{
- if(null != oformat)
+ synchronized(m_reentryGuard)
{
- // See if an *explicit* method was set.
- String method = (String)oformat.get(OutputKeys.METHOD);
- if(null != method)
- m_outputFormat = new OutputProperties(method);
- else
- m_outputFormat = new OutputProperties();
- }
-
- m_outputFormat.copyFrom(m_stylesheetRoot.getOutputProperties());
- if(null != oformat)
- {
- m_outputFormat.copyFrom(oformat);
+ if(null != oformat)
+ {
+ // See if an *explicit* method was set.
+ String method = (String)oformat.get(OutputKeys.METHOD);
+ if(null != method)
+ m_outputFormat = new OutputProperties(method);
+ else
+ m_outputFormat = new OutputProperties();
+ }
+
+ m_outputFormat.copyFrom(m_stylesheetRoot.getOutputProperties());
+ if(null != oformat)
+ {
+ m_outputFormat.copyFrom(oformat);
+ }
}
}
@@ -1085,10 +1089,13 @@
public void transform(Source xmlSource, Result outputTarget)
throws TransformerException
{
- ContentHandler handler = createResultContentHandler(outputTarget);
-
- this.setContentHandler(handler);
- transform(xmlSource);
+ synchronized(m_reentryGuard)
+ {
+ ContentHandler handler = createResultContentHandler(outputTarget);
+
+ this.setContentHandler(handler);
+ transform(xmlSource);
+ }
}
/**
@@ -1121,68 +1128,72 @@
*/
public void transformNode(Node node) throws TransformerException
{
- m_hasBeenReset = false;
-
- try
+ // Make sure we're not writing to the same output content handler.
+ synchronized(m_outputContentHandler)
{
- pushGlobalVars(node);
-
- // ==========
- // Give the top-level templates a chance to pass information into
- // the context (this is mainly for setting up tables for extensions).
- StylesheetRoot stylesheet = this.getStylesheet();
- int n = stylesheet.getGlobalImportCount();
-
- for (int i = 0; i < n; i++)
+ m_hasBeenReset = false;
+
+ try
{
- StylesheetComposed imported = stylesheet.getGlobalImport(i);
-
- int includedCount = imported.getIncludeCountComposed();
-
- for (int j = -1; j < includedCount; j++)
+ pushGlobalVars(node);
+
+ // ==========
+ // Give the top-level templates a chance to pass information into
+ // the context (this is mainly for setting up tables for extensions).
+ StylesheetRoot stylesheet = this.getStylesheet();
+ int n = stylesheet.getGlobalImportCount();
+
+ for (int i = 0; i < n; i++)
{
- Stylesheet included = imported.getIncludeComposed(j);
-
- included.runtimeInit(this);
-
- for (ElemTemplateElement child = included.getFirstChildElem();
- child != null; child = child.getNextSiblingElem())
+ StylesheetComposed imported = stylesheet.getGlobalImport(i);
+
+ int includedCount = imported.getIncludeCountComposed();
+
+ for (int j = -1; j < includedCount; j++)
{
- child.runtimeInit(this);
+ Stylesheet included = imported.getIncludeComposed(j);
+
+ included.runtimeInit(this);
+
+ for (ElemTemplateElement child = included.getFirstChildElem();
+ child != null; child = child.getNextSiblingElem())
+ {
+ child.runtimeInit(this);
+ }
}
}
+
+ // ===========
+ // System.out.println("Calling applyTemplateToNode -
"+Thread.currentThread().getName());
+ this.applyTemplateToNode(null, null, node, null);
+ // System.out.println("Done with applyTemplateToNode -
"+Thread.currentThread().getName());
+
+ if (null != m_resultTreeHandler)
+ {
+ m_resultTreeHandler.endDocument();
+ }
}
-
- // ===========
- // System.out.println("Calling applyTemplateToNode -
"+Thread.currentThread().getName());
- this.applyTemplateToNode(null, null, node, null);
- // System.out.println("Done with applyTemplateToNode -
"+Thread.currentThread().getName());
-
- if (null != m_resultTreeHandler)
+ catch (Exception se)
{
- m_resultTreeHandler.endDocument();
- }
- }
- catch (Exception se)
- {
- // System.out.println(Thread.currentThread().getName()+" threw an
exception! "
- // +se.getMessage());
- // If an exception was thrown, we need to make sure that any waiting
- // handlers can terminate, which I guess is best done by sending
- // an endDocument.
- if (null != m_resultTreeHandler)
- {
- try
+ // System.out.println(Thread.currentThread().getName()+" threw an
exception! "
+ // +se.getMessage());
+ // If an exception was thrown, we need to make sure that any waiting
+ // handlers can terminate, which I guess is best done by sending
+ // an endDocument.
+ if (null != m_resultTreeHandler)
{
- m_resultTreeHandler.endDocument();
+ try
+ {
+ m_resultTreeHandler.endDocument();
+ }
+ catch(Exception e){}
}
- catch(Exception e){}
+ throw new TransformerException(se.getMessage(), se);
}
- throw new TransformerException(se.getMessage(), se);
- }
- finally
- {
- this.reset();
+ finally
+ {
+ this.reset();
+ }
}
}
@@ -1465,9 +1476,12 @@
*/
public void clearParameters()
{
- VariableStack varstack = new VariableStack();
- getXPathContext().setVarStack(varstack);
- m_userParams = null;
+ synchronized(m_reentryGuard)
+ {
+ VariableStack varstack = new VariableStack();
+ getXPathContext().setVarStack(varstack);
+ m_userParams = null;
+ }
}
/**
@@ -1603,7 +1617,10 @@
*/
public void setURIResolver(URIResolver resolver)
{
- getXPathContext().getSourceTreeManager().setURIResolver(resolver);
+ synchronized(m_reentryGuard)
+ {
+ getXPathContext().getSourceTreeManager().setURIResolver(resolver);
+ }
}
/**
@@ -2628,9 +2645,12 @@
public void setErrorListener (ErrorListener listener)
throws IllegalArgumentException
{
- if (listener == null)
- throw new IllegalArgumentException("Null error handler");
- m_errorHandler = listener;
+ synchronized(m_reentryGuard)
+ {
+ if (listener == null)
+ throw new IllegalArgumentException("Null error handler");
+ m_errorHandler = listener;
+ }
}
@@ -2750,7 +2770,10 @@
*/
public boolean isTransformDone()
{
- return m_isTransformDone;
+ synchronized(this)
+ {
+ return m_isTransformDone;
+ }
}
/**
@@ -2759,7 +2782,7 @@
*
* @param e The exception that was thrown.
*/
- void postExceptionFromThread(Exception e)
+ void postExceptionFromThread(Exception e)
{
// Commented out in response to problem reported by Nicola Brown <[EMAIL
PROTECTED]>
// if(m_reportInPostExceptionFromThread)
@@ -2812,7 +2835,6 @@
try
{
-
// Node n = ((SourceTreeHandler)getInputContentHandler()).getRoot();
// transformNode(n);
if (isParserEventsOnMain())