1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 package com.sun.star.script.framework.container; 29 30 import java.io.InputStream; 31 import java.io.OutputStream; 32 import java.io.IOException; 33 import java.lang.reflect.Method; 34 35 import javax.xml.parsers.*; 36 import org.w3c.dom.Document; 37 import org.xml.sax.InputSource; 38 import org.xml.sax.SAXException; 39 import org.xml.sax.SAXParseException; 40 41 public class XMLParserFactory { 42 43 private static XMLParser parser = null; 44 private static String officedtdurl = null; 45 46 private XMLParserFactory() {} 47 48 public static XMLParser getParser() { 49 if (parser == null) { 50 synchronized (XMLParserFactory.class) { 51 if (parser == null) 52 parser = new DefaultParser(); 53 } 54 } 55 return parser; 56 } 57 58 public static void setParser(XMLParser p) { 59 parser = p; 60 } 61 62 public static void setOfficeDTDURL(String url) { 63 officedtdurl = url; 64 } 65 66 private static class DefaultParser implements XMLParser { 67 68 private DocumentBuilderFactory factory; 69 70 public DefaultParser() { 71 factory = DocumentBuilderFactory.newInstance(); 72 } 73 74 public Document parse(InputStream inputStream) throws IOException { 75 Document result = null; 76 InputSource is = null; 77 78 try { 79 DocumentBuilder builder = factory.newDocumentBuilder(); 80 81 is = new InputSource(inputStream); 82 83 if (officedtdurl != null) { 84 is.setSystemId(officedtdurl); 85 } 86 87 result = builder.parse(is); 88 } 89 catch (SAXParseException spe) { 90 throw new IOException(spe.getMessage()); 91 } 92 catch (SAXException se) { 93 throw new IOException(se.getMessage()); 94 } 95 catch (ParserConfigurationException pce) { 96 throw new IOException(pce.getMessage()); 97 } 98 return result; 99 } 100 101 public void write(Document doc, OutputStream out) throws IOException { 102 Class clazz = doc.getClass(); 103 String name = clazz.getName(); 104 105 // depending on the class of the Document object use introspection 106 // to invoke the appropriate methods for writing the XML 107 // this code is based on the code used by the NetBeans 108 // class XMLUtilImpl in the openide module 109 try { 110 if (name.equals("com.sun.xml.tree.XmlDocument") || 111 name.equals("org.apache.crimson.tree.XmlDocument")) { 112 113 // these DOM implementations are self writing 114 Method write; 115 write = clazz.getDeclaredMethod("write", 116 new Class[] {OutputStream.class}); 117 write.invoke(doc, new Object[] {out}); 118 } 119 else { 120 // try xerces serialize package using introspection 121 ClassLoader cl = this.getClass().getClassLoader(); 122 123 Class serializerClass = null; 124 Class formatterClass = null; 125 126 try { 127 serializerClass = Class.forName( 128 "org.apache.xml.serialize.XMLSerializer", true, cl); 129 formatterClass = Class.forName( 130 "org.apache.xml.serialize.OutputFormat", true, cl); 131 } catch (ClassNotFoundException cnfe) { 132 String prefix = "com.sun.org.apache.xml.internal."; 133 134 serializerClass = Class.forName( 135 prefix + "serialize.XMLSerializer" , true, cl); 136 formatterClass = Class.forName( 137 prefix + "serialize.OutputFormat", true, cl); 138 } 139 140 Object serializerObject = serializerClass.newInstance(); 141 Object formatterObject = formatterClass.newInstance(); 142 143 // improve output readability using the OutputFormat class 144 Method method = null; 145 method = formatterClass.getMethod("setMethod", 146 new Class[] {String.class}); 147 method.invoke(formatterObject, new Object[] {"xml"}); 148 method = formatterClass.getMethod("setIndenting", 149 new Class[] {Boolean.TYPE}); 150 method.invoke(formatterObject, new Object[] {Boolean.TRUE}); 151 152 // now set up an instance of XMLSerializer with our 153 // OutputStream and serialize our Document 154 method = serializerClass.getMethod("setOutputByteStream", 155 new Class[] {OutputStream.class}); 156 method.invoke(serializerObject, new Object[] {out}); 157 method = serializerClass.getMethod("setOutputFormat", 158 new Class[] {formatterClass}); 159 method.invoke(serializerObject, 160 new Object[] {formatterObject}); 161 162 method = serializerClass.getMethod("asDOMSerializer", 163 new Class[0]); 164 Object impl = method.invoke(serializerObject, 165 new Object[0]); 166 167 method = impl.getClass().getMethod("serialize", 168 new Class[] {Document.class}); 169 method.invoke(impl, new Object[] {doc}); 170 } 171 } catch (NoSuchMethodException ex) { 172 throw new IOException(ex.getMessage()); 173 } catch (ClassNotFoundException ex) { 174 throw new IOException(ex.getMessage()); 175 } catch (Exception ex) { 176 throw new IOException(ex.getMessage()); 177 } 178 } 179 } 180 } 181