KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > StandardURIResolver


1 package net.sf.saxon;
2 import net.sf.saxon.functions.URIQueryParameters;
3 import net.sf.saxon.trans.DynamicError;
4 import net.sf.saxon.trans.XPathException;
5 import net.sf.saxon.event.Stripper;
6 import net.sf.saxon.event.IDFilter;
7 import net.sf.saxon.om.AllElementStripper;
8 import org.xml.sax.InputSource JavaDoc;
9 import org.xml.sax.XMLReader JavaDoc;
10
11 import javax.xml.parsers.SAXParserFactory JavaDoc;
12 import javax.xml.transform.Source JavaDoc;
13 import javax.xml.transform.URIResolver JavaDoc;
14 import javax.xml.transform.sax.SAXSource JavaDoc;
15 import java.io.File JavaDoc;
16 import java.io.Serializable JavaDoc;
17 import java.net.MalformedURLException JavaDoc;
18 import java.net.URI JavaDoc;
19 import java.net.URISyntaxException JavaDoc;
20 import java.net.URL JavaDoc;
21
22
23 /**
24 * This class provides the service of converting a URI into an InputSource.
25 * It is used to get stylesheet modules referenced by xsl:import and xsl:include,
26 * and source documents referenced by the document() function. The standard version
27 * handles anything that the java URL class will handle.
28 * You can write a subclass to handle other kinds of URI, e.g. references to things in
29 * a database.
30 * @author Michael H. Kay
31 */

32
33 public class StandardURIResolver implements URIResolver JavaDoc, Serializable JavaDoc {
34
35     private Configuration config = null;
36     protected boolean recognizeQueryParameters = false;
37
38     /**
39      * Create a StandardURIResolver, with no reference to a TransformerFactory
40      */

41     public StandardURIResolver() {
42         this(null);
43     }
44
45     /**
46      * Create a StandardURIResolver, with a reference to a TransformerFactory
47      * @param config The Configuration object.
48      * This is used to get a SAX Parser for a source XML document
49      */

50
51     public StandardURIResolver(Configuration config) {
52         this.config = config;
53     }
54
55     /**
56      * Indicate that query parameters (such as ?validation=strict) are to be recognized
57      * @param recognize Set to true if query parameters in the URI are to be recognized and acted upon.
58      * The default (for compatibility and interoperability reasons) is false.
59      */

60
61     public void setRecognizeQueryParameters(boolean recognize) {
62         recognizeQueryParameters = recognize;
63     }
64
65     /**
66      * Determine whether query parameters (such as ?validation=strict) are to be recognized
67      * @return true if query parameters are recognized and interpreted by Saxon.
68      */

69
70     public boolean queryParametersAreRecognized() {
71         return recognizeQueryParameters;
72     }
73
74     /**
75     * Resolve a URI
76     * @param href The relative or absolute URI. May be an empty string. May contain
77     * a fragment identifier starting with "#", which must be the value of an ID attribute
78     * in the referenced XML document.
79     * @param base The base URI that should be used. May be null if uri is absolute.
80     * @return a Source object representing an XML document
81     */

82
83     public Source JavaDoc resolve(String JavaDoc href, String JavaDoc base)
84     throws XPathException {
85
86         // System.err.println("StandardURIResolver, HREF=" + href + ", base=" + base);
87

88         String JavaDoc relativeURI = href;
89         String JavaDoc id = null;
90
91         // Extract any fragment identifier. Note, this code is no longer used to
92
// resolve fragment identifiers in URI references passed to the document()
93
// function: the code of the document() function handles these itself.
94

95         int hash = href.indexOf('#');
96         if (hash>=0) {
97             relativeURI = href.substring(0, hash);
98             id = href.substring(hash+1);
99             // System.err.println("StandardURIResolver, HREF=" + href + ", id=" + id);
100
}
101
102         URIQueryParameters params = null;
103         URI JavaDoc url;
104         URI JavaDoc relative;
105         try {
106             relativeURI = escapeSpaces(relativeURI);
107             relative = new URI JavaDoc(relativeURI);
108         } catch (URISyntaxException JavaDoc err) {
109             throw new DynamicError("Invalid relative URI " + Err.wrap(relativeURI), err);
110         }
111
112         String JavaDoc query = relative.getQuery();
113         if (query != null && recognizeQueryParameters) {
114             params = new URIQueryParameters(query, config);
115             int q = relativeURI.indexOf('?');
116             relativeURI = relativeURI.substring(0, q);
117         }
118
119         Source JavaDoc source = null;
120         if (recognizeQueryParameters && relativeURI.endsWith(".ptree")) {
121             source = getPTreeSource(relativeURI, base);
122         }
123
124         if (source == null) {
125             try {
126                 url = makeAbsolute(relativeURI, base);
127             } catch (URISyntaxException JavaDoc err) {
128                 // System.err.println("Recovering from " + err);
129
// last resort: if the base URI is null, or is itself a relative URI, we
130
// try to expand it relative to the current working directory
131
String JavaDoc expandedBase = tryToExpand(base);
132                 if (!expandedBase.equals(base)) { // prevent infinite recursion
133
return resolve(href, expandedBase);
134                 }
135                 //err.printStackTrace();
136
throw new DynamicError("Invalid URI " + Err.wrap(relativeURI) + " - base " + Err.wrap(base), err);
137             }
138
139             source = new SAXSource JavaDoc();
140             ((SAXSource JavaDoc)source).setInputSource(new InputSource JavaDoc(url.toString()));
141             source.setSystemId(url.toString());
142
143             if (params != null) {
144                 XMLReader JavaDoc parser = params.getXMLReader();
145                 if (parser != null) {
146                     ((SAXSource JavaDoc)source).setXMLReader(parser);
147                 }
148             }
149
150             if (((SAXSource JavaDoc)source).getXMLReader() == null) {
151                 if (config==null) {
152                     try {
153                         ((SAXSource JavaDoc)source).setXMLReader(SAXParserFactory.newInstance().newSAXParser().getXMLReader());
154                     } catch (Exception JavaDoc err) {
155                         throw new DynamicError(err);
156                     }
157                 } else {
158                     //((SAXSource)source).setXMLReader(config.getSourceParser());
159
// Leave the Sender to allocate an XMLReader, so that it can be returned to the pool after use
160
}
161             }
162         }
163
164         if (params != null) {
165             Boolean JavaDoc stripSpace = params.getStripSpace();
166             if (stripSpace != null && stripSpace.booleanValue()) {
167                 Stripper stripper = AllElementStripper.getInstance();
168                 stripper.setStripAll();
169                 source = AugmentedSource.makeAugmentedSource(source);
170                 ((AugmentedSource)source).addFilter(stripper);
171             }
172         }
173
174         if (id != null) {
175             IDFilter filter = new IDFilter(id);
176             source = AugmentedSource.makeAugmentedSource(source);
177             ((AugmentedSource)source).addFilter(filter);
178         }
179
180         if (params != null) {
181             Integer JavaDoc validation = params.getValidationMode();
182             if (validation != null) {
183                 source = AugmentedSource.makeAugmentedSource(source);
184                 ((AugmentedSource)source).setSchemaValidationMode(validation.intValue());
185             }
186         }
187
188         return source;
189     }
190
191     /**
192      * Combine the relative URI and base URI
193      */

194
195     public static URI JavaDoc makeAbsolute(String JavaDoc relativeURI, String JavaDoc base) throws DynamicError, URISyntaxException JavaDoc {
196         URI JavaDoc url;
197         relativeURI = escapeSpaces(relativeURI);
198         base = escapeSpaces(base);
199         try {
200             if (base==null) {
201                 url = new URI JavaDoc(relativeURI);
202                 if (!url.isAbsolute()) {
203                     String JavaDoc expandedBase = tryToExpand(base);
204                     if (!expandedBase.equals(base)) { // prevent infinite recursion
205
return makeAbsolute(relativeURI, expandedBase);
206                     }
207                 }
208                 // System.err.println("Resolved " + relativeURI + " as " + url.toString());
209
} else {
210                 // System.err.println("Resolving " + relativeURI + " against " + base);
211
URI JavaDoc baseURL = new URI JavaDoc(base);
212                 // System.err.println("Base URI " + base);
213
url = (relativeURI.length()==0 ?
214                                  baseURL :
215                                  baseURL.resolve(relativeURI)
216                              );
217                 // Note: an older version of this method incorrectly double-escaped percent signs,
218
// for example %20 was escaped to %2520. We removed them by hand, as follows. But
219
// the problem seems to have gone away (test mdocs31)
220
// String u = url.toString();
221
// int pc = u.indexOf("%25");
222
// if (pc >= 0) {
223
// while (pc>=0) {
224
// u = u.substring(0, pc+1) + u.substring(pc+3);
225
// pc = u.indexOf("%25");
226
// }
227
// url = new URI(u);
228
// }
229
// System.err.println("Resolved URI " + url);
230
}
231         } catch (IllegalArgumentException JavaDoc err0) {
232             // can be thrown by resolve() when given a bad URI
233
throw new DynamicError("Invalid URI " + Err.wrap(relativeURI) + " - base " + Err.wrap(base));
234         }
235         return url;
236     }
237
238     /**
239      * Replace spaces by %20
240      */

241
242     public static String JavaDoc escapeSpaces(String JavaDoc s) {
243         // It's not entirely clear why we have to escape spaces by hand, and not other special characters;
244
// it's just that tests with a variety of filenames show that this approach seems to work.
245
if (s == null) return s;
246         int i = s.indexOf(' ');
247         if (i < 0) {
248             return s;
249         }
250         return (i == 0 ? "" : s.substring(0, i))
251                 + "%20"
252                 + (i == s.length()-1 ? "" : escapeSpaces(s.substring(i+1)));
253     }
254     /**
255     * If a system ID can't be parsed as a URL, we'll try to expand it as a relative
256     * URI using the current directory as the base URI: MHK addition.
257     */

258
259     public static String JavaDoc tryToExpand(String JavaDoc systemId) {
260         if (systemId==null) {
261             systemId = "";
262         }
263         try {
264             new URL JavaDoc(systemId);
265             return systemId; // all is well
266
} catch (MalformedURLException JavaDoc err) {
267             String JavaDoc dir;
268             try {
269                 dir = System.getProperty("user.dir");
270             } catch (Exception JavaDoc geterr) {
271                 // this doesn't work when running an applet
272
return systemId;
273             }
274             if (!(dir.endsWith("/") || systemId.startsWith("/"))) {
275                 dir = dir + '/';
276             }
277
278             try {
279                 URL JavaDoc currentDirectoryURL = new File JavaDoc(dir).toURL();
280                 URL JavaDoc baseURL = new URL JavaDoc(currentDirectoryURL, systemId);
281                 // System.err.println("SAX Driver: expanded " + systemId + " to " + baseURL);
282
return baseURL.toString();
283             } catch (MalformedURLException JavaDoc err2) {
284                 // go with the original one
285
return systemId;
286             }
287         }
288     }
289
290     /**
291      * Handle a PTree source file (Saxon-SA only)
292      */

293
294     protected Source JavaDoc getPTreeSource(String JavaDoc href, String JavaDoc base) throws XPathException {
295         return null;
296     }
297
298 }
299
300 //
301
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
302
// you may not use this file except in compliance with the License. You may obtain a copy of the
303
// License at http://www.mozilla.org/MPL/
304
//
305
// Software distributed under the License is distributed on an "AS IS" basis,
306
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
307
// See the License for the specific language governing rights and limitations under the License.
308
//
309
// The Original Code is: all this file.
310
//
311
// The Initial Developer of the Original Code is Michael H. Kay.
312
//
313
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
314
//
315
// Contributor(s): none.
316
//
317
Popular Tags