added more xml writer options and improved api doc output.

This commit is contained in:
Willem Cazander 2014-03-06 23:15:53 +01:00
parent 380b829fcb
commit 5f08acb488
12 changed files with 571 additions and 250 deletions

View file

@ -1,14 +1,12 @@
-- x4o TODO list -- -- x4o TODO list --
-- Fix debug output
-- RM function methods from Element interface. -- RM function methods from Element interface.
-- Change global attr to namespace attributes.
- finish eld doc-output content. - finish eld doc-output content.
- Make generic/safe? config bean. - Make generic/safe? config bean.
- Make language config done by driver xml parser. - Make language config done by driver xml parser.
- Add langauge task api + reg via driver conf or service - change (internal) x4o language to "x4o-" prefix so; x4o-cel,x4o-eld,x4o-meta
- Convert ant/mvn plugin to single task executor.
- change x4o language to "x4o-" prefix so; x4o-cel,x4o-eld,x4o-meta
- Add language locking, and lock eld/cel and add <lang>-eld wrap language for eld extentions per language. - Add language locking, and lock eld/cel and add <lang>-eld wrap language for eld extentions per language.
- Add doc version upgrade handler; - Add doc version upgrade handler;
@ -44,6 +42,14 @@
- make element tree jdom api compatible - make element tree jdom api compatible
- Test if possible to use threadpool for executing phases - Test if possible to use threadpool for executing phases
?? v2;
x4o-driver
x4o-s4j-jaxp (dom,sax,stax,xslt) (jsr; 5,63,173)
x4o-s4j-sax
x4o-s4j-stax
x4o-s4j-jaxb (jsr; 222)
-- TODO for version 1.0 -- -- TODO for version 1.0 --
## NON-CODE ## NON-CODE

View file

@ -8,6 +8,10 @@ Version 0.8.7:
- Renamed ElementNamespaceContext to ElementNamespace. - Renamed ElementNamespaceContext to ElementNamespace.
- Removed binding handler from element interface. - Removed binding handler from element interface.
- Refactored all property keys with PropertyConfig bean. - Refactored all property keys with PropertyConfig bean.
- Change global attr to namespace attributes.
- Updated ant/maven plugins to new task and properties.
- Added options to xml writer like OUTPUT_LINE_BREAK_WIDTH.
Version 0.8.6: Version 0.8.6:
- Changed to X4ODriver interface. - Changed to X4ODriver interface.

View file

@ -39,7 +39,7 @@ import org.x4o.xml.lang.X4OLanguage;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
/** /**
* EldSchemaGenerator Creates XML Schema for a namespace uri from a x4o language driver. * EldXsdWriter creates XML Schema files fom a x4o language.
* *
* @author Willem Cazander * @author Willem Cazander
* @version 1.0 Aug 8, 2012 * @version 1.0 Aug 8, 2012

View file

@ -71,10 +71,11 @@ public class AbstractContentWriterHandler implements ContentHandler {
public final static String OUTPUT_ENCODING = PROPERTY_CONTEXT_PREFIX+"output/encoding"; public final static String OUTPUT_ENCODING = PROPERTY_CONTEXT_PREFIX+"output/encoding";
public final static String OUTPUT_CHAR_TAB = PROPERTY_CONTEXT_PREFIX+"output/char-tab"; public final static String OUTPUT_CHAR_TAB = PROPERTY_CONTEXT_PREFIX+"output/char-tab";
public final static String OUTPUT_CHAR_NEWLINE = PROPERTY_CONTEXT_PREFIX+"output/char-newline"; public final static String OUTPUT_CHAR_NEWLINE = PROPERTY_CONTEXT_PREFIX+"output/char-newline";
public final static String OUTPUT_CHAR_NULL = PROPERTY_CONTEXT_PREFIX+"output/char-null";
public final static String OUTPUT_COMMENT_ENABLE = PROPERTY_CONTEXT_PREFIX+"output/comment-enable"; public final static String OUTPUT_COMMENT_ENABLE = PROPERTY_CONTEXT_PREFIX+"output/comment-enable";
public final static String OUTPUT_COMMENT_AUTO_SPACE = PROPERTY_CONTEXT_PREFIX+"output/comment-auto-space"; public final static String OUTPUT_COMMENT_AUTO_SPACE = PROPERTY_CONTEXT_PREFIX+"output/comment-auto-space";
//public final static String OUTPUT_LINE_BREAK_WIDTH = PROPERTY_CONTEXT_PREFIX+"output/line-break-width"; public final static String OUTPUT_LINE_BREAK_WIDTH = PROPERTY_CONTEXT_PREFIX+"output/line-break-width";
//public final static String OUTPUT_LINE_PER_ATTRIBUTE = PROPERTY_CONTEXT_PREFIX+"output/line-per-attribute"; public final static String OUTPUT_LINE_PER_ATTRIBUTE = PROPERTY_CONTEXT_PREFIX+"output/line-per-attribute";
public final static String PROLOG_LICENCE_FILE = PROPERTY_CONTEXT_PREFIX+"prolog/licence-file"; public final static String PROLOG_LICENCE_FILE = PROPERTY_CONTEXT_PREFIX+"prolog/licence-file";
public final static String PROLOG_LICENCE_RESOURCE = PROPERTY_CONTEXT_PREFIX+"prolog/licence-resource"; public final static String PROLOG_LICENCE_RESOURCE = PROPERTY_CONTEXT_PREFIX+"prolog/licence-resource";
public final static String PROLOG_LICENCE_ENCODING = PROPERTY_CONTEXT_PREFIX+"prolog/licence-encoding"; public final static String PROLOG_LICENCE_ENCODING = PROPERTY_CONTEXT_PREFIX+"prolog/licence-encoding";
@ -89,10 +90,11 @@ public class AbstractContentWriterHandler implements ContentHandler {
new PropertyConfigItem(OUTPUT_ENCODING, String.class, XMLConstants.XML_DEFAULT_ENCODING), new PropertyConfigItem(OUTPUT_ENCODING, String.class, XMLConstants.XML_DEFAULT_ENCODING),
new PropertyConfigItem(OUTPUT_CHAR_TAB, String.class, XMLConstants.CHAR_TAB+""), new PropertyConfigItem(OUTPUT_CHAR_TAB, String.class, XMLConstants.CHAR_TAB+""),
new PropertyConfigItem(OUTPUT_CHAR_NEWLINE, String.class, XMLConstants.CHAR_NEWLINE+""), new PropertyConfigItem(OUTPUT_CHAR_NEWLINE, String.class, XMLConstants.CHAR_NEWLINE+""),
new PropertyConfigItem(OUTPUT_CHAR_NULL, String.class, "null"), // TODO: or "" ?? (or skip)
new PropertyConfigItem(OUTPUT_COMMENT_ENABLE, Boolean.class, true), new PropertyConfigItem(OUTPUT_COMMENT_ENABLE, Boolean.class, true),
new PropertyConfigItem(OUTPUT_COMMENT_AUTO_SPACE, Boolean.class, true), new PropertyConfigItem(OUTPUT_COMMENT_AUTO_SPACE, Boolean.class, true),
// TODO new PropertyConfigItem(OUTPUT_LINE_BREAK_WIDTH, Integer.class, -1), new PropertyConfigItem(OUTPUT_LINE_BREAK_WIDTH, Integer.class, -1),
// TODO new PropertyConfigItem(OUTPUT_LINE_PER_ATTRIBUTE, Boolean.class, false), new PropertyConfigItem(OUTPUT_LINE_PER_ATTRIBUTE, Boolean.class, false),
new PropertyConfigItem(PROLOG_LICENCE_ENCODING, String.class, XMLConstants.XML_DEFAULT_ENCODING), new PropertyConfigItem(PROLOG_LICENCE_ENCODING, String.class, XMLConstants.XML_DEFAULT_ENCODING),
new PropertyConfigItem(PROLOG_LICENCE_FILE, File.class ), new PropertyConfigItem(PROLOG_LICENCE_FILE, File.class ),
new PropertyConfigItem(PROLOG_LICENCE_RESOURCE, String.class ), new PropertyConfigItem(PROLOG_LICENCE_RESOURCE, String.class ),
@ -289,7 +291,7 @@ public class AbstractContentWriterHandler implements ContentHandler {
startElement.append(' '); startElement.append(' ');
startElement.append(XMLConstants.XMLNS_ATTRIBUTE); startElement.append(XMLConstants.XMLNS_ATTRIBUTE);
if ("".equals(prefix)==false) { if ("".equals(prefix)==false) {
startElement.append(':'); startElement.append(XMLConstants.XMLNS_ASSIGN);
startElement.append(prefix); startElement.append(prefix);
} }
startElement.append("=\""); startElement.append("=\"");
@ -333,17 +335,32 @@ public class AbstractContentWriterHandler implements ContentHandler {
} }
} }
private void printElementAttributeNewLineSpace() {
startElement.append(XMLConstants.CHAR_NEWLINE);
for (int ii = 0; ii < indent+1; ii++) {
startElement.append(getPropertyConfig().getPropertyString(OUTPUT_CHAR_TAB));
}
}
private void startElementAttributes(Attributes atts) throws SAXException { private void startElementAttributes(Attributes atts) throws SAXException {
int prevChars = 0;
for (int i=0;i<atts.getLength();i++) { for (int i=0;i<atts.getLength();i++) {
String attributeUri = atts.getURI(i); String attributeUri = atts.getURI(i);
String attributeName = XMLConstants.escapeAttributeName(atts.getLocalName(i)); String attributeName = XMLConstants.escapeAttributeName(atts.getLocalName(i));
String attributeValue = atts.getValue(i); String attributeValue = atts.getValue(i);
if (attributeValue==null) { if (attributeValue==null) {
attributeValue = "null"; // TODO: Add null value key to config. attributeValue = propertyConfig.getPropertyString(OUTPUT_CHAR_NULL);
} }
String attributeValueSafe = XMLConstants.escapeAttributeValue(attributeValue); String attributeValueSafe = XMLConstants.escapeAttributeValue(attributeValue);
if (propertyConfig.getPropertyBoolean(OUTPUT_LINE_PER_ATTRIBUTE)) {
if (i==0) {
printElementAttributeNewLineSpace();
}
} else {
startElement.append(' '); startElement.append(' ');
}
if (XMLConstants.NULL_NS_URI.equals(attributeUri) | attributeUri ==null) { if (XMLConstants.NULL_NS_URI.equals(attributeUri) | attributeUri ==null) {
startElement.append(attributeName); startElement.append(attributeName);
} else { } else {
@ -354,11 +371,20 @@ public class AbstractContentWriterHandler implements ContentHandler {
startElement.append("=\""); startElement.append("=\"");
startElement.append(attributeValueSafe); startElement.append(attributeValueSafe);
startElement.append('"'); startElement.append('"');
boolean printNewLine = attributeValueSafe.length()>80; // TODO add config
if (printNewLine) { if (propertyConfig.getPropertyBoolean(OUTPUT_LINE_PER_ATTRIBUTE)) {
startElement.append(XMLConstants.CHAR_NEWLINE); printElementAttributeNewLineSpace();
for (int ii = 0; ii < indent+1; ii++) { }
startElement.append(getPropertyConfig().getPropertyString(OUTPUT_CHAR_TAB));
int breakLines = propertyConfig.getPropertyInteger(OUTPUT_LINE_BREAK_WIDTH);
if (breakLines>0) {
if (prevChars==0 && startElement.length() > breakLines) {
printElementAttributeNewLineSpace();
prevChars = startElement.length();
}
if (prevChars>0 && (startElement.length()-prevChars) > breakLines) {
printElementAttributeNewLineSpace();
prevChars = startElement.length();
} }
} }
} }

View file

@ -0,0 +1,133 @@
/*
* 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.io.sax;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import org.x4o.xml.io.sax.ext.ContentWriterXml;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import junit.framework.TestCase;
/**
* ContentWriterXmlAttributeTest test xml attribute printing. *
* @author Willem Cazander
* @version 1.0 S 17, 2012
*/
public class ContentWriterXmlAttributeTest extends TestCase {
public void testAttributeNormal() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
AttributesImpl atts = new AttributesImpl();
atts.addAttribute ("", "attr", "", "", "foobar");
writer.startElementEnd("", "test", "", atts);
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test attr=\"foobar\"/>"));
}
public void testAttributeEscape() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
AttributesImpl atts = new AttributesImpl();
atts.addAttribute ("", "attr", "", "", "<test/> & 'foobar' is \"quoted\"!");
writer.startElementEnd("", "test", "", atts);
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test attr=\"&lt;test/&gt; &amp; &apos;foobar&apos; is &quote;quoted&quote;!\"/>"));
}
private String createLongAttribute(Map<String,Object> para) throws SAXException {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
for (String key:para.keySet()) {
Object value = para.get(key);
writer.getPropertyConfig().setProperty(key, value);
}
AttributesImpl atts = new AttributesImpl();
String data = "_FOR_FOO_BAR";
String dataValue = "LOOP";
for (int i=0;i<15;i++) {
atts.addAttribute("", "attr"+i, "", "", dataValue+=data);
}
writer.startDocument();
writer.startElement("", "test", "", atts);
writer.startElement("", "testNode", "", new AttributesImpl());
writer.endElement("", "testNode", "");
writer.endElement("", "test", "");
writer.endDocument();
String output = outputWriter.toString();
return output;
}
public void testAttributeLongNormal() throws Exception {
Map<String,Object> para = new HashMap<String,Object>();
String output = createLongAttribute(para);
int newlines = output.split("\n").length;
assertNotNull(output);
assertTrue("outputs: "+newlines,newlines==4);
}
public void testAttributeLongPerLine() throws Exception {
Map<String,Object> para = new HashMap<String,Object>();
para.put(ContentWriterXml.OUTPUT_LINE_PER_ATTRIBUTE, true);
String output = createLongAttribute(para);
int newlines = output.split("\n").length;
assertNotNull(output);
assertTrue("outputs: "+newlines,newlines==20);
}
public void testAttributeLongSplit80() throws Exception {
Map<String,Object> para = new HashMap<String,Object>();
para.put(ContentWriterXml.OUTPUT_LINE_BREAK_WIDTH, 80);
String output = createLongAttribute(para);
int newlines = output.split("\n").length;
assertNotNull(output);
assertTrue("outputs: "+newlines,newlines==16);
}
public void testAttributeLongSplit180() throws Exception {
Map<String,Object> para = new HashMap<String,Object>();
para.put(ContentWriterXml.OUTPUT_LINE_BREAK_WIDTH, 180);
String output = createLongAttribute(para);
int newlines = output.split("\n").length;
assertNotNull(output);
assertTrue("outputs: "+newlines,newlines==11);
}
}

View file

@ -0,0 +1,162 @@
/*
* 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.io.sax;
import java.io.StringWriter;
import org.x4o.xml.io.sax.ext.ContentWriterXml;
import junit.framework.TestCase;
/**
* ContentWriterXmlCDataTest tests cdata xml escaping.
*
* @author Willem Cazander
* @version 1.0 Sep 17, 2013
*/
public class ContentWriterXmlCDataTest extends TestCase {
public void testCDATANone() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.characters("foobar");
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>foobar"));
}
public void testCDATANoneTagEscape() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.characters("foobar<test/>");
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>foobar&lt;test/&gt;"));
}
public void testCDATANormal() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.startCDATA();
writer.characters("foobar");
writer.endCDATA();
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[foobar]]>"));
}
public void testCDATAEscapeTag() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.startCDATA();
writer.characters("foobar<test/>");
writer.endCDATA();
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[foobar<test/>]]>"));
}
public void testCDATAEscapeStart() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.startCDATA();
writer.characters("<![CDATA[foobar");
writer.endCDATA();
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[foobar]]>"));
}
public void testCDATAEscapeEnd() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.startCDATA();
writer.characters("foobar]]>");
writer.endCDATA();
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[foobar]]>"));
}
public void testCDATAEscapeInvalid() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.startCDATA();
writer.characters("<![CDATA[tokens like ']]>' are <invalid>]]>");
writer.endCDATA();
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[tokens like \'\' are <invalid>]]>"));
}
public void testCDATAEscapeValid() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.startCDATA();
writer.characters("<![CDATA[tokens like ']]]]><![CDATA[>' are <valid>]]>");
writer.endCDATA();
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[tokens like \']]>\' are <valid>]]>"));
}
}

View file

@ -39,130 +39,6 @@ import junit.framework.TestCase;
*/ */
public class ContentWriterXmlTest extends TestCase { public class ContentWriterXmlTest extends TestCase {
public void testCDATANone() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.characters("foobar");
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>foobar"));
}
public void testCDATANoneTagEscape() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.characters("foobar<test/>");
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>foobar&lt;test/&gt;"));
}
public void testCDATANormal() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.startCDATA();
writer.characters("foobar");
writer.endCDATA();
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[foobar]]>"));
}
public void testCDATAEscapeTag() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.startCDATA();
writer.characters("foobar<test/>");
writer.endCDATA();
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[foobar<test/>]]>"));
}
public void testCDATAEscapeStart() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.startCDATA();
writer.characters("<![CDATA[foobar");
writer.endCDATA();
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[foobar]]>"));
}
public void testCDATAEscapeEnd() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.startCDATA();
writer.characters("foobar]]>");
writer.endCDATA();
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[foobar]]>"));
}
public void testCDATAEscapeInvalid() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.startCDATA();
writer.characters("<![CDATA[tokens like ']]>' are <invalid>]]>");
writer.endCDATA();
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[tokens like \'\' are <invalid>]]>"));
}
public void testCDATAEscapeValid() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
writer.startCDATA();
writer.characters("<![CDATA[tokens like ']]]]><![CDATA[>' are <valid>]]>");
writer.endCDATA();
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[tokens like \']]>\' are <valid>]]>"));
}
public void testCharactersNormal() throws Exception { public void testCharactersNormal() throws Exception {
StringWriter outputWriter = new StringWriter(); StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter); ContentWriterXml writer = new ContentWriterXml(outputWriter);
@ -191,39 +67,6 @@ public class ContentWriterXmlTest extends TestCase {
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>&lt;test/&gt; &amp; &apos;foobar&apos; is &quote;quoted&quote;!")); assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>&lt;test/&gt; &amp; &apos;foobar&apos; is &quote;quoted&quote;!"));
} }
public void testAttributeNormal() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
AttributesImpl atts = new AttributesImpl();
atts.addAttribute ("", "attr", "", "", "foobar");
writer.startElementEnd("", "test", "", atts);
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test attr=\"foobar\"/>"));
}
public void testAttributeEscape() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
writer.startDocument();
AttributesImpl atts = new AttributesImpl();
atts.addAttribute ("", "attr", "", "", "<test/> & 'foobar' is \"quoted\"!");
writer.startElementEnd("", "test", "", atts);
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.length()>0);
assertTrue(output,output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test attr=\"&lt;test/&gt; &amp; &apos;foobar&apos; is &quote;quoted&quote;!\"/>"));
}
public void testCommentNormal() throws Exception { public void testCommentNormal() throws Exception {
StringWriter outputWriter = new StringWriter(); StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter); ContentWriterXml writer = new ContentWriterXml(outputWriter);
@ -394,26 +237,4 @@ public class ContentWriterXmlTest extends TestCase {
assertTrue(e.getMessage().contains("invalid char")); assertTrue(e.getMessage().contains("invalid char"));
assertTrue(e.getMessage().contains("isInvalidChar=55296")); assertTrue(e.getMessage().contains("isInvalidChar=55296"));
} }
public void testAttributeValueLongData() throws Exception {
StringWriter outputWriter = new StringWriter();
ContentWriterXml writer = new ContentWriterXml(outputWriter);
AttributesImpl atts = new AttributesImpl();
String data = "_FOR_FOO_BAR";
String dataValue = "LOOP";
for (int i=0;i<15;i++) {
atts.addAttribute("", "attr"+i, "", "", dataValue+=data);
}
writer.startDocument();
writer.startElement("", "test", "", atts);
writer.startElement("", "testNode", "", new AttributesImpl());
writer.endElement("", "testNode", "");
writer.endElement("", "test", "");
writer.endDocument();
String output = outputWriter.toString();
assertNotNull(output);
assertTrue(output.split("\n").length==13);
}
} }

View file

@ -175,8 +175,8 @@ public class EldDocWriter {
doc.setNoFrameAllName("All Elements"); doc.setNoFrameAllName("All Elements");
doc.setFrameNavPrintParent(true); doc.setFrameNavPrintParent(true);
doc.setFrameNavPrintParentId(true); doc.setFrameNavPrintParentId(true);
doc.setGroupTypeName("summary", "Summary"); doc.setGroupTypeName("summary", "Summary",1);
doc.setGroupTypeName("overview", "Overview"); doc.setGroupTypeName("overview", "Overview",2);
// Javadoc linking config // Javadoc linking config
List<String> javadocLinkList = propertyConfig.getPropertyList(JAVADOC_LINK); List<String> javadocLinkList = propertyConfig.getPropertyList(JAVADOC_LINK);

View file

@ -94,13 +94,13 @@ public class ApiDocWriter extends AbstractApiDocWriter {
writeAllFrameNav(true); writeAllFrameNav(true);
writeAllFrameNav(false); writeAllFrameNav(false);
// Write pages // Write api doc tree
writeNode(doc.getRootNode());
// Write pages last
for (ApiDocPage page:doc.getDocPages()) { for (ApiDocPage page:doc.getDocPages()) {
writePage(page); writePage(page);
} }
// Write api doc tree
writeNode(doc.getRootNode());
} }
private void writeNode(ApiDocNode node) throws SAXException { private void writeNode(ApiDocNode node) throws SAXException {
@ -371,7 +371,11 @@ public class ApiDocWriter extends AbstractApiDocWriter {
private void configSubNavLinks(ApiDocNode node) { private void configSubNavLinks(ApiDocNode node) {
ApiDocNodeData conf = doc.getNodeData(); ApiDocNodeData conf = doc.getNodeData();
for (ApiDocNodeWriter writer:findNodeBodyWriters(node, null)) { List<ApiDocNodeWriter> orderedWriters = new ArrayList<ApiDocNodeWriter>(10);
for (ApiDocNodeBody bodyType:ApiDocNodeBody.values()) {
orderedWriters.addAll(findNodeBodyWriters(node,bodyType)); // enum order is oke
}
for (ApiDocNodeWriter writer:orderedWriters) {
String group = writer.getContentGroup(); String group = writer.getContentGroup();
String groupTypeKey = writer.getContentGroupType(); String groupTypeKey = writer.getContentGroupType();
if (group==null | groupTypeKey==null) { if (group==null | groupTypeKey==null) {
@ -464,10 +468,16 @@ public class ApiDocWriter extends AbstractApiDocWriter {
} }
private List<ApiDocNodeWriter> findNodeBodyWriters(ApiDocNode node,ApiDocNodeBody nodeBody) { private List<ApiDocNodeWriter> findNodeBodyWriters(ApiDocNode node,ApiDocNodeBody nodeBody) {
if (node==null) {
throw new NullPointerException("Can't search writers on null node.");
}
if (nodeBody==null) {
throw new NullPointerException("Can't search writers with null nodeBody."); // for sorting rules
}
List<ApiDocNodeWriter> result = new ArrayList<ApiDocNodeWriter>(); List<ApiDocNodeWriter> result = new ArrayList<ApiDocNodeWriter>();
final Class<?> objClass = node.getUserData().getClass(); final Class<?> objClass = node.getUserData().getClass();
for (ApiDocNodeWriter writer:doc.getNodeBodyWriters()) { for (ApiDocNodeWriter writer:doc.getNodeBodyWriters()) {
if (nodeBody!=null && !nodeBody.equals(writer.getNodeBody())) { if (!nodeBody.equals(writer.getNodeBody())) {
continue; continue;
} }
for (Class<?> c:writer.getTargetClasses()) { for (Class<?> c:writer.getTargetClasses()) {
@ -476,7 +486,15 @@ public class ApiDocWriter extends AbstractApiDocWriter {
} }
} }
} }
Collections.sort(result, new Comparator<ApiDocNodeWriter>() { Collections.sort(result, new ApiDocNodeWriterComparator(objClass));
return result;
}
private class ApiDocNodeWriterComparator implements Comparator<ApiDocNodeWriter> {
final Class<?> objClass;
public ApiDocNodeWriterComparator(Class<?> objClass) {
this.objClass=objClass;
}
public int compare(ApiDocNodeWriter o1, ApiDocNodeWriter o2) { public int compare(ApiDocNodeWriter o1, ApiDocNodeWriter o2) {
int index1 = -1; int index1 = -1;
int index2 = -1; int index2 = -1;
@ -490,11 +508,10 @@ public class ApiDocWriter extends AbstractApiDocWriter {
for (int i=0;i<o2.getTargetClasses().size();i++) { for (int i=0;i<o2.getTargetClasses().size();i++) {
Class<?> c = o2.getTargetClasses().get(i); Class<?> c = o2.getTargetClasses().get(i);
if (c.isAssignableFrom(objClass)) { if (c.isAssignableFrom(objClass)) {
index1 = i; index2 = i;
break; break;
} }
} }
// TODO: note check return value if are oke in order..
if (index1==-1 && index2==-1) { if (index1==-1 && index2==-1) {
return 0; return 0;
} }
@ -504,18 +521,10 @@ public class ApiDocWriter extends AbstractApiDocWriter {
if (index2==-1) { if (index2==-1) {
return -1; return -1;
} }
int orderValue1 = o1.getNodeBodyOrders().get(index1); Integer orderValue1 = o1.getNodeBodyOrders().get(index1);
int orderValue2 = o2.getNodeBodyOrders().get(index2); Integer orderValue2 = o2.getNodeBodyOrders().get(index2);
if (orderValue1==orderValue2) { return orderValue1.compareTo(orderValue2);
return 0;
} }
if (orderValue1 > orderValue2) {
return -1;
}
return 1;
}
});
return result;
} }
private List<ApiDocNodeDataConfigurator> findDataConfigurators(ApiDocNode node) { private List<ApiDocNodeDataConfigurator> findDataConfigurators(ApiDocNode node) {
@ -980,6 +989,7 @@ public class ApiDocWriter extends AbstractApiDocWriter {
atts.addAttribute ("", "href", "", "", "#skip-"+barId); atts.addAttribute ("", "href", "", "", "#skip-"+barId);
atts.addAttribute ("", "title", "", "", "Skip navigation links"); atts.addAttribute ("", "title", "", "", "Skip navigation links");
writer.startElement("", "a", "", atts); writer.startElement("", "a", "", atts);
writer.comment(" ");
writer.endElement("", "a", ""); writer.endElement("", "a", "");
writer.printHrefNamed(barId+"_firstrow"); writer.printHrefNamed(barId+"_firstrow");
@ -1055,18 +1065,27 @@ public class ApiDocWriter extends AbstractApiDocWriter {
} }
writer.printTagEnd(Tag.div); writer.printTagEnd(Tag.div);
} }
String tabSpace = "&nbsp;|&nbsp;"; String tabSpace = "&nbsp;|&nbsp;";
List<String> groupKeys = conf.getGroupTypeKeys(); boolean printLink = conf.getGroupTypeKeys().isEmpty()==false;
boolean printLink = groupKeys.isEmpty()==false;
if (printLink) { if (printLink) {
writer.printTagStart(Tag.div); List<String> groupKeys = new ArrayList<String>(5);
writer.printTagStart(Tag.ul,ApiDocContentCss.subNavList); for (String groupKey:doc.getGroupTypesOrdered()) {
if (!conf.getGroupTypeKeys().contains(groupKey)) {
continue;
}
groupKeys.add(groupKey);
}
boolean printDiv = false;
for (int i=0;i<groupKeys.size();i++) { for (int i=0;i<groupKeys.size();i++) {
String groupKey = groupKeys.get(i); String groupKey = groupKeys.get(i);
String groupName = doc.getGroupTypeName(groupKey); String groupName = doc.getGroupTypeName(groupKey);
List<ApiDocNavLink> links = conf.getGroupTypeLinks(groupKey); List<ApiDocNavLink> links = conf.getGroupTypeLinks(groupKey);
if (links.isEmpty()==false) { if (links.isEmpty()==false) {
if (!printDiv) {
printDiv = true;
writer.printTagStart(Tag.div); // don't print empty div
}
writer.printTagStart(Tag.ul,ApiDocContentCss.subNavList);
writer.printTagStart(Tag.li);writer.characters(groupName+":&nbsp;");writer.printTagEnd(Tag.li); writer.printTagStart(Tag.li);writer.characters(groupName+":&nbsp;");writer.printTagEnd(Tag.li);
for (int l=0;l<links.size();l++) { for (int l=0;l<links.size();l++) {
ApiDocNavLink link = links.get(l); ApiDocNavLink link = links.get(l);
@ -1083,15 +1102,15 @@ public class ApiDocWriter extends AbstractApiDocWriter {
writer.characters(tab); writer.characters(tab);
} }
} }
writer.printTagEnd(Tag.li); writer.printTagEnd(Tag.li);
} }
}
}
writer.printTagEnd(Tag.ul); writer.printTagEnd(Tag.ul);
}
}
if (printDiv) {
writer.printTagEnd(Tag.div); writer.printTagEnd(Tag.div);
} }
}
writer.printHrefNamed("skip-"+barId); writer.printHrefNamed("skip-"+barId);
writer.printTagEnd(Tag.div); writer.printTagEnd(Tag.div);
writer.comment("========= END OF "+barComment+" NAVBAR ======="); writer.comment("========= END OF "+barComment+" NAVBAR =======");

View file

@ -30,6 +30,7 @@ import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap;
import org.x4o.xml.eld.doc.api.ApiDocNodeDataConfiguratorBean; import org.x4o.xml.eld.doc.api.ApiDocNodeDataConfiguratorBean;
import org.x4o.xml.eld.doc.api.ApiDocNodeWriterBean; import org.x4o.xml.eld.doc.api.ApiDocNodeWriterBean;
@ -75,6 +76,7 @@ public class ApiDoc {
private boolean printConceptTitle = true; private boolean printConceptTitle = true;
private boolean printConceptPrevNext = true; private boolean printConceptPrevNext = true;
private Map<String,String> groupTypeNames = null; private Map<String,String> groupTypeNames = null;
private Map<String,Integer> groupTypeOrder = null;
private String docPageSubTitle = null; private String docPageSubTitle = null;
public ApiDoc() { public ApiDoc() {
@ -88,6 +90,7 @@ public class ApiDoc {
annotatedClasses = new ArrayList<Class<?>>(5); annotatedClasses = new ArrayList<Class<?>>(5);
remoteClasses = new ArrayList<ApiDocRemoteClass>(5); remoteClasses = new ArrayList<ApiDocRemoteClass>(5);
groupTypeNames = new HashMap<String,String>(3); groupTypeNames = new HashMap<String,String>(3);
groupTypeOrder = new HashMap<String,Integer>(3);
} }
public void checkModel() throws NullPointerException,IllegalArgumentException { public void checkModel() throws NullPointerException,IllegalArgumentException {
@ -671,6 +674,15 @@ public class ApiDoc {
this.printConceptPrevNext = printConceptPrevNext; this.printConceptPrevNext = printConceptPrevNext;
} }
public List<String> getGroupTypesOrdered() {
Map<Integer,String> orderedMap = new TreeMap<Integer,String>();
for (String key:groupTypeOrder.keySet()) {
Integer order = groupTypeOrder.get(key);
orderedMap.put(order, key);
}
return new ArrayList<String>(orderedMap.values());
}
public String getGroupTypeName(String groupTypeKey) { public String getGroupTypeName(String groupTypeKey) {
String result = groupTypeNames.get(groupTypeKey); String result = groupTypeNames.get(groupTypeKey);
if (result==null) { if (result==null) {
@ -679,8 +691,9 @@ public class ApiDoc {
return result; return result;
} }
public void setGroupTypeName(String groupTypeKey,String name) { public void setGroupTypeName(String groupTypeKey,String name,int order) {
groupTypeNames.put(groupTypeKey,name); groupTypeNames.put(groupTypeKey,name);
groupTypeOrder.put(groupTypeKey, order);
} }
/** /**

View file

@ -0,0 +1,127 @@
/*
* 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.eld.doc.api.dom;
/**
* ApiDocIndexItem holds data to print the index all page.
*
* @author Willem Cazander
* @version 1.0 Nov 09, 2013
*/
public class ApiDocIndexItem {
private String linkHref = null;
private String linkText = null;
private String titlePostHref = null;
private String titlePostText = null;
private String title = null;
private String description = null;
public ApiDocIndexItem() {
}
/**
* @return the linkHref
*/
public String getLinkHref() {
return linkHref;
}
/**
* @param linkHref the linkHref to set
*/
public void setLinkHref(String linkHref) {
this.linkHref = linkHref;
}
/**
* @return the linkText
*/
public String getLinkText() {
return linkText;
}
/**
* @param linkText the linkText to set
*/
public void setLinkText(String linkText) {
this.linkText = linkText;
}
/**
* @return the titlePostHref
*/
public String getTitlePostHref() {
return titlePostHref;
}
/**
* @param titlePostHref the titlePostHref to set
*/
public void setTitlePostHref(String titlePostHref) {
this.titlePostHref = titlePostHref;
}
/**
* @return the titlePostText
*/
public String getTitlePostText() {
return titlePostText;
}
/**
* @param titlePostText the titlePostText to set
*/
public void setTitlePostText(String titlePostText) {
this.titlePostText = titlePostText;
}
/**
* @return the title
*/
public String getTitle() {
return title;
}
/**
* @param title the title to set
*/
public void setTitle(String title) {
this.title = title;
}
/**
* @return the description
*/
public String getDescription() {
return description;
}
/**
* @param description the description to set
*/
public void setDescription(String description) {
this.description = description;
}
}

View file

@ -43,11 +43,21 @@ public class ApiDocNodeData {
private String nextLink = null; private String nextLink = null;
private String framePath = null;; private String framePath = null;;
private List<ApiDocNavLink> navLinks = null; private List<ApiDocNavLink> navLinks = null;
private List<ApiDocIndexItem> indexItems = null;
public ApiDocNodeData() { public ApiDocNodeData() {
navLinks = new ArrayList<ApiDocNavLink>(12); navLinks = new ArrayList<ApiDocNavLink>(12);
groupTypeKeys = new ArrayList<String>(navLinks.size()/3); groupTypeKeys = new ArrayList<String>(navLinks.size()/3);
groupTypeLinks = new HashMap<String,List<ApiDocNavLink>>(groupTypeKeys.size()); groupTypeLinks = new HashMap<String,List<ApiDocNavLink>>(groupTypeKeys.size());
indexItems = new ArrayList<ApiDocIndexItem>(500);
}
public List<ApiDocIndexItem> getIndexItems() {
return indexItems;
}
public void addIndexItem(ApiDocIndexItem indexItem) {
indexItems.add(indexItem);
} }
public void addGroupTypeKey(String groupTypeKey) { public void addGroupTypeKey(String groupTypeKey) {