e.g. Calendar Search Help
You must enter a value before pressing Search
batik

Class: org.apache.batik.apps.svgbrowser.XMLInputHandler   ©

 OK to copy?
001 /*
002 
003  ============================================================================
004                    The Apache Software License, Version 1.1
005  ============================================================================
006 
007  Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
008 
009  Redistribution and use in source and binary forms, with or without modifica-
010  tion, are permitted provided that the following conditions are met:
011 
012  1. Redistributions of  source code must  retain the above copyright  notice,
013     this list of conditions and the following disclaimer.
014 
015  2. Redistributions in binary form must reproduce the above copyright notice,
016     this list of conditions and the following disclaimer in the documentation
017     and/or other materials provided with the distribution.
018 
019  3. The end-user documentation included with the redistribution, if any, must
020     include  the following  acknowledgment:  "This product includes  software
021     developed  by the  Apache Software Foundation  (http://www.apache.org/)."
022     Alternately, this  acknowledgment may  appear in the software itself,  if
023     and wherever such third-party acknowledgments normally appear.
024 
025  4. The names "Batik" and  "Apache Software Foundation" must  not  be
026     used to  endorse or promote  products derived from  this software without
027     prior written permission. For written permission, please contact
028     apache@apache.org.
029 
030  5. Products  derived from this software may not  be called "Apache", nor may
031     "Apache" appear  in their name,  without prior written permission  of the
032     Apache Software Foundation.
033 
034  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
035  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
036  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
037  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
038  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
039  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
040  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
041  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
042  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
043  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
044 
045  This software  consists of voluntary contributions made  by many individuals
046  on  behalf of the Apache Software  Foundation. For more  information on the
047  Apache Software Foundation, please see <http://www.apache.org/>.
048 
049 */
050 
051 package org.apache.batik.apps.svgbrowser;
052 
053 import java.io.File;
054 import java.io.StringReader;
055 import java.io.StringWriter;
056 
057 import javax.xml.parsers.DocumentBuilder;
058 import javax.xml.parsers.DocumentBuilderFactory;
059 import javax.xml.transform.Source;
060 import javax.xml.transform.Transformer;
061 import javax.xml.transform.TransformerFactory;
062 import javax.xml.transform.URIResolver;
063 import javax.xml.transform.dom.DOMSource;
064 import javax.xml.transform.stream.StreamResult;
065 import javax.xml.transform.stream.StreamSource;
066 
067 import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
068 import org.apache.batik.dom.svg.SVGDOMImplementation;
069 import org.apache.batik.dom.util.DOMUtilities;
070 import org.apache.batik.dom.util.HashTable;
071 import org.apache.batik.util.ParsedURL;
072 import org.apache.batik.util.SVGConstants;
073 import org.apache.batik.util.XMLResourceDescriptor;
074 import org.w3c.dom.Attr;
075 import org.w3c.dom.Document;
076 import org.w3c.dom.Element;
077 import org.w3c.dom.NamedNodeMap;
078 import org.w3c.dom.Node;
079 import org.w3c.dom.ProcessingInstruction;
080 import org.w3c.dom.svg.SVGDocument;
081 
082 /**
083  * This implementation of the <tt>SquiggleInputHandler</tt> class
084  * handles XML files by looking for the first
085  * &lt;?xml-stylesheet ... ?&gt; processing instruction referencing
086  * an xsl document. In case there is one, the transform is applied to the 
087  * input XML file and the handler checks that the result is an 
088  * SVG document with an SVG root.
089  *
090  * @author <a mailto="vincent.hardy@sun.com">Vincent Hardy</a>
091  * @version $Id: XMLInputHandler.java,v 1.7 2003/08/09 16:58:45 deweese Exp $
092  */
093 public class XMLInputHandler implements SquiggleInputHandler {
094     public static final String[] XVG_MIME_TYPES = 
095     { "image/xml+xsl+svg" };
096 
097     public static final String[] XVG_FILE_EXTENSIONS =
098     { ".xml", ".xsl" };
099 
100     public static final String ERROR_NO_XML_STYLESHEET_PROCESSING_INSTRUCTION
101         = "XMLInputHandler.error.no.xml.stylesheet.processing.instruction";
102 
103     public static final String ERROR_TRANSFORM_OUTPUT_NOT_SVG
104         = "XMLInputHandler.error.transform.output.not.svg";
105 
106     public static final String ERROR_TRANSFORM_PRODUCED_NO_CONTENT
107         = "XMLInputHandler.error.transform.produced.no.content";
108 
109     public static final String ERROR_TRANSFORM_OUTPUT_WRONG_NS
110         = "XMLInputHandler.error.transform.output.wrong.ns";
111 
112     public static final String ERROR_RESULT_GENERATED_EXCEPTION 
113         = "XMLInputHandler.error.result.generated.exception";
114 
115     public static final String XSL_PROCESSING_INSTRUCTION_TYPE
116         = "text/xsl";
117 
118     public static final String PSEUDO_ATTRIBUTE_TYPE
119         = "type";
120 
121     public static final String PSEUDO_ATTRIBUTE_HREF
122         = "href";
123 
124     /**
125      * Returns the list of mime types handled by this handler.
126      */
127     public String[] getHandledMimeTypes() {
128         return XVG_MIME_TYPES;
129     }
130     
131     /**
132      * Returns the list of file extensions handled by this handler
133      */
134     public String[] getHandledExtensions() {
135         return XVG_FILE_EXTENSIONS;
136     }
137 
138     /**
139      * Returns a description for this handler
140      */
141     public String getDescription() {
142         return "";
143     }
144 
145     /**
146      * Returns true if the input file can be handled by the handler
147      */
148     public boolean accept(File f) {
Rate149         return f.isFile() && accept(f.getPath());
150     }
151 
152     /**
153      * Returns true if the input URI can be handled by the handler
154      */
155     public boolean accept(ParsedURL purl) {
156         if (purl == null) {
157             return false;
158         }
159 
160         // <!> Note: this should be improved to rely on Mime Type 
161         //     when the http protocol is used. This will use the 
162         //     ParsedURL.getContentType method.
163 
164         String path = purl.getPath();        
165         return accept(path);
166     }
167 
168     /**
169      * Return true if the resource with the given path can 
170      * be handled.
171      */
172     public boolean accept(String path) {
173         if (path == null) {
174             return false;
175         }
176 
177         for (int i=0; i<XVG_FILE_EXTENSIONS.length; i++) {
178             if (path.endsWith(XVG_FILE_EXTENSIONS[i])) {
179                 return true;
180             }
181         }
182 
183         return false;
184     }
185 
186     /**
187      * Handles the given input for the given JSVGViewerFrame
188      */
189     public void handle(ParsedURL purl, JSVGViewerFrame svgViewerFrame) throws Exception {
190         String uri = purl.toString();
191 
192         TransformerFactory tFactory 
193             = TransformerFactory.newInstance();
194         
195         // First, load the input XML document into a generic DOM tree
196         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
197         dbf.setValidating(false);
198         dbf.setNamespaceAware(true);
199 
200         DocumentBuilder db = dbf.newDocumentBuilder();
201 
202         Document inDoc = db.parse(uri);
203        
204         // Now, look for <?xml-stylesheet ...?> processing instructions
205         String xslStyleSheetURI 
206             = extractXSLProcessingInstruction(inDoc);
207         
208         if (xslStyleSheetURI == null) {
209             // Assume that the input file is a literal result template
210             xslStyleSheetURI = uri;
211         }
212 
213         ParsedURL parsedXSLStyleSheetURI 
214             = new ParsedURL(uri, xslStyleSheetURI);
215 
216         Transformer transformer
217             = tFactory.newTransformer
218             (new StreamSource(parsedXSLStyleSheetURI.toString()));
219 
220         // Set the URIResolver to properly handle document() and xsl:include
221         transformer.setURIResolver
222             (new DocumentURIResolver(parsedXSLStyleSheetURI.toString()));
223 
224         // Now, apply the transformation to the input document.
225         //
226         // <!> Due to issues with namespaces, the transform creates the 
227         //     result in a stream which is parsed. This is sub-optimal
228         //     but this was the only solution found to be able to 
229         //     generate content in the proper namespaces.
230         //
231         // SVGOMDocument outDoc = 
232         //   (SVGOMDocument)impl.createDocument(svgNS, "svg", null);
233         // outDoc.setURLObject(new URL(uri));
234         // transformer.transform
235         //     (new DOMSource(inDoc),
236         //     new DOMResult(outDoc.getDocumentElement()));
237         //
238         StringWriter sw = new StringWriter();
239         StreamResult result = new StreamResult(sw);
240         transformer.transform(new DOMSource(inDoc),
241                               result);
242         sw.flush();
243         sw.close();
244 
245         String parser = XMLResourceDescriptor.getXMLParserClassName();
246         SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
247         SVGDocument outDoc = null;
248 
249         try {
250             outDoc = f.createSVGDocument
251                 (uri, new StringReader(sw.toString()));
252         } catch (Exception e) {
253             System.err.println("======================================");
254             System.err.println(sw.toString());
255             System.err.println("======================================");
256             
257             throw new IllegalArgumentException
258                 (Resources.getString(ERROR_RESULT_GENERATED_EXCEPTION));
259         }
260 
261         // Patch the result tree to go under the root node
262         // checkAndPatch(outDoc);
263         
264         svgViewerFrame.getJSVGCanvas().setSVGDocument(outDoc);
265         svgViewerFrame.setSVGDocument(outDoc,
266                                       uri,
267                                       outDoc.getTitle());
268     }
269 
270     /**
271      * This method checks that the generated content is SVG.
272      *
273      * This method accounts for the fact that the root svg's first child
274      * is the result of the transform. It moves all its children under the root
275      * and sets the attributes
276      */
277     protected void checkAndPatch(Document doc) {
278         Element root = doc.getDocumentElement();
279         Node realRoot = root.getFirstChild();
280         String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
281 
282         if (realRoot == null) {
283             throw new IllegalArgumentException
284                 (Resources.getString(ERROR_TRANSFORM_PRODUCED_NO_CONTENT));
285         }
286 
287         if (realRoot.getNodeType() != Node.ELEMENT_NODE
288             || 
289             !SVGConstants.SVG_SVG_TAG.equals(realRoot.getLocalName())) {
290             throw new IllegalArgumentException
291                 (Resources.getString(ERROR_TRANSFORM_OUTPUT_NOT_SVG));
292         }
293 
294         if (!svgNS.equals(realRoot.getNamespaceURI())) {
295             throw new IllegalArgumentException
296                 (Resources.getString(ERROR_TRANSFORM_OUTPUT_WRONG_NS));
297         }
298 
299         Node child = realRoot.getFirstChild();
300         while ( child != null ) {
301             root.appendChild(child);
302             child = realRoot.getFirstChild();
303         }
304 
305         NamedNodeMap attrs = realRoot.getAttributes();
306         int n = attrs.getLength();
307         for (int i=0; i<n; i++) {
308             root.setAttributeNode((Attr)attrs.item(i));
309         }
310 
311         root.removeChild(realRoot);
312     }
313 
314     /**
315      * Extracts the first XSL processing instruction from the input 
316      * XML document. 
317      */
318     protected String extractXSLProcessingInstruction(Document doc) {
319         Node child = doc.getFirstChild();
320         while (child != null) {
321             if (child.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
322                 ProcessingInstruction pi 
323                     = (ProcessingInstruction)child;
324                 
325                 HashTable table = new HashTable();
326                 DOMUtilities.parseStyleSheetPIData(pi.getData(),
327                                                    table);
328 
329                 Object type = table.get(PSEUDO_ATTRIBUTE_TYPE);
330                 if (XSL_PROCESSING_INSTRUCTION_TYPE.equals(type)) {
331                     Object href = table.get(PSEUDO_ATTRIBUTE_HREF);
332                     if (href != null) {
333                         return href.toString();
334                     } else {
335                         return null;
336                     }
337                 }
338             }
339             child = child.getNextSibling();
340         }
341 
342         return null;
343     }
344 
345     /**
346      * Implements the URIResolver interface so that relative urls used in 
347      * transformations are resolved properly.
348      */
349     public class DocumentURIResolver implements URIResolver {
350         String documentURI;
351 
352         public DocumentURIResolver(String documentURI) {
353             this.documentURI = documentURI;
354         }
355 
356         public Source resolve(String href, String base) {
357             if (base == null || "".equals(base)) {
358                 base = documentURI;
359             }
360 
361             ParsedURL purl = new ParsedURL(base, href);
362 
363             return new StreamSource(purl.toString());
364         }
365     }
366 }

            
All Examples in File:
Example
Line
Rating (found
useful by...)
149 0% of 0