You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by jk...@apache.org on 2001/04/23 00:08:28 UTC
cvs commit: xml-xalan/java/src/org/apache/xml/dtm DTMBuilder.java DTMSafeStringPool.java CoroutineManager.java CoroutineParser.java CoroutineSAXParser.java CoroutineSAXParser_Xerces.java DTMStringPool.java
jkesselm 01/04/22 15:08:28
Modified: java/src/org/apache/xml/dtm Tag: DTM_EXP
CoroutineManager.java CoroutineParser.java
CoroutineSAXParser.java
CoroutineSAXParser_Xerces.java DTMStringPool.java
Added: java/src/org/apache/xml/dtm Tag: DTM_EXP DTMBuilder.java
DTMSafeStringPool.java
Log:
Many changes related to supporting the DTM Builder.
String pool and coroutine parser layers now have built-in
unit-test drivers; see their main()s.
The calls from DTMBuilder to DTM still need a lot of work to
polish exactly what pools are used and what filtering goes on
during DTM build. More importantly, the whole startup sequence
needs to be properly architected -- the DTM, builder and
parser have cross-awareness of each other and someone
needs to decide who creates what and/or connects to what
in what order.
In Progress!
Revision Changes Path
No revision
No revision
1.1.2.6 +1 -1 xml-xalan/java/src/org/apache/xml/dtm/Attic/CoroutineManager.java
Index: CoroutineManager.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/CoroutineManager.java,v
retrieving revision 1.1.2.5
retrieving revision 1.1.2.6
diff -u -r1.1.2.5 -r1.1.2.6
--- CoroutineManager.java 2001/04/14 02:37:10 1.1.2.5
+++ CoroutineManager.java 2001/04/22 22:08:27 1.1.2.6
@@ -255,7 +255,7 @@
* a registered member of this group. %REVIEW% whether this is the
* best choice.
* */
- public Object co_entry_pause(int thisCoroutine) throws java.lang.NoSuchMethodException
+ public synchronized Object co_entry_pause(int thisCoroutine) throws java.lang.NoSuchMethodException
{
if(!m_activeIDs.get(thisCoroutine))
throw new java.lang.NoSuchMethodException();
1.1.2.4 +15 -2 xml-xalan/java/src/org/apache/xml/dtm/Attic/CoroutineParser.java
Index: CoroutineParser.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/CoroutineParser.java,v
retrieving revision 1.1.2.3
retrieving revision 1.1.2.4
diff -u -r1.1.2.3 -r1.1.2.4
--- CoroutineParser.java 2001/04/14 02:37:10 1.1.2.3
+++ CoroutineParser.java 2001/04/22 22:08:27 1.1.2.4
@@ -55,13 +55,14 @@
* <http://www.apache.org/>.
*/
-//package org.apache.xerces.parsers;
-package org.apache.xalan.xml.dtm;
+package org.apache.xml.dtm;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import java.io.IOException;
import org.apache.xml.dtm.CoroutineManager;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.ContentHandler;
/** <p>CoroutineParser is an API for parser threads that operate as
* coroutines. See CoroutineSAXParser and CoroutineSAXParser_Xerces
@@ -88,6 +89,18 @@
* you're talking to.
* */
public int getParserCoroutine();
+
+ /** Register a SAX-style content handler for us to output to */
+ public void setContentHandler(ContentHandler handler);
+
+ /** Register a SAX-style lexical handler for us to output to
+ * Not all parsers support this...
+ *
+ * %REVIEW% Not called setLexicalHandler because Xalan uses that name
+ * internally, which causes subclassing nuisances.
+ */
+ public void setLexHandler(org.xml.sax.ext.LexicalHandler handler);
+
/**
* This coroutine (thread) can be resumed with the following arguments:
1.1.2.3 +124 -86 xml-xalan/java/src/org/apache/xml/dtm/Attic/CoroutineSAXParser.java
Index: CoroutineSAXParser.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/CoroutineSAXParser.java,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- CoroutineSAXParser.java 2001/04/17 16:50:20 1.1.2.2
+++ CoroutineSAXParser.java 2001/04/22 22:08:27 1.1.2.3
@@ -55,98 +55,37 @@
* <http://www.apache.org/>.
*/
-//package org.apache.xerces.parsers;
-package org.apache.xalan.xml.dtm;
+package org.apache.xml.dtm;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.Attributes;
-import org.xml.sax.ext.LexicalHandler;
import java.io.IOException;
import org.apache.xml.dtm.CoroutineManager;
-/** <p>CoroutineSAXParser illustrates how to run a SAX2 parser in a
- * coroutine to achieve incremental parsing. Output from the parser
- * will still be issued via callbacks, which will need to be recieved
- * and acted upon by an appopriate handler. But those callbacks will
- * pass through a counting stage which periodically yields control
- * back to the other coroutines in this set.</p>
- *
- * Usage is something like this:
- * <code>
- * CoroutineManager co = new CoroutineManager()
- * int appCoroutine = co.co_joinCoroutineSet(-1);
- * if (appCoroutine == -1) { [[error handling]] }
- * CoroutineParser parser = CoroutineSAXParser.createCoroutineparser(co, appCoroutine,theSAXParserBeingWrapped);
- * int parserCoroutine = parser.getParserCoroutine();
- * [[register typical SAX handlers with the parser]]
- *
- * ...
- *
- * InputSource source = [[document source]];
- * Object result = co.co_resume(source, appCoroutine, parserCoroutine);
- * if (result == null) {
- * [[cannot happen here, only if we ask parser to terminate]]
- * }
- * else if (result instanceof Boolean) {
- * if (((Boolean)result).booleanValue()) {
- * [[document open, ready to proceed]]
- * }
- * else {
- * [[document not open, but no exception? I think that this might
- * relate to the continue-on-fatal-error feature, but obviously
- * we cannot continue in this case...]]
- * }
- * }
- * else if (result instanceof Exception) {
- * [[process error]]
- * }
- *
- * ...
+/** <p>CoroutineSAXParser runs a SAX2 parser in a coroutine to achieve
+ * incremental parsing. Output from the parser will still be issued
+ * via callbacks, which will need to be recieved and acted upon by an
+ * appopriate handler. But those callbacks will pass through a
+ * counting stage which periodically yields control back to the other
+ * coroutines in this set.</p>
*
- * [[nothing in queue to process, so run the parser coroutine]]
- * Object result = co.co_resume(Boolean.TRUE, appCoroutine, parserCoroutine);
- * if (result == null) {
- * [[cannot happen here, only if we ask parser to terminate]]
- * }
- * else if (result instanceof Boolean) {
- * if (((Boolean)result).booleanValue()) {
- * [[some parsing has been performed and
- * the end of the document has not been seen]]
- * }
- * else {
- * [[some parsing might have been performed and
- * the end of the document has been seen]]
- * }
- * }
- * else if (result instanceof Exception) {
- * [[process error during parsing]]
- * }
+ * <p>For a brief usage example, see the unit-test main() method.</p>
*
- * ...
+ * <p>Status: Passes simple main() unit-test</p>
*
- * [[reset the parser coroutine]]
- * Object result = co.co_resume(Boolean.FALSE, appCoroutine, parserCoroutine);
- * [[returns Boolean.FALSE, expect next InputSource]]
- *
- * ...
- *
- * [[terminate the parser coroutine]]
- * Object result = co.co_resume(null, appCoroutine, parserCoroutine);
- * [[returns null]]
- * </code>
- *
- * <p>Status: In progress</p>
- *
* %TBD% Javadoc needs lots of work.
* */
public class CoroutineSAXParser
implements CoroutineParser, Runnable, ContentHandler, LexicalHandler {
+ boolean DEBUG=false; //Internal status report
+
//
// Data
//
@@ -212,7 +151,8 @@
// Register a lexical handler for us to output to
// Not all parsers support this...
// ??? Should we register directly on the parser?
- public void setLexicalHandler(LexicalHandler handler)
+ // NOTE NAME.
+ public void setLexHandler(LexicalHandler handler)
{
clientLexicalHandler=handler;
}
@@ -441,7 +381,7 @@
* */
void count_and_yield(boolean moreExpected)
{
- if(!moreExpected) eventCounter=0;
+ if(!moreExpected) eventcounter=0;
if(--eventcounter<=0)
{
@@ -522,7 +462,8 @@
*
* InputSource setup to read from this source.
* resumes with:
- * co_resume(Boolean.TRUE, ...) on success.
+ * co_resume(Boolean.TRUE, ...) on partial parse
+ * co_resume(Boolean.FALSE, ...) on complete parse
* co_resume(Exception, ...) on error.
*
* %REVEIW% Should this be able to set listeners? Partner coroutine ID?
@@ -537,6 +478,7 @@
// Shut down requested.
if (arg == null) {
+ if(DEBUG)System.out.println("CoroutineSAXParser at-rest shutdown requested");
fCoroutineManager.co_exit_to(arg, fParserCoroutine, fAppCoroutine);
break;
}
@@ -548,20 +490,33 @@
// middle of a synchronous method.
if (arg instanceof InputSource) {
try {
+ if(DEBUG)System.out.println("Inactive CoroutineSAXParser new parse "+arg);
xmlreader.parse((InputSource)arg);
arg=Boolean.TRUE;
}
- catch (UserRequestedStopException e)
- {
+
+ catch (SAXException ex) {
+ Exception inner=ex.getException();
+ if(inner instanceof UserRequestedStopException){
+ if(DEBUG)System.out.println("Active CoroutineSAXParser user stop exception");
arg=Boolean.FALSE;
}
- catch (UserRequestedShutdownException e)
- {
- break;
+ else if(inner instanceof UserRequestedShutdownException){
+ if(DEBUG)System.out.println("Active CoroutineSAXParser user shutdown exception");
+ break;
}
- catch (Exception ex) {
- arg = ex;
+ else {
+ if(DEBUG)System.out.println("Active CoroutineSAXParser UNEXPECTED SAX exception: "+ex);
+ arg=ex;
+ }
+
}
+ catch(Exception ex)
+ {
+ if(DEBUG)System.out.println("Active CoroutineSAXParser non-SAX exception: "+ex);
+ arg = ex;
+ }
+
}
else // Unexpected!
@@ -587,15 +542,98 @@
class UserRequestedStopException extends RuntimeException
{
}
- // Instance so we don't have to create a new one each time
UserRequestedStopException stopException=new UserRequestedStopException();
-
+
/** Used so co_yield can return control to run for coroutine thread
* termination. */
class UserRequestedShutdownException extends RuntimeException
{
}
- // Instance so we don't have to create a new one each time
UserRequestedShutdownException shutdownException=new UserRequestedShutdownException();
+ //================================================================
+ /** Simple unit test. Attempt coroutine parsing of document indicated
+ * by first argument (as a URI), report progress.
+ */
+ public static void main(String args[])
+ {
+ System.out.println("Starting...");
+
+ org.xml.sax.XMLReader theSAXParser=
+ new org.apache.xerces.parsers.SAXParser();
+
+ CoroutineManager co = new CoroutineManager();
+ int appCoroutine = co.co_joinCoroutineSet(-1);
+ if (appCoroutine == -1)
+ {
+ System.out.println("ERROR: Couldn't allocate coroutine number.\n");
+ return;
+ }
+ CoroutineSAXParser parser=
+ new CoroutineSAXParser(co, appCoroutine, theSAXParser);
+ int parserCoroutine = parser.getParserCoroutine();
+
+ // Use a serializer as our sample output
+ org.apache.xml.serialize.XMLSerializer trace;
+ trace=new org.apache.xml.serialize.XMLSerializer(System.out,null);
+ parser.setContentHandler(trace);
+ parser.setLexHandler(trace);
+
+ // Tell coroutine to begin parsing, run while parsing is in progress
+ for(int arg=0;arg<args.length;++arg)
+ {
+ try
+ {
+ InputSource source = new InputSource(args[arg]);
+ Object result=null;
+ Boolean more=Boolean.TRUE;
+ for(result = co.co_resume(source, appCoroutine, parserCoroutine);
+ (result instanceof Boolean && ((Boolean)result)==Boolean.TRUE);
+ result = co.co_resume(more, appCoroutine, parserCoroutine))
+ {
+ System.out.println("\nSome parsing successful, trying more.\n");
+
+ // Special test: Terminate parsing early.
+ if(arg+1<args.length && "!".equals(args[arg+1]))
+ {
+ ++arg;
+ more=Boolean.FALSE;
+ }
+
+ }
+
+ if (result instanceof Boolean && ((Boolean)result)==Boolean.FALSE)
+ {
+ System.out.println("\nParser ended (EOF or on request).\n");
+ }
+ else if (result == null) {
+ System.out.println("\nUNEXPECTED: Parser says shut down prematurely.\n");
+ }
+ else if (result instanceof Exception) {
+ System.out.println("\nParser threw exception:");
+ ((Exception)result).printStackTrace();
+ }
+
+ }
+ catch(java.lang.NoSuchMethodException e)
+ {
+ System.out.println("\nUNEXPECTED Coroutine not resolved:");
+ e.printStackTrace();
+ }
+ }
+
+ try
+ {
+ System.out.println("Requesting parser shutdown");
+ Object result = co.co_resume(null, appCoroutine, parserCoroutine);
+ if(result!=null)
+ System.out.println("\nUNEXPECTED: Parser co-shutdown answers "+result);
+ }
+ catch(java.lang.NoSuchMethodException e)
+ {
+ System.out.println("\nUNEXPECTED Coroutine not resolved:");
+ e.printStackTrace();
+ }
+ }
+
} // class CoroutineSAXParser
1.1.2.2 +109 -67 xml-xalan/java/src/org/apache/xml/dtm/Attic/CoroutineSAXParser_Xerces.java
Index: CoroutineSAXParser_Xerces.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/CoroutineSAXParser_Xerces.java,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- CoroutineSAXParser_Xerces.java 2001/04/13 21:43:25 1.1.2.1
+++ CoroutineSAXParser_Xerces.java 2001/04/22 22:08:27 1.1.2.2
@@ -56,7 +56,7 @@
*/
//package org.apache.xerces.parsers;
-package org.apache.xalan.xml.dtm;
+package org.apache.xml.dtm;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@@ -68,76 +68,14 @@
* will still be issued via callbacks, which will need to be recieved
* and acted upon by an appopriate handler.</p>
*
- * Usage is something like this:
- * <code>
- * CoroutineManager co = new CoroutineManager()
- * int appCoroutine = co.co_joinCoroutineSet(-1);
- * if (appCoroutine == -1) { [[error handling]] }
- * CoroutineParser parser = CoroutineSAXParser_Xerces.createCoroutineparser(co, appCoroutine);
- * int parserCoroutine = parser.getParserCoroutine();
- * [[register typical SAX handlers with the parser]]
+ * <p>Usage example: See main().</p>
*
- * ...
- *
- * InputSource source = [[document source]];
- * Object result = co.co_resume(source, appCoroutine, parserCoroutine);
- * if (result == null) {
- * [[cannot happen here, only if we ask parser to terminate]]
- * }
- * else if (result instanceof Boolean) {
- * if (((Boolean)result).booleanValue()) {
- * [[document open, ready to proceed]]
- * }
- * else {
- * [[document not open, but no exception? I think that this might
- * relate to the continue-on-fatal-error feature, but obviously
- * we cannot continue in this case...]]
- * }
- * }
- * else if (result instanceof Exception) {
- * [[process error]]
- * }
- *
- * ...
- *
- * [[nothing in queue to process, so run the parser coroutine]]
- * Object result = co.co_resume(Boolean.TRUE, appCoroutine, parserCoroutine);
- * if (result == null) {
- * [[cannot happen here, only if we ask parser to terminate]]
- * }
- * else if (result instanceof Boolean) {
- * if (((Boolean)result).booleanValue()) {
- * [[some parsing has been performed and
- * the end of the document has not been seen]]
- * }
- * else {
- * [[some parsing might have been performed and
- * the end of the document has been seen]]
- * }
- * }
- * else if (result instanceof Exception) {
- * [[process error during parsing]]
- * }
- *
- * ...
- *
- * [[reset the parser coroutine]]
- * Object result = co.co_resume(Boolean.FALSE, appCoroutine, parserCoroutine);
- * [[returns Boolean.FALSE, expect next InputSource]]
- *
- * ...
- *
- * [[terminate the parser coroutine]]
- * Object result = co.co_resume(null, appCoroutine, parserCoroutine);
- * [[returns null]]
- * </code>
- *
- * <p>Status: In progress</p>
- *
+ * <p>Status: Passes simple main() unit-test</p>
* */
public class CoroutineSAXParser_Xerces
extends org.apache.xerces.parsers.SAXParser
-implements CoroutineParser, Runnable {
+implements CoroutineParser, Runnable
+{
//
// Data
@@ -183,6 +121,28 @@
return fParserCoroutine;
}
+ // Note name, needed to dodge the inherited Xerces setLexicalHandler
+ // which isn't public.
+ public void setLexHandler(org.xml.sax.ext.LexicalHandler handler)
+ {
+ // Not supported by all SAX2 parsers but should work in Xerces:
+ try
+ {
+ setProperty("http://xml.org/sax/properties/lexical-handler",
+ this);
+ }
+ catch(org.xml.sax.SAXNotRecognizedException e)
+ {
+ // Nothing we can do about it
+ }
+ catch(org.xml.sax.SAXNotSupportedException e)
+ {
+ // Nothing we can do about it
+ }
+ }
+
+
+
/**
* This coroutine (thread) can be resumed with the following arguments:
*
@@ -263,4 +223,86 @@
}
}
+
+ //================================================================
+ /** Simple unit test. Attempt coroutine parsing of document indicated
+ * by first argument (as a URI), report progress.
+ */
+ public static void main(String args[])
+ {
+ System.out.println("Starting...");
+
+ CoroutineManager co = new CoroutineManager();
+ int appCoroutine = co.co_joinCoroutineSet(-1);
+ if (appCoroutine == -1)
+ {
+ System.out.println("ERROR: Couldn't allocate coroutine number.\n");
+ return;
+ }
+ CoroutineSAXParser_Xerces parser=
+ new CoroutineSAXParser_Xerces(co, appCoroutine);
+ int parserCoroutine = parser.getParserCoroutine();
+
+ // Use a serializer as our sample output
+ org.apache.xml.serialize.XMLSerializer trace;
+ trace=new org.apache.xml.serialize.XMLSerializer(System.out,null);
+ parser.setContentHandler(trace);
+ parser.setLexHandler(trace);
+
+ // Tell coroutine to begin parsing, run while parsing is in progress
+ for(int arg=0;arg<args.length;++arg)
+ {
+ try
+ {
+ InputSource source = new InputSource(args[arg]);
+ Object result=null;
+ Boolean more=Boolean.TRUE;
+ for(result = co.co_resume(source, appCoroutine, parserCoroutine);
+ (result instanceof Boolean && ((Boolean)result)==Boolean.TRUE);
+ result = co.co_resume(more, appCoroutine, parserCoroutine))
+ {
+ System.out.println("\nSome parsing successful, trying more.\n");
+
+ // Special test: Terminate parsing early.
+ if(arg+1<args.length && "!".equals(args[arg+1]))
+ {
+ ++arg;
+ more=Boolean.FALSE;
+ }
+
+ }
+
+ if (result instanceof Boolean && ((Boolean)result)==Boolean.FALSE)
+ {
+ System.out.println("\nParser ended (EOF or on request).\n");
+ }
+ else if (result == null) {
+ System.out.println("\nUNEXPECTED: Parser says shut down prematurely.\n");
+ }
+ else if (result instanceof Exception) {
+ System.out.println("\nParser threw exception:");
+ ((Exception)result).printStackTrace();
+ }
+
+ }
+ catch(java.lang.NoSuchMethodException e)
+ {
+ System.out.println("\nUNEXPECTED Coroutine not resolved:");
+ e.printStackTrace();
+ }
+ }
+
+ try
+ {
+ System.out.println("Requesting parser shutdown");
+ Object result = co.co_resume(null, appCoroutine, parserCoroutine);
+ if(result!=null)
+ System.out.println("\nUNEXPECTED: Parser co-shutdown answers "+result);
+ }
+ catch(java.lang.NoSuchMethodException e)
+ {
+ System.out.println("\nUNEXPECTED Coroutine not resolved:");
+ e.printStackTrace();
+ }
+ }
} // class CoroutineSAXParser_Xerces
1.1.2.3 +1 -1 xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMStringPool.java
Index: DTMStringPool.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMStringPool.java,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- DTMStringPool.java 2001/04/20 15:33:25 1.1.2.2
+++ DTMStringPool.java 2001/04/22 22:08:27 1.1.2.3
@@ -86,7 +86,7 @@
* it's safer that way, but this could trivially be turned into a general
* ObjectPool if one was needed.</p>
*
- * <p>Status: In progress</p>
+ * <p>Status: Passed basic test in main().</p>
* */
public class DTMStringPool
{
No revision
No revision
1.1.2.1 +444 -0 xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMBuilder.java
1.1.2.1 +147 -0 xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMSafeStringPool.java
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org