/**
*
*/
package com.bagri.xquery.saxon;
import static com.bagri.core.Constants.bg_schema;
import java.io.Reader;
import java.io.StringReader;
import java.net.URI;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;
import com.bagri.core.api.SchemaRepository;
import com.bagri.core.api.BagriException;
import com.bagri.core.server.api.DocumentManagement;
import com.bagri.support.util.FileUtils;
import net.sf.saxon.Configuration;
import net.sf.saxon.lib.SourceResolver;
import net.sf.saxon.lib.UnparsedTextURIResolver;
import net.sf.saxon.trans.XPathException;
/**
* @author Denis Sukhoroslov
*
*/
public class SourceResolverImpl implements SourceResolver, URIResolver, UnparsedTextURIResolver {
private static final Logger logger = LoggerFactory.getLogger(SourceResolverImpl.class);
private SchemaRepository repo;
public SourceResolverImpl(SchemaRepository repo) {
this.repo = repo;
}
/**
* {@inheritDoc}
*/
@Override
public Source resolve(String href, String base) throws TransformerException {
logger.trace("resolve. href: {}; base: {}", href, base);
return resolveSource(new StreamSource(href), null);
}
/**
* {@inheritDoc}
*/
@Override
public Source resolveSource(Source source, Configuration config) throws XPathException {
logger.trace("resolveSource. source: {}; config: {}", source.getSystemId(), config);
String original = source.getSystemId();
URI uri = URI.create(original);
logger.trace("resolveSource. got {} URI: {}", uri.isAbsolute() ? "absolute" : "relative", uri);
String content = resolveContent(uri, config);
//Source src = mgr.getDocumentAsSource(docId);
//if (src != null) {
// logger.trace("resolveSource. got document from cache, returning: {}", src);
// //if (source instanceof TinyDocumentImpl) {
// ((TinyDocumentImpl) src).getTree().setConfiguration(config);
// return src;
//}
// move this processing to a node (member)
// the document belongs to
//logger.debug("resolveSource; looking for documentId: {}", docId);
//String content;
//try {
// another bottleneck! takes 6.73 ms, even to get XML from cache! !?
// content = repo.getDocumentManagement().getDocumentAsString(docId);
//content = content.replaceAll("&", "&");
//} catch (XDMException ex) {
// throw new XPathException(ex);
//}
if (content != null && content.trim().length() > 0) {
logger.trace("resolveSource; got content: {}", content.length());
StreamSource ss = new StreamSource(new StringReader(content));
ss.setSystemId(original);
//InputSource is = new InputSource(new StringReader(content));
//is.setSystemId(original);
//Source ss = new SAXSource(is);
//ss.setSystemId(original);
// bottleneck! takes 15 ms. Cache DocumentInfo in Saxon instead!
//NodeInfo doc = config.buildDocument(ss);
//mgr.storeDocumentSource(docId, doc);
//return doc;
//mgr.storeDocumentSource(docId, ss);
return ss;
}
logger.trace("resolveSource. got empty content: '{}'", content);
return null;
}
@Override
public Reader resolve(URI absoluteURI, String encoding, Configuration config) throws XPathException {
logger.trace("resolve; uri: {}; encoding: {}", absoluteURI, encoding);
String content = resolveContent(absoluteURI, config);
return new StringReader(content);
}
private String resolveContent(URI uri, Configuration config) throws XPathException {
String content;
try {
if (bg_schema.equals(uri.getScheme())) {
// skip leading "/"
long docKey = Long.parseLong(uri.getPath().substring(1));
content = ((DocumentManagement) repo.getDocumentManagement()).getDocumentAsString(docKey, null);
} else {
String src = uri.toString();
if ("file".equals(uri.getScheme())) {
// here we search by fileName
src = FileUtils.getPathName(src);
}
logger.debug("resolveContent; not a native schema {}, trying short uri: {}", uri.getScheme(), src);
content = repo.getDocumentManagement().getDocumentAsString(src, null);
}
if (content == null) {
throw new XPathException("cannot resolve document for URI: " + uri); //??
}
return content;
} catch (BagriException ex) {
throw new XPathException("cannot resolve document for URI: " + uri);
}
}
}