View Javadoc

1   /*
2    * Copyright (c) 2003 Peter Antman, Teknik i Media  <peter.antman@tim.se>
3    *
4    * $Id: Catalog.java,v 1.1.1.1 2004/05/19 12:07:31 pra Exp $
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2 of the License, or (at your option) any later version
10   * 
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  package org.backsource.utils.xml;
21  import java.util.Vector;
22  import java.io.File;
23  import java.io.InputStream;
24  import java.io.IOException;
25  import java.net.URL;
26  import java.net.MalformedURLException;
27  
28  import javax.xml.parsers.SAXParserFactory;
29  
30  import org.w3c.dom.Document;
31  
32  import org.apache.xml.resolver.CatalogManager;
33  import org.apache.xml.resolver.CatalogException;
34  import org.apache.xml.resolver.readers.CatalogReader;
35  import org.apache.xml.resolver.readers.SAXCatalogReader;
36  import org.apache.xml.resolver.readers.OASISXMLCatalogReader;
37  
38  import org.backsource.utils.io.DOMInputStream;
39  /***
40   * A simple extension of the {@link org.apache.xml.resolver.Catalog} to make it easier to construct instances progranatically. It is easier to add catalog entries and set a baseUri programatically than the original.</p>
41   <p>This version of the Catalog allways need a base uri to work against. This should normally be a directory where dtd:s and other files are collected. To make it easier to use in a component environment where other forms of configurations are used than system wide catalog files the {@link #addCatalogEntry} should be used. The different type of entries jave static create methods in {@link CatalogEntry}. Here is one possible way of setting up the Catalog and adding some entries. It is important to note that how the resolved uris are translated to URL:s, ie resources that are also possible to get physically is really up to the resolver that used this Catalog, see {@link Catalogresolver}.</p>
42   <pre>
43        File base = new File("resources/test/dtd/");
44        catalog = new Catalog(base.getAbsolutePath());
45        
46        // Ad a systemId that will get rewritten to base+dtd2/ttnitf2.dtd
47        catalog.addCatalogEntry( CatalogEntry.getRewriteSystemEntry("http://www.tt.se/dtd/ttnitf2.dtd", "dtd2/ttnitf2.dtd") );
48  
49        // add a systemId, that really shoul be looked up in classpath by resolver
50        catalog.addCatalogEntry( CatalogEntry.getSystemEntry("log4j.dtd", "/org/apache/log4j/xml/log4j.dtd") );
51  
52        // Ad a publicId - amsterdam2.dtd must be in base dir
53        catalog.addCatalogEntry( CatalogEntry.getPublicEntry("-//Teknik i Meda//DTD Amsterdam//EN", "amsterdam2.dtd") );
54  
55        // ad an uri that will be looked up in base + ../xsl/include.xsl
56        CatalogEntry en = CatalogEntry.getUriEntry("include.xsl", "../xsl/include.xsl");
57        
58        catalog.addCatalogEntry( en );
59   </pre>
60   <p> See <a href="http://oasis-open.org/committees/entity/spec-2001-08-06.html">The OASIS</a> spec to understand how the concept works.</p>
61   <p>Apart from all the configuration options given byte the original Catalog it is also possible to configure the Catalog with a DOM tree following the OASI spec. Say you have access to the following xml in a DOM Document: </p>
62   <pre>&lt;?xml version="1.0" ?&gt;
63  &lt;!-- Do NOT forget the trailing slash --&gt;
64  &lt;catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"
65    prefer="public"
66    xml:base="dtd2/"&gt;
67    &lt;public publicId="-//OASIS//DTD DocBook XML V4.1.2//EN"
68              uri="docbookx.dtd"/&gt;
69    &lt;system systemId="ttnitf2.dtd"
70      uri="ttnitf2.dtd"/&gt;
71  
72  &lt;/catalog&gt;
73  </pre>
74  <p>You could configure the Catalog with:</p>
75  <pre>
76  File base = new File("resources/test/dtd/");
77        Catalog cat = new Catalog(base.getAbsolutePath());
78        Document d = DocumentUtil.getDocument( new FileInputStream("resources/test/catalog.xml") );
79        cat.configure(d);
80  </pre>
81  <p>This is obsolete from 1.1. Unfortunately the parsing rutines of the resolver lib seems to be pretty sloppy, so don't be to suprised if the xml was not properly read because some XML error but with no exception.</p>
82   <p>Unfortunately the Catalog implementation is based on a lot of implicit working and static stuff: it is normally meant to be used for system wide usage. This has the disadvandage that there are a lot of stuff that the resolver tries to set in the background; and it will complain about missing propertfiles. To make it shutup, this should be run before the Catalog is used:</p>
83  <pre>
84        org.apache.xml.resolver.CatalogManager.ignoreMissingProperties(true);
85  </pre>
86   * @author <a href="mailto:pra@tim.se">Peter Antman</a>
87   * @version $Revision: 1.1.1.1 $
88   */
89  
90  public class Catalog extends org.apache.xml.resolver.Catalog {
91     public Catalog (String baseUri) throws XmlException{
92        super(new CatalogManager());
93        getCatalogManager().ignoreMissingProperties(true);
94        try {
95           base = new URL(baseUri);
96        } catch (MalformedURLException e) {
97           // Ok it was not an URL try file
98           try {
99              File f = new File(baseUri);
100             base = f.toURL();
101          } catch (Exception ex) {
102             throw new XmlException("The base URI "+baseUri + "was not an URL "+ex,ex);
103          } // end of try-catch
104          
105       } // end of try-catch
106       
107    }
108 
109    public void setDebug(int level) {
110       getCatalogManager().setVerbosity(level);
111    }
112    
113    public void setBaseUri(String baseUri) throws XmlException {
114       try {
115       
116          Vector args = new Vector();
117          args.add(baseUri);
118          org.apache.xml.resolver.CatalogEntry entry = new org.apache.xml.resolver.CatalogEntry(org.apache.xml.resolver.Catalog.BASE, args);
119          addEntry(entry);
120          
121       } catch (CatalogException e) {
122          throw new XmlException("Could not set base " + baseUri + ": " +e,e);
123       } // end of try-catch
124    }
125    
126    public URL getBase() {
127       return base;
128    }
129    
130    public void addCatalogEntry(CatalogEntry entry) {
131       super.addEntry( entry.getEntry() );
132    }
133    
134    /***
135     * Configure from an OASIS xml document.
136     * <p>Ig chaning the base of the catalog with xml:base, don't forget to ad a traling slash to any dirs mentioned!</p>
137     */
138    public void configure(Document doc) throws XmlException{
139       try {
140             SAXParserFactory spf = SAXParserFactory.newInstance();
141       spf.setNamespaceAware(true);
142       spf.setValidating(false);
143       
144       SAXCatalogReader saxReader = new SAXCatalogReader(spf);
145       saxReader.setCatalogParser(OASISXMLCatalogReader.namespaceName,
146                                  "catalog",
147                                  "org.apache.xml.resolver.readers.OASISXMLCatalogReader");
148       addReader("application/xml", saxReader);
149       
150       InputStream is = new DOMInputStream(doc);
151       parseCatalog("application/xml",is);
152                 
153       } catch (CatalogException e) {
154          throw new XmlException("Could not configure catalog from document: "+e,e);
155       } catch (IOException e) {
156          throw new XmlException("Could not configure catalog from document: "+e,e);
157       } // end of catch
158       
159    }
160 }// Catalog