author | joehw |
Wed, 14 Sep 2016 13:18:17 -0700 | |
changeset 41021 | 444f2b1bcc8c |
parent 26516 | 8e6a45c22cea |
permissions | -rw-r--r-- |
6 | 1 |
/* |
26516 | 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 |
|
6 | 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 com.sun.org.apache.xml.internal.resolver; |
|
19 |
||
20 |
import java.io.IOException; |
|
21 |
import java.io.InputStream; |
|
22 |
import java.io.FileNotFoundException; |
|
23 |
import java.util.Enumeration; |
|
24 |
import java.util.Vector; |
|
25 |
import java.net.URL; |
|
26 |
import java.net.URLConnection; |
|
27 |
import java.net.MalformedURLException; |
|
12458 | 28 |
import javax.xml.parsers.SAXParserFactory; |
29 |
import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl; |
|
16953 | 30 |
import com.sun.org.apache.xerces.internal.utils.SecuritySupport; |
6 | 31 |
import com.sun.org.apache.xml.internal.resolver.readers.SAXCatalogReader; |
32 |
import com.sun.org.apache.xml.internal.resolver.readers.OASISXMLCatalogReader; |
|
33 |
import com.sun.org.apache.xml.internal.resolver.readers.TR9401CatalogReader; |
|
34 |
||
35 |
/** |
|
36 |
* An extension to OASIS Open Catalog files, this class supports |
|
37 |
* suffix-based matching and an external RFC2483 resolver. |
|
38 |
* |
|
39 |
* @see Catalog |
|
41021
444f2b1bcc8c
8165784: Deprecate the internal Catalog API in JDK 9
joehw
parents:
26516
diff
changeset
|
40 |
* @deprecated The JDK internal Catalog API in package |
444f2b1bcc8c
8165784: Deprecate the internal Catalog API in JDK 9
joehw
parents:
26516
diff
changeset
|
41 |
* {@code com.sun.org.apache.xml.internal.resolver} |
444f2b1bcc8c
8165784: Deprecate the internal Catalog API in JDK 9
joehw
parents:
26516
diff
changeset
|
42 |
* is encapsulated in JDK 9. The entire implementation under the package is now |
444f2b1bcc8c
8165784: Deprecate the internal Catalog API in JDK 9
joehw
parents:
26516
diff
changeset
|
43 |
* deprecated and subject to removal in a future release. Users of the API |
444f2b1bcc8c
8165784: Deprecate the internal Catalog API in JDK 9
joehw
parents:
26516
diff
changeset
|
44 |
* should migrate to the {@linkplain javax.xml.catalog new public API}. |
444f2b1bcc8c
8165784: Deprecate the internal Catalog API in JDK 9
joehw
parents:
26516
diff
changeset
|
45 |
* <p> |
444f2b1bcc8c
8165784: Deprecate the internal Catalog API in JDK 9
joehw
parents:
26516
diff
changeset
|
46 |
* The new Catalog API is supported throughout the JDK XML Processors, which allows |
444f2b1bcc8c
8165784: Deprecate the internal Catalog API in JDK 9
joehw
parents:
26516
diff
changeset
|
47 |
* the use of Catalog by simply setting a path to a Catalog file as a property. |
6 | 48 |
* |
49 |
* @author Norman Walsh |
|
50 |
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a> |
|
51 |
* |
|
12458 | 52 |
* @version 1.0 |
6 | 53 |
*/ |
41021
444f2b1bcc8c
8165784: Deprecate the internal Catalog API in JDK 9
joehw
parents:
26516
diff
changeset
|
54 |
@Deprecated(since="9", forRemoval=true) |
6 | 55 |
public class Resolver extends Catalog { |
56 |
/** |
|
57 |
* The URISUFFIX Catalog Entry type. |
|
58 |
* |
|
59 |
* <p>URI suffix entries match URIs that end in a specified suffix.</p> |
|
60 |
*/ |
|
61 |
public static final int URISUFFIX = CatalogEntry.addEntryType("URISUFFIX", 2); |
|
62 |
||
63 |
/** |
|
64 |
* The SYSTEMSUFFIX Catalog Entry type. |
|
65 |
* |
|
66 |
* <p>System suffix entries match system identifiers that end in a |
|
67 |
* specified suffix.</p> |
|
68 |
*/ |
|
69 |
public static final int SYSTEMSUFFIX = CatalogEntry.addEntryType("SYSTEMSUFFIX", 2); |
|
70 |
||
71 |
/** |
|
72 |
* The RESOLVER Catalog Entry type. |
|
73 |
* |
|
74 |
* <p>A hook for providing support for web-based backup resolvers.</p> |
|
75 |
*/ |
|
76 |
public static final int RESOLVER = CatalogEntry.addEntryType("RESOLVER", 1); |
|
77 |
||
78 |
/** |
|
79 |
* The SYSTEMREVERSE Catalog Entry type. |
|
80 |
* |
|
81 |
* <p>This is a bit of a hack. There's no actual SYSTEMREVERSE entry, |
|
82 |
* but this entry type is used to indicate that a reverse lookup is |
|
83 |
* being performed. (This allows the Resolver to implement |
|
84 |
* RFC2483 I2N and I2NS.) |
|
85 |
*/ |
|
86 |
public static final int SYSTEMREVERSE |
|
87 |
= CatalogEntry.addEntryType("SYSTEMREVERSE", 1); |
|
88 |
||
89 |
/** |
|
90 |
* Setup readers. |
|
91 |
*/ |
|
92 |
public void setupReaders() { |
|
12458 | 93 |
SAXParserFactory spf = catalogManager.useServicesMechanism() ? |
94 |
SAXParserFactory.newInstance() : new SAXParserFactoryImpl(); |
|
6 | 95 |
spf.setNamespaceAware(true); |
96 |
spf.setValidating(false); |
|
97 |
||
98 |
SAXCatalogReader saxReader = new SAXCatalogReader(spf); |
|
99 |
||
26516 | 100 |
saxReader.setCatalogParser(null, "XCatalog", |
6 | 101 |
"com.sun.org.apache.xml.internal.resolver.readers.XCatalogReader"); |
102 |
||
103 |
saxReader.setCatalogParser(OASISXMLCatalogReader.namespaceName, |
|
104 |
"catalog", |
|
105 |
"com.sun.org.apache.xml.internal.resolver.readers.ExtendedXMLCatalogReader"); |
|
106 |
||
107 |
addReader("application/xml", saxReader); |
|
108 |
||
109 |
TR9401CatalogReader textReader = new TR9401CatalogReader(); |
|
110 |
addReader("text/plain", textReader); |
|
111 |
} |
|
112 |
||
113 |
/** |
|
114 |
* Cleanup and process a Catalog entry. |
|
115 |
* |
|
116 |
* <p>This method processes each Catalog entry, changing mapped |
|
117 |
* relative system identifiers into absolute ones (based on the current |
|
118 |
* base URI), and maintaining other information about the current |
|
119 |
* catalog.</p> |
|
120 |
* |
|
121 |
* @param entry The CatalogEntry to process. |
|
122 |
*/ |
|
123 |
public void addEntry(CatalogEntry entry) { |
|
124 |
int type = entry.getEntryType(); |
|
125 |
||
126 |
if (type == URISUFFIX) { |
|
127 |
String suffix = normalizeURI(entry.getEntryArg(0)); |
|
128 |
String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1))); |
|
129 |
||
130 |
entry.setEntryArg(1, fsi); |
|
131 |
||
132 |
catalogManager.debug.message(4, "URISUFFIX", suffix, fsi); |
|
133 |
} else if (type == SYSTEMSUFFIX) { |
|
134 |
String suffix = normalizeURI(entry.getEntryArg(0)); |
|
135 |
String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1))); |
|
136 |
||
137 |
entry.setEntryArg(1, fsi); |
|
138 |
||
139 |
catalogManager.debug.message(4, "SYSTEMSUFFIX", suffix, fsi); |
|
140 |
} |
|
141 |
||
142 |
super.addEntry(entry); |
|
143 |
} |
|
144 |
||
145 |
/** |
|
146 |
* Return the applicable URI. |
|
147 |
* |
|
148 |
* <p>If a URI entry exists in the Catalog |
|
149 |
* for the URI specified, return the mapped value.</p> |
|
150 |
* |
|
151 |
* <p>In the Resolver (as opposed to the Catalog) class, if the |
|
152 |
* URI isn't found by the usual algorithm, URISUFFIX entries are |
|
153 |
* considered.</p> |
|
154 |
* |
|
155 |
* <p>URI comparison is case sensitive.</p> |
|
156 |
* |
|
157 |
* @param uri The URI to locate in the catalog. |
|
158 |
* |
|
159 |
* @return The resolved URI. |
|
160 |
* |
|
161 |
* @throws MalformedURLException The system identifier of a |
|
162 |
* subordinate catalog cannot be turned into a valid URL. |
|
163 |
* @throws IOException Error reading subordinate catalog file. |
|
164 |
*/ |
|
165 |
public String resolveURI(String uri) |
|
166 |
throws MalformedURLException, IOException { |
|
167 |
||
168 |
String resolved = super.resolveURI(uri); |
|
169 |
if (resolved != null) { |
|
170 |
return resolved; |
|
171 |
} |
|
172 |
||
173 |
Enumeration en = catalogEntries.elements(); |
|
174 |
while (en.hasMoreElements()) { |
|
175 |
CatalogEntry e = (CatalogEntry) en.nextElement(); |
|
176 |
if (e.getEntryType() == RESOLVER) { |
|
177 |
resolved = resolveExternalSystem(uri, e.getEntryArg(0)); |
|
178 |
if (resolved != null) { |
|
179 |
return resolved; |
|
180 |
} |
|
181 |
} else if (e.getEntryType() == URISUFFIX) { |
|
182 |
String suffix = e.getEntryArg(0); |
|
183 |
String result = e.getEntryArg(1); |
|
184 |
||
185 |
if (suffix.length() <= uri.length() |
|
186 |
&& uri.substring(uri.length()-suffix.length()).equals(suffix)) { |
|
187 |
return result; |
|
188 |
} |
|
189 |
} |
|
190 |
} |
|
191 |
||
192 |
// Otherwise, look in the subordinate catalogs |
|
193 |
return resolveSubordinateCatalogs(Catalog.URI, |
|
194 |
null, |
|
195 |
null, |
|
196 |
uri); |
|
197 |
} |
|
198 |
||
199 |
/** |
|
200 |
* Return the applicable SYSTEM system identifier, resorting |
|
201 |
* to external RESOLVERs if necessary. |
|
202 |
* |
|
203 |
* <p>If a SYSTEM entry exists in the Catalog |
|
204 |
* for the system ID specified, return the mapped value.</p> |
|
205 |
* |
|
206 |
* <p>In the Resolver (as opposed to the Catalog) class, if the |
|
207 |
* URI isn't found by the usual algorithm, SYSTEMSUFFIX entries are |
|
208 |
* considered.</p> |
|
209 |
* |
|
210 |
* <p>On Windows-based operating systems, the comparison between |
|
211 |
* the system identifier provided and the SYSTEM entries in the |
|
212 |
* Catalog is case-insensitive.</p> |
|
213 |
* |
|
214 |
* @param systemId The system ID to locate in the catalog. |
|
215 |
* |
|
216 |
* @return The system identifier to use for systemId. |
|
217 |
* |
|
218 |
* @throws MalformedURLException The formal system identifier of a |
|
219 |
* subordinate catalog cannot be turned into a valid URL. |
|
220 |
* @throws IOException Error reading subordinate catalog file. |
|
221 |
*/ |
|
222 |
public String resolveSystem(String systemId) |
|
223 |
throws MalformedURLException, IOException { |
|
224 |
||
225 |
String resolved = super.resolveSystem(systemId); |
|
226 |
if (resolved != null) { |
|
227 |
return resolved; |
|
228 |
} |
|
229 |
||
230 |
Enumeration en = catalogEntries.elements(); |
|
231 |
while (en.hasMoreElements()) { |
|
232 |
CatalogEntry e = (CatalogEntry) en.nextElement(); |
|
233 |
if (e.getEntryType() == RESOLVER) { |
|
234 |
resolved = resolveExternalSystem(systemId, e.getEntryArg(0)); |
|
235 |
if (resolved != null) { |
|
236 |
return resolved; |
|
237 |
} |
|
238 |
} else if (e.getEntryType() == SYSTEMSUFFIX) { |
|
239 |
String suffix = e.getEntryArg(0); |
|
240 |
String result = e.getEntryArg(1); |
|
241 |
||
242 |
if (suffix.length() <= systemId.length() |
|
243 |
&& systemId.substring(systemId.length()-suffix.length()).equals(suffix)) { |
|
244 |
return result; |
|
245 |
} |
|
246 |
} |
|
247 |
} |
|
248 |
||
249 |
return resolveSubordinateCatalogs(Catalog.SYSTEM, |
|
250 |
null, |
|
251 |
null, |
|
252 |
systemId); |
|
253 |
} |
|
254 |
||
255 |
/** |
|
256 |
* Return the applicable PUBLIC or SYSTEM identifier, resorting |
|
257 |
* to external resolvers if necessary. |
|
258 |
* |
|
259 |
* <p>This method searches the Catalog and returns the system |
|
260 |
* identifier specified for the given system or |
|
261 |
* public identifiers. If |
|
262 |
* no appropriate PUBLIC or SYSTEM entry is found in the Catalog, |
|
263 |
* null is returned.</p> |
|
264 |
* |
|
265 |
* <p>Note that a system or public identifier in the current catalog |
|
266 |
* (or subordinate catalogs) will be used in preference to an |
|
267 |
* external resolver. Further, if a systemId is present, the external |
|
268 |
* resolver(s) will be queried for that before the publicId.</p> |
|
269 |
* |
|
270 |
* @param publicId The public identifier to locate in the catalog. |
|
271 |
* Public identifiers are normalized before comparison. |
|
272 |
* @param systemId The nominal system identifier for the entity |
|
273 |
* in question (as provided in the source document). |
|
274 |
* |
|
275 |
* @throws MalformedURLException The formal system identifier of a |
|
276 |
* subordinate catalog cannot be turned into a valid URL. |
|
277 |
* @throws IOException Error reading subordinate catalog file. |
|
278 |
* |
|
279 |
* @return The system identifier to use. |
|
280 |
* Note that the nominal system identifier is not returned if a |
|
281 |
* match is not found in the catalog, instead null is returned |
|
282 |
* to indicate that no match was found. |
|
283 |
*/ |
|
284 |
public String resolvePublic(String publicId, String systemId) |
|
285 |
throws MalformedURLException, IOException { |
|
286 |
||
287 |
String resolved = super.resolvePublic(publicId, systemId); |
|
288 |
if (resolved != null) { |
|
289 |
return resolved; |
|
290 |
} |
|
291 |
||
292 |
Enumeration en = catalogEntries.elements(); |
|
293 |
while (en.hasMoreElements()) { |
|
294 |
CatalogEntry e = (CatalogEntry) en.nextElement(); |
|
295 |
if (e.getEntryType() == RESOLVER) { |
|
296 |
if (systemId != null) { |
|
297 |
resolved = resolveExternalSystem(systemId, |
|
298 |
e.getEntryArg(0)); |
|
299 |
if (resolved != null) { |
|
300 |
return resolved; |
|
301 |
} |
|
302 |
} |
|
303 |
resolved = resolveExternalPublic(publicId, e.getEntryArg(0)); |
|
304 |
if (resolved != null) { |
|
305 |
return resolved; |
|
306 |
} |
|
307 |
} |
|
308 |
} |
|
309 |
||
310 |
return resolveSubordinateCatalogs(Catalog.PUBLIC, |
|
311 |
null, |
|
312 |
publicId, |
|
313 |
systemId); |
|
314 |
} |
|
315 |
||
316 |
/** |
|
317 |
* Query an external RFC2483 resolver for a system identifier. |
|
318 |
* |
|
319 |
* @param systemId The system ID to locate. |
|
320 |
* @param resolver The name of the resolver to use. |
|
321 |
* |
|
322 |
* @return The system identifier to use for the systemId. |
|
323 |
*/ |
|
324 |
protected String resolveExternalSystem(String systemId, String resolver) |
|
325 |
throws MalformedURLException, IOException { |
|
326 |
Resolver r = queryResolver(resolver, "i2l", systemId, null); |
|
327 |
if (r != null) { |
|
328 |
return r.resolveSystem(systemId); |
|
329 |
} else { |
|
330 |
return null; |
|
331 |
} |
|
332 |
} |
|
333 |
||
334 |
/** |
|
335 |
* Query an external RFC2483 resolver for a public identifier. |
|
336 |
* |
|
337 |
* @param publicId The system ID to locate. |
|
338 |
* @param resolver The name of the resolver to use. |
|
339 |
* |
|
340 |
* @return The system identifier to use for the systemId. |
|
341 |
*/ |
|
342 |
protected String resolveExternalPublic(String publicId, String resolver) |
|
343 |
throws MalformedURLException, IOException { |
|
344 |
Resolver r = queryResolver(resolver, "fpi2l", publicId, null); |
|
345 |
if (r != null) { |
|
346 |
return r.resolvePublic(publicId, null); |
|
347 |
} else { |
|
348 |
return null; |
|
349 |
} |
|
350 |
} |
|
351 |
||
352 |
/** |
|
353 |
* Query an external RFC2483 resolver. |
|
354 |
* |
|
355 |
* @param resolver The URL of the RFC2483 resolver. |
|
356 |
* @param command The command to send the resolver. |
|
357 |
* @param arg1 The first argument to the resolver. |
|
358 |
* @param arg2 The second argument to the resolver, usually null. |
|
359 |
* |
|
360 |
* @return The Resolver constructed. |
|
361 |
*/ |
|
362 |
protected Resolver queryResolver(String resolver, |
|
363 |
String command, |
|
364 |
String arg1, |
|
365 |
String arg2) { |
|
366 |
InputStream iStream = null; |
|
367 |
String RFC2483 = resolver + "?command=" + command |
|
368 |
+ "&format=tr9401&uri=" + arg1 |
|
369 |
+ "&uri2=" + arg2; |
|
370 |
String line = null; |
|
371 |
||
372 |
try { |
|
373 |
URL url = new URL(RFC2483); |
|
374 |
||
375 |
URLConnection urlCon = url.openConnection(); |
|
376 |
||
377 |
urlCon.setUseCaches(false); |
|
378 |
||
379 |
Resolver r = (Resolver) newCatalog(); |
|
380 |
||
381 |
String cType = urlCon.getContentType(); |
|
382 |
||
383 |
// I don't care about the character set or subtype |
|
384 |
if (cType.indexOf(";") > 0) { |
|
385 |
cType = cType.substring(0, cType.indexOf(";")); |
|
386 |
} |
|
387 |
||
388 |
r.parseCatalog(cType, urlCon.getInputStream()); |
|
389 |
||
390 |
return r; |
|
391 |
} catch (CatalogException cex) { |
|
392 |
if (cex.getExceptionType() == CatalogException.UNPARSEABLE) { |
|
393 |
catalogManager.debug.message(1, "Unparseable catalog: " + RFC2483); |
|
394 |
} else if (cex.getExceptionType() |
|
395 |
== CatalogException.UNKNOWN_FORMAT) { |
|
396 |
catalogManager.debug.message(1, "Unknown catalog format: " + RFC2483); |
|
397 |
} |
|
398 |
return null; |
|
399 |
} catch (MalformedURLException mue) { |
|
400 |
catalogManager.debug.message(1, "Malformed resolver URL: " + RFC2483); |
|
401 |
return null; |
|
402 |
} catch (IOException ie) { |
|
403 |
catalogManager.debug.message(1, "I/O Exception opening resolver: " + RFC2483); |
|
404 |
return null; |
|
405 |
} |
|
406 |
} |
|
407 |
||
408 |
/** |
|
409 |
* Append two vectors, returning the result. |
|
410 |
* |
|
411 |
* @param vec The first vector |
|
412 |
* @param appvec The vector to be appended |
|
413 |
* @return The vector vec, with appvec's elements appended to it |
|
414 |
*/ |
|
415 |
private Vector appendVector(Vector vec, Vector appvec) { |
|
416 |
if (appvec != null) { |
|
417 |
for (int count = 0; count < appvec.size(); count++) { |
|
418 |
vec.addElement(appvec.elementAt(count)); |
|
419 |
} |
|
420 |
} |
|
421 |
return vec; |
|
422 |
} |
|
423 |
||
424 |
/** |
|
425 |
* Find the URNs for a given system identifier in all catalogs. |
|
426 |
* |
|
427 |
* @param systemId The system ID to locate. |
|
428 |
* |
|
429 |
* @return A vector of URNs that map to the systemId. |
|
430 |
*/ |
|
431 |
public Vector resolveAllSystemReverse(String systemId) |
|
432 |
throws MalformedURLException, IOException { |
|
433 |
Vector resolved = new Vector(); |
|
434 |
||
435 |
// If there's a SYSTEM entry in this catalog, use it |
|
436 |
if (systemId != null) { |
|
437 |
Vector localResolved = resolveLocalSystemReverse(systemId); |
|
438 |
resolved = appendVector(resolved, localResolved); |
|
439 |
} |
|
440 |
||
441 |
// Otherwise, look in the subordinate catalogs |
|
442 |
Vector subResolved = resolveAllSubordinateCatalogs(SYSTEMREVERSE, |
|
443 |
null, |
|
444 |
null, |
|
445 |
systemId); |
|
446 |
||
447 |
return appendVector(resolved, subResolved); |
|
448 |
} |
|
449 |
||
450 |
/** |
|
451 |
* Find the URN for a given system identifier. |
|
452 |
* |
|
453 |
* @param systemId The system ID to locate. |
|
454 |
* |
|
455 |
* @return A (single) URN that maps to the systemId. |
|
456 |
*/ |
|
457 |
public String resolveSystemReverse(String systemId) |
|
458 |
throws MalformedURLException, IOException { |
|
459 |
Vector resolved = resolveAllSystemReverse(systemId); |
|
460 |
if (resolved != null && resolved.size() > 0) { |
|
461 |
return (String) resolved.elementAt(0); |
|
462 |
} else { |
|
463 |
return null; |
|
464 |
} |
|
465 |
} |
|
466 |
||
467 |
/** |
|
468 |
* Return the applicable SYSTEM system identifiers. |
|
469 |
* |
|
470 |
* <p>If one or more SYSTEM entries exists in the Catalog |
|
471 |
* for the system ID specified, return the mapped values.</p> |
|
472 |
* |
|
473 |
* <p>The caller is responsible for doing any necessary |
|
474 |
* normalization of the system identifier before calling |
|
475 |
* this method. For example, a relative system identifier in |
|
476 |
* a document might be converted to an absolute system identifier |
|
477 |
* before attempting to resolve it.</p> |
|
478 |
* |
|
479 |
* <p>Note that this function will force all subordinate catalogs |
|
480 |
* to be loaded.</p> |
|
481 |
* |
|
482 |
* <p>On Windows-based operating systems, the comparison between |
|
483 |
* the system identifier provided and the SYSTEM entries in the |
|
484 |
* Catalog is case-insensitive.</p> |
|
485 |
* |
|
486 |
* @param systemId The system ID to locate in the catalog. |
|
487 |
* |
|
488 |
* @return The system identifier to use for the notation. |
|
489 |
* |
|
490 |
* @throws MalformedURLException The formal system identifier of a |
|
491 |
* subordinate catalog cannot be turned into a valid URL. |
|
492 |
* @throws IOException Error reading subordinate catalog file. |
|
493 |
*/ |
|
494 |
public Vector resolveAllSystem(String systemId) |
|
495 |
throws MalformedURLException, IOException { |
|
496 |
Vector resolutions = new Vector(); |
|
497 |
||
498 |
// If there are SYSTEM entries in this catalog, start with them |
|
499 |
if (systemId != null) { |
|
500 |
Vector localResolutions = resolveAllLocalSystem(systemId); |
|
501 |
resolutions = appendVector(resolutions, localResolutions); |
|
502 |
} |
|
503 |
||
504 |
// Then look in the subordinate catalogs |
|
505 |
Vector subResolutions = resolveAllSubordinateCatalogs(SYSTEM, |
|
506 |
null, |
|
507 |
null, |
|
508 |
systemId); |
|
509 |
resolutions = appendVector(resolutions, subResolutions); |
|
510 |
||
511 |
if (resolutions.size() > 0) { |
|
512 |
return resolutions; |
|
513 |
} else { |
|
514 |
return null; |
|
515 |
} |
|
516 |
} |
|
517 |
||
518 |
/** |
|
519 |
* Return all applicable SYSTEM system identifiers in this |
|
520 |
* catalog. |
|
521 |
* |
|
522 |
* <p>If one or more SYSTEM entries exists in the catalog file |
|
523 |
* for the system ID specified, return the mapped values.</p> |
|
524 |
* |
|
525 |
* @param systemId The system ID to locate in the catalog |
|
526 |
* |
|
527 |
* @return A vector of the mapped system identifiers or null |
|
528 |
*/ |
|
529 |
private Vector resolveAllLocalSystem(String systemId) { |
|
530 |
Vector map = new Vector(); |
|
16953 | 531 |
String osname = SecuritySupport.getSystemProperty("os.name"); |
6 | 532 |
boolean windows = (osname.indexOf("Windows") >= 0); |
533 |
Enumeration en = catalogEntries.elements(); |
|
534 |
while (en.hasMoreElements()) { |
|
535 |
CatalogEntry e = (CatalogEntry) en.nextElement(); |
|
536 |
if (e.getEntryType() == SYSTEM |
|
537 |
&& (e.getEntryArg(0).equals(systemId) |
|
538 |
|| (windows |
|
539 |
&& e.getEntryArg(0).equalsIgnoreCase(systemId)))) { |
|
540 |
map.addElement(e.getEntryArg(1)); |
|
541 |
} |
|
542 |
} |
|
543 |
if (map.size() == 0) { |
|
544 |
return null; |
|
545 |
} else { |
|
546 |
return map; |
|
547 |
} |
|
548 |
} |
|
549 |
||
550 |
/** |
|
551 |
* Find the URNs for a given system identifier in the current catalog. |
|
552 |
* |
|
553 |
* @param systemId The system ID to locate. |
|
554 |
* |
|
555 |
* @return A vector of URNs that map to the systemId. |
|
556 |
*/ |
|
557 |
private Vector resolveLocalSystemReverse(String systemId) { |
|
558 |
Vector map = new Vector(); |
|
16953 | 559 |
String osname = SecuritySupport.getSystemProperty("os.name"); |
6 | 560 |
boolean windows = (osname.indexOf("Windows") >= 0); |
561 |
Enumeration en = catalogEntries.elements(); |
|
562 |
while (en.hasMoreElements()) { |
|
563 |
CatalogEntry e = (CatalogEntry) en.nextElement(); |
|
564 |
if (e.getEntryType() == SYSTEM |
|
565 |
&& (e.getEntryArg(1).equals(systemId) |
|
566 |
|| (windows |
|
567 |
&& e.getEntryArg(1).equalsIgnoreCase(systemId)))) { |
|
568 |
map.addElement(e.getEntryArg(0)); |
|
569 |
} |
|
570 |
} |
|
571 |
if (map.size() == 0) { |
|
572 |
return null; |
|
573 |
} else { |
|
574 |
return map; |
|
575 |
} |
|
576 |
} |
|
577 |
||
578 |
/** |
|
579 |
* Search the subordinate catalogs, in order, looking for all |
|
580 |
* match. |
|
581 |
* |
|
582 |
* <p>This method searches the Catalog and returns all of the system |
|
583 |
* identifiers specified for the given entity type with the given |
|
584 |
* name, public, and system identifiers. In some contexts, these |
|
585 |
* may be null.</p> |
|
586 |
* |
|
587 |
* @param entityType The CatalogEntry type for which this query is |
|
588 |
* being conducted. This is necessary in order to do the approprate |
|
589 |
* query on a subordinate catalog. |
|
590 |
* @param entityName The name of the entity being searched for, if |
|
591 |
* appropriate. |
|
592 |
* @param publicId The public identifier of the entity in question |
|
593 |
* (as provided in the source document). |
|
594 |
* @param systemId The nominal system identifier for the entity |
|
595 |
* in question (as provided in the source document). |
|
596 |
* |
|
597 |
* @throws MalformedURLException The formal system identifier of a |
|
598 |
* delegated catalog cannot be turned into a valid URL. |
|
599 |
* @throws IOException Error reading delegated catalog file. |
|
600 |
* |
|
601 |
* @return The system identifier to use. |
|
602 |
* Note that the nominal system identifier is not returned if a |
|
603 |
* match is not found in the catalog, instead null is returned |
|
604 |
* to indicate that no match was found. |
|
605 |
*/ |
|
606 |
private synchronized Vector resolveAllSubordinateCatalogs(int entityType, |
|
607 |
String entityName, |
|
608 |
String publicId, |
|
609 |
String systemId) |
|
610 |
throws MalformedURLException, IOException { |
|
611 |
||
612 |
Vector resolutions = new Vector(); |
|
613 |
||
614 |
for (int catPos = 0; catPos < catalogs.size(); catPos++) { |
|
615 |
Resolver c = null; |
|
616 |
||
617 |
try { |
|
618 |
c = (Resolver) catalogs.elementAt(catPos); |
|
619 |
} catch (ClassCastException e) { |
|
620 |
String catfile = (String) catalogs.elementAt(catPos); |
|
621 |
c = (Resolver) newCatalog(); |
|
622 |
||
623 |
try { |
|
624 |
c.parseCatalog(catfile); |
|
625 |
} catch (MalformedURLException mue) { |
|
626 |
catalogManager.debug.message(1, "Malformed Catalog URL", catfile); |
|
627 |
} catch (FileNotFoundException fnfe) { |
|
628 |
catalogManager.debug.message(1, "Failed to load catalog, file not found", |
|
629 |
catfile); |
|
630 |
} catch (IOException ioe) { |
|
631 |
catalogManager.debug.message(1, "Failed to load catalog, I/O error", catfile); |
|
632 |
} |
|
633 |
||
634 |
catalogs.setElementAt(c, catPos); |
|
635 |
} |
|
636 |
||
637 |
String resolved = null; |
|
638 |
||
639 |
// Ok, now what are we supposed to call here? |
|
640 |
if (entityType == DOCTYPE) { |
|
641 |
resolved = c.resolveDoctype(entityName, |
|
642 |
publicId, |
|
643 |
systemId); |
|
644 |
if (resolved != null) { |
|
645 |
// Only find one DOCTYPE resolution |
|
646 |
resolutions.addElement(resolved); |
|
647 |
return resolutions; |
|
648 |
} |
|
649 |
} else if (entityType == DOCUMENT) { |
|
650 |
resolved = c.resolveDocument(); |
|
651 |
if (resolved != null) { |
|
652 |
// Only find one DOCUMENT resolution |
|
653 |
resolutions.addElement(resolved); |
|
654 |
return resolutions; |
|
655 |
} |
|
656 |
} else if (entityType == ENTITY) { |
|
657 |
resolved = c.resolveEntity(entityName, |
|
658 |
publicId, |
|
659 |
systemId); |
|
660 |
if (resolved != null) { |
|
661 |
// Only find one ENTITY resolution |
|
662 |
resolutions.addElement(resolved); |
|
663 |
return resolutions; |
|
664 |
} |
|
665 |
} else if (entityType == NOTATION) { |
|
666 |
resolved = c.resolveNotation(entityName, |
|
667 |
publicId, |
|
668 |
systemId); |
|
669 |
if (resolved != null) { |
|
670 |
// Only find one NOTATION resolution |
|
671 |
resolutions.addElement(resolved); |
|
672 |
return resolutions; |
|
673 |
} |
|
674 |
} else if (entityType == PUBLIC) { |
|
675 |
resolved = c.resolvePublic(publicId, systemId); |
|
676 |
if (resolved != null) { |
|
677 |
// Only find one PUBLIC resolution |
|
678 |
resolutions.addElement(resolved); |
|
679 |
return resolutions; |
|
680 |
} |
|
681 |
} else if (entityType == SYSTEM) { |
|
682 |
Vector localResolutions = c.resolveAllSystem(systemId); |
|
683 |
resolutions = appendVector(resolutions, localResolutions); |
|
684 |
break; |
|
685 |
} else if (entityType == SYSTEMREVERSE) { |
|
686 |
Vector localResolutions = c.resolveAllSystemReverse(systemId); |
|
687 |
resolutions = appendVector(resolutions, localResolutions); |
|
688 |
} |
|
689 |
} |
|
690 |
||
691 |
if (resolutions != null) { |
|
692 |
return resolutions; |
|
693 |
} else { |
|
694 |
return null; |
|
695 |
} |
|
696 |
} |
|
697 |
} |