001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.jaxws.description.impl;
020:
021: import org.apache.axis2.jaxws.ExceptionFactory;
022: import org.apache.axis2.jaxws.i18n.Messages;
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.apache.ws.commons.schema.resolver.URIResolver;
026: import org.xml.sax.InputSource;
027:
028: import java.io.File;
029: import java.io.InputStream;
030: import java.net.MalformedURLException;
031: import java.net.URI;
032: import java.net.URISyntaxException;
033: import java.net.URL;
034:
035: /** This class is used to locate xml schemas that are imported by wsdl documents. */
036: public class URIResolverImpl implements URIResolver {
037:
038: private final String HTTP_PROTOCOL = "http";
039:
040: private final String HTTPS_PROTOCOL = "https";
041:
042: private final String FILE_PROTOCOL = "file";
043:
044: private final String JAR_PROTOCOL = "jar";
045:
046: private ClassLoader classLoader;
047:
048: private static final Log log = LogFactory
049: .getLog(URIResolverImpl.class);
050:
051: public URIResolverImpl() {
052: }
053:
054: public URIResolverImpl(ClassLoader cl) {
055: classLoader = cl;
056: }
057:
058: public InputSource resolveEntity(String namespace,
059: String schemaLocation, String baseUri) {
060: //TODO: Temporary, please change the following log.info to log.debug
061: log.info("resolveEntity: [" + namespace + "][" + schemaLocation
062: + "][ " + baseUri + "]");
063:
064: InputStream is = null;
065: URI pathURI = null;
066: String pathURIStr = null;
067: if (log.isDebugEnabled()) {
068: log.debug("Import location: " + schemaLocation
069: + " parent document: " + baseUri);
070: }
071: if (baseUri != null) {
072: try {
073: // if the location is an absolute path, build a URL directly
074: // from it
075: if (log.isDebugEnabled()) {
076: log.debug("Base URI not null");
077: }
078: if (isAbsolute(schemaLocation)) {
079: if (log.isDebugEnabled()) {
080: log
081: .debug("Retrieving input stream for absolute schema location: "
082: + schemaLocation);
083: }
084: is = getInputStreamForURI(schemaLocation);
085: }
086:
087: else {
088: if (log.isDebugEnabled()) {
089: log
090: .debug("schemaLocation not in absolute path");
091: }
092: try {
093: pathURI = new URI(baseUri);
094: } catch (URISyntaxException e) {
095: // Got URISyntaxException, Creation of URI requires
096: // that we use special escape characters in path.
097: // The URI constructor below does this for us, so lets use that.
098: if (log.isDebugEnabled()) {
099: log
100: .debug("Got URISyntaxException. Exception Message = "
101: + e.getMessage());
102: log
103: .debug("Implementing alternate way to create URI");
104: }
105: pathURI = new URI(null, null, baseUri, null);
106: }
107: pathURIStr = schemaLocation;
108: // If this is absolute we need to resolve the path without the
109: // scheme information
110: if (pathURI.isAbsolute()) {
111: if (log.isDebugEnabled()) {
112: log
113: .debug("Parent document is at absolute location: "
114: + pathURI.toString());
115: }
116: URL url = new URL(baseUri);
117: if (url != null) {
118: URI tempURI;
119: try {
120: tempURI = new URI(url.getPath());
121: } catch (URISyntaxException e) {
122: //Got URISyntaxException, Creation of URI requires
123: // that we use special escape characters in path.
124: // The URI constructor below does this for us, so lets use that.
125: if (log.isDebugEnabled()) {
126: log
127: .debug("Got URISyntaxException. Exception Message = "
128: + e.getMessage());
129: log
130: .debug("Implementing alternate way to create URI");
131: }
132: tempURI = new URI(null, null, url
133: .getPath(), null);
134: }
135: URI resolvedURI = tempURI
136: .resolve(schemaLocation);
137: // Add back the scheme to the resolved path
138: pathURIStr = constructPath(url, resolvedURI);
139: if (log.isDebugEnabled()) {
140: log
141: .debug("Resolved this path to imported document: "
142: + pathURIStr);
143: }
144: }
145: } else {
146: if (log.isDebugEnabled()) {
147: log
148: .debug("Parent document is at relative location: "
149: + pathURI.toString());
150: }
151: pathURI = pathURI.resolve(schemaLocation);
152: pathURIStr = pathURI.toString();
153: if (log.isDebugEnabled()) {
154: log
155: .debug("Resolved this path to imported document: "
156: + pathURIStr);
157: }
158: }
159: // If path is absolute, build URL directly from it
160: if (isAbsolute(pathURIStr)) {
161: is = getInputStreamForURI(pathURIStr);
162: }
163:
164: // if the location is relative, we need to resolve the
165: // location using
166: // the baseURI, then use the loadStrategy to gain an input
167: // stream
168: // because the URI will still be relative to the module
169: else {
170: is = classLoader.getResourceAsStream(pathURI
171: .toString());
172: }
173: }
174: } catch (Exception e) {
175: if (log.isDebugEnabled()) {
176: log
177: .debug("Exception occured in resolveEntity, ignoring exception continuing processing "
178: + e.getMessage());
179: log.debug(e);
180: }
181: }
182: }
183: if (is == null) {
184: if (log.isDebugEnabled()) {
185: log
186: .debug("XSD input stream is null after resolving import for: "
187: + schemaLocation
188: + " from parent document: " + baseUri);
189: }
190: } else {
191: if (log.isDebugEnabled()) {
192: log
193: .debug("XSD input stream is not null after resolving import for: "
194: + schemaLocation
195: + " from parent document: " + baseUri);
196: }
197: }
198:
199: InputSource returnInputSource = new InputSource(is);
200: // We need to set the systemId. XmlSchema will use this value to maintain a collection of
201: // imported XSDs that have been read. If this value is null, then circular XSDs will
202: // cause infinite recursive reads.
203: returnInputSource.setSystemId(pathURIStr != null ? pathURIStr
204: : schemaLocation);
205: //TODO: Temporary, please change the following log.info to log.debug
206: log.info("returnInputSource :"
207: + returnInputSource.getSystemId());
208: return returnInputSource;
209: }
210:
211: /**
212: * Checks to see if the location given is an absolute (actual) or relative path.
213: *
214: * @param location
215: * @return
216: */
217: private boolean isAbsolute(String location) {
218: boolean absolute = false;
219: if (location.indexOf(":/") != -1) {
220: absolute = true;
221: } else if (location.indexOf(":\\") != -1) {
222: absolute = true;
223: } else if (location.indexOf("file:") != -1) {
224: absolute = true;
225: }
226: return absolute;
227: }
228:
229: /**
230: * Gets input stream from the uri given. If we cannot find the stream, <code>null</code> is
231: * returned.
232: *
233: * @param uri
234: * @return
235: */
236: private InputStream getInputStreamForURI(String uri) {
237: URL streamURL = null;
238: InputStream is = null;
239: URI pathURI = null;
240:
241: try {
242: streamURL = new URL(uri);
243: is = streamURL.openStream();
244: } catch (Throwable t) {
245: //Exception handling not needed
246: }
247:
248: if (is == null) {
249: try {
250: pathURI = new URI(uri);
251: streamURL = pathURI.toURL();
252: is = streamURL.openStream();
253: } catch (Throwable t) {
254: //Exception handling not needed
255: }
256: }
257:
258: if (is == null) {
259: try {
260: File file = new File(uri);
261: streamURL = file.toURL();
262: is = streamURL.openStream();
263: } catch (Throwable t) {
264: //Exception handling not needed
265: }
266: }
267: return is;
268: }
269:
270: private String constructPath(URL baseURL, URI resolvedURI) {
271: String importLocation = null;
272: URL url = null;
273: try {
274: // Allow for http or https
275: if (baseURL.getProtocol() != null
276: && (baseURL.getProtocol().equals(HTTP_PROTOCOL) || baseURL
277: .getProtocol().equals(HTTPS_PROTOCOL))) {
278: if (log.isDebugEnabled()) {
279: log
280: .debug("Constructing path with http/https protocol");
281: }
282: url = new URL(baseURL.getProtocol(), baseURL.getHost(),
283: baseURL.getPort(), resolvedURI.toString());
284: if (log.isDebugEnabled()) {
285: log.debug("URL = " + url);
286: }
287:
288: }
289: // Check for file
290: else if (baseURL.getProtocol() != null
291: && baseURL.getProtocol().equals(FILE_PROTOCOL)) {
292: if (log.isDebugEnabled()) {
293: log.debug("Constructing path with file protocol");
294: }
295: url = new URL(baseURL.getProtocol(), baseURL.getHost(),
296: resolvedURI.toString());
297: }
298: //Check for jar
299: else if (baseURL.getProtocol() != null
300: && baseURL.getProtocol().equals(JAR_PROTOCOL)) {
301: if (log.isDebugEnabled()) {
302: log.debug("Constructing path with jar protocol");
303: }
304: url = new URL(baseURL.getProtocol(), baseURL.getHost(),
305: resolvedURI.toString());
306: } else {
307: if (log.isDebugEnabled()) {
308: if (baseURL != null) {
309: log.debug("unknown protocol in url "
310: + baseURL.getProtocol());
311: } else {
312: log.debug("baseURL is NULL");
313: }
314: }
315: }
316:
317: } catch (MalformedURLException e) {
318: throw ExceptionFactory.makeWebServiceException(Messages
319: .getMessage("schemaImportError", resolvedURI
320: .toString(), baseURL.toString()), e);
321: }
322: if (url == null) {
323: throw ExceptionFactory.makeWebServiceException(Messages
324: .getMessage("schemaImportError", resolvedURI
325: .toString(), baseURL.toString()));
326: }
327: importLocation = url.toString();
328: return importLocation;
329: }
330:
331: }
|