Lines 44-77
Link Here
|
44 |
import java.io.CharConversionException; |
44 |
import java.io.CharConversionException; |
45 |
import java.io.IOException; |
45 |
import java.io.IOException; |
46 |
import java.io.OutputStream; |
46 |
import java.io.OutputStream; |
47 |
import java.io.StringReader; |
|
|
48 |
import java.util.ArrayList; |
47 |
import java.util.ArrayList; |
49 |
import java.util.Arrays; |
48 |
import java.util.Arrays; |
50 |
import java.util.HashMap; |
49 |
import java.util.HashMap; |
51 |
import java.util.HashSet; |
|
|
52 |
import java.util.List; |
50 |
import java.util.List; |
53 |
import java.util.logging.Level; |
51 |
import java.util.logging.Level; |
54 |
import java.util.logging.Logger; |
52 |
import java.util.logging.Logger; |
55 |
import java.util.Map; |
53 |
import java.util.Map; |
56 |
import java.util.Set; |
|
|
57 |
import javax.xml.parsers.DocumentBuilder; |
54 |
import javax.xml.parsers.DocumentBuilder; |
58 |
import javax.xml.parsers.DocumentBuilderFactory; |
55 |
import javax.xml.parsers.DocumentBuilderFactory; |
59 |
import javax.xml.parsers.FactoryConfigurationError; |
56 |
import javax.xml.parsers.FactoryConfigurationError; |
60 |
import javax.xml.parsers.ParserConfigurationException; |
57 |
import javax.xml.parsers.ParserConfigurationException; |
61 |
import javax.xml.parsers.SAXParserFactory; |
58 |
import javax.xml.parsers.SAXParserFactory; |
62 |
import javax.xml.transform.OutputKeys; |
|
|
63 |
import javax.xml.transform.Result; |
64 |
import javax.xml.transform.Source; |
65 |
import javax.xml.transform.Transformer; |
66 |
import javax.xml.transform.TransformerFactory; |
67 |
import javax.xml.transform.dom.DOMSource; |
59 |
import javax.xml.transform.dom.DOMSource; |
68 |
import javax.xml.transform.stream.StreamResult; |
|
|
69 |
import javax.xml.transform.stream.StreamSource; |
70 |
import javax.xml.validation.Schema; |
60 |
import javax.xml.validation.Schema; |
71 |
import javax.xml.validation.Validator; |
61 |
import javax.xml.validation.Validator; |
72 |
import org.openide.util.Exceptions; |
62 |
import org.openide.util.Exceptions; |
73 |
import org.w3c.dom.Attr; |
63 |
import org.w3c.dom.Attr; |
74 |
import org.w3c.dom.CDATASection; |
|
|
75 |
import org.w3c.dom.DOMException; |
64 |
import org.w3c.dom.DOMException; |
76 |
import org.w3c.dom.DOMImplementation; |
65 |
import org.w3c.dom.DOMImplementation; |
77 |
import org.w3c.dom.Document; |
66 |
import org.w3c.dom.Document; |
Lines 81-86
Link Here
|
81 |
import org.w3c.dom.Node; |
70 |
import org.w3c.dom.Node; |
82 |
import org.w3c.dom.NodeList; |
71 |
import org.w3c.dom.NodeList; |
83 |
import org.w3c.dom.Text; |
72 |
import org.w3c.dom.Text; |
|
|
73 |
import org.w3c.dom.ls.DOMImplementationLS; |
74 |
import org.w3c.dom.ls.LSOutput; |
75 |
import org.w3c.dom.ls.LSSerializer; |
84 |
import org.xml.sax.EntityResolver; |
76 |
import org.xml.sax.EntityResolver; |
85 |
import org.xml.sax.ErrorHandler; |
77 |
import org.xml.sax.ErrorHandler; |
86 |
import org.xml.sax.InputSource; |
78 |
import org.xml.sax.InputSource; |
Lines 355-381
Link Here
|
355 |
} |
347 |
} |
356 |
|
348 |
|
357 |
/** |
349 |
/** |
358 |
* Identity transformation in XSLT with indentation added. |
|
|
359 |
* Just using the identity transform and calling |
360 |
* t.setOutputProperty(OutputKeys.INDENT, "yes"); |
361 |
* t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); |
362 |
* does not work currently. |
363 |
* You really have to use this bogus stylesheet. |
364 |
* @see "JDK bug #5064280" |
365 |
*/ |
366 |
private static final String IDENTITY_XSLT_WITH_INDENT = |
367 |
"<xsl:stylesheet version='1.0' " + // NOI18N |
368 |
"xmlns:xsl='http://www.w3.org/1999/XSL/Transform' " + // NOI18N |
369 |
"xmlns:xalan='http://xml.apache.org/xslt' " + // NOI18N |
370 |
"exclude-result-prefixes='xalan'>" + // NOI18N |
371 |
"<xsl:output method='xml' indent='yes' xalan:indent-amount='4'/>" + // NOI18N |
372 |
"<xsl:template match='@*|node()'>" + // NOI18N |
373 |
"<xsl:copy>" + // NOI18N |
374 |
"<xsl:apply-templates select='@*|node()'/>" + // NOI18N |
375 |
"</xsl:copy>" + // NOI18N |
376 |
"</xsl:template>" + // NOI18N |
377 |
"</xsl:stylesheet>"; // NOI18N |
378 |
/** |
379 |
* Writes a DOM document to a stream. |
350 |
* Writes a DOM document to a stream. |
380 |
* The precise output format is not guaranteed but this method will attempt to indent it sensibly. |
351 |
* The precise output format is not guaranteed but this method will attempt to indent it sensibly. |
381 |
* |
352 |
* |
Lines 398-455
Link Here
|
398 |
throw new NullPointerException("You must set an encoding; use \"UTF-8\" unless you have a good reason not to!"); // NOI18N |
369 |
throw new NullPointerException("You must set an encoding; use \"UTF-8\" unless you have a good reason not to!"); // NOI18N |
399 |
} |
370 |
} |
400 |
Document doc2 = normalize(doc); |
371 |
Document doc2 = normalize(doc); |
401 |
try { |
372 |
DOMImplementationLS ls = (DOMImplementationLS) doc2.getImplementation().getFeature("LS", "3.0"); // NOI18N |
402 |
Transformer t = TransformerFactory.newInstance().newTransformer( |
373 |
assert ls != null : "No DOM 3 LS supported in " + doc2.getClass().getName(); |
403 |
new StreamSource(new StringReader(IDENTITY_XSLT_WITH_INDENT))); |
374 |
LSOutput output = ls.createLSOutput(); |
404 |
DocumentType dt = doc2.getDoctype(); |
375 |
output.setEncoding(enc); |
405 |
if (dt != null) { |
376 |
output.setByteStream(out); |
406 |
String pub = dt.getPublicId(); |
377 |
LSSerializer ser = ls.createLSSerializer(); |
407 |
if (pub != null) { |
378 |
String fpp = "format-pretty-print"; // NOI18N |
408 |
t.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, pub); |
379 |
if (ser.getDomConfig().canSetParameter(fpp, true)) { |
409 |
} |
380 |
ser.getDomConfig().setParameter(fpp, true); |
410 |
String sys = dt.getSystemId(); |
|
|
411 |
if (sys != null) { |
412 |
t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, sys); |
413 |
} |
414 |
} |
415 |
t.setOutputProperty(OutputKeys.ENCODING, enc); |
416 |
|
417 |
// See #123816 |
418 |
Set<String> cdataQNames = new HashSet<String>(); |
419 |
collectCDATASections(doc2, cdataQNames); |
420 |
if (cdataQNames.size() > 0) { |
421 |
StringBuilder cdataSections = new StringBuilder(); |
422 |
for(String s : cdataQNames) { |
423 |
cdataSections.append(s).append(' '); //NOI18N |
424 |
} |
425 |
t.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, cdataSections.toString()); |
426 |
} |
427 |
|
428 |
Source source = new DOMSource(doc2); |
429 |
Result result = new StreamResult(out); |
430 |
t.transform(source, result); |
431 |
} catch (Exception e) { |
432 |
throw new IOException(e); |
433 |
} |
381 |
} |
434 |
} |
382 |
ser.write(doc2, output); |
435 |
|
|
|
436 |
private static void collectCDATASections(Node node, Set<String> cdataQNames) { |
437 |
if (node instanceof CDATASection) { |
438 |
Node parent = node.getParentNode(); |
439 |
if (parent != null) { |
440 |
String uri = parent.getNamespaceURI(); |
441 |
if (uri != null) { |
442 |
cdataQNames.add("{" + uri + "}" + parent.getNodeName()); //NOI18N |
443 |
} else { |
444 |
cdataQNames.add(parent.getNodeName()); |
445 |
} |
446 |
} |
447 |
} |
448 |
|
449 |
NodeList children = node.getChildNodes(); |
450 |
for(int i = 0; i < children.getLength(); i++) { |
451 |
collectCDATASections(children.item(i), cdataQNames); |
452 |
} |
453 |
} |
383 |
} |
454 |
|
384 |
|
455 |
/** |
385 |
/** |