1 package fr.in2p3.jsaga.helpers;
2
3 import fr.in2p3.jsaga.Base;
4 import org.w3c.dom.Document;
5 import org.w3c.dom.Element;
6 import org.xml.sax.SAXException;
7 import org.xml.sax.SAXParseException;
8
9 import javax.xml.parsers.*;
10 import javax.xml.transform.*;
11 import javax.xml.transform.dom.DOMSource;
12 import javax.xml.transform.stream.StreamResult;
13 import java.io.*;
14
15
16
17
18
19
20
21
22
23
24
25
26
27 public class XMLFileParser {
28
29
30
31 private DocumentBuilderFactory m_parser;
32
33 public XMLFileParser(String[] schemaResourcePaths) throws IOException {
34 System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
35 "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
36 System.setProperty("javax.xml.parsers.SAXParserFactory",
37 "org.apache.xerces.jaxp.SAXParserFactoryImpl");
38 System.setProperty("org.apache.xerces.xni.parser.XMLParserConfiguration",
39 "org.apache.xerces.parsers.XIncludeParserConfiguration");
40 m_parser = DocumentBuilderFactory.newInstance();
41 m_parser.setNamespaceAware(true);
42 if (schemaResourcePaths!=null && schemaResourcePaths.length>0) {
43 extractSchemaFiles(schemaResourcePaths);
44 m_parser.setValidating(true);
45 m_parser.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
46 "http://www.w3.org/2001/XMLSchema");
47 m_parser.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource",
48 new File(Base.JSAGA_VAR, schemaResourcePaths[0]).getAbsolutePath());
49 } else {
50 m_parser.setValidating(false);
51 }
52 }
53
54 public XMLFileParser() throws IOException {
55 this(null);
56 }
57
58
59
60
61 public byte[] xinclude(InputStream xmlStream) throws ParserConfigurationException, IOException, SAXException, TransformerException {
62 ByteArrayOutputStream dump = new ByteArrayOutputStream();
63 dump(m_parser.newDocumentBuilder().parse(xmlStream), dump);
64 return dump.toByteArray();
65 }
66
67
68
69
70 public Document parse(InputStream xmlStream, File dumpMergedFile) throws ParserConfigurationException, IOException, SAXException, TransformerException {
71 Document doc;
72 if (m_parser.isValidating()) {
73 DocumentBuilder builder = m_parser.newDocumentBuilder();
74 XMLFileParserExceptionHandler handler = new XMLFileParserExceptionHandler();
75 builder.setErrorHandler(handler);
76 doc = builder.parse(xmlStream);
77 if(handler.getSAXParseException() != null) {
78 SAXParseException e = handler.getSAXParseException();
79 String filename;
80 if (e.getSystemId() != null) {
81 filename = new File(e.getSystemId()).getName();
82 } else {
83 filename = dumpMergedFile.getName();
84 if (dumpMergedFile.getParentFile().mkdirs()) {
85 dump(doc, new FileOutputStream(dumpMergedFile));
86 }
87 }
88 throw new SAXException("["+filename+": "+e.getLineNumber()+"] "+e.getMessage());
89 }
90 } else {
91 DocumentBuilder builder = m_parser.newDocumentBuilder();
92 doc = builder.parse(xmlStream);
93 }
94 return doc;
95 }
96
97 public static void dump(Document doc, OutputStream out) throws TransformerException {
98 dump(doc.getDocumentElement(), out);
99 }
100 public static void dump(Element doc, OutputStream out) throws TransformerException {
101 Transformer transformer = TransformerFactory.newInstance().newTransformer();
102 transformer.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, "xml");
103 transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
104 transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
105 transformer.setOutputProperty("{http://xml.apache.org/xalan/}indent-amount", "4");
106 transformer.transform(new DOMSource(doc), new StreamResult(out));
107 }
108
109 private void extractSchemaFiles(String[] schemaResourcePaths) throws IOException {
110 for (int i=0; schemaResourcePaths!=null && i<schemaResourcePaths.length; i++) {
111 String resourcePath = schemaResourcePaths[i];
112 File schemaFile = new File(Base.JSAGA_VAR, resourcePath);
113 if (!schemaFile.exists()) {
114 InputStream in = getClass().getClassLoader().getResourceAsStream(resourcePath);
115 if (in == null) {
116 throw new IOException("Schema resource not found: "+resourcePath);
117 }
118 schemaFile.getParentFile().mkdirs();
119 copyBytes(in, new FileOutputStream(schemaFile));
120 }
121 }
122 }
123
124 private void copyBytes(InputStream in, OutputStream out) throws IOException {
125 byte[] buffer = new byte[1024];
126 int len;
127 while((len=in.read(buffer))>0) {
128 out.write(buffer, 0, len);
129 }
130 out.close();
131 in.close();
132 }
133 }