package org.archstudio.schematron.core;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.lang.reflect.Method;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class SchematronUtils {
public static String SCHEMATRON_METASTYLESHEET_URL = "platform:/plugin/org.archstudio.schematron.core/res/schematron-xml1-6.xsl";
public static String SCHEMATRON_SKELETON_URL = "platform:/plugin/org.archstudio.schematron.core/res/skeleton1-6.xsl";
private static DOMSource schematronMetastylesheet = null;
private static DOMSource schematronSkeleton = null;
public static String getXalanVersion() {
try {
Class.forName("org.apache.xalan.xslt.EnvironmentCheck");
}
catch (ClassNotFoundException cnfe) {
return null;
}
Class<?> versionClass = null;
try {
versionClass = Class.forName("org.apache.xalan.Version");
}
catch (ClassNotFoundException cnfe2) {
try {
versionClass = Class.forName("org.apache.xalan.processor.Version");
}
catch (ClassNotFoundException cnfe3) {
}
}
if (versionClass == null) {
return "UnknownButPresent";
}
else {
try {
Method m = versionClass.getMethod("getVersion", new Class[0]);
String version = (String) m.invoke(null, new Object[0]);
return version;
}
catch (Exception e) {
return "UnknownButPresent";
}
}
}
private static InputStream openURI(String uriString) throws IOException {
URI uri = URI.createURI(uriString);
InputStream is = URIConverter.INSTANCE.createInputStream(uri);
return is;
}
public static DOMSource getSchematronMetastylesheet() throws SchematronInitializationException {
if (schematronMetastylesheet != null) {
return schematronMetastylesheet;
}
try {
InputStream is = openURI(SCHEMATRON_METASTYLESHEET_URL);
InputStreamReader isr = new InputStreamReader(is);
Document doc = parseToDocument(isr);
isr.close();
schematronMetastylesheet = new DOMSource(doc, "schematron-xml1-6.xsl");
return schematronMetastylesheet;
}
catch (Exception e) {
throw new SchematronInitializationException(e);
}
}
public static DOMSource getSchematronSkeleton() throws SchematronInitializationException {
if (schematronSkeleton != null) {
return schematronSkeleton;
}
try {
InputStream is = openURI(SCHEMATRON_SKELETON_URL);
InputStreamReader isr = new InputStreamReader(is);
Document doc = parseToDocument(isr);
isr.close();
schematronSkeleton = new DOMSource(doc, "skeleton1-6.xsl");
return schematronSkeleton;
}
catch (Exception e) {
throw new SchematronInitializationException(e);
}
}
public static DOMResult getEmptyDOMResult() throws SchematronInitializationException {
return new DOMResult();
}
public static Document parseToDocument(java.io.Reader r) throws SAXException, IOException,
ParserConfigurationException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
dbf.setIgnoringElementContentWhitespace(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(r));
return doc;
}
/**
* Gets the DOMImplementation for the preferred parser.
*
* @return DOMImplementation object for the preferred parser.
*/
public static DOMImplementation getDOMImplementation() throws ParserConfigurationException {
//return DOMImplementationImpl.getDOMImplementation();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
dbf.setIgnoringElementContentWhitespace(true);
try {
DocumentBuilder db = dbf.newDocumentBuilder();
return db.getDOMImplementation();
}
catch (ParserConfigurationException pce) {
pce.printStackTrace();
return null;
}
}
public static TransformerFactory getTransformerFactory() throws SchematronInitializationException {
try {
return TransformerFactory.newInstance();
}
catch (Exception e) {
throw new SchematronInitializationException(e);
}
}
public static Transformer getTransformer() throws SchematronInitializationException {
try {
TransformerFactory factory = getTransformerFactory();
return factory.newTransformer();
}
catch (Exception e) {
throw new SchematronInitializationException(e);
}
}
public static Transformer getTransformer(Source src) throws SchematronInitializationException {
try {
TransformerFactory factory = getTransformerFactory();
factory.setURIResolver(new SchematronURIResolver(factory.getURIResolver(), getSchematronSkeleton()));
return factory.newTransformer(src);
}
catch (Exception e) {
throw new SchematronInitializationException(e);
}
}
public static String serialize(Document doc) {
try {
StringWriter sw = new StringWriter();
Source domSource = new javax.xml.transform.dom.DOMSource(doc);
Result streamResult = new javax.xml.transform.stream.StreamResult(sw);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
t.transform(domSource, streamResult);
return sw.toString();
}
catch (Exception e) {
System.err.println("This shouldn't happen.");
e.printStackTrace();
return null;
}
}
static class SchematronURIResolver implements URIResolver {
protected URIResolver baseResolver;
protected DOMSource schematronSkeleton;
public SchematronURIResolver(URIResolver baseResolver, DOMSource schematronSkeleton) {
this.schematronSkeleton = schematronSkeleton;
this.baseResolver = baseResolver;
}
@Override
public Source resolve(String href, String base) throws TransformerException {
if (href.equals("skeleton1-6.xsl")) {
return schematronSkeleton;
}
return baseResolver.resolve(href, base);
}
}
}