All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.oxm.record.FormattedOutputStreamRecord Maven / Gradle / Ivy

There is a newer version: 4.0.2
Show newest version
/*
 * 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:
//      Denise Smith - November 2, 2009
package org.eclipse.persistence.oxm.record;

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;

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.XMLFragmentReader;
import org.w3c.dom.Attr;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

/**
 * 

Use this type of MarshalRecord when the marshal target is an OutputStream and the * XML should be formatted with carriage returns and indenting. This type is only * used if the encoding of the OutputStream is UTF-8

*

* XMLContext xmlContext = new XMLContext("session-name");
* XMLMarshaller xmlMarshaller = xmlContext.createMarshaller();
* FormattedOutputStreamRecord record = new FormattedOutputStreamRecord();
* record.setOutputStream(myOutputStream);
* xmlMarshaller.marshal(myObject, record);
*

*

If the marshal(OutputStream) and setFormattedOutput(true) method is called on * XMLMarshaller and the encoding is UTF-8, then the OutputStream is automatically wrapped * in a FormattedOutputStreamRecord.

*

* XMLContext xmlContext = new XMLContext("session-name");
* XMLMarshaller xmlMarshaller = xmlContext.createMarshaller();
* xmlMarshaller xmlMarshaller.setFormattedOutput(true);
* xmlMarshaller.marshal(myObject, myOutputStream);
*

* @see org.eclipse.persistence.oxm.XMLMarshaller */ public class FormattedOutputStreamRecord extends OutputStreamRecord { private byte[] cr = Constants.cr().getBytes(Constants.DEFAULT_CHARSET); private byte[] tab; private int numberOfTabs; private boolean complexType; private boolean isLastEventText; public FormattedOutputStreamRecord() { super(); numberOfTabs = 0; complexType = true; isLastEventText = false; } private byte[] tab() { if (tab == null) { String sTab = getMarshaller().getIndentString(); // Escape the tab using writeValue ByteArrayOutputStream baos = new ByteArrayOutputStream(); writeValue(sTab, true, false, baos); tab = baos.toByteArray(); } return tab; } /** * INTERNAL: */ public void endDocument() { outputStreamWrite(cr); } /** * INTERNAL: */ public void startDocument(String encoding, String version) { super.startDocument(encoding, version); outputStreamWrite(cr); } /** * INTERNAL */ public void writeHeader() { outputStreamWrite(getMarshaller().getXmlHeader().getBytes()); outputStreamWrite(cr); } /** * INTERNAL: */ public void openStartElement(XPathFragment xPathFragment, NamespaceResolver namespaceResolver) { this.addPositionalNodes(xPathFragment, namespaceResolver); if (isStartElementOpen) { outputStreamWrite(CLOSE_ELEMENT); } if (!isLastEventText) { if (numberOfTabs > 0) { outputStreamWrite(cr); } outputStreamWriteTab(); } isStartElementOpen = true; outputStreamWrite(OPEN_START_ELEMENT); byte[] prefixBytes = getPrefixBytes(xPathFragment); if(null != prefixBytes) { outputStreamWrite(prefixBytes); outputStreamWrite((byte)':'); } outputStreamWrite(xPathFragment.getLocalNameBytes()); if(xPathFragment.isGeneratedPrefix()){ namespaceDeclaration(xPathFragment.getPrefix(), xPathFragment.getNamespaceURI()); } numberOfTabs++; isLastEventText = false; } /** * INTERNAL: */ public void element(XPathFragment frag) { isLastEventText = false; if (isStartElementOpen) { outputStreamWrite(CLOSE_ELEMENT); isStartElementOpen = false; } outputStreamWrite(cr); outputStreamWriteTab(); super.element(frag); } /** * INTERNAL: */ public void endElement(XPathFragment xPathFragment, NamespaceResolver namespaceResolver) { isLastEventText = false; numberOfTabs--; if (isStartElementOpen) { outputStreamWrite((byte) '/'); outputStreamWrite((byte) '>'); isStartElementOpen = false; return; } if (complexType) { outputStreamWrite(cr); outputStreamWriteTab(); } else { complexType = true; } super.endElement(xPathFragment, namespaceResolver); } /** * INTERNAL: */ public void characters(String value) { super.characters(value); isLastEventText = true; complexType = false; } /** * INTERNAL: */ public void cdata(String value) { //Format the CDATA on it's own line if(isStartElementOpen) { outputStreamWrite(CLOSE_ELEMENT); isStartElementOpen = false; } super.cdata(value); complexType=false; } /** * Receive notification of a node. * @param node The Node to be added to the document * @param namespaceResolver The NamespaceResolver can be used to resolve the * namespace URI/prefix of the node */ public void node(Node node, NamespaceResolver namespaceResolver, String newNamespace, String newName) { if (node.getNodeType() == Node.ATTRIBUTE_NODE) { Attr attr = (Attr) node; String resolverPfx = null; if (namespaceResolver != null) { resolverPfx = namespaceResolver.resolveNamespaceURI(attr.getNamespaceURI()); } // If the namespace resolver contains a prefix for the attribute's URI, // use it instead of what is set on the attribute if (resolverPfx != null) { attribute(attr.getNamespaceURI(), Constants.EMPTY_STRING, resolverPfx+Constants.COLON+attr.getLocalName(), attr.getNodeValue()); } else { attribute(attr.getNamespaceURI(), Constants.EMPTY_STRING, attr.getName(), attr.getNodeValue()); // May need to declare the URI locally if (attr.getNamespaceURI() != null) { namespaceDeclaration(attr.getPrefix(), attr.getNamespaceURI()); } } } else if (node.getNodeType() == Node.TEXT_NODE) { characters(node.getNodeValue()); } else { try { FormattedOutputStreamRecordContentHandler handler = new FormattedOutputStreamRecordContentHandler(); XMLFragmentReader xfragReader = new XMLFragmentReader(namespaceResolver); xfragReader.setContentHandler(handler); xfragReader.setProperty(Constants.LEXICAL_HANDLER_PROPERTY, handler); xfragReader.parse(node, newNamespace, newName); } catch (SAXException sex) { throw XMLMarshalException.marshalException(sex); } } } /** * This class will typically be used in conjunction with an XMLFragmentReader. * The XMLFragmentReader will walk a given XMLFragment node and report events * to this class - the event's data is then written to the enclosing class' * writer. * * @see org.eclipse.persistence.internal.oxm.record.XMLFragmentReader * @see org.eclipse.persistence.oxm.record.WriterRecord.WriterRecordContentHandler */ private class FormattedOutputStreamRecordContentHandler extends OutputStreamRecordContentHandler { // --------------------- CONTENTHANDLER METHODS --------------------- // public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { try { if (isStartElementOpen) { outputStreamWrite(CLOSE_ELEMENT); } if (!isLastEventText) { outputStreamWrite(cr); outputStreamWriteTab(); } outputStreamWrite(OPEN_START_ELEMENT); outputStreamWrite(qName.getBytes(Constants.DEFAULT_XML_ENCODING)); numberOfTabs++; isStartElementOpen = true; isLastEventText = false; // Handle attributes handleAttributes(atts); // Handle prefix mappings writePrefixMappings(); } catch (UnsupportedEncodingException e) { throw XMLMarshalException.marshalException(e); } } public void endElement(String namespaceURI, String localName, String qName) throws SAXException { isLastEventText = false; numberOfTabs--; if (isStartElementOpen) { outputStreamWrite((byte) '/'); outputStreamWrite((byte) '>'); isStartElementOpen = false; complexType = true; return; } if (complexType) { outputStreamWrite(cr); outputStreamWriteTab(); } else { complexType = true; } super.endElement(namespaceURI, localName, qName); } public void characters(char[] ch, int start, int length) throws SAXException { if (isProcessingCData) { cdata(new String (ch, start, length)); return; } if (new String(ch).trim().length() == 0) { return; } super.characters(ch, start, length); isLastEventText = true; complexType = false; } // --------------------- LEXICALHANDLER METHODS --------------------- // public void comment(char[] ch, int start, int length) throws SAXException { if (isStartElementOpen) { outputStreamWrite(CLOSE_ELEMENT); outputStreamWrite(cr); isStartElementOpen = false; } writeComment(ch, start, length); complexType = false; } } private void outputStreamWriteTab() { for (int x = 0; x < numberOfTabs; x++) { outputStreamWrite(tab()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy