| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.axis2.jaxws.description.impl; |
| |
| import org.apache.axis2.jaxws.ExceptionFactory; |
| import org.apache.axis2.jaxws.i18n.Messages; |
| import org.apache.axis2.java.security.AccessController; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.ws.commons.schema.resolver.URIResolver; |
| import org.xml.sax.InputSource; |
| |
| import java.io.File; |
| import java.io.InputStream; |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.net.URL; |
| import java.security.PrivilegedAction; |
| import java.security.PrivilegedExceptionAction; |
| import java.security.PrivilegedActionException; |
| |
| /** This class is used to locate xml schemas that are imported by wsdl documents. */ |
| public class URIResolverImpl implements URIResolver { |
| |
| private static final String HTTP_PROTOCOL = "http"; |
| |
| private static final String HTTPS_PROTOCOL = "https"; |
| |
| private static final String FILE_PROTOCOL = "file"; |
| |
| private static final String JAR_PROTOCOL = "jar"; |
| |
| private static final String BUNDLE_RESOURCE_PROTOCOL = "bundleresource"; |
| |
| private ClassLoader classLoader; |
| |
| private static final Log log = LogFactory.getLog(URIResolverImpl.class); |
| |
| public URIResolverImpl() { |
| } |
| |
| public URIResolverImpl(ClassLoader cl) { |
| classLoader = cl; |
| } |
| |
| public InputSource resolveEntity(String namespace, String schemaLocation, |
| String baseUri) { |
| if (log.isDebugEnabled()) { |
| log.debug("resolveEntity: ["+ namespace + "]["+ schemaLocation + "][ " + baseUri+ "]"); |
| } |
| |
| InputStream is = null; |
| URI pathURI = null; |
| String pathURIStr = null; |
| if(log.isDebugEnabled()) { |
| log.debug("Import location: " + schemaLocation + " parent document: " + |
| baseUri); |
| } |
| if (baseUri != null) { |
| try { |
| // if the location is an absolute path, build a URL directly |
| // from it |
| if(log.isDebugEnabled()){ |
| log.debug("Base URI not null"); |
| } |
| if (isAbsolute(schemaLocation)) { |
| if(log.isDebugEnabled()) { |
| log.debug("Retrieving input stream for absolute schema location: " |
| + schemaLocation); |
| } |
| is = getInputStreamForURI(schemaLocation); |
| } |
| |
| else { |
| if(log.isDebugEnabled()){ |
| log.debug("schemaLocation not in absolute path"); |
| } |
| try{ |
| pathURI = new URI(baseUri); |
| }catch(URISyntaxException e){ |
| // Got URISyntaxException, Creation of URI requires |
| // that we use special escape characters in path. |
| // The URI constructor below does this for us, so lets use that. |
| if(log.isDebugEnabled()){ |
| log.debug("Got URISyntaxException. Exception Message = "+e.getMessage()); |
| log.debug("Implementing alternate way to create URI"); |
| } |
| pathURI = new URI(null, null, baseUri, null); |
| } |
| pathURIStr = schemaLocation; |
| // If this is absolute we need to resolve the path without the |
| // scheme information |
| if (pathURI.isAbsolute()) { |
| if(log.isDebugEnabled()) { |
| log.debug("Parent document is at absolute location: " + |
| pathURI.toString()); |
| } |
| URL url = new URL(baseUri); |
| if (url != null) { |
| URI tempURI; |
| try{ |
| tempURI = new URI(url.getPath()); |
| }catch(URISyntaxException e){ |
| //Got URISyntaxException, Creation of URI requires |
| // that we use special escape characters in path. |
| // The URI constructor below does this for us, so lets use that. |
| if(log.isDebugEnabled()){ |
| log.debug("Got URISyntaxException. Exception Message = "+e.getMessage()); |
| log.debug("Implementing alternate way to create URI"); |
| } |
| tempURI = new URI(null, null, url.getPath(), null); |
| } |
| URI resolvedURI = tempURI.resolve(schemaLocation); |
| // Add back the scheme to the resolved path |
| pathURIStr = constructPath(url, resolvedURI); |
| if(log.isDebugEnabled()) { |
| log.debug("Resolved this path to imported document: " + |
| pathURIStr); |
| } |
| } |
| } else { |
| if(log.isDebugEnabled()) { |
| log.debug("Parent document is at relative location: " + |
| pathURI.toString()); |
| } |
| pathURI = pathURI.resolve(schemaLocation); |
| pathURIStr = pathURI.toString(); |
| if(log.isDebugEnabled()) { |
| log.debug("Resolved this path to imported document: " + |
| pathURIStr); |
| } |
| } |
| // If path is absolute, build URL directly from it |
| if (isAbsolute(pathURIStr)) { |
| is = getInputStreamForURI(pathURIStr); |
| } |
| |
| // if the location is relative, we need to resolve the |
| // location using |
| // the baseURI, then use the loadStrategy to gain an input |
| // stream |
| // because the URI will still be relative to the module |
| if(is == null) { |
| is = classLoader |
| .getResourceAsStream(pathURI.toString()); |
| } |
| } |
| } catch (Exception e) { |
| if(log.isDebugEnabled()) { |
| log.debug("Exception occured in resolveEntity, ignoring exception continuing processing "+e.getMessage()); |
| log.debug(e); |
| } |
| } |
| } |
| if(is == null) { |
| if(log.isDebugEnabled()) { |
| log.debug("XSD input stream is null after resolving import for: " + |
| schemaLocation + " from parent document: " + baseUri); |
| } |
| } |
| else { |
| if(log.isDebugEnabled()) { |
| log.debug("XSD input stream is not null after resolving import for: " + |
| schemaLocation + " from parent document: " + baseUri); |
| } |
| } |
| |
| InputSource returnInputSource = new InputSource(is); |
| // We need to set the systemId. XmlSchema will use this value to maintain a collection of |
| // imported XSDs that have been read. If this value is null, then circular XSDs will |
| // cause infinite recursive reads. |
| returnInputSource.setSystemId(pathURIStr != null ? pathURIStr : schemaLocation); |
| |
| if (log.isDebugEnabled()) { |
| log.debug("returnInputSource :" + returnInputSource.getSystemId()); |
| } |
| |
| return returnInputSource; |
| } |
| |
| /** |
| * Checks to see if the location given is an absolute (actual) or relative path. |
| * |
| * @param location |
| * @return |
| */ |
| private boolean isAbsolute(String location) { |
| boolean absolute = false; |
| if (location.indexOf(":/") != -1) { |
| absolute = true; |
| } else if (location.indexOf(":\\") != -1) { |
| absolute = true; |
| } else if (location.indexOf("file:") != -1) { |
| absolute = true; |
| } |
| return absolute; |
| } |
| |
| /** |
| * Gets input stream from the uri given. If we cannot find the stream, <code>null</code> is |
| * returned. |
| * |
| * @param uri |
| * @return |
| */ |
| private InputStream getInputStreamForURI(String uri) { |
| URL streamURL = null; |
| InputStream is = null; |
| URI pathURI = null; |
| |
| try { |
| streamURL = new URL(uri); |
| is = openStream_doPriv(streamURL); |
| } catch (Throwable t) { |
| //Exception handling not needed |
| } |
| |
| if (is == null) { |
| try { |
| pathURI = new URI(uri); |
| streamURL = pathURI.toURL(); |
| is = openStream_doPriv(streamURL); |
| } catch (Throwable t) { |
| //Exception handling not needed |
| } |
| } |
| |
| if (is == null) { |
| try { |
| final File file = new File(uri); |
| streamURL = (URL) AccessController.doPrivileged( |
| new PrivilegedExceptionAction() { |
| public Object run() throws MalformedURLException { |
| return file.toURL(); |
| } |
| } |
| ); |
| is = openStream_doPriv(streamURL); |
| } catch (Throwable t) { |
| //Exception handling not needed |
| } |
| } |
| return is; |
| } |
| |
| private InputStream openStream_doPriv(final URL streamURL) throws IOException { |
| try { |
| return (InputStream) AccessController.doPrivileged( |
| new PrivilegedExceptionAction() { |
| public Object run() throws IOException { |
| return streamURL.openStream(); |
| } |
| } |
| ); |
| } catch (PrivilegedActionException e) { |
| throw (IOException) e.getException(); |
| } |
| } |
| |
| private String constructPath(URL baseURL, URI resolvedURI) { |
| String importLocation = null; |
| URL url = null; |
| try { |
| // Allow for http or https |
| if (baseURL.getProtocol() != null && |
| (baseURL.getProtocol().equals(HTTP_PROTOCOL) || |
| baseURL.getProtocol().equals(HTTPS_PROTOCOL) || |
| baseURL.getProtocol().equals(BUNDLE_RESOURCE_PROTOCOL))) { |
| if(log.isDebugEnabled()){ |
| log.debug("Constructing path with http/https protocol"); |
| } |
| url = new URL(baseURL.getProtocol(), baseURL.getHost(), baseURL.getPort(), |
| resolvedURI.toString()); |
| if (log.isDebugEnabled()) { |
| log.debug("URL = " + url); |
| } |
| |
| } |
| // Check for file |
| else if (baseURL.getProtocol() != null && baseURL.getProtocol().equals(FILE_PROTOCOL)) { |
| if(log.isDebugEnabled()){ |
| log.debug("Constructing path with file protocol"); |
| } |
| url = new URL(baseURL.getProtocol(), baseURL.getHost(), resolvedURI.toString()); |
| } |
| //Check for jar |
| else if (baseURL.getProtocol() != null && baseURL.getProtocol().equals(JAR_PROTOCOL)) { |
| if(log.isDebugEnabled()){ |
| log.debug("Constructing path with jar protocol"); |
| } |
| url = new URL(baseURL.getProtocol(), baseURL.getHost(), resolvedURI.toString()); |
| } |
| else{ |
| if(baseURL != null) { |
| |
| // try constructing it with unknown protocol |
| if(log.isDebugEnabled()){ |
| log.debug("Constructing path with unknown protocol: " + baseURL.getProtocol()); |
| } |
| url = new URL(baseURL.getProtocol(), baseURL.getHost(), resolvedURI.toString()); |
| } |
| else { |
| if(log.isDebugEnabled()) { |
| log.debug("baseURL is NULL"); |
| } |
| } |
| } |
| |
| } |
| catch (MalformedURLException e) { |
| throw ExceptionFactory.makeWebServiceException(Messages.getMessage("schemaImportError", |
| resolvedURI.toString(), |
| baseURL.toString()), |
| e); |
| } |
| if (url == null) { |
| throw ExceptionFactory.makeWebServiceException(Messages.getMessage("schemaImportError", |
| resolvedURI.toString(), |
| baseURL.toString())); |
| } |
| importLocation = url.toString(); |
| return importLocation; |
| } |
| |
| } |