KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > convertor > Convertors


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.api.convertor;
21
22 import java.beans.PropertyChangeListener JavaDoc;
23 import java.beans.PropertyChangeSupport JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.OutputStream JavaDoc;
27 import java.util.Properties JavaDoc;
28 import java.util.Set JavaDoc;
29 import javax.xml.parsers.DocumentBuilder JavaDoc;
30 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
31 import javax.xml.parsers.FactoryConfigurationError JavaDoc;
32 import javax.xml.parsers.ParserConfigurationException JavaDoc;
33 import org.netbeans.modules.convertor.Accessor;
34 import org.netbeans.modules.convertor.ConvertorsPool;
35 import org.netbeans.spi.convertor.Convertor;
36 import org.openide.ErrorManager;
37 import org.openide.xml.EntityCatalog;
38 import org.openide.xml.XMLUtil;
39 import org.w3c.dom.Document JavaDoc;
40 import org.w3c.dom.Element JavaDoc;
41 import org.xml.sax.InputSource JavaDoc;
42 import org.xml.sax.SAXException JavaDoc;
43
44 /**
45  * Main API class with methods allowing conversion of object to
46  * namespace aware XML fragment and recreation of object from that fragment.
47  * Apart from methods doing the conversions there is couple of other
48  * helper methods, for example for listing all currently supported conversions
49  * that is listing of available convertor descriptors; listening on changes of available
50  * convertors; methods for testing convertibility of the XML fragment or object, etc.
51  *
52  * @author David Konecny
53  */

54 public final class Convertors {
55
56     /** Property name of the list of convertor descriptors */
57     public static final String JavaDoc CONVERTOR_DESCRIPTORS = "convertorDescriptors"; // NOI18N
58

59     private java.beans.PropertyChangeSupport JavaDoc support;
60
61     private static Convertors DEFAULT = new Convertors();
62     
63     private static DocumentBuilderFactory JavaDoc factory;
64     private static DocumentBuilder JavaDoc builder;
65     
66     // Yarda's Accessor Pattern in practise
67
static {
68         Accessor.DEFAULT = new AccessorImpl();
69     }
70
71     private Convertors() {
72         support = new PropertyChangeSupport JavaDoc(this);
73     }
74
75     /** Get default instance of Convertors class. Can be used for listing of
76      * convertor descriptors and for listening on changes in that list.
77      *
78      * @return singleton instance of Convertors class
79      */

80     public static Convertors getDefault() {
81         return DEFAULT;
82     }
83     
84
85     private static DocumentBuilderFactory JavaDoc getDocumentBuilderFactory() {
86         if (factory == null) {
87             //TODO: suspicious impl. - evaluate
88
// XXX Crimson documents do not seem to work too well; e.g. create a document element
89
// with a namespace and attributes, and Xerces will not write out the attributes
90
try {
91                 String JavaDoc prop = "javax.xml.parsers.DocumentBuilderFactory"; // NOI18N
92
Properties JavaDoc p = System.getProperties();
93                 String JavaDoc old = p.getProperty(prop);
94                 try {
95                     p.setProperty(prop, "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"); // NOI18N
96
factory = DocumentBuilderFactory.newInstance();
97                 } finally {
98                     if (old != null) {
99                         p.setProperty(prop, old);
100                     } else {
101                         p.remove(prop);
102                     }
103                 }
104             } catch (FactoryConfigurationError JavaDoc e) {
105                 // OK, Xerces didn't work, try the default configuration and hope.
106
factory = DocumentBuilderFactory.newInstance();
107             }
108             factory = DocumentBuilderFactory.newInstance();
109             factory.setNamespaceAware(true);
110             factory.setValidating(false);
111             // Please read follwing about why are these here:
112
// http://www-106.ibm.com/developerworks/xml/library/x-perfap2.html
113
factory.setAttribute("http://apache.org/xml/properties/dom/document-class-name", "org.apache.xerces.dom.CoreDocumentImpl");
114             factory.setAttribute("http://apache.org/xml/features/dom/defer-node-expansion", Boolean.FALSE);
115         }
116         return factory;
117     }
118
119     
120     private static DocumentBuilder JavaDoc getDocumentBuilder() throws ParserConfigurationException JavaDoc {
121         if (builder == null) {
122             builder = getDocumentBuilderFactory().newDocumentBuilder();
123             builder.setEntityResolver(EntityCatalog.getDefault());
124         }
125         return builder;
126     }
127     
128     static Document JavaDoc createDocument() {
129         Document JavaDoc doc = null;
130         try {
131             doc = getDocumentBuilder().newDocument();
132         } catch (ParserConfigurationException JavaDoc ex) {
133             ErrorManager.getDefault().log(ErrorManager.WARNING, "Could not create instance of new dom.Document.\n" + ex.toString());
134             return null;
135         }
136         return doc;
137     }
138     
139     /**
140      * Is there a convertor for the given XML element?
141      *
142      * @param element XML element to convertor; cannot be null
143      * @return true if this element can be converted to an object
144      */

145     public static boolean canRead(Element JavaDoc element) {
146         if (element == null) {
147             throw new IllegalArgumentException JavaDoc("Element cannot be null."); // NOI18N
148
}
149         return canRead(element.getNamespaceURI(), element.getNodeName());
150     }
151     
152     /**
153      * Is there a convertor for the given XML namespace and element name?
154      *
155      * @param namespace XML namespace; cannot be null
156      * @param element element name; cannot be null
157      * @return true if element with this name from this namespace can be converted to an object
158      */

159     public static boolean canRead(String JavaDoc namespace, String JavaDoc element) {
160         if (namespace == null || element == null) {
161             throw new IllegalArgumentException JavaDoc("Namespace and element cannot be null."); // NOI18N
162
}
163         return ConvertorsPool.getDefault().getReadConvertor(namespace, element) != null;
164     }
165     
166     /**
167      * Is there a convertor for the given object?
168      *
169      * @param o an object; cannot be null
170      * @return true if there is registered convertor for the given object class
171      */

172     public static boolean canWrite(Object JavaDoc o) {
173         if (o == null) {
174             throw new IllegalArgumentException JavaDoc("Object cannot be null."); // NOI18N
175
}
176         return ConvertorsPool.getDefault().getWriteConvertor(o) != null;
177     }
178     
179     /**
180      * Creates instance from the given XML namespace aware fragment.
181      * See also {@link #canRead} for how to test whether the element
182      * is convertible or not.
183      *
184      * @param element XML namespace aware element which will be converted to
185      * an object; cannot be null
186      * @return instance of the object created from the element; cannot be null
187      * @throws ConvertorException thrown when there is no convertor for the
188      * passed element or when there was a runtime error during conversion.
189      * Client should call {@link #canRead} to prevent this exception.
190      */

191     public static Object JavaDoc read(Element JavaDoc element) {
192         ConvertorDescriptor cd = ConvertorsPool.getDefault().getReadConvertor(element.getNamespaceURI(), element.getNodeName());
193         if (cd == null) {
194             throw new ConvertorException("There is no convertor registered "+ // NOI18N
195
"for element with namespace URI "+element.getNamespaceURI()); // NOI18N
196
}
197         return cd.getConvertor().read(element);
198     }
199     
200     /**
201      * Creates instance from the given input stream. The stream is expected
202      * to contain namespace aware XML document otherwise the SAXException
203      * is thrown. It is also expected that convertor exists for the root element
204      * of this XML document otherwise IOException is thrown. See also
205      * {@link #read(Element)}.
206      *
207      * @param is input stream containing XML namespace aware document
208      * @return instance of the object created from the stream; cannot be null
209      * @throws SAXException thrown when input stream does not contain valid XML document
210      * @throws IOException thrown when XML document cannot be read from input
211      * stream or when convertor does not exist for root element of XML document.
212      * @throws ConvertorException thrown when there was a runtime error
213      * during conversion.
214      */

215     public static Object JavaDoc read(InputStream JavaDoc is) throws SAXException JavaDoc, IOException JavaDoc {
216         InputSource JavaDoc iss = new InputSource JavaDoc(is);
217         Document JavaDoc doc = XMLUtil.parse(iss, false, true, null, null);
218         if (!canRead(doc.getDocumentElement())) {
219             throw new IOException JavaDoc("Stream cannot be converted. "+ // NOI18N
220
"There is no convertor for element "+doc.getDocumentElement()); // NOI18N
221
}
222         return read(doc.getDocumentElement());
223     }
224     
225     /**
226      * Converts the object to XML namespace aware fragment.
227      *
228      * @param doc document to which the returned element should belong
229      * @param o object to convert
230      * @return element describing converted object
231      * @throws ConvertorException thrown when there is no convertor for the
232      * passed object or when there was a runtime error during conversion.
233      * Client should call {@link #canWrite} to prevent this exception.
234      */

235     public static Element JavaDoc write(Document JavaDoc doc, Object JavaDoc o) {
236         ConvertorDescriptor cd = ConvertorsPool.getDefault().getWriteConvertor(o);
237         if (cd == null) {
238             throw new ConvertorException("There is no convertor registered for instance "+o); // NOI18N
239
}
240         return cd.getConvertor().write(doc, o);
241     }
242
243     /**
244      * Converts the object to XML document and writes it into
245      * given output stream.
246      *
247      * @param os output stream to which the XML document will be written
248      * @param o object to convert
249      * @throws ConvertorException thrown when there is no convertor for the
250      * passed object or when there was a runtime error during conversion.
251      * Client should call {@link #canWrite} to prevent this exception.
252      * @throws IOException thrown when XML document cannot be written to output stream
253      */

254     public static void write(OutputStream JavaDoc os, Object JavaDoc o) throws IOException JavaDoc {
255         Document JavaDoc doc = createDocument();
256         Element JavaDoc e = write(doc, o);
257         doc.appendChild(e);
258         XMLUtil.write(doc, os, "UTF-8"); // NOI18N
259
}
260
261     /**
262      * Gets set of all available convertors.
263      *
264      * @return set of {@link ConvertorDescriptor} instances. Method always
265      * returns new instance of set.
266      */

267     public Set JavaDoc getConvertorDescriptors() {
268         return ConvertorsPool.getDefault().getDescriptors();
269     }
270
271     /**
272      * Adds listener on changes of this object.
273      *
274      * @param listener property change listener
275      */

276     public void addPropertyChangeListener(PropertyChangeListener JavaDoc listener) {
277         support.addPropertyChangeListener(listener);
278     }
279     
280     /**
281      * Removes listener on changes of this object.
282      *
283      * @param listener property change listener
284      */

285     public void removePropertyChangeListener(PropertyChangeListener JavaDoc listener) {
286         support.removePropertyChangeListener(listener);
287     }
288     
289     final static void firePropertyChange(String JavaDoc propertyName, Object JavaDoc oldValue, Object JavaDoc newValue) {
290         DEFAULT.support.firePropertyChange(propertyName, oldValue, newValue);
291     }
292     
293 }
294
Popular Tags