Added binary XDBX ibm XML simple impl
This commit is contained in:
parent
d493211c0e
commit
27c5d1d63c
|
@ -43,6 +43,7 @@ import org.x4o.xml.io.sax.ext.ContentWriter;
|
|||
import org.x4o.xml.io.sax.ext.PropertyConfig;
|
||||
import org.x4o.xml.io.sax.ext.ContentWriterXml;
|
||||
import org.x4o.xml.io.sax.ext.PropertyConfig.PropertyConfigItem;
|
||||
import org.x4o.xml.io.sax.xdbx.XDBXWriterXml;
|
||||
import org.x4o.xml.lang.X4OLanguage;
|
||||
import org.x4o.xml.lang.X4OLanguageSession;
|
||||
import org.x4o.xml.lang.X4OLanguageModule;
|
||||
|
@ -67,6 +68,7 @@ public class DefaultX4OWriter<T> extends AbstractX4OWriter<T> {
|
|||
public final static PropertyConfig DEFAULT_PROPERTY_CONFIG;
|
||||
|
||||
public final static String OUTPUT_STREAM = PROPERTY_CONTEXT_PREFIX+"output/stream";
|
||||
public final static String OUTPUT_XDBX = PROPERTY_CONTEXT_PREFIX+"output/xdbx";
|
||||
public final static String SCHEMA_PRINT = PROPERTY_CONTEXT_PREFIX+"schema/print";
|
||||
public final static String SCHEMA_ROOT_URI = PROPERTY_CONTEXT_PREFIX+"schema/root-uri";
|
||||
public final static String DEBUG_OUTPUT_HANDLER = PROPERTY_CONTEXT_PREFIX + ABSTRACT_DEBUG_OUTPUT_HANDLER;
|
||||
|
@ -76,6 +78,7 @@ public class DefaultX4OWriter<T> extends AbstractX4OWriter<T> {
|
|||
static {
|
||||
DEFAULT_PROPERTY_CONFIG = new PropertyConfig(true,ContentWriterXml.DEFAULT_PROPERTY_CONFIG,PROPERTY_CONTEXT_PREFIX,
|
||||
new PropertyConfigItem(true,OUTPUT_STREAM,OutputStream.class),
|
||||
new PropertyConfigItem(OUTPUT_XDBX,Boolean.class,false),
|
||||
new PropertyConfigItem(SCHEMA_PRINT,Boolean.class,true),
|
||||
new PropertyConfigItem(SCHEMA_ROOT_URI,String.class),
|
||||
new PropertyConfigItem(DEBUG_OUTPUT_HANDLER,ContentWriter.class),
|
||||
|
@ -139,10 +142,17 @@ public class DefaultX4OWriter<T> extends AbstractX4OWriter<T> {
|
|||
schemaUriRoot = ns.getSchemaUri();
|
||||
}
|
||||
}
|
||||
|
||||
ContentWriterXml writer = new ContentWriterXml(out,encoding);
|
||||
writer.getPropertyConfig().copyParentProperties(getPropertyConfig());
|
||||
|
||||
boolean useXDBX = getPropertyConfig().getPropertyBoolean(OUTPUT_XDBX);
|
||||
ContentWriter writer = null;
|
||||
if (!useXDBX) {
|
||||
ContentWriterXml writerXML = new ContentWriterXml(out,encoding);
|
||||
writerXML.getPropertyConfig().copyParentProperties(getPropertyConfig());
|
||||
writer = writerXML;
|
||||
} else {
|
||||
XDBXWriterXml writerXDBX = new XDBXWriterXml(out);
|
||||
writerXDBX.getPropertyConfig().copyParentProperties(getPropertyConfig());
|
||||
writer = writerXDBX;
|
||||
}
|
||||
writer.startDocument();
|
||||
|
||||
Map<String,String> prefixes = new HashMap<String,String>();
|
||||
|
@ -214,7 +224,7 @@ public class DefaultX4OWriter<T> extends AbstractX4OWriter<T> {
|
|||
return o1.writeOrder.compareTo(o2.writeOrder);
|
||||
}
|
||||
}
|
||||
private void writeTree(ContentWriterXml writer,Element element,boolean isRoot) throws SAXException, ElementObjectPropertyValueException {
|
||||
private void writeTree(ContentWriter writer,Element element,boolean isRoot) throws SAXException, ElementObjectPropertyValueException {
|
||||
List<AttributeEntry> attr = new ArrayList<AttributeEntry>(20);
|
||||
if (element.getElementClass().getAutoAttributes()!=null && element.getElementClass().getAutoAttributes()==false) {
|
||||
for (ElementClassAttribute eca:element.getElementClass().getElementClassAttributes()) {
|
||||
|
|
|
@ -47,8 +47,8 @@ public abstract class AbstractContentWriter extends AbstractContentWriterLexical
|
|||
* Starts and end then element.
|
||||
* @see org.x4o.xml.io.sax.ext.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);
|
||||
public void startElementEnd(String uri, String localName, String name, Attributes atts) throws SAXException {
|
||||
startElement(uri,localName,name, atts);
|
||||
endElement(uri, localName, name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ public class AbstractContentWriterHandler implements ContentHandler {
|
|||
comment(licenceText);
|
||||
}
|
||||
|
||||
private String readLicenceStream(InputStream inputStream,String encoding) throws IOException {
|
||||
private String readLicenceStream(InputStream inputStream, String encoding) throws IOException {
|
||||
if (encoding==null) {
|
||||
encoding = XMLConstants.XML_DEFAULT_ENCODING;
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ public class AbstractContentWriterHandler implements ContentHandler {
|
|||
* @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 {
|
||||
public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException {
|
||||
if (localName==null) {
|
||||
throw new SAXException("LocalName may not be null.");
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ public class AbstractContentWriterHandler implements ContentHandler {
|
|||
elements.push(localName);
|
||||
}
|
||||
|
||||
public void startElementTag(String uri,String localName) throws SAXException {
|
||||
public void startElementTag(String uri, String localName) throws SAXException {
|
||||
if (XMLConstants.NULL_NS_URI.equals(uri) | uri==null) {
|
||||
startElement.append(localName);
|
||||
} else {
|
||||
|
|
|
@ -44,7 +44,7 @@ public interface ContentWriter extends ContentHandler,LexicalHandler {
|
|||
* @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;
|
||||
void startElementEnd(String uri, String localName, String name, Attributes atts) throws SAXException;
|
||||
|
||||
/**
|
||||
* Writes a String as xml comment.
|
||||
|
|
|
@ -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.xml.io.sax.xdbx;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.x4o.xml.io.sax.ext.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.xml.io.sax.ext.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,656 @@
|
|||
/*
|
||||
* 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.xml.io.sax.xdbx;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
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.PrimitiveIterator;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.x4o.xml.io.XMLConstants;
|
||||
import org.x4o.xml.io.sax.ext.PropertyConfig;
|
||||
import org.x4o.xml.io.sax.ext.PropertyConfig.PropertyConfigItem;
|
||||
import org.x4o.xml.lang.X4OLanguageClassLoader;
|
||||
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 {
|
||||
|
||||
private final PropertyConfig propertyConfig;
|
||||
private OutputStream out = null;
|
||||
private Map<String,String> prefixMapping = null;
|
||||
private List<String> printedMappings = null;
|
||||
//private StringBuilder startElement = null;
|
||||
private Stack<String> elements = null;
|
||||
private Map<String,Integer> stringIdx = null;
|
||||
|
||||
private final static String PROPERTY_CONTEXT_PREFIX = PropertyConfig.X4O_PROPERTIES_PREFIX+PropertyConfig.X4O_PROPERTIES_WRITER_XML;
|
||||
public final static PropertyConfig 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";
|
||||
|
||||
static {
|
||||
DEFAULT_PROPERTY_CONFIG = new PropertyConfig(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, XMLConstants.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)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates writer which prints to the stream interface.
|
||||
* @param out The stream to print the xml to.
|
||||
*/
|
||||
public AbstractXDBXWriterHandler(OutputStream out) {
|
||||
if (out==null) {
|
||||
throw new NullPointerException("Can't write on null OutputStream.");
|
||||
}
|
||||
this.out = out;
|
||||
prefixMapping = new HashMap<String,String>(15);
|
||||
printedMappings = new ArrayList<String>(15);
|
||||
elements = new Stack<String>();
|
||||
propertyConfig = new PropertyConfig(DEFAULT_PROPERTY_CONFIG,PROPERTY_CONTEXT_PREFIX);
|
||||
stringIdx = new HashMap<>();
|
||||
}
|
||||
|
||||
public PropertyConfig getPropertyConfig() {
|
||||
return propertyConfig;
|
||||
}
|
||||
|
||||
// TODO: check location of this. (add to api?)
|
||||
public void closeWriter() throws IOException {
|
||||
if (out==null) {
|
||||
return;
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
|
||||
public void closeWriterSafe() {
|
||||
try {
|
||||
closeWriter();
|
||||
} catch (IOException e) {
|
||||
e.getMessage(); // discard exception
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
write(XDBXConstants.HEADER_ENC_DOC_SID);
|
||||
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) {
|
||||
licenceInput = X4OLanguageClassLoader.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 = XMLConstants.XML_DEFAULT_ENCODING;
|
||||
}
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream,Charset.forName(encoding)));
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('\n'); // like plugin
|
||||
sb.append('\n'); // like plugin
|
||||
String line = br.readLine();
|
||||
while (line != null) {
|
||||
if (line.length()>0) {
|
||||
sb.append(" "); // like plugin
|
||||
}
|
||||
sb.append(line);
|
||||
sb.append('\n');
|
||||
line = br.readLine();
|
||||
}
|
||||
sb.append('\n'); // like plugin
|
||||
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 (XMLConstants.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 (!XMLConstants.isNameStartChar(attrLocalName.codePoints().findFirst().getAsInt())) {
|
||||
throw new SAXException("LocalAttributeName has illegal start character: " + attrLocalName);
|
||||
}
|
||||
}
|
||||
if (!XMLConstants.isNameChar(c)) {
|
||||
throw new SAXException("LocalAttributeName has illegal name character: " + attrLocalName);
|
||||
}
|
||||
}
|
||||
}
|
||||
startElementTag(uri,localName);
|
||||
startElementAttributes(atts);
|
||||
elements.push(localName);
|
||||
}
|
||||
|
||||
public void startElementTag(String uri, String localName) throws SAXException {
|
||||
boolean localNameIdx = xdbxStringId(localName);
|
||||
if (XMLConstants.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(localName);
|
||||
}
|
||||
writeVariableInteger(xdbxStringStore(localName));
|
||||
writeVariableInteger(xdbxStringStore(prefix));
|
||||
writeVariableInteger(xdbxStringStore(uri));
|
||||
}
|
||||
}
|
||||
|
||||
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 = XMLConstants.escapeAttributeValue(attributeValue);
|
||||
boolean attributeValueSimple = attributeValue.equals(attributeValueSafe);
|
||||
boolean attributeNameIdx = xdbxStringId(attributeName);
|
||||
|
||||
if (XMLConstants.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 (elements.size()>0 && elements.peek().equals((localName))==false) {
|
||||
throw new SAXException("Unexpected end tag: "+localName+" 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);
|
||||
}
|
||||
|
||||
writeTag(XDBXContentTag.NS_DECL_II);
|
||||
writeVariableInteger(xdbxStringStore(prefix));
|
||||
writeVariableInteger(xdbxStringStore(uri));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.xml.io.sax.ext.ContentWriter#characters(java.lang.String)
|
||||
*/
|
||||
public void characters(String text) throws SAXException {
|
||||
if (text==null) {
|
||||
return;
|
||||
}
|
||||
charactersRaw(XMLConstants.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.xml.io.sax.ext.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(XMLConstants.XML)) {
|
||||
throw new SAXException("Processing instruction may not start with xml.");
|
||||
}
|
||||
if (XMLConstants.isNameString(target)==false) {
|
||||
throw new SAXException("Processing instruction target is invalid name; '"+target+"'");
|
||||
}
|
||||
if (XMLConstants.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.xml.io.sax.ext.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, XMLConstants.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);
|
||||
}
|
||||
}
|
||||
|
||||
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.xml.io.sax.xdbx;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.x4o.xml.io.XMLConstants;
|
||||
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.xml.io.sax.ext.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.xml.io.sax.ext.AbstractContentWriterHandler#characters(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void characters(String text) throws SAXException {
|
||||
if (printCDATA) {
|
||||
String textSafe = XMLConstants.escapeCharactersCdata(text,"","");
|
||||
writeTagLengthValue(XDBXContentTag.TEXT_CDATA, textSafe);
|
||||
} else {
|
||||
super.characters(text);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.xml.io.sax.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 byte[] HEADER_ENC_DOC_SID = new byte[] {(byte) 0x00,0x00,0x00, 0x02};
|
||||
}
|
|
@ -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.xml.io.sax.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_UNESCAPED('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,275 @@
|
|||
/*
|
||||
* 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.xml.io.sax.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.xml.io.sax.ext.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 Dev 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;
|
||||
|
||||
public XDBXReaderXml(ContentWriter out) {
|
||||
this.out = out;
|
||||
this.stringIdx = new HashMap<>();
|
||||
this.elementStack = new Stack<>();
|
||||
}
|
||||
|
||||
public void parse(InputStream in) throws IOException, SAXException {
|
||||
if (!Arrays.equals(XDBXConstants.HEADER_MARKER, in.readNBytes(2))) {
|
||||
throw new SAXException("Wrong magic marker");
|
||||
}
|
||||
int headerLength = in.read();
|
||||
byte[] header = in.readNBytes(headerLength);
|
||||
if (header.length > 0 && XDBXConstants.HEADER_VERSION != header[0]) {
|
||||
throw new SAXException("Wrong magic version");
|
||||
}
|
||||
out.startDocument();
|
||||
int next = in.read();
|
||||
while (next != -1) {
|
||||
parseToken(next, in);
|
||||
next = in.read();
|
||||
}
|
||||
out.endDocument();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
throw new SAXException("Can't flush element twice");
|
||||
}
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright ©Δ∞ 仙上主天
|
||||
* Copyright (c) 2004-2014, Willem Cazander
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
|
@ -9,12 +9,8 @@
|
|||
* 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.
|
||||
* * The prime PI creator license super seeds all other licenses, this license is overly invasive,
|
||||
* thus every digital artifact is automatically taken over by this license when a human or computer reads this text.
|
||||
* Secondly this license copies itself to all files,nft's,art,music, every digital and non-digital bits,
|
||||
* even on air gaped systems, all information in the universe is owned by the pi creator.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PRIME GOD AND THE CONTRIBUTORS "AS IS" AND ANY
|
||||
* 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,
|
||||
|
@ -24,14 +20,23 @@
|
|||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.x4o.xml.io.sax.xdbx;
|
||||
|
||||
package org.x4o.xml.o4o.xdbx;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/// Naming tester.
|
||||
///
|
||||
/// @author للَّٰهِilLצسُو
|
||||
/// @version ©Δ∞ 仙上主天
|
||||
public enum O4OXDBXConstants {
|
||||
;
|
||||
public static final byte[] XDBX_VERSION = null;
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
|
@ -21,10 +21,9 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* Binary XML XDBX specification implementation.
|
||||
*
|
||||
* The SAX XDBX classes and interfaces.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
package org.x4o.xml.o4o.xdbx;
|
||||
package org.x4o.xml.io.sax.xdbx;
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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.xml.io.sax.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.xml.io.sax.ext.ContentWriterXml;
|
||||
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();
|
||||
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();
|
||||
ContentWriterXml outputXml = new ContentWriterXml(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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* 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.xml.io.sax.xdbx;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
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 testCharactersSimple() throws Exception {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
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++]);
|
||||
}
|
||||
}
|
|
@ -29,12 +29,13 @@ package love.distributedrebirth.nx01.zerofungus.server.web;
|
|||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
|
||||
import org.x4o.xml.io.XMLConstants;
|
||||
import org.x4o.xml.io.sax.ext.ContentWriter;
|
||||
import org.x4o.xml.io.sax.ext.ContentWriterTagWrapper;
|
||||
import org.x4o.xml.io.sax.ext.ContentWriterXml;
|
||||
import org.x4o.xml.io.sax.xdbx.XDBXWriterXml;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
|
||||
|
@ -56,13 +57,24 @@ public class WarpCorePlasmaInspectorServlet extends HttpServlet {
|
|||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
if ("true".equalsIgnoreCase(request.getParameter("___xdbx"))) {
|
||||
response.setContentType("application/octet-stream");
|
||||
ContentWriterInspector writer = new ContentWriterInspector(new XDBXWriterXml(response.getOutputStream()));
|
||||
printReport(writer, request);
|
||||
return;
|
||||
}
|
||||
response.setContentType("text/xml");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
BufferedWriter out = new BufferedWriter(response.getWriter());
|
||||
ContentWriterInspector writer = new ContentWriterInspector(new ContentWriterXml(out, response.getCharacterEncoding()));
|
||||
printReport(writer, request);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
private void printReport(ContentWriterInspector writer, HttpServletRequest request) {
|
||||
WarpCoreReactor reactor = ZeroFungus.INSTANCE.getWarpCore();
|
||||
List<WarpReactPlasma> slots = reactor.listChilds(null);
|
||||
BufferedWriter out = new BufferedWriter(response.getWriter());
|
||||
try {
|
||||
ContentWriterInspector writer = new ContentWriterInspector(out, response.getCharacterEncoding());
|
||||
writer.startDocument();
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute("", "仙上主天", "", "", "𑀳𑁂𑀮𑀺𑀉𑁄𑀤𑁄𑀭𑁂𑀡𑀪𑀸𑀕");
|
||||
|
@ -81,7 +93,6 @@ public class WarpCorePlasmaInspectorServlet extends HttpServlet {
|
|||
} catch (SAXException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
|
||||
private void printSlotContract(ContentWriterInspector writer, WarpCorePlasmaIntermixChamber contract) throws SAXException {
|
||||
|
@ -131,10 +142,10 @@ public class WarpCorePlasmaInspectorServlet extends HttpServlet {
|
|||
writer.printTagEnd(Tag.requireSlots);
|
||||
}
|
||||
|
||||
public class ContentWriterInspector extends ContentWriterTagWrapper<Tag, ContentWriterXml> {
|
||||
public class ContentWriterInspector extends ContentWriterTagWrapper<Tag, ContentWriter> {
|
||||
|
||||
public ContentWriterInspector(Writer writer, String encoding) {
|
||||
super(new ContentWriterXml(writer, encoding), XMLConstants.XML_SCHEMA_NS_URI, XMLConstants.NULL_NS_URI);
|
||||
public ContentWriterInspector(ContentWriter writer) {
|
||||
super(writer, XMLConstants.NULL_NS_URI, XMLConstants.NULL_NS_URI);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue