Easter cleaning
This commit is contained in:
commit
9e36078b2e
1862 changed files with 270281 additions and 0 deletions
160
nx01-x4o-sax3/src/main/java/org/x4o/sax3/SAX3WriterEnum.java
Normal file
160
nx01-x4o-sax3/src/main/java/org/x4o/sax3/SAX3WriterEnum.java
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.x4o.sax3.io.ContentCloseable;
|
||||
import org.x4o.sax3.io.ContentWriter;
|
||||
import org.x4o.sax3.io.SAX3XMLConstants;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
|
||||
/**
|
||||
* ContentWriterXmlTag can write enum based xml events.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 May 3, 2013
|
||||
*/
|
||||
public class SAX3WriterEnum<TAG extends Enum<?>,TAG_WRITER extends ContentWriter> implements SAX3WriterEnumHammer<TAG>, Closeable {
|
||||
|
||||
private final Attributes EMPTY_ATTRIBUTES = new AttributesImpl();
|
||||
private final TAG_WRITER contentWriter;
|
||||
private final String tagNamespaceUri;
|
||||
private final String tagNamespacePrefix;
|
||||
|
||||
public SAX3WriterEnum(TAG_WRITER contentWriter) {
|
||||
this(contentWriter, SAX3XMLConstants.NULL_NS_URI, SAX3XMLConstants.NULL_NS_URI);
|
||||
}
|
||||
|
||||
public SAX3WriterEnum(TAG_WRITER contentWriter, String tagNamespaceUri, String tagNamespacePrefix) {
|
||||
this.contentWriter = Objects.requireNonNull(contentWriter, "Can't create wrapper on null ContentWriter");
|
||||
this.tagNamespaceUri = Objects.requireNonNull(tagNamespaceUri, "Can't create wrapper with null tagNamespaceUri");
|
||||
this.tagNamespacePrefix = Objects.requireNonNull(tagNamespacePrefix, "Can't create wrapper with null tagNamespacePrefix");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
contentWriter.close();
|
||||
}
|
||||
|
||||
public TAG_WRITER getContentWriterWrapped() {
|
||||
return contentWriter;
|
||||
}
|
||||
|
||||
public String getTagNamespaceUri() {
|
||||
return tagNamespaceUri;
|
||||
}
|
||||
|
||||
public void startDocument() throws IOException {
|
||||
try {
|
||||
contentWriter.startDocument();
|
||||
contentWriter.startPrefixMapping(tagNamespacePrefix, getTagNamespaceUri());
|
||||
} catch (SAXException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void endDocument() throws IOException {
|
||||
try {
|
||||
contentWriter.endDocument();
|
||||
} catch (SAXException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public ContentCloseable printTag(TAG tag) throws IOException {
|
||||
return printTag(tag, EMPTY_ATTRIBUTES);
|
||||
}
|
||||
|
||||
public ContentCloseable printTag(TAG tag, Attributes atts) throws IOException {
|
||||
printTagStart(tag, atts);
|
||||
return () -> printTagEnd(tag);
|
||||
}
|
||||
|
||||
public void printTagStartEnd(TAG tag, Attributes atts) throws IOException {
|
||||
printTagStart(tag, atts);
|
||||
printTagEnd(tag);
|
||||
}
|
||||
|
||||
public void printTagStartEnd(TAG tag) throws IOException {
|
||||
printTagStart(tag);
|
||||
printTagEnd(tag);
|
||||
}
|
||||
|
||||
public void printTagStart(TAG tag) throws IOException {
|
||||
printTagStart(tag, EMPTY_ATTRIBUTES);
|
||||
}
|
||||
|
||||
public void printTagStart(TAG tag, Attributes atts) throws IOException {
|
||||
try {
|
||||
contentWriter.startElement(getTagNamespaceUri(), toTagString(tag), "", atts);
|
||||
} catch (SAXException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void printTagEnd(TAG tag) throws IOException {
|
||||
try {
|
||||
contentWriter.endElement(getTagNamespaceUri(),toTagString(tag) , "");
|
||||
} catch (SAXException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String toTagString(TAG tag) {
|
||||
String result = tag.name();
|
||||
if (result.startsWith("_")) {
|
||||
result = result.substring(1); // remove _
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void printTagCharacters(TAG tag, String text) throws IOException {
|
||||
printTagStart(tag);
|
||||
if (text == null) {
|
||||
text = " ";
|
||||
}
|
||||
printCharacters(text);
|
||||
printTagEnd(tag);
|
||||
}
|
||||
|
||||
public void printCharacters(String text) throws IOException {
|
||||
try {
|
||||
contentWriter.characters(text);
|
||||
} catch (SAXException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void printComment(String text) throws IOException {
|
||||
try {
|
||||
contentWriter.comment(text);
|
||||
} catch (SAXException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
/**
|
||||
* ContentWriterTag writes enum tags as xml.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 May 3, 2013
|
||||
*/
|
||||
public interface SAX3WriterEnumHammer<TAG extends Enum<?>> {
|
||||
|
||||
String getTagNamespaceUri();
|
||||
|
||||
void startDocument() throws IOException;
|
||||
|
||||
void endDocument() throws IOException;
|
||||
|
||||
void printTagStartEnd(TAG tag) throws IOException;
|
||||
|
||||
void printTagStartEnd(TAG tag, Attributes atts) throws IOException;
|
||||
|
||||
void printTagStart(TAG tag) throws IOException;
|
||||
|
||||
void printTagStart(TAG tag, Attributes atts) throws IOException;
|
||||
|
||||
void printTagEnd(TAG tag) throws IOException;
|
||||
|
||||
void printTagCharacters(TAG tag, String text) throws IOException;
|
||||
|
||||
void printCharacters(String text) throws IOException;
|
||||
|
||||
void printComment(String text) throws IOException;
|
||||
}
|
||||
324
nx01-x4o-sax3/src/main/java/org/x4o/sax3/SAX3WriterHtml.java
Normal file
324
nx01-x4o-sax3/src/main/java/org/x4o/sax3/SAX3WriterHtml.java
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.x4o.sax3.io.ContentCloseable;
|
||||
import org.x4o.sax3.io.SAX3PropertyConfig;
|
||||
import org.x4o.sax3.io.SAX3XMLConstants;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
|
||||
/**
|
||||
* ContentWriterHtml writes HTML events as SAX events to XML.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Apr 30, 2013
|
||||
*/
|
||||
public class SAX3WriterHtml extends SAX3WriterEnum<SAX3WriterHtml.Tag,SAX3WriterXml> {
|
||||
|
||||
public SAX3WriterHtml(Writer out, String encoding) {
|
||||
super(new SAX3WriterXml(out, encoding), "", SAX3XMLConstants.NULL_NS_URI);
|
||||
}
|
||||
|
||||
public SAX3PropertyConfig getPropertyConfig() {
|
||||
return getContentWriterWrapped().getPropertyConfig();
|
||||
}
|
||||
|
||||
public void printDocType(DocType doc) throws IOException {
|
||||
try {
|
||||
getContentWriterWrapped().startDTD(doc.getName(), doc.getPublicId(), doc.getSystemId());
|
||||
} catch (SAXException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void printHtmlStart(String language) throws IOException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
if (language != null) {
|
||||
atts.addAttribute("", "lang", "", "", language);
|
||||
}
|
||||
printTagStart(Tag.html, atts);
|
||||
}
|
||||
|
||||
public void printHtmlEnd() throws IOException {
|
||||
printTagEnd(Tag.html);
|
||||
}
|
||||
|
||||
public void printHeadMetaDate() throws IOException {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
printHeadMeta("date", cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH)+1) + "-" + cal.get(Calendar.DAY_OF_MONTH));
|
||||
}
|
||||
|
||||
public void printHeadTitle(String title) throws IOException {
|
||||
printTagCharacters(Tag.title, title);
|
||||
}
|
||||
|
||||
public void printHeadMetaContentType() throws IOException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute("", "http-equiv", "", "", "Content-Type");
|
||||
atts.addAttribute("", "content", "", "", "text/html");
|
||||
atts.addAttribute("", "charset", "", "", getPropertyConfig().getPropertyString(SAX3WriterXml.OUTPUT_ENCODING));
|
||||
printTagStartEnd(Tag.meta, atts);
|
||||
}
|
||||
|
||||
public void printHeadMeta(String name, String content) throws IOException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute("", "name", "", "", name);
|
||||
atts.addAttribute("", "content", "", "", content);
|
||||
printTagStartEnd(Tag.meta, atts);
|
||||
}
|
||||
|
||||
public void printHeadLinkCss(String cssUrl) throws IOException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute("", "rel", "", "", "stylesheet");
|
||||
atts.addAttribute("", "type", "", "", "text/css");
|
||||
atts.addAttribute("", "title", "", "", "Style");
|
||||
atts.addAttribute("", "href", "", "", cssUrl);
|
||||
printTagStartEnd(Tag.link, atts);
|
||||
}
|
||||
|
||||
public void printScriptSrc(String jsUrl) throws IOException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute("", "type", "", "", "text/javascript");
|
||||
atts.addAttribute("", "src", "", "", jsUrl);
|
||||
printTagStart(Tag.script, atts);
|
||||
printCharacters(" "); // NOTE: space needed to keep browsers happy
|
||||
printTagEnd(Tag.script);
|
||||
}
|
||||
|
||||
public void printScriptInline(String script) throws IOException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute("", "type", "", "", "text/javascript");
|
||||
printTagStart(Tag.script, atts);
|
||||
printComment(script);
|
||||
printTagEnd(Tag.script);
|
||||
}
|
||||
|
||||
public void printScriptNoDiv() throws IOException {
|
||||
printScriptNoDiv(null);
|
||||
}
|
||||
|
||||
public void printScriptNoDiv(String text) throws IOException {
|
||||
if (text == null) {
|
||||
text = "JavaScript is disabled on your browser.";
|
||||
}
|
||||
printTagStart(Tag.noscript);
|
||||
printTagStart(Tag.div);printCharacters(text);printTagEnd(Tag.div);
|
||||
printTagEnd(Tag.noscript);
|
||||
}
|
||||
|
||||
public void printHrefNamed(String name) throws IOException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute("", "name", "", "", name);
|
||||
printTagStart(Tag.a, atts);
|
||||
printComment(" ");
|
||||
printTagEnd(Tag.a);
|
||||
}
|
||||
|
||||
public void printHrefTarget(String href, String target, String text) throws IOException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute("", "href", "", "", href);
|
||||
atts.addAttribute("", "target", "", "", target);
|
||||
printTagStart(Tag.a, atts);
|
||||
printCharacters(text);
|
||||
printTagEnd(Tag.a);
|
||||
}
|
||||
|
||||
public void printHref(String href, String text) throws IOException {
|
||||
printHref(href, text, text);
|
||||
}
|
||||
|
||||
public void printHref(String href, String text, String title) throws IOException {
|
||||
printHref(href, text, title, null);
|
||||
}
|
||||
|
||||
public void printHref(String href, String text, String title, String spanClass) throws IOException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute("", "href", "", "", href);
|
||||
if (title != null) {
|
||||
atts.addAttribute("", "title", "", "", title);
|
||||
}
|
||||
printTagStart(Tag.a,atts);
|
||||
if (spanClass != null) {
|
||||
atts = new AttributesImpl();
|
||||
if (spanClass.length() > 0) {
|
||||
atts.addAttribute("", "class", "", "", spanClass);
|
||||
}
|
||||
printTagStart(Tag.span,atts);
|
||||
}
|
||||
printCharacters(text);
|
||||
if (spanClass != null) {
|
||||
printTagEnd(Tag.span);
|
||||
}
|
||||
printTagEnd(Tag.a);
|
||||
}
|
||||
|
||||
public void printTagCharacters(Tag tag, String text, String tagClass) throws IOException {
|
||||
printTagCharacters(tag, text, tagClass, null);
|
||||
}
|
||||
|
||||
public void printTagCharacters(Tag tag, String text, String tagClass, String tagId) throws IOException {
|
||||
printTagStart(tag, tagClass, tagId, null);
|
||||
if (text == null) {
|
||||
text = " ";
|
||||
}
|
||||
printCharacters(text);
|
||||
printTagEnd(tag);
|
||||
}
|
||||
|
||||
public ContentCloseable printTag(Tag tag, String tagClass) throws IOException {
|
||||
return printTag(tag, tagClass, null, null);
|
||||
}
|
||||
|
||||
public ContentCloseable printTag(Tag tag, Enum<?> tagClassEnum) throws IOException {
|
||||
return printTag(tag, tagClassEnum, null);
|
||||
}
|
||||
|
||||
public ContentCloseable printTag(Tag tag, Enum<?> tagClassEnum, String tagId) throws IOException {
|
||||
return printTag(tag, tagClassEnum, tagId, null);
|
||||
}
|
||||
|
||||
public ContentCloseable printTag(Tag tag, Enum<?> tagClassEnum, String tagId, String typeId) throws IOException {
|
||||
return printTag(tag, tagClassEnum.name(), tagId, typeId);
|
||||
}
|
||||
|
||||
public ContentCloseable printTag(Tag tag, String tagClass, String tagId, String typeId) throws IOException {
|
||||
printTagStart(tag, tagClass, tagId, typeId);
|
||||
return () -> printTagEnd(tag);
|
||||
}
|
||||
|
||||
public void printTagStart(Tag tag, String tagClass) throws IOException {
|
||||
printTagStart(tag, tagClass, null, null);
|
||||
}
|
||||
|
||||
public void printTagStart(Tag tag, Enum<?> tagClassEnum) throws IOException {
|
||||
printTagStart(tag, tagClassEnum, null);
|
||||
}
|
||||
|
||||
public void printTagStart(Tag tag, Enum<?> tagClassEnum, String tagId) throws IOException {
|
||||
printTagStart(tag, tagClassEnum, tagId, null);
|
||||
}
|
||||
|
||||
public void printTagStart(Tag tag, Enum<?> tagClassEnum, String tagId, String typeId) throws IOException {
|
||||
printTagStart(tag, tagClassEnum.name(), tagId, typeId);
|
||||
}
|
||||
|
||||
public void printTagStart(Tag tag, String tagClass, String tagId, String typeId) throws IOException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
if (tagId != null && tagId.length() > 0) {
|
||||
atts.addAttribute("", "id", "", "", tagId);
|
||||
}
|
||||
if (tagClass != null && tagClass.length() > 0) {
|
||||
atts.addAttribute("", "class", "", "", tagClass);
|
||||
}
|
||||
if (typeId != null && typeId.length() > 0) {
|
||||
atts.addAttribute("", "type", "", "", typeId);
|
||||
}
|
||||
printTagStart(tag, atts);
|
||||
}
|
||||
|
||||
public enum Tag {
|
||||
|
||||
/* Deprecated TAGS */
|
||||
frameset,frame,noframes,tt,font,dir,center,strike,
|
||||
big,basefont,acronym,applet,iframe,
|
||||
|
||||
/* HTML 4 TAGS */
|
||||
html,head,title,meta,link,base,body,script,style,
|
||||
|
||||
h1,h2,h3,h4,h5,h6,
|
||||
a,div,span,p,pre,img,hr,br,
|
||||
b,em,strong,small,noscript,
|
||||
|
||||
ul,li,dl,dt,dd,ol,
|
||||
table,thead,tfoot,tbody,caption,th,tr,td,
|
||||
|
||||
abbr,address,area,bdo,blockquote,
|
||||
cite,code,col,colgroup,del,dfn,i,ins,
|
||||
kbd,legend,map,menu,object,param,
|
||||
optgroup,q,s,samp,sub,u,var,
|
||||
|
||||
form,fieldset,input,option,
|
||||
label,button,select,textarea,
|
||||
|
||||
/* HTML 5 TAGS */
|
||||
canvas,audio,video,source,embed,track,
|
||||
datalist,keygen,output,
|
||||
article,aside,bdi,command,details,dialog,summary,
|
||||
figure,figcaption,footer,header,hgroup,mark,meter,
|
||||
nav,progress,ruby,rt,rp,section,time,wbr,
|
||||
;
|
||||
}
|
||||
|
||||
private final static String DOCTYPE_NAME = "HTML PUBLIC";
|
||||
public enum DocType {
|
||||
/* Order from worst to better. */
|
||||
HTML_5("html","",""),
|
||||
|
||||
HTML_4_FRAMESET(DOCTYPE_NAME,"\"-//W3C//DTD HTML 4.01 Frameset//EN\"","http://www.w3.org/TR/html4/frameset.dtd"),
|
||||
HTML_4_TRANSITIONAL(DOCTYPE_NAME,"\"-//W3C//DTD HTML 4.01 Transitional//EN\"","http://www.w3.org/TR/html4/loose.dtd"),
|
||||
HTML_4_STRICT(DOCTYPE_NAME,"\"-//W3C//DTD HTML 4.01//EN\"","http://www.w3.org/TR/html4/strict.dtd"),
|
||||
|
||||
XHTML_1_FRAMESET(DOCTYPE_NAME,"\"-//W3C//DTD XHTML 1.0 Frameset//EN\"","http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"),
|
||||
XHTML_1_TRANSITIONAL(DOCTYPE_NAME,"\"-//W3C//DTD XHTML 1.0 Transitional//EN\"","http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"),
|
||||
XHTML_1_STRICT(DOCTYPE_NAME,"\"-//W3C//DTD XHTML 1.0 Strict//EN\"","http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"),
|
||||
|
||||
XHTML_11(DOCTYPE_NAME,"\"-//W3C//DTD XHTML 1.1//EN\"","http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"),
|
||||
;
|
||||
|
||||
private final String name;
|
||||
private final String publicId;
|
||||
private final String systemId;
|
||||
|
||||
private DocType(String name, String publicId, String systemId) {
|
||||
this.name = name;
|
||||
this.publicId = publicId;
|
||||
this.systemId = systemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the publicId
|
||||
*/
|
||||
public String getPublicId() {
|
||||
return publicId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the systemId
|
||||
*/
|
||||
public String getSystemId() {
|
||||
return systemId;
|
||||
}
|
||||
}
|
||||
}
|
||||
76
nx01-x4o-sax3/src/main/java/org/x4o/sax3/SAX3WriterXml.java
Normal file
76
nx01-x4o-sax3/src/main/java/org/x4o/sax3/SAX3WriterXml.java
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Writer;
|
||||
|
||||
import org.x4o.sax3.io.AbstractContentWriter;
|
||||
import org.x4o.sax3.io.SAX3XMLConstants;
|
||||
|
||||
/**
|
||||
* ContentWriterXml writes SAX content handler events to XML.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Apr 17, 2005
|
||||
*/
|
||||
public class SAX3WriterXml extends AbstractContentWriter {
|
||||
|
||||
/**
|
||||
* Creates XmlWriter which prints to the Writer interface.
|
||||
* @param out The writer to print the xml to.
|
||||
*/
|
||||
public SAX3WriterXml(Writer out, String encoding) {
|
||||
super(out);
|
||||
getPropertyConfig().setProperty(OUTPUT_ENCODING, encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates XmlWriter which prints to the Writer interface.
|
||||
* @param out The writer to print the xml to.
|
||||
*/
|
||||
public SAX3WriterXml(Writer out) {
|
||||
this(out,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates XmlWriter which prints to the OutputStream interface.
|
||||
* @param out The OutputStream to write to.
|
||||
* @throws UnsupportedEncodingException Is thrown when UTF-8 can't we printed.
|
||||
*/
|
||||
public SAX3WriterXml(OutputStream out) throws UnsupportedEncodingException {
|
||||
this(new OutputStreamWriter(out, SAX3XMLConstants.XML_DEFAULT_ENCODING), SAX3XMLConstants.XML_DEFAULT_ENCODING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates XmlWriter which prints to the OutputStream interface.
|
||||
* @param out The OutputStream to write to.
|
||||
* @param encoding The OutputStream encoding.
|
||||
* @throws UnsupportedEncodingException Is thrown when UTF-8 can't we printed.
|
||||
*/
|
||||
public SAX3WriterXml(OutputStream out,String encoding) throws UnsupportedEncodingException {
|
||||
this(new OutputStreamWriter(out, encoding), encoding);
|
||||
}
|
||||
}
|
||||
84
nx01-x4o-sax3/src/main/java/org/x4o/sax3/SAX3WriterXsd.java
Normal file
84
nx01-x4o-sax3/src/main/java/org/x4o/sax3/SAX3WriterXsd.java
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
import org.x4o.sax3.io.SAX3PropertyConfig;
|
||||
import org.x4o.sax3.io.SAX3XMLConstants;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
|
||||
/**
|
||||
* ContentWriterXsd writes XSD events as SAX events to XML.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 May 3, 2013
|
||||
*/
|
||||
public class SAX3WriterXsd extends SAX3WriterEnum<SAX3WriterXsd.Tag,SAX3WriterXml> {
|
||||
|
||||
public SAX3WriterXsd(Writer out, String encoding) {
|
||||
super(new SAX3WriterXml(out, encoding), SAX3XMLConstants.XML_SCHEMA_NS_URI, SAX3XMLConstants.NULL_NS_URI);
|
||||
}
|
||||
|
||||
public SAX3PropertyConfig getPropertyConfig() {
|
||||
return getContentWriterWrapped().getPropertyConfig();
|
||||
}
|
||||
|
||||
public void printXsdImport(String namespace, String schemaLocation) throws IOException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute("", "namespace", "", "", namespace);
|
||||
atts.addAttribute("", "schemaLocation", "", "", schemaLocation);
|
||||
printTagStartEnd(Tag._import, atts);
|
||||
}
|
||||
|
||||
public void printXsdDocumentation(String description) throws IOException {
|
||||
if (description == null) {
|
||||
return;
|
||||
}
|
||||
printTagStart(Tag.annotation);
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute("", "xml:lang", "", "", "en");
|
||||
printTagStart(Tag.documentation, atts);
|
||||
printCharacters(description);
|
||||
printTagEnd(Tag.documentation);
|
||||
printTagEnd(Tag.annotation);
|
||||
}
|
||||
|
||||
public void printXsdElementAttribute(String name, String type, String description) throws IOException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute("", "name", "", "", name);
|
||||
atts.addAttribute("", "type", "", "", type);
|
||||
printTagStart(Tag.attribute, atts);
|
||||
printXsdDocumentation(description);
|
||||
printTagEnd(Tag.attribute);
|
||||
}
|
||||
|
||||
public enum Tag {
|
||||
all,annotation,any,anyAttribute,appinfo,attribute,attributeGroup,
|
||||
choice,complexContent,complexType,documentation,element,extension,
|
||||
field,group,_import,include,key,keyref,list,notation,
|
||||
redefine,restriction,schema,selector,sequence,
|
||||
simpleContent,simpleType,unoin,unique
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* ContentWriterXml writes SAX content handler events to XML.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 May 3, 2013
|
||||
*/
|
||||
public abstract class AbstractContentWriter extends AbstractContentWriterLexical implements ContentWriter {
|
||||
|
||||
/**
|
||||
* Creates an Lecical content writer for XML.
|
||||
* @param out The writer to write to.
|
||||
*/
|
||||
public AbstractContentWriter(Writer out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts and end then element.
|
||||
* @see org.x4o.sax3.io.ContentWriter#startElementEnd(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
|
||||
*/
|
||||
public void startElementEnd(String uri, String localName, String name, Attributes atts) throws SAXException {
|
||||
startElement(uri, localName, name, atts);
|
||||
endElement(uri, localName, name);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,728 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.x4o.sax3.io.SAX3PropertyConfig.PropertyConfigItem;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.Locator;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* AbstractContentWriterHandler writes SAX content handler events as XML.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 May 3, 2013
|
||||
*/
|
||||
public class AbstractContentWriterHandler implements ContentHandler, Closeable {
|
||||
|
||||
private final SAX3PropertyConfig propertyConfig;
|
||||
private final Writer out;
|
||||
private int indent = 0;
|
||||
private Map<String,String> prefixMapping = null;
|
||||
private List<String> printedMappings = null;
|
||||
private StringBuilder startElement = null;
|
||||
private boolean printReturn = false;
|
||||
private String lastElement = null;
|
||||
private Stack<String> elements = null;
|
||||
|
||||
private final static String PROPERTY_CONTEXT_PREFIX = SAX3PropertyConfig.X4O_PROPERTIES_PREFIX + "content/"; // TODO: change to "writer/xml"
|
||||
public final static SAX3PropertyConfig DEFAULT_PROPERTY_CONFIG;
|
||||
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_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_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_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_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_ENABLE = PROPERTY_CONTEXT_PREFIX + "prolog/licence-enable";
|
||||
public final static String PROLOG_USER_COMMENT = PROPERTY_CONTEXT_PREFIX + "prolog/user-comment";
|
||||
public final static String PROLOG_USER_COMMENT_ENABLE = PROPERTY_CONTEXT_PREFIX + "prolog/user-comment-enable";
|
||||
public final static String ROOT_END_APPEND_NEWLINE = PROPERTY_CONTEXT_PREFIX + "root/end-append-newline";
|
||||
public final static String ROOT_START_NAMESPACE_ALL = PROPERTY_CONTEXT_PREFIX + "root/start-namespace-all";
|
||||
|
||||
static {
|
||||
DEFAULT_PROPERTY_CONFIG = new SAX3PropertyConfig(true,null,PROPERTY_CONTEXT_PREFIX,
|
||||
new PropertyConfigItem(OUTPUT_ENCODING, String.class, SAX3XMLConstants.XML_DEFAULT_ENCODING),
|
||||
new PropertyConfigItem(OUTPUT_CHAR_TAB, String.class, SAX3XMLConstants.CHAR_TAB+""),
|
||||
new PropertyConfigItem(OUTPUT_CHAR_NEWLINE, String.class, SAX3XMLConstants.CHAR_NEWLINE+""),
|
||||
new PropertyConfigItem(OUTPUT_CHAR_NULL, String.class, "NULL"),
|
||||
new PropertyConfigItem(OUTPUT_COMMENT_ENABLE, Boolean.class, true),
|
||||
new PropertyConfigItem(OUTPUT_COMMENT_AUTO_SPACE, Boolean.class, true),
|
||||
new PropertyConfigItem(OUTPUT_LINE_BREAK_WIDTH, Integer.class, -1),
|
||||
new PropertyConfigItem(OUTPUT_LINE_PER_ATTRIBUTE, Boolean.class, false),
|
||||
new PropertyConfigItem(PROLOG_LICENCE_ENCODING, String.class, SAX3XMLConstants.XML_DEFAULT_ENCODING),
|
||||
new PropertyConfigItem(PROLOG_LICENCE_FILE, File.class ),
|
||||
new PropertyConfigItem(PROLOG_LICENCE_RESOURCE, String.class ),
|
||||
new PropertyConfigItem(PROLOG_LICENCE_ENABLE, Boolean.class, true),
|
||||
new PropertyConfigItem(PROLOG_USER_COMMENT, String.class ),
|
||||
new PropertyConfigItem(PROLOG_USER_COMMENT_ENABLE, Boolean.class, true),
|
||||
new PropertyConfigItem(ROOT_END_APPEND_NEWLINE, Boolean.class, true),
|
||||
new PropertyConfigItem(ROOT_START_NAMESPACE_ALL, Boolean.class, true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates XmlWriter which prints to the Writer interface.
|
||||
* @param out The writer to print the xml to.
|
||||
*/
|
||||
public AbstractContentWriterHandler(Writer out) {
|
||||
this.out = Objects.requireNonNull(out, "Can't write on null writer.");
|
||||
this.prefixMapping = new HashMap<String,String>(15);
|
||||
this.printedMappings = new ArrayList<String>(15);
|
||||
this.elements = new Stack<String>();
|
||||
this.propertyConfig = new SAX3PropertyConfig(DEFAULT_PROPERTY_CONFIG, PROPERTY_CONTEXT_PREFIX);
|
||||
}
|
||||
|
||||
public SAX3PropertyConfig getPropertyConfig() {
|
||||
return propertyConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
out.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ContentHandler#startDocument()
|
||||
*/
|
||||
public void startDocument() throws SAXException {
|
||||
indent = 0;
|
||||
write(SAX3XMLConstants.getDocumentDeclaration(getPropertyConfig().getPropertyString(OUTPUT_ENCODING)));
|
||||
prologWriteLicence();
|
||||
prologWriteUserComment();
|
||||
}
|
||||
|
||||
private void prologWriteLicence() throws SAXException {
|
||||
if (!propertyConfig.getPropertyBoolean(PROLOG_LICENCE_ENABLE)) {
|
||||
return;
|
||||
}
|
||||
InputStream licenceInput = null;
|
||||
String licenceEncoding = propertyConfig.getPropertyString(PROLOG_LICENCE_ENCODING);
|
||||
String licenceResource = propertyConfig.getPropertyString(PROLOG_LICENCE_RESOURCE);
|
||||
if (licenceResource != null) {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
if (cl == null) {
|
||||
cl = this.getClass().getClassLoader();
|
||||
}
|
||||
licenceInput = cl.getResourceAsStream(licenceResource);
|
||||
if (licenceInput == null) {
|
||||
throw new NullPointerException("Could not load licence resource from: " + licenceResource);
|
||||
}
|
||||
}
|
||||
if (licenceInput == null) {
|
||||
File licenceFile = propertyConfig.getPropertyFile(PROLOG_LICENCE_FILE);
|
||||
if (licenceFile == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
licenceInput = new FileInputStream(licenceFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new SAXException(e);
|
||||
}
|
||||
}
|
||||
String licenceText;
|
||||
try {
|
||||
licenceText = readLicenceStream(licenceInput, licenceEncoding);
|
||||
} catch (IOException e) {
|
||||
throw new SAXException(e);
|
||||
}
|
||||
comment(licenceText);
|
||||
}
|
||||
|
||||
private String readLicenceStream(InputStream inputStream, String encoding) throws IOException {
|
||||
if (encoding == null) {
|
||||
encoding = SAX3XMLConstants.XML_DEFAULT_ENCODING;
|
||||
}
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, Charset.forName(encoding)));
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('\n');
|
||||
sb.append('\n');
|
||||
String line = br.readLine();
|
||||
while (line != null) {
|
||||
if (line.length() > 0) {
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(line);
|
||||
sb.append('\n');
|
||||
line = br.readLine();
|
||||
}
|
||||
sb.append('\n');
|
||||
String out = sb.toString();
|
||||
return out;
|
||||
} finally {
|
||||
br.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void prologWriteUserComment() throws SAXException {
|
||||
if (!propertyConfig.getPropertyBoolean(PROLOG_USER_COMMENT_ENABLE)) {
|
||||
return;
|
||||
}
|
||||
String userComment = propertyConfig.getPropertyString(PROLOG_USER_COMMENT);
|
||||
if (userComment == null) {
|
||||
return;
|
||||
}
|
||||
if (userComment.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String chEnter = getPropertyConfig().getPropertyString(OUTPUT_CHAR_NEWLINE);
|
||||
String chTab = getPropertyConfig().getPropertyString(OUTPUT_CHAR_TAB);
|
||||
userComment = userComment.replaceAll("\n", chEnter + chTab);
|
||||
comment(chEnter + chTab + userComment + chEnter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ContentHandler#endDocument()
|
||||
*/
|
||||
public void endDocument() throws SAXException {
|
||||
writeFlush();
|
||||
if (elements.size() > 0) {
|
||||
throw new SAXException("Invalid xml still have " + elements.size() + " elements open.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri The xml namespace uri.
|
||||
* @param localName The local name of the xml tag.
|
||||
* @param name The (full) name of the xml tag.
|
||||
* @param atts The attributes of the xml tag.
|
||||
* @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
|
||||
*/
|
||||
public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException {
|
||||
if (localName == null) {
|
||||
throw new SAXException("LocalName may not be null.");
|
||||
}
|
||||
if (SAX3XMLConstants.isNameString(localName)==false) {
|
||||
throw new SAXException("LocalName of element is not valid in xml; '" + localName + "'");
|
||||
}
|
||||
for (int i = 0; i < atts.getLength(); i++) {
|
||||
boolean isFirst = true;
|
||||
String attrLocalName = atts.getLocalName(i);
|
||||
if (attrLocalName.isEmpty()) {
|
||||
throw new SAXException("LocalAttributeName is missing characters");
|
||||
}
|
||||
PrimitiveIterator.OfInt iterator = attrLocalName.codePoints().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
int c = iterator.nextInt();
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
if (!SAX3XMLConstants.isNameStartChar(attrLocalName.codePoints().findFirst().getAsInt())) {
|
||||
throw new SAXException("LocalAttributeName has illegal start character: " + attrLocalName);
|
||||
}
|
||||
}
|
||||
if (!SAX3XMLConstants.isNameChar(c)) {
|
||||
throw new SAXException("LocalAttributeName has illegal name character: " + attrLocalName);
|
||||
}
|
||||
}
|
||||
}
|
||||
autoCloseStartElement();
|
||||
startElement = new StringBuilder(200);
|
||||
startElement.append(getPropertyConfig().getPropertyString(OUTPUT_CHAR_NEWLINE));
|
||||
for (int i = 0; i < indent; i++) {
|
||||
startElement.append(getPropertyConfig().getPropertyString(OUTPUT_CHAR_TAB));
|
||||
}
|
||||
startElement.append(SAX3XMLConstants.TAG_OPEN);
|
||||
|
||||
startElementTag(uri,localName);
|
||||
startElementNamespace(uri);
|
||||
startElementNamespaceAll();
|
||||
startElementAttributes(atts);
|
||||
startElement.append(SAX3XMLConstants.TAG_CLOSE);
|
||||
indent++;
|
||||
lastElement = localName;
|
||||
elements.push(localName);
|
||||
}
|
||||
|
||||
public void startElementTag(String uri, String localName) throws SAXException {
|
||||
if (SAX3XMLConstants.NULL_NS_URI.equals(uri) || uri == null) {
|
||||
startElement.append(localName);
|
||||
} else {
|
||||
String prefix = prefixMapping.get(uri);
|
||||
if (prefix == null) {
|
||||
throw new SAXException("preFixUri: " + uri + " is not started.");
|
||||
}
|
||||
if (SAX3XMLConstants.NULL_NS_URI.equals(prefix) == false) {
|
||||
startElement.append(prefix);
|
||||
startElement.append(SAX3XMLConstants.XMLNS_ASSIGN);
|
||||
}
|
||||
startElement.append(localName);
|
||||
}
|
||||
}
|
||||
|
||||
public void startElementNamespace(String uri) throws SAXException {
|
||||
if (uri == null) {
|
||||
return;
|
||||
}
|
||||
if (SAX3XMLConstants.NULL_NS_URI.equals(uri)) {
|
||||
return;
|
||||
}
|
||||
if (printedMappings.contains(uri)) {
|
||||
return;
|
||||
}
|
||||
String prefix = prefixMapping.get(uri);
|
||||
if (prefix == null) {
|
||||
throw new SAXException("preFixUri: " + uri + " is not started.");
|
||||
}
|
||||
printedMappings.add(uri);
|
||||
|
||||
startElement.append(' ');
|
||||
startElement.append(SAX3XMLConstants.XMLNS_ATTRIBUTE);
|
||||
if ("".equals(prefix) == false) {
|
||||
startElement.append(SAX3XMLConstants.XMLNS_ASSIGN);
|
||||
startElement.append(prefix);
|
||||
}
|
||||
startElement.append("=\"");
|
||||
startElement.append(uri);
|
||||
startElement.append('"');
|
||||
}
|
||||
|
||||
public void startElementNamespaceAll() throws SAXException {
|
||||
if (!propertyConfig.getPropertyBoolean(ROOT_START_NAMESPACE_ALL)) {
|
||||
return;
|
||||
}
|
||||
String prefix = null;
|
||||
boolean first = true;
|
||||
for (String uri2 : prefixMapping.keySet()) {
|
||||
if (printedMappings.contains(uri2)) {
|
||||
continue;
|
||||
}
|
||||
prefix = prefixMapping.get(uri2);
|
||||
if (prefix == null) {
|
||||
throw new SAXException("preFixUri: " + uri2 + " is not started.");
|
||||
}
|
||||
printedMappings.add(uri2);
|
||||
if (SAX3XMLConstants.NULL_NS_URI.equals(uri2)) {
|
||||
continue; // don't print empty namespace uri location
|
||||
}
|
||||
if (first) {
|
||||
startElement.append(getPropertyConfig().getPropertyString(OUTPUT_CHAR_NEWLINE));
|
||||
first = false;
|
||||
}
|
||||
startElement.append(' ');
|
||||
startElement.append(SAX3XMLConstants.XMLNS_ATTRIBUTE);
|
||||
if ("".equals(prefix) == false) {
|
||||
startElement.append(SAX3XMLConstants.XMLNS_ASSIGN);
|
||||
startElement.append(prefix);
|
||||
}
|
||||
startElement.append("=\"");
|
||||
startElement.append(uri2);
|
||||
startElement.append('"');
|
||||
startElement.append(getPropertyConfig().getPropertyString(OUTPUT_CHAR_NEWLINE));
|
||||
}
|
||||
}
|
||||
|
||||
private void printElementAttributeNewLineSpace() {
|
||||
startElement.append(SAX3XMLConstants.CHAR_NEWLINE);
|
||||
for (int ii = 0; ii < indent+1; ii++) {
|
||||
startElement.append(getPropertyConfig().getPropertyString(OUTPUT_CHAR_TAB));
|
||||
}
|
||||
}
|
||||
|
||||
private void startElementAttributes(Attributes atts) throws SAXException {
|
||||
int prevChars = 0;
|
||||
for (int i = 0; i < atts.getLength(); i++) {
|
||||
String attributeUri = atts.getURI(i);
|
||||
String attributeName = atts.getLocalName(i);
|
||||
String attributeValue = atts.getValue(i);
|
||||
if (attributeValue == null) {
|
||||
attributeValue = propertyConfig.getPropertyString(OUTPUT_CHAR_NULL);
|
||||
}
|
||||
String attributeValueSafe = SAX3XMLConstants.escapeAttributeValue(attributeValue);
|
||||
|
||||
if (propertyConfig.getPropertyBoolean(OUTPUT_LINE_PER_ATTRIBUTE)) {
|
||||
if (i == 0) {
|
||||
printElementAttributeNewLineSpace();
|
||||
}
|
||||
} else {
|
||||
startElement.append(' ');
|
||||
}
|
||||
if (SAX3XMLConstants.NULL_NS_URI.equals(attributeUri) || attributeUri == null) {
|
||||
startElement.append(attributeName);
|
||||
} else {
|
||||
startElement.append(attributeUri);
|
||||
startElement.append(SAX3XMLConstants.XMLNS_ASSIGN);
|
||||
startElement.append(attributeName);
|
||||
}
|
||||
startElement.append("=\"");
|
||||
startElement.append(attributeValueSafe);
|
||||
startElement.append('"');
|
||||
|
||||
if (propertyConfig.getPropertyBoolean(OUTPUT_LINE_PER_ATTRIBUTE)) {
|
||||
printElementAttributeNewLineSpace();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri The xml namespace uri.
|
||||
* @param localName The local name of the xml tag.
|
||||
* @param name The (full) name of the xml tag.
|
||||
* @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void endElement(String uri, String localName, String name) throws SAXException {
|
||||
if (elements.size() > 0 && elements.peek().equals((localName)) == false) {
|
||||
throw new SAXException("Unexpected end tag: " + localName + " should be: " + elements.peek());
|
||||
}
|
||||
elements.pop();
|
||||
|
||||
if (startElement != null) {
|
||||
String tag = startElement.toString();
|
||||
write(tag.substring(0,tag.length() - 1));// rm normal close
|
||||
write(SAX3XMLConstants.TAG_CLOSE_EMPTY);
|
||||
startElement = null;
|
||||
indent--;
|
||||
return;
|
||||
}
|
||||
|
||||
indent--;
|
||||
if (printReturn || !localName.equals(lastElement)) {
|
||||
write(getPropertyConfig().getPropertyString(OUTPUT_CHAR_NEWLINE));
|
||||
writeIndent();
|
||||
} else {
|
||||
printReturn = true;
|
||||
}
|
||||
if (localName == null) {
|
||||
localName = "null";
|
||||
}
|
||||
|
||||
write(SAX3XMLConstants.TAG_OPEN_END);
|
||||
if (SAX3XMLConstants.NULL_NS_URI.equals(uri) || uri == null) {
|
||||
write(localName);
|
||||
} else {
|
||||
String prefix = prefixMapping.get(uri);
|
||||
if (prefix == null) {
|
||||
throw new SAXException("preFixUri: " + uri + " is not started.");
|
||||
}
|
||||
if (SAX3XMLConstants.NULL_NS_URI.equals(prefix) == false) {
|
||||
write(prefix);
|
||||
write(SAX3XMLConstants.XMLNS_ASSIGN);
|
||||
}
|
||||
write(localName);
|
||||
}
|
||||
write(SAX3XMLConstants.TAG_CLOSE);
|
||||
if (elements.isEmpty() && propertyConfig.getPropertyBoolean(ROOT_END_APPEND_NEWLINE)) {
|
||||
ignorableWhitespace(SAX3XMLConstants.CHAR_NEWLINE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the prefix mapping of an xml namespace uri.
|
||||
* @param prefix The xml prefix of this xml namespace uri.
|
||||
* @param uri The xml namespace uri to add the prefix for.
|
||||
* @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void startPrefixMapping(String prefix, String uri) throws SAXException {
|
||||
prefixMapping.put(uri, prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param prefix The xml prefix of this xml namespace uri to be ended.
|
||||
* @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
|
||||
*/
|
||||
public void endPrefixMapping(String prefix) throws SAXException {
|
||||
Set<Map.Entry<String,String>> s = prefixMapping.entrySet();
|
||||
String uri = null;
|
||||
for (Map.Entry<String,String> e:s) {
|
||||
if (e.getValue() == null) {
|
||||
continue; // way ?
|
||||
}
|
||||
if (e.getValue().equals(prefix)) {
|
||||
uri = e.getKey();
|
||||
}
|
||||
}
|
||||
if (uri != null) {
|
||||
printedMappings.remove(uri);
|
||||
prefixMapping.remove(uri);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml characters and uses characters(java.lang.String) method.
|
||||
*
|
||||
* @param ch Character buffer.
|
||||
* @param start The start index of the chars in the ch buffer.
|
||||
* @param length The length index of the chars in the ch buffer.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
* @see org.xml.sax.ContentHandler#characters(char[], int, int)
|
||||
*/
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
characters(new String(ch, start, length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape and prints xml characters.
|
||||
* @param text The text to write.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
* @see org.x4o.sax3.io.ContentWriter#characters(java.lang.String)
|
||||
*/
|
||||
public void characters(String text) throws SAXException {
|
||||
if (text == null) {
|
||||
return;
|
||||
}
|
||||
charactersRaw(SAX3XMLConstants.escapeCharacters(text));
|
||||
}
|
||||
|
||||
public void characters(char c) throws SAXException {
|
||||
characters(new char[]{c}, 0, 1);
|
||||
}
|
||||
|
||||
// move or remove ?
|
||||
protected void charactersRaw(String text) throws SAXException {
|
||||
if (text == null) {
|
||||
return;
|
||||
}
|
||||
autoCloseStartElement();
|
||||
checkPrintedReturn(text);
|
||||
write(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml ignorable whitespace.
|
||||
*
|
||||
* @param ch Character buffer.
|
||||
* @param start The start index of the chars in the ch buffer.
|
||||
* @param length The length index of the chars in the ch buffer.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
|
||||
*/
|
||||
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
||||
ignorableWhitespace(new String(ch, start, length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml ignorable whitespace.
|
||||
*
|
||||
* @param text The text to print.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
* @see org.x4o.sax3.io.ContentWriter#ignorableWhitespace(java.lang.String)
|
||||
*/
|
||||
public void ignorableWhitespace(String text) throws SAXException {
|
||||
if (text == null) {
|
||||
return;
|
||||
}
|
||||
autoCloseStartElement();
|
||||
write(text); // TODO: check chars
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml ignorable whitespace character.
|
||||
*
|
||||
* @param c The character to print.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
*/
|
||||
public void ignorableWhitespace(char c) throws SAXException {
|
||||
ignorableWhitespace(new char[]{c}, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml instructions.
|
||||
*
|
||||
* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
|
||||
* @param target The target.
|
||||
* @param data The data.
|
||||
*/
|
||||
public void processingInstruction(String target, String data) throws SAXException {
|
||||
String targetLow = target.toLowerCase();
|
||||
if (targetLow.startsWith(SAX3XMLConstants.XML)) {
|
||||
throw new SAXException("Processing instruction may not start with xml.");
|
||||
}
|
||||
if (SAX3XMLConstants.isNameString(target) == false) {
|
||||
throw new SAXException("Processing instruction target is invalid name; '" + target + "'");
|
||||
}
|
||||
if (SAX3XMLConstants.isCharString(data) == false) {
|
||||
throw new SAXException("Processing instruction data is invalid char; '" + data + "'");
|
||||
}
|
||||
autoCloseStartElement();
|
||||
write(getPropertyConfig().getPropertyString(OUTPUT_CHAR_NEWLINE));
|
||||
writeIndent();
|
||||
write(SAX3XMLConstants.PROCESS_START);
|
||||
write(target);
|
||||
write(' ');
|
||||
write(data);
|
||||
write(SAX3XMLConstants.PROCESS_END);
|
||||
writeFlush();
|
||||
printReturn = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented.
|
||||
*
|
||||
* @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
|
||||
* @param locator The DocumentLocator to set.
|
||||
*/
|
||||
public void setDocumentLocator(Locator locator) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented.
|
||||
*
|
||||
* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
|
||||
* @param name The name of the skipped entity.
|
||||
*/
|
||||
public void skippedEntity(String name) throws SAXException {
|
||||
// is for validating parser support, so not needed in xml writing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml comment.
|
||||
*
|
||||
* @param ch Character buffer.
|
||||
* @param start The start index of the chars in the ch buffer.
|
||||
* @param length The length index of the chars in the ch buffer.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
* @see org.xml.sax.ext.DefaultHandler2#comment(char[], int, int)
|
||||
*/
|
||||
public void comment(char[] ch, int start, int length) throws SAXException {
|
||||
comment(new String(ch, start, length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml comment.
|
||||
*
|
||||
* @param text The text to write.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
* @see org.x4o.sax3.io.ContentWriter#comment(java.lang.String)
|
||||
*/
|
||||
public void comment(String text) throws SAXException {
|
||||
if (text == null) {
|
||||
return;
|
||||
}
|
||||
if (!propertyConfig.getPropertyBoolean(OUTPUT_COMMENT_ENABLE)) {
|
||||
return;
|
||||
}
|
||||
if (propertyConfig.getPropertyBoolean(OUTPUT_COMMENT_AUTO_SPACE)) {
|
||||
char textStart = text.charAt(0);
|
||||
char textEnd = text.charAt(text.length() - 1);
|
||||
if (textStart != ' ' && textStart != '\t' && textStart != '\n') {
|
||||
text = " " + text;
|
||||
}
|
||||
if (textEnd != ' ' && textEnd != '\t' && textEnd != '\n') {
|
||||
text = text + " ";
|
||||
}
|
||||
}
|
||||
autoCloseStartElement();
|
||||
checkPrintedReturn(text);
|
||||
write(getPropertyConfig().getPropertyString(OUTPUT_CHAR_NEWLINE));
|
||||
writeIndent();
|
||||
write(SAX3XMLConstants.COMMENT_START);
|
||||
write(SAX3XMLConstants.escapeCharactersComment(text,getPropertyConfig().getPropertyString(OUTPUT_CHAR_TAB), indent));
|
||||
write(SAX3XMLConstants.COMMENT_END);
|
||||
printReturn = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the value contains any new lines and sets the printReturn field.
|
||||
*
|
||||
* @param value The value to check.
|
||||
*/
|
||||
private void checkPrintedReturn(String value) {
|
||||
if (value.indexOf(SAX3XMLConstants.CHAR_NEWLINE) > 0) {
|
||||
printReturn = true;
|
||||
} else {
|
||||
printReturn = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto close the start element if working in printing event.
|
||||
* @throws SAXException When prints gives exception.
|
||||
*/
|
||||
protected void autoCloseStartElement() throws SAXException {
|
||||
if (startElement == null) {
|
||||
return;
|
||||
}
|
||||
write(startElement.toString());
|
||||
startElement = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indent the output writer with tabs by indent count.
|
||||
* @throws SAXException When prints gives exception.
|
||||
*/
|
||||
private void writeIndent() throws SAXException {
|
||||
for (int i = 0; i < indent; i++) {
|
||||
write(getPropertyConfig().getPropertyString(OUTPUT_CHAR_TAB));
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeFlush() throws SAXException {
|
||||
try {
|
||||
out.flush();
|
||||
} catch (IOException e) {
|
||||
throw new SAXException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void write(String text) throws SAXException {
|
||||
try {
|
||||
out.write(text);
|
||||
} catch (IOException e) {
|
||||
throw new SAXException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void write(char c) throws SAXException {
|
||||
try {
|
||||
out.write(c);
|
||||
} catch (IOException e) {
|
||||
throw new SAXException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.ext.LexicalHandler;
|
||||
|
||||
/**
|
||||
* ContentWriterXml writes SAX content handler events to XML.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 May 3, 2013
|
||||
*/
|
||||
public abstract class AbstractContentWriterLexical extends AbstractContentWriterHandler implements LexicalHandler {
|
||||
|
||||
protected boolean printCDATA = false;
|
||||
|
||||
/**
|
||||
* Creates XmlWriter which prints to the Writer interface.
|
||||
* @param out The writer to print the xml to.
|
||||
*/
|
||||
public AbstractContentWriterLexical(Writer out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ext.LexicalHandler#startCDATA()
|
||||
*/
|
||||
public void startCDATA() throws SAXException {
|
||||
autoCloseStartElement();
|
||||
charactersRaw(SAX3XMLConstants.CDATA_START);
|
||||
printCDATA = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ext.LexicalHandler#endCDATA()
|
||||
*/
|
||||
public void endCDATA() throws SAXException {
|
||||
charactersRaw(SAX3XMLConstants.CDATA_END);
|
||||
printCDATA = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void startDTD(String name, String publicId, String systemId) throws SAXException {
|
||||
charactersRaw(SAX3XMLConstants.XML_DOCTYPE_TAG_OPEN);
|
||||
charactersRaw(" ");
|
||||
charactersRaw(name);
|
||||
if (publicId != null && !publicId.isEmpty()) {
|
||||
charactersRaw(" ");
|
||||
charactersRaw(publicId);
|
||||
}
|
||||
if (systemId != null && !systemId.isEmpty()) {
|
||||
charactersRaw(" \"");
|
||||
charactersRaw(systemId);
|
||||
charactersRaw("\"");
|
||||
}
|
||||
charactersRaw(SAX3XMLConstants.TAG_CLOSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ext.LexicalHandler#endDTD()
|
||||
*/
|
||||
public void endDTD() throws SAXException {
|
||||
writeFlush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String)
|
||||
*/
|
||||
public void startEntity(String arg0) throws SAXException {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)
|
||||
*/
|
||||
public void endEntity(String arg0) throws SAXException {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.x4o.sax3.io.AbstractContentWriterHandler#characters(char[], int, int)
|
||||
*/
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
characters(new String(ch, start, length));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.x4o.sax3.io.AbstractContentWriterHandler#characters(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void characters(String text) throws SAXException {
|
||||
if (printCDATA) {
|
||||
charactersRaw(SAX3XMLConstants.escapeCharactersCdata(text, "", ""));
|
||||
} else {
|
||||
super.characters(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
368
nx01-x4o-sax3/src/main/java/org/x4o/sax3/io/AttributeMap.java
Normal file
368
nx01-x4o-sax3/src/main/java/org/x4o/sax3/io/AttributeMap.java
Normal file
|
|
@ -0,0 +1,368 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Maps an SAX attributes set to an Map interface.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Apr 17, 2005
|
||||
* @param <K> The key class.
|
||||
* @param <V> The value class.
|
||||
*/
|
||||
public class AttributeMap<K,V> implements Map<K,V> {
|
||||
|
||||
/** stores the SAX attributes set */
|
||||
private Attributes attributes = null;
|
||||
|
||||
/** stores the namespace uri for this attributes */
|
||||
private String uri = null;
|
||||
|
||||
/**
|
||||
* Constuctes an new AttributeMap.
|
||||
*
|
||||
* @param attributes The data backend of this map.
|
||||
*/
|
||||
public AttributeMap(Attributes attributes) {
|
||||
setAttributes(attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructes an new AttributesMap.
|
||||
*
|
||||
* @param attributes The data backed of this map.
|
||||
* @param uri The namespace of these attributes.
|
||||
*/
|
||||
public AttributeMap(Attributes attributes, String uri) {
|
||||
setAttributes(attributes);
|
||||
setNameSpace(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data backend of this map.
|
||||
*
|
||||
* @param attributes The Attributes to be used as data backend.
|
||||
*/
|
||||
public void setAttributes(Attributes attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the data backend of this map.
|
||||
*
|
||||
* @return The data backend of attributes
|
||||
*/
|
||||
public Attributes getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the namespace uri, when set to null it is disabled(default).
|
||||
*
|
||||
* @param uri The namespace uri for when parsing when an certain namespace is required.
|
||||
*/
|
||||
public void setNameSpace(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the namespace used for these attributes.
|
||||
*
|
||||
* @return The namespace uri for the attributes.
|
||||
*/
|
||||
public String getNameSpace() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
// --------------- inner util functions.
|
||||
|
||||
/**
|
||||
* Gets the local of full name by index.
|
||||
*
|
||||
* @param index The index of the attribute.
|
||||
* @return The name of the attribute.
|
||||
*/
|
||||
private String getName(int index) {
|
||||
if (uri == null) {
|
||||
return attributes.getLocalName(index);
|
||||
}
|
||||
return attributes.getQName(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the attributes. uses the uri if not null.
|
||||
*
|
||||
* @param name The name of the attributes.
|
||||
* @return The value of the attribute.
|
||||
*/
|
||||
private String getValue(String name) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
if (uri != null) {
|
||||
return attributes.getValue(uri, name);
|
||||
}
|
||||
return attributes.getValue(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the attribute value.
|
||||
* @param key The name of the attribute.
|
||||
* @return The value of the attribute.
|
||||
*/
|
||||
private String getValue(Object key) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
return getValue(key.toString());
|
||||
}
|
||||
|
||||
// ------------------------------ MAP intreface
|
||||
|
||||
/**
|
||||
* Returns the size of the map.
|
||||
*
|
||||
* @return The size of the map.
|
||||
*/
|
||||
public int size() {
|
||||
return attributes.getLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there are attributes in this map.
|
||||
*
|
||||
* @return True if there are attributes entrys in this map.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
if (size() == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is an attributes with an certain key.
|
||||
*
|
||||
* @param key The name of an attribute.
|
||||
* @return True if the attributes excist.
|
||||
*/
|
||||
public boolean containsKey(Object key) {
|
||||
if (getValue(key) != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is an attributes with an value.
|
||||
*
|
||||
* @param value The value to check.
|
||||
* @return True if an attributes has this value.
|
||||
*/
|
||||
public boolean containsValue(Object value) {
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (attributes.getValue(i).equals(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns The value of an attribute.
|
||||
*
|
||||
* @param key The name of the attribute.
|
||||
* @return The value of the attribute.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public V get(Object key) {
|
||||
return (V)getValue(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function not implements. because we can't add to the attributes.
|
||||
*
|
||||
* @param key ignored.
|
||||
* @param value ignored.
|
||||
* @return always null
|
||||
*/
|
||||
public V put(K key, V value) {
|
||||
return null; // we can't add.
|
||||
}
|
||||
|
||||
/**
|
||||
* Function not implements. because we can't remove to the attributes.
|
||||
*
|
||||
* @param key ignored.
|
||||
* @return always null
|
||||
*/
|
||||
public V remove(Object key) {
|
||||
return null ;// we can't remove
|
||||
}
|
||||
|
||||
/**
|
||||
* Function not implements. because we can't add to the attributes.
|
||||
*
|
||||
* @param t ignored.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void putAll(Map t) {
|
||||
// we can't add.
|
||||
}
|
||||
|
||||
/**
|
||||
* Function not implements. because we can't clear the attributes.
|
||||
*/
|
||||
public void clear() {
|
||||
// we can't clear
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Set whith the names of the attributes.
|
||||
*
|
||||
* @return An set with attributes names.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<K> keySet() {
|
||||
HashSet<K> result = new HashSet<K>();
|
||||
for (int i = 0; i < size(); i++) {
|
||||
result.add((K)getName(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Collection of the values in the attributes list.
|
||||
*
|
||||
* @return An Collection of values.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<V> values() {
|
||||
ArrayList<V> result = new ArrayList<V>();
|
||||
for (int i = 0; i < size(); i++) {
|
||||
result.add((V)attributes.getValue(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Set made of Map.Entry. note: This Map.Entry is not refenced by
|
||||
* the attribute list. so changes to not reflect to this map object.
|
||||
*
|
||||
* @see java.util.Map#entrySet()
|
||||
* @return An entry set.
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public Set entrySet() {
|
||||
HashSet result = new HashSet();
|
||||
for (int i = 0; i < size(); i++) {
|
||||
Map.Entry mapEntry = new AttributeMapEntry(getName(i));
|
||||
mapEntry.setValue(attributes.getValue(i));
|
||||
result.add(mapEntry);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the SAX attribute list.
|
||||
*
|
||||
* @param o The Object to compare with.
|
||||
* @return True if the object are equal.
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
return attributes.equals(o); // compare to attributes
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the hashCode of the attribute list.
|
||||
*
|
||||
* @return An hashCode.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return attributes.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* An innerclass used by entrySet().
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
class AttributeMapEntry implements Map.Entry {
|
||||
|
||||
private Object key = null;
|
||||
private Object value = null;
|
||||
|
||||
/**
|
||||
* Creates AttributeMapEntry with key object.
|
||||
* @param key The key.
|
||||
*/
|
||||
protected AttributeMapEntry(Object key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the key.
|
||||
*/
|
||||
public Object getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this Map.Entry.
|
||||
* @param value The value to set.
|
||||
* @return The old value.
|
||||
*/
|
||||
public Object setValue(Object value) {
|
||||
Object result = this.value;
|
||||
this.value = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The value of this Map.Entry.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param o Check if o is equal.
|
||||
* @return True if key and value of Map.Entry are equal.
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Map.Entry) {
|
||||
Map.Entry mapEntry = (Map.Entry) o;
|
||||
if (mapEntry.getKey().equals(key) && mapEntry.getValue().equals(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* Functional closable callback for indenting api flow.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Jan 17, 2025
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ContentCloseable extends Closeable {
|
||||
|
||||
void closeContent() throws IOException;
|
||||
|
||||
@Override
|
||||
default void close() throws IOException {
|
||||
closeContent(); // wrap for stack trace users
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.ext.LexicalHandler;
|
||||
|
||||
|
||||
/**
|
||||
* ContentWriter is ContentHandler for writing sax events.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Apr 30, 2013
|
||||
*/
|
||||
public interface ContentWriter extends ContentHandler, LexicalHandler, Closeable {
|
||||
|
||||
/**
|
||||
* Starts and ends an element in one call.
|
||||
* @param uri The uri of the element.
|
||||
* @param localName The localName of the element.
|
||||
* @param name The name of the element.
|
||||
* @param atts The attributes of the element.
|
||||
* @throws SAXException When IOException is thrown.
|
||||
*/
|
||||
void startElementEnd(String uri, String localName, String name, Attributes atts) throws SAXException;
|
||||
|
||||
/**
|
||||
* Writes a String as xml comment.
|
||||
* @param text The text to have embedded as comment in xml.
|
||||
* @throws SAXException On error.
|
||||
*/
|
||||
void comment(String text) throws SAXException;
|
||||
|
||||
/**
|
||||
* Writes a whitespace String to the body.
|
||||
* @param text The String of whitespace to write.
|
||||
* @throws SAXException On error.
|
||||
*/
|
||||
void ignorableWhitespace(String text) throws SAXException;
|
||||
|
||||
/**
|
||||
* Writes a whitespace character to the body.
|
||||
* @param c The character to write.
|
||||
* @throws SAXException On error;
|
||||
*/
|
||||
void ignorableWhitespace(char c) throws SAXException;
|
||||
|
||||
/**
|
||||
* Writes a String in the body.
|
||||
* @param text The text to write.
|
||||
* @throws SAXException On error.
|
||||
*/
|
||||
void characters(String text) throws SAXException;
|
||||
|
||||
/**
|
||||
* Writes a single character in the body body.
|
||||
* @param c The character to write.
|
||||
* @throws SAXException On error.
|
||||
*/
|
||||
void characters(char c) throws SAXException;
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.Locator;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
|
||||
/**
|
||||
* ContentWriterAdapter is base ContentHandler for writing SAX3 events.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Dec 27, 2024
|
||||
*/
|
||||
abstract public class ContentWriterAdapter implements ContentWriter {
|
||||
|
||||
public void comment(char[] ch, int start, int length) throws SAXException {
|
||||
comment(new String(ch, start, length));
|
||||
}
|
||||
|
||||
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
||||
ignorableWhitespace(new String(ch, start, length));
|
||||
}
|
||||
|
||||
public void ignorableWhitespace(char c) throws SAXException {
|
||||
ignorableWhitespace(new char[]{c}, 0, 1);
|
||||
}
|
||||
|
||||
public void startElementEnd(String uri, String localName, String name, Attributes atts) throws SAXException {
|
||||
startElement(uri, localName, name, atts);
|
||||
endElement(uri, localName, name);
|
||||
}
|
||||
|
||||
public void characters(char c) throws SAXException {
|
||||
characters(new char[]{c}, 0, 1);
|
||||
}
|
||||
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
characters(new String(ch, start, length));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endCDATA() throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endDTD() throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endEntity(String arg0) throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startCDATA() throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startDTD(String arg0, String arg1, String arg2) throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startEntity(String arg0) throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endPrefixMapping(String arg0) throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processingInstruction(String arg0, String arg1) throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocumentLocator(Locator arg0) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skippedEntity(String arg0) throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPrefixMapping(String arg0, String arg1) throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void comment(String text) throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ignorableWhitespace(String text) throws SAXException {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* ContentConfig Defines checked config options.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 May 1, 2013
|
||||
*/
|
||||
public final class SAX3PropertyConfig implements Cloneable {
|
||||
|
||||
public final static String X4O_PROPERTIES_PREFIX = "http://x4o.org/properties/";
|
||||
private final Map<String,PropertyConfigItem> items;
|
||||
private final boolean readOnly;
|
||||
private final String keyPrefix;
|
||||
|
||||
public SAX3PropertyConfig(String keyPrefix, PropertyConfigItem... items) {
|
||||
this(false, null, keyPrefix, items);
|
||||
}
|
||||
|
||||
public SAX3PropertyConfig(SAX3PropertyConfig parentPropertyConfig, String keyPrefix, PropertyConfigItem... items) {
|
||||
this(false, parentPropertyConfig, keyPrefix, items);
|
||||
}
|
||||
|
||||
public SAX3PropertyConfig(boolean readOnly, SAX3PropertyConfig parentPropertyConfig, String keyPrefix, PropertyConfigItem... itemConfig) {
|
||||
if (keyPrefix == null) {
|
||||
throw new NullPointerException("Can't create PropertyConfig with null keyPrefix.");
|
||||
}
|
||||
this.readOnly = readOnly;
|
||||
this.keyPrefix = appendSlashIfMissing(keyPrefix);
|
||||
Map<String,PropertyConfigItem> fillItems = new HashMap<String,PropertyConfigItem>(itemConfig.length);
|
||||
fillPropertyConfigItems(fillItems, itemConfig);
|
||||
copyParentPropertyConfig(fillItems, parentPropertyConfig);
|
||||
if (fillItems.isEmpty()) {
|
||||
throw new IllegalArgumentException("Can't create PropertyConfig with zero PropertyConfigItems.");
|
||||
}
|
||||
for (String key : fillItems.keySet()) {
|
||||
if (!key.startsWith(X4O_PROPERTIES_PREFIX)) {
|
||||
throw new IllegalArgumentException("Illegal key missing prefix; " + key);
|
||||
}
|
||||
fillItems.put(key, fillItems.get(key).clone());
|
||||
}
|
||||
items = Collections.unmodifiableMap(fillItems);
|
||||
}
|
||||
|
||||
private final String appendSlashIfMissing(String keyPrefix) {
|
||||
if (keyPrefix.endsWith("/") == false) {
|
||||
keyPrefix += "/";
|
||||
}
|
||||
return keyPrefix;
|
||||
}
|
||||
|
||||
private final void fillPropertyConfigItems(Map<String,PropertyConfigItem> fillItems, PropertyConfigItem... itemConfig) {
|
||||
for (int i = 0; i < itemConfig.length; i++) {
|
||||
PropertyConfigItem item = itemConfig[i];
|
||||
fillItems.put(item.getValueKey(),item);
|
||||
}
|
||||
}
|
||||
|
||||
private final void copyParentPropertyConfig(Map<String,PropertyConfigItem> fillItems, SAX3PropertyConfig parentPropertyConfig) {
|
||||
if (parentPropertyConfig == null) {
|
||||
return;
|
||||
}
|
||||
for (String key : parentPropertyConfig.getPropertyKeys()) {
|
||||
fillItems.put(key, parentPropertyConfig.getPropertyConfigItem(key));
|
||||
}
|
||||
}
|
||||
|
||||
public static final class PropertyConfigItem implements Cloneable {
|
||||
private final boolean valueRequired;
|
||||
private final String valueKey;
|
||||
private final Class<?> valueType;
|
||||
private final Object valueDefault;
|
||||
private Object value = null;
|
||||
|
||||
public PropertyConfigItem(boolean valueRequired, String valueKey, Class<?> valueType) {
|
||||
this(valueRequired, valueKey, valueType, null);
|
||||
}
|
||||
|
||||
public PropertyConfigItem(String valueKey, Class<?> valueType) {
|
||||
this(false, valueKey, valueType, null);
|
||||
}
|
||||
|
||||
public PropertyConfigItem(String valueKey, Class<?> valueType, Object valueDefault) {
|
||||
this(false, valueKey, valueType, valueDefault); // with default then value can not be required.
|
||||
}
|
||||
|
||||
private PropertyConfigItem(boolean valueRequired, String valueKey, Class<?> valueType, Object valueDefault) {
|
||||
if (valueKey == null) {
|
||||
throw new NullPointerException("Can't create PropertyConfigItem with null valueKey.");
|
||||
}
|
||||
if (valueType == null) {
|
||||
throw new NullPointerException("Can't create PropertyConfigItem with null valueType.");
|
||||
}
|
||||
this.valueRequired = valueRequired;
|
||||
this.valueKey = valueKey;
|
||||
this.valueType = valueType;
|
||||
this.valueDefault = valueDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value key.
|
||||
*/
|
||||
public String getValueKey() {
|
||||
return valueKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the valueType.
|
||||
*/
|
||||
public Class<?> getValueType() {
|
||||
return valueType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value default.
|
||||
*/
|
||||
public Object getValueDefault() {
|
||||
return valueDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the valueRequired.
|
||||
*/
|
||||
public boolean isValueRequired() {
|
||||
return valueRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value the value to set.
|
||||
*/
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones all the fields into the new PropertyConfigItem.
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
@Override
|
||||
protected PropertyConfigItem clone() {
|
||||
PropertyConfigItem clone = new PropertyConfigItem(valueRequired, valueKey, valueType, valueDefault);
|
||||
clone.setValue(getValue());
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
private final PropertyConfigItem getPropertyConfigItem(String key) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("Can't search with null key.");
|
||||
}
|
||||
PropertyConfigItem item = items.get(key);
|
||||
if (item == null) {
|
||||
throw new IllegalArgumentException("No config item found for key: " + key);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public final String getKeyPrefix() {
|
||||
return keyPrefix;
|
||||
}
|
||||
|
||||
public final boolean isPropertyRequired(String key) {
|
||||
return getPropertyKeysRequired().contains(key);
|
||||
}
|
||||
|
||||
public final List<String> getPropertyKeysRequired() {
|
||||
return findPropertyKeysRequired(false);
|
||||
}
|
||||
|
||||
public final List<String> getPropertyKeysRequiredValues() {
|
||||
return findPropertyKeysRequired(true);
|
||||
}
|
||||
|
||||
private final List<String> findPropertyKeysRequired(boolean checkValue) {
|
||||
List<String> result = new ArrayList<String>(10);
|
||||
for (String key : getPropertyKeys()) {
|
||||
PropertyConfigItem item = getPropertyConfigItem(key);
|
||||
if (!item.isValueRequired()) {
|
||||
continue;
|
||||
}
|
||||
if (!checkValue) {
|
||||
result.add(item.getValueKey());
|
||||
} else if (item.getValue() == null && item.getValueDefault() == null) {
|
||||
result.add(item.getValueKey());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public final List<String> getPropertyKeys() {
|
||||
List<String> result = new ArrayList<String>(items.keySet());
|
||||
Collections.sort(result);
|
||||
return Collections.unmodifiableList(result);
|
||||
}
|
||||
|
||||
public final void setProperty(String key,Object value) {
|
||||
if (readOnly) {
|
||||
throw new IllegalStateException("This property is readonly for key:" + key);
|
||||
}
|
||||
PropertyConfigItem item = getPropertyConfigItem(key);
|
||||
item.setValue(value);
|
||||
}
|
||||
|
||||
public final Object getPropertyDefault(String key) {
|
||||
PropertyConfigItem item = getPropertyConfigItem(key);
|
||||
return item.getValueDefault();
|
||||
}
|
||||
|
||||
public final Object getProperty(String key) {
|
||||
PropertyConfigItem item = getPropertyConfigItem(key);
|
||||
Object value = item.getValue();
|
||||
if (value == null) {
|
||||
value = item.getValueDefault();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public final Class<?> getPropertyType(String key) {
|
||||
PropertyConfigItem item = getPropertyConfigItem(key);
|
||||
return item.getValueType();
|
||||
}
|
||||
|
||||
public final Class<?> getPropertyType(String key, Supplier<Class<?>> defaultValue) {
|
||||
Class<?> result = getPropertyType(key);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
return defaultValue.get();
|
||||
}
|
||||
|
||||
public final File getPropertyFile(String key) {
|
||||
Object value = getProperty(key);
|
||||
if (value instanceof File) {
|
||||
return (File)value;
|
||||
}
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
throw new IllegalStateException("Wrong value type: " + value.getClass() + " for key: " + key);
|
||||
}
|
||||
|
||||
public final File getPropertyFile(String key, Supplier<File> defaultValue) {
|
||||
File result = getPropertyFile(key);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
return defaultValue.get();
|
||||
}
|
||||
|
||||
public final Boolean getPropertyBoolean(String key) {
|
||||
Object value = getProperty(key);
|
||||
if (value instanceof Boolean) {
|
||||
return (Boolean)value;
|
||||
}
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
throw new IllegalStateException("Wrong value type: " + value.getClass() + " for key: " + key);
|
||||
}
|
||||
|
||||
public final Boolean getPropertyBoolean(String key, Supplier<Boolean> defaultValue) {
|
||||
Boolean result = getPropertyBoolean(key);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
return defaultValue.get();
|
||||
}
|
||||
|
||||
public final Integer getPropertyInteger(String key) {
|
||||
Object value = getProperty(key);
|
||||
if (value instanceof Integer) {
|
||||
return (Integer)value;
|
||||
}
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
throw new IllegalStateException("Wrong value type: " + value.getClass() + " for key: " + key);
|
||||
}
|
||||
|
||||
public final Integer getPropertyInteger(String key, Supplier<Integer> defaultValue) {
|
||||
Integer result = getPropertyInteger(key);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
return defaultValue.get();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final List<String> getPropertyList(String key) {
|
||||
Object value = getProperty(key);
|
||||
if (value instanceof List) {
|
||||
return (List<String>)value;
|
||||
}
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
throw new IllegalStateException("Wrong value type: " + value.getClass() + " for key: " + key);
|
||||
}
|
||||
|
||||
public final List<String> getPropertyList(String key, Supplier<List<String>> defaultValue) {
|
||||
List<String> result = getPropertyList(key);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
return defaultValue.get();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final Map<String,String> getPropertyMap(String key) {
|
||||
Object value = getProperty(key);
|
||||
if (value instanceof Map) {
|
||||
return (Map<String,String>)value;
|
||||
}
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
throw new IllegalStateException("Wrong value type: " + value.getClass() + " for key: " + key);
|
||||
}
|
||||
|
||||
public final Map<String,String> getPropertyMap(String key, Supplier<Map<String,String>> defaultValue) {
|
||||
Map<String,String> result = getPropertyMap(key);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
return defaultValue.get();
|
||||
}
|
||||
|
||||
public final String getPropertyString(String key) {
|
||||
Object value = getProperty(key);
|
||||
if (value instanceof String) {
|
||||
return (String)value;
|
||||
}
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
throw new IllegalStateException("Wrong value type: " + value.getClass() + " for key: " + key);
|
||||
}
|
||||
|
||||
public final String getPropertyString(String key,String defaultValue) {
|
||||
String propertyValue = getPropertyString(key);
|
||||
if (propertyValue == null) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
return propertyValue;
|
||||
}
|
||||
}
|
||||
|
||||
public final String getPropertyString(String key,Supplier<String> defaultValue) {
|
||||
String result = getPropertyString(key);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
return defaultValue.get();
|
||||
}
|
||||
|
||||
public final void copyParentProperties(SAX3PropertyConfig config) {
|
||||
for (String key : getPropertyKeys()) {
|
||||
Object value = config.getProperty(key);
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
setProperty(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final void setPropertyParsedValue(String key,String value) {
|
||||
Class<?> valueType = getPropertyType(key);
|
||||
if (String.class.equals(valueType)) {
|
||||
setProperty(key, value);
|
||||
return;
|
||||
}
|
||||
if (Boolean.class.equals(valueType)) {
|
||||
setProperty(key, Boolean.parseBoolean(value));
|
||||
return;
|
||||
}
|
||||
if (Integer.class.equals(valueType)) {
|
||||
setProperty(key, Integer.parseInt(value));
|
||||
return;
|
||||
}
|
||||
if (Double.class.equals(valueType)) {
|
||||
setProperty(key, Double.parseDouble(value));
|
||||
return;
|
||||
}
|
||||
if (Float.class.equals(valueType)) {
|
||||
setProperty(key, Float.parseFloat(value));
|
||||
return;
|
||||
}
|
||||
if (File.class.equals(valueType)) {
|
||||
setProperty(key, new File(value));
|
||||
return;
|
||||
}
|
||||
if (List.class.equals(valueType)) {
|
||||
String[] listValues = value.split(",");
|
||||
List<String> result = (List<String>)getProperty(key);
|
||||
if (result == null) {
|
||||
result = new ArrayList<String>(10);
|
||||
setProperty(key, result);
|
||||
}
|
||||
for (String listValue : listValues) {
|
||||
result.add(listValue);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (Map.class.equals(valueType)) {
|
||||
String[] listValues = value.split(",");
|
||||
Map<String,String> result = (Map<String,String>)getProperty(key);
|
||||
if (result == null) {
|
||||
result = new HashMap<String,String>(10);
|
||||
setProperty(key, result);
|
||||
}
|
||||
if (listValues.length != 2) {
|
||||
throw new IllegalArgumentException("Coult not parse map value: '" + value + "' parsed length: " + listValues.length + " needs to be 2.");
|
||||
}
|
||||
String mKey = listValues[0];
|
||||
String mValue = listValues[1];
|
||||
result.put(mKey, mValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones all the properties into the new PropertyConfig.
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
@Override
|
||||
public SAX3PropertyConfig clone() {
|
||||
SAX3PropertyConfig clone = new SAX3PropertyConfig(this, this.keyPrefix);
|
||||
clone.copyParentProperties(this);
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,416 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io;
|
||||
|
||||
import java.util.PrimitiveIterator;
|
||||
|
||||
/**
|
||||
* XMLConstants for writing XML.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Mrt 31, 2012
|
||||
*/
|
||||
public final class SAX3XMLConstants {
|
||||
|
||||
/**
|
||||
* Lowcase xml.
|
||||
*/
|
||||
public static final String XML = javax.xml.XMLConstants.XML_NS_PREFIX; // "xml"
|
||||
|
||||
/**
|
||||
* XML Default encoding is utf-8.
|
||||
*/
|
||||
public static final String XML_DEFAULT_ENCODING = "UTF-8";
|
||||
|
||||
/**
|
||||
* XML Default version is 1.0.
|
||||
*/
|
||||
public static final String XML_DEFAULT_VERSION = "1.0";
|
||||
|
||||
/**
|
||||
* XML Namespace prefix attribute.
|
||||
*/
|
||||
public static final String XMLNS_ATTRIBUTE = javax.xml.XMLConstants.XMLNS_ATTRIBUTE; // "xmlns"
|
||||
|
||||
/**
|
||||
* XML Namespace prefix seperator
|
||||
*/
|
||||
public static final String XMLNS_ASSIGN = ":";
|
||||
|
||||
/**
|
||||
* XML Schema namespace URI.
|
||||
*/
|
||||
public static final String XML_SCHEMA_NS_URI = javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; // "http://www.w3.org/2001/XMLSchema"
|
||||
|
||||
/**
|
||||
* XML Schema instance namespace URI.
|
||||
*/
|
||||
public static final String XML_SCHEMA_INSTANCE_NS_URI = javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI; // "http://www.w3.org/2001/XMLSchema-instance"
|
||||
|
||||
/**
|
||||
* Null or empty namespace uri.
|
||||
* @see <a href="http://www.w3.org/TR/REC-xml-names/#defaulting">Namespaces in XML, 5.2 Namespace Defaulting</a>
|
||||
*/
|
||||
public static final String NULL_NS_URI = javax.xml.XMLConstants.NULL_NS_URI; // ""
|
||||
|
||||
/**
|
||||
* Definition of DTD doctype opening tag.
|
||||
*/
|
||||
public static final String XML_DOCTYPE_TAG_OPEN = "<!DOCTYPE";
|
||||
|
||||
/**
|
||||
* Opens xml element tag.
|
||||
*/
|
||||
public static final String TAG_OPEN = "<";
|
||||
|
||||
/**
|
||||
* Opens end xml element tag.
|
||||
*/
|
||||
public static final String TAG_OPEN_END = "</";
|
||||
|
||||
/**
|
||||
* Closes xml element tag.
|
||||
*/
|
||||
public static final String TAG_CLOSE = ">";
|
||||
|
||||
/**
|
||||
* Close empty xml element tag.
|
||||
*/
|
||||
public static final String TAG_CLOSE_EMPTY = "/>";
|
||||
|
||||
/**
|
||||
* Starts a comment.
|
||||
*/
|
||||
public static final String COMMENT_START = "<!--";
|
||||
|
||||
/**
|
||||
* Ends a comment.
|
||||
*/
|
||||
public static final String COMMENT_END = "-->";
|
||||
|
||||
/**
|
||||
* Starts a processing instruction.
|
||||
*/
|
||||
public static final String PROCESS_START = "<?";
|
||||
|
||||
/**
|
||||
* Ends a processing instruction.
|
||||
*/
|
||||
public static final String PROCESS_END = "?>";
|
||||
|
||||
/**
|
||||
* Starts a cdata section.
|
||||
*/
|
||||
public static final String CDATA_START = "<![CDATA[";
|
||||
|
||||
/**
|
||||
* Ends a cdata section.
|
||||
*/
|
||||
public static final String CDATA_END = "]]>";
|
||||
|
||||
/**
|
||||
* The regex expression of a cdata start section.
|
||||
*/
|
||||
public static final String CDATA_START_REGEX = "<!\\x"+Integer.toHexString('[')+"CDATA\\x"+Integer.toHexString('[');
|
||||
|
||||
/**
|
||||
* The regex expression of a cdata end section.
|
||||
*/
|
||||
public static final String CDATA_END_REGEX = "\\x"+Integer.toHexString(']')+"\\x"+Integer.toHexString(']')+">";
|
||||
|
||||
/**
|
||||
* Tab char
|
||||
*/
|
||||
public static final char CHAR_TAB = '\t';
|
||||
|
||||
/**
|
||||
* Newline char
|
||||
*/
|
||||
public static final char CHAR_NEWLINE = '\n';
|
||||
|
||||
/// Unicode entity reference escape sequence starter
|
||||
public static final int CODE_POINT_ENTIY_REF_ESCAPE = '&';
|
||||
|
||||
/// Unicode entity reference by number
|
||||
public static final int CODE_POINT_ENTIY_REF_NUMBER = '#';
|
||||
|
||||
/// Unicode entity reference by hex number
|
||||
public static final int CODE_POINT_ENTIY_REF_NUMBER_HEX = 'x';
|
||||
|
||||
/// Unicode entity reference escape sequence terminator
|
||||
public static final int CODE_POINT_ENTIY_REF_TERMINATOR = ';';
|
||||
|
||||
static public String getDocumentDeclaration(String encoding) {
|
||||
return getDocumentDeclaration(encoding,null);
|
||||
}
|
||||
|
||||
static public String getDocumentDeclaration(String encoding, String version) {
|
||||
if (encoding == null) {
|
||||
encoding = XML_DEFAULT_ENCODING;
|
||||
}
|
||||
if (version == null) {
|
||||
version = XML_DEFAULT_VERSION;
|
||||
}
|
||||
return String.format("<?xml version=\"%s\" encoding=\"%s\"?>", version, encoding);
|
||||
}
|
||||
|
||||
static public boolean isChar(int c) {
|
||||
// Exclude "compatibility characters", as defined in section 2.3 of [Unicode]
|
||||
if (c>=0x7F & c<=0x84) { return false; }
|
||||
if (c>=0x86 & c<=0x9F) { return false; }
|
||||
if (c>=0xFDD0 & c<=0xFDEF) { return false; }
|
||||
if ((c>=0x1FFFE & c<=0x1FFFF)||(c>=0x2FFFE & c<=0x2FFFF)|(c>=0x3FFFE & c<=0x3FFFF)) { return false; }
|
||||
if ((c>=0x4FFFE & c<=0x4FFFF)||(c>=0x5FFFE & c<=0x5FFFF)|(c>=0x6FFFE & c<=0x6FFFF)) { return false; }
|
||||
if ((c>=0x7FFFE & c<=0x7FFFF)||(c>=0x8FFFE & c<=0x8FFFF)|(c>=0x9FFFE & c<=0x9FFFF)) { return false; }
|
||||
if ((c>=0xAFFFE & c<=0xAFFFF)||(c>=0xBFFFE & c<=0xBFFFF)|(c>=0xCFFFE & c<=0xCFFFF)) { return false; }
|
||||
if ((c>=0xDFFFE & c<=0xDFFFF)||(c>=0xEFFFE & c<=0xEFFFF)|(c>=0xFFFFE & c<=0xFFFFF)) { return false; }
|
||||
if (c>=0x10FFFE & c<=0x10FFFF) { return false; }
|
||||
|
||||
// Source;
|
||||
// #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
|
||||
if (c==0x9) { return true; }
|
||||
if (c==0xA) { return true; }
|
||||
if (c==0xD) { return true; }
|
||||
if (c>=0x20 & c<=0xD7FF) { return true; }
|
||||
if (c>=0xE000 & c<=0xFFFD) { return true; }
|
||||
if (c>=0x10000 & c<=0x10FFFF) { return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
static public boolean isNameStartChar(int c) {
|
||||
// Source;
|
||||
// ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
|
||||
if (c>='a' & c<='z') { return true; }
|
||||
if (c>='A' & c<='Z') { return true; }
|
||||
if (c==':' || c=='_') { return true; }
|
||||
if (c>=0xC0 & c<=0xD6) { return true; }
|
||||
if (c>=0xD8 & c<=0xF6) { return true; }
|
||||
if (c>=0xF8 & c<=0x2FF) { return true; }
|
||||
if (c>=0x370 & c<=0x37D) { return true; }
|
||||
if (c>=0x37F & c<=0x1FFF) { return true; }
|
||||
if (c>=0x200C & c<=0x200D) { return true; }
|
||||
if (c>=0x2070 & c<=0x218F) { return true; }
|
||||
if (c>=0x2C00 & c<=0x2FEF) { return true; }
|
||||
if (c>=0x3001 & c<=0xD7FF) { return true; }
|
||||
if (c>=0xF900 & c<=0xFDCF) { return true; }
|
||||
if (c>=0xFDF0 & c<=0xFFFD) { return true; }
|
||||
if (c>=0x10000 & c<=0xEFFFF) { return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
static public boolean isNameChar(int c) {
|
||||
// Source;
|
||||
// NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
|
||||
if (isNameStartChar(c)) {
|
||||
return true;
|
||||
}
|
||||
if (c=='-' || c=='.') { return true; }
|
||||
if (c>='0' & c<='9') { return true; }
|
||||
if (c==0xB7) { return true; }
|
||||
if (c>=0x0300 & c<=0x036F) { return true; }
|
||||
if (c>=0x203F & c<=0x2040) { return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
static public boolean isCharString(String value) {
|
||||
PrimitiveIterator.OfInt iterator = value.codePoints().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
int c = iterator.nextInt();
|
||||
if (isNameChar(c) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static public boolean isNameString(String value) {
|
||||
boolean first = true;
|
||||
PrimitiveIterator.OfInt iterator = value.codePoints().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
int c = iterator.nextInt();
|
||||
if (first) {
|
||||
first = false;
|
||||
if (isNameStartChar(c) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (isNameChar(c) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static private boolean escapeXMLValueAppend(int codePoint, StringBuilder result) {
|
||||
if (codePoint == '<') {
|
||||
result.append("<");
|
||||
return true;
|
||||
}
|
||||
if (codePoint == '>') {
|
||||
result.append(">");
|
||||
return true;
|
||||
}
|
||||
if (codePoint == '&') {
|
||||
result.append("&");
|
||||
return true;
|
||||
}
|
||||
if (codePoint == '\"') {
|
||||
result.append(""");
|
||||
return true;
|
||||
}
|
||||
if (codePoint == '\'') {
|
||||
result.append("'");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static public String escapeAttributeValue(String value) {
|
||||
// Reference ::= EntityRef | CharRef
|
||||
// AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
|
||||
StringBuilder result = new StringBuilder(value.length());
|
||||
PrimitiveIterator.OfInt iterator = value.codePoints().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
int c = iterator.nextInt();
|
||||
// 3.3.3 Attribute-Value Normalization.
|
||||
if (escapeXMLValueAppend(c,result)) {
|
||||
continue;
|
||||
}
|
||||
result.appendCodePoint(c);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
static public String escapeCharacters(String value) {
|
||||
StringBuilder result = new StringBuilder(value.length());
|
||||
PrimitiveIterator.OfInt iterator = value.codePoints().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
int c = iterator.nextInt();
|
||||
if (c == '&') {
|
||||
StringBuilder entity = new StringBuilder(16);
|
||||
entity.appendCodePoint(c);
|
||||
while (iterator.hasNext()) {
|
||||
int entityCodePoint = iterator.nextInt();
|
||||
entity.appendCodePoint(entityCodePoint);
|
||||
if (entityCodePoint == ';') {
|
||||
break;
|
||||
}
|
||||
if (entityCodePoint == ' ') { // TODO: impl DTD and check if add more or inverse only allow abc...
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (charEntityAllowed(entity.toString())) {
|
||||
result.append(entity);
|
||||
continue; // contine to next i char.
|
||||
} else {
|
||||
//i = iOrg; // continue normal escape.
|
||||
PrimitiveIterator.OfInt entityIterator = entity.codePoints().iterator();
|
||||
while (entityIterator.hasNext()) {
|
||||
int entityCodePoint = entityIterator.nextInt();
|
||||
if (escapeXMLValueAppend(entityCodePoint,result)) {
|
||||
continue;
|
||||
}
|
||||
result.appendCodePoint(entityCodePoint);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (escapeXMLValueAppend(c,result)) {
|
||||
continue;
|
||||
}
|
||||
result.appendCodePoint(c);
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
// TODO: make it loaded and xml and html version aware for correctness.
|
||||
static private boolean charEntityAllowed(String entity) {
|
||||
|
||||
// Hex code points
|
||||
if (entity.startsWith("&#")) {
|
||||
String hex = entity.substring(2,entity.length() - 1);
|
||||
if (hex.startsWith("x")) {
|
||||
hex = hex.substring(1);
|
||||
}
|
||||
int codePoint = Integer.parseInt(hex, 16);
|
||||
return codePoint > 0; // TODO: check if code point is valid.
|
||||
}
|
||||
|
||||
// XML
|
||||
if ("<".equals(entity)) { return true; }
|
||||
if (">".equals(entity)) { return true; }
|
||||
if ("&".equals(entity)) { return true; }
|
||||
if (""".equals(entity)) { return true; }
|
||||
if ("'".equals(entity)) { return true; }
|
||||
|
||||
// HTML
|
||||
if ("´".equals(entity)) { return true; }
|
||||
if ("ℵ".equals(entity)) { return true; }
|
||||
if ("≈".equals(entity)) { return true; }
|
||||
if ("∠".equals(entity)) { return true; }
|
||||
if ("∗".equals(entity)) { return true; }
|
||||
if ("♣".equals(entity)) { return true; }
|
||||
if ("♦".equals(entity)) { return true; }
|
||||
if ("♥".equals(entity)) { return true; }
|
||||
if ("♠".equals(entity)) { return true; }
|
||||
// TODO: etc/etc
|
||||
if ("ÿ".equals(entity)) { return true; }
|
||||
if ("ý".equals(entity)) { return true; }
|
||||
if ("ù".equals(entity)) { return true; }
|
||||
if ("ü".equals(entity)) { return true; }
|
||||
if ("û".equals(entity)) { return true; }
|
||||
if ("ú".equals(entity)) { return true; }
|
||||
|
||||
if ("÷".equals(entity)) { return true; }
|
||||
if (" ".equals(entity)) { return true; }
|
||||
if ("®".equals(entity)) { return true; }
|
||||
if ("™".equals(entity)) { return true; }
|
||||
if ("©".equals(entity)) { return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
static public String escapeCharactersCdata(String value,String replaceCdataStart,String replaceCdataEnd) {
|
||||
value = value.replaceAll(CDATA_START_REGEX, replaceCdataStart);
|
||||
value = value.replaceAll(CDATA_END_REGEX, replaceCdataEnd);
|
||||
return value;
|
||||
}
|
||||
|
||||
static public String escapeCharactersComment(String value,String charTab,int indent) {
|
||||
value = value.replaceAll(COMMENT_START, "");
|
||||
value = value.replaceAll(COMMENT_END, "");
|
||||
StringBuilder result = new StringBuilder(value.length());
|
||||
PrimitiveIterator.OfInt iterator = value.codePoints().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
int c = iterator.nextInt();
|
||||
if (c == '\n') {
|
||||
result.appendCodePoint(c);
|
||||
for (int ii = 0; ii < indent; ii++) {
|
||||
result.append(charTab);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
result.appendCodePoint(c);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The SAX 3-Extended classes and interfaces.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
package org.x4o.sax3.io;
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io.xdbx;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.x4o.sax3.io.ContentWriter;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Writes SAX events to binary XML.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Dec 20, 2024
|
||||
*/
|
||||
public abstract class AbstractXDBXWriter extends AbstractXDBXWriterLexical implements ContentWriter {
|
||||
|
||||
/**
|
||||
* Creates writer which prints to the stream interface.
|
||||
* @param out The stream to print the xml to.
|
||||
*/
|
||||
public AbstractXDBXWriter(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts and end then element.
|
||||
* @see org.x4o.sax3.io.ContentWriter#startElementEnd(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
|
||||
*/
|
||||
public void startElementEnd(String uri, String localName, String name, Attributes atts) throws SAXException {
|
||||
startElement(uri,localName,name, atts);
|
||||
endElement(uri, localName, name);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,696 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io.xdbx;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.x4o.sax3.io.SAX3PropertyConfig;
|
||||
import org.x4o.sax3.io.SAX3XMLConstants;
|
||||
import org.x4o.sax3.io.SAX3PropertyConfig.PropertyConfigItem;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.Locator;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Writes SAX content handler events as binary XML called XDBX.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Dec 19, 2024
|
||||
*/
|
||||
public class AbstractXDBXWriterHandler implements ContentHandler, Closeable {
|
||||
|
||||
private final SAX3PropertyConfig propertyConfig;
|
||||
private final OutputStream out;
|
||||
private Map<String,String> prefixMapping = null;
|
||||
private List<String> printedMappings = null;
|
||||
private Stack<String> elements = null;
|
||||
private Map<String,Integer> stringIdx = null;
|
||||
|
||||
private final static String PROPERTY_CONTEXT_PREFIX = SAX3PropertyConfig.X4O_PROPERTIES_PREFIX+"writer/xdbx/";
|
||||
public final static SAX3PropertyConfig DEFAULT_PROPERTY_CONFIG;
|
||||
public final static String OUTPUT_DECLARATION = PROPERTY_CONTEXT_PREFIX+"output/declaration";
|
||||
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_AUTO_SPACE = PROPERTY_CONTEXT_PREFIX+"output/comment-auto-space";
|
||||
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_ENCODING = PROPERTY_CONTEXT_PREFIX+"prolog/licence-encoding";
|
||||
public final static String PROLOG_LICENCE_ENABLE = PROPERTY_CONTEXT_PREFIX+"prolog/licence-enable";
|
||||
public final static String PROLOG_USER_COMMENT = PROPERTY_CONTEXT_PREFIX+"prolog/user-comment";
|
||||
public final static String PROLOG_USER_COMMENT_ENABLE = PROPERTY_CONTEXT_PREFIX+"prolog/user-comment-enable";
|
||||
public final static String ROOT_START_NAMESPACE_ALL = PROPERTY_CONTEXT_PREFIX+"root/start-namespace-all";
|
||||
|
||||
static {
|
||||
DEFAULT_PROPERTY_CONFIG = new SAX3PropertyConfig(true,null,PROPERTY_CONTEXT_PREFIX,
|
||||
new PropertyConfigItem(OUTPUT_DECLARATION, Boolean.class, true),
|
||||
new PropertyConfigItem(OUTPUT_CHAR_NULL, String.class, "NULL"),
|
||||
new PropertyConfigItem(OUTPUT_COMMENT_ENABLE, Boolean.class, true),
|
||||
new PropertyConfigItem(OUTPUT_COMMENT_AUTO_SPACE, Boolean.class, true),
|
||||
new PropertyConfigItem(PROLOG_LICENCE_ENCODING, String.class, SAX3XMLConstants.XML_DEFAULT_ENCODING),
|
||||
new PropertyConfigItem(PROLOG_LICENCE_FILE, File.class ),
|
||||
new PropertyConfigItem(PROLOG_LICENCE_RESOURCE, String.class ),
|
||||
new PropertyConfigItem(PROLOG_LICENCE_ENABLE, Boolean.class, true),
|
||||
new PropertyConfigItem(PROLOG_USER_COMMENT, String.class ),
|
||||
new PropertyConfigItem(PROLOG_USER_COMMENT_ENABLE, Boolean.class, true),
|
||||
new PropertyConfigItem(ROOT_START_NAMESPACE_ALL, Boolean.class, true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates writer which prints to the stream interface.
|
||||
* @param out The stream to print the xml to.
|
||||
*/
|
||||
public AbstractXDBXWriterHandler(OutputStream out) {
|
||||
this.out = Objects.requireNonNull(out, "Can't write on null OutputStream.");
|
||||
this.prefixMapping = new HashMap<String,String>(15);
|
||||
this.printedMappings = new ArrayList<String>(15);
|
||||
this.elements = new Stack<String>();
|
||||
this.propertyConfig = new SAX3PropertyConfig(DEFAULT_PROPERTY_CONFIG, PROPERTY_CONTEXT_PREFIX);
|
||||
this.stringIdx = new HashMap<>();
|
||||
}
|
||||
|
||||
public SAX3PropertyConfig getPropertyConfig() {
|
||||
return propertyConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
out.close();
|
||||
}
|
||||
|
||||
protected boolean xdbxStringId(String data) {
|
||||
Integer result = stringIdx.get(data);
|
||||
return result != null;
|
||||
}
|
||||
|
||||
protected int xdbxStringStore(String data) {
|
||||
Integer result = stringIdx.get(data);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
result = stringIdx.size() + 1;
|
||||
stringIdx.put(data, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ContentHandler#startDocument()
|
||||
*/
|
||||
public void startDocument() throws SAXException {
|
||||
write(XDBXConstants.HEADER_MARKER);
|
||||
write(XDBXConstants.HEADER_LENGHT);
|
||||
write(XDBXConstants.HEADER_VERSION);
|
||||
writeHeaderFlags(out, XDBXConstants.FLAG_STRING_ID + XDBXConstants.FLAG_STRING_ID_IDX);
|
||||
boolean printDeclaration = getPropertyConfig().getPropertyBoolean(OUTPUT_DECLARATION);
|
||||
if (printDeclaration) {
|
||||
writeTag(XDBXContentTag.XML_VERSION); /// tODO: move to declaration method..
|
||||
writeLengthValue("1.0");
|
||||
writeTag(XDBXContentTag.ENCODING);
|
||||
writeLengthValue("utf-8");
|
||||
//Standalone in TV(standalone) form where the value of 'standalone' is either 0 or 1.
|
||||
//write(XDBXContentTag.STANDALONE);
|
||||
//write(1);
|
||||
}
|
||||
prologWriteLicence();
|
||||
prologWriteUserComment();
|
||||
}
|
||||
|
||||
private void prologWriteLicence() throws SAXException {
|
||||
if (!propertyConfig.getPropertyBoolean(PROLOG_LICENCE_ENABLE)) {
|
||||
return;
|
||||
}
|
||||
InputStream licenceInput = null;
|
||||
String licenceEncoding = propertyConfig.getPropertyString(PROLOG_LICENCE_ENCODING);
|
||||
String licenceResource = propertyConfig.getPropertyString(PROLOG_LICENCE_RESOURCE);
|
||||
if (licenceResource != null) {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
if (cl == null) {
|
||||
cl = this.getClass().getClassLoader();
|
||||
}
|
||||
licenceInput = cl.getResourceAsStream(licenceResource);
|
||||
if (licenceInput == null) {
|
||||
throw new NullPointerException("Could not load licence resource from: "+licenceResource);
|
||||
}
|
||||
}
|
||||
if (licenceInput == null) {
|
||||
File licenceFile = propertyConfig.getPropertyFile(PROLOG_LICENCE_FILE);
|
||||
if (licenceFile == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
licenceInput = new FileInputStream(licenceFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new SAXException(e);
|
||||
}
|
||||
}
|
||||
String licenceText;
|
||||
try {
|
||||
licenceText = readLicenceStream(licenceInput, licenceEncoding);
|
||||
} catch (IOException e) {
|
||||
throw new SAXException(e);
|
||||
}
|
||||
comment(licenceText);
|
||||
}
|
||||
|
||||
private String readLicenceStream(InputStream inputStream, String encoding) throws IOException {
|
||||
if (encoding == null) {
|
||||
encoding = SAX3XMLConstants.XML_DEFAULT_ENCODING;
|
||||
}
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, Charset.forName(encoding)));
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('\n');
|
||||
sb.append('\n');
|
||||
String line = br.readLine();
|
||||
while (line != null) {
|
||||
if (line.length()>0) {
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(line);
|
||||
sb.append('\n');
|
||||
line = br.readLine();
|
||||
}
|
||||
sb.append('\n');
|
||||
String out = sb.toString();
|
||||
return out;
|
||||
} finally {
|
||||
br.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void prologWriteUserComment() throws SAXException {
|
||||
if (!propertyConfig.getPropertyBoolean(PROLOG_USER_COMMENT_ENABLE)) {
|
||||
return;
|
||||
}
|
||||
String userComment = propertyConfig.getPropertyString(PROLOG_USER_COMMENT);
|
||||
if (userComment == null) {
|
||||
return;
|
||||
}
|
||||
if (userComment.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String chEnter = "\n"; //getPropertyConfig().getPropertyString(OUTPUT_CHAR_NEWLINE);
|
||||
String chTab = "\t"; //getPropertyConfig().getPropertyString(OUTPUT_CHAR_TAB);
|
||||
userComment = userComment.replaceAll("\n", chEnter + chTab);
|
||||
comment(chEnter + chTab + userComment + chEnter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ContentHandler#endDocument()
|
||||
*/
|
||||
public void endDocument() throws SAXException {
|
||||
writeTag(XDBXContentTag.DOCUMENT_END);
|
||||
writeFlush();
|
||||
if (elements.size() > 0) {
|
||||
throw new SAXException("Invalid xml still have " + elements.size() + " elements open.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri The xml namespace uri.
|
||||
* @param localName The local name of the xml tag.
|
||||
* @param name The (full) name of the xml tag.
|
||||
* @param atts The attributes of the xml tag.
|
||||
* @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
|
||||
*/
|
||||
public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException {
|
||||
if (localName == null) {
|
||||
throw new SAXException("LocalName may not be null.");
|
||||
}
|
||||
if (SAX3XMLConstants.isNameString(localName) == false) {
|
||||
throw new SAXException("LocalName of element is not valid in xml; '" + localName + "'");
|
||||
}
|
||||
for (int i = 0; i < atts.getLength(); i++) {
|
||||
boolean isFirst = true;
|
||||
String attrLocalName = atts.getLocalName(i);
|
||||
if (attrLocalName.isEmpty()) {
|
||||
throw new SAXException("LocalAttributeName is missing characters");
|
||||
}
|
||||
PrimitiveIterator.OfInt iterator = attrLocalName.codePoints().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
int c = iterator.nextInt();
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
if (!SAX3XMLConstants.isNameStartChar(attrLocalName.codePoints().findFirst().getAsInt())) {
|
||||
throw new SAXException("LocalAttributeName has illegal start character: " + attrLocalName);
|
||||
}
|
||||
}
|
||||
if (!SAX3XMLConstants.isNameChar(c)) {
|
||||
throw new SAXException("LocalAttributeName has illegal name character: " + attrLocalName);
|
||||
}
|
||||
}
|
||||
}
|
||||
startElementTag(uri,localName,name);
|
||||
startElementNamespace(uri);
|
||||
startElementAttributes(atts);
|
||||
if (SAX3XMLConstants.NULL_NS_URI.equals(uri) || uri == null) {
|
||||
elements.push(localName);
|
||||
} else {
|
||||
elements.push(uri + ":" + name);
|
||||
}
|
||||
}
|
||||
|
||||
public void startElementTag(String uri, String localName, String name) throws SAXException {
|
||||
boolean localNameIdx = xdbxStringId(localName);
|
||||
if (SAX3XMLConstants.NULL_NS_URI.equals(uri) || uri==null) {
|
||||
if (localNameIdx) {
|
||||
writeTag(XDBXContentTag.ELEMENT_I);
|
||||
writeVariableInteger(xdbxStringStore(localName));
|
||||
} else {
|
||||
writeTag(XDBXContentTag.ELEMENT_SII);
|
||||
writeLengthValue(localName);
|
||||
writeVariableInteger(xdbxStringStore(localName));
|
||||
writeVariableInteger(0);
|
||||
writeVariableInteger(0);
|
||||
}
|
||||
} else {
|
||||
String prefix = prefixMapping.get(uri);
|
||||
if (prefix == null) {
|
||||
throw new SAXException("preFixUri: "+uri+" is not started.");
|
||||
}
|
||||
if (localNameIdx) {
|
||||
writeTag(XDBXContentTag.ELEMENT_III);
|
||||
} else {
|
||||
writeTag(XDBXContentTag.ELEMENT_SII);
|
||||
writeLengthValue(name);
|
||||
}
|
||||
writeVariableInteger(xdbxStringStore(name));
|
||||
writeVariableInteger(xdbxStringStore(prefix));
|
||||
writeVariableInteger(xdbxStringStore(uri));
|
||||
}
|
||||
}
|
||||
|
||||
public void startElementNamespace(String uri) throws SAXException {
|
||||
if ((uri != null && SAX3XMLConstants.NULL_NS_URI.equals(uri) == false) && printedMappings.contains(uri) == false) {
|
||||
String prefix = prefixMapping.get(uri);
|
||||
if (prefix == null) {
|
||||
throw new SAXException("preFixUri: "+uri+" is not started.");
|
||||
}
|
||||
printedMappings.add(uri);
|
||||
|
||||
writeTag(XDBXContentTag.NS_DECL_II);
|
||||
writeVariableInteger(xdbxStringStore(prefix));
|
||||
writeVariableInteger(xdbxStringStore(uri));
|
||||
}
|
||||
startElementNamespaceAll(uri);
|
||||
}
|
||||
|
||||
public void startElementNamespaceAll(String uri) throws SAXException {
|
||||
if (!propertyConfig.getPropertyBoolean(ROOT_START_NAMESPACE_ALL)) {
|
||||
return;
|
||||
}
|
||||
String prefix = null;
|
||||
for (String uri2 : prefixMapping.keySet()) {
|
||||
if (printedMappings.contains(uri2) == false) {
|
||||
prefix = prefixMapping.get(uri2);
|
||||
if (prefix == null) {
|
||||
throw new SAXException("preFixUri: "+uri+" is not started.");
|
||||
}
|
||||
printedMappings.add(uri2);
|
||||
|
||||
writeTag(XDBXContentTag.NS_DECL_II);
|
||||
writeVariableInteger(xdbxStringStore(prefix));
|
||||
writeVariableInteger(xdbxStringStore(uri2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startElementAttributes(Attributes atts) throws SAXException {
|
||||
for (int i = 0; i < atts.getLength(); i++) {
|
||||
String attributeUri = atts.getURI(i);
|
||||
String attributeName = atts.getLocalName(i);
|
||||
String attributeValue = atts.getValue(i);
|
||||
if (attributeValue == null) {
|
||||
attributeValue = propertyConfig.getPropertyString(OUTPUT_CHAR_NULL);
|
||||
}
|
||||
String attributeValueSafe = SAX3XMLConstants.escapeAttributeValue(attributeValue);
|
||||
boolean attributeValueSimple = attributeValue.equals(attributeValueSafe);
|
||||
boolean attributeNameIdx = xdbxStringId(attributeName);
|
||||
|
||||
if (SAX3XMLConstants.NULL_NS_URI.equals(attributeUri) || attributeUri ==null) {
|
||||
if (attributeNameIdx) {
|
||||
writeTag(XDBXContentTag.ATTRIBUTE_I);
|
||||
writeVariableInteger(xdbxStringStore(attributeName));
|
||||
} else {
|
||||
writeTag(XDBXContentTag.ATTRIBUTE_SII);
|
||||
writeLengthValue(attributeName);
|
||||
writeVariableInteger(xdbxStringStore(attributeName));
|
||||
writeVariableInteger(0);
|
||||
writeVariableInteger(0);
|
||||
}
|
||||
} else {
|
||||
String attributeUriPrefix = prefixMapping.get(attributeUri);
|
||||
if (attributeUriPrefix == null) {
|
||||
throw new SAXException("preFixUri: " + attributeUri + " is not started.");
|
||||
}
|
||||
if (attributeNameIdx) {
|
||||
if (attributeValueSimple) {
|
||||
writeTag(XDBXContentTag.ATTRIBUTE_III_FAST);
|
||||
} else {
|
||||
writeTag(XDBXContentTag.ATTRIBUTE_III);
|
||||
}
|
||||
} else {
|
||||
writeTag(XDBXContentTag.ATTRIBUTE_SII);
|
||||
writeLengthValue(attributeName);
|
||||
}
|
||||
writeVariableInteger(xdbxStringStore(attributeName));
|
||||
writeVariableInteger(xdbxStringStore(attributeUriPrefix));
|
||||
writeVariableInteger(xdbxStringStore(attributeUri));
|
||||
}
|
||||
writeLengthValue(attributeValueSafe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri The xml namespace uri.
|
||||
* @param localName The local name of the xml tag.
|
||||
* @param name The (full) name of the xml tag.
|
||||
* @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void endElement(String uri, String localName, String name) throws SAXException {
|
||||
if (SAX3XMLConstants.NULL_NS_URI.equals(uri) || uri==null) {
|
||||
if (elements.size() > 0 && elements.peek().equals(localName) == false) {
|
||||
throw new SAXException("Unexpected end tag: " + localName + " should be: " + elements.peek());
|
||||
}
|
||||
} else {
|
||||
String qName = uri + ":" + name;
|
||||
if (elements.size() > 0 && elements.peek().equals(qName) == false) {
|
||||
throw new SAXException("Unexpected end tag: " + qName + " should be: " + elements.peek());
|
||||
}
|
||||
}
|
||||
elements.pop();
|
||||
writeTag(XDBXContentTag.END_ELEMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the prefix mapping of an xml namespace uri.
|
||||
* @param prefix The xml prefix of this xml namespace uri.
|
||||
* @param uri The xml namespace uri to add the prefix for.
|
||||
* @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void startPrefixMapping(String prefix, String uri) throws SAXException {
|
||||
prefixMapping.put(uri, prefix);
|
||||
|
||||
boolean prefixIdx = xdbxStringId(prefix);
|
||||
if (!prefixIdx) {
|
||||
int prefixIdxNum = xdbxStringStore(prefix);
|
||||
writeTagLengthValue(XDBXContentTag.STRING_ID, prefix);
|
||||
writeVariableInteger(prefixIdxNum);
|
||||
}
|
||||
boolean uriIdx = xdbxStringId(uri);
|
||||
if (!uriIdx) {
|
||||
int uriIdxNum = xdbxStringStore(uri);
|
||||
writeTagLengthValue(XDBXContentTag.STRING_ID, uri);
|
||||
writeVariableInteger(uriIdxNum);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param prefix The xml prefix of this xml namespace uri to be ended.
|
||||
* @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
|
||||
*/
|
||||
public void endPrefixMapping(String prefix) throws SAXException {
|
||||
Set<Map.Entry<String,String>> s = prefixMapping.entrySet();
|
||||
String uri = null;
|
||||
for (Map.Entry<String,String> e : s) {
|
||||
if (e.getValue() == null) {
|
||||
continue; // way ?
|
||||
}
|
||||
if (e.getValue().equals(prefix)) {
|
||||
uri = e.getKey();
|
||||
}
|
||||
}
|
||||
if (uri != null) {
|
||||
prefixMapping.remove(uri);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml characters and uses characters(java.lang.String) method.
|
||||
*
|
||||
* @param ch Character buffer.
|
||||
* @param start The start index of the chars in the ch buffer.
|
||||
* @param length The length index of the chars in the ch buffer.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
* @see org.xml.sax.ContentHandler#characters(char[], int, int)
|
||||
*/
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
characters(new String(ch, start, length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape and prints xml characters.
|
||||
* @param text The text to write.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
* @see org.x4o.sax3.io.ContentWriter#characters(java.lang.String)
|
||||
*/
|
||||
public void characters(String text) throws SAXException {
|
||||
if (text == null) {
|
||||
return;
|
||||
}
|
||||
charactersRaw(SAX3XMLConstants.escapeCharacters(text));
|
||||
}
|
||||
|
||||
public void characters(char c) throws SAXException {
|
||||
characters(new char[]{c}, 0, 1);
|
||||
}
|
||||
|
||||
// move or remove ?
|
||||
protected void charactersRaw(String text) throws SAXException {
|
||||
if (text == null) {
|
||||
return;
|
||||
}
|
||||
writeTagLengthValue(XDBXContentTag.TEXT_T, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml ignorable whitespace.
|
||||
*
|
||||
* @param ch Character buffer.
|
||||
* @param start The start index of the chars in the ch buffer.
|
||||
* @param length The length index of the chars in the ch buffer.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
|
||||
*/
|
||||
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
||||
ignorableWhitespace(new String(ch, start, length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml ignorable whitespace.
|
||||
*
|
||||
* @param text The text to print.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
* @see org.x4o.sax3.io.ContentWriter#ignorableWhitespace(java.lang.String)
|
||||
*/
|
||||
public void ignorableWhitespace(String text) throws SAXException {
|
||||
if (text == null) {
|
||||
return;
|
||||
}
|
||||
writeTagLengthValue(XDBXContentTag.TEXT_WHITE_SPACE, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml ignorable whitespace character.
|
||||
*
|
||||
* @param c The character to print.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
*/
|
||||
public void ignorableWhitespace(char c) throws SAXException {
|
||||
ignorableWhitespace(new char[]{c}, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml instructions.
|
||||
*
|
||||
* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
|
||||
* @param target The target.
|
||||
* @param data The data.
|
||||
*/
|
||||
public void processingInstruction(String target, String data) throws SAXException {
|
||||
String targetLow = target.toLowerCase();
|
||||
if (targetLow.startsWith(SAX3XMLConstants.XML)) {
|
||||
throw new SAXException("Processing instruction may not start with xml.");
|
||||
}
|
||||
if (SAX3XMLConstants.isNameString(target) == false) {
|
||||
throw new SAXException("Processing instruction target is invalid name; '" + target + "'");
|
||||
}
|
||||
if (SAX3XMLConstants.isCharString(data) == false) {
|
||||
throw new SAXException("Processing instruction data is invalid char; '" + data + "'");
|
||||
}
|
||||
|
||||
//'I' LengthValue StringID
|
||||
int targetIdx = xdbxStringStore(target);
|
||||
writeTagLengthValue(XDBXContentTag.STRING_ID, target);
|
||||
writeVariableInteger(targetIdx);
|
||||
|
||||
//'P' StringID LengthValue
|
||||
writeTag(XDBXContentTag.PROCESSING_INSTRUCTION);
|
||||
writeVariableInteger(targetIdx);
|
||||
writeLengthValue(data);
|
||||
|
||||
writeFlush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented.
|
||||
*
|
||||
* @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
|
||||
* @param locator The DocumentLocator to set.
|
||||
*/
|
||||
public void setDocumentLocator(Locator locator) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented.
|
||||
*
|
||||
* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
|
||||
* @param name The name of the skipped entity.
|
||||
*/
|
||||
public void skippedEntity(String name) throws SAXException {
|
||||
// is for validating parser support, so not needed in xml writing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml comment.
|
||||
*
|
||||
* @param ch Character buffer.
|
||||
* @param start The start index of the chars in the ch buffer.
|
||||
* @param length The length index of the chars in the ch buffer.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
* @see org.xml.sax.ext.DefaultHandler2#comment(char[], int, int)
|
||||
*/
|
||||
public void comment(char[] ch, int start, int length) throws SAXException {
|
||||
comment(new String(ch, start, length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints xml comment.
|
||||
*
|
||||
* @param text The text to write.
|
||||
* @throws SAXException When IOException has happend while printing.
|
||||
* @see org.x4o.sax3.io.ContentWriter#comment(java.lang.String)
|
||||
*/
|
||||
public void comment(String text) throws SAXException {
|
||||
if (text == null) {
|
||||
return;
|
||||
}
|
||||
if (!propertyConfig.getPropertyBoolean(OUTPUT_COMMENT_ENABLE)) {
|
||||
return;
|
||||
}
|
||||
if (propertyConfig.getPropertyBoolean(OUTPUT_COMMENT_AUTO_SPACE)) {
|
||||
char textStart = text.charAt(0);
|
||||
char textEnd = text.charAt(text.length() - 1);
|
||||
if (textStart != ' ' && textStart != '\t' && textStart != '\n') {
|
||||
text = " "+text;
|
||||
}
|
||||
if (textEnd != ' ' && textEnd != '\t' && textEnd != '\n') {
|
||||
text = text + " ";
|
||||
}
|
||||
}
|
||||
writeTagLengthValue(XDBXContentTag.COMMENT, SAX3XMLConstants.escapeCharactersComment(text, "", 0));
|
||||
}
|
||||
|
||||
protected void writeFlush() throws SAXException {
|
||||
try {
|
||||
out.flush();
|
||||
} catch (IOException e) {
|
||||
throw new SAXException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void write(byte[] data) throws SAXException {
|
||||
try {
|
||||
out.write(data);
|
||||
} catch (IOException e) {
|
||||
throw new SAXException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void write(int c) throws SAXException {
|
||||
try {
|
||||
out.write(c);
|
||||
} catch (IOException e) {
|
||||
throw new SAXException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeHeaderFlags(OutputStream out, int flags) throws SAXException {
|
||||
write(flags >> 24);
|
||||
write(flags >> 16);
|
||||
write(flags >> 8);
|
||||
write(flags >> 0);
|
||||
}
|
||||
|
||||
protected void writeTag(XDBXContentTag tag) throws SAXException {
|
||||
write(tag.getTagNumber());
|
||||
}
|
||||
|
||||
protected void writeTagLengthValue(XDBXContentTag tag, String data) throws SAXException {
|
||||
writeTag(tag);
|
||||
writeLengthValue(data);
|
||||
}
|
||||
|
||||
protected void writeVariableInteger(int i) throws SAXException {
|
||||
if (i < 128) {
|
||||
write(i);
|
||||
return;
|
||||
}
|
||||
if (i < 16383) {
|
||||
write((i >> 7) & 0b1111111 + 128);
|
||||
write(i & 0b1111111);
|
||||
return;
|
||||
}
|
||||
write((i >> 14) & 0b1111111 + 128);
|
||||
write((i >> 7) & 0b1111111 + 128);
|
||||
write(i & 0b1111111);
|
||||
}
|
||||
|
||||
protected void writeLengthValue(byte[] data) throws SAXException {
|
||||
writeVariableInteger(data.length);
|
||||
write(data);
|
||||
}
|
||||
|
||||
protected void writeLengthValue(String data) throws SAXException {
|
||||
writeLengthValue(data.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io.xdbx;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.x4o.sax3.io.SAX3XMLConstants;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.ext.LexicalHandler;
|
||||
|
||||
/**
|
||||
* Writes SAX lexical handler events to XML.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Dec 20, 2024
|
||||
*/
|
||||
public abstract class AbstractXDBXWriterLexical extends AbstractXDBXWriterHandler implements LexicalHandler {
|
||||
|
||||
protected boolean printCDATA = false;
|
||||
|
||||
/**
|
||||
* Creates writer which prints to the stream interface.
|
||||
* @param out The stream to print the xml to.
|
||||
*/
|
||||
public AbstractXDBXWriterLexical(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ext.LexicalHandler#startCDATA()
|
||||
*/
|
||||
public void startCDATA() throws SAXException {
|
||||
printCDATA = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ext.LexicalHandler#endCDATA()
|
||||
*/
|
||||
public void endCDATA() throws SAXException {
|
||||
printCDATA = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void startDTD(String name, String publicId, String systemId) throws SAXException {
|
||||
// not supported
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ext.LexicalHandler#endDTD()
|
||||
*/
|
||||
public void endDTD() throws SAXException {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String)
|
||||
*/
|
||||
public void startEntity(String arg0) throws SAXException {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)
|
||||
*/
|
||||
public void endEntity(String arg0) throws SAXException {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.x4o.sax3.io.AbstractContentWriterHandler#characters(char[], int, int)
|
||||
*/
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
characters(new String(ch, start, length));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.x4o.sax3.io.AbstractContentWriterHandler#characters(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void characters(String text) throws SAXException {
|
||||
if (printCDATA) {
|
||||
String textSafe = SAX3XMLConstants.escapeCharactersCdata(text, "", "");
|
||||
writeTagLengthValue(XDBXContentTag.TEXT_CDATA, textSafe);
|
||||
} else {
|
||||
super.characters(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io.xdbx;
|
||||
|
||||
/**
|
||||
* XDBXConstants for writing binary XML.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Dec 20, 2024
|
||||
*/
|
||||
public final class XDBXConstants {
|
||||
|
||||
static public final byte[] HEADER_MARKER = new byte[] {(byte) 0xCA, 0x3B};
|
||||
static public final byte HEADER_LENGHT = 0x05;
|
||||
static public final byte HEADER_VERSION = 0x01;
|
||||
|
||||
static public final int FLAG_XML_SEQUENCE = 0x1;
|
||||
static public final int FLAG_STRING_ID = 0x2;
|
||||
static public final int FLAG_STRING_ID_IDX = 0x20;
|
||||
static public final int FLAG_VALIDATED = 0x80;
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io.xdbx;
|
||||
|
||||
/**
|
||||
* XDBXContentTag indicate the binary tag of the XDBX stream.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Dec 20, 2024
|
||||
*/
|
||||
public enum XDBXContentTag {
|
||||
|
||||
DOCUMENT_END('Z'),
|
||||
COMPLETED_DOC('d'),
|
||||
ATOMIC_VALUE('V'),
|
||||
DOC_TYPE('F'),
|
||||
XML_VERSION('L'),
|
||||
ENCODING('D'),
|
||||
STANDALONE('t'),
|
||||
ELEMENT_I('e'),
|
||||
ELEMENT_SII('X'),
|
||||
ELEMENT_III('x'),
|
||||
END_ELEMENT('z'),
|
||||
NS_DECL_II('m'),
|
||||
ATTRIBUTE_I('a'),
|
||||
ATTRIBUTE_SII('Y'),
|
||||
ATTRIBUTE_III('y'),
|
||||
ATTRIBUTE_III_FAST('b'), // no CR,AMP,GT,LT,',",\t,\n
|
||||
TEXT_T('T'),
|
||||
TEXT_T_FAST('U'), // no CR,AMP,GT,LT in text node
|
||||
TEXT_CDATA('C'),
|
||||
TEXT_WHITE_SPACE('W'),
|
||||
COMMENT('c'),
|
||||
PROCESSING_INSTRUCTION('P'),
|
||||
STRING_ID('I'),
|
||||
HINT('H'),
|
||||
SEQUENCE_SEPERATOR('@'),
|
||||
;
|
||||
|
||||
private final int tagNumber;
|
||||
|
||||
private XDBXContentTag(char tag) {
|
||||
tagNumber = tag;
|
||||
}
|
||||
|
||||
public int getTagNumber() {
|
||||
return tagNumber;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io.xdbx;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.x4o.sax3.io.ContentWriter;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
|
||||
/**
|
||||
* XDBXReaderXml reads XDBX binary XML and writes it as SAX events.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Dec 20, 2024
|
||||
*/
|
||||
public class XDBXReaderXml {
|
||||
|
||||
private final ContentWriter out;
|
||||
private final Map<Integer, String> stringIdx;
|
||||
private boolean docMetaFlushed = false;
|
||||
private String docXmlVersion;
|
||||
private String docEncoding;
|
||||
private Stack<XDBXElement> elementStack;
|
||||
private boolean failOnUnsupportedTag = true;
|
||||
|
||||
public XDBXReaderXml(ContentWriter out) {
|
||||
this.out = out;
|
||||
this.stringIdx = new HashMap<>();
|
||||
this.elementStack = new Stack<>();
|
||||
}
|
||||
|
||||
// TODO: replace with proper PropertyConfig support
|
||||
public XDBXReaderXml withNoFailOnUnsupportedTag() {
|
||||
failOnUnsupportedTag = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void parse(InputStream in) throws IOException {
|
||||
if (!Arrays.equals(XDBXConstants.HEADER_MARKER, in.readNBytes(2))) {
|
||||
throw new IOException("Wrong magic marker");
|
||||
}
|
||||
int headerLength = in.read();
|
||||
if (XDBXConstants.HEADER_LENGHT != headerLength) {
|
||||
throw new IOException("Wrong header length");
|
||||
}
|
||||
int headerVersion = in.read();
|
||||
if (XDBXConstants.HEADER_VERSION != headerVersion) {
|
||||
throw new IOException("Wrong magic version");
|
||||
}
|
||||
int flags = readHeaderFlags(in);
|
||||
if (0 != (flags & XDBXConstants.FLAG_XML_SEQUENCE)) {
|
||||
throw new IOException("XML Sequence mode is not supported");
|
||||
}
|
||||
if (0 == (flags & XDBXConstants.FLAG_STRING_ID)) {
|
||||
throw new IOException("None StringID mode is not supported");
|
||||
}
|
||||
try {
|
||||
out.startDocument();
|
||||
int next = in.read();
|
||||
while (next != -1) {
|
||||
parseToken(next, in);
|
||||
next = in.read();
|
||||
}
|
||||
out.endDocument();
|
||||
} catch (SAXException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseToken(int token, InputStream in) throws IOException, SAXException {
|
||||
if (XDBXContentTag.STRING_ID.getTagNumber() == token) {
|
||||
String value = readLengthValue(in);
|
||||
int strIdx = readVariableInteger(in);
|
||||
stringIdx.put(strIdx, value);
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.PROCESSING_INSTRUCTION.getTagNumber() == token) {
|
||||
flushDocDeclaration();
|
||||
int targetIdx = readVariableInteger(in);
|
||||
String data = readLengthValue(in);
|
||||
String target = stringIdx.get(targetIdx);
|
||||
out.processingInstruction(target, data);
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.COMMENT.getTagNumber() == token) {
|
||||
flushElement();
|
||||
out.comment(readLengthValue(in));
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.TEXT_WHITE_SPACE.getTagNumber() == token) {
|
||||
flushElement();
|
||||
out.ignorableWhitespace(readLengthValue(in));
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.TEXT_T.getTagNumber() == token) {
|
||||
flushElement();
|
||||
out.characters(readLengthValue(in));
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.NS_DECL_II.getTagNumber() == token) {
|
||||
int prefixIdx = readVariableInteger(in);
|
||||
int uriIdx = readVariableInteger(in);
|
||||
String prefix = stringIdx.get(prefixIdx);
|
||||
String uri = stringIdx.get(uriIdx);
|
||||
out.startPrefixMapping(prefix, uri);
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.END_ELEMENT.getTagNumber() == token) {
|
||||
flushElement();
|
||||
XDBXElement element = elementStack.pop();
|
||||
out.endElement(element.uri, element.localName, element.name);
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.XML_VERSION.getTagNumber() == token) {
|
||||
docXmlVersion = readLengthValue(in);
|
||||
return; // FIXME add flushing code...
|
||||
}
|
||||
if (XDBXContentTag.ENCODING.getTagNumber() == token) {
|
||||
docEncoding = readLengthValue(in);
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.TEXT_CDATA.getTagNumber() == token) {
|
||||
flushElement();
|
||||
out.startCDATA();
|
||||
out.characters(readLengthValue(in));
|
||||
out.endCDATA();
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.ELEMENT_I.getTagNumber() == token) {
|
||||
flushElement();
|
||||
elementStack.add(new XDBXElement(stringIdx.get(readVariableInteger(in))));
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.ELEMENT_SII.getTagNumber() == token) {
|
||||
flushElement();
|
||||
String value = readLengthValue(in);
|
||||
int strIdx = readVariableInteger(in);
|
||||
int prefixIdx = readVariableInteger(in);
|
||||
int uriIdx = readVariableInteger(in);
|
||||
stringIdx.put(strIdx, value);
|
||||
elementStack.add(new XDBXElement(value));
|
||||
if (prefixIdx > 0) {
|
||||
elementStack.peek().name = stringIdx.get(prefixIdx);
|
||||
}
|
||||
if (uriIdx > 0) {
|
||||
elementStack.peek().uri = stringIdx.get(uriIdx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.ELEMENT_III.getTagNumber() == token) {
|
||||
flushElement();
|
||||
int strIdx = readVariableInteger(in);
|
||||
int prefixIdx = readVariableInteger(in);
|
||||
int uriIdx = readVariableInteger(in);
|
||||
elementStack.add(new XDBXElement(stringIdx.get(strIdx)));
|
||||
if (prefixIdx > 0) {
|
||||
elementStack.peek().name = stringIdx.get(prefixIdx);
|
||||
}
|
||||
if (uriIdx > 0) {
|
||||
elementStack.peek().uri = stringIdx.get(uriIdx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.ATTRIBUTE_I.getTagNumber() == token) {
|
||||
int attrNameIdx = readVariableInteger(in);
|
||||
String attrName = stringIdx.get(attrNameIdx);
|
||||
String attrValue = readLengthValue(in);
|
||||
elementStack.peek().atts.addAttribute("", attrName, "", "", attrValue);
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.ATTRIBUTE_SII.getTagNumber() == token) {
|
||||
String attrName = readLengthValue(in);
|
||||
int attrNameIdx = readVariableInteger(in);
|
||||
stringIdx.put(attrNameIdx, attrName);
|
||||
int prefixIdx = readVariableInteger(in);
|
||||
int uriIdx = readVariableInteger(in);
|
||||
String attrValue = readLengthValue(in);
|
||||
String prefix = "";
|
||||
String uri = "";
|
||||
if (prefixIdx > 0) {
|
||||
prefix = stringIdx.get(prefixIdx);
|
||||
}
|
||||
if (uriIdx > 0) {
|
||||
uri = stringIdx.get(uriIdx);
|
||||
}
|
||||
elementStack.peek().atts.addAttribute(uri, attrName, prefix, "", attrValue);
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.ATTRIBUTE_III.getTagNumber() == token || XDBXContentTag.ATTRIBUTE_III_FAST.getTagNumber() == token) {
|
||||
int attrNameIdx = readVariableInteger(in);
|
||||
String attrName = stringIdx.get(attrNameIdx);
|
||||
int prefixIdx = readVariableInteger(in);
|
||||
int uriIdx = readVariableInteger(in);
|
||||
String attrValue = readLengthValue(in);
|
||||
String prefix = "";
|
||||
String uri = "";
|
||||
if (prefixIdx > 0) {
|
||||
prefix = stringIdx.get(prefixIdx);
|
||||
}
|
||||
if (uriIdx > 0) {
|
||||
uri = stringIdx.get(uriIdx);
|
||||
}
|
||||
elementStack.peek().atts.addAttribute(uri, attrName, prefix, "", attrValue);
|
||||
return;
|
||||
}
|
||||
if (XDBXContentTag.DOCUMENT_END.getTagNumber() == token) {
|
||||
return; // NOP is done by caller
|
||||
}
|
||||
if (failOnUnsupportedTag) {
|
||||
throw new SAXException("Unsupported tag: " + (char)token + " 0x" + Integer.toHexString(token).toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
protected void flushDocDeclaration() throws SAXException {
|
||||
if (docMetaFlushed) {
|
||||
return;
|
||||
}
|
||||
docMetaFlushed = true;
|
||||
out.declaration(docXmlVersion, docEncoding, "");
|
||||
}
|
||||
|
||||
protected void flushElement() throws SAXException {
|
||||
flushDocDeclaration();
|
||||
if (elementStack.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
XDBXElement element = elementStack.peek();
|
||||
if (element.started) {
|
||||
return;
|
||||
}
|
||||
element.started = true;
|
||||
out.startElement(element.uri, element.localName, element.name, element.atts);
|
||||
}
|
||||
|
||||
protected String readLengthValue(InputStream in) throws IOException {
|
||||
int len = readVariableInteger(in);
|
||||
String value = new String(in.readNBytes(len));
|
||||
return value;
|
||||
}
|
||||
|
||||
protected int readVariableInteger(InputStream in) throws IOException {
|
||||
int result = in.read();
|
||||
if (result < 128) {
|
||||
return result;
|
||||
}
|
||||
result = result + (in.read() << 7);
|
||||
if (result < 16383) {
|
||||
return result;
|
||||
}
|
||||
return result + (in.read() << 14);
|
||||
}
|
||||
|
||||
public int readHeaderFlags(InputStream in) throws IOException {
|
||||
int result = 0;
|
||||
result += in.read() << 24;
|
||||
result += in.read() << 16;
|
||||
result += in.read() << 8;
|
||||
result += in.read() << 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getDocXmlVersion() {
|
||||
return docXmlVersion;
|
||||
}
|
||||
|
||||
public String getDocEncoding() {
|
||||
return docEncoding;
|
||||
}
|
||||
|
||||
class XDBXElement {
|
||||
String uri;
|
||||
String localName;
|
||||
String name;
|
||||
final AttributesImpl atts;
|
||||
boolean started = false;
|
||||
|
||||
XDBXElement() {
|
||||
atts = new AttributesImpl();
|
||||
}
|
||||
XDBXElement(String localName) {
|
||||
this();
|
||||
this.localName = localName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io.xdbx;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* XDBXWriterXml writes SAX content handler events to binary XML.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Dev 20, 2024
|
||||
*/
|
||||
public class XDBXWriterXml extends AbstractXDBXWriter {
|
||||
|
||||
/**
|
||||
* Creates XmlWriter which prints to the OutputStream interface.
|
||||
* @param out The OutputStream to write to.
|
||||
*/
|
||||
public XDBXWriterXml(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The SAX XDBX classes and interfaces.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
package org.x4o.sax3.io.xdbx;
|
||||
30
nx01-x4o-sax3/src/main/java/org/x4o/sax3/package-info.java
Normal file
30
nx01-x4o-sax3/src/main/java/org/x4o/sax3/package-info.java
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* X4O SAX 3 and binary XML support classes.
|
||||
*
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
package org.x4o.sax3;
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.x4o.sax3.SAX3WriterXml;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
|
||||
/**
|
||||
* ContentWriterXmlAttributeTest test xml attribute printing.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 S 17, 2012
|
||||
*/
|
||||
public class SAX3WriterXmlAttributeTest {
|
||||
|
||||
@Test
|
||||
public void testAttributeNormal() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute ("", "attr", "", "", "foobar");
|
||||
writer.startElementEnd("", "test", "", atts);
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test attr=\"foobar\"/>"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttributeEscape() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute ("", "attr", "", "", "<test/> & 'foobar' is \"quoted\"!");
|
||||
writer.startElementEnd("", "test", "", atts);
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test attr=\"<test/> & 'foobar' is "quoted"!\"/>"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttributeWhiteSpace() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
Assertions.assertThrows(SAXException.class, () -> {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute ("", "", "", "", "junit");
|
||||
writer.startElementEnd("", "test", "", atts);
|
||||
});
|
||||
Assertions.assertThrows(SAXException.class, () -> {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute ("", " ", "", "", "junit");
|
||||
writer.startElementEnd("", "test", "", atts);
|
||||
});
|
||||
Assertions.assertThrows(SAXException.class, () -> {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute ("", "foo bar", "", "", "junit");
|
||||
writer.startElementEnd("", "test", "", atts);
|
||||
});
|
||||
Assertions.assertThrows(SAXException.class, () -> {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute ("", "foobar", "", "", "junit");
|
||||
writer.startElementEnd("", "test junit", "", atts);
|
||||
});
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute ("", "abc", "", "", " junit ");
|
||||
writer.startElementEnd("", "root", "", atts);
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root abc=\" junit \"/>"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttributeChinees() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute ("", "仙上主天", "", "", "仙上主天");
|
||||
writer.startElementEnd("", "chinees", "", atts);
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<chinees 仙上主天=\"仙上主天\"/>"), output);
|
||||
|
||||
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = saxFactory.newSAXParser();
|
||||
XMLReader saxReader = saxParser.getXMLReader();
|
||||
saxReader.parse(new InputSource(new ByteArrayInputStream(output.getBytes(StandardCharsets.UTF_8))));
|
||||
Assertions.assertNotNull(saxReader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttributeBrahmi() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
// Legal by spec, but not in JVM SAX Reader
|
||||
writer.startDocument();
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute ("", "𑀳𑁂𑀮𑀺𑀉𑁄𑀤𑁄𑀭𑁂𑀡𑀪𑀸𑀕", "", "", "𑀳𑁂𑀮𑀺𑀉𑁄𑀤𑁄𑀭𑁂𑀡𑀪𑀸𑀕");
|
||||
atts.addAttribute ("", "ᒡᒢᑊᒻᒻᓫᔿ", "", "", "ᒡᒢᑊᒻᒻᓫᔿ");
|
||||
writer.startElementEnd("", "test", "", atts);
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test 𑀳𑁂𑀮𑀺𑀉𑁄𑀤𑁄𑀭𑁂𑀡𑀪𑀸𑀕=\"𑀳𑁂𑀮𑀺𑀉𑁄𑀤𑁄𑀭𑁂𑀡𑀪𑀸𑀕\" ᒡᒢᑊᒻᒻᓫᔿ=\"ᒡᒢᑊᒻᒻᓫᔿ\"/>"), output);
|
||||
|
||||
// TODO: fix SAX impl
|
||||
Assertions.assertThrows(SAXException.class, () -> {
|
||||
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = saxFactory.newSAXParser();
|
||||
XMLReader saxReader = saxParser.getXMLReader();
|
||||
saxReader.parse(new InputSource(new ByteArrayInputStream(output.getBytes(StandardCharsets.UTF_8))));
|
||||
});
|
||||
}
|
||||
|
||||
private String createLongAttribute(Map<String,Object> para) throws SAXException, IOException {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(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();
|
||||
}
|
||||
return outputWriter.toString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttributeLongNormal() throws Exception {
|
||||
Map<String,Object> para = new HashMap<String,Object>();
|
||||
String output = createLongAttribute(para);
|
||||
int newlines = output.split("\n").length;
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(newlines==4, "outputs: "+newlines);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttributeLongPerLine() throws Exception {
|
||||
Map<String,Object> para = new HashMap<String,Object>();
|
||||
para.put(SAX3WriterXml.OUTPUT_LINE_PER_ATTRIBUTE, true);
|
||||
String output = createLongAttribute(para);
|
||||
int newlines = output.split("\n").length;
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(newlines==20, "outputs: "+newlines);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttributeLongSplit80() throws Exception {
|
||||
Map<String,Object> para = new HashMap<String,Object>();
|
||||
para.put(SAX3WriterXml.OUTPUT_LINE_BREAK_WIDTH, 80);
|
||||
String output = createLongAttribute(para);
|
||||
int newlines = output.split("\n").length;
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(newlines==16, "outputs: "+newlines);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttributeLongSplit180() throws Exception {
|
||||
Map<String,Object> para = new HashMap<String,Object>();
|
||||
para.put(SAX3WriterXml.OUTPUT_LINE_BREAK_WIDTH, 180);
|
||||
String output = createLongAttribute(para);
|
||||
int newlines = output.split("\n").length;
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(newlines==11, "outputs: "+newlines);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io;
|
||||
|
||||
import java.io.StringWriter;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.x4o.sax3.SAX3WriterXml;
|
||||
|
||||
/**
|
||||
* ContentWriterXmlCDataTest tests cdata xml escaping.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Sep 17, 2013
|
||||
*/
|
||||
public class SAX3WriterXmlCDataTest {
|
||||
|
||||
@Test
|
||||
public void testCDATANone() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.characters("foobar");
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>foobar"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCDATANoneTagEscape() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.characters("foobar<test/>");
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>foobar<test/>"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCDATANormal() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.startCDATA();
|
||||
writer.characters("foobar");
|
||||
writer.endCDATA();
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[foobar]]>"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCDATAEscapeTag() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.startCDATA();
|
||||
writer.characters("foobar<test/>");
|
||||
writer.endCDATA();
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[foobar<test/>]]>"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCDATAEscapeStart() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.startCDATA();
|
||||
writer.characters("<![CDATA[foobar");
|
||||
writer.endCDATA();
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[foobar]]>"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCDATAEscapeEnd() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.startCDATA();
|
||||
writer.characters("foobar]]>");
|
||||
writer.endCDATA();
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[foobar]]>"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCDATAEscapeEndEskimo() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.startCDATA();
|
||||
writer.characters("ᒡᒢᑊᒻ]]>ᒻᓫᔿ");
|
||||
writer.endCDATA();
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[ᒡᒢᑊᒻᒻᓫᔿ]]>"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCDATAEscapeInvalid() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.startCDATA();
|
||||
writer.characters("<![CDATA[tokens like ']]>' are <invalid>]]>");
|
||||
writer.endCDATA();
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[tokens like \'\' are <invalid>]]>"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCDATAEscapeValid() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.startCDATA();
|
||||
writer.characters("<![CDATA[tokens like ']]]]><![CDATA[>' are <valid>]]>");
|
||||
writer.endCDATA();
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><![CDATA[tokens like \']]>\' are <valid>]]>"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io;
|
||||
|
||||
import java.io.StringWriter;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.x4o.sax3.SAX3WriterXml;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
|
||||
/**
|
||||
* ContentWriterXml test xml escaping.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Aug 26, 2012
|
||||
*/
|
||||
public class SAX3WriterXmlTest {
|
||||
|
||||
@Test
|
||||
public void testCharactersNormal() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.characters("test is foobar!");
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>test is foobar!"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharactersEscape() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.characters("<test/> & 'foobar' is \"quoted\"!");
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><test/> & 'foobar' is "quoted"!"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommentNormal() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.comment("foobar");
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- foobar -->"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommentEscape() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
writer.startDocument();
|
||||
writer.comment("<!-- foobar -->");
|
||||
writer.endDocument();
|
||||
}
|
||||
// note two space because auto-space is before escaping and places spaces over comment tags.
|
||||
// 1) "<!-- foobar -->" - argu
|
||||
// 2) " <!-- foobar --> " - auto-space (default enabled)
|
||||
// 3) " foobar " - escapes
|
||||
// 4) "<!-- foobar -->" - printed
|
||||
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- foobar -->"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXmlInvalid() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
SAXException e = Assertions.assertThrows(SAXException.class, () -> {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
writer.startDocument();
|
||||
writer.startElement("", "test", "", atts);
|
||||
writer.startElement("", "foobar", "", atts);
|
||||
writer.endElement("", "test", "");
|
||||
writer.endDocument();
|
||||
});
|
||||
Assertions.assertTrue(e.getMessage().contains("tag"));
|
||||
Assertions.assertTrue(e.getMessage().contains("foobar"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXmlInvalidEnd() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
SAXException e = Assertions.assertThrows(SAXException.class, () -> {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
writer.startDocument();
|
||||
writer.startElement("", "test", "", atts);
|
||||
writer.startElement("", "foobar", "", atts);
|
||||
writer.endDocument();
|
||||
});
|
||||
Assertions.assertTrue(e.getMessage().contains("Invalid"));
|
||||
Assertions.assertTrue(e.getMessage().contains("2"));
|
||||
Assertions.assertTrue(e.getMessage().contains("open"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessingInstruction() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
writer.startDocument();
|
||||
writer.processingInstruction("target", "data");
|
||||
writer.startElement("", "test", "", atts);
|
||||
writer.endElement("", "test", "");
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<?target data?>\n<test/>"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessingInstructionInline() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
writer.startDocument();
|
||||
writer.processingInstruction("target", "data");
|
||||
writer.startElement("", "test", "", atts);
|
||||
writer.processingInstruction("target-doc", "data-doc");
|
||||
writer.endElement("", "test", "");
|
||||
writer.endDocument();
|
||||
}
|
||||
String output = outputWriter.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length()>0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<?target data?>\n<test>\n\t<?target-doc data-doc?>\n</test>\n"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessingInstructionTargetXmlPrefix() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
SAXException e = Assertions.assertThrows(SAXException.class, () -> {
|
||||
writer.startDocument();
|
||||
writer.processingInstruction("xmlPrefix", "isInvalid");
|
||||
});
|
||||
Assertions.assertTrue(e.getMessage().contains("instruction"));
|
||||
Assertions.assertTrue(e.getMessage().contains("start with xml"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessingInstructionTargetNoneNameChar() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
SAXException e = Assertions.assertThrows(SAXException.class, () -> {
|
||||
writer.startDocument();
|
||||
writer.processingInstruction("4Prefix", "isInvalid");
|
||||
});
|
||||
Assertions.assertTrue(e.getMessage().contains("instruction"));
|
||||
Assertions.assertTrue(e.getMessage().contains("invalid name"));
|
||||
Assertions.assertTrue(e.getMessage().contains("4Prefix"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessingInstructionDataNoneChar() throws Exception {
|
||||
StringWriter outputWriter = new StringWriter();
|
||||
try (SAX3WriterXml writer = new SAX3WriterXml(outputWriter)) {
|
||||
SAXException e = Assertions.assertThrows(SAXException.class, () -> {
|
||||
writer.startDocument();
|
||||
writer.processingInstruction("target", "isInvalidChar="+0xD800);
|
||||
});
|
||||
Assertions.assertTrue(e.getMessage().contains("instruction"));
|
||||
Assertions.assertTrue(e.getMessage().contains("invalid char"));
|
||||
Assertions.assertTrue(e.getMessage().contains("isInvalidChar=55296"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io.xdbx;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.x4o.sax3.SAX3WriterXml;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
|
||||
/**
|
||||
* XDBXReaderXmlTest tests xdbx writing.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Dec 21, 2024
|
||||
*/
|
||||
public class XDBXReaderXmlTest {
|
||||
|
||||
@Test
|
||||
public void testReadWrite() throws Exception {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (XDBXWriterXml writer = new XDBXWriterXml(baos)) {
|
||||
writer.startDocument();
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute ("", "attr", "", "", "foobar");
|
||||
writer.startElementEnd("", "test", "", atts);
|
||||
writer.endDocument();
|
||||
}
|
||||
|
||||
StringWriter outputXmlStr = new StringWriter();
|
||||
SAX3WriterXml outputXml = new SAX3WriterXml(outputXmlStr);
|
||||
XDBXReaderXml reader = new XDBXReaderXml(outputXml);
|
||||
byte[] writeData = baos.toByteArray();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(writeData);
|
||||
reader.parse(bais);
|
||||
|
||||
String output = outputXmlStr.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length() > 0);
|
||||
Assertions.assertTrue(output.equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test attr=\"foobar\"/>"), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWritePom() throws Exception {
|
||||
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
|
||||
saxFactory.setNamespaceAware(true);
|
||||
SAXParser saxParser = saxFactory.newSAXParser();
|
||||
XMLReader saxReader = saxParser.getXMLReader();
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
XDBXWriterXml writer = new XDBXWriterXml(baos);
|
||||
|
||||
saxReader.setContentHandler(writer);
|
||||
saxReader.parse(new InputSource(new FileInputStream(new File("../pom.xml"))));
|
||||
|
||||
StringWriter outputXmlStr = new StringWriter();
|
||||
SAX3WriterXml outputXml = new SAX3WriterXml(outputXmlStr);
|
||||
XDBXReaderXml reader = new XDBXReaderXml(outputXml);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
reader.parse(bais);
|
||||
|
||||
String output = outputXmlStr.toString();
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length() > 0);
|
||||
Assertions.assertTrue(output.contains("<artifactId>nx01-x4o-driver</artifactId>"), output);
|
||||
|
||||
long sizePom = new File("../pom.xml").length();
|
||||
long sizeXDBX = baos.toByteArray().length;
|
||||
|
||||
System.out.println("size-pom.xml:: " + sizePom);
|
||||
System.out.println("size-pom.xdbx: " + sizeXDBX);
|
||||
|
||||
Assertions.assertTrue(sizePom > sizeXDBX, "XDBX is not smaller");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2014, 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.sax3.io.xdbx;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.x4o.sax3.SAX3WriterXml;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
|
||||
/**
|
||||
* XDBXWriterXmlTest tests xdbx writing.
|
||||
*
|
||||
* @author Willem Cazander
|
||||
* @version 1.0 Dec 21, 2024
|
||||
*/
|
||||
public class XDBXWriterXmlTest {
|
||||
|
||||
@Test
|
||||
public void testExample1DefaultEncoding() throws Exception {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (XDBXWriterXml writer = new XDBXWriterXml(baos)) {
|
||||
writer.getPropertyConfig().setProperty(XDBXWriterXml.OUTPUT_DECLARATION, false);
|
||||
|
||||
writer.startDocument();
|
||||
writer.startElement("", "root", "", new AttributesImpl());
|
||||
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute ("", "mgr", "", "", "NO");
|
||||
writer.startElement("", "name", "", atts);
|
||||
writer.characters("Joe");
|
||||
writer.endElement("", "name", "");
|
||||
|
||||
writer.startElement("", "name", "", new AttributesImpl());
|
||||
writer.characters("Susan");
|
||||
writer.endElement("", "name", "");
|
||||
writer.startElement("", "name", "", new AttributesImpl());
|
||||
writer.characters("Bill");
|
||||
writer.endElement("", "name", "");
|
||||
|
||||
writer.endElement("", "root", "");
|
||||
writer.endDocument();
|
||||
}
|
||||
|
||||
byte[] output = baos.toByteArray();
|
||||
int outIdx = 8;
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length > 0);
|
||||
Assertions.assertEquals((byte)'X', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 4, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'r', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'o', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'o', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'t', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 1, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((byte)'X', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 4, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'n', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'a', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'m', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'e', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 2, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((byte)'Y', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 3, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'m', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'g', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'r', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 3, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 2, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'N', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'O', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'T', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 3, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'J', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'o', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'e', output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((byte)'z', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'e', output[outIdx++]); // IBM SPEC example FAIL: 'x' is for WITH namespace
|
||||
Assertions.assertEquals((byte) 2, output[outIdx++]);
|
||||
//Assertions.assertEquals((byte) 0, output[outIdx++]); // IBM SPEC example FAIL: 'x' is for WITH namespace
|
||||
//Assertions.assertEquals((byte) 0, output[outIdx++]); // IBM SPEC example FAIL: 'x' is for WITH namespace
|
||||
Assertions.assertEquals((byte)'T', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 5, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'S', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'u', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'s', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'a', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'n', output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((byte)'z', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'e', output[outIdx++]); // IBM SPEC example FAIL: 'x' is for WITH namespace
|
||||
Assertions.assertEquals((byte) 2, output[outIdx++]);
|
||||
//Assertions.assertEquals((byte) 0, output[outIdx++]); // IBM SPEC example FAIL: 'x' is for WITH namespace
|
||||
//Assertions.assertEquals((byte) 0, output[outIdx++]); // IBM SPEC example FAIL: 'x' is for WITH namespace
|
||||
Assertions.assertEquals((byte)'T', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 4, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'B', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'i', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'l', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'l', output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((byte)'z', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'z', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'Z', output[outIdx++]);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExample3StringIds() throws Exception {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (XDBXWriterXml writer = new XDBXWriterXml(baos)) {
|
||||
writer.getPropertyConfig().setProperty(XDBXWriterXml.OUTPUT_DECLARATION, false);
|
||||
AttributesImpl atts;
|
||||
|
||||
writer.startDocument();
|
||||
writer.startPrefixMapping("foo", "bar");
|
||||
writer.startElement("", "root", "", new AttributesImpl());
|
||||
|
||||
writer.startElement("", "Person", "", new AttributesImpl());
|
||||
atts = new AttributesImpl();
|
||||
atts.addAttribute ("", "mgr", "", "", "NO");
|
||||
writer.startElement("", "name", "", atts);
|
||||
writer.characters("Bill");
|
||||
writer.endElement("", "name", "");
|
||||
writer.startElement("bar", "age", "age", new AttributesImpl());
|
||||
writer.characters("35");
|
||||
writer.endElement("bar", "age", "age");
|
||||
writer.endElement("", "Person", "");
|
||||
|
||||
writer.startElement("", "Person", "", new AttributesImpl());
|
||||
atts = new AttributesImpl();
|
||||
atts.addAttribute ("", "mgr", "", "", "NO");
|
||||
writer.startElement("", "name", "", atts);
|
||||
writer.characters("Joe");
|
||||
writer.endElement("", "name", "");
|
||||
writer.startElement("bar", "age", "age", new AttributesImpl());
|
||||
writer.characters("45");
|
||||
writer.endElement("bar", "age", "age");
|
||||
writer.endElement("", "Person", "");
|
||||
|
||||
writer.endElement("", "root", "");
|
||||
writer.endDocument();
|
||||
}
|
||||
|
||||
byte[] output = baos.toByteArray();
|
||||
int outIdx = 8;
|
||||
Assertions.assertNotNull(output);
|
||||
Assertions.assertTrue(output.length > 0);
|
||||
Assertions.assertEquals((byte)'I', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 3, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'f', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'o', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'o', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 1, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'I', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 3, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'b', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'a', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'r', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 2, output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((char)'X', (char)output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 4, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'r', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'o', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'o', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'t', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 3, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
Assertions.assertEquals((char)'m', (char)output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 1, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 2, output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((char)'X', (char)output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 6, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'P', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'e', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'r', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'s', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'o', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'n', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 4, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((char)'X', (char)output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 4, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'n', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'a', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'m', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'e', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 5, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((char)'Y', (char)output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 3, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'m', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'g', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'r', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 6, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 0, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 2, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'N', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'O', output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((byte)'T', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 4, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'B', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'i', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'l', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'l', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'z', output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((char)'X', (char)output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 3, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'a', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'g', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'e', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 7, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 1, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 2, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 'T', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 2, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'3', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'5', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'z', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'z', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'e', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 4, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'e', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 5, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'a', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 6, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 2, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'N', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'O', output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((byte)'T', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 3, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'J', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'o', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'e', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'z', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'x', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 7, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 1, output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 2, output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((byte)'T', output[outIdx++]);
|
||||
Assertions.assertEquals((byte) 2, output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'4', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'5', output[outIdx++]);
|
||||
|
||||
Assertions.assertEquals((byte)'z', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'z', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'z', output[outIdx++]);
|
||||
Assertions.assertEquals((byte)'Z', output[outIdx++]);
|
||||
|
||||
StringWriter outputXmlStr = new StringWriter();
|
||||
SAX3WriterXml outputXml = new SAX3WriterXml(outputXmlStr);
|
||||
XDBXReaderXml reader = new XDBXReaderXml(outputXml);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(output);
|
||||
reader.parse(bais);
|
||||
|
||||
String outputStr = outputXmlStr.toString();
|
||||
Assertions.assertTrue(outputStr.contains("<root"));
|
||||
Assertions.assertTrue(outputStr.contains("xmlns:foo=\"bar\""));
|
||||
Assertions.assertTrue(outputStr.contains("<name mgr=\"NO\">Bill</name>"));
|
||||
Assertions.assertTrue(outputStr.contains("<foo:age>45</foo:age>"));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue