/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun * Microsystems, Inc. All Rights Reserved. */ package org.openide.xml; import java.io.*; import java.util.*; import java.lang.reflect.*; import javax.xml.parsers.*; import org.xml.sax.*; import org.w3c.dom.Document; import org.openide.util.Lookup; import org.openide.ErrorManager; /** * This backend class for XMLUtil contains implementation of DOM implementation * "independent" write method. * * @author Petr Kuzel * @version reflection based implemetation */ class XMLUtilImpl extends Object { /** * Write Document into out using introspection. * * @param out must be Writer or OutputStream * @param XML encoding name (ignored parametr) */ static void write(Document doc, Object out, String encoding) throws IOException { Class dock = doc.getClass(); // no implementation neutral write exist try { if ("com.sun.xml.tree.XmlDocument".equals(dock.getName()) //NOI18N || "org.apache.crimson.tree.XmlDocument".equals(dock.getName())) { //NOI18N // these DOM implementations are self writing Method write; if (out instanceof Writer) { write = dock.getDeclaredMethod("write", new Class[] {Writer.class});//NOI18N } else { write = dock.getDeclaredMethod("write", new Class[] {OutputStream.class});//NOI18N } write.invoke(doc,new Object[] {out}); } else { // try apache's serialize package // using introspection because calling implementation // specific methods // may change as they prove to be stable ClassLoader cl = (ClassLoader)Lookup.getDefault().lookup(ClassLoader.class); if (cl == null) cl = XMLUtilImpl.class.getClassLoader(); Class serka = Class.forName("org.apache.xml.serialize.XMLSerializer", true, cl); //NOI18N Class forka = Class.forName("org.apache.xml.serialize.OutputFormat", true, cl); //NOI18N Object serin = serka.newInstance(); Object forin = forka.newInstance(); // hopefully it could improve output readability Method setmet = null; setmet = forka.getMethod("setMethod", new Class[] {String.class}); //NOI18N setmet.invoke(forin, new Object[] {"xml"}); //NOI18N setmet = forka.getMethod("setIndenting", new Class[] {Boolean.TYPE}); //NOI18N setmet.invoke(forin, new Object[] {Boolean.TRUE}); //NOI18N setmet = forka.getMethod("setLineWidth", new Class[] {Integer.TYPE}); //NOI18N setmet.invoke(forin, new Object[] {new Integer(0)}); //NOI18N String detectedEncoding = null; Method init; if (out instanceof OutputStream) { init = serka.getMethod("setOutputByteStream", new Class[] {OutputStream.class}); //NOI18N init.invoke(serin, new Object[] {out}); // set encoding in output format detectedEncoding = encoding; } else if (out instanceof Writer) { init = serka.getMethod("setOutputCharStream", new Class[] {Writer.class}); //NOI18N init.invoke(serin, new Object[] {out}); //detect (same as Crimson did) and set encoding if (out instanceof OutputStreamWriter) { detectedEncoding = ((OutputStreamWriter)out).getEncoding(); // no general way how to transorm XML encoding names to Java names // and vice versa detectedEncoding = null; } else { detectedEncoding = null; } } else { throw new ClassCastException("OutputStream or Writer expected."); //NOI18N } Method setenc = forka.getMethod("setEncoding", new Class[] {String.class}); //NOI18N setenc.invoke(forin, new Object[] {detectedEncoding} ); Method setout = serka.getMethod("setOutputFormat", new Class[] {forka}); //NOI18N setout.invoke(serin, new Object[] {forin}); Method asDOM = serka.getMethod("asDOMSerializer", new Class[0]);//NOI18N Object impl = asDOM.invoke(serin, new Object[0]); Method serialize = impl.getClass().getMethod("serialize", new Class[] {Document.class}); //NOI18N serialize.invoke(impl, new Object[] {doc}); } } catch (IllegalAccessException ex) { handleImplementationException(ex); } catch (InstantiationException ex) { handleImplementationException(ex); } catch (IllegalArgumentException ex) { handleImplementationException(ex); } catch (NoSuchMethodException ex) { handleImplementationException(ex); } catch (ClassNotFoundException ex) { handleImplementationException(ex); } catch (InvocationTargetException ex) { handleTargetException(ex); } } /** TargetException handler */ private static void handleTargetException(InvocationTargetException ex) throws IOException { Throwable t = ex.getTargetException(); if (t instanceof IOException) { throw (IOException) t; } else if (t instanceof RuntimeException) { throw (RuntimeException) t; } else if (t instanceof Error) { throw (Error) t; } } private static void handleImplementationException(Exception ex) throws IOException { ErrorManager err = ErrorManager.getDefault(); IOException explained = new IOException("Unsupported DOM document implementation!"); // NOI18N err.annotate(explained, ex); throw explained; } }