KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > deployment > xml > LocalEntityResolver


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. 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.geronimo.deployment.xml;
19
20 import java.io.BufferedInputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.net.MalformedURLException JavaDoc;
24 import java.net.URI JavaDoc;
25 import java.util.Vector JavaDoc;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.geronimo.gbean.GBeanInfo;
30 import org.apache.geronimo.gbean.GBeanInfoBuilder;
31 import org.apache.xml.resolver.Catalog;
32 import org.apache.xml.resolver.CatalogEntry;
33 import org.apache.xml.resolver.CatalogException;
34 import org.apache.xml.resolver.CatalogManager;
35 import org.xml.sax.EntityResolver JavaDoc;
36 import org.xml.sax.InputSource JavaDoc;
37 import org.xml.sax.SAXException JavaDoc;
38
39 /**
40  * Implementation of EntityResolver that looks to the local filesystem.
41  *
42  * The implementation tries to resolve an entity via the following steps:
43  *
44  * <ul>
45  * <li>using a catalog file</li>
46  * <li>using a local repository</li>
47  * <li>using JAR files in Classpath</li>
48  * </ul>
49  *
50  * The catalog resolving is based on the OASIS XML Catalog Standard.
51  * OASIS seems to move it around. Try
52  * http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=entity
53  * and the list of documents currently at
54  * http://www.oasis-open.org/committees/documents.php?wg_abbrev=entity
55  * An older version may be at
56  * http://www.oasis-open.org/committees/entity/archives/spec-2001-08-01.html
57  * and see http://www.oasis-open.org/html/a401.htm
58  *
59  * @version $Rev: 486195 $ $Date: 2006-12-12 10:42:02 -0500 (Tue, 12 Dec 2006) $
60  */

61 public class LocalEntityResolver implements EntityResolver JavaDoc {
62     /**
63      * used Logger
64      */

65     private static final Log log = LogFactory.getLog(LocalEntityResolver.class);
66
67     /**
68      * The used Catalog Manager
69      */

70     private final CatalogManager manager = new CatalogManager();
71
72     /**
73      * the XML Catalog
74      */

75     private Catalog catalog = null;
76
77     /**
78      * the URI of the catalog file
79      */

80     private URI JavaDoc catalogFileURI = null;
81
82     /**
83      * Local Repository where DTDs and Schemas are located
84      */

85     private URI JavaDoc localRepositoryURI = null;
86
87     /**
88      * Flag indicating if this resolver may return null to signal
89      * the parser to open a regular URI connection to the system
90      * identifier. Otherwise an exception is thrown.
91      */

92     private boolean failOnUnresolvable = false;
93
94
95     public LocalEntityResolver(URI JavaDoc catalogFileURI, URI JavaDoc localRepositoryURI, boolean failOnUnresolvable) {
96         this.catalogFileURI = catalogFileURI;
97         setLocalRepositoryURI(localRepositoryURI);
98         setFailOnUnresolvable(failOnUnresolvable);
99         init();
100     }
101
102     /**
103      * Sets the setFailOnUnresolvable flag.
104      *
105      * @param b value (true means that a SAXException is thrown
106      * if the entity could not be resolved)
107      */

108     public void setFailOnUnresolvable(final boolean b) {
109         failOnUnresolvable = b;
110     }
111
112     public boolean isFailOnUnresolvable() {
113         return failOnUnresolvable;
114     }
115
116     public void setCatalogFileURI(final URI JavaDoc catalogFileURI) {
117         this.catalogFileURI = catalogFileURI;
118         init();
119     }
120
121     public URI JavaDoc getCatalogFileURI() {
122         return this.catalogFileURI;
123     }
124
125     public URI JavaDoc getLocalRepositoryURI() {
126         return localRepositoryURI;
127     }
128
129     public void setLocalRepositoryURI(URI JavaDoc string) {
130         localRepositoryURI = string;
131     }
132
133     public void addPublicMapping(final String JavaDoc publicId, final String JavaDoc uri) {
134
135         Vector JavaDoc args = new Vector JavaDoc();
136         args.add(publicId);
137         args.add(uri);
138
139         addEntry("PUBLIC", args);
140
141     }
142
143     public void addSystemMapping(final String JavaDoc systemId, final String JavaDoc uri) {
144
145         Vector JavaDoc args = new Vector JavaDoc();
146         args.add(systemId);
147         args.add(uri);
148
149         addEntry("SYSTEM", args);
150
151     }
152
153     /**
154      * Attempt to resolve the entity based on the supplied publicId and systemId.
155      * First the catalog is queried with both publicId and systemId.
156      * Then the local repository is queried with the file name part of the systemId
157      * Then the classpath is queried with the file name part of the systemId.
158      *
159      * Then, if failOnUnresolvable is true, an exception is thrown: otherwise null is returned.
160      * @param publicId
161      * @param systemId
162      * @return
163      * @throws SAXException
164      * @throws IOException
165      */

166     public InputSource JavaDoc resolveEntity(
167             final String JavaDoc publicId,
168             final String JavaDoc systemId)
169             throws SAXException JavaDoc, IOException JavaDoc {
170
171         if (log.isTraceEnabled()) {
172             log.trace("start resolving for " + entityMessageString(publicId, systemId));
173         }
174
175         InputSource JavaDoc source = resolveWithCatalog(publicId, systemId);
176         if (source != null) {
177             return source;
178         }
179
180         source = resolveWithRepository(publicId, systemId);
181         if (source != null) {
182             return source;
183         }
184
185         source = resolveWithClasspath(publicId, systemId);
186         if (source != null) {
187             return source;
188         }
189
190         String JavaDoc message = "could not resolve " + entityMessageString(publicId, systemId);
191
192         if (failOnUnresolvable) {
193             throw new SAXException JavaDoc(message);
194         } else {
195             log.debug(message);
196         }
197
198         return null;
199     }
200
201     /**
202      * Try to resolve using the catalog file
203      *
204      * @param publicId the PublicId
205      * @param systemId the SystemId
206      * @return InputSource if the entity could be resolved. null otherwise
207      * @throws MalformedURLException
208      * @throws IOException
209      */

210     InputSource JavaDoc resolveWithCatalog(
211             final String JavaDoc publicId,
212             final String JavaDoc systemId)
213             throws MalformedURLException JavaDoc, IOException JavaDoc {
214
215         if (catalogFileURI == null) {
216             return null;
217         }
218
219         String JavaDoc resolvedSystemId =
220                 catalog.resolvePublic(guaranteeNotNull(publicId), systemId);
221
222         if (resolvedSystemId != null) {
223             if (log.isTraceEnabled()) {
224                 log.trace("resolved " + entityMessageString(publicId, systemId) + " using the catalog file. result: " + resolvedSystemId);
225             }
226             return new InputSource JavaDoc(resolvedSystemId);
227         }
228
229         return null;
230     }
231
232     /**
233      * Try to resolve using the local repository and only the supplied systemID filename.
234      * Any path in the systemID will be removed.
235      *
236      * @param publicId the PublicId
237      * @param systemId the SystemId
238      * @return InputSource if the entity could be resolved. null otherwise
239      */

240     InputSource JavaDoc resolveWithRepository(
241             final String JavaDoc publicId,
242             final String JavaDoc systemId) {
243
244         if (localRepositoryURI == null) {
245             return null;
246         }
247
248         String JavaDoc fileName = getSystemIdFileName(systemId);
249
250         if (fileName == null) {
251             return null;
252         }
253
254         InputStream JavaDoc inputStream = null;
255         URI JavaDoc resolvedSystemIDURI;
256         try {
257             resolvedSystemIDURI = localRepositoryURI.resolve(fileName);
258             inputStream = resolvedSystemIDURI.toURL().openStream();
259         } catch (IOException JavaDoc e) {
260             return null;
261         } catch (IllegalArgumentException JavaDoc e) {
262             //typically "uri is not absolute"
263
return null;
264         }
265         if (inputStream != null) {
266             if (log.isTraceEnabled()) {
267                 log.trace("resolved " + entityMessageString(publicId, systemId) + "with file relative to " + localRepositoryURI + resolvedSystemIDURI);
268             }
269             return new InputSource JavaDoc(inputStream);
270         } else {
271             return null;
272         }
273         /*
274         String resolvedSystemId = null;
275
276         File file = new File(localRepositoryURI, fileName);
277         if (file.exists()) {
278             resolvedSystemId = file.getAbsolutePath();
279             if (log.isTraceEnabled()) {
280                 log.trace(
281                         "resolved "
282                         + entityMessageString(publicId, systemId)
283                         + "with file relative to "
284                         + localRepositoryURI
285                         + resolvedSystemId);
286             }
287             return new InputSource(resolvedSystemId);
288         }
289         return null;
290         */

291     }
292
293     /**
294      * Try to resolve using the the classpath and only the supplied systemID.
295      * Any path in the systemID will be removed.
296      *
297      * @param publicId the PublicId
298      * @param systemId the SystemId
299      * @return InputSource if the entity could be resolved. null otherwise
300      */

301     InputSource JavaDoc resolveWithClasspath(
302             final String JavaDoc publicId,
303             final String JavaDoc systemId) {
304
305         String JavaDoc fileName = getSystemIdFileName(systemId);
306
307         if (fileName == null) {
308             return null;
309         }
310
311         InputStream JavaDoc in =
312                 getClass().getClassLoader().getResourceAsStream(fileName);
313         if (in != null) {
314             if (log.isTraceEnabled()) {
315                 log.trace("resolved " + entityMessageString(publicId, systemId) + " via file found file on classpath: " + fileName);
316             }
317             InputSource JavaDoc is = new InputSource JavaDoc(new BufferedInputStream JavaDoc(in));
318             is.setSystemId(systemId);
319             return is;
320         }
321
322         return null;
323     }
324
325     /**
326      * Guarantees a not null value
327      */

328     private String JavaDoc guaranteeNotNull(final String JavaDoc string) {
329         return string != null ? string : "";
330     }
331
332     /**
333      * Returns the SystemIds filename
334      *
335      * @param systemId SystemId
336      * @return filename
337      */

338     private String JavaDoc getSystemIdFileName(final String JavaDoc systemId) {
339
340         if (systemId == null) {
341             return null;
342         }
343
344         int indexBackSlash = systemId.lastIndexOf("\\");
345         int indexSlash = systemId.lastIndexOf("/");
346
347         int index = Math.max(indexBackSlash, indexSlash);
348
349         String JavaDoc fileName = systemId.substring(index + 1);
350         return fileName;
351     }
352
353     /**
354      * Constructs a debugging message string
355      */

356     private String JavaDoc entityMessageString(
357             final String JavaDoc publicId,
358             final String JavaDoc systemId) {
359
360         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("entity with publicId '");
361         buffer.append(publicId);
362         buffer.append("' and systemId '");
363         buffer.append(systemId);
364         buffer.append("'");
365         return buffer.toString();
366
367     }
368
369     /**
370      * Adds a new Entry to the catalog
371      */

372     private void addEntry(String JavaDoc type, Vector JavaDoc args) {
373         try {
374             CatalogEntry entry = new CatalogEntry(type, args);
375             catalog.addEntry(entry);
376         } catch (CatalogException e) {
377             throw new RuntimeException JavaDoc(e);
378         }
379     }
380
381     /**
382      * Loads mappings from configuration file
383      */

384     private void init() {
385
386         if (log.isDebugEnabled()) {
387             log.debug("init catalog file " + this.catalogFileURI);
388         }
389
390         manager.setUseStaticCatalog(false);
391         manager.setCatalogFiles(this.catalogFileURI.toString());
392         manager.setIgnoreMissingProperties(true);
393         catalog = manager.getCatalog();
394     }
395
396     public static final GBeanInfo GBEAN_INFO;
397
398     static {
399         GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("configurable local entity resolver", LocalEntityResolver.class);
400
401         infoFactory.addAttribute("catalogFileURI", URI JavaDoc.class, true);
402         infoFactory.addAttribute("localRepositoryURI", URI JavaDoc.class, true);
403         infoFactory.addAttribute("failOnUnresolvable", boolean.class, true);
404
405         infoFactory.addOperation("resolveEntity", new Class JavaDoc[]{String JavaDoc.class, String JavaDoc.class});
406         infoFactory.addOperation("addPublicMapping", new Class JavaDoc[]{String JavaDoc.class, String JavaDoc.class});
407         infoFactory.addOperation("addSystemMapping", new Class JavaDoc[]{String JavaDoc.class, String JavaDoc.class});
408
409         infoFactory.setConstructor(new String JavaDoc[]{"catalogFileURI", "localRepositoryURI", "failOnUnresolvable"});
410
411         GBEAN_INFO = infoFactory.getBeanInfo();
412     }
413
414     public static GBeanInfo getGBeanInfo() {
415         return GBEAN_INFO;
416     }
417
418 }
419
Popular Tags