/*
* eXist Open Source Native XML Database
* Copyright (C) 2001-2010 The eXist Project
* http://exist-db.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* $Id$
*/
package org.exist.validation.resolver;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import org.apache.log4j.Logger;
import org.apache.xerces.util.XMLCatalogResolver;
import org.apache.xerces.xni.XMLResourceIdentifier;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.parser.XMLInputSource;
import org.w3c.dom.ls.LSInput;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Wrapper around xerces2's
* <a href="http://xerces.apache.org/xerces2-j/javadocs/xerces2/org/apache/xerces/util/XMLCatalogResolver.html"
* >XMLCatalogresolver</a>
* @author Dannes Wessels (dizzzz@exist-db.org)
*/
public class eXistXMLCatalogResolver extends XMLCatalogResolver {
public eXistXMLCatalogResolver(){
super();
LOG.debug("Initializing");
}
public eXistXMLCatalogResolver(java.lang.String[] catalogs){
super(catalogs);
LOG.debug("Initializing using catalogs");
}
eXistXMLCatalogResolver(java.lang.String[] catalogs, boolean preferPublic){
super(catalogs, preferPublic);
LOG.debug("Initializing using catalogs, preferPublic="+preferPublic);
}
private final static Logger LOG = Logger.getLogger(eXistXMLCatalogResolver.class);
/**
* Constructs a catalog resolver with the given list of entry files.
*
* @param catalogs List of Strings
*
* TODO: check for non-String and NULL values.
*/
public void setCatalogs(List<String> catalogs){
if(catalogs!=null && catalogs.size()>0){
final String[] allCatalogs = new String[catalogs.size()];
int counter=0;
for (String element : catalogs) {
allCatalogs[counter]=element;
counter++;
}
super.setCatalogList(allCatalogs);
}
}
/**
* @see org.apache.xerces.util.XMLCatalogResolver#resolveEntity(String, String)
*/
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
LOG.debug("Resolving publicId='"+publicId+"', systemId='"+systemId+"'");
InputSource retValue = super.resolveEntity(publicId, systemId);
if(retValue == null)
{
retValue = resolveEntityFallback(publicId, systemId);
}
LOG.debug("Resolved " + (retValue!=null));
if(retValue!=null){
LOG.debug("PublicId='" + retValue.getPublicId() + "' SystemId=" + retValue.getSystemId());
}
return retValue;
}
/** moved from Collection.resolveEntity() revision 6144 */
private InputSource resolveEntityFallback(String publicId, String systemId) throws SAXException, IOException
{
//if resolution failed and publicId == null,
// try to make absolute file names relative and retry
LOG.debug("Resolve failed, fallback scenario");
if(publicId != null)
{
return null;
}
final URL url = new URL(systemId);
if("file".equals(url.getProtocol()))
{
final String path = url.getPath();
final File f = new File(path);
if(!f.canRead())
{
return resolveEntity(null, f.getName());
}
else
{
return new InputSource(f.getAbsolutePath());
}
}
else
{
return new InputSource(url.openStream());
}
}
/**
* @see org.apache.xerces.util.XMLCatalogResolver#resolveResource(String, String, String, String, String)
*/
public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
LOG.debug("Resolving type='"+type+"', namespaceURI='"+namespaceURI+"', publicId='"+publicId+"', systemId='"+systemId+"', baseURI='"+baseURI+"'");
final LSInput retValue= super.resolveResource(type, namespaceURI, publicId, systemId, baseURI);
LOG.debug("Resolved " + (retValue!=null));
if(retValue!=null){
LOG.debug("PublicId='" + retValue.getPublicId() + "' SystemId='"
+ retValue.getSystemId() + "' BaseURI='" + retValue.getBaseURI() +"'");
}
return retValue;
}
/**
* @see org.apache.xerces.util.XMLCatalogResolver#resolveEntity(String, String, String, String)
*/
public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId) throws SAXException, IOException {
LOG.debug("Resolving name='"+name+"', publicId='"+publicId+"', baseURI='"+baseURI+"', systemId='"+systemId+"'");
final InputSource retValue = super.resolveEntity(name, publicId, baseURI, systemId);
LOG.debug("Resolved " + (retValue!=null));
if(retValue!=null){
LOG.debug("PublicId='" + retValue.getPublicId() + "' SystemId='"
+ retValue.getSystemId() +"'");
}
return retValue;
}
/**
* @see org.apache.xerces.util.XMLCatalogResolver#resolveIdentifier(XMLResourceIdentifier)
*/
public String resolveIdentifier(XMLResourceIdentifier xri) throws IOException, XNIException {
if(xri.getExpandedSystemId()==null && xri.getLiteralSystemId()==null &&
xri.getNamespace()==null && xri.getPublicId()==null){
// quick fail
return null;
}
if(LOG.isDebugEnabled()) {
LOG.debug("Resolving XMLResourceIdentifier: "+getXriDetails(xri));
}
final String retValue = super.resolveIdentifier(xri);
LOG.debug("Resolved " + (retValue!=null));
if(retValue!=null){
LOG.debug("Identifier='" + retValue +"'");
}
return retValue;
}
/**
* @see org.apache.xerces.util.XMLCatalogResolver#resolveEntity(XMLResourceIdentifier)
*/
public XMLInputSource resolveEntity(XMLResourceIdentifier xri) throws XNIException, IOException {
if(xri.getExpandedSystemId()==null && xri.getLiteralSystemId()==null &&
xri.getNamespace()==null && xri.getPublicId()==null){
// quick fail
return null;
}
if(LOG.isDebugEnabled()) {
LOG.debug("Resolving XMLResourceIdentifier: " + getXriDetails(xri));
}
final XMLInputSource retValue = super.resolveEntity(xri);
LOG.debug("Resolved " + (retValue!=null));
if(retValue!=null){
LOG.debug("PublicId='" + retValue.getPublicId() + "' SystemId='"
+ retValue.getSystemId() +"' BaseSystemId=" + retValue.getBaseSystemId());
}
return retValue;
}
/**
* @see org.apache.xerces.util.XMLCatalogResolver#getExternalSubset(String, String)
*/
public InputSource getExternalSubset(String name, String baseURI) throws SAXException, IOException {
LOG.debug("name='"+name+"' baseURI='"+baseURI+"'");
return super.getExternalSubset(name, baseURI);
}
private String getXriDetails(XMLResourceIdentifier xrid){
final StringBuilder sb = new StringBuilder();
sb.append("PublicId='").append(xrid.getPublicId()).append("' ");
sb.append("BaseSystemId='").append(xrid.getBaseSystemId()).append("' ");
sb.append("ExpandedSystemId='").append(xrid.getExpandedSystemId()).append("' ");
sb.append("LiteralSystemId='").append(xrid.getLiteralSystemId()).append("' ");
sb.append("Namespace='").append(xrid.getNamespace()).append("' ");
return sb.toString();
}
}