package cz.cuni.mff.d3s.been.xml.resolve;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver;
/**
* This is the EverBEEN implementation of the catalog resolver, used for cross-jar <em>XSD</em> loading.
*/
public class BEENClassPathCatalogResolver extends CatalogResolver {
private static final String BEEN_URI_BASE = "http://been.d3s.mff.cuni.cz/";
private static final Logger log = LoggerFactory.getLogger(BEENClassPathCatalogResolver.class);
/**
* User entity resolvers used to fetch extra XSDs from the classpath.
*/
private final List<EntityResolver> resolvers;
/**
* Create an EverBEEN catalog resolver
*/
public BEENClassPathCatalogResolver() {
resolvers = new ArrayList<EntityResolver>();
Iterator<XSDClassPathResolver> sl = ServiceLoader.load(XSDClassPathResolver.class).iterator();
while (sl.hasNext()) {
resolvers.add(sl.next());
}
log.info("Loaded user entity resolvers {}", resolvers.toString());
}
@Override
public InputSource resolveEntity(String publicId, String systemId) {
log.debug("resolveEntity() called with params publicId={}, systemId={}", publicId, systemId);
InputSource source = attemptResolutionWithUserResolvers(publicId, systemId);
return (source != null) ? source : super.resolveEntity(publicId, systemId);
}
@Override
public Source resolve(String href, String base) throws TransformerException {
log.debug("source resolution: href={}, base={}", href, base);
if (base == null) {
log.debug("Patching URI base from <null> to <{}>", BEEN_URI_BASE);
return super.resolve(href, BEEN_URI_BASE);
} else {
log.debug("URI base for href <{}> was <{}>, which looked OK", BEEN_URI_BASE);
return super.resolve(href, base);
}
}
private InputSource attemptResolutionWithUserResolvers(String publicId,
String systemId) {
log.debug("resolveEntity() default implementation found nothing, trying user entity resolvers");
for (EntityResolver resolver : resolvers) {
final InputSource source = iosafeResolveEntity(resolver, publicId, systemId);
if (source != null) {
log.debug("user resolvers found {} for publicId={}", source, publicId);
return source;
}
}
log.debug("user resolvers found nothing either");
return null;
}
private InputSource iosafeResolveEntity(EntityResolver resolver,
String publicId, String systemId) {
try {
return resolver.resolveEntity(publicId, systemId);
} catch (IOException | SAXException e) {
return null;
}
}
}