Path: blob/aarch64-shenandoah-jdk8u272-b10/jaxp/src/com/sun/xml/internal/stream/writers/XMLDOMWriterImpl.java
48527 views
/*1* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.xml.internal.stream.writers;2627import java.lang.reflect.InvocationTargetException;28import java.lang.reflect.Method;29import javax.xml.XMLConstants;30import javax.xml.namespace.NamespaceContext;31import javax.xml.stream.XMLStreamException;32import javax.xml.stream.XMLStreamWriter;33import javax.xml.transform.dom.DOMResult;34import org.w3c.dom.Attr;35import org.w3c.dom.CDATASection;36import org.w3c.dom.Comment;37import org.w3c.dom.Document;38import org.w3c.dom.Element;39import org.w3c.dom.EntityReference;40import org.w3c.dom.Node;41import org.w3c.dom.ProcessingInstruction;42import org.w3c.dom.Text;43import org.xml.sax.helpers.NamespaceSupport;4445/**46* This class provides support to build a DOM tree using XMLStreamWriter API's.47* @author [email protected]48*/4950/*51* TODO : -Venu52* Internal NamespaceManagement53* setPrefix54* support for isRepairNamespace property.55* Some Unsupported Methods.56* Change StringBuffer to StringBuilder, when JDK 1.5 will be minimum requirement for SJSXP.57*/5859public class XMLDOMWriterImpl implements XMLStreamWriter {606162private Document ownerDoc = null;63private Node currentNode = null;64private Node node = null;65private NamespaceSupport namespaceContext = null;66private Method mXmlVersion = null;67private boolean [] needContextPop = null;68private StringBuffer stringBuffer = null;69private int resizeValue = 20;70private int depth = 0;71/**72* Creates a new instance of XMLDOMwriterImpl73* @param result DOMResult object @javax.xml.transform.dom.DOMResult74*/75public XMLDOMWriterImpl(DOMResult result) {7677node = result.getNode();78if( node.getNodeType() == Node.DOCUMENT_NODE){79ownerDoc = (Document)node;80currentNode = ownerDoc;81}else{82ownerDoc = node.getOwnerDocument();83currentNode = node;84}85getDLThreeMethods();86stringBuffer = new StringBuffer();87needContextPop = new boolean[resizeValue];88namespaceContext = new NamespaceSupport();89}9091private void getDLThreeMethods(){92try{93mXmlVersion = ownerDoc.getClass().getMethod("setXmlVersion",new Class[] {String.class});94}catch(NoSuchMethodException mex){95//log these errors at fine level.96mXmlVersion = null;97}catch(SecurityException se){98//log these errors at fine level.99mXmlVersion = null;100}101}102103104/**105* This method has no effect when called.106* @throws javax.xml.stream.XMLStreamException {@inheritDoc}107*/108public void close() throws XMLStreamException {109//no-op110}111112/**113* This method has no effect when called.114* @throws javax.xml.stream.XMLStreamException {@inheritDoc}115*/116public void flush() throws XMLStreamException {117//no-op118}119120/**121* {@inheritDoc}122* @return {@inheritDoc}123*/124public javax.xml.namespace.NamespaceContext getNamespaceContext() {125return null;126}127128/**129* {@inheritDoc}130* @param namespaceURI {@inheritDoc}131* @throws javax.xml.stream.XMLStreamException {@inheritDoc}132* @return {@inheritDoc}133*/134public String getPrefix(String namespaceURI) throws XMLStreamException {135String prefix = null;136if(this.namespaceContext != null){137prefix = namespaceContext.getPrefix(namespaceURI);138}139return prefix;140}141142/**143* Is not supported in this implementation.144* @param str {@inheritDoc}145* @throws java.lang.IllegalArgumentException {@inheritDoc}146* @return {@inheritDoc}147*/148public Object getProperty(String str) throws IllegalArgumentException {149throw new UnsupportedOperationException();150}151152/**153* Is not supported in this version of the implementation.154* @param uri {@inheritDoc}155* @throws javax.xml.stream.XMLStreamException {@inheritDoc}156*/157public void setDefaultNamespace(String uri) throws XMLStreamException {158namespaceContext.declarePrefix(XMLConstants.DEFAULT_NS_PREFIX, uri);159if(!needContextPop[depth]){160needContextPop[depth] = true;161}162}163164/**165* {@inheritDoc}166* @param namespaceContext {@inheritDoc}167* @throws javax.xml.stream.XMLStreamException {@inheritDoc}168*/169public void setNamespaceContext(javax.xml.namespace.NamespaceContext namespaceContext) throws XMLStreamException {170throw new UnsupportedOperationException();171}172173/**174* Is not supported in this version of the implementation.175* @param prefix {@inheritDoc}176* @param uri {@inheritDoc}177* @throws javax.xml.stream.XMLStreamException {@inheritDoc}178*/179public void setPrefix(String prefix, String uri) throws XMLStreamException {180if(prefix == null){181throw new XMLStreamException("Prefix cannot be null");182}183namespaceContext.declarePrefix(prefix, uri);184if(!needContextPop[depth]){185needContextPop[depth] = true;186}187}188189/**190* Creates a DOM Atrribute @see org.w3c.dom.Node and associates it with the current DOM element @see org.w3c.dom.Node.191* @param localName {@inheritDoc}192* @param value {@inheritDoc}193* @throws javax.xml.stream.XMLStreamException {@inheritDoc}194*/195public void writeAttribute(String localName, String value) throws XMLStreamException {196197if(currentNode.getNodeType() == Node.ELEMENT_NODE){198Attr attr = ownerDoc.createAttribute(localName);199attr.setValue(value);200((Element)currentNode).setAttributeNode(attr);201}else{202//Convert node type to String203throw new IllegalStateException("Current DOM Node type is "+ currentNode.getNodeType() +204"and does not allow attributes to be set ");205}206}207208/**209* Creates a DOM Atrribute @see org.w3c.dom.Node and associates it with the current DOM element @see org.w3c.dom.Node.210* @param namespaceURI {@inheritDoc}211* @param localName {@inheritDoc}212* @param value {@inheritDoc}213* @throws javax.xml.stream.XMLStreamException {@inheritDoc}214*/215public void writeAttribute(String namespaceURI,String localName,String value)throws XMLStreamException {216if(currentNode.getNodeType() == Node.ELEMENT_NODE){217String prefix = null;218if(namespaceURI == null ){219throw new XMLStreamException("NamespaceURI cannot be null");220}221if(localName == null){222throw new XMLStreamException("Local name cannot be null");223}224if(namespaceContext != null){225prefix = namespaceContext.getPrefix(namespaceURI);226}227228if(prefix == null){229throw new XMLStreamException("Namespace URI "+namespaceURI +230"is not bound to any prefix" );231}232233String qualifiedName = null;234if(prefix.equals("")){235qualifiedName = localName;236}else{237qualifiedName = getQName(prefix,localName);238}239Attr attr = ownerDoc.createAttributeNS(namespaceURI, qualifiedName);240attr.setValue(value);241((Element)currentNode).setAttributeNode(attr);242}else{243//Convert node type to String244throw new IllegalStateException("Current DOM Node type is "+ currentNode.getNodeType() +245"and does not allow attributes to be set ");246}247}248249/**250* Creates a DOM Atrribute @see org.w3c.dom.Node and associates it with the current DOM element @see org.w3c.dom.Node.251* @param prefix {@inheritDoc}252* @param namespaceURI {@inheritDoc}253* @param localName {@inheritDoc}254* @param value {@inheritDoc}255* @throws javax.xml.stream.XMLStreamException {@inheritDoc}256*/257public void writeAttribute(String prefix,String namespaceURI,String localName,String value)throws XMLStreamException {258if(currentNode.getNodeType() == Node.ELEMENT_NODE){259if(namespaceURI == null ){260throw new XMLStreamException("NamespaceURI cannot be null");261}262if(localName == null){263throw new XMLStreamException("Local name cannot be null");264}265if(prefix == null){266throw new XMLStreamException("prefix cannot be null");267}268String qualifiedName = null;269if(prefix.equals("")){270qualifiedName = localName;271}else{272273qualifiedName = getQName(prefix,localName);274}275Attr attr = ownerDoc.createAttributeNS(namespaceURI, qualifiedName);276attr.setValue(value);277((Element)currentNode).setAttributeNodeNS(attr);278}else{279//Convert node type to String280throw new IllegalStateException("Current DOM Node type is "+ currentNode.getNodeType() +281"and does not allow attributes to be set ");282}283284}285286/**287* Creates a CDATA object @see org.w3c.dom.CDATASection.288* @param data {@inheritDoc}289* @throws javax.xml.stream.XMLStreamException {@inheritDoc}290*/291public void writeCData(String data) throws XMLStreamException {292if(data == null){293throw new XMLStreamException("CDATA cannot be null");294}295296CDATASection cdata = ownerDoc.createCDATASection(data);297getNode().appendChild(cdata);298}299300/**301* Creates a character object @see org.w3c.dom.Text and appends it to the current302* element in the DOM tree.303* @param charData {@inheritDoc}304* @throws javax.xml.stream.XMLStreamException {@inheritDoc}305*/306public void writeCharacters(String charData) throws XMLStreamException {307Text text = ownerDoc.createTextNode(charData);308currentNode.appendChild(text);309}310311/**312* Creates a character object @see org.w3c.dom.Text and appends it to the current313* element in the DOM tree.314* @param values {@inheritDoc}315* @param param {@inheritDoc}316* @param param2 {@inheritDoc}317* @throws javax.xml.stream.XMLStreamException {@inheritDoc}318*/319public void writeCharacters(char[] values, int param, int param2) throws XMLStreamException {320321Text text = ownerDoc.createTextNode(new String(values,param,param2));322currentNode.appendChild(text);323}324325/**326* Creates a Comment object @see org.w3c.dom.Comment and appends it to the current327* element in the DOM tree.328* @param str {@inheritDoc}329* @throws javax.xml.stream.XMLStreamException {@inheritDoc}330*/331public void writeComment(String str) throws XMLStreamException {332Comment comment = ownerDoc.createComment(str);333getNode().appendChild(comment);334}335336/**337* This method is not supported in this implementation.338* @param str {@inheritDoc}339* @throws javax.xml.stream.XMLStreamException {@inheritDoc}340*/341public void writeDTD(String str) throws XMLStreamException {342throw new UnsupportedOperationException();343}344345/**346* Creates a DOM attribute and adds it to the current element in the DOM tree.347* @param namespaceURI {@inheritDoc}348* @throws javax.xml.stream.XMLStreamException {@inheritDoc}349*/350public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException {351if(currentNode.getNodeType() == Node.ELEMENT_NODE){352String qname = XMLConstants.XMLNS_ATTRIBUTE;353((Element)currentNode).setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,qname, namespaceURI);354}else{355//Convert node type to String356throw new IllegalStateException("Current DOM Node type is "+ currentNode.getNodeType() +357"and does not allow attributes to be set ");358}359}360361/**362* creates a DOM Element and appends it to the current element in the tree.363* @param localName {@inheritDoc}364* @throws javax.xml.stream.XMLStreamException {@inheritDoc}365*/366public void writeEmptyElement(String localName) throws XMLStreamException {367if(ownerDoc != null){368Element element = ownerDoc.createElement(localName);369if(currentNode!=null){370currentNode.appendChild(element);371}else{372ownerDoc.appendChild(element);373}374}375376}377378/**379* creates a DOM Element and appends it to the current element in the tree.380* @param namespaceURI {@inheritDoc}381* @param localName {@inheritDoc}382* @throws javax.xml.stream.XMLStreamException {@inheritDoc}383*/384public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {385if(ownerDoc != null){386String qualifiedName = null;387String prefix = null;388if(namespaceURI == null ){389throw new XMLStreamException("NamespaceURI cannot be null");390}391if(localName == null){392throw new XMLStreamException("Local name cannot be null");393}394395if(namespaceContext != null){396prefix = namespaceContext.getPrefix(namespaceURI);397}398if(prefix == null){399throw new XMLStreamException("Namespace URI "+namespaceURI +400"is not bound to any prefix" );401}402if("".equals(prefix)){403qualifiedName = localName;404}else{405406qualifiedName = getQName(prefix,localName);407408}409Element element = ownerDoc.createElementNS(namespaceURI, qualifiedName);410if(currentNode!=null){411currentNode.appendChild(element);412}else{413ownerDoc.appendChild(element);414}415//currentNode = element;416}417}418419/**420* creates a DOM Element and appends it to the current element in the tree.421* @param prefix {@inheritDoc}422* @param localName {@inheritDoc}423* @param namespaceURI {@inheritDoc}424* @throws javax.xml.stream.XMLStreamException {@inheritDoc}425*/426public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {427if(ownerDoc != null){428if(namespaceURI == null ){429throw new XMLStreamException("NamespaceURI cannot be null");430}431if(localName == null){432throw new XMLStreamException("Local name cannot be null");433}434if(prefix == null){435throw new XMLStreamException("Prefix cannot be null");436}437String qualifiedName = null;438if("".equals(prefix)){439qualifiedName = localName;440}else{441qualifiedName = getQName(prefix,localName);442}443Element el = ownerDoc.createElementNS(namespaceURI,qualifiedName);444if(currentNode!=null){445currentNode.appendChild(el);446}else{447ownerDoc.appendChild(el);448}449450}451}452453/**454* Will reset current Node pointer maintained by the implementation.455* @throws javax.xml.stream.XMLStreamException {@inheritDoc}456*/457public void writeEndDocument() throws XMLStreamException {458//What do you want me to do eh! :)459currentNode = null;460for(int i=0; i< depth;i++){461if(needContextPop[depth]){462needContextPop[depth] = false;463namespaceContext.popContext();464}465depth--;466}467depth =0;468}469470/**471* Internal current Node pointer will point to the parent of the current Node.472* @throws javax.xml.stream.XMLStreamException {@inheritDoc}473*/474public void writeEndElement() throws XMLStreamException {475Node node= currentNode.getParentNode();476if(currentNode.getNodeType() == Node.DOCUMENT_NODE){477currentNode = null;478}else{479currentNode = node;480}481if(needContextPop[depth]){482needContextPop[depth] = false;483namespaceContext.popContext();484}485depth--;486}487488/**489* Is not supported in this implementation.490* @param name {@inheritDoc}491* @throws javax.xml.stream.XMLStreamException {@inheritDoc}492*/493public void writeEntityRef(String name) throws XMLStreamException {494EntityReference er = ownerDoc.createEntityReference(name);495currentNode.appendChild(er);496}497498/**499* creates a namespace attribute and will associate it with the current element in500* the DOM tree.501* @param prefix {@inheritDoc}502* @param namespaceURI {@inheritDoc}503* @throws javax.xml.stream.XMLStreamException {@inheritDoc}504*/505public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {506507if (prefix == null) {508throw new XMLStreamException("prefix cannot be null");509}510511if (namespaceURI == null) {512throw new XMLStreamException("NamespaceURI cannot be null");513}514515String qname = null;516517if (prefix.equals("")) {518qname = XMLConstants.XMLNS_ATTRIBUTE;519} else {520qname = getQName(XMLConstants.XMLNS_ATTRIBUTE,prefix);521}522523((Element)currentNode).setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,qname, namespaceURI);524}525526/**527* is not supported in this release.528* @param target {@inheritDoc}529* @throws javax.xml.stream.XMLStreamException {@inheritDoc}530*/531public void writeProcessingInstruction(String target) throws XMLStreamException {532if(target == null){533throw new XMLStreamException("Target cannot be null");534}535ProcessingInstruction pi = ownerDoc.createProcessingInstruction(target, "");536currentNode.appendChild(pi);537}538539/**540* is not supported in this release.541* @param target {@inheritDoc}542* @param data {@inheritDoc}543* @throws javax.xml.stream.XMLStreamException {@inheritDoc}544*/545public void writeProcessingInstruction(String target, String data) throws XMLStreamException {546if(target == null){547throw new XMLStreamException("Target cannot be null");548}549ProcessingInstruction pi = ownerDoc.createProcessingInstruction(target, data);550currentNode.appendChild(pi);551}552553/**554* will set version on the Document object when the DOM Node passed to this implementation555* supports DOM Level3 API's.556* @throws javax.xml.stream.XMLStreamException {@inheritDoc}557*/558public void writeStartDocument() throws XMLStreamException {559try{560if(mXmlVersion != null){561mXmlVersion.invoke(ownerDoc, new Object[] {"1.0"});562}563}catch(IllegalAccessException iae){564throw new XMLStreamException(iae);565}catch(InvocationTargetException ite){566throw new XMLStreamException(ite);567}568}569570/**571* will set version on the Document object when the DOM Node passed to this implementation572* supports DOM Level3 API's.573* @param version {@inheritDoc}574* @throws javax.xml.stream.XMLStreamException {@inheritDoc}575*/576public void writeStartDocument(String version) throws XMLStreamException {577try{578if(mXmlVersion != null){579mXmlVersion.invoke(ownerDoc, new Object[] {version});580}581}catch(IllegalAccessException iae){582throw new XMLStreamException(iae);583}catch(InvocationTargetException ite){584throw new XMLStreamException(ite);585}586}587588/**589* will set version on the Document object when the DOM Node passed to this implementation590* supports DOM Level3 API's.591* @param encoding {@inheritDoc}592* @param version {@inheritDoc}593* @throws javax.xml.stream.XMLStreamException {@inheritDoc}594*/595public void writeStartDocument(String encoding, String version) throws XMLStreamException {596try{597if(mXmlVersion != null){598mXmlVersion.invoke(ownerDoc, new Object[] {version});599}600}catch(IllegalAccessException iae){601throw new XMLStreamException(iae);602}catch(InvocationTargetException ite){603throw new XMLStreamException(ite);604}605//TODO: What to do with encoding.-Venu606}607608/**609* creates a DOM Element and appends it to the current element in the tree.610* @param localName {@inheritDoc}611* @throws javax.xml.stream.XMLStreamException {@inheritDoc}612*/613public void writeStartElement(String localName) throws XMLStreamException {614if(ownerDoc != null){615Element element = ownerDoc.createElement(localName);616if(currentNode!=null){617currentNode.appendChild(element);618}else{619ownerDoc.appendChild(element);620}621currentNode = element;622}623if(needContextPop[depth]){624namespaceContext.pushContext();625}626incDepth();627}628629/**630* creates a DOM Element and appends it to the current element in the tree.631* @param namespaceURI {@inheritDoc}632* @param localName {@inheritDoc}633* @throws javax.xml.stream.XMLStreamException {@inheritDoc}634*/635public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {636if(ownerDoc != null){637String qualifiedName = null;638String prefix = null;639640if(namespaceURI == null ){641throw new XMLStreamException("NamespaceURI cannot be null");642}643if(localName == null){644throw new XMLStreamException("Local name cannot be null");645}646647if(namespaceContext != null){648prefix = namespaceContext.getPrefix(namespaceURI);649}650if(prefix == null){651throw new XMLStreamException("Namespace URI "+namespaceURI +652"is not bound to any prefix" );653}654if("".equals(prefix)){655qualifiedName = localName;656}else{657qualifiedName = getQName(prefix,localName);658}659660Element element = ownerDoc.createElementNS(namespaceURI, qualifiedName);661662if(currentNode!=null){663currentNode.appendChild(element);664}else{665ownerDoc.appendChild(element);666}667currentNode = element;668}669if(needContextPop[depth]){670namespaceContext.pushContext();671}672incDepth();673}674675/**676* creates a DOM Element and appends it to the current element in the tree.677* @param prefix {@inheritDoc}678* @param localName {@inheritDoc}679* @param namespaceURI {@inheritDoc}680* @throws javax.xml.stream.XMLStreamException {@inheritDoc}681*/682public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {683684if(ownerDoc != null){685String qname = null;686if(namespaceURI == null ){687throw new XMLStreamException("NamespaceURI cannot be null");688}689if(localName == null){690throw new XMLStreamException("Local name cannot be null");691}692if(prefix == null){693throw new XMLStreamException("Prefix cannot be null");694}695696if(prefix.equals("")){697qname = localName;698}else{699qname = getQName(prefix,localName);700}701702Element el = ownerDoc.createElementNS(namespaceURI,qname);703704if(currentNode!=null){705currentNode.appendChild(el);706}else{707ownerDoc.appendChild(el);708}709currentNode = el;710if(needContextPop[depth]){711namespaceContext.pushContext();712}713incDepth();714715}716}717718private String getQName(String prefix , String localName){719stringBuffer.setLength(0);720stringBuffer.append(prefix);721stringBuffer.append(":");722stringBuffer.append(localName);723return stringBuffer.toString();724}725726private Node getNode(){727if(currentNode == null){728return ownerDoc;729} else{730return currentNode;731}732}733private void incDepth() {734depth++;735if (depth == needContextPop.length) {736boolean[] array = new boolean[depth + resizeValue];737System.arraycopy(needContextPop, 0, array, 0, depth);738needContextPop = array;739}740}741}742743744