Resolver.java
/**
* **********************************************************************
*
* <p>DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* <p>Copyright 2008, 2010 Oracle and/or its affiliates. All rights reserved.
*
* <p>Use is subject to license terms.
*
* <p>Licensed 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. You can also obtain a copy of the License at
* http://odftoolkit.org/docs/license.txt
*
* <p>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.
*
* <p>See the License for the specific language governing permissions and limitations under the
* License.
*
* <p>**********************************************************************
*/
package org.odftoolkit.odfdom.pkg;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/** resolve external entities */
class Resolver implements EntityResolver, URIResolver {
private final OdfPackage mPackage;
/** Resolver constructor. */
public Resolver(OdfPackage pkg) {
super();
mPackage = pkg;
}
/**
* Allow the application to resolve external entities.
*
* <p>The Parser will call this method before opening any external entity except the top-level
* document entity (including the external DTD subset, external entities referenced within the
* DTD, and external entities referenced within the document element): the application may request
* that the parser resolve the entity itself, that it use an alternative URI, or that it use an
* entirely different input source.
*/
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
// this deactivates the attempt to load the none existent Math DTD once referenced from OOo
// files
if (publicId != null && publicId.startsWith("-//OpenOffice.org//DTD Modified W3C MathML")) {
return new InputSource(
new ByteArrayInputStream("<?xml version='1.0' encoding='UTF-8'?>".getBytes()));
}
if (systemId != null) {
// if the entity to be resolved is the base URI return the package
if ((mPackage.getBaseURI() != null) && systemId.startsWith(mPackage.getBaseURI())) {
if (systemId.equals(mPackage.getBaseURI())) {
InputStream in = null;
try {
in = mPackage.getInputStream();
} catch (Exception e) {
throw new SAXException(e);
}
InputSource ins;
ins = new InputSource(in);
if (ins == null) {
return null;
}
ins.setSystemId(systemId);
return ins;
} else {
// if the reference points into the package (is larger than the base URI)
if (systemId.length() > mPackage.getBaseURI().length() + 1) {
InputStream in = null;
try {
String path = systemId.substring(mPackage.getBaseURI().length() + 1);
in = mPackage.getInputStream(path);
InputSource ins = new InputSource(in);
ins.setSystemId(systemId);
return ins;
} catch (Exception ex) {
Logger.getLogger(Resolver.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
in.close();
} catch (IOException ex) {
Logger.getLogger(Resolver.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
return null;
}
} else if (systemId.startsWith("resource:/")) {
int i = systemId.indexOf('/');
if ((i > 0) && systemId.length() > i + 1) {
String res = systemId.substring(i + 1);
ClassLoader cl = OdfPackage.class.getClassLoader();
InputStream in = cl.getResourceAsStream(res);
if (in != null) {
InputSource ins = new InputSource(in);
ins.setSystemId(systemId);
return ins;
}
}
return null;
} else if (systemId.startsWith("jar:")) {
try {
URL url = new URL(systemId);
JarURLConnection jarConn = (JarURLConnection) url.openConnection();
InputSource ins = new InputSource(jarConn.getInputStream());
ins.setSystemId(systemId);
return ins;
} catch (MalformedURLException ex) {
Logger.getLogger(OdfPackage.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
return null;
}
public Source resolve(String href, String base) throws TransformerException {
try {
URI uri = null;
if (base != null) {
URI baseuri = new URI(base);
uri = baseuri.resolve(href);
} else {
uri = new URI(href);
}
InputSource ins = null;
try {
ins = resolveEntity(null, uri.toString());
} catch (Exception e) {
throw new TransformerException(e);
}
if (ins == null) {
return null;
}
InputStream in = ins.getByteStream();
StreamSource src = new StreamSource(in);
src.setSystemId(uri.toString());
return src;
} catch (URISyntaxException use) {
return null;
}
}
}