org.eclipse.persistence.oxm.record.XMLEventWriterRecord Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.eclipse.persistence.core Show documentation
Show all versions of org.eclipse.persistence.core Show documentation
EclipseLink build based upon Git transaction ecdf3c32c4
/*
* Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// mmacivor - September 09/2009 - 1.0 - Initial implementation
package org.eclipse.persistence.oxm.record;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.record.DomToXMLEventWriter;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public class XMLEventWriterRecord extends MarshalRecord {
private Map prefixMapping;
private NamespaceResolver namespaceResolver;
private XMLEventWriter xmlEventWriter;
private XMLEventFactory xmlEventFactory;
private DomToXMLEventWriter domToXMLEventWriter;
private boolean isStartElementOpen = false;
private List attributes;
private List namespaceDeclarations;
private XPathFragment xPathFragment;
public XMLEventWriterRecord(XMLEventWriter xmlEventWriter) {
this.xmlEventWriter = xmlEventWriter;
this.xmlEventFactory = XMLEventFactory.newInstance();
this.domToXMLEventWriter = new DomToXMLEventWriter(xmlEventFactory);
}
public XMLEventWriter getXMLEventWriter() {
return xmlEventWriter;
}
public void setXMLEventWriter(XMLEventWriter anXMLEventWriter) {
this.xmlEventWriter = anXMLEventWriter;
}
@Override
public void attribute(XPathFragment xPathFragment, NamespaceResolver namespaceResolver, String value) {
String namespaceURI = xPathFragment.getNamespaceURI();
XMLEvent event;
if(namespaceURI == null) {
event = xmlEventFactory.createAttribute(xPathFragment.getLocalName(), value);
} else {
String prefix = getPrefixForFragment(xPathFragment);
if(prefix == null) {
event = xmlEventFactory.createAttribute(null, namespaceURI, xPathFragment.getLocalName(), value);
} else {
if(xmlEventWriter.getNamespaceContext().getNamespaceURI(prefix) == null || !xmlEventWriter.getNamespaceContext().getNamespaceURI(prefix).equals(namespaceURI)) {
event = xmlEventFactory.createNamespace(prefix, namespaceURI);
try {
this.xmlEventWriter.setPrefix(prefix, namespaceURI);
} catch(XMLStreamException e) {
throw XMLMarshalException.marshalException(e);
}
}
event = xmlEventFactory.createAttribute(prefix, namespaceURI, xPathFragment.getLocalName(), value);
}
}
if(event.isNamespace()) {
if(null == this.namespaceDeclarations) {
this.namespaceDeclarations = new ArrayList();
}
this.namespaceDeclarations.add(event);
} else {
if(null == attributes) {
attributes = new ArrayList();
}
this.attributes.add(event);
}
}
@Override
public void attribute(String namespaceURI, String localName, String name, String value) {
XMLEvent event;
if(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI)) {
try {
if(javax.xml.XMLConstants.XMLNS_ATTRIBUTE.equals(localName)) {
event = xmlEventFactory.createNamespace(value);
xmlEventWriter.setDefaultNamespace(value);
} else {
event = xmlEventFactory.createNamespace(localName, value);
xmlEventWriter.setPrefix(localName, value);
}
} catch(XMLStreamException e) {
throw XMLMarshalException.marshalException(e);
}
} else {
if(namespaceURI == null || namespaceURI.length() == 0) {
event = xmlEventFactory.createAttribute(localName, value);
} else {
int index = name.indexOf(':');
if(index == -1) {
event = xmlEventFactory.createAttribute(Constants.EMPTY_STRING, namespaceURI, localName, value);
} else {
String prefix = name.substring(0, index);
event = xmlEventFactory.createAttribute(prefix, namespaceURI, localName, value);
}
}
}
if(event.isNamespace()) {
if(null == this.namespaceDeclarations) {
this.namespaceDeclarations = new ArrayList();
}
this.namespaceDeclarations.add(event);
} else {
if(null == this.attributes) {
this.attributes = new ArrayList();
}
this.attributes.add(event);
}
}
private void openAndCloseStartElement() {
try {
String namespaceURI = xPathFragment.getNamespaceURI();
if(null == namespaceURI) {
Iterator attributesIterator = null;
if(null != attributes) {
attributesIterator = attributes.iterator();
}
Iterator namespaceDeclarationsIterator = null;
if(null != namespaceDeclarations) {
namespaceDeclarationsIterator = namespaceDeclarations.iterator();
}
xmlEventWriter.add(xmlEventFactory.createStartElement(Constants.EMPTY_STRING, Constants.EMPTY_STRING, xPathFragment.getLocalName(), attributesIterator, namespaceDeclarationsIterator));
String defaultNamespace = xmlEventWriter.getNamespaceContext().getNamespaceURI(Constants.EMPTY_STRING);
if(defaultNamespace != null && defaultNamespace.length() > 0 ) {
xmlEventWriter.setDefaultNamespace(Constants.EMPTY_STRING);
xmlEventWriter.add(xmlEventFactory.createNamespace(Constants.EMPTY_STRING));
}
} else {
String prefix = getPrefixForFragment(xPathFragment);
if(null == prefix) {
prefix = Constants.EMPTY_STRING;
}
Iterator attributesIterator = null;
if(null != attributes) {
attributesIterator = attributes.iterator();
}
Iterator namespaceDeclarationsIterator = null;
if(null != namespaceDeclarations) {
namespaceDeclarationsIterator = namespaceDeclarations.iterator();
}
xmlEventWriter.add(xmlEventFactory.createStartElement(prefix, namespaceURI, xPathFragment.getLocalName(), attributesIterator, namespaceDeclarationsIterator));
}
} catch(XMLStreamException ex) {
throw XMLMarshalException.marshalException(ex);
}
}
@Override
public void cdata(String value) {
try {
if(isStartElementOpen) {
openAndCloseStartElement();
isStartElementOpen = false;
}
for(String part : MarshalRecord.splitCData(value)) {
xmlEventWriter.add(xmlEventFactory.createCData(part));
}
} catch(Exception e) {
throw XMLMarshalException.marshalException(e);
}
}
@Override
public void characters(String value) {
try {
if(isStartElementOpen) {
openAndCloseStartElement();
isStartElementOpen = false;
}
xmlEventWriter.add(xmlEventFactory.createCharacters(value));
} catch(Exception e) {
throw XMLMarshalException.marshalException(e);
}
}
@Override
public void closeStartElement() {
}
@Override
public void openStartElement(XPathFragment xPathFragment, NamespaceResolver namespaceResolver) {
super.openStartElement(xPathFragment, namespaceResolver);
if (isStartElementOpen) {
openAndCloseStartElement();
}
isStartElementOpen = true;
this.xPathFragment = xPathFragment;
this.attributes = null;
this.namespaceDeclarations = null;
if(xPathFragment.isGeneratedPrefix()){
namespaceDeclaration(xPathFragment.getPrefix(), xPathFragment.getNamespaceURI());
}
writePrefixMappings();
}
@Override
public void element(XPathFragment frag) {
try {
if(isStartElementOpen) {
openAndCloseStartElement();
isStartElementOpen = false;
}
String namespaceURI = frag.getNamespaceURI();
String localName = frag.getLocalName();
String prefix = getPrefixForFragment(xPathFragment);
if(null == prefix) {
prefix = Constants.EMPTY_STRING;
}
xmlEventWriter.add(xmlEventFactory.createStartElement(prefix, namespaceURI, localName));
xmlEventWriter.add(xmlEventFactory.createEndElement(prefix, namespaceURI, localName));
} catch(Exception e) {
throw XMLMarshalException.marshalException(e);
}
}
@Override
public void endDocument() {
try {
if(isStartElementOpen) {
openAndCloseStartElement();
isStartElementOpen = false;
}
xmlEventWriter.add(xmlEventFactory.createEndDocument());
xmlEventWriter.flush();
} catch(Exception e) {
throw XMLMarshalException.marshalException(e);
}
}
@Override
public void endElement(XPathFragment pathFragment, NamespaceResolver namespaceResolver) {
if(isStartElementOpen) {
openAndCloseStartElement();
isStartElementOpen = false;
}
String prefix = getPrefixForFragment(pathFragment);
if(null == prefix) {
prefix = Constants.EMPTY_STRING;
}
try {
xmlEventWriter.add(xmlEventFactory.createEndElement(prefix, xPathFragment.getNamespaceURI(), pathFragment.getLocalName()));
} catch(Exception e) {
throw XMLMarshalException.marshalException(e);
}
}
@Override
public void node(Node node, NamespaceResolver resolver, String uri, String name) {
if(isStartElementOpen) {
openAndCloseStartElement();
isStartElementOpen = false;
}
try {
if(node.getNodeType() == Node.DOCUMENT_NODE) {
node = ((Document)node).getDocumentElement();
}
domToXMLEventWriter.writeToEventWriter(node, uri, name, xmlEventWriter);
} catch(XMLStreamException e) {
throw XMLMarshalException.marshalException(e);
}
}
@Override
public void startDocument(String encoding, String version) {
try {
xmlEventWriter.add(this.xmlEventFactory.createStartDocument(encoding, version, false));
} catch(Exception e) {
throw XMLMarshalException.marshalException(e);
}
}
@Override
public void startPrefixMapping(String prefix, String namespaceUri) {
if(null == this.prefixMapping) {
this.prefixMapping = new HashMap();
}
this.prefixMapping.put(prefix, namespaceUri);
}
private void writePrefixMappings() {
if(null != namespaceResolver) {
String defaultNamespace = namespaceResolver.getDefaultNamespaceURI();
if(defaultNamespace != null) {
XMLEvent namespace = xmlEventFactory.createNamespace(Constants.EMPTY_STRING, defaultNamespace);
if(null == namespaceDeclarations) {
namespaceDeclarations = new ArrayList();
}
namespaceDeclarations.add(namespace);
}
if(this.namespaceResolver.hasPrefixesToNamespaces()) {
for(Map.Entry entry:this.namespaceResolver.getPrefixesToNamespaces().entrySet()) {
XMLEvent namespace = xmlEventFactory.createNamespace(entry.getKey(), entry.getValue());
if(null == namespaceDeclarations) {
namespaceDeclarations = new ArrayList();
}
namespaceDeclarations.add(namespace);
}
}
namespaceResolver = null;
}
if(null != prefixMapping) {
for(Map.Entry entry:this.prefixMapping.entrySet()) {
XMLEvent namespace = xmlEventFactory.createNamespace(entry.getKey(), entry.getValue());
if(null == namespaceDeclarations) {
namespaceDeclarations = new ArrayList();
}
namespaceDeclarations.add(namespace);
}
prefixMapping = null;
}
}
@Override
public void namespaceDeclarations(NamespaceResolver namespaceResolver) {
}
@Override
public void startPrefixMappings(NamespaceResolver namespaceResolver) {
this.namespaceResolver = namespaceResolver;
}
}