KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > dom > svg > SAXSVGDocumentFactory


1 /*
2
3    Copyright 2001-2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.dom.svg;
19
20 import java.io.IOException JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.io.Reader JavaDoc;
23 import java.io.StringReader JavaDoc;
24 import java.net.MalformedURLException JavaDoc;
25 import java.net.URL JavaDoc;
26 import java.util.MissingResourceException JavaDoc;
27 import java.util.Properties JavaDoc;
28
29 import org.apache.batik.dom.util.SAXDocumentFactory;
30 import org.apache.batik.dom.util.XLinkSupport;
31 import org.apache.batik.dom.svg12.SVG12DOMImplementation;
32 import org.apache.batik.util.MimeTypeConstants;
33 import org.apache.batik.util.ParsedURL;
34
35 import org.w3c.dom.Document JavaDoc;
36 import org.w3c.dom.DOMImplementation JavaDoc;
37 import org.w3c.dom.svg.SVGDocument;
38 import org.xml.sax.InputSource JavaDoc;
39 import org.xml.sax.SAXException JavaDoc;
40
41 /**
42  * This class contains methods for creating SVGDocument instances
43  * from an URI using SAX2.
44  *
45  * @author <a HREF="mailto:stephane@hillion.org">Stephane Hillion</a>
46  * @version $Id: SAXSVGDocumentFactory.java,v 1.29 2005/03/27 08:58:32 cam Exp $
47  */

48 public class SAXSVGDocumentFactory
49     extends SAXDocumentFactory
50     implements SVGDocumentFactory {
51
52     public static final Object JavaDoc LOCK = new Object JavaDoc();
53
54     /**
55      * Key used for public identifiers
56      */

57     public static final String JavaDoc KEY_PUBLIC_IDS = "publicIds";
58
59     /**
60      * Key used for public identifiers
61      */

62     public static final String JavaDoc KEY_SKIPPABLE_PUBLIC_IDS = "skippablePublicIds";
63
64     /**
65      * Key used for the skippable DTD substitution
66      */

67     public static final String JavaDoc KEY_SKIP_DTD = "skipDTD";
68
69     /**
70      * Key used for system identifiers
71      */

72     public static final String JavaDoc KEY_SYSTEM_ID = "systemId.";
73
74     /**
75      * The dtd public IDs resource bundle class name.
76      */

77     protected final static String JavaDoc DTDIDS =
78         "org.apache.batik.dom.svg.resources.dtdids";
79
80     /**
81      * Constant for HTTP content type header charset field.
82      */

83     protected final static String JavaDoc HTTP_CHARSET = "charset";
84
85     /**
86      * The accepted DTD public IDs.
87      */

88     protected static String JavaDoc dtdids;
89
90     /**
91      * The DTD public IDs we know we can skip.
92      */

93     protected static String JavaDoc skippable_dtdids;
94
95     /**
96      * The DTD content to use when skipping
97      */

98     protected static String JavaDoc skip_dtd;
99
100     /**
101      * The ResourceBunder for the public and system ids
102      */

103     protected static Properties JavaDoc dtdProps;
104
105     /**
106      * Creates a new SVGDocumentFactory object.
107      * @param parser The SAX2 parser classname.
108      */

109     public SAXSVGDocumentFactory(String JavaDoc parser) {
110         super(SVGDOMImplementation.getDOMImplementation(), parser);
111     }
112
113     /**
114      * Creates a new SVGDocumentFactory object.
115      * @param parser The SAX2 parser classname.
116      * @param dd Whether a document descriptor must be generated.
117      */

118     public SAXSVGDocumentFactory(String JavaDoc parser, boolean dd) {
119         super(SVGDOMImplementation.getDOMImplementation(), parser, dd);
120     }
121
122     public SVGDocument createSVGDocument(String JavaDoc uri) throws IOException JavaDoc {
123         return (SVGDocument)createDocument(uri);
124     }
125
126     /**
127      * Creates a SVG Document instance.
128      * @param uri The document URI.
129      * @param inp The document input stream.
130      * @exception IOException if an error occured while reading the document.
131      */

132     public SVGDocument createSVGDocument(String JavaDoc uri, InputStream JavaDoc inp)
133         throws IOException JavaDoc {
134         return (SVGDocument)createDocument(uri, inp);
135     }
136
137     /**
138      * Creates a SVG Document instance.
139      * @param uri The document URI.
140      * @param r The document reader.
141      * @exception IOException if an error occured while reading the document.
142      */

143     public SVGDocument createSVGDocument(String JavaDoc uri, Reader JavaDoc r)
144         throws IOException JavaDoc {
145         return (SVGDocument)createDocument(uri, r);
146     }
147
148     /**
149      * Creates a SVG Document instance.
150      * This method supports gzipped sources.
151      * @param uri The document URI.
152      * @exception IOException if an error occured while reading the document.
153      */

154     public Document JavaDoc createDocument(String JavaDoc uri) throws IOException JavaDoc {
155         ParsedURL purl = new ParsedURL(uri);
156
157         InputStream JavaDoc is = purl.openStream(MimeTypeConstants.MIME_TYPES_SVG);
158
159         InputSource JavaDoc isrc = new InputSource JavaDoc(is);
160         
161         // now looking for a charset encoding in the content type such
162
// as "image/svg+xml; charset=iso8859-1" this is not official
163
// for image/svg+xml yet! only for text/xml and maybe
164
// for application/xml
165
String JavaDoc contentType = purl.getContentType();
166         int cindex = -1;
167         if (contentType != null) {
168             contentType = contentType.toLowerCase();
169             cindex = contentType.indexOf(HTTP_CHARSET);
170         }
171  
172         if (cindex != -1) {
173             int i = cindex + HTTP_CHARSET.length();
174             int eqIdx = contentType.indexOf('=', i);
175             if (eqIdx != -1) {
176                 eqIdx++; // no one is interested in the equals sign...
177

178                 String JavaDoc charset;
179                 // The patch had ',' as the terminator but I suspect
180
// that is the delimiter between possible charsets,
181
// but if another 'attribute' were in the accept header
182
// charset would be terminated by a ';'. So I look
183
// for both and take to closer of the two.
184
int idx = contentType.indexOf(',', eqIdx);
185                 int semiIdx = contentType.indexOf(';', eqIdx);
186                 if ((semiIdx != -1) && ((semiIdx < idx) || (idx == -1)))
187                     idx = semiIdx;
188                 if (idx != -1)
189                     charset = contentType.substring(eqIdx, idx);
190                 else
191                     charset = contentType.substring(eqIdx);
192                 isrc.setEncoding(charset.trim());
193             }
194         }
195
196         isrc.setSystemId(uri);
197
198         Document JavaDoc doc = super.createDocument
199             (SVGDOMImplementation.SVG_NAMESPACE_URI, "svg", uri, isrc);
200         try {
201             ((SVGOMDocument)doc).setURLObject(new URL JavaDoc(purl.toString()));
202         } catch (MalformedURLException JavaDoc mue) {
203             // Not very likely to happen given we already opened the stream.
204
throw new IOException JavaDoc("Malformed URL: " + uri);
205         }
206
207         return doc;
208     }
209
210     /**
211      * Creates a SVG Document instance.
212      * @param uri The document URI.
213      * @param inp The document input stream.
214      * @exception IOException if an error occured while reading the document.
215      */

216     public Document JavaDoc createDocument(String JavaDoc uri, InputStream JavaDoc inp)
217         throws IOException JavaDoc {
218         Document JavaDoc doc;
219         InputSource JavaDoc is = new InputSource JavaDoc(inp);
220         is.setSystemId(uri);
221
222         try {
223             doc = super.createDocument
224                 (SVGDOMImplementation.SVG_NAMESPACE_URI, "svg", uri, is);
225             if (uri != null) {
226                 ((SVGOMDocument)doc).setURLObject(new URL JavaDoc(uri));
227             }
228         } catch (MalformedURLException JavaDoc e) {
229             throw new IOException JavaDoc(e.getMessage());
230         }
231         return doc;
232     }
233
234     /**
235      * Creates a SVG Document instance.
236      * @param uri The document URI.
237      * @param r The document reader.
238      * @exception IOException if an error occured while reading the document.
239      */

240     public Document JavaDoc createDocument(String JavaDoc uri, Reader JavaDoc r)
241         throws IOException JavaDoc {
242         Document JavaDoc doc;
243         InputSource JavaDoc is = new InputSource JavaDoc(r);
244         is.setSystemId(uri);
245
246         try {
247             doc = super.createDocument
248                 (SVGDOMImplementation.SVG_NAMESPACE_URI, "svg", uri, is);
249             if (uri != null) {
250                 ((SVGOMDocument)doc).setURLObject(new URL JavaDoc(uri));
251             }
252         } catch (MalformedURLException JavaDoc e) {
253             throw new IOException JavaDoc(e.getMessage());
254         }
255         return doc;
256     }
257
258     /**
259      * Creates a Document instance.
260      * @param ns The namespace URI of the root element of the document.
261      * @param root The name of the root element of the document.
262      * @param uri The document URI.
263      * @exception IOException if an error occured while reading the document.
264      */

265     public Document JavaDoc createDocument(String JavaDoc ns, String JavaDoc root, String JavaDoc uri)
266         throws IOException JavaDoc {
267         if (!SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns) ||
268             !"svg".equals(root)) {
269             throw new RuntimeException JavaDoc("Bad root element");
270         }
271         return createDocument(uri);
272     }
273
274     /**
275      * Creates a Document instance.
276      * @param ns The namespace URI of the root element of the document.
277      * @param root The name of the root element of the document.
278      * @param uri The document URI.
279      * @param is The document input stream.
280      * @exception IOException if an error occured while reading the document.
281      */

282     public Document JavaDoc createDocument(String JavaDoc ns, String JavaDoc root, String JavaDoc uri,
283                                    InputStream JavaDoc is) throws IOException JavaDoc {
284         if (!SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns) ||
285             !"svg".equals(root)) {
286             throw new RuntimeException JavaDoc("Bad root element");
287         }
288         return createDocument(uri, is);
289     }
290
291     /**
292      * Creates a Document instance.
293      * @param ns The namespace URI of the root element of the document.
294      * @param root The name of the root element of the document.
295      * @param uri The document URI.
296      * @param r The document reader.
297      * @exception IOException if an error occured while reading the document.
298      */

299     public Document JavaDoc createDocument(String JavaDoc ns, String JavaDoc root, String JavaDoc uri,
300                                    Reader JavaDoc r) throws IOException JavaDoc {
301         if (!SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns) ||
302             !"svg".equals(root)) {
303             throw new RuntimeException JavaDoc("Bad root element");
304         }
305         return createDocument(uri, r);
306     }
307
308     public DOMImplementation getDOMImplementation(String JavaDoc ver) {
309         if ((ver == null) || (ver.length()==0) ||
310             ver.equals("1.0") || ver.equals("1.1"))
311             return SVGDOMImplementation.getDOMImplementation();
312
313         return SVG12DOMImplementation.getDOMImplementation();
314     }
315
316     /**
317      * <b>SAX</b>: Implements {@link
318      * org.xml.sax.ContentHandler#startDocument()}.
319      */

320     public void startDocument() throws SAXException JavaDoc {
321         super.startDocument();
322     namespaces.put("", SVGDOMImplementation.SVG_NAMESPACE_URI);
323     namespaces.put("xlink", XLinkSupport.XLINK_NAMESPACE_URI);
324     }
325
326     /**
327      * <b>SAX2</b>: Implements {@link
328      * org.xml.sax.EntityResolver#resolveEntity(String,String)}.
329      */

330     public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId)
331         throws SAXException JavaDoc {
332         try {
333             synchronized (LOCK) {
334                 // Bootstrap if needed - move to a static block???
335
if (dtdProps == null) {
336                     dtdProps = new Properties JavaDoc();
337                     try {
338                         Class JavaDoc cls = SAXSVGDocumentFactory.class;
339                         InputStream JavaDoc is = cls.getResourceAsStream
340                             ("resources/dtdids.properties");
341                         dtdProps.load(is);
342                     } catch (IOException JavaDoc ioe) {
343                         throw new SAXException JavaDoc(ioe);
344                     }
345                 }
346
347                 if (dtdids == null)
348                     dtdids = dtdProps.getProperty(KEY_PUBLIC_IDS);
349
350                 if (skippable_dtdids == null)
351                     skippable_dtdids =
352                         dtdProps.getProperty(KEY_SKIPPABLE_PUBLIC_IDS);
353
354                 if (skip_dtd == null)
355                     skip_dtd = dtdProps.getProperty(KEY_SKIP_DTD);
356             }
357
358             if (publicId == null)
359                 return null; // Let SAX Parser find it.
360

361             if (!isValidating &&
362                 (skippable_dtdids.indexOf(publicId) != -1)) {
363                 // We are not validating and this is a DTD we can
364
// safely skip so do it... Here we provide just enough
365
// of the DTD to keep stuff running (set svg and
366
// xlink namespaces).
367
return new InputSource JavaDoc(new StringReader JavaDoc(skip_dtd));
368             }
369             
370             if (dtdids.indexOf(publicId) != -1) {
371                 String JavaDoc localSystemId =
372                     dtdProps.getProperty(KEY_SYSTEM_ID +
373                                          publicId.replace(' ', '_'));
374                 
375                 if (localSystemId != null && !"".equals(localSystemId)) {
376                     return new InputSource JavaDoc
377                         (getClass().getResource(localSystemId).toString());
378                 }
379             }
380         } catch (MissingResourceException JavaDoc e) {
381             throw new SAXException JavaDoc(e);
382         }
383         // Let the SAX parser find the entity.
384
return null;
385     }
386 }
387
Popular Tags