SaxWriterImpl.java
/*
** Module : SaxWriterImpl
** Abstract : SAX writer specific features implementation.
**
** Copyright (c) 2013-2025, Golden Code Development Corporation.
**
** -#- -I- --Date-- ---------------------------------Description----------------------------------
** 001 EVL 20130208 Created initial version. Implementation is limited to the stubs to get the
** converted java code compiled.
** 002 CA 20130221 This resource doesn't have NAME attribute support.
** 003 EVL 20130320 Spelling fixes for comments.
** 004 EVK 20131001 Implement methods and class logic.
** 005 EVK 20140113 Added method resourceDelete to properly remove the object.
** 006 OM 20160129 Fixed ClassCastException in SET-OUTPUT-DESTINATION.
** 007 ECF 20160419 Fixed NPE in writeDataElement and writeEmptyElement.
** 008 IAS 20160707 Fixed the behavior to be more consistent with 4GL SAX-WRITER one.
** 009 CA 20211126 Fixed performance when writing a XML via FileOutputStreamWrapper.
** EVL 20221017 Added namespace repair option set.
** 010 CA 20230116 Avoid using handle.unwrap, handle.getReference or other BDT usage from within FWD runtime.
** 011 GBB 20230512 Logging methods replaced by CentralLogger/ConversionStatus.
** 012 AS 20250903 Honor the fragment attribute of the writer.
** 013 CA 20250516 Fixed issues with XML namespaces - these need to be scoped for each XML element, and
** ensure that when an element is written, it uses the prefix (if it exists).
** 014 CA 20250526 Namespace URIs and prefixes are looked up in all scopes, not just current scope.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.xml;
import java.io.*;
import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.function.*;
import java.util.logging.*;
import javax.xml.namespace.*;
import javax.xml.stream.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import com.goldencode.p2j.util.logging.*;
import org.codehaus.stax2.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import com.ctc.wstx.api.*;
import com.ctc.wstx.stax.*;
import com.goldencode.p2j.util.*;
import com.goldencode.p2j.util.ErrorManager;
import com.goldencode.p2j.util.Text;
import javanet.staxutils.*;
/**
* Implementation SAX-Writer specific features of the SAX objects.
*/
public class SaxWriterImpl
extends SaxEntityImpl
implements SaxWriter
{
/** default version of XML */
private static final String DEFAULT_XML_VERSION = "1.0";
/** Anonymous log instance. */
private static final CentralLogger LOG = CentralLogger.get(SaxWriterImpl.class.getName());
/** Current status of SAX-Writer */
private WriteStatus writeStatus = WriteStatus.SAX_WRITE_IDLE;
/** Current output source of SAX-Writer */
private OutputStream outputWrapper = null;
/** encoding of SAX-Writer */
private String encoding = "";
/** version of xml */
private String version = DEFAULT_XML_VERSION;
/** formatted attribute */
private boolean formatted = false;
/** strict attribute. */
private boolean strict = true;
/** fragment attribute. */
private boolean fragment = false;
/** standalone attribute. */
private Boolean standalone = null;
/** XML stream cursor writer.*/
private XMLStreamWriter writer = null;
/** Track the namespaces for each element. */
private ScopedNamespaceContext nscontext = null;
/**
* Default constructor.
*/
public SaxWriterImpl()
{
// no-op
}
/**
* Gets the value of the encoding attribute for the given SAX-Writer object.
*
* @return The character value of the encoding attribute.
*/
@Override
public character getEncoding()
{
return new character(encoding);
}
/**
* Sets the new value of the encoding attribute for the given SAX-Writer object.
*
* @param encoding
* The encoding value to be set for the given writer.
*/
@Override
public void setEncoding(String encoding)
{
setEncoding(new character(encoding));
}
/**
* Sets the new value of the encoding attribute for the given SAX-Writer object.
*
* @param encoding
* The encoding value to be set for the given writer.
*/
@Override
public void setEncoding(character encoding)
{
if (encoding.isUnknown())
{
invalidArgumentAssignError("ENCODING");
return;
}
if (!WriteStatus.nonWritableStatuses.contains(writeStatus))
{
invalidStatusAttributeError("ENCODING", writeStatus);
return;
}
this.encoding = encoding.toStringMessage();
}
/**
* Gets the value of the formatted attribute for the given SAX-Writer object. Formatted means
* extra space or carrage returns should be added to preserve the hierarchical view of the
* document.
*
* @return The <code>true</code> in case of formatted <code>false</code> otherwise.
*/
@Override
public logical getFormatted()
{
return new logical(formatted);
}
/**
* Sets the value of the formatted attribute for the given SAX-Writer object. Formatted means
* extra space or carriage returns should be added to preserve the hierarchical view of the
* document.
*
* @param isFormatted
* The <code>true</code> in case of formatted <code>false</code> otherwise.
*/
@Override
public void setFormatted(logical isFormatted)
{
if (!WriteStatus.nonWritableStatuses.contains(writeStatus))
{
invalidStatusAttributeError("FORMATTED", writeStatus);
return;
}
formatted = isFormatted.booleanValue();
}
/**
* Sets the value of the formatted attribute for the given SAX-Writer object. Formatted means
* extra space or carrage returns should be added to preserve the hierarchical view of the
* document.
*
* @param isFormatted
* The <code>true</code> in case of formatted <code>false</code> otherwise.
*/
@Override
public void setFormatted(boolean isFormatted)
{
setFormatted(new logical(isFormatted));
}
/**
* Gets the value of the strict attribute for the given SAX-Writer object. Strict means
* SAX-Writer should make well formed XML document. The default is true.
*
* @return The <code>true</code> in case of strict <code>false</code> otherwise.
*/
@Override
public logical getStrict()
{
return new logical(strict);
}
/**
* Sets the value of the strict attribute for the given SAX-Writer object. Strict means
* SAX-Writer should make well formed XML document. The default is true.
*
* @param isStrict
* The <code>true</code> in case of strict <code>false</code> otherwise.
*/
@Override
public void setStrict(logical isStrict)
{
if (!WriteStatus.nonWritableStatuses.contains(writeStatus))
{
invalidStatusAttributeError("STRICT", writeStatus);
return;
}
strict = isStrict.booleanValue();
}
/**
* Sets the value of the strict attribute for the given SAX-Writer object. Strict means
* SAX-Writer should make well formed XML document. The default is true.
*
* @param isStrict
* The <code>true</code> in case of strict <code>false</code> otherwise.
*/
@Override
public void setStrict(boolean isStrict)
{
setStrict(new logical(isStrict));
}
/**
* Gets the value of the fragment attribute for the given SAX-Writer object. Fragment means
* SAX-Writer output is part of the document or full.
*
* @return The <code>true</code> in case of fragment <code>false</code> for full document.
*/
@Override
public logical getFragment()
{
return new logical(fragment);
}
/**
* Sets the value of the fragment attribute for the given SAX-Writer object. Fragment means
* SAX-Writer output is part of the document or full.
*
* @param isFragment
* The <code>true</code> in case of fragment <code>false</code> for full document.
*/
@Override
public void setFragment(logical isFragment)
{
if (!WriteStatus.nonWritableStatuses.contains(writeStatus))
{
invalidStatusAttributeError("FRAGMENT", writeStatus);
return;
}
fragment = isFragment.booleanValue();
}
/**
* Sets the value of the fragment attribute for the given SAX-Writer object. Fragment means
* SAX-Writer output is part of the document or full.
*
* @param isFragment
* The <code>true</code> in case of fragment <code>false</code> for full document.
*/
@Override
public void setFragment(boolean isFragment)
{
setFragment(new logical(isFragment));
}
/**
* Gets the value of the standalone attribute for the given SAX-Writer object.
*
* @return The character value of the standalone attribute.
*/
@Override
public logical getStandalone()
{
return new logical(standalone);
}
/**
* Sets the value of the standalone attribute for the given SAX-Writer object.
*
* @param isStandalone
* The <code>true</code> in case of standalone <code>false</code> otherwise.
*/
@Override
public void setStandalone(logical isStandalone)
{
if (!WriteStatus.nonWritableStatuses.contains(writeStatus))
{
invalidStatusAttributeError("STANDALONE", writeStatus);
return;
}
standalone = isStandalone.toJavaType();
}
/**
* Sets the value of the standalone attribute for the given SAX-Writer object.
*
* @param isStandalone
* The <code>true</code> in case of standalone <code>false</code> otherwise.
*/
@Override
public void setStandalone(boolean isStandalone)
{
setStandalone(new logical(isStandalone));
}
/**
* Gets the value of the version attribute for the given SAX-Writer object.
*
* @return The character value of the version attribute.
*/
@Override
public character getVersion()
{
return new character(version);
}
/**
* Sets the new value of the version attribute for the given SAX-Writer object.
*
* @param version
* The version value to be set for the given writer.
*/
@Override
public void setVersion(String version)
{
setVersion(new character(version));
}
/**
* Sets the new value of the version attribute for the given SAX-Writer object.
*
* @param version
* The version value to be set for the given writer.
*/
@Override
public void setVersion(character version)
{
if (version.isUnknown())
{
invalidArgumentAssignError("VERSION");
return;
}
if (!WriteStatus.nonWritableStatuses.contains(writeStatus))
{
invalidStatusAttributeError("VERSION", writeStatus);
return;
}
this.version = version.toStringMessage();
}
/**
* Gets the value of the write-status attribute for the given SAX-Writer object. This is one
* of the SAX_WRITE_* constants defined by the {@link SaxWriter} interface.
* <p>
* Documentation states that the type of this attribute is character, but this is incorrect.
* The attribute's real type is integer, same as PARSE-STATUS for the SAX-Reader object.
*
* @return The integer value of the write-status attribute.
*/
@Override
public integer getWriteStatus()
{
return new integer(writeStatus.getStatus());
}
/**
* Adds namespace declaration to a tag in a XML document associated with SAX-Writer object.
*
* @param uri
* The URI namespace to add.
* @param prefix
* The prefix of the namespace to add.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical declareNamespace(Text uri, Text prefix)
{
if (!WriteStatus.writableBodyStatuses.contains(writeStatus))
{
invalidStatusMethodError("DECLARE-NAMESPACE", writeStatus);
return new logical(false);
}
String prefixStr = prefix.isUnknown() ? "" : prefix.toStringMessage();
try
{
writer.writeNamespace(prefixStr, uri.toStringMessage());
}
catch (XMLStreamException ignored)
{
writerOutputError("DECLARE-NAMESPACE");
return new logical(false);
}
return new logical(true);
}
/**
* Adds namespace declaration to a tag in a XML document associated with SAX-Writer object.
*
* @param uri
* The URI namespace to add.
* @param prefix
* The prefix of the namespace to add.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical declareNamespace(String uri, Text prefix)
{
return declareNamespace(new character(uri), prefix);
}
/**
* Adds namespace declaration to a tag in a XML document associated with SAX-Writer object.
*
* @param uri
* The URI namespace to add.
* @param prefix
* The prefix of the namespace to add.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical declareNamespace(Text uri, String prefix)
{
return declareNamespace(uri, new character(prefix));
}
/**
* Adds namespace declaration to a tag in a XML document associated with SAX-Writer object.
*
* @param uri
* The URI namespace to add.
* @param prefix
* The prefix of the namespace to add.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical declareNamespace(String uri, String prefix)
{
return declareNamespace(new character(uri), new character(prefix));
}
/**
* Adds namespace declaration to a tag in a XML document associated with SAX-Writer object.
*
* @param uri
* The URI namespace to add.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical declareNamespace(String uri)
{
return declareNamespace(new character(uri), new character());
}
/**
* Adds namespace declaration to a tag in a XML document associated with SAX-Writer object.
*
* @param uri
* The URI namespace to add.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical declareNamespace(Text uri)
{
return declareNamespace(uri, new character());
}
/**
* Closes the XML document associated with SAX-Writer object.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical endDocument()
{
if (!WriteStatus.writableStatuses.contains(writeStatus))
{
invalidStatusMethodError("END-DOCUMENT", writeStatus);
return new logical(false);
}
try
{
writer.writeEndDocument();
writer.close();
writeStatus = WriteStatus.SAX_WRITE_COMPLETE;
outputWrapper.close();
nscontext.endElement();
}
catch (XMLStreamException | IOException ignored)
{
writerOutputError("END-DOCUMENT");
return new logical(false);
}
return new logical(true);
}
/**
* Ends an XML node of the given name in a XML document associated with SAX-Writer object.
*
* @param name
* The name of the node to end.
* @param uri
* The URI namespace of the node to end.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical endElement(Text name, Text uri)
{
if (!BaseDataType.elementsOfType(character.class, uri, name))
{
invalidArgumentError("END-ELEMENT");
return new logical(false);
}
if (!WriteStatus.writableStatuses.contains(writeStatus))
{
invalidStatusMethodError("END-ELEMENT", writeStatus);
return new logical(false);
}
try
{
writer.writeEndElement();
nscontext.endElement();
writeStatus = WriteStatus.SAX_WRITE_ELEMENT;
}
catch (XMLStreamException ignored)
{
writerOutputError("END-ELEMENT");
return new logical(false);
}
return new logical(true);
}
/**
* Ends an XML node of the given name in a XML document associated with SAX-Writer object.
*
* @param name
* The name of the node to end.
* @param uri
* The URI namespace of the node to end.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical endElement(String name, Text uri)
{
return endElement(new character(name), uri);
}
/**
* Ends an XML node of the given name in a XML document associated with SAX-Writer object.
*
* @param name
* The name of the node to end.
* @param uri
* The URI namespace of the node to end.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical endElement(Text name, String uri)
{
return endElement(name, new character(uri));
}
/**
* Ends an XML node of the given name in a XML document associated with SAX-Writer object.
*
* @param name
* The name of the node to end.
* @param uri
* The URI namespace of the node to end.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical endElement(String name, String uri)
{
return endElement(new character(name), new character(uri));
}
/**
* Ends an XML node of the given name in a XML document associated with SAX-Writer object.
*
* @param name
* The name of the node to end.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical endElement(String name)
{
return endElement(new character(name), new character());
}
/**
* Ends an XML node of the given name in a XML document associated with SAX-Writer object.
*
* @param name
* The name of the node to end.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical endElement(Text name)
{
return endElement(name, new character());
}
/**
* Specifies the output destination of the XML document to be created by a SAX-Writer object.
*
* @param mode
* The type of the destination to write to. Can be 'FILE', 'STREAM', 'MEMPTR',
* 'STREAM-HANDLE' or 'LONGCHAR'.
* @param destination
* The appropriate object to write.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical setOutputDestination(String mode, Object destination)
{
return setOutputDestination(new character(mode), destination);
}
/**
* Specifies the output destination of the XML document to be created by a SAX-Writer object.
*
* @param mode
* The type of the destination to write to. Can be 'FILE', 'STREAM', 'MEMPTR',
* 'STREAM-HANDLE' or 'LONGCHAR'.
* @param destination
* The appropriate object to write.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical setOutputDestination(character mode, Object destination)
{
if (!WriteStatus.nonWritableStatuses.contains(writeStatus))
{
invalidStatusAttributeError("SET-OUTPUT-DESTINATION", writeStatus);
return new logical(false);
}
final String writeMode;
if (mode.isUnknown())
{
writeMode = "file";
}
else
{
writeMode = mode.getValue();
}
if ("file".equalsIgnoreCase(writeMode))
{
String fileName = null;
if (destination instanceof String)
{
fileName = (String) destination;
}
else if (destination instanceof Text)
{
fileName = ((Text) destination).getValue();
}
else
{
String msg = "The SET-OUTPUT-DESTINATION attribute on the SAX-WRITER widget has " +
"invalid arguments";
ErrorManager.recordOrShowError(4065, msg, false, true);
return new logical(false);
}
outputWrapper = new FileOutputStreamWrapper(fileName);
}
else if ("stream".equalsIgnoreCase(writeMode))
{
LOG.warning("Stream is not supported");
return new logical(false);
}
else if ("memptr".equalsIgnoreCase(writeMode))
{
outputWrapper = new MemptrOutputStream((memptr) destination);
}
else if ("stream-handle".equalsIgnoreCase(writeMode))
{
LOG.warning("Stream-handle is not supported");
return new logical(false);
}
else if ("longchar".equalsIgnoreCase(writeMode))
{
outputWrapper = new LongcharOutputStream((longchar) destination);
}
else
{
invalidReadWriteModeError("SET-OUTPUT-DESTINATION");
return new logical(false);
}
return new logical(true);
}
/**
* Creates the XML document with the prolog information.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startDocument()
{
if (!WriteStatus.nonWritableStatuses.contains(writeStatus))
{
invalidStatusMethodError("START-DOCUMENT", writeStatus);
return new logical(false);
}
if (outputWrapper == null)
{
String msg = "START-DOCUMENT was unable to open the output destination. " +
"No output destination was specified";
ErrorManager.recordOrShowError(14610, msg, false, false, false);
}
XMLOutputFactory2 output = (XMLOutputFactory2) XMLOutputFactory2.newFactory();
output.configureForSpeed();
output.setProperty(WstxOutputProperties.P_OUTPUT_VALIDATE_STRUCTURE, false);
output.setProperty(WstxOutputProperties.P_AUTOMATIC_END_ELEMENTS, false);
output.setProperty(WstxOutputFactory.P_AUTOMATIC_EMPTY_ELEMENTS, false);
output.setProperty("javax.xml.stream.isRepairingNamespaces", true);
try
{
writer = output.createXMLStreamWriter(outputWrapper);
if (formatted)
{
writer = new IndentingXMLStreamWriter(writer)
{
int depth = 0;
@Override
protected void beforeEndElement()
{
if (depth == 1 && writeStatus == WriteStatus.SAX_WRITE_TAG)
{
writeLn();
}
super.beforeEndElement();
}
@Override
protected void afterEndElement()
{
super.afterEndElement();
if (--depth == 0)
{
writeLn();
}
}
@Override
protected void afterStartElement()
{
super.afterStartElement();
depth++;
}
protected void writeLn()
{
try
{
writeNewLine(0);
}
catch (XMLStreamException ignore)
{
}
}
};
}
nscontext = new ScopedNamespaceContext();
nscontext.startElement();
writer.setNamespaceContext(nscontext);
}
catch (XMLStreamException ignored)
{
writerOutputError("START-DOCUMENT");
return new logical(false);
}
if (!fragment)
{
try
{
writeXMLDeclaration(writer, version, encoding, standalone == null ? null : standalone);
}
catch (XMLStreamException ignored) {
writerOutputError("START-DOCUMENT");
return new logical(false);
}
}
writeStatus = WriteStatus.SAX_WRITE_BEGIN;
return new logical(true);
}
/**
* Starts the XML node according to the specified name, namespace URI and handle of the SAX
* attribute object.
*
* @param name
* The name of the element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startElement(Text name)
{
return startElement(name, new character(), null);
}
/**
* Starts the XML node according to the specified name, namespace URI and handle of the SAX
* attribute object.
*
* @param name
* The name of the element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startElement(String name)
{
return startElement(new character(name), new character(), null);
}
/**
* Starts the XML node according to the specified name, namespace URI and handle of the SAX
* attribute object.
*
* @param name
* The name of the element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startElement(Text name, handle handle)
{
return startElement(name, new character(), handle);
}
/**
* Starts the XML node according to the specified name, namespace URI and handle of the SAX
* attribute object.
*
* @param name
* The name of the element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startElement(String name, handle handle)
{
return startElement(new character(name), new character(), handle);
}
/**
* Starts the XML node according to the specified name, namespace URI and handle of the SAX
* attribute object.
*
* @param name
* The name of the element.
* @param uri
* The namespace URI of the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startElement(Text name, Text uri)
{
return startElement(new character(name), uri, null);
}
/**
* Starts the XML node according to the specified name, namespace URI and handle of the SAX
* attribute object.
*
* @param name
* The name of the element.
* @param uri
* The namespace URI of the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startElement(String name, Text uri)
{
return startElement(new character(name), uri, null);
}
/**
* Starts the XML node according to the specified name, namespace URI and handle of the SAX
* attribute object.
*
* @param name
* The name of the element.
* @param uri
* The namespace URI of the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startElement(Text name, String uri)
{
return startElement(name, new character(uri), null);
}
/**
* Starts the XML node according to the specified name, namespace URI and handle of the SAX
* attribute object.
*
* @param name
* The name of the element.
* @param uri
* The namespace URI of the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startElement(String name, String uri)
{
return startElement(new character(name), new character(uri), null);
}
/**
* Starts the XML node according to the specified name, namespace URI and handle of the SAX
* attribute object.
*
* @param name
* The name of the element.
* @param uri
* The namespace URI of the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startElement(String name, Text uri, handle handle)
{
return startElement(new character(name), uri, handle);
}
/**
* Starts the XML node according to the specified name, namespace URI and handle of the SAX
* attribute object.
*
* @param name
* The name of the element.
* @param uri
* The namespace URI of the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startElement(Text name, String uri, handle handle)
{
return startElement(name, new character(uri), handle);
}
/**
* Starts the XML node according to the specified name, namespace URI and handle of the SAX
* attribute object.
*
* @param name
* The name of the element.
* @param uri
* The namespace URI of the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startElement(String name, String uri, handle handle)
{
return startElement(new character(name), new character(uri), handle);
}
/**
* Adding the single attribute to the start tag in the XML document if applied for SAX writer
* object. For SAX attributes object inserts attribute and its name into SAX attributes object.
*
* @param name
* The attribute name to insert.
* @param value
* The attribute value to insert.
* @param uri
* The URI of the attribute to insert or '?' for unknown value.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical insertAttribute(Text name, Text value, Text uri)
{
if (!BaseDataType.elementsOfType(character.class, uri, name, value))
{
invalidArgumentError("INSERT-ATTRIBUTE");
return new logical(false);
}
if (name.isUnknown() || value.isUnknown())
{
invalidArgumentError("INSERT-ATTRIBUTE");
return new logical(false);
}
try
{
if (uri.isUnknown())
{
String attr = name.toStringMessage();
if (attr.startsWith("xmlns:"))
{
String xmlns = attr.substring(attr.indexOf(':') + 1);
nscontext.setPrefix(xmlns, value.toStringMessage());
}
writer.writeAttribute(attr, value.toStringMessage());
}
else
{
writer.writeAttribute(uri.toStringMessage(),
name.toStringMessage(),
value.toStringMessage());
}
}
catch (XMLStreamException ignored)
{
writerOutputError("INSERT-ATTRIBUTE");
return new logical(false);
}
return new logical(true);
}
/**
* Starts the XML node according to the specified name, namespace URI and handle of the SAX
* attribute object.
*
* @param name
* The name of the element.
* @param uri
* The namespace URI of the given element.
* @param attr
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical startElement(Text name, Text uri, handle attr)
{
if (!BaseDataType.elementsOfType(character.class, uri, name))
{
invalidArgumentError("START-ELEMENT");
return new logical(false);
}
if (!WriteStatus.writableStatuses.contains(writeStatus))
{
invalidStatusMethodError("START-ELEMENT", writeStatus);
return new logical(false);
}
if (name.isUnknown())
{
invalidArgumentError("START-ELEMENT");
return new logical(false);
}
if (attr != null && !attr.isUnknown() && !handle.isHandleTypeOf(attr, SaxAttributes.class))
{
invalidArgumentError("START-ELEMENT");
return new logical(false);
}
try
{
String uriStr = uri.isUnknown() ? "" : uri.toStringMessage();
String prefix = nscontext.getPrefix(uriStr);
if (prefix == null)
{
writer.setDefaultNamespace(uriStr);
writer.writeStartElement(uriStr, name.toStringMessage());
}
else
{
writer.writeStartElement(prefix, name.toStringMessage(), uriStr);
}
writeStatus = WriteStatus.SAX_WRITE_TAG;
nscontext.startElement();
if (attr == null || attr.isUnknown())
{
return new logical(true);
}
Attributes attributes = ((SaxAttributesImpl) attr.getResource()).getAttributes();
for (int i = 0; i < attributes.getLength(); i++)
{
logical res = insertAttribute(attributes.getLocalName(i), attributes.getValue(i));
if (!res.booleanValue())
{
return res;
}
}
}
catch (XMLStreamException ignored)
{
writerOutputError("WRITE-ELEMENT");
return new logical(false);
}
return new logical(true);
}
/**
* Adds CDATA block to the XML document crating by SAX-Writer object.
*
* @param cdataBlock
* The data to be written with CDATA block.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeCdata(String cdataBlock)
{
return writeCdata(new character(cdataBlock));
}
/**
* Adds CDATA block to the XML document crating by SAX-Writer object.
*
* @param cdataBlock
* The data to be written with CDATA block.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeCdata(Text cdataBlock)
{
if (!WriteStatus.writableStatuses.contains(writeStatus))
{
invalidStatusMethodError("WRITE-CDATA", writeStatus);
return new logical(false);
}
if (cdataBlock.isUnknown())
{
invalidArgumentError("WRITE-CDATA");
return new logical(false);
}
try
{
writer.writeCData(cdataBlock.toStringMessage());
}
catch (XMLStreamException ignored)
{
writerOutputError("WRITE-CDATA");
return new logical(false);
}
return new logical(true);
}
/**
* Adds character data to the XML document crating by SAX-Writer object.
*
* @param chardata
* The character or longchar data to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeCharacters(String chardata)
{
return writeCharacters(new character(chardata));
}
/**
* Adds character data to the XML document crating by SAX-Writer object.
*
* @param chardata
* The character or longchar data to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeCharacters(Text chardata)
{
if (!WriteStatus.writableStatuses.contains(writeStatus))
{
invalidStatusMethodError("WRITE-CHARACTERS", writeStatus);
return new logical(false);
}
if (chardata.isUnknown())
{
invalidArgumentError("WRITE-CHARACTERS");
return new logical(false);
}
try
{
writer.writeCharacters(chardata.toStringMessage());
writeStatus = WriteStatus.SAX_WRITE_CONTENT;
}
catch (XMLStreamException ignored)
{
writerOutputError("WRITE-CHARACTERS");
return new logical(false);
}
return new logical(true);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(Text name, Text chardata)
{
return writeDataElement(name, chardata, new character(), null);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(String name, Text chardata)
{
return writeDataElement(new character(name), chardata, new character(), null);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(Text name, String chardata)
{
return writeDataElement(name, new character(chardata), new character(), null);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(String name, String chardata)
{
return writeDataElement(new character(name), new character(chardata), new character(),
null);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(Text name, Text chardata, Text uri)
{
return writeDataElement(name, chardata, uri, null);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(String name, Text chardata, Text uri)
{
return writeDataElement(new character(name), chardata, uri, null);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(Text name, String chardata, Text uri)
{
return writeDataElement(name, new character(chardata), uri, null);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(String name, String chardata, Text uri)
{
return writeDataElement(new character(name), new character(chardata), uri, null);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(Text name, Text chardata, String uri)
{
return writeDataElement(name, chardata, new character(uri), null);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(String name, Text chardata, String uri)
{
return writeDataElement(new character(name), chardata, new character(uri), null);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(Text name, String chardata, String uri)
{
return writeDataElement(name, new character(chardata), new character(uri), null);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(String name, String chardata, String uri)
{
return writeDataElement(new character(name), new character(chardata),
new character(uri), null);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(Text name, Text chardata, handle handle)
{
return writeDataElement(name, chardata, new character(), handle);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(String name, Text chardata, handle handle)
{
return writeDataElement(new character(name), chardata, new character(), handle);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(Text name, String chardata, handle handle)
{
return writeDataElement(name, new character(chardata), new character(), handle);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(String name, String chardata, handle handle)
{
return writeDataElement(new character(name), new character(chardata), new character(),
handle);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(String name, Text chardata, Text uri, handle handle)
{
return writeDataElement(new character(name), chardata, uri, handle);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(Text name, String chardata, Text uri, handle handle)
{
return writeDataElement(name, new character(chardata), uri, handle);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(Text name, Text chardata, String uri, handle handle)
{
return writeDataElement(name, chardata, new character(uri), handle);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(String name, String chardata, Text uri, handle handle)
{
return writeDataElement(new character(name), new character(chardata), uri, handle);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(String name, Text chardata, String uri, handle handle)
{
return writeDataElement(new character(name), chardata, new character(uri), handle);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(Text name, String chardata, String uri, handle handle)
{
return writeDataElement(name, new character(chardata), new character(uri), handle);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
* @param handle
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(String name, String chardata, String uri, handle handle)
{
return writeDataElement(new character(name), new character(chardata),
new character(uri), handle);
}
/**
* Creates complete XML node with a given SAX-Writer object.
*
* @param name
* The name of the element.
* @param chardata
* The XML text to write for the given element.
* @param uri
* The namespace URI of the given element.
* @param attr
* The handle of the SAX-Attribute object to be added into XML document.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeDataElement(Text name, Text chardata, Text uri, handle attr)
{
if (!BaseDataType.elementsOfType(character.class, uri, name))
{
invalidArgumentError("WRITE-DATA-ELEMENT");
return new logical(false);
}
if (!WriteStatus.writableStatuses.contains(writeStatus))
{
invalidStatusMethodError("WRITE-DATA-ELEMENT", writeStatus);
return new logical(false);
}
if (name.isUnknown())
{
invalidArgumentError("WRITE-DATA-ELEMENT");
return new logical(false);
}
if (attr != null && !attr.isUnknown() && !handle.isHandleTypeOf(attr, SaxAttributes.class))
{
invalidArgumentError("WRITE-DATA-ELEMENT");
return new logical(false);
}
try
{
String uriStr = uri.isUnknown() ? "" : uri.toStringMessage();
String prefix = nscontext.getPrefix(uriStr);
if (prefix != null)
{
writer.writeStartElement(prefix, name.toStringMessage(), uriStr);
}
else
{
// for this node, ensure the uri is the default namespace, so it will not use a prefix
writer.setDefaultNamespace(uriStr);
writer.writeStartElement(uriStr, name.toStringMessage());
writer.setDefaultNamespace(null);
}
writeStatus = WriteStatus.SAX_WRITE_TAG;
if (attr != null)
{
Attributes attributes = ((SaxAttributesImpl) attr.getResource()).getAttributes();
for(int i = 0; i < attributes.getLength(); i++)
{
logical res = insertAttribute(attributes.getLocalName(i), attributes.getValue(i));
if (!res.booleanValue())
{
return res;
}
}
}
if (!chardata.isUnknown())
{
writer.writeCharacters(chardata.toStringMessage());
}
writer.writeEndElement();
writeStatus = WriteStatus.SAX_WRITE_ELEMENT;
}
catch (XMLStreamException ignored)
{
writerOutputError("WRITE-EMPTY-ELEMENT");
return new logical(false);
}
return new logical(true);
}
/**
* Adds character data to the XML document crating by SAX-Writer object.
*
* @param chardata
* The character or longchar data to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeFragment(String chardata)
{
return writeFragment(new character(chardata));
}
/**
* Adds character data to the XML document crating by SAX-Writer object.
*
* @param chardata
* The character or longchar data to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeFragment(Text chardata)
{
if (!WriteStatus.writableStatuses.contains(writeStatus))
{
invalidStatusMethodError("WRITE-FRAGMENT", writeStatus);
return new logical(false);
}
if (chardata.isUnknown())
{
invalidArgumentError("WRITE-FRAGMENT");
return new logical(false);
}
String content = chardata.toStringMessage();
return writeCharacterData(content);
}
/**
* Adds character data to the XML document crating by SAX-Writer object.
*
* @param content
* string to write.
*
* @return {@code true} if success, {@code false} otherwise.
*/
private logical writeCharacterData(String content)
{
try
{
writer.writeCharacters(content);
writeStatus = WriteStatus.SAX_WRITE_CONTENT;
}
catch (XMLStreamException ignored)
{
writerOutputError("WRITE-FRAGMENT");
return new logical(false);
}
return new logical(true);
}
/**
* Adds character data to the XML document crating by SAX-Writer object.
*
* @param xhandle
* The valid X-Nodereference handle containing XML text.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeFragment(handle xhandle)
{
if (!WriteStatus.writableStatuses.contains(writeStatus))
{
invalidStatusMethodError("WRITE-FRAGMENT", writeStatus);
return new logical(false);
}
if (!XEntityImpl.isXNodeHandle(xhandle) || !XEntityImpl.isXNodeHandleInitialized(xhandle))
{
invalidArgumentError("WRITE-FRAGMENT");
return new logical(false);
}
Node node = ((XEntityImpl) xhandle.get()).getNode();
String nodeXML;
try
{
nodeXML = serializeNodeToString(node);
}
catch (TransformerException ignored)
{
invalidArgumentError("WRITE-FRAGMENT");
return new logical(false);
}
return writeCharacterData(nodeXML);
}
/**
* Closes the open stream and resets the SAX-Writer object to the default state.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical reset()
{
if (outputWrapper != null)
{
try
{
outputWrapper.close();
}
catch (IOException ignored)
{
// no-op
}
}
writeStatus = WriteStatus.SAX_WRITE_IDLE;
return new logical(true);
}
/**
* Adds comment to the XML document crating by SAX-Writer object.
*
* @param comment
* The character or longchar text comment to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeComment(String comment)
{
return writeComment(new character(comment));
}
/**
* Adds comment to the XML document crating by SAX-Writer object.
*
* @param comment
* The character or longchar text comment to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeComment(Text comment)
{
if (!WriteStatus.writableStatuses.contains(writeStatus))
{
invalidStatusMethodError("WRITE-COMMENT", writeStatus);
return new logical(false);
}
if (comment.isUnknown())
{
invalidArgumentError("WRITE-COMMENT");
return new logical(false);
}
try
{
writer.writeComment(comment.toStringMessage());
}
catch (XMLStreamException ignored)
{
writerOutputError("WRITE-COMMENT");
return new logical(false);
}
return new logical(true);
}
/**
* Creates an empty node in a given SAX-Writer object.
*
* @param name
* The character or longchar element name to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEmptyElement(Text name)
{
return writeEmptyElement(name, new character(), null);
}
/**
* Creates an empty node in a given SAX-Writer object.
*
* @param name
* The character or longchar element name to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEmptyElement(String name)
{
return writeEmptyElement(new character(name), new character(), null);
}
/**
* Creates an empty node in a given SAX-Writer object.
*
* @param name
* The character or longchar element name to be written.
* @param uri
* The character or longchar element URI to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEmptyElement(Text name, Text uri)
{
return writeEmptyElement(name, uri, null);
}
/**
* Creates an empty node in a given SAX-Writer object.
*
* @param name
* The character or longchar element name to be written.
* @param uri
* The character or longchar element URI to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEmptyElement(String name, Text uri)
{
return writeEmptyElement(new character(name), uri, null);
}
/**
* Creates an empty node in a given SAX-Writer object.
*
* @param name
* The character or longchar element name to be written.
* @param uri
* The character or longchar element URI to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEmptyElement(Text name, String uri)
{
return writeEmptyElement(name, new character(uri), null);
}
/**
* Creates an empty node in a given SAX-Writer object.
*
* @param name
* The character or longchar element name to be written.
* @param uri
* The character or longchar element URI to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEmptyElement(String name, String uri)
{
return writeEmptyElement(new character(name), new character(uri), null);
}
/**
* Creates an empty node in a given SAX-Writer object.
*
* @param name
* The character or longchar element name to be written.
* @param attr
* The handle of the SAX-Attributes object to be used.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEmptyElement(Text name, handle attr)
{
return writeEmptyElement(name, new character(), attr);
}
/**
* Creates an empty node in a given SAX-Writer object.
*
* @param name
* The character or longchar element name to be written.
* @param attr
* The handle of the SAX-Attributes object to be used.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEmptyElement(String name, handle attr)
{
return writeEmptyElement(new character(name), new character(), attr);
}
/**
* Creates an empty node in a given SAX-Writer object.
*
* @param name
* The character or longchar element name to be written.
* @param uri
* The character or longchar element URI to be written.
* @param attr
* The handle of the SAX-Attributes object to be used.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEmptyElement(String name, Text uri, handle attr)
{
return writeEmptyElement(new character(name), uri, attr);
}
/**
* Creates an empty node in a given SAX-Writer object.
*
* @param name
* The character or longchar element name to be written.
* @param uri
* The character or longchar element URI to be written.
* @param attr
* The handle of the SAX-Attributes object to be used.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEmptyElement(Text name, String uri, handle attr)
{
return writeEmptyElement(name, new character(uri), attr);
}
/**
* Creates an empty node in a given SAX-Writer object.
*
* @param name
* The character or longchar element name to be written.
* @param uri
* The character or longchar element URI to be written.
* @param attr
* The handle of the SAX-Attributes object to be used.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEmptyElement(String name, String uri, handle attr)
{
return writeEmptyElement(new character(name), new character(uri), attr);
}
/**
* Creates an empty node in a given SAX-Writer object.
*
* @param name
* The character or longchar element name to be written.
* @param uri
* The character or longchar element URI to be written.
* @param attr
* The handle of the SAX-Attributes object to be used.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEmptyElement(Text name, Text uri, handle attr)
{
if (!BaseDataType.elementsOfType(character.class, uri, name))
{
invalidArgumentError("WRITE-EMPTY-ELEMENT");
return new logical(false);
}
if (!WriteStatus.writableStatuses.contains(writeStatus))
{
invalidStatusMethodError("WRITE-EMPTY-ELEMENT", writeStatus);
return new logical(false);
}
if (name.isUnknown())
{
invalidArgumentError("WRITE-EMPTY-ELEMENT");
return new logical(false);
}
if (attr != null && !attr.isUnknown() && !handle.isHandleTypeOf(attr, SaxAttributes.class))
{
invalidArgumentError("WRITE-EMPTY-ELEMENT");
return new logical(false);
}
try
{
String uriStr = uri.isUnknown() ? null : uri.toStringMessage();
writer.writeEmptyElement(uriStr, name.toStringMessage());
writeStatus = WriteStatus.SAX_WRITE_TAG;
if (attr != null)
{
Attributes attributes = ((SaxAttributesImpl) attr.getResource()).getAttributes();
for (int i = 0; i < attributes.getLength(); i++)
{
logical res = insertAttribute(attributes.getLocalName(i), attributes.getValue(i));
if (!res.booleanValue())
{
return res;
}
}
}
}
catch (XMLStreamException ignored)
{
writerOutputError("WRITE-EMPTY-ELEMENT");
return new logical(false);
}
return new logical(true);
}
/**
* Adds an entity referenc to the XML document associated with given SAX-Writer object.
*
* @param value
* The character or longchar value to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEntityRef(String value)
{
return writeEntityRef(new character(value));
}
/**
* Adds an entity referenc to the XML document associated with given SAX-Writer object.
*
* @param value
* The character or longchar value to be written.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeEntityRef(Text value)
{
if (!WriteStatus.writableStatuses.contains(writeStatus))
{
invalidStatusMethodError("WRITE-ENTITY-REF", writeStatus);
return new logical(false);
}
if (value.isUnknown())
{
invalidArgumentError("WRITE-ENTITY-REF");
return new logical(false);
}
try
{
writer.writeEntityRef(value.toStringMessage());
}
catch (XMLStreamException ignored)
{
writerOutputError("WRITE-ENTITY-REF");
return new logical(false);
}
return new logical(true);
}
/**
* Adds an external DTD reference to the XML document associated with a SAX-Writer object.
*
* @param name
* The character or longchar name of the document root node.
* @param systemId
* The character or longchar system ID of the DTD.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeExternalDtd(Text name, Text systemId)
{
return writeExternalDtd(name, systemId, new character());
}
/**
* Adds an external DTD reference to the XML document associated with a SAX-Writer object.
*
* @param name
* The character or longchar name of the document root node.
* @param systemId
* The character or longchar system ID of the DTD.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeExternalDtd(String name, Text systemId)
{
return writeExternalDtd(new character(name), systemId, new character());
}
/**
* Adds an external DTD reference to the XML document associated with a SAX-Writer object.
*
* @param name
* The character or longchar name of the document root node.
* @param systemId
* The character or longchar system ID of the DTD.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeExternalDtd(Text name, String systemId)
{
return writeExternalDtd(name, new character(systemId), new character());
}
/**
* Adds an external DTD reference to the XML document associated with a SAX-Writer object.
*
* @param name
* The character or longchar name of the document root node.
* @param systemId
* The character or longchar system ID of the DTD.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeExternalDtd(String name, String systemId)
{
return writeExternalDtd(new character(name), new character(systemId), new character());
}
/**
* Adds an external DTD reference to the XML document associated with a SAX-Writer object.
*
* @param name
* The character or longchar name of the document root node.
* @param systemId
* The character or longchar system ID of the DTD.
* @param publicId
* The character or longchar public ID of the DTD.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeExternalDtd(String name, Text systemId, Text publicId)
{
return writeExternalDtd(new character(name), systemId, publicId);
}
/**
* Adds an external DTD reference to the XML document associated with a SAX-Writer object.
*
* @param name
* The character or longchar name of the document root node.
* @param systemId
* The character or longchar system ID of the DTD.
* @param publicId
* The character or longchar public ID of the DTD.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeExternalDtd(Text name, String systemId, Text publicId)
{
return writeExternalDtd(name, new character(systemId), publicId);
}
/**
* Adds an external DTD reference to the XML document associated with a SAX-Writer object.
*
* @param name
* The character or longchar name of the document root node.
* @param systemId
* The character or longchar system ID of the DTD.
* @param publicId
* The character or longchar public ID of the DTD.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeExternalDtd(String name, String systemId, Text publicId)
{
return writeExternalDtd(new character(name), new character(systemId), publicId);
}
/**
* Adds an external DTD reference to the XML document associated with a SAX-Writer object.
*
* @param name
* The character or longchar name of the document root node.
* @param systemId
* The character or longchar system ID of the DTD.
* @param publicId
* The character or longchar public ID of the DTD.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeExternalDtd(Text name, Text systemId, String publicId)
{
return writeExternalDtd(name, systemId, new character(publicId));
}
/**
* Adds an external DTD reference to the XML document associated with a SAX-Writer object.
*
* @param name
* The character or longchar name of the document root node.
* @param systemId
* The character or longchar system ID of the DTD.
* @param publicId
* The character or longchar public ID of the DTD.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeExternalDtd(String name, Text systemId, String publicId)
{
return writeExternalDtd(new character(name), systemId, new character(publicId));
}
/**
* Adds an external DTD reference to the XML document associated with a SAX-Writer object.
*
* @param name
* The character or longchar name of the document root node.
* @param systemId
* The character or longchar system ID of the DTD.
* @param publicId
* The character or longchar public ID of the DTD.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeExternalDtd(Text name, String systemId, String publicId)
{
return writeExternalDtd(name, new character(systemId), new character(publicId));
}
/**
* Adds an external DTD reference to the XML document associated with a SAX-Writer object.
*
* @param name
* The character or longchar name of the document root node.
* @param systemId
* The character or longchar system ID of the DTD.
* @param publicId
* The character or longchar public ID of the DTD.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeExternalDtd(String name, String systemId, String publicId)
{
return writeExternalDtd(new character(name), new character(systemId),
new character(publicId));
}
/**
* Adds an external DTD reference to the XML document associated with a SAX-Writer object.
*
* @param name
* The character or longchar name of the document root node.
* @param systemId
* The character or longchar system ID of the DTD.
* @param publicId
* The character or longchar public ID of the DTD.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeExternalDtd(Text name, Text systemId, Text publicId)
{
if (writeStatus != WriteStatus.SAX_WRITE_BEGIN)
{
invalidStatusMethodError("WRITE-EXTERNAL-DTD", writeStatus);
return new logical(false);
}
if (name.isUnknown())
{
invalidArgumentError("WRITE-EXTERNAL-DTD");
return new logical(false);
}
if (systemId.isUnknown())
{
invalidArgumentError("WRITE-EXTERNAL-DTD");
return new logical(false);
}
StringBuilder xmlDeclarationBuilder = new StringBuilder();
xmlDeclarationBuilder.append("<!DOCTYPE ");
xmlDeclarationBuilder.append(name.toStringMessage());
xmlDeclarationBuilder.append(' ');
xmlDeclarationBuilder.append(systemId.toStringMessage());
if (!publicId.isUnknown())
{
xmlDeclarationBuilder.append(" \"");
xmlDeclarationBuilder.append(publicId.toStringMessage());
xmlDeclarationBuilder.append('"');
}
xmlDeclarationBuilder.append(">\n");
try
{
writer.writeDTD(xmlDeclarationBuilder.toString());
}
catch (XMLStreamException ignored)
{
writerOutputError("WRITE-EXTERNAL-DTD");
return new logical(false);
}
return new logical(true);
}
/**
* Creates a processing instruction node in XML document for given SAX-Writer object.
*
* @param target
* The character or longchar target of the processing instruction.
* @param data
* The character or longchar data associated with the processing instruction.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeProcessingInstruction(String target, Text data)
{
return writeProcessingInstruction(new character(target), data);
}
/**
* Creates a processing instruction node in XML document for given SAX-Writer object.
*
* @param target
* The character or longchar target of the processing instruction.
* @param data
* The character or longchar data associated with the processing instruction.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeProcessingInstruction(Text target, String data)
{
return writeProcessingInstruction(target, new character(data));
}
/**
* Creates a processing instruction node in XML document for given SAX-Writer object.
*
* @param target
* The character or longchar target of the processing instruction.
* @param data
* The character or longchar data associated with the processing instruction.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeProcessingInstruction(String target, String data)
{
return writeProcessingInstruction(new character(target), new character(data));
}
/**
* Creates a processing instruction node in XML document for given SAX-Writer object.
*
* @param target
* The character or longchar target of the processing instruction.
* @param data
* The character or longchar data associated with the processing instruction.
*
* @return The <code>true</code> in case of success <code>false</code> otherwise.
*/
@Override
public logical writeProcessingInstruction(Text target, Text data)
{
if (!WriteStatus.writableStatuses.contains(writeStatus))
{
invalidStatusMethodError("WRITE-PROCESSING-INSTRUCTION", writeStatus);
return new logical(false);
}
if (target.isUnknown())
{
invalidArgumentError("WRITE-PROCESSING-INSTRUCTION");
return new logical(false);
}
if (data.isUnknown())
{
invalidArgumentError("WRITE-PROCESSING-INSTRUCTION");
return new logical(false);
}
try
{
writer.writeProcessingInstruction(target.toStringMessage(), data.toStringMessage());
}
catch (XMLStreamException ignored)
{
writerOutputError("WRITE-PROCESSING-INSTRUCTION");
return new logical(false);
}
return new logical(true);
}
/**
* Check if this resource supports the NAME attribute.
*
* @return Always <code>false</code>.
*/
@Override
protected boolean hasName()
{
return false;
}
/**
* Delete the resource.
*
* @return <code>true</code> if the resource was deleted.
*/
@Override
protected boolean resourceDelete()
{
if (writer != null)
{
try
{
writer.close();
}
catch (XMLStreamException e)
{
LOG.log(Level.SEVERE, "SaxWriterImpl", e);
}
}
isValid = false;
writer = null;
nscontext = null;
return true;
}
/**
* This method is used to serialize Node from DOM to string.
*
* @param node
* Node instance from DOM model.
*
* @return Text representation of the node.
*
* @throws TransformerFactoryConfigurationError
* If an error occurs writing the identifier.
* @throws TransformerException
* If an error occurs writing the identifier.
*/
static String serializeNodeToString(Node node)
throws TransformerFactoryConfigurationError,
TransformerException
{
StreamResult xmlOutput = new StreamResult(new StringWriter());
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(new DOMSource(node), xmlOutput);
return xmlOutput.getWriter().toString();
}
/**
* This method is used to write the XML document declaration at the beginning of an XML
* document. This version is used when the standalone attribute is to be written as the
* XMLStreamWriter provides no way for writing this attribute.
*
* @param outputWriter
* XMLStreamWriter instance.
* @param xmlVersion
* Xml version which will specify in xml header.
* @param encodingName
* encoding which will specify in xml header.
* @param standalone
* standalone flag.
*
* @throws XMLStreamException
* If an error occurs writing the identifier.
*/
public static void writeXMLDeclaration(XMLStreamWriter outputWriter,
String xmlVersion,
String encodingName,
Boolean standalone)
throws XMLStreamException
{
if (xmlVersion == null || xmlVersion.trim().isEmpty())
{
xmlVersion = DEFAULT_XML_VERSION;
}
StringBuilder xmlDeclarationBuilder = new StringBuilder();
xmlDeclarationBuilder.append("<?xml version=\"");
xmlDeclarationBuilder.append(xmlVersion);
xmlDeclarationBuilder.append('"');
if (encodingName != null && !"".equals(encodingName))
{
xmlDeclarationBuilder.append(" encoding=\"");
xmlDeclarationBuilder.append(encodingName);
xmlDeclarationBuilder.append('"');
}
if (standalone != null)
{
xmlDeclarationBuilder.append(" standalone=\"");
xmlDeclarationBuilder.append(standalone ? "yes" : "no");
xmlDeclarationBuilder.append('"');
}
xmlDeclarationBuilder.append("?>");
//Work around to avoid the angle brackets getting escaped.
outputWriter.writeDTD(xmlDeclarationBuilder.toString());
}
/**
* Special wrapper to wrap write to file in lazy mode. It's means that first try to write
* will check if file is available.
*/
private static class FileOutputStreamWrapper
extends OutputStream
{
/** File name.*/
private final String fileName;
/** Lazy initialization flag.*/
private volatile boolean isStarted;
/** Buffered output Stream.*/
private Stream stream;
/**
* Constructor accepting a file name, which will read after first call.
*
* @param source
* A file name.
*/
private FileOutputStreamWrapper(String source)
{
isStarted = false;
fileName = source;
}
/**
* Write one byte into the stream.
* @param b
* the data to write.
* @throws IOException
*/
@Override
public void write(int b)
throws IOException
{
if (!isStarted)
{
init(true);
}
stream.writeByte((byte) b);
}
/**
* Writes the entire contents of the specified byte array to this output stream.
*
* @param b
* The byte array to write.
*
* @throws IOException
* if an I/O error occurs. In particular, an IOException may be
* thrown if the output stream has been closed.
* @throws NullPointerException
* if the array is <code>null</code>.
*/
@Override
public void write(byte[] b)
throws IOException,
NullPointerException
{
write(b, 0, b.length);
}
/**
* Writes <code>len</code> bytes from the specified byte array starting
* at offset <code>off</code> in this output stream. Element b[off] is
* the first byte written and b[off+len-1] is the last byte written.
*
* @param b
* The array of bytes to write.
* @param off
* the start offset in the array.
* @param len
* the number of bytes to write.
*
* @throws IOException
* if an I/O error occurs. In particular, an IOException may be
* thrown if the output stream has been closed.
* @throws NullPointerException
* if the array is <code>null</code>.
* @throws IndexOutOfBoundsException
* if the offset or length are negative, or if offset + length
* is larger than the length of the array.
*/
@Override
public void write(byte[] b, int off, int len)
throws IOException,
NullPointerException,
IndexOutOfBoundsException
{
if (!isStarted)
{
init(true);
}
stream.write(b, off, len);
}
/**
* Close current stream and reset state.
*/
@Override
public void close()
throws IOException
{
if (stream != null)
{
stream.close();
isStarted = false;
}
}
/**
* Initialization method which creates stream wrapper.
*
* @param canWrite
* if {@code true} than file will open in read/write mode, otherwise only in
* read mode.
*
* @throws IOException
* In case of I/O errors.
*/
private void init(boolean canWrite)
throws IOException
{
try
{
stream = StreamFactory.openFileStream(fileName, canWrite, false);
if (stream == null)
{
throw new IOException("An exception occurred!");
}
}
catch (ErrorConditionException e)
{
throw new IOException("An exception occurred!", e);
}
isStarted = true;
}
}
/**
* Special wrapper to wrap write to longchar in lazy mode. It's means that first try to write
* will check if longchar is available.
*/
private static class LongcharOutputStream
extends OutputStream
{
/** A valid longchar object to write.*/
private longchar lchar;
/** Buffered output Stream.*/
private StringWriter buffer = new StringWriter();
/** Lazy initialization flag.*/
private volatile boolean isStarted;
/**
* Constructor accepting a longchar, which will read after first call.
*
* @param source
* A valid longchar object.
*/
private LongcharOutputStream(longchar source)
{
lchar = source;
}
/**
* Write one byte into the buffer.
* @param b
* the data to write.
*/
@Override
public void write(int b)
throws IOException
{
if (!isStarted)
{
lchar.assign("");
isStarted = true;
}
buffer.write(b);
}
/**
* Flush data from internal buffer to longchar object.
*/
@Override
public void flush()
throws IOException
{
String buf = buffer.getBuffer().toString();
buffer.getBuffer().setLength(0);
lchar.assign(TextOps.concat(lchar, buf));
}
/**
* Close current stream and reset state.
*/
@Override
public void close()
throws IOException
{
flush();
buffer.close();
isStarted = false;
}
}
/**
* Special wrapper to wrap write to memptr in lazy mode. It's means that first try to write
* will check if memptr is available.
*/
private static class MemptrOutputStream
extends OutputStream
{
/** A valid memptr */
private final memptr mptr;
/** Current read cursor position, started from index 1.*/
private final AtomicLong position = new AtomicLong();
/** Lazy initialization flag.*/
private volatile boolean isStarted = false;
/** Lazy initialization flag.*/
private long totalSize = 0;
/**
* Constructor accepting a memptr to write.
*
* @param source
* A valid memptr object.
*/
private MemptrOutputStream(memptr source)
{
mptr = source;
}
/**
* Write one byte into memptr. If capacity of memptr is not enough then expand capacity.
* @param b
* the data to write.
* @throws IOException
* wrap any exception from memptr into IO exception.
*/
@Override
public void write(int b)
throws IOException
{
if (!isStarted)
{
mptr.setLength(0); //reset memptr
position.set(1);
totalSize = mptr.length().longValue();
isStarted = true;
}
ensureCapacity(1);
try
{
mptr.setByte(b, position.getAndIncrement());
}
catch (ErrorConditionException e)
{
throw new IOException(e);
}
}
/**
* Wrap super method to ensure that memptr has enough length and reduce number of calls to
* expand capacity.
*
* @param b
* the data.
* @param off
* the start offset in the data.
* @param len
* the number of bytes to write.
* @throws IOException
*/
@Override
public void write(byte[] b, int off, int len)
throws IOException
{
if (!isStarted)
{
mptr.setLength(0); //reset memptr
position.set(1);
totalSize = mptr.length().longValue();
isStarted = true;
}
ensureCapacity(len);
super.write(b, off, len);
}
/**
* Close current stream and reset state.
*/
@Override
public void close()
throws IOException
{
isStarted = false;
}
/**
* Check capacity of memptr, if capacity is less then needed, then increase capacity.
* @param len
* Count of bytes to ensure capacity.
*/
private void ensureCapacity(int len)
{
long freeSpace = totalSize - position.intValue();
if (len > freeSpace)
{
totalSize = mptr.length().longValue() + len;
mptr.setLength(totalSize);
}
}
}
/**
* Track the namespaces (prefix and uri) for each XML element scope.
*/
private static class ScopedNamespaceContext
implements NamespaceContext
{
/** Map of prefixes to URIs. */
private Map<String, String> prefixToUri = null;
/** The context stack of namespaces for each XML element. */
private Deque<Map<String, String>> scopes = new ArrayDeque<>();
/**
* Notification a new XML element or document starts.
*/
public void startElement()
{
scopes.push(prefixToUri = new HashMap<>());
}
/**
* Notification the XML document or element ends.
*/
public void endElement()
{
prefixToUri = scopes.pop();
}
/**
* Register the given prefix for the given uri.
*
* @param prefix
* The namespace prefix to use.
* @param uri
* The URI to use.
*/
public void setPrefix(String prefix, String uri)
{
prefixToUri.put(prefix, uri);
}
/**
* Get Namespace URI bound to a prefix in the current scope.
*
* @param prefix
* The prefix.
*
* @return The namespace URI or <code>null</code> if not found..
*/
@Override
public String getNamespaceURI(String prefix)
{
String uri = prefixToUri.get(prefix);
if (uri != null)
{
return uri;
}
for (Map<String, String> p : scopes)
{
uri = p.get(prefix);
if (uri != null)
{
return uri;
}
}
return null;
}
/**
* Get prefix bound to Namespace URI in the current scope.
*
* @param namespaceURI
* The namespace URI.
*
* @return The prefix or <code>null</code> if not found.
*/
@Override
public String getPrefix(String namespaceURI)
{
BiFunction<Map<String, String>, String, String> findPrefix = (m, uri) ->
{
for (Map.Entry<String, String> entry : m.entrySet())
{
if (entry.getValue().equals(uri))
{
return entry.getKey();
}
}
return null;
};
String prefix = findPrefix.apply(prefixToUri, namespaceURI);
if (prefix != null)
{
return prefix;
}
for (Map<String, String> p : scopes)
{
prefix = findPrefix.apply(p, namespaceURI);
if (prefix != null)
{
return prefix;
}
}
return null;
}
/**
* Get all the prefixes associated with the specified URI.
*
* @param namespaceURI
* The namespace URI.
*
* @return An iterator for all prefixes for this URI.
*/
@Override
public Iterator<String> getPrefixes(String namespaceURI)
{
List<String> ret = new ArrayList<>(2);
BiConsumer<Map<String, String>, String> findPrefix = (m, uri) ->
{
for (Map.Entry<String, String> entry : m.entrySet())
{
if (entry.getValue().equals(uri))
{
ret.add(entry.getKey());
}
}
};
findPrefix.accept(prefixToUri, namespaceURI);
for (Map<String, String> p : scopes)
{
findPrefix.accept(p, namespaceURI);
}
return ret.iterator();
}
}
}