1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package com.sun.star.script.framework.container;
25 
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.io.IOException;
29 import java.lang.reflect.Method;
30 
31 import javax.xml.parsers.*;
32 import org.w3c.dom.Document;
33 import org.xml.sax.InputSource;
34 import org.xml.sax.SAXException;
35 import org.xml.sax.SAXParseException;
36 
37 public class XMLParserFactory {
38 
39     private static XMLParser parser = null;
40     private static String officedtdurl = null;
41 
XMLParserFactory()42     private XMLParserFactory() {}
43 
getParser()44     public static XMLParser getParser() {
45         if (parser == null) {
46             synchronized (XMLParserFactory.class) {
47                 if (parser == null)
48                     parser = new DefaultParser();
49             }
50         }
51         return parser;
52     }
53 
setParser(XMLParser p)54     public static void setParser(XMLParser p) {
55         parser = p;
56     }
57 
setOfficeDTDURL(String url)58     public static void setOfficeDTDURL(String url) {
59         officedtdurl = url;
60     }
61 
62     private static class DefaultParser implements XMLParser {
63 
64         private DocumentBuilderFactory factory;
65 
DefaultParser()66         public DefaultParser() {
67             factory = DocumentBuilderFactory.newInstance();
68         }
69 
parse(InputStream inputStream)70         public Document parse(InputStream inputStream) throws IOException {
71             Document result = null;
72             InputSource is = null;
73 
74             try {
75                 DocumentBuilder builder = factory.newDocumentBuilder();
76 
77                 is = new InputSource(inputStream);
78 
79                 if (officedtdurl != null) {
80                     is.setSystemId(officedtdurl);
81                 }
82 
83                 result = builder.parse(is);
84             }
85             catch (SAXParseException spe) {
86                 throw new IOException(spe.getMessage());
87             }
88             catch (SAXException se) {
89                 throw new IOException(se.getMessage());
90             }
91             catch (ParserConfigurationException pce) {
92                 throw new IOException(pce.getMessage());
93             }
94             return result;
95         }
96 
write(Document doc, OutputStream out)97         public void write(Document doc, OutputStream out) throws IOException {
98             Class clazz = doc.getClass();
99             String name = clazz.getName();
100 
101             // depending on the class of the Document object use introspection
102             // to invoke the appropriate methods for writing the XML
103             // this code is based on the code used by the NetBeans
104             // class XMLUtilImpl in the openide module
105             try {
106                 if (name.equals("com.sun.xml.tree.XmlDocument") ||
107                     name.equals("org.apache.crimson.tree.XmlDocument")) {
108 
109                     // these DOM implementations are self writing
110                     Method write;
111                     write = clazz.getDeclaredMethod("write",
112                         new Class[] {OutputStream.class});
113                     write.invoke(doc, new Object[] {out});
114                 }
115                 else {
116                     // try xerces serialize package using introspection
117                     ClassLoader cl = this.getClass().getClassLoader();
118 
119                     Class serializerClass = null;
120                     Class formatterClass = null;
121 
122                     try {
123                         serializerClass = Class.forName(
124                             "org.apache.xml.serialize.XMLSerializer", true, cl);
125                         formatterClass = Class.forName(
126                             "org.apache.xml.serialize.OutputFormat", true, cl);
127                     } catch (ClassNotFoundException cnfe) {
128                         String prefix = "com.sun.org.apache.xml.internal.";
129 
130                         serializerClass = Class.forName(
131                             prefix +  "serialize.XMLSerializer" , true, cl);
132                         formatterClass = Class.forName(
133                             prefix + "serialize.OutputFormat", true, cl);
134                     }
135 
136                     Object serializerObject = serializerClass.newInstance();
137                     Object formatterObject = formatterClass.newInstance();
138 
139                     // improve output readability using the OutputFormat class
140                     Method method = null;
141                     method = formatterClass.getMethod("setMethod",
142                         new Class[] {String.class});
143                     method.invoke(formatterObject, new Object[] {"xml"});
144                     method = formatterClass.getMethod("setIndenting",
145                         new Class[] {Boolean.TYPE});
146                     method.invoke(formatterObject, new Object[] {Boolean.TRUE});
147 
148                     // now set up an instance of XMLSerializer with our
149                     // OutputStream and serialize our Document
150                     method = serializerClass.getMethod("setOutputByteStream",
151                         new Class[] {OutputStream.class});
152                     method.invoke(serializerObject, new Object[] {out});
153                     method = serializerClass.getMethod("setOutputFormat",
154                         new Class[] {formatterClass});
155                     method.invoke(serializerObject,
156                         new Object[] {formatterObject});
157 
158                     method = serializerClass.getMethod("asDOMSerializer",
159                         new Class[0]);
160                     Object impl = method.invoke(serializerObject,
161                         new Object[0]);
162 
163                     method = impl.getClass().getMethod("serialize",
164                         new Class[] {Document.class});
165                     method.invoke(impl, new Object[] {doc});
166                 }
167             } catch (NoSuchMethodException ex) {
168                 throw new IOException(ex.getMessage());
169             } catch (ClassNotFoundException ex) {
170                 throw new IOException(ex.getMessage());
171             } catch (Exception ex) {
172                 throw new IOException(ex.getMessage());
173             }
174         }
175     }
176 }
177