/*
* Copyright (c) 2012 Data Harmonisation Panel
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution. If not, see <http://www.gnu.org/licenses/>.
*
* Contributors:
* HUMBOLDT EU Integrated Project #030962
* Data Harmonisation Panel <http://www.dhpanel.eu>
*/
package eu.esdihumboldt.hale.io.xsd.reader.internal;
import java.io.File;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.ws.commons.schema.resolver.CollectionURIResolver;
import org.apache.ws.commons.schema.resolver.URIResolver;
import org.xml.sax.InputSource;
import eu.esdihumboldt.hale.common.cache.Request;
import eu.esdihumboldt.util.io.InputSupplier;
import eu.esdihumboldt.util.resource.Resources;
/**
* This resolver provides the means of resolving the imports and includes of a
* given schema document. The system will call this default resolver if there is
* no other resolver present in the system.
*
* @author Bernd Schneiders
* @author Simon Templer
*/
public class HumboldtURIResolver implements CollectionURIResolver {
private String collectionBaseURI;
/**
* @see URIResolver#resolveEntity(String, String, String)
*/
@Override
public InputSource resolveEntity(String namespace, String schemaLocation, String baseUri) {
final URI uriLoc;
final String stringLoc;
if (baseUri != null) {
try {
if (baseUri.startsWith("jar:file:")) {
// scheme definition w/ colon seems to break resolving
// -> resolve against file URI and add Jar part later
baseUri = baseUri.substring(4);
uriLoc = new URI(baseUri).resolve(new URI(schemaLocation));
stringLoc = "jar:" + uriLoc.toString();
}
else {
// XXX don't really understand what this File/URI juggling
// is supposed to to
if (baseUri.startsWith("file:/")) { //$NON-NLS-1$
baseUri = new URI(baseUri).getPath();
}
File baseFile = new File(baseUri);
if (baseFile.exists()) {
baseUri = baseFile.toURI().toString();
}
else if (collectionBaseURI != null) {
baseFile = new File(collectionBaseURI);
if (baseFile.exists()) {
baseUri = baseFile.toURI().toString();
}
}
uriLoc = new URI(baseUri).resolve(new URI(schemaLocation));
stringLoc = uriLoc.toString();
}
} catch (URISyntaxException e1) {
throw new RuntimeException(e1);
}
}
else {
stringLoc = schemaLocation;
URI uri;
try {
uri = new URI(schemaLocation);
} catch (URISyntaxException e) {
uri = null;
}
uriLoc = uri;
}
// create a lazy input source because we cannot be sure that the
// stream is actually consumed (and if not consumed we get a
// problem because the connection is not released)
InputSource is = new InputSource(stringLoc) {
private boolean initializedStream = false;
@Override
public InputStream getByteStream() {
if (!initializedStream) {
initializedStream = true;
InputStream in = null;
// try resolving using (local) Resources
if (uriLoc != null) {
InputSupplier<? extends InputStream> input = Resources.tryResolve(uriLoc,
Resources.RESOURCE_TYPE_XML_SCHEMA);
if (input != null) {
try {
in = input.getInput();
} catch (Exception e) {
// ignore
}
}
}
// try resolving through cache
if (in == null) {
try {
in = Request.getInstance().get(getSystemId());
} catch (Exception e) {
// ignore
}
}
// fall-back
if (in == null && uriLoc != null) {
try {
in = uriLoc.toURL().openStream();
} catch (Exception e) {
// ignore
}
}
setByteStream(in);
}
return super.getByteStream();
}
};
return is;
}
/**
* @see CollectionURIResolver#getCollectionBaseURI()
*/
@Override
public String getCollectionBaseURI() {
return collectionBaseURI;
}
/**
* @see CollectionURIResolver#setCollectionBaseURI(String)
*/
@Override
public void setCollectionBaseURI(String collectionBaseURI) {
this.collectionBaseURI = collectionBaseURI;
}
}