From 362ae2e7427c13c9565ef59b0a0d821a8750dc54 Mon Sep 17 00:00:00 2001 From: Willem Cazander Date: Sat, 8 Mar 2014 18:04:03 +0100 Subject: [PATCH] Made debug output partialy working again. --- .../org/x4o/xml/io/AbstractX4OConnection.java | 121 +++++++++ .../java/org/x4o/xml/io/DefaultX4OReader.java | 95 ++----- .../java/org/x4o/xml/io/DefaultX4OWriter.java | 15 +- .../org/x4o/xml/io/sax/X4OContentParser.java | 47 +++- .../org/x4o/xml/io/sax/X4ODebugWriter.java | 247 ++++++++++++++---- .../x4o/xml/io/sax/ext/PropertyConfig.java | 1 - .../xml/lang/AbstractX4OLanguageSession.java | 16 +- .../org/x4o/xml/lang/X4OLanguageSession.java | 8 +- .../lang/phase/DefaultX4OPhaseManager.java | 13 +- .../xml/lang/phase/X4OPhaseLanguageInit.java | 2 +- .../xml/lang/phase/X4OPhaseLanguageRead.java | 139 +--------- .../xml/lang/phase/X4OPhaseLanguageWrite.java | 2 +- .../x4o/xml/lang/phase/X4OPhaseListener.java | 4 +- .../x4o/xml/lang/phase/X4OPhaseManager.java | 24 +- .../xml/lang/phase/X4OPhaseManagerLocal.java | 35 +++ .../org/x4o/xml/core/X4ODebugWriterTest.java | 58 +++- .../org/x4o/xml/core/X4OPhaseManagerTest.java | 5 +- .../lang/DefaultX4OLanguageLoaderTest.java | 42 +-- 18 files changed, 524 insertions(+), 350 deletions(-) create mode 100644 x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseManagerLocal.java diff --git a/x4o-driver/src/main/java/org/x4o/xml/io/AbstractX4OConnection.java b/x4o-driver/src/main/java/org/x4o/xml/io/AbstractX4OConnection.java index 12822f6..22e4f6e 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/io/AbstractX4OConnection.java +++ b/x4o-driver/src/main/java/org/x4o/xml/io/AbstractX4OConnection.java @@ -22,12 +22,28 @@ */ package org.x4o.xml.io; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.x4o.xml.io.sax.X4ODebugWriter; +import org.x4o.xml.io.sax.ext.ContentWriter; +import org.x4o.xml.io.sax.ext.ContentWriterXml; import org.x4o.xml.io.sax.ext.PropertyConfig; import org.x4o.xml.lang.X4OLanguage; +import org.x4o.xml.lang.X4OLanguageSession; +import org.x4o.xml.lang.X4OLanguageSessionLocal; +import org.x4o.xml.lang.phase.X4OPhase; +import org.x4o.xml.lang.phase.X4OPhaseException; +import org.x4o.xml.lang.phase.X4OPhaseLanguageRead; +import org.x4o.xml.lang.phase.X4OPhaseLanguageWrite; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; /** * AbstractX4OConnection is the read/write interface for the classes. @@ -38,8 +54,12 @@ import org.x4o.xml.lang.X4OLanguage; public abstract class AbstractX4OConnection implements X4OConnection { private final X4OLanguage language; + private boolean debugStarted = false; + private OutputStream debugCloseOutputStream = null; protected String phaseStop = null; protected List phaseSkip = null; + protected final static String ABSTRACT_DEBUG_OUTPUT_HANDLER = "debug/output-handler"; + protected final static String ABSTRACT_DEBUG_OUTPUT_STREAM = "debug/output-stream"; public AbstractX4OConnection(X4OLanguage language) { this.language=language; @@ -76,4 +96,105 @@ public abstract class AbstractX4OConnection implements X4OConnection { public void addPhaseSkip(String phaseId) { phaseSkip.add( phaseId ); } + + protected void debugStart(X4OLanguageSession languageSession,String debugHandlerKey,String debugStreamKey) throws UnsupportedEncodingException, SAXException { + Object debugOutputHandler = getProperty(debugHandlerKey); + Object debugOutputStream = getProperty(debugStreamKey); + if (languageSession.getX4ODebugWriter()==null) { + ContentWriter xmlDebugWriter = null; + if (debugOutputHandler instanceof ContentWriter) { + xmlDebugWriter = (ContentWriter)debugOutputHandler; + } else if (debugOutputStream instanceof OutputStream) { + debugCloseOutputStream = (OutputStream)debugOutputStream; + xmlDebugWriter = new ContentWriterXml(debugCloseOutputStream); + } + if (xmlDebugWriter!=null) { + xmlDebugWriter.startDocument(); + xmlDebugWriter.startPrefixMapping("debug", X4ODebugWriter.DEBUG_URI); + X4ODebugWriter debugWriter = new X4ODebugWriter(xmlDebugWriter); + X4OLanguageSessionLocal local = (X4OLanguageSessionLocal)languageSession; + local.setX4ODebugWriter(debugWriter); + + // We only close if we started it, this is for recursief debugging. + debugStarted = true; + } + } + + // debug language + if (languageSession.hasX4ODebugWriter()) { + languageSession.getX4ODebugWriter().debugConnectionStart(languageSession, this); + + // Add debug phases for all phases + for (String key:languageSession.getLanguage().getPhaseManager().getPhaseKeys()) { + X4OPhase p = languageSession.getLanguage().getPhaseManager().getPhase(key); + + p.addPhaseListener(languageSession.getX4ODebugWriter().createDebugX4OPhaseListener()); + + if (shouldPrintTree(p)) { + p.addPhaseListener(languageSession.getX4ODebugWriter().createDebugPrintTreePhaseListener()); + } + } + } + } + + private boolean shouldPrintTree(X4OPhase p) { + String phase = p.getId(); + if (X4OPhaseLanguageWrite.WRITE_END.equals(phase)) { + return true; + } + if (X4OPhaseLanguageRead.READ_END.equals(phase)) { + return true; + } + if (X4OPhaseLanguageRead.READ_RUN_ATTRIBUTE.equals(phase)) { + return true; + } + if (X4OPhaseLanguageRead.READ_TRANSFORM.equals(phase)) { + return true; + } + if (X4OPhaseLanguageRead.READ_BIND_ELEMENT.equals(phase)) { + return true; + } + return false; + } + + protected void debugException(X4OLanguageSession languageSession,Exception e) { + if (languageSession.hasX4ODebugWriter()) { + try { + AttributesImpl atts = new AttributesImpl(); + atts.addAttribute ("", "message", "", "", e.getMessage()); + if (e instanceof X4OPhaseException) { + atts.addAttribute ("", "phase", "", "", ((X4OPhaseException)e).getX4OPhaseHandler().getId()); + } + languageSession.getX4ODebugWriter().getContentWriter().startElement(X4ODebugWriter.DEBUG_URI, "exceptionStackTrace", "", atts); + StringWriter writer = new StringWriter(); + PrintWriter printer = new PrintWriter(writer); + printer.append('\n'); + if (e.getCause()==null) { + e.printStackTrace(printer); + } else { + e.getCause().printStackTrace(printer); + } + char[] stack = writer.getBuffer().toString().toCharArray(); + languageSession.getX4ODebugWriter().getContentWriter().characters(stack, 0, stack.length); + languageSession.getX4ODebugWriter().getContentWriter().endElement(X4ODebugWriter.DEBUG_URI, "exceptionStackTrace", ""); + } catch (Exception ee) { + // TODO print e; + //logger.warning(ee.getMessage()); + } + } + } + + protected void debugStop(X4OLanguageSession languageSession) throws SAXException, IOException { + if (languageSession.hasX4ODebugWriter()) { + languageSession.getX4ODebugWriter().debugConnectionEnd(); + } + if (debugStarted && languageSession.hasX4ODebugWriter()) { + languageSession.getX4ODebugWriter().getContentWriter().endPrefixMapping("debug"); + languageSession.getX4ODebugWriter().getContentWriter().endDocument(); + if (debugCloseOutputStream!=null) { + debugCloseOutputStream.flush(); + debugCloseOutputStream.close(); // need this here ? + } + } + } } diff --git a/x4o-driver/src/main/java/org/x4o/xml/io/DefaultX4OReader.java b/x4o-driver/src/main/java/org/x4o/xml/io/DefaultX4OReader.java index f95b10f..f9c94ab 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/io/DefaultX4OReader.java +++ b/x4o-driver/src/main/java/org/x4o/xml/io/DefaultX4OReader.java @@ -26,18 +26,13 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.StringWriter; import java.net.URL; -import java.util.logging.Logger; import javax.el.ValueExpression; import javax.xml.parsers.ParserConfigurationException; import org.x4o.xml.io.sax.X4OContentParser; -import org.x4o.xml.io.sax.X4ODebugWriter; import org.x4o.xml.io.sax.ext.ContentWriter; -import org.x4o.xml.io.sax.ext.ContentWriterXml; import org.x4o.xml.io.sax.ext.PropertyConfig; import org.x4o.xml.io.sax.ext.PropertyConfig.PropertyConfigItem; import org.x4o.xml.lang.X4OLanguage; @@ -49,7 +44,6 @@ import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import org.xml.sax.helpers.AttributesImpl; /** * DefaultX4OReader can read and parse the xml language. @@ -59,9 +53,6 @@ import org.xml.sax.helpers.AttributesImpl; */ public class DefaultX4OReader extends AbstractX4OReader { - /** The logger to log to. */ - private Logger logger = null; - private X4OLanguageSession languageSession = null; private final PropertyConfig propertyConfig; @@ -82,6 +73,8 @@ public class DefaultX4OReader extends AbstractX4OReader { public final static String VALIDATION_SCHEMA_PATH = PROPERTY_CONTEXT_PREFIX + "validation/schema-path"; public final static String VALIDATION_INPUT_DOC = PROPERTY_CONTEXT_PREFIX + "validation/input-doc"; public final static String VALIDATION_INPUT_SCHEMA = PROPERTY_CONTEXT_PREFIX + "validation/input-schema"; + public final static String DEBUG_OUTPUT_HANDLER = PROPERTY_CONTEXT_PREFIX + ABSTRACT_DEBUG_OUTPUT_HANDLER; + public final static String DEBUG_OUTPUT_STREAM = PROPERTY_CONTEXT_PREFIX + ABSTRACT_DEBUG_OUTPUT_STREAM; static { DEFAULT_PROPERTY_CONFIG = new PropertyConfig(true,null,PROPERTY_CONTEXT_PREFIX, @@ -97,13 +90,14 @@ public class DefaultX4OReader extends AbstractX4OReader { new PropertyConfigItem(VALIDATION_SCHEMA_AUTO_WRITE,Boolean.class,true), new PropertyConfigItem(VALIDATION_SCHEMA_PATH,File.class), new PropertyConfigItem(VALIDATION_INPUT_DOC,Boolean.class,false), - new PropertyConfigItem(VALIDATION_INPUT_SCHEMA,Boolean.class,false) + new PropertyConfigItem(VALIDATION_INPUT_SCHEMA,Boolean.class,false), + new PropertyConfigItem(DEBUG_OUTPUT_HANDLER,ContentWriter.class), + new PropertyConfigItem(DEBUG_OUTPUT_STREAM,OutputStream.class) ); } public DefaultX4OReader(X4OLanguage language) { super(language); - logger = Logger.getLogger(DefaultX4OReader.class.getName()); languageSession = language.createLanguageSession(); propertyConfig = new PropertyConfig(DEFAULT_PROPERTY_CONFIG,PROPERTY_CONTEXT_PREFIX); } @@ -139,11 +133,12 @@ public class DefaultX4OReader extends AbstractX4OReader { * Parses the input stream as a X4O document. */ protected void read() throws X4OConnectionException,SAXException,IOException { + // Extra check if we have a language if (languageSession.getLanguage()==null) { throw new X4OConnectionException("languageSession is broken getLanguage() returns null."); } - + // Insert stop/skip phase if we allowed to. TODO: move layer ? if (languageSession instanceof X4OLanguageSessionLocal) { X4OLanguageSessionLocal ll = (X4OLanguageSessionLocal)languageSession; if (phaseStop!=null) { @@ -154,69 +149,22 @@ public class DefaultX4OReader extends AbstractX4OReader { } } - // init debugWriter if enabled - boolean startedDebugWriter = false; - Object debugOutputHandler = null; //TODO: getProperty(X4OLanguageProperty.DEBUG_OUTPUT_HANDLER.name()); - Object debugOutputStream = null; //getProperty(X4OLanguageProperty.DEBUG_OUTPUT_STREAM.name()); - if (languageSession.getX4ODebugWriter()==null) { - ContentWriter xmlDebugWriter = null; - if (debugOutputHandler instanceof ContentWriter) { - xmlDebugWriter = (ContentWriter)debugOutputHandler; - } else if (debugOutputStream instanceof OutputStream) { - xmlDebugWriter = new ContentWriterXml((OutputStream)debugOutputStream); - } - if (xmlDebugWriter!=null) { - xmlDebugWriter.startDocument(); - xmlDebugWriter.startPrefixMapping("debug", X4ODebugWriter.DEBUG_URI); - X4ODebugWriter debugWriter = new X4ODebugWriter(xmlDebugWriter); - X4OLanguageSessionLocal local = (X4OLanguageSessionLocal)languageSession; - local.setX4ODebugWriter(debugWriter); - startedDebugWriter = true; - } - } + // init debug + debugStart(languageSession, DEBUG_OUTPUT_HANDLER, DEBUG_OUTPUT_STREAM); - // debug language - if (languageSession.hasX4ODebugWriter()) { - AttributesImpl atts = new AttributesImpl(); - atts.addAttribute ("", "language", "", "", languageSession.getLanguage().getLanguageName()); - atts.addAttribute ("", "currentTimeMillis", "", "", System.currentTimeMillis()+""); - languageSession.getX4ODebugWriter().getContentWriter().startElement(X4ODebugWriter.DEBUG_URI, "X4ODriver", "", atts); - } - - // start parsing language try { + // Run document parsing X4OContentParser parser = new X4OContentParser(propertyConfig); parser.parse(languageSession); + // Run phases to build object tree getLanguage().getPhaseManager().runPhases(languageSession, X4OPhaseType.XML_READ); } catch (Exception e) { - // also debug exceptions - if (languageSession.hasX4ODebugWriter()) { - try { - AttributesImpl atts = new AttributesImpl(); - atts.addAttribute ("", "message", "", "", e.getMessage()); - if (e instanceof X4OPhaseException) { - atts.addAttribute ("", "phase", "", "", ((X4OPhaseException)e).getX4OPhaseHandler().getId()); - } - languageSession.getX4ODebugWriter().getContentWriter().startElement(X4ODebugWriter.DEBUG_URI, "exceptionStackTrace", "", atts); - StringWriter writer = new StringWriter(); - PrintWriter printer = new PrintWriter(writer); - printer.append('\n'); - if (e.getCause()==null) { - e.printStackTrace(printer); - } else { - e.getCause().printStackTrace(printer); - } - char[] stack = writer.getBuffer().toString().toCharArray(); - languageSession.getX4ODebugWriter().getContentWriter().characters(stack, 0, stack.length); - languageSession.getX4ODebugWriter().getContentWriter().endElement(X4ODebugWriter.DEBUG_URI, "exceptionStackTrace", ""); - } catch (Exception ee) { - logger.warning(ee.getMessage()); - } - } + debugException(languageSession, e); - // unwrap exception + // unwrap exception + // TODO: cleanup exceptions a bit more see X4OConnectionException if (e.getCause() instanceof ParserConfigurationException) { throw new X4OConnectionException((ParserConfigurationException)e.getCause()); } @@ -232,21 +180,10 @@ public class DefaultX4OReader extends AbstractX4OReader { throw new SAXException((Exception)e.getCause()); } } finally { - if (languageSession.hasX4ODebugWriter()) { - languageSession.getX4ODebugWriter().getContentWriter().endElement(X4ODebugWriter.DEBUG_URI, "X4ODriver", ""); - } - if (startedDebugWriter && languageSession.hasX4ODebugWriter()) { - languageSession.getX4ODebugWriter().getContentWriter().endPrefixMapping("debug"); - languageSession.getX4ODebugWriter().getContentWriter().endDocument(); - if (debugOutputStream instanceof OutputStream) { - OutputStream outputStream = (OutputStream)debugOutputStream; - outputStream.flush(); - outputStream.close(); // need this here ? - } - } + debugStop(languageSession); } } - + public void releaseSession(X4OLanguageSession context) throws X4OPhaseException { if (context==null) { return; diff --git a/x4o-driver/src/main/java/org/x4o/xml/io/DefaultX4OWriter.java b/x4o-driver/src/main/java/org/x4o/xml/io/DefaultX4OWriter.java index d06853b..6bdbb2d 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/io/DefaultX4OWriter.java +++ b/x4o-driver/src/main/java/org/x4o/xml/io/DefaultX4OWriter.java @@ -39,13 +39,13 @@ import org.x4o.xml.element.ElementClassAttribute; import org.x4o.xml.element.ElementInterface; import org.x4o.xml.element.ElementNamespace; import org.x4o.xml.element.ElementObjectPropertyValueException; +import org.x4o.xml.io.sax.ext.ContentWriter; import org.x4o.xml.io.sax.ext.PropertyConfig; import org.x4o.xml.io.sax.ext.ContentWriterXml; import org.x4o.xml.io.sax.ext.PropertyConfig.PropertyConfigItem; import org.x4o.xml.lang.X4OLanguage; import org.x4o.xml.lang.X4OLanguageSession; import org.x4o.xml.lang.X4OLanguageModule; -import org.x4o.xml.lang.phase.X4OPhase; import org.x4o.xml.lang.phase.X4OPhaseException; import org.x4o.xml.lang.phase.X4OPhaseLanguageWrite; import org.x4o.xml.lang.phase.X4OPhaseType; @@ -69,12 +69,16 @@ public class DefaultX4OWriter extends AbstractX4OWriter { public final static String OUTPUT_STREAM = PROPERTY_CONTEXT_PREFIX+"output/stream"; public final static String SCHEMA_PRINT = PROPERTY_CONTEXT_PREFIX+"schema/print"; public final static String SCHEMA_ROOT_URI = PROPERTY_CONTEXT_PREFIX+"schema/root-uri"; + public final static String DEBUG_OUTPUT_HANDLER = PROPERTY_CONTEXT_PREFIX + ABSTRACT_DEBUG_OUTPUT_HANDLER; + public final static String DEBUG_OUTPUT_STREAM = PROPERTY_CONTEXT_PREFIX + ABSTRACT_DEBUG_OUTPUT_STREAM; static { DEFAULT_PROPERTY_CONFIG = new PropertyConfig(true,ContentWriterXml.DEFAULT_PROPERTY_CONFIG,PROPERTY_CONTEXT_PREFIX, new PropertyConfigItem(true,OUTPUT_STREAM,OutputStream.class), new PropertyConfigItem(SCHEMA_PRINT,Boolean.class,true), - new PropertyConfigItem(SCHEMA_ROOT_URI,String.class) + new PropertyConfigItem(SCHEMA_ROOT_URI,String.class), + new PropertyConfigItem(DEBUG_OUTPUT_HANDLER,ContentWriter.class), + new PropertyConfigItem(DEBUG_OUTPUT_STREAM,OutputStream.class) ); } @@ -104,6 +108,7 @@ public class DefaultX4OWriter extends AbstractX4OWriter { public void writeSession(X4OLanguageSession languageSession,OutputStream output) throws X4OConnectionException,SAXException,IOException { setProperty(OUTPUT_STREAM, output); addPhaseSkip(X4OPhaseLanguageWrite.WRITE_RELEASE); + debugStart(languageSession, DEBUG_OUTPUT_HANDLER, DEBUG_OUTPUT_STREAM); try { languageSession.getLanguage().getPhaseManager().runPhases(languageSession, X4OPhaseType.XML_WRITE); } catch (X4OPhaseException e) { @@ -153,8 +158,14 @@ public class DefaultX4OWriter extends AbstractX4OWriter { out.flush(); } catch (Exception e) { + debugException(languageSession, e); throw new X4OConnectionException(e); } finally { + try { + debugStop(languageSession); + } catch (Exception e1) { + // FIXME + } if (out!=null) { try { out.close(); diff --git a/x4o-driver/src/main/java/org/x4o/xml/io/sax/X4OContentParser.java b/x4o-driver/src/main/java/org/x4o/xml/io/sax/X4OContentParser.java index 06f17b0..7da47fa 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/io/sax/X4OContentParser.java +++ b/x4o-driver/src/main/java/org/x4o/xml/io/sax/X4OContentParser.java @@ -58,7 +58,20 @@ public class X4OContentParser { } public void parse(X4OLanguageSession languageSession) throws SAXException, IOException { - + // Group debug config property messages + if (languageSession.hasX4ODebugWriter()) { + languageSession.getX4ODebugWriter().debugSAXConfigStart(); + } + try { + parseSax(languageSession); + } finally { + if (languageSession.hasX4ODebugWriter()) { + languageSession.getX4ODebugWriter().debugSAXConfigEnd(); + } + } + } + + private void parseSax(X4OLanguageSession languageSession) throws SAXException, IOException { // If xsd caching is needed this should be the way //XMLParserConfiguration config = new XIncludeAwareParserConfiguration(); //config.setProperty("http://apache.org/xml/properties/internal/grammar-pool",myFullGrammarPool); @@ -72,14 +85,14 @@ public class X4OContentParser { saxParser.setContentHandler(xth); saxParser.setProperty("http://xml.org/sax/properties/lexical-handler", xth); saxParser.setProperty("http://xml.org/sax/properties/declaration-handler",xth); - + // Set properties and optional Map saxParserProperties = getSAXParserProperties(languageSession); for (Map.Entry entry:saxParserProperties.entrySet()) { String name = entry.getKey(); Object value= entry.getValue(); saxParser.setProperty(name, value); - debugMessage("Set SAX property: "+name+" to: "+value,languageSession); + debugMessage("property",name,value,languageSession); } Map saxParserPropertiesOptional = getSAXParserPropertiesOptional(languageSession); for (Map.Entry entry:saxParserPropertiesOptional.entrySet()) { @@ -87,9 +100,9 @@ public class X4OContentParser { Object value= entry.getValue(); try { saxParser.setProperty(name, value); - debugMessage("Set SAX optional property: "+name+" to: "+value,languageSession); + debugMessage("optional-property",name,value,languageSession); } catch (SAXException e) { - debugMessage("Could not set optional SAX property: "+name+" to: "+value+" error: "+e.getMessage(),languageSession); + debugMessageLog("Could not set optional SAX property: "+name+" to: "+value+" error: "+e.getMessage(),languageSession); } } @@ -98,26 +111,26 @@ public class X4OContentParser { for (String key:features.keySet()) { Boolean value=features.get(key); saxParser.setFeature(key, value); - debugMessage("Set SAX feature: "+key+" to: "+value,languageSession); + debugMessage("feature",key,value,languageSession); } Map featuresOptional = getSAXParserFeaturesOptional(languageSession); for (String key:featuresOptional.keySet()) { Boolean value=featuresOptional.get(key); try { saxParser.setFeature(key, value); - debugMessage("Set SAX optional feature: "+key+" to: "+value,languageSession); + debugMessage("optional-feature",key,value,languageSession); } catch (SAXException e) { - debugMessage("Could not set optional SAX feature: "+key+" to: "+value+" error: "+e.getMessage(),languageSession); + debugMessageLog("Could not set optional SAX feature: "+key+" to: "+value+" error: "+e.getMessage(),languageSession); } } // check for required features List requiredFeatures = getSAXParserFeaturesRequired(languageSession); for (String requiredFeature:requiredFeatures) { - debugMessage("Checking required SAX feature: "+requiredFeature,languageSession); if (saxParser.getFeature(requiredFeature)==false) { throw new IllegalStateException("Missing required feature: "+requiredFeature); - } + } + debugMessage("required",requiredFeature,"true",languageSession); } // Finally start parsing the xml input stream @@ -149,16 +162,22 @@ public class X4OContentParser { } } - private void debugMessage(String message,X4OLanguageSession languageSession) throws SAXException { + private void debugMessageLog(String message,X4OLanguageSession languageSession) throws SAXException { if (languageSession.hasX4ODebugWriter()) { try { - languageSession.getX4ODebugWriter().debugPhaseMessage(message, X4OContentParser.class); - } catch (ElementException ee) { - throw new SAXException(ee); + languageSession.getX4ODebugWriter().debugPhaseMessage(message, getClass()); + } catch (ElementException e) { + throw new SAXException(e); } } } + private void debugMessage(String type,String key,Object value,X4OLanguageSession languageSession) throws SAXException { + if (languageSession.hasX4ODebugWriter()) { + languageSession.getX4ODebugWriter().debugSAXMessage(type,key,""+value); + } + } + /** * @see org.x4o.xml.lang.X4OLanguageConfiguration#getSAXParserProperties(org.x4o.xml.lang.X4OLanguageSession) */ diff --git a/x4o-driver/src/main/java/org/x4o/xml/io/sax/X4ODebugWriter.java b/x4o-driver/src/main/java/org/x4o/xml/io/sax/X4ODebugWriter.java index 64773be..f84e1e8 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/io/sax/X4ODebugWriter.java +++ b/x4o-driver/src/main/java/org/x4o/xml/io/sax/X4ODebugWriter.java @@ -23,6 +23,7 @@ package org.x4o.xml.io.sax; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -40,6 +41,7 @@ import org.x4o.xml.element.ElementException; import org.x4o.xml.element.ElementInterface; import org.x4o.xml.element.ElementNamespace; import org.x4o.xml.element.ElementNamespaceInstanceProvider; +import org.x4o.xml.io.AbstractX4OConnection; import org.x4o.xml.io.sax.ext.ContentWriter; import org.x4o.xml.lang.X4OLanguageModule; import org.x4o.xml.lang.X4OLanguageModuleLoaderResult; @@ -88,6 +90,7 @@ public class X4ODebugWriter { startTime = System.currentTimeMillis(); try { AttributesImpl atts = new AttributesImpl(); + atts.addAttribute("", "phaseId","","", phase.getId()); if (elementLanguage!=null) { atts.addAttribute("", "language","","", elementLanguage.getLanguage().getLanguageName()); } @@ -95,15 +98,15 @@ public class X4ODebugWriter { } catch (SAXException e) { throw new X4OPhaseException(phase,e); } - debugPhase(phase); } public void endRunPhase(X4OPhase phase,X4OLanguageSession elementLanguage) throws X4OPhaseException { long stopTime = System.currentTimeMillis(); try { AttributesImpl atts = new AttributesImpl(); - atts.addAttribute ("", "id", "", "", phase.getId()); - atts.addAttribute ("", "speed", "", "", (stopTime-startTime)+" ms"); + atts.addAttribute ("", "phaseId", "", "", phase.getId()); + atts.addAttribute ("", "time", "", "", (stopTime-startTime)+""); + atts.addAttribute ("", "timeUnit", "", "", "ms"); contentWriter.startElement (DEBUG_URI, "executePhaseDone", "", atts); contentWriter.endElement (DEBUG_URI, "executePhaseDone" , ""); @@ -114,53 +117,89 @@ public class X4ODebugWriter { } } - /* - public void debugLanguageProperties(X4OLanguageSession ec) throws ElementException { - try { - AttributesImpl atts = new AttributesImpl(); - contentWriter.startElement (DEBUG_URI, "X4OLanguageProperties", "", atts); - for (X4OLanguageProperty p:X4OLanguageProperty.values()) { - Object value = ec.getLanguageProperty(p); - if (value==null) { - continue; - } - AttributesImpl atts2 = new AttributesImpl(); - atts2.addAttribute ("", "uri", "", "", p.toUri()); - atts2.addAttribute ("", "value", "", "", value.toString()); - contentWriter.startElement (DEBUG_URI, "X4OLanguageProperty", "", atts2); - contentWriter.endElement(DEBUG_URI, "X4OLanguageProperty", ""); + private String convertCharToHex(String newline) { + StringBuilder buf = new StringBuilder(); + buf.append("0x"); + for (char c:newline.toCharArray()) { + Integer i = new Integer(c); + if (i<16) { + buf.append('0'); } - contentWriter.endElement(DEBUG_URI, "X4OLanguageProperties", ""); - } catch (SAXException e) { - throw new ElementException(e); - } + buf.append(Integer.toHexString(i).toUpperCase()); + } + return buf.toString(); + } + + public void debugConnectionStart(X4OLanguageSession languageSession,AbstractX4OConnection ec) throws SAXException { + AttributesImpl atts = new AttributesImpl(); + atts.addAttribute ("", "language", "", "", languageSession.getLanguage().getLanguageName()); + atts.addAttribute ("", "languageVersion", "", "", languageSession.getLanguage().getLanguageVersion()); + atts.addAttribute ("", "className", "", "", ec.getClass().getName()); + atts.addAttribute ("", "currentTimeMillis", "", "", System.currentTimeMillis()+""); + contentWriter.startElement(X4ODebugWriter.DEBUG_URI, "X4OConnection", "", atts); + + atts = new AttributesImpl(); + atts.addAttribute ("", "phaseStop", "", "", languageSession.getPhaseStop()); + atts.addAttribute ("", "className", "", "", languageSession.getClass().getName()); + contentWriter.startElement (DEBUG_URI, "X4OLanguageSession", "", atts); + for (String skipPhase:languageSession.getPhaseSkip()) { + atts = new AttributesImpl(); + contentWriter.startElement (DEBUG_URI, "X4OLanguageSessionSkipPhase", "", atts); + contentWriter.characters(skipPhase); + contentWriter.endElement(DEBUG_URI, "X4OLanguageSessionSkipPhase", ""); + } + contentWriter.endElement(DEBUG_URI, "X4OLanguageSession", ""); + + atts = new AttributesImpl(); + contentWriter.startElement (DEBUG_URI, "X4OConnectionProperties", "", atts); + for (String key:ec.getPropertyKeys()) { + Object value = ec.getProperty(key); + AttributesImpl atts2 = new AttributesImpl(); + atts2.addAttribute ("", "key", "", "", key); + if (value==null) { + atts2.addAttribute ("", "valueIsNull", "", "", "true"); + } else { + if (key.endsWith("char-newline") | key.endsWith("char-tab")) { + value = convertCharToHex(value.toString()); + } + atts2.addAttribute ("", "value", "", "", value.toString()); + } + + contentWriter.startElement (DEBUG_URI, "X4OConnectionProperty", "", atts2); + contentWriter.endElement(DEBUG_URI, "X4OConnectionProperty", ""); + } + contentWriter.endElement(DEBUG_URI, "X4OConnectionProperties", ""); + } + + + public void debugConnectionEnd() throws SAXException { + contentWriter.endElement(X4ODebugWriter.DEBUG_URI, "X4OConnection", ""); } - */ public void debugLanguageDefaultClasses(X4OLanguageSession ec) throws ElementException { try { AttributesImpl atts = new AttributesImpl(); contentWriter.startElement (DEBUG_URI, "X4OLanguageDefaultClasses", "", atts); X4OLanguageConfiguration conf = ec.getLanguage().getLanguageConfiguration(); - - debugLanguageDefaultClass("getDefaultElementNamespace",conf.getDefaultElementNamespace()); - debugLanguageDefaultClass("getDefaultElementInterface",conf.getDefaultElementInterface()); - debugLanguageDefaultClass("getDefaultElement",conf.getDefaultElement()); - debugLanguageDefaultClass("getDefaultElementClass",conf.getDefaultElementClass()); - debugLanguageDefaultClass("getDefaultElementClassAttribute",conf.getDefaultElementClassAttribute()); - debugLanguageDefaultClass("getDefaultElementLanguageModule",conf.getDefaultElementLanguageModule()); - debugLanguageDefaultClass("getDefaultElementBodyComment",conf.getDefaultElementBodyComment()); - debugLanguageDefaultClass("getDefaultElementBodyCharacters",conf.getDefaultElementBodyCharacters()); - debugLanguageDefaultClass("getDefaultElementBodyWhitespace",conf.getDefaultElementBodyWhitespace()); - debugLanguageDefaultClass("getDefaultElementNamespaceInstanceProvider",conf.getDefaultElementNamespaceInstanceProvider()); - debugLanguageDefaultClass("getDefaultElementAttributeValueParser",conf.getDefaultElementAttributeValueParser()); - debugLanguageDefaultClass("getDefaultElementObjectPropertyValue",conf.getDefaultElementObjectPropertyValue()); - debugLanguageDefaultClass("getDefaultElementNamespaceAttributeComparator",conf.getDefaultElementNamespaceAttributeComparator()); - + + debugLanguageDefaultClass("defaultElementNamespace",conf.getDefaultElementNamespace()); + debugLanguageDefaultClass("defaultElementInterface",conf.getDefaultElementInterface()); + debugLanguageDefaultClass("defaultElement",conf.getDefaultElement()); + debugLanguageDefaultClass("defaultElementClass",conf.getDefaultElementClass()); + debugLanguageDefaultClass("defaultElementClassAttribute",conf.getDefaultElementClassAttribute()); + debugLanguageDefaultClass("defaultElementLanguageModule",conf.getDefaultElementLanguageModule()); + debugLanguageDefaultClass("defaultElementBodyComment",conf.getDefaultElementBodyComment()); + debugLanguageDefaultClass("defaultElementBodyCharacters",conf.getDefaultElementBodyCharacters()); + debugLanguageDefaultClass("defaultElementBodyWhitespace",conf.getDefaultElementBodyWhitespace()); + debugLanguageDefaultClass("defaultElementNamespaceInstanceProvider",conf.getDefaultElementNamespaceInstanceProvider()); + debugLanguageDefaultClass("defaultElementAttributeValueParser",conf.getDefaultElementAttributeValueParser()); + debugLanguageDefaultClass("defaultElementObjectPropertyValue",conf.getDefaultElementObjectPropertyValue()); + debugLanguageDefaultClass("defaultElementNamespaceAttributeComparator",conf.getDefaultElementNamespaceAttributeComparator()); + contentWriter.endElement(DEBUG_URI, "X4OLanguageDefaultClasses", ""); } catch (SAXException e) { throw new ElementException(e); - } + } } private void debugLanguageDefaultClass(String name,Class clazz) throws SAXException { @@ -197,6 +236,7 @@ public class X4ODebugWriter { try { AttributesImpl atts = new AttributesImpl(); atts.addAttribute ("", "id", "", "", phase.getId()); + atts.addAttribute ("", "type", "", "", phase.getType().name()); atts.addAttribute ("", "runOnce", "", "", phase.isRunOnce()+""); atts.addAttribute ("", "listenersSize", "", "", phase.getPhaseListeners().size()+""); @@ -207,10 +247,17 @@ public class X4ODebugWriter { contentWriter.startElement (DEBUG_URI, "X4OPhaseListener", "", atts); contentWriter.endElement(DEBUG_URI, "X4OPhaseListener", ""); } + for (String dep:phase.getPhaseDependencies()) { + atts = new AttributesImpl(); + //atts.addAttribute ("", "dependency", "", "", dep); + contentWriter.startElement (DEBUG_URI, "X4OPhaseDependency", "", atts); + contentWriter.characters(dep); + contentWriter.endElement(DEBUG_URI, "X4OPhaseDependency", ""); + } contentWriter.endElement(DEBUG_URI, "phase", ""); } catch (SAXException e) { throw new X4OPhaseException(phase,e); - } + } } public void debugElementLanguageModules(X4OLanguageSession elementLanguage) throws ElementException { @@ -377,13 +424,30 @@ public class X4ODebugWriter { return buff; } + public void debugSAXConfigStart() throws SAXException { + AttributesImpl atts = new AttributesImpl(); + contentWriter.startElement (DEBUG_URI, "SAXConfig", "", atts); + } + + public void debugSAXConfigEnd() throws SAXException { + contentWriter.endElement(DEBUG_URI, "SAXConfig", ""); + } + + public void debugSAXMessage(String type,String key,String value) throws SAXException { + AttributesImpl atts = new AttributesImpl(); + atts.addAttribute ("", "key", "", "", key); + atts.addAttribute ("", "value", "", "", value); + atts.addAttribute ("", "type", "", "", type); + contentWriter.startElement (DEBUG_URI, "SAXConfigProperty", "", atts); + contentWriter.endElement(DEBUG_URI, "SAXConfigProperty", ""); + } + public void debugPhaseMessage(String message,Class clazz) throws ElementException { AttributesImpl atts = new AttributesImpl(); atts.addAttribute ("", "class", "", "", clazz.getName()+""); try { contentWriter.startElement (DEBUG_URI, "message", "", atts); - char[] msg = message.toCharArray(); - contentWriter.characters(msg,0,msg.length); + contentWriter.characters(message); contentWriter.endElement(DEBUG_URI, "message", ""); } catch (SAXException e) { throw new ElementException(e); @@ -424,17 +488,6 @@ public class X4ODebugWriter { } } - public void debugLanguageSession(X4OLanguageSession elementLanguage) throws SAXException { - AttributesImpl atts = new AttributesImpl(); - //atts.addAttribute ("", key, "", "", value); - atts.addAttribute ("", "language", "", "", elementLanguage.getLanguage().getLanguageName()); - atts.addAttribute ("", "languageVersion", "", "", elementLanguage.getLanguage().getLanguageVersion()); - atts.addAttribute ("", "className", "", "", elementLanguage.getClass().getName()+""); - atts.addAttribute ("", "currentX4OPhase", "", "", elementLanguage.getPhaseCurrent().getId()); - contentWriter.startElement (DEBUG_URI, "printElementLanguage", "", atts); - contentWriter.endElement(DEBUG_URI, "printElementLanguage", ""); - } - private void debugElementClass(ElementClass elementClass) throws SAXException { AttributesImpl atts = new AttributesImpl(); atts.addAttribute ("", "id", "", "", elementClass.getId()); @@ -537,4 +590,92 @@ public class X4ODebugWriter { contentWriter.endElement(DEBUG_URI, "elementBindingHandler", ""); } } + + /** + * Creates an debug phase + * @return The X4OPhaseHandler for this phase. + */ + public X4OPhaseListener createDebugPrintTreePhaseListener() { + return new X4OPhaseListener() { + List startedPrefix = new ArrayList(10); + public void preRunPhase(X4OPhase phase,X4OLanguageSession languageSession) throws X4OPhaseException { + } + public void endRunPhase(X4OPhase phase,X4OLanguageSession languageSession) throws X4OPhaseException { + if (languageSession.hasX4ODebugWriter()==false) { + throw new X4OPhaseException(phase,"Use debugPhase only when X4OParser.debugWriter is filled."); + } + try { + AttributesImpl atts = new AttributesImpl(); + contentWriter.startElement (X4ODebugWriter.DEBUG_URI, "printElementTree", "", atts); + startedPrefix.clear(); + printXML(languageSession.getRootElement()); + for (String prefix:startedPrefix) { + contentWriter.endPrefixMapping(prefix); + } + contentWriter.endElement(X4ODebugWriter.DEBUG_URI, "printElementTree", ""); + + } catch (SAXException e) { + throw new X4OPhaseException(phase,e); + } + } + + // note: slow version + private String getNamespaceForElement(Element e) { + for (X4OLanguageModule mod:e.getLanguageSession().getLanguage().getLanguageModules()) { + for (ElementNamespace enc:mod.getElementNamespaces()) { + List l = enc.getElementClasses(); + if (l.contains(e.getElementClass())) { + return enc.getUri(); + } + } + } + return null; + } + + private void printXML(Element element) throws SAXException { + if (element==null) { + throw new SAXException("Can't print debug xml of null element."); + } + ContentWriter handler = contentWriter; //element.getLanguageSession().getX4ODebugWriter().getContentWriter(); + if (element.getElementType().equals(Element.ElementType.comment)) { + handler.comment((String)element.getElementObject()); + return; + } + if (element.getElementType().equals(Element.ElementType.characters)) { + handler.characters((String)element.getElementObject()); + return; + } + if (element.getElementClass()==null) { + throw new SAXException("Element without ElementClass is not valid: "+element+" obj: "+element.getElementObject()); + } + + AttributesImpl atts = new AttributesImpl(); + for (String key:element.getAttributes().keySet()) { + String value = element.getAttributes().get(key); + //uri, localName, xml1.0name, type, value + atts.addAttribute ("", key, "", "", value); + } + + String nameSpace = getNamespaceForElement(element); + ElementNamespace en = element.getLanguageSession().getLanguage().findElementNamespace(nameSpace); + + String prefix = en.getPrefixMapping(); // TODO: note is for reading; getPrefixMapping + if (prefix==null) { + prefix = en.getSchemaPrefix(); + } + if (prefix==null) { + prefix = en.getId(); + } + if (startedPrefix.contains(prefix)==false) { + handler.startPrefixMapping(prefix, nameSpace); + startedPrefix.add(prefix); + } + handler.startElement (nameSpace, element.getElementClass().getId(), "", atts); + for (Element e:element.getAllChilderen()) { + printXML(e); + } + handler.endElement (nameSpace, element.getElementClass().getId(), ""); + } + }; + } } diff --git a/x4o-driver/src/main/java/org/x4o/xml/io/sax/ext/PropertyConfig.java b/x4o-driver/src/main/java/org/x4o/xml/io/sax/ext/PropertyConfig.java index e84cbd3..e1c1635 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/io/sax/ext/PropertyConfig.java +++ b/x4o-driver/src/main/java/org/x4o/xml/io/sax/ext/PropertyConfig.java @@ -24,7 +24,6 @@ package org.x4o.xml.io.sax.ext; import java.io.File; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; diff --git a/x4o-driver/src/main/java/org/x4o/xml/lang/AbstractX4OLanguageSession.java b/x4o-driver/src/main/java/org/x4o/xml/lang/AbstractX4OLanguageSession.java index 8111ce3..826cc60 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/lang/AbstractX4OLanguageSession.java +++ b/x4o-driver/src/main/java/org/x4o/xml/lang/AbstractX4OLanguageSession.java @@ -24,8 +24,6 @@ package org.x4o.xml.lang; import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.HashMap; import java.util.logging.Logger; import javax.el.ELContext; @@ -51,7 +49,7 @@ public abstract class AbstractX4OLanguageSession implements X4OLanguageSessionLo private ELContext eLContext = null; private ElementAttributeValueParser elementAttributeValueParser = null; private ElementObjectPropertyValue elementObjectPropertyValue = null; - private Map dirtyElements = null; + private List dirtyElements = null; private Element rootElement = null; private X4ODebugWriter debugWriter = null; private X4OPhase phaseCurrent = null; @@ -68,7 +66,7 @@ public abstract class AbstractX4OLanguageSession implements X4OLanguageSessionLo logger = Logger.getLogger(AbstractX4OLanguageSession.class.getName()); logger.finest("Creating new ParsingContext"); this.language=language; - dirtyElements = new HashMap(40); + dirtyElements = new ArrayList(20); phaseSkip = new ArrayList(5); } @@ -145,19 +143,19 @@ public abstract class AbstractX4OLanguageSession implements X4OLanguageSessionLo } /** - * @see org.x4o.xml.lang.X4OLanguageSession#addDirtyElement(org.x4o.xml.element.Element, org.x4o.xml.lang.phase.X4OPhase) + * @see org.x4o.xml.lang.X4OLanguageSession#addDirtyElement(org.x4o.xml.element.Element) */ - public void addDirtyElement(Element element, X4OPhase phase) { - if (dirtyElements.containsKey(element)) { + public void addDirtyElement(Element element) { + if (dirtyElements.contains(element)) { throw new IllegalArgumentException("Can't add an element twice."); } - dirtyElements.put(element,phase); + dirtyElements.add(element); } /** * @see org.x4o.xml.lang.X4OLanguageSession#getDirtyElements() */ - public Map getDirtyElements() { + public List getDirtyElements() { return dirtyElements; } diff --git a/x4o-driver/src/main/java/org/x4o/xml/lang/X4OLanguageSession.java b/x4o-driver/src/main/java/org/x4o/xml/lang/X4OLanguageSession.java index ec3db6f..135a59e 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/lang/X4OLanguageSession.java +++ b/x4o-driver/src/main/java/org/x4o/xml/lang/X4OLanguageSession.java @@ -23,7 +23,6 @@ package org.x4o.xml.lang; import java.util.List; -import java.util.Map; import javax.el.ELContext; import javax.el.ExpressionFactory; @@ -70,15 +69,14 @@ public interface X4OLanguageSession { * Marks an (new) Element as dirty and run the phases from this start phase. * * @param element The Element which needs the magic. - * @param phase May be null, then it should defualt to configElementPhase */ - void addDirtyElement(Element element,X4OPhase phase); + void addDirtyElement(Element element); /** * Get all Dirty Elements. - * @return Returns Map with dirty elements. + * @return Returns List with dirty elements. */ - Map getDirtyElements(); + List getDirtyElements(); /** * Returns the root Element which starts the xml tree. diff --git a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/DefaultX4OPhaseManager.java b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/DefaultX4OPhaseManager.java index 6f2df87..d640ba2 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/DefaultX4OPhaseManager.java +++ b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/DefaultX4OPhaseManager.java @@ -38,7 +38,7 @@ import org.x4o.xml.lang.X4OLanguageSessionLocal; * @author Willem Cazander * @version 1.0 Jan 6, 2008 */ -public class DefaultX4OPhaseManager implements X4OPhaseManager { +public class DefaultX4OPhaseManager implements X4OPhaseManagerLocal { /** The X4OPhaseHandler */ private List x4oPhases = null; @@ -76,6 +76,14 @@ PHASE_ORDER = { *startupX4OPhase, return null; } + public List getPhaseKeys() { + List result = new ArrayList(x4oPhases.size()); + for (X4OPhase phase:x4oPhases) { + result.add(phase.getId()); + } + return result; + } + /** * Adds an X4OPhaseHandler. * @param phase The X4OPhaseHandler to add. @@ -89,6 +97,7 @@ PHASE_ORDER = { *startupX4OPhase, // throw new IllegalStateException("Can't add new phases after first phase is completed."); //} x4oPhases.add(phase); + } /** @@ -125,7 +134,7 @@ PHASE_ORDER = { *startupX4OPhase, // debug output if (languageSession.getX4ODebugWriter()!=null) { - languageSession.getX4ODebugWriter().debugPhaseOrder(x4oPhases); + languageSession.getX4ODebugWriter().debugPhaseOrder(x4oPhasesOrder); } List phaseSkip = languageSession.getPhaseSkip(); diff --git a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseLanguageInit.java b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseLanguageInit.java index 99d5aa0..1ca24b5 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseLanguageInit.java +++ b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseLanguageInit.java @@ -51,7 +51,7 @@ public class X4OPhaseLanguageInit { logger = Logger.getLogger(X4OPhaseLanguageInit.class.getName()); } - public void createPhases(DefaultX4OPhaseManager manager) { + public void createPhases(X4OPhaseManagerLocal manager) { manager.addX4OPhase(new X4OPhaseInitStart()); manager.addX4OPhase(new X4OPhaseInitLanguage()); manager.addX4OPhase(new X4OPhaseInitLanguageSiblings()); diff --git a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseLanguageRead.java b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseLanguageRead.java index ad65d4a..fec80ab 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseLanguageRead.java +++ b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseLanguageRead.java @@ -34,7 +34,6 @@ import org.x4o.xml.element.Element; import org.x4o.xml.element.ElementNamespaceAttribute; import org.x4o.xml.element.ElementAttributeValueParser; import org.x4o.xml.element.ElementBindingHandler; -import org.x4o.xml.element.ElementClass; import org.x4o.xml.element.ElementClassAttribute; import org.x4o.xml.element.ElementConfigurator; import org.x4o.xml.element.ElementConfiguratorGlobal; @@ -42,7 +41,6 @@ import org.x4o.xml.element.ElementException; import org.x4o.xml.element.ElementInterface; import org.x4o.xml.element.ElementNamespace; import org.x4o.xml.io.sax.X4ODebugWriter; -import org.x4o.xml.io.sax.ext.ContentWriter; import org.x4o.xml.lang.X4OLanguageModule; import org.x4o.xml.lang.X4OLanguageSession; import org.x4o.xml.lang.X4OLanguageClassLoader; @@ -78,13 +76,10 @@ public class X4OPhaseLanguageRead { logger = Logger.getLogger(X4OPhaseLanguageRead.class.getName()); } - - public void createPhases(DefaultX4OPhaseManager manager) { - manager.addX4OPhase(new X4OPhaseReadBegin()); + public void createPhases(X4OPhaseManagerLocal manager) { // meta start point -// manager.addX4OPhase(factory.startX4OPhase()); -// if (languageSession.hasX4ODebugWriter()) {manager.addX4OPhaseHandler(factory.debugPhase());} + manager.addX4OPhase(new X4OPhaseReadBegin()); // config X4OPhaseReadRunConfigurator runConf = new X4OPhaseReadRunConfigurator(); @@ -95,41 +90,26 @@ public class X4OPhaseLanguageRead { // run all attribute events manager.addX4OPhase(new X4OPhaseReadRunAttribute()); -// if (languageSession.hasX4ODebugWriter()) {manager.addX4OPhaseHandler(factory.debugPhase());} + // templating manager.addX4OPhase(new X4OPhaseReadFillTemplate()); -// if (languageSession.hasX4ODebugWriter()) {manager.addX4OPhaseHandler(factory.debugPhase());} - + // transforming manager.addX4OPhase(new X4OPhaseReadTransform()); manager.addX4OPhase(new X4OPhaseReadRunDirty(manager)); -// if (languageSession.hasX4ODebugWriter()) {manager.addX4OPhaseHandler(factory.debugPhase());} // binding elements manager.addX4OPhase(new X4OPhaseReadBindElement()); // runing and releasing manager.addX4OPhase(new X4OPhaseReadRun()); -// if (languageSession.hasX4ODebugWriter()) {manager.addX4OPhaseHandler(factory.debugPhase());} - manager.addX4OPhase(runConf); - manager.addX4OPhase(new X4OPhaseReadRunDirtyLast(manager)); -// if (languageSession.hasX4ODebugWriter()) {manager.addX4OPhaseHandler(factory.debugPhase());} - - manager.addX4OPhase(new X4OPhaseReadEnd()); // after release phase Element Tree is not avible anymore manager.addX4OPhase(releasePhase()); - // Add debug phase listener to all phases -// if (languageSession.hasX4ODebugWriter()) { - //for (X4OPhase h:manager.getOrderedPhases()) { -// h.addPhaseListener(languageSession.getX4ODebugWriter().createDebugX4OPhaseListener()); - //} - //} - // We are done } @@ -204,7 +184,7 @@ public class X4OPhaseLanguageRead { if (element.getAttributes().containsKey(alias)) { String attributeValue = element.getAttributes().get(alias); element.getAttributes().put(eca.getId(), attributeValue); - element.getAttributes().remove(alias); + element.getAttributes().remove(alias); } } } @@ -463,13 +443,13 @@ public class X4OPhaseLanguageRead { return new String[] {READ_TRANSFORM}; } public void runElementPhase(Element element) throws X4OPhaseException { - Map dirtyElements = element.getLanguageSession().getDirtyElements(); + List dirtyElements = element.getLanguageSession().getDirtyElements(); if (dirtyElements.isEmpty()) { return; } debugPhaseMessage("Dirty elements: "+dirtyElements.size(), this,element.getLanguageSession()); - for (Element e:dirtyElements.keySet()) { - X4OPhase p = dirtyElements.get(e); + X4OPhase p = phaseManager.getPhase(READ_BEGIN); + for (Element e:dirtyElements) { phaseManager.runPhasesForElement(e,getType(), p); } element.getLanguageSession().getDirtyElements().clear(); @@ -494,13 +474,13 @@ public class X4OPhaseLanguageRead { return new String[] {READ_RUN}; } public void runElementPhase(Element element) throws X4OPhaseException { - Map dirtyElements = element.getLanguageSession().getDirtyElements(); + List dirtyElements = element.getLanguageSession().getDirtyElements(); if (dirtyElements.isEmpty()) { return; } debugPhaseMessage("Dirty elements last: "+dirtyElements.size(), this,element.getLanguageSession()); - for (Element e:dirtyElements.keySet()) { - X4OPhase p = dirtyElements.get(e); + X4OPhase p = phaseManager.getPhase(READ_BEGIN); + for (Element e:dirtyElements) { phaseManager.runPhasesForElement(e,getType(), p); } element.getLanguageSession().getDirtyElements().clear(); @@ -736,101 +716,4 @@ public class X4OPhaseLanguageRead { result.addPhaseListener(releaseCounter); return result; } - - /** - * Creates an debug phase - * @return The X4OPhaseHandler for this phase. - */ - public X4OPhase debugPhase(final X4OPhase afterPhase) { - X4OPhase result = new AbstractX4OPhase() { - public X4OPhaseType getType() { - return X4OPhaseType.XML_READ; - } - public String getId() { - return "X4O_DEBUG_"+afterPhase.getId(); - } - public String[] getPhaseDependencies() { - return new String[] {afterPhase.getId()}; - } - public boolean isElementPhase() { - return false; - } - public void runElementPhase(Element element) throws X4OPhaseException { - } - public void runPhase(X4OLanguageSession languageSession) throws X4OPhaseException { - // safety check - if (languageSession.hasX4ODebugWriter()==false) { - throw new X4OPhaseException(this,"Use debugPhase only when X4OParser.debugWriter is filled."); - } - try { - AttributesImpl atts = new AttributesImpl(); - //atts.addAttribute ("", key, "", "", value); - //atts.addAttribute ("", "verbose", "", "", "true"); - languageSession.getX4ODebugWriter().getContentWriter().startElement (X4ODebugWriter.DEBUG_URI, "printElementTree", "", atts); - startedPrefix.clear(); - printXML(languageSession.getRootElement()); - for (String prefix:startedPrefix) { - languageSession.getX4ODebugWriter().getContentWriter().endPrefixMapping(prefix); - } - languageSession.getX4ODebugWriter().getContentWriter().endElement(X4ODebugWriter.DEBUG_URI, "printElementTree", ""); - languageSession.getX4ODebugWriter().debugLanguageSession(languageSession); - } catch (SAXException e) { - throw new X4OPhaseException(this,e); - } - } - List startedPrefix = new ArrayList(10); - - // note: slow version - private String getNamespaceForElement(Element e) { - for (X4OLanguageModule mod:e.getLanguageSession().getLanguage().getLanguageModules()) { - for (ElementNamespace enc:mod.getElementNamespaces()) { - List l = enc.getElementClasses(); - if (l.contains(e.getElementClass())) { - return enc.getUri(); - } - } - } - return null; - } - - private void printXML(Element element) throws SAXException { - if (element==null) { - throw new SAXException("Can't print debug xml of null element."); - } - ContentWriter handler = element.getLanguageSession().getX4ODebugWriter().getContentWriter(); - if (element.getElementType().equals(Element.ElementType.comment)) { - handler.comment((String)element.getElementObject()); - return; - } - if (element.getElementType().equals(Element.ElementType.characters)) { - handler.characters((String)element.getElementObject()); - return; - } - if (element.getElementClass()==null) { - throw new SAXException("Element without ElementClass is not valid: "+element+" obj: "+element.getElementObject()); - } - - AttributesImpl atts = new AttributesImpl(); - for (String key:element.getAttributes().keySet()) { - String value = element.getAttributes().get(key); - //uri, localName, xml1.0name, type, value - atts.addAttribute ("", key, "", "", value); - } - - String nameSpace = getNamespaceForElement(element); - String prefix = element.getLanguageSession().getLanguage().findElementNamespace(nameSpace).getPrefixMapping(); - - if (startedPrefix.contains(prefix)==false) { - handler.startPrefixMapping(prefix, nameSpace); - startedPrefix.add(prefix); - } - handler.startElement (nameSpace, element.getElementClass().getId(), "", atts); - for (Element e:element.getAllChilderen()) { - printXML(e); - } - handler.endElement (nameSpace, element.getElementClass().getId(), ""); - } - }; - return result; - } } diff --git a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseLanguageWrite.java b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseLanguageWrite.java index 5714eb2..c4de076 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseLanguageWrite.java +++ b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseLanguageWrite.java @@ -52,7 +52,7 @@ public class X4OPhaseLanguageWrite { logger = Logger.getLogger(X4OPhaseLanguageWrite.class.getName()); } - public void createPhases(DefaultX4OPhaseManager manager) { + public void createPhases(X4OPhaseManagerLocal manager) { manager.addX4OPhase(new X4OPhaseWriteBegin()); manager.addX4OPhase(new X4OPhaseWriteFillTree()); manager.addX4OPhase(new X4OPhaseWriteEnd()); diff --git a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseListener.java b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseListener.java index d45eca9..6c20891 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseListener.java +++ b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseListener.java @@ -40,7 +40,7 @@ public interface X4OPhaseListener { * @param elementLanguage The elementLanguage of the driver. * @throws X4OPhaseException Is throws when listeners has error. */ - void preRunPhase(X4OPhase phase,X4OLanguageSession elementLanguage) throws X4OPhaseException; + void preRunPhase(X4OPhase phase,X4OLanguageSession languageSession) throws X4OPhaseException; /** * Gets called after the X4OPhaseHandler is runned. @@ -48,5 +48,5 @@ public interface X4OPhaseListener { * @param elementLanguage The elementLanguage of the driver. * @throws X4OPhaseException Is throws when listeners has error. */ - void endRunPhase(X4OPhase phase,X4OLanguageSession elementLanguage) throws X4OPhaseException; + void endRunPhase(X4OPhase phase,X4OLanguageSession languageSession) throws X4OPhaseException; } diff --git a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseManager.java b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseManager.java index 2c6a33a..ec028ea 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseManager.java +++ b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseManager.java @@ -22,13 +22,11 @@ */ package org.x4o.xml.lang.phase; -import java.util.Collection; import java.util.List; import org.x4o.xml.element.Element; import org.x4o.xml.lang.X4OLanguageSession; - /** * X4OPhaseManager stores the X4OPhaseHandler and puts them in the right order. * And will execute the phases when runPhases is called. @@ -38,20 +36,24 @@ import org.x4o.xml.lang.X4OLanguageSession; */ public interface X4OPhaseManager { + /** + * Gets an X4OPhase object by the phaseName. + * @param phaseName The phaseName to lookup. + * @return The X4OPhase requested or null. + */ X4OPhase getPhase(String phaseName); /** - * Returns all the X4OPhaseHandlers. - * @return Returns all X4OPhaseHandlers. + * Gets all the keys of the phases registrated whith this phase manager. + * @return The phase keys. */ - Collection getAllPhases(); - + List getPhaseKeys(); + /** - * Returns all the X4OPhaseHandlers in ordered list. - * @return Returns all X4OPhaseHandler is order. + * Runs release phase if it was requested not to run it automaticly. + * @param languageSession The session to release. + * @throws X4OPhaseException When a running handlers throws one. */ - List getOrderedPhases(X4OPhaseType type); - void doReleasePhaseManual(X4OLanguageSession languageSession) throws X4OPhaseException; /** @@ -59,7 +61,7 @@ public interface X4OPhaseManager { * @throws X4OPhaseException When a running handlers throws one. */ void runPhases(X4OLanguageSession elementContext,X4OPhaseType type) throws X4OPhaseException; - + /** * Runs phase on single element. * @param e The Element to process. diff --git a/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseManagerLocal.java b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseManagerLocal.java new file mode 100644 index 0000000..147fd41 --- /dev/null +++ b/x4o-driver/src/main/java/org/x4o/xml/lang/phase/X4OPhaseManagerLocal.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2004-2013, Willem Cazander + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.x4o.xml.lang.phase; + + +/** + * X4OPhaseManagerLocal has the local config methods. + * + * @author Willem Cazander + * @version 1.0 Mrt 8, 2014 + */ +public interface X4OPhaseManagerLocal extends X4OPhaseManager { + + void addX4OPhase(X4OPhase phase); +} diff --git a/x4o-driver/src/test/java/org/x4o/xml/core/X4ODebugWriterTest.java b/x4o-driver/src/test/java/org/x4o/xml/core/X4ODebugWriterTest.java index 6bad78f..1c68bc4 100644 --- a/x4o-driver/src/test/java/org/x4o/xml/core/X4ODebugWriterTest.java +++ b/x4o-driver/src/test/java/org/x4o/xml/core/X4ODebugWriterTest.java @@ -22,11 +22,19 @@ */ package org.x4o.xml.core; +import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.Charset; import org.x4o.xml.X4ODriver; +import org.x4o.xml.io.DefaultX4OReader; +import org.x4o.xml.io.DefaultX4OWriter; import org.x4o.xml.io.X4OReader; +import org.x4o.xml.io.X4OWriter; import org.x4o.xml.test.TestDriver; import org.x4o.xml.test.models.TestObjectRoot; @@ -40,33 +48,67 @@ import junit.framework.TestCase; */ public class X4ODebugWriterTest extends TestCase { - private File createDebugFile() throws IOException { File debugFile = File.createTempFile("test-debug", ".xml"); debugFile.deleteOnExit(); return debugFile; } - public void testDebugOutput() throws Exception { + static public String readFile(File file) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file),Charset.forName("UTF-8"))); + try { + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + while (line != null) { + sb.append(line); + sb.append('\n'); + line = br.readLine(); + } + String out = sb.toString(); + //System.out.println(out); + return out; + } finally { + br.close(); + } + } + + public void testDebugOutputReader() throws Exception { File debugFile = createDebugFile(); X4ODriver driver = TestDriver.getInstance(); X4OReader reader = driver.createReader(); - //reader.setProperty(X4OLanguagePropertyKeys.DEBUG_OUTPUT_STREAM, new FileOutputStream(debugFile)); + reader.setProperty(DefaultX4OReader.DEBUG_OUTPUT_STREAM, new FileOutputStream(debugFile)); reader.readResource("tests/attributes/test-bean.xml"); assertTrue("Debug file does not exists.",debugFile.exists()); + String debug = readFile(debugFile); + assertNotNull(debug); + assertFalse("no debug content",debug.isEmpty()); + assertTrue("debug content to small",debug.length()>20); + + //System.out.println("=================== Reader Output ======================"); + //System.out.println(debug); debugFile.delete(); } - - public void testDebugOutputFull() throws Exception { + + public void testDebugOutputWriter() throws Exception { File debugFile = createDebugFile(); + File writeFile = createDebugFile(); X4ODriver driver = TestDriver.getInstance(); X4OReader reader = driver.createReader(); - //reader.setProperty(X4OLanguagePropertyKeys.DEBUG_OUTPUT_STREAM, new FileOutputStream(debugFile)); - //reader.setProperty(X4OLanguagePropertyKeys.DEBUG_OUTPUT_ELD_PARSER, true); - reader.readResource("tests/attributes/test-bean.xml"); + X4OWriter writer = driver.createWriter(); + TestObjectRoot object = reader.readResource("tests/attributes/test-bean.xml"); + + writer.setProperty(DefaultX4OWriter.DEBUG_OUTPUT_STREAM, new FileOutputStream(debugFile)); + writer.writeFile(object, writeFile); assertTrue("Debug file does not exists.",debugFile.exists()); + String debug = readFile(debugFile); + assertNotNull(debug); + assertFalse("no debug content",debug.isEmpty()); + assertTrue("debug content to small",debug.length()>20); + + //System.out.println("=================== Writer Output ======================"); + //System.out.println(debug); debugFile.delete(); } } diff --git a/x4o-driver/src/test/java/org/x4o/xml/core/X4OPhaseManagerTest.java b/x4o-driver/src/test/java/org/x4o/xml/core/X4OPhaseManagerTest.java index b22ac49..c59ae52 100644 --- a/x4o-driver/src/test/java/org/x4o/xml/core/X4OPhaseManagerTest.java +++ b/x4o-driver/src/test/java/org/x4o/xml/core/X4OPhaseManagerTest.java @@ -26,12 +26,11 @@ import java.util.Collection; import java.util.List; import org.x4o.xml.lang.X4OLanguageSession; +import org.x4o.xml.lang.phase.DefaultX4OPhaseManager; import org.x4o.xml.lang.phase.X4OPhase; -import org.x4o.xml.lang.phase.X4OPhaseManager; import org.x4o.xml.lang.phase.X4OPhaseType; import org.x4o.xml.test.TestDriver; - import junit.framework.TestCase; /** @@ -51,7 +50,7 @@ public class X4OPhaseManagerTest extends TestCase { public void testPhases() throws Exception { TestDriver driver = TestDriver.getInstance(); X4OLanguageSession context = driver.createLanguage().createLanguageSession(); - X4OPhaseManager manager = context.getLanguage().getPhaseManager(); + DefaultX4OPhaseManager manager = (DefaultX4OPhaseManager)context.getLanguage().getPhaseManager(); Collection phasesAll = manager.getAllPhases(); List phases = manager.getOrderedPhases(X4OPhaseType.XML_READ); assertNotNull(phases); diff --git a/x4o-driver/src/test/java/org/x4o/xml/lang/DefaultX4OLanguageLoaderTest.java b/x4o-driver/src/test/java/org/x4o/xml/lang/DefaultX4OLanguageLoaderTest.java index 9c3fc4b..139cbe8 100644 --- a/x4o-driver/src/test/java/org/x4o/xml/lang/DefaultX4OLanguageLoaderTest.java +++ b/x4o-driver/src/test/java/org/x4o/xml/lang/DefaultX4OLanguageLoaderTest.java @@ -29,11 +29,6 @@ import org.x4o.xml.X4ODriver; import org.x4o.xml.lang.X4OLanguage; import org.x4o.xml.lang.X4OLanguageLocal; import org.x4o.xml.lang.DefaultX4OLanguageLoader.VersionedResources; -import org.x4o.xml.lang.phase.DefaultX4OPhaseManager; -import org.x4o.xml.lang.phase.X4OPhaseLanguageInit; -import org.x4o.xml.lang.phase.X4OPhaseLanguageRead; -import org.x4o.xml.lang.phase.X4OPhaseLanguageWrite; -import org.x4o.xml.lang.phase.X4OPhaseManager; import org.x4o.xml.test.TestDriver; import org.x4o.xml.test.models.TestObjectRoot; @@ -48,39 +43,24 @@ import junit.framework.TestCase; public class DefaultX4OLanguageLoaderTest extends TestCase { X4ODriver driver; + X4OLanguage language; DefaultX4OLanguageLoader loader; public void setUp() throws Exception { driver = TestDriver.getInstance(); - //X4OReader reader = driver.createReader(); - //reader.readResource("tests/namespace/uri-simple.xml"); - X4OLanguage language = driver.createLanguage(); + language = driver.createLanguage(); loader = (DefaultX4OLanguageLoader)language.getLanguageConfiguration().getDefaultLanguageLoader().newInstance(); - - } - - X4OLanguageConfiguration buildLanguageConfiguration() { - DefaultX4OLanguageConfiguration config = new DefaultX4OLanguageConfiguration(); - config.fillDefaults(); - X4OLanguageConfiguration result = config.createProxy(); - return result; - } - X4OPhaseManager buildPhaseManager() { - DefaultX4OPhaseManager manager = new DefaultX4OPhaseManager(); - new X4OPhaseLanguageInit().createPhases(manager); - new X4OPhaseLanguageRead().createPhases(manager); - new X4OPhaseLanguageWrite().createPhases(manager); - return manager; } - public void testLanguageURINameSpaceTest() throws Exception { - DefaultX4OLanguage result = new DefaultX4OLanguage( - buildLanguageConfiguration(), - buildPhaseManager(), - driver.getLanguageName(), - "1.0" - ); - loader.loadLanguage((X4OLanguageLocal)result, "test", "1.0"); + public void testLoadingDuplicate() throws Exception { + Exception e = null; + try { + loader.loadLanguage((X4OLanguageLocal)language, "test", "1.0"); + } catch (Exception ee) { + e = ee; + } + assertNotNull("no duplicate module exception",e); + assertTrue("wrong module id.",e.getMessage().contains("test")); } public void testModulesSimple() throws Exception {