#123816 - better support for CDATA sections beforemerge_newconfigsupport partial_reparse_t2b_b versionability_89629_base_10 versionability_89629_base_11 versionability_89629_base_9
authorvstejskal@netbeans.org
Thu, 10 Jan 2008 13:45:24 +0000
changeset 319b5d1bdca7357
parent 318 c316f82dc25c
child 320 ea7d449f606f
#123816 - better support for CDATA sections
openide.util/src/org/openide/xml/XMLUtil.java
     1.1 --- a/openide.util/src/org/openide/xml/XMLUtil.java	Wed Jan 09 16:58:12 2008 +0000
     1.2 +++ b/openide.util/src/org/openide/xml/XMLUtil.java	Thu Jan 10 13:45:24 2008 +0000
     1.3 @@ -45,6 +45,8 @@
     1.4  import java.io.IOException;
     1.5  import java.io.OutputStream;
     1.6  import java.io.StringReader;
     1.7 +import java.util.HashSet;
     1.8 +import java.util.Set;
     1.9  import javax.xml.parsers.DocumentBuilder;
    1.10  import javax.xml.parsers.DocumentBuilderFactory;
    1.11  import javax.xml.parsers.ParserConfigurationException;
    1.12 @@ -58,6 +60,7 @@
    1.13  import javax.xml.transform.stream.StreamResult;
    1.14  import javax.xml.transform.stream.StreamSource;
    1.15  import org.openide.util.Lookup;
    1.16 +import org.w3c.dom.CDATASection;
    1.17  import org.w3c.dom.DOMException;
    1.18  import org.w3c.dom.DOMImplementation;
    1.19  import org.w3c.dom.Document;
    1.20 @@ -351,6 +354,15 @@
    1.21       * Writes a DOM document to a stream.
    1.22       * The precise output format is not guaranteed but this method will attempt to indent it sensibly.
    1.23       * 
    1.24 +     * <p class="nonnormative"><b>Important</b>: There might be some problems with
    1.25 +     * <code>&lt;![CDATA[ ]]&gt;</code> sections in the DOM tree you pass into this method. Specifically,
    1.26 +     * some CDATA sections my not be written as CDATA section or may be merged with
    1.27 +     * other CDATA section at the same level. Also if plain text nodes are mixed with
    1.28 +     * CDATA sections at the same level all text is likely to end up in one big CDATA section.
    1.29 +     * <br/>
    1.30 +     * For nodes that only have one CDATA section this method should work fine.
    1.31 +     * </p>
    1.32 +     * 
    1.33       * @param doc DOM document to be written
    1.34       * @param out data sink
    1.35       * @param enc XML-defined encoding name (e.g. "UTF-8")
    1.36 @@ -403,6 +415,18 @@
    1.37                  t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, dt.getSystemId());
    1.38              }
    1.39              t.setOutputProperty(OutputKeys.ENCODING, enc);
    1.40 +
    1.41 +            // See #123816
    1.42 +            Set<String> cdataQNames = new HashSet<String>();
    1.43 +            collectCDATASections(doc2, cdataQNames);
    1.44 +            if (cdataQNames.size() > 0) {
    1.45 +                StringBuilder cdataSections = new StringBuilder();
    1.46 +                for(String s : cdataQNames) {
    1.47 +                    cdataSections.append(s).append(' '); //NOI18N
    1.48 +                }
    1.49 +                t.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, cdataSections.toString());
    1.50 +            }
    1.51 +            
    1.52              Source source = new DOMSource(doc2);
    1.53              Result result = new StreamResult(out);
    1.54              t.transform(source, result);
    1.55 @@ -413,6 +437,25 @@
    1.56          }
    1.57      }
    1.58  
    1.59 +    private static void collectCDATASections(Node node, Set<String> cdataQNames) {
    1.60 +        if (node instanceof CDATASection) {
    1.61 +            Node parent = node.getParentNode();
    1.62 +            if (parent != null) {
    1.63 +                String uri = parent.getNamespaceURI();
    1.64 +                if (uri != null) {
    1.65 +                    cdataQNames.add("{" + uri + "}" + parent.getNodeName()); //NOI18N
    1.66 +                } else {
    1.67 +                    cdataQNames.add(parent.getNodeName());
    1.68 +                }
    1.69 +            }
    1.70 +        }
    1.71 +        
    1.72 +        NodeList children = node.getChildNodes();
    1.73 +        for(int i = 0; i < children.getLength(); i++) {
    1.74 +            collectCDATASections(children.item(i), cdataQNames);
    1.75 +        }
    1.76 +    }
    1.77 +    
    1.78      /**
    1.79       * Escape passed string as XML attibute value
    1.80       * (<code>&lt;</code>, <code>&amp;</code>, <code>'</code> and <code>"</code>