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