blob: d82fed424a970d29afc1eb4338a7aa717bc4eef3 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
package com.sun.star.script.framework.container;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.xml.parsers.*;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class XMLParserFactory {
private static XMLParser parser = null;
private static String officedtdurl = null;
private XMLParserFactory() {}
public static XMLParser getParser() {
if (parser == null) {
synchronized (XMLParserFactory.class) {
if (parser == null)
parser = new DefaultParser();
}
}
return parser;
}
public static void setParser(XMLParser p) {
parser = p;
}
public static void setOfficeDTDURL(String url) {
officedtdurl = url;
}
private static class DefaultParser implements XMLParser {
private DocumentBuilderFactory factory;
public DefaultParser() {
factory = DocumentBuilderFactory.newInstance();
}
public Document parse(InputStream inputStream) throws IOException {
Document result = null;
InputSource is = null;
try {
DocumentBuilder builder = factory.newDocumentBuilder();
is = new InputSource(inputStream);
if (officedtdurl != null) {
is.setSystemId(officedtdurl);
}
result = builder.parse(is);
}
catch (SAXParseException spe) {
throw new IOException(spe.getMessage());
}
catch (SAXException se) {
throw new IOException(se.getMessage());
}
catch (ParserConfigurationException pce) {
throw new IOException(pce.getMessage());
}
return result;
}
public void write(Document doc, OutputStream out) throws IOException {
Class clazz = doc.getClass();
String name = clazz.getName();
// depending on the class of the Document object use introspection
// to invoke the appropriate methods for writing the XML
// this code is based on the code used by the NetBeans
// class XMLUtilImpl in the openide module
try {
if (name.equals("com.sun.xml.tree.XmlDocument") ||
name.equals("org.apache.crimson.tree.XmlDocument")) {
// these DOM implementations are self writing
Method write;
write = clazz.getDeclaredMethod("write",
new Class[] {OutputStream.class});
write.invoke(doc, new Object[] {out});
}
else {
// try xerces serialize package using introspection
ClassLoader cl = this.getClass().getClassLoader();
Class serializerClass = null;
Class formatterClass = null;
try {
serializerClass = Class.forName(
"org.apache.xml.serialize.XMLSerializer", true, cl);
formatterClass = Class.forName(
"org.apache.xml.serialize.OutputFormat", true, cl);
} catch (ClassNotFoundException cnfe) {
String prefix = "com.sun.org.apache.xml.internal.";
serializerClass = Class.forName(
prefix + "serialize.XMLSerializer" , true, cl);
formatterClass = Class.forName(
prefix + "serialize.OutputFormat", true, cl);
}
Object serializerObject = serializerClass.newInstance();
Object formatterObject = formatterClass.newInstance();
// improve output readability using the OutputFormat class
Method method = null;
method = formatterClass.getMethod("setMethod",
new Class[] {String.class});
method.invoke(formatterObject, new Object[] {"xml"});
method = formatterClass.getMethod("setIndenting",
new Class[] {Boolean.TYPE});
method.invoke(formatterObject, new Object[] {Boolean.TRUE});
// now set up an instance of XMLSerializer with our
// OutputStream and serialize our Document
method = serializerClass.getMethod("setOutputByteStream",
new Class[] {OutputStream.class});
method.invoke(serializerObject, new Object[] {out});
method = serializerClass.getMethod("setOutputFormat",
new Class[] {formatterClass});
method.invoke(serializerObject,
new Object[] {formatterObject});
method = serializerClass.getMethod("asDOMSerializer",
new Class[0]);
Object impl = method.invoke(serializerObject,
new Object[0]);
method = impl.getClass().getMethod("serialize",
new Class[] {Document.class});
method.invoke(impl, new Object[] {doc});
}
} catch (NoSuchMethodException ex) {
throw new IOException(ex.getMessage());
} catch (ClassNotFoundException ex) {
throw new IOException(ex.getMessage());
} catch (Exception ex) {
throw new IOException(ex.getMessage());
}
}
}
}