src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XmlWriterToTree.java
branchstuefe-statistical-history
changeset 57244 a535e674d50d
parent 57221 9653470b7294
parent 54010 17fb726e6d8e
child 57245 0ed37e453a39
equal deleted inserted replaced
57221:9653470b7294 57244:a535e674d50d
     1 /*
       
     2  * reserved comment block
       
     3  * DO NOT REMOVE OR ALTER!
       
     4  */
       
     5 /**
       
     6  * Licensed to the Apache Software Foundation (ASF) under one
       
     7  * or more contributor license agreements. See the NOTICE file
       
     8  * distributed with this work for additional information
       
     9  * regarding copyright ownership. The ASF licenses this file
       
    10  * to you under the Apache License, Version 2.0 (the
       
    11  * "License"); you may not use this file except in compliance
       
    12  * with the License. You may obtain a copy of the License at
       
    13  *
       
    14  * http://www.apache.org/licenses/LICENSE-2.0
       
    15  *
       
    16  * Unless required by applicable law or agreed to in writing,
       
    17  * software distributed under the License is distributed on an
       
    18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       
    19  * KIND, either express or implied. See the License for the
       
    20  * specific language governing permissions and limitations
       
    21  * under the License.
       
    22  */
       
    23 package org.jcp.xml.dsig.internal.dom;
       
    24 
       
    25 import java.util.List;
       
    26 
       
    27 import javax.xml.XMLConstants;
       
    28 import javax.xml.crypto.MarshalException;
       
    29 import javax.xml.crypto.XMLCryptoContext;
       
    30 import javax.xml.crypto.XMLStructure;
       
    31 import javax.xml.crypto.dom.DOMStructure;
       
    32 
       
    33 import org.w3c.dom.Attr;
       
    34 import org.w3c.dom.Comment;
       
    35 import org.w3c.dom.Document;
       
    36 import org.w3c.dom.Element;
       
    37 import org.w3c.dom.Node;
       
    38 import org.w3c.dom.Text;
       
    39 
       
    40 /**
       
    41  * Manifestation of XmlWriter interface designed to write to a tree.
       
    42  */
       
    43 public class XmlWriterToTree implements XmlWriter {
       
    44 
       
    45     private Document factory;
       
    46 
       
    47     private Element createdElement;
       
    48 
       
    49     private Node nextSibling;
       
    50 
       
    51     private Node currentNode;
       
    52 
       
    53     private List<XmlWriter.ToMarshal<? extends XMLStructure>> m_marshallers;
       
    54 
       
    55     public XmlWriterToTree(List<XmlWriter.ToMarshal<? extends XMLStructure>> marshallers, Node parent) {
       
    56         m_marshallers = marshallers;
       
    57         factory = parent instanceof Document ? (Document)parent : parent.getOwnerDocument();
       
    58         currentNode = parent;
       
    59     }
       
    60 
       
    61     /**
       
    62      * Reset to a new parent so that the writer can be re-used.
       
    63      * @param newParent
       
    64      */
       
    65     public void resetToNewParent(Node newParent) {
       
    66         currentNode = newParent;
       
    67         createdElement = null;
       
    68     }
       
    69 
       
    70     /**
       
    71      * Get the root element created with this writer.
       
    72      * @return the root element created with this writer.
       
    73      */
       
    74     public Element getCreatedElement() {
       
    75         return createdElement;
       
    76     }
       
    77 
       
    78     /**
       
    79      * In cases where the serialization is supposed to precede a specific
       
    80      * element, we add an extra parameter to capture that. Only affects the
       
    81      * first element insertion (obviously?).
       
    82      *
       
    83      * @param marshallers
       
    84      * @param parent
       
    85      * @param nextSibling The first element created will be created *before* this element.
       
    86      */
       
    87     public XmlWriterToTree(List<XmlWriter.ToMarshal<? extends XMLStructure>> marshallers, Node parent, Node nextSibling) {
       
    88         this(marshallers, parent);
       
    89         this.nextSibling = nextSibling;
       
    90     }
       
    91 
       
    92     @Override
       
    93     public void writeStartElement(String prefix, String localName, String namespaceURI) {
       
    94         if ("".equals(namespaceURI)) {
       
    95             // Map global namespace from StAX to DOM
       
    96             namespaceURI = null;
       
    97         }
       
    98 
       
    99         Element newElem = factory.createElementNS(namespaceURI, DOMUtils.getQNameString(prefix, localName));
       
   100         if (nextSibling != null) {
       
   101             newElem = (Element)nextSibling.getParentNode().insertBefore(newElem, nextSibling);
       
   102         }
       
   103         else {
       
   104             newElem = (Element)currentNode.appendChild(newElem);
       
   105         }
       
   106         nextSibling = null;
       
   107         currentNode = newElem;
       
   108 
       
   109         if (createdElement == null) {
       
   110             createdElement = newElem;
       
   111         }
       
   112     }
       
   113 
       
   114     @Override
       
   115     public void writeEndElement() {
       
   116         currentNode = currentNode.getParentNode();
       
   117     }
       
   118 
       
   119 
       
   120     @Override
       
   121     public void writeTextElement(String prefix, String localName, String namespaceURI, String value) {
       
   122         writeStartElement(prefix, localName, namespaceURI);
       
   123         writeCharacters(value);
       
   124         writeEndElement();
       
   125     }
       
   126 
       
   127     @Override
       
   128     public void writeNamespace(String prefix, String namespaceURI) {
       
   129         if ("".equals(prefix) || prefix == null) {
       
   130             writeAttribute(null, XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns", namespaceURI);
       
   131         }
       
   132         else {
       
   133             writeAttribute("xmlns", XMLConstants.XMLNS_ATTRIBUTE_NS_URI, prefix, namespaceURI);
       
   134         }
       
   135     }
       
   136 
       
   137     @Override
       
   138     public void writeCharacters(String text) {
       
   139         Text textNode = factory.createTextNode(text);
       
   140         currentNode.appendChild(textNode);
       
   141     }
       
   142 
       
   143 
       
   144     @Override
       
   145     public void writeComment(String text) {
       
   146         Comment commentNode = factory.createComment(text);
       
   147         currentNode.appendChild(commentNode);
       
   148     }
       
   149 
       
   150     @Override
       
   151     public Attr writeAttribute(String prefix, String namespaceURI, String localName, String value) {
       
   152 
       
   153         Attr result = null;
       
   154         if (value != null) {
       
   155             if ("".equals(namespaceURI)) {
       
   156                 // Map global namespace from StAX to DOM
       
   157                 namespaceURI = null;
       
   158             }
       
   159 
       
   160             result = factory.createAttributeNS(namespaceURI, DOMUtils.getQNameString(prefix, localName));
       
   161             result.setTextContent(value);
       
   162             if (! (currentNode instanceof Element)) {
       
   163                 throw new IllegalStateException(
       
   164                         "Attempting to add an attribute to something other than an element node. Node is "
       
   165                                 + currentNode.toString());
       
   166             }
       
   167             ( (Element)currentNode).setAttributeNodeNS(result);
       
   168         }
       
   169         return result;
       
   170     }
       
   171 
       
   172     @Override
       
   173     public void writeIdAttribute(String prefix, String namespaceURI, String localName, String value) {
       
   174         if (value == null) {
       
   175             return;
       
   176         }
       
   177         Attr newAttr = writeAttribute(prefix, namespaceURI, localName, value);
       
   178         ( (Element)currentNode).setIdAttributeNode(newAttr, true);
       
   179     }
       
   180 
       
   181 
       
   182     @Override
       
   183     public String getCurrentLocalName() {
       
   184         return currentNode.getLocalName();
       
   185     }
       
   186 
       
   187     @Override
       
   188     public XMLStructure getCurrentNodeAsStructure() {
       
   189         return new DOMStructure(currentNode);
       
   190     }
       
   191 
       
   192     @Override
       
   193     public void marshalStructure(XMLStructure toMarshal, String dsPrefix, XMLCryptoContext context) throws MarshalException {
       
   194 
       
   195         // look for the first isInstance match, and marshal to that.
       
   196         for (int idx = 0 ; idx < m_marshallers.size() ; idx++) {
       
   197             @SuppressWarnings("unchecked")
       
   198             XmlWriter.ToMarshal<XMLStructure> marshaller = (ToMarshal<XMLStructure>) m_marshallers.get(idx);
       
   199             if (marshaller.clazzToMatch.isInstance(toMarshal)) {
       
   200                 marshaller.marshalObject(this, toMarshal, dsPrefix, context);
       
   201                 return;
       
   202             }
       
   203         }
       
   204         throw new IllegalArgumentException("Unable to marshal unexpected object of class " + toMarshal.getClass().toString());
       
   205     }
       
   206 
       
   207 
       
   208 }