// OO jDREW - An Object Oriented extension of the Java Deductive Reasoning Engine for the Web // Copyright (C) 2011 // // This library 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.1 of the License, or (at your option) any later version. // // This library 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 Street, Fifth Floor, Boston, MA 02110-1301 USA package org.ruleml.oojdrew.xml; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import nu.xom.ParsingException; import org.ruleml.oojdrew.parsing.RuleMLFormat; public class RuleMLNormalizer { /** * Supported XSL versions (1.x and 2.0) */ public enum XSLVersion { XSL1X, XSL20 } // System property string which specifies the XML transformer factory to use private final String TransformerFactoryProperty = "javax.xml.transform.TransformerFactory"; // SAXON XML transformer (http://saxon.sourceforge.net/) private final String SaxonTransformer = "net.sf.saxon.TransformerFactoryImpl"; // XALAN (default) XML transformer private final String XalanTransformer = "org.apache.xalan.processor.TransformerFactoryImpl"; /** * Initializes a RuleML normalizer which uses XSL either in version 1.x or * in version 2.0 * * @param xslVersion * The XSL version to use (XSL 1.x or XSL 2.0) */ public RuleMLNormalizer(XSLVersion xslVersion) { if (xslVersion == XSLVersion.XSL20) { System.setProperty(TransformerFactoryProperty, SaxonTransformer); } else { // Use XALAN (default) for XML transforming System.setProperty(TransformerFactoryProperty, XalanTransformer); } } /** * Initializes a RuleML normalizer which uses XSL in version 1.x */ public RuleMLNormalizer() { this(XSLVersion.XSL1X); } /** * Normalizes a given RuleML string with the given format. * * @param input * The input which should be normalized * * @param rmlFormat * The RuleML format (e.g. RuleML 1.0) * * @return The normalized RuleML string * * @throws TransformerFactoryConfigurationError * @throws TransformerException * @throws IOException * @throws ParsingException * @throws UnsupportedEncodingException */ public String normalize(String input, RuleMLFormat rmlFormat) throws TransformerFactoryConfigurationError, TransformerException, ParsingException, UnsupportedEncodingException { String normalizerXSLT = getXSLTNormalizer(rmlFormat); InputStream xsltStream = RuleMLNormalizer.class.getResourceAsStream(normalizerXSLT); StreamSource xsltStreamSource = new StreamSource(xsltStream); ByteArrayInputStream xmlStream = new ByteArrayInputStream(input.getBytes()); StreamSource xmlSource = new StreamSource(xmlStream); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); StreamResult outputTarget = new StreamResult(outputStream); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer xmlTransformer = transformerFactory.newTransformer(xsltStreamSource); xmlTransformer.transform(xmlSource, outputTarget); String result = outputTarget.getOutputStream().toString(); // Format normalized document try { result = XmlUtils.formatDocument(result); } catch (Exception e) { e.printStackTrace(); } return result; } /** * Get the XSLT for the given RuleML format. By now, RuleML 1.0 and * RuleML 0.91 are supported. * * @param rmlFormat * The RuleML format (e.g. RuleML 1.0) * * @return The XSLT corresponding to the RuleML format * * @throws UnsupportedEncodingException * If the RuleML format is not supported */ private String getXSLTNormalizer(RuleMLFormat rmlFormat) throws UnsupportedEncodingException { switch (rmlFormat) { case RuleML100: return "100_normalizer.quarantine.xslt"; case RuleML91: return "091_normalizer.xslt"; default: String msg = String.format("RuleML format is not supported (%s).", rmlFormat.getVersionName()); throw new UnsupportedEncodingException(msg); } } }