View Javadoc

1   package net.sf.mmapps.commons.util;
2   
3   import java.io.ByteArrayInputStream;
4   import java.io.ByteArrayOutputStream;
5   import java.io.IOException;
6   import java.io.InputStream;
7   import java.io.OutputStream;
8   import java.io.UnsupportedEncodingException;
9   import java.util.ArrayList;
10  import java.util.List;
11  
12  import javax.xml.parsers.DocumentBuilder;
13  import javax.xml.parsers.DocumentBuilderFactory;
14  import javax.xml.parsers.FactoryConfigurationError;
15  import javax.xml.parsers.ParserConfigurationException;
16  
17  import org.apache.xml.serialize.OutputFormat;
18  import org.apache.xml.serialize.XMLSerializer;
19  import org.mmbase.util.logging.Logger;
20  import org.mmbase.util.logging.Logging;
21  import org.w3c.dom.Document;
22  import org.w3c.dom.DocumentFragment;
23  import org.w3c.dom.Element;
24  import org.w3c.dom.Node;
25  import org.w3c.dom.NodeList;
26  import org.w3c.dom.Text;
27  
28  /***
29   * Common utilities for handling XML.
30   * 
31   * @author Nico Klasens
32   */
33  public class XmlUtil {
34  
35      /*** MMbase logging system */
36      private static Logger logger = Logging.getLoggerInstance(XmlUtil.class.getName());
37      
38      private XmlUtil() {
39          // utility class
40      }
41  
42  	/***
43  	 * Serialize <code>Document</code> instance to pretty printed
44  	 * <code>String</code>.
45  	 *
46  	 * @param doc  Source object.
47  	 * @return document as <code>String</code>.
48  	 */
49  	public static String serializeDocument(Document doc) {
50  		OutputStream bos = null;
51  		try {
52  			bos = new ByteArrayOutputStream();
53  			OutputFormat format = getXmlOutput(false, false, false, false);
54              
55  			XMLSerializer serializer = new XMLSerializer( bos, format );
56  			serializer.serialize( doc );
57  
58  			return bos.toString();
59  		} catch( Exception e ) {
60  			logger.error( "[serializeDocument()] Pretty printing failed!" );
61  			logger.debug(e);
62  		} finally {
63  			try {
64  				if( bos != null ) bos.close();
65  			}
66  			catch( IOException e ) {
67  				logger.error( "[serializeDocument()] Could not close OutputStream!" );
68  			}
69  		}
70  		return "";
71  	}
72  
73  	/***
74  	 * Serialize <code>DocumentFragment</code> instance to pretty printed
75  	 * <code>String</code>.
76  	 *
77  	 * @param docfrag  Source object.
78  	 * @return documentfragment as <code>String</code>.
79  	 */
80  	public static String serializeDocumentFragment(DocumentFragment docfrag) {
81  		OutputStream bos = null;
82  		try {
83  			bos = new ByteArrayOutputStream();
84              OutputFormat format = getXmlOutput(false, false, true, true);
85  
86  			XMLSerializer serializer = new XMLSerializer(bos, format);
87  			serializer.serialize( docfrag );
88  
89  			return bos.toString();
90  		} catch( Exception e ) {
91  			logger.error( "[serializeDocument()] Pretty printing failed!" );
92  			logger.debug(e);
93  		} finally {
94  			try {
95  				if( bos != null ) bos.close();
96  			}
97  			catch( IOException e ) {
98  				logger.error( "[serializeDocument()] Could not close OutputStream!" );
99  			}
100 		}
101 		return "";
102 	}
103 
104     /***
105 	 * Serialize <code>Document</code> instance to pretty printed
106 	 * <code>String</code>.
107 	 *
108 	 * @param element  Source object.
109 	 * @return Element as <code>String</code>.
110 	 */
111 	public static String serializeElement(Element element) {
112 		return serializeElement(element,false);
113 	}
114 
115 	/***
116 	 * Serialize <code>Document</code> instance to pretty printed
117 	 * <code>String</code>.
118 	 *
119 	 * @param element  Source object.
120      * @param omitxml Omit the xml declaration from the returned xml
121 	 * @return Element as <code>String</code>.
122 	 */
123 	public static String serializeElement(Element element, boolean omitxml) {
124 		OutputStream bos = null;
125 		try {
126 			bos = new ByteArrayOutputStream();
127             OutputFormat format = getXmlOutput(false, false, omitxml, omitxml);
128 
129             XMLSerializer serializer = new XMLSerializer(bos, format);
130 			serializer.serialize( element );
131 
132 			return bos.toString();
133 		} catch( Exception e ) {
134 			logger.error( "[serializeDocument()] Pretty printing failed!" );
135 			logger.debug(e);
136 		} finally {
137 			try {
138 				if( bos != null ) bos.close();
139 			}
140 			catch( IOException e ) {
141 				logger.error( "[serializeDocument()] Could not close OutputStream!" );
142 			}
143 		}
144 		return "";
145 	}
146 
147     /***
148      * create Output format for xml
149      * Be caregull, Textnodes will be fomormatted and indented too.
150      * @param indent - indent xml
151      * @param omitComments - omit tcomments
152      * @param omitDocumentType - omit document type
153      * @param omitXMLDeclaration - omit xml declaration
154      * @return output format
155      */
156     public static OutputFormat getXmlOutput(boolean indent, boolean omitComments,
157             boolean omitDocumentType, boolean omitXMLDeclaration) {
158         OutputFormat format = new OutputFormat();
159         if (indent) {
160             format.setIndent(2);
161             format.setLineWidth(80);
162             format.setLineSeparator("\n");
163         }
164         format.setOmitComments(omitComments);
165         format.setOmitDocumentType(omitDocumentType);
166         format.setOmitXMLDeclaration(omitXMLDeclaration);
167         return format;
168     }
169     
170     public static Document createDocument() {
171         try {
172             return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
173         } catch (ParserConfigurationException e) {
174             logger.debug("" + e.getMessage(), e);
175         } catch (FactoryConfigurationError e) {
176             logger.debug("" + e.getMessage(), e);
177         }
178         return null;
179     }
180 
181     public static Element createChild(Element root, String elementName) {
182         return createChild(root, elementName, null);
183     }
184     
185     public static Element createChild(Element root, String elementName, String namespaceURI) {
186         Element child = createElement(root.getOwnerDocument(), elementName, namespaceURI);
187         root.appendChild(child);
188         return child;
189     }
190 
191     public static Element createRoot(Document doc, String elementName) {
192         return createRoot(doc, elementName, null);
193     }
194     
195     public static Element createRoot(Document doc, String elementName, String namespaceURI) {
196         Element child = createElement(doc, elementName, namespaceURI);
197         doc.appendChild(child);
198         return child;
199     }
200 
201     public static Element createElement(Document doc, String elementName) {
202         return createElement(doc, elementName, null);
203     }
204     
205     public static Element createElement(Document doc, String elementName, String namespaceURI) {
206         Element child;
207         if (namespaceURI != null) {
208             child = doc.createElementNS(namespaceURI, elementName);    
209         }
210         else {
211             child = doc.createElement(elementName);
212         }
213         return child;
214     }
215     
216     public static void createAttribute(Element element, String name, String value) {
217         element.setAttribute(name, value);
218     }
219 
220     public static void createText(Element root, String text) {
221         if (text != null) {
222             Text child;
223             if (text.indexOf("<")!=-1 || text.indexOf("&")!=-1 ) {
224                 child = root.getOwnerDocument().createCDATASection(text);
225             } else {
226                 child = root.getOwnerDocument().createTextNode(text);
227             }
228             root.appendChild(child);
229         }
230     }
231     
232     public static Element createChildText(Element element, String name, String value) {
233         Element child = createChild(element, name);
234         createText(child, value);
235         return child;
236     }
237 
238     public static void createAttribute(Element root, String name, boolean value) {
239         createAttribute(root, name, String.valueOf(value));
240     }
241     public static void createAttribute(Element root, String name, int value) {
242         createAttribute(root, name, String.valueOf(value));
243     }
244     public static void createAttribute(Element root, String name, float value) {
245         createAttribute(root, name, String.valueOf(value));
246     }
247     public static void createAttribute(Element root, String name, long value) {
248         createAttribute(root, name, String.valueOf(value));
249     }
250     public static void createAttribute(Element root, String name, double value) {
251         createAttribute(root, name, String.valueOf(value));
252     }
253     
254     public static void createText(Element root, boolean text) {
255         createText(root, String.valueOf(text));
256     }
257     public static void createText(Element root, int text) {
258         createText(root, String.valueOf(text));
259     }
260     public static void createText(Element root, float text) {
261         createText(root, String.valueOf(text));
262     }
263     public static void createText(Element root, long text) {
264         createText(root, String.valueOf(text));
265     }
266     public static void createText(Element root, double text) {
267         createText(root, String.valueOf(text));
268     }
269     
270     public static Element createChildText(Element element, String name, boolean value) {
271         return createChildText(element, name, String.valueOf(value));
272     }
273     public static Element createChildText(Element element, String name, int value) {
274         return createChildText(element, name, String.valueOf(value));
275     }
276     public static Element createChildText(Element element, String name, float value) {
277         return createChildText(element, name, String.valueOf(value));
278     }
279     public static Element createChildText(Element element, String name, long value) {
280         return createChildText(element, name, String.valueOf(value));
281     }
282     public static Element createChildText(Element element, String name, double value) {
283         return createChildText(element, name, String.valueOf(value));
284     }
285     
286     public static String getText(Node node) {
287         return getText(node, "");
288     }
289     
290     public static String getText(Node node, String defaultvalue) {
291 		if (node == null) {
292 			return defaultvalue;
293 		}
294 		try {
295             // return the value of the node if that node is itself a text-holding node
296             if ((node.getNodeType()==Node.TEXT_NODE)
297                     || (node.getNodeType()==Node.CDATA_SECTION_NODE)
298                     || (node.getNodeType()==Node.ATTRIBUTE_NODE)) {
299                 return node.getNodeValue();
300             }
301             // otherwise return the text contained by the node's children
302             Node childnode=node.getFirstChild();
303             StringBuffer value = new StringBuffer();
304             while (childnode != null) {
305                 if ((childnode.getNodeType()==Node.TEXT_NODE) 
306                         || (childnode.getNodeType()==Node.CDATA_SECTION_NODE)) {
307                     value.append(childnode.getNodeValue());
308                 }
309                 childnode = childnode.getNextSibling();
310             }
311             if (value.length() > 0) 
312                 return value.toString();
313         } catch (Exception e) {
314             logger.error(e.getMessage(), e);
315         }
316         return defaultvalue;
317     }
318     
319     /***
320      * Returns a W3C Document representation of the string.
321      * 
322      * @param str Xml which should be converted
323      * @return DOM structure
324      */
325     public static Document toDocument(String str) {
326       Document doc = null;
327       try {
328          doc = toDocument(new ByteArrayInputStream(str.getBytes("UTF-8")));
329       } catch (UnsupportedEncodingException e) {
330          logger.error("String could not be converted to a Document.", e);
331       }
332       if (doc == null) {
333          logger.error("Erroneous String: " + str);
334       }
335       return doc;
336    }
337     
338    /***
339     * Returns a W3C Document representation of the string.
340     * @param stream The input stream with the xml to convert
341     * @return DOM structure
342     */
343    public static Document toDocument(InputStream stream) {
344       try {
345          DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
346          Document doc = docBuilder.parse(stream);
347          return doc;
348       } catch (Exception e) {
349          logger.error("InputStream could not be converted to a Document.", e);
350       }
351       return null;
352    }
353 
354    public static List getElements(Element element) {
355       List<Element> elements = new ArrayList<Element>();
356       
357       NodeList nlist = element.getChildNodes();
358       for(int i = 0; i < nlist.getLength(); i++) {
359           Node node = nlist.item(i);
360           if (node.getNodeType() == Node.ELEMENT_NODE) {
361               Element e = (Element) node;
362               elements.add(e);
363           }
364       }
365       return elements;
366    }
367 
368    public static String xmlEscape(String fragment) {
369        return fragment.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
370    }
371 
372    public static String xmlUnescape(String escapedFragment) {
373        return escapedFragment.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
374    }
375 
376 }