Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/arranger/jarl/util/XMLUtil.java


1   package com.arranger.jarl.util;
2   
3   
4   import org.apache.xpath.XPathAPI;
5   import org.apache.xml.serialize.XMLSerializer;
6   import org.apache.xml.serialize.OutputFormat;
7   import org.w3c.dom.*;
8   import org.w3c.dom.traversal.NodeIterator;
9   import org.xml.sax.*;
10  
11  import javax.xml.parsers.DocumentBuilder;
12  import javax.xml.parsers.DocumentBuilderFactory;
13  import javax.xml.transform.TransformerException;
14  import java.io.*;
15  import java.util.Stack;
16  import java.util.regex.Pattern;
17  import java.util.regex.Matcher;
18  
19  /**
20   * XMLUtil created on Jan 18, 2003
21   */
22  public class XMLUtil {
23  
24      public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
25      public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
26  
27      protected static DocumentBuilderFactory s_docBuilderFactory = null;
28      protected static boolean s_useValidation = true;
29  
30      public static DocumentBuilderFactory getDocBuilderFactory() {
31          return s_docBuilderFactory;
32      }
33  
34      public static void setDocBuilderFactory(DocumentBuilderFactory docBuilderFactory) {
35          s_docBuilderFactory = docBuilderFactory;
36      }
37  
38      public static boolean isUseValidation() {
39          return s_useValidation;
40      }
41  
42      public static void setUseValidation(boolean useValidation) {
43          s_useValidation = useValidation;
44      }
45  
46      public static Document loadDocument(String location) throws Exception {
47          InputStream inputStream = IOUtil.getInputStream(location);
48          Document doc = loadDocument(inputStream);
49          inputStream.close();
50          return doc;
51      }
52  
53      public static Document loadDocument(String location, boolean doInclude) throws Exception {
54          if (!doInclude) {
55              return loadDocument(location);
56          } else {
57              String text = preprocesXML(new File(location), new Stack());
58              return loadDocumentFromXML(text);
59          }
60      }
61  
62      /**
63       * returns a node from the suplied node that meets the xpath criteria.
64       * @param node is the tree starting point.
65       * @param xpath is a valid xpath statement.
66       */
67      public static Node selectSingleNode(Node node, String xpath) {
68          try {
69              return XPathAPI.selectSingleNode(node, xpath);
70          } catch (TransformerException te) {
71              Debug.warn(te.getMessage());
72          }
73  
74          return null;
75      }
76  
77      /**
78       * returns a node from the suplied node that meets the xpath criteria.
79       * @param node is the tree starting point.
80       * @param xpath is a valid xpath statement.
81       */
82      public static Element selectElement(Node node, String xpath) {
83          try {
84              return (Element)XPathAPI.selectSingleNode(node, xpath);
85          } catch (TransformerException te) {
86              Debug.warn(te.getMessage());
87          }
88  
89          return null;
90      }
91  
92  
93      /**
94       * returns a node list from the suplied node that meets the xpath criteria.
95       * @param node is the tree starting point.
96       * @param xpath is a valid xpath statement.
97       */
98      public static NodeList selectNodeList(Node node, String xpath) {
99          try {
100             return XPathAPI.selectNodeList(node, xpath);
101         } catch (TransformerException te) {
102             Debug.warn(te.getMessage());
103         }
104         return null;
105     }
106 
107     /**
108      * returns a node iterator from the suplied node that meets the xpath criteria.
109      * @param node is the tree starting point.
110      * @param xpath is a valid xpath statement.
111      */
112     public static NodeIterator selectNodeIterator(Node node, String xpath) {
113         try {
114             return XPathAPI.selectNodeIterator(node, xpath);
115         } catch (TransformerException te) {
116             Debug.warn(te.getMessage());
117         }
118 
119         return null;
120     }
121 
122     public static Document loadDocument(InputStream inputStream) throws Exception {
123         return _loadDocument(new InputSource(inputStream));
124     }
125 
126     public static Document loadDocument(Reader reader) throws Exception {
127         return _loadDocument(new InputSource(reader));
128     }
129 
130     public static Document loadDocumentFromXML(String xml) throws Exception {
131         return loadDocument(new StringReader(xml));
132     }
133 
134     public static Document newDocument() {
135         try {
136             return getBuilderFactory().newDocumentBuilder().newDocument();
137         } catch (Exception e) {
138             Debug.warn(e.getMessage());
139         }
140 
141         return null;
142     }
143 
144     /**
145      * Creates and returns document builder
146      */
147     public static DocumentBuilder newDocumentBuilder() {
148         try {
149             return getBuilderFactory().newDocumentBuilder();
150         } catch (Exception e) {
151             Debug.warn(e.getMessage());
152         }
153         return null;
154     }
155 
156     public static DocumentBuilderFactory getBuilderFactory() throws Exception {
157         if (s_docBuilderFactory == null) {
158             s_docBuilderFactory = DocumentBuilderFactory.newInstance();
159             s_docBuilderFactory.setNamespaceAware(true);
160             s_docBuilderFactory.setIgnoringElementContentWhitespace(true);
161         }
162         return s_docBuilderFactory;
163     }
164 
165     /**
166      * Get the text value for the given node.
167      *
168      * @param node the node to examine
169      * @return the text value of the node, or null if not available
170      */
171     public static String getNodeText(Node node) {
172         if (node == null) {
173             return null;
174         }
175         String textValue = null;
176         //if we are already a text node, just get the value
177         if (node instanceof Text)
178             textValue = node.getNodeValue();
179         else {
180             Node child = node.getFirstChild();
181             if (child instanceof Text) {
182                 Text textNode = (Text)child;
183                 textValue = textNode.getNodeValue();
184             }
185 
186             if (child instanceof CharacterData) {
187                 CharacterData cdataNode = (CharacterData)child;
188                 textValue = cdataNode.getNodeValue();
189             }
190         }
191         return textValue;
192     }
193 
194     protected static Document _loadDocument(InputSource inputSource) throws Exception {
195         DocumentBuilderFactory documentBuilderFactory = getBuilderFactory();
196         if (s_useValidation) {
197             documentBuilderFactory.setValidating(true);
198             documentBuilderFactory.setNamespaceAware(true);
199             documentBuilderFactory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
200         } else {
201             documentBuilderFactory.setValidating(false);
202             documentBuilderFactory.setNamespaceAware(false);
203         }
204 
205         DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
206         if (s_useValidation) {
207             CustomErrorHandler customErrorHandler = new CustomErrorHandler();
208             builder.setErrorHandler(customErrorHandler);
209             builder.setEntityResolver(new CustomEntityResolver());
210             Document document = builder.parse(inputSource);
211             if (customErrorHandler.m_numErrors > 0) {
212                 throw new Exception(customErrorHandler.m_buffer.toString());
213             }
214             return document;
215 
216         } else {
217             return builder.parse(inputSource);
218         }
219     }
220 
221     /**
222      * Serializes document node and returns its content as a string
223      */
224     public static String toString(Node node) {
225         return toString(node, false);
226     }
227 
228     /**
229      * Serializes document node and returns its content as a string
230      * @param node the xml DOM node
231      * @param minimizeXMLSize if true then omit comments, identing, etc to minimize overall xml size
232      */
233     public static String toString(Node node, boolean minimizeXMLSize) {
234         Element element = (Element)node;
235         try {
236             StringWriter out = new StringWriter();
237             getXMLSerializer(out, minimizeXMLSize).serialize(element);
238             return out.toString();
239         } catch (Exception e) {
240             Debug.warn(e.getMessage());
241             return null;
242         }
243     }
244 
245     private static XMLSerializer getXMLSerializer(Writer out, boolean minimizeXMLSize) {
246         OutputFormat xmlFormat = new OutputFormat("text/xml", "UTF-8", false);
247         xmlFormat.setNonEscapingElements(new String[]{"script"});
248         xmlFormat.setOmitXMLDeclaration(true);
249         if (minimizeXMLSize) {
250             xmlFormat.setPreserveSpace(false);
251             xmlFormat.setOmitComments(true);
252             xmlFormat.setIndenting(false);
253         } else {
254             xmlFormat.setPreserveSpace(true);
255             // xmlFormat.setIndenting(true);
256             // xmlFormat.setIndent(3);
257         }
258         return new XMLSerializer(out, xmlFormat);
259     }
260 
261     public static String preprocesXML(File file, Stack stack) throws Exception {
262         if (stack.contains(file)) {
263             throw new Exception("Recursive include of a file");
264         }
265         stack.push(file);
266 
267         String text = IOUtil.toString(file.getAbsolutePath());
268 
269         //look for <xml:include file='
270         Pattern pattern = Pattern.compile("<xml:include\\s+file=.+>");
271         Matcher matcher = pattern.matcher(text);
272 
273         StringBuffer buffer = new StringBuffer();
274         while (matcher.find()) {
275             String includeDirective = matcher.group();
276             String replacementText = replaceText(includeDirective, stack);
277             matcher.appendReplacement(buffer, replacementText);
278         }
279         matcher.appendTail(buffer);
280         stack.pop();
281         return buffer.toString();
282     }
283 
284     protected static String replaceText(String includeDirective, Stack stack) throws Exception {
285         Pattern pattern = Pattern.compile("\\w*/*[a-zA-Z]+\\.xml|\\w*/*[a-zA-Z]+\\.jarlml");
286         Matcher matcher = pattern.matcher(includeDirective);
287         if (matcher.find()) {
288             String includedFile = matcher.group();
289 
290             if (!(includedFile.startsWith("/") || ":".equals(includedFile.substring(1, 2)))) {
291                 //fix up the included file
292                 File parentFile = (File)stack.peek();
293                 includedFile = StringTools.appendPath(parentFile.getParent(), includedFile);
294             }
295 
296             return preprocesXML(new File(includedFile), stack);
297         } else {
298             return null;
299         }
300     }
301 
302     protected static class CustomErrorHandler implements ErrorHandler {
303 
304         protected int m_numErrors = 0;
305         protected StringBuffer m_buffer = new StringBuffer();
306 
307         protected void report(SAXParseException exception) {
308             m_buffer.append(exception.getSystemId() + " " +
309                 exception.getLineNumber() + ":" +
310                 exception.getColumnNumber() + " --> " +
311                 exception.getMessage() + "\r\n");
312             m_numErrors++;
313         }
314 
315         public void warning(SAXParseException exception)
316             throws SAXException {
317             report(exception);
318         }
319 
320         public void error(SAXParseException exception)
321             throws SAXException {
322             report(exception);
323         }
324 
325         public void fatalError(SAXParseException exception)
326             throws SAXException {
327             report(exception);
328         }
329     }
330 
331     protected static class CustomEntityResolver implements EntityResolver {
332 
333         public InputSource resolveEntity(String publicId, String systemId)
334             throws SAXException, IOException {
335             InputStream is = getClass().getResourceAsStream("/com/arranger/jarl/schema/jarl.xsd");
336             ByteArrayOutputStream baos = new ByteArrayOutputStream();
337             IOUtil.copyStream(is, baos);
338             is.close();
339             InputSource inputSource = new InputSource(new ByteArrayInputStream(baos.toByteArray()));
340             inputSource.setSystemId("jarl.xsd");
341             inputSource.setPublicId("jarl.xsd");
342             return inputSource;
343         }
344     }
345 }
346