// UML Model Transformation Tool (UMT)
// Copyright (C) 2003, 2004, 2005 SINTEF
// Authors: jon.oldevik at sintef.no | roy.gronmo at sintef.no | tor.neple at sintef.no | fredrik.vraalsen at sintef.no
// Webpage: http://umt.sourceforge.net
// Deloped in the projects: ACEGIS (EU project - IST-2002-37724),
// CAFE (EUREKA/ITEA - ip00004), FAMILIES (ITEA project ip02009)
//
// 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.1
// 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 program; if not, write to the Free
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
// 02111-1307 USA
package org.sintef.umt.transformer;
/**
* @author Jon Oldevik, (jon.oldevik@sintef.no),
* @author Arnor Solberg (arnor.solberg@sintef.no)
* @copyright (c) SINTEF 2002 (www.sintef.no)
*
*/
import javax.xml.transform.*;
import javax.xml.parsers.*;
import org.sintef.umt.umtmain.MyErrorListener;
import org.sintef.umt.umtmain.MyURIResolver;
import org.sintef.umt.umtmain.OutputListener;
import org.sintef.umt.umtmain.OutputWindow;
import org.w3c.dom.*;
import org.xml.sax.*;
import org.apache.xerces.parsers.DOMParser;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.util.*;
public class XMLUtility
{
public static final int TYPE_DOM = 1;
public static final int TYPE_SAX = 2;
public static final int TYPE_STRING = 0;
private int _type = TYPE_DOM;
private static OutputListener _output;
private Vector _lookuppath;
private boolean _validating;
private String _context_name=null, _context_id = null;
public XMLUtility (OutputListener output)
{
_output = output;
_lookuppath = new Vector ();
_validating = true;
}
public XMLUtility () {
_output = new OutputWindow ();
_lookuppath = new Vector ();
}
public static void setXMLProperties () {
// System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
// System.setProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
// System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl");
}
public void setValidating (boolean is_validating){
_validating = is_validating;
}
public void addLookupPath (File lookup)
{
addLookupForFile (lookup);
/* File parentfile = lookup.getParentFile();
String parentpath = lookup.getAbsolutePath();
if(parentfile != null)
parentpath = parentfile.getAbsolutePath();
addLookupPath (parentpath);
*/
}
public void addLookupPath (String path)
{
if(!_lookuppath.contains(path))
_lookuppath.add(path);
}
public void setContext (String contextname, String contextid) {
_context_name = contextname;
_context_id = contextid;
}
public String transform (String source, String xslt)
{
StringReader sourcereader = new StringReader (source);
StringReader xsltreader = new StringReader (xslt);
StringWriter result = new StringWriter ();
transform (sourcereader, xsltreader, TYPE_STRING, new BufferedWriter(result));
sourcereader = null;
xsltreader = null;
return result.getBuffer().toString();
}
private void addLookupForFile (File f){
File parentfile;
parentfile = f.getParentFile();
String parentpath = f.getAbsolutePath();
if (parentfile != null){
parentpath = parentfile.getAbsolutePath ();
addLookupPath (parentpath);
File [] files = parentfile.listFiles();
for (int i = 0; i < files.length;i++){
File dir = files[i];
if (dir.exists() && dir.isDirectory()){
addLookupPath (dir.getAbsolutePath());
}
}
} else
addLookupPath (parentpath);
}
public String transform (File source, File xslt)
{
FileReader sourcereader = null;
FileReader xsltreader = null;
System.out.println ("XMLUtility::transform: " + source.getAbsolutePath() + " " + xslt.getAbsolutePath());
try {
sourcereader = new FileReader (source);
xsltreader = new FileReader (xslt);
// add lookup paths
File parentfile = xslt.getParentFile();
String parentpath = xslt.getAbsolutePath();
if(parentfile != null)
parentpath = parentfile.getAbsolutePath();
addLookupPath (parentpath);
addLookupForFile (source);
StringWriter result = new StringWriter ();
transform (sourcereader, xsltreader, TYPE_STRING, new BufferedWriter(result));
sourcereader = null; xsltreader = null;
return result.getBuffer().toString();
} catch (Exception ex) {
_output.addLine("An error occurred in transformation. " + ex.getMessage());
ex.printStackTrace();
} finally {
sourcereader = null; xsltreader = null;
}
return "";
}
public String transform (Reader sourcereader, Reader xsltreader)
{
StringWriter result = new StringWriter ();
try {
transform (sourcereader, xsltreader, TYPE_STRING, result);
} catch (Exception ex) {
}
return result.getBuffer().toString();
}
public void transform (Reader sourcereader, Reader xsltreader, Writer resultwriter)
{
try {
transform (sourcereader, xsltreader, TYPE_STRING, resultwriter);
} catch (Exception ex) {
}
}
public Node transformDom (Reader sourcereader, Reader xsltreader)
{
try{
return (Node) transform (sourcereader, xsltreader, TYPE_DOM, null);
} catch (ClassCastException ccex) {
// This should not happen, but ...
} catch (Exception ex) {
}
return null;
}
protected Object transform (Reader sourcereader, Reader xsltreader, int type, Writer resultwriter)
{
if (resultwriter == null)
resultwriter = new StringWriter ();
MyURIResolver resolver = null;
MyErrorListener errorhandler = null;
SAXParser saxparser = null;
org.xml.sax.XMLReader reader = null;
Object resultobject = null;
try{
resolver = new MyURIResolver ();
resolver.addLookup(_lookuppath);
errorhandler = new MyErrorListener (_output);
TransformerFactory tFactory = TransformerFactory.newInstance();
try {
// tFactory.setAttribute("http://xml.apache.org/xalan/features/incremental", java.lang.Boolean.TRUE);
} catch (Exception ex) {
System.out.println ("XMLUtility::transform - " + ex);
}
tFactory.setURIResolver (resolver);
tFactory.setErrorListener(errorhandler);
javax.xml.transform.sax.SAXTransformerFactory saxTFactory =
((javax.xml.transform.sax.SAXTransformerFactory) tFactory);
saxTFactory.setErrorListener(errorhandler);
javax.xml.transform.sax.TemplatesHandler templatesHandler = saxTFactory.newTemplatesHandler();
SAXParserFactory saxfactory = getParserFactory();
saxfactory.setNamespaceAware (true);
saxfactory.setValidating(false);
saxparser = saxfactory.newSAXParser();
reader = saxparser.getXMLReader();
reader.setEntityResolver(resolver);
reader.setContentHandler(templatesHandler);
reader.setErrorHandler(errorhandler);
reader.parse(new InputSource(xsltreader));
javax.xml.transform.Templates templates = templatesHandler.getTemplates();
javax.xml.transform.sax.TransformerHandler transformerHandler
= saxTFactory.newTransformerHandler(templates);
reader.setContentHandler(transformerHandler);
reader.setErrorHandler(errorhandler);
reader.setProperty("http://xml.org/sax/properties/lexical-handler", transformerHandler);
javax.xml.transform.Result result;
if (type == TYPE_DOM)
result = new DOMResult();
else // if type == TYPE_STRING
result = new javax.xml.transform.stream.StreamResult (resultwriter);
transformerHandler.setResult(result);
reader.setErrorHandler(errorhandler);
reader.setEntityResolver(resolver);
try {
reader.setFeature("http://xml.org/sax/features/validation", false);
// reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// SAXON -- // reader.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
// SAXON -- // reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
// reader.setFeature("http://xml.apache.org/xalan/features/optimize", true);
// reader.setFeature("http://xml.apache.org/xalan/features/incremental", true);
} catch (SAXNotRecognizedException snrec) {
System.out.println ("XMLUtility::transform: " + snrec);
}
System.out.println ("Starting transform.");
try {
reader.parse(new InputSource(sourcereader));
} catch (Exception ex) {
System.out.println ("XMLUtility::transform - " + ex);
}
if (type == TYPE_DOM)
resultobject = ((DOMResult)result).getNode();
// else
// resultobject = resultwriter.toString();
//
System.out.println ("Finishing transform.");
} catch (ParserConfigurationException pcex) {
_output.addLine("Parser config error: " + pcex.getMessage());
System.out.println (pcex);
} catch (TransformerConfigurationException tcex) {
_output.addLine("Transformation config error: " + tcex.getMessage());
System.out.println (tcex);
} catch (SAXException sex) {
_output.addLine("XMLUtility::transform::SAXException: " + sex.getMessage());
System.out.println (sex);
} catch (IOException io) {
_output.addLine(io.getMessage());
System.out.println ("XMLUtility::transform::IOException: " + io);
} catch (Exception ex) {
// _output.addLine(ex.getMessage());
System.out.println ("XMLUtility::transform::Exception: " + ex);
} finally {
try {
sourcereader.close();
xsltreader.close();
} catch (IOException ioex) {System.out.println ("XMLUtility::transform::" + ioex);}
resolver = null;
errorhandler = null;
saxparser = null;
reader = null;
sourcereader = null;
xsltreader = null;
// resultwriter = null;
}
return resultobject;
}
public void doParseValidate (Reader source)
{
DocumentBuilder parser = null;
MyURIResolver resolver = null;
try{
// javax.xml.parsers.DocumentBuilderFactory
_output.addLine("Validating (DOM)");
DocumentBuilderFactory factory = getDocumentBuilder ();
factory.setValidating (_validating);
factory.setNamespaceAware (true);
// factory.setIgnoringComments (true);
// factory.setCoalescing(true);
// factory.setExpandEntityReferences(true);
parser = factory.newDocumentBuilder ();
resolver = new MyURIResolver ();
resolver.addLookup(_lookuppath);
parser.setEntityResolver(resolver);
parser.setErrorHandler (new MyErrorListener (_output));
// parser.setFeature("http://xml.org/sax/features/validation", true);
parser.parse (new org.xml.sax.InputSource (source));
_output.addLine("Finished validating.");
} catch (Exception ex){
// _output.addLine ("XMLUtility::doParseValidate - " + ex.getMessage ());
// System.out.println ("doParseValidate:" + ex);
} finally {
parser = null;
resolver = null;
}
}
public void doSAXParseValidate (Reader source){
SAXParser parser = null;
XMLReader reader = null;
MyURIResolver resolver = null;
try{
_output.addLine("Validating (SAX)");
SAXParserFactory factory = null;
try {
factory = getParserFactory ();
} catch (Exception ex) {
_output.addLine("Error instantiating - " + ex.getMessage());
}
factory.setValidating (_validating);
factory.setNamespaceAware (true);
parser = factory.newSAXParser ();
reader = parser.getXMLReader();
try {
reader.setFeature("http://xml.org/sax/features/validation", true);
reader.setFeature("http://apache.org/xml/features/validation/dynamic", true);
reader.setFeature("http://apache.org/xml/features/validation/schema", true);
reader.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
// reader.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true);
} catch (SAXNotRecognizedException snrec) {
System.out.println ("XMLUtility::doSAXParseValidate: " + snrec);
}
resolver = new MyURIResolver ();
resolver.addLookup(_lookuppath);
reader.setEntityResolver(resolver);
reader.setErrorHandler(new MyErrorListener(_output));
_output.addLine("Parsing input.");
reader.parse (new org.xml.sax.InputSource(source));
_output.addLine("Finished validating.");
} catch (SAXException saex) {
_output.addLine(saex.getLocalizedMessage());
} catch (Exception ex){
System.out.println ("doSAXParseValidate: " + ex);
_output.addLine ("XMLUtility::doSAXParseValidate - " + ex.getMessage ());
} finally {
parser = null;
reader = null;
resolver = null;
}
}
/**
* Returns a boolean value that signifies if last node was complex (a node) or simple (text)
* the value 'true' signifies a node
*/
public static boolean writeNode (Node n, Writer w, int indent) {
boolean is_node = false;
try {
short type = n.getNodeType();
String name = n.getNodeName();
String val = n.getNodeValue();
NodeList children = null;
NamedNodeMap attributes = null;
Node tmp = null;
// System.out.println ("writeNode: " + n.getNodeName() + " type: "+ n.getNodeType());
switch (type) {
case Node.TEXT_NODE: w.write(val); break;
case Node.COMMENT_NODE: w.write ("\n<!--"+val+"-->");break;
case Node.ELEMENT_NODE:
is_node = true;
w.write("\n" + doIndent(indent) + "<" + name);
attributes = n.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
tmp = attributes.item(i);
w.write(" " + tmp.getNodeName() + "="); w.write("'" + tmp.getNodeValue()+ "'");
}
children = n.getChildNodes();
boolean has_children = children.getLength() > 0?true:false;
if (!has_children) {
w.write("/");
}
w.write(">");
boolean child_is_node = false;
for (int i = 0; i < children.getLength();i++) {
tmp = children.item(i);
child_is_node = writeNode (tmp, w, indent + 2);
if (child_is_node && i == children.getLength() - 1)
w.write("\n" + doIndent (indent));
}
if (has_children)
w.write("</" + name + ">");
break;
case Node.DOCUMENT_NODE:
case Node.DOCUMENT_FRAGMENT_NODE:
children = n.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
tmp = children.item(i);
writeNode (tmp, w, indent);
}
default: break;
}
} catch (Exception ex) {
}
return is_node;
}
public static String nodeToString (Node n) {
java.io.StringWriter sw = new java.io.StringWriter ();
writeNode (n, sw, 0);
return sw.toString ();
}
public Collection readXML (Reader reader){
DocumentBuilder parser = null;
MyURIResolver resolver = null;
Collection collection = new java.util.ArrayList ();
try{
DocumentBuilderFactory factory = getDocumentBuilder ();
factory.setNamespaceAware (true);
factory.setIgnoringComments(false);
factory.setCoalescing(true);
factory.setValidating (false);
parser = factory.newDocumentBuilder ();
resolver = new MyURIResolver ();
resolver.addLookup(_lookuppath);
parser.setEntityResolver(resolver);
parser.setErrorHandler (new MyErrorListener (_output));
Document doc = parser.parse (new InputSource(reader));
Element root = doc.getDocumentElement ();
collection.add(root);
/* NodeList children = root.getChildNodes ();
for (int i = 0; i < children.getLength(); i++){
Node child = children.item(i);
if (child.getNodeType () == Node.ELEMENT_NODE)
collection.add (child);
}
*/
} catch (Exception ex){
/* System.out.println ("XMLUtility::readXML() --> " + ex); */
/* Not necessarily an error - this will occur if non-xml is given as input */
} finally {
parser = null;
resolver = null;
}
return collection;
}
/**
* readDOM - a platform specific implementation of XML reader
* @param reader
* @return
*/
public Collection readDOM (Reader reader) {
Collection collection = new java.util.ArrayList ();
DOMParser parser = new DOMParser ();
try {
parser.setErrorHandler(new MyErrorListener (_output));
parser.parse (new InputSource(reader));
Document doc = parser.getDocument();
collection.add(doc.getDocumentElement());
} catch (Exception ex) {
System.out.println ("XMLUtility::readDOM - " + ex);
}
return collection;
}
/**
*
* readXMLString -- parses the XML as String input.
* @param xmlstring
* @return
*/
public Collection readXMLString (String xmlstring){
DocumentBuilder parser = null;
MyURIResolver resolver = null;
Collection collection = new java.util.ArrayList ();
try{
DocumentBuilderFactory factory = getDocumentBuilder ();
factory.setNamespaceAware (true);
factory.setIgnoringComments(false);
factory.setCoalescing(true);
factory.setValidating (false);
parser = factory.newDocumentBuilder ();
resolver = new MyURIResolver ();
resolver.addLookup(_lookuppath);
parser.setEntityResolver(resolver);
parser.setErrorHandler (new MyErrorListener (_output));
Document doc = parser.parse (xmlstring);
Element root = doc.getDocumentElement ();
collection.add(root);
} catch (Exception ex){
System.out.println ("XMLUtility::readXMLString() --> " + ex);
/* Not necessarily an error - this will occur if non-xml is given as input */
} finally {
parser = null;
resolver = null;
}
return collection;
}
// TBD: These properties should be fetched from a propery file
public static DocumentBuilderFactory getDocumentBuilder () {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance ();
return factory;
}
public static SAXParserFactory getParserFactory () {
SAXParserFactory factory = SAXParserFactory.newInstance ();
return factory;
}
private static String doIndent (int indent) {
String str = "";
for (int i = 0; i < indent;i++) {
str = str + " ";
}
return str;
}
/**
* Util function that maps an "unstructured" source xml to indented / lined XML.
* {{really a copy of the XMLEditor::readXML function}}
*/
public void writeXML (Writer target, Reader source) {
if (source == null || target == null)
return;
try{
BufferedReader reader = new BufferedReader (source);
int indent = 0;
String line = reader.readLine().trim();
while (line != null){
line = line.trim() + "\n";
if (line.startsWith("</")){
target.write (doIndent(--indent) + line);
}
else if (line.startsWith("<?")) {
target.write (doIndent(indent) + line);
}
else if (line.startsWith("<")){
target.write (doIndent(indent));
int tagend = line.indexOf(' ');
String tagname, rest;
if (tagend > 0) {
tagname = line.substring(0, tagend);
rest = line.substring(tagend, line.length());
} else {
tagname = line;
rest = "";
}
target.write(tagname + rest);
int isended = line.indexOf("/>");
if (isended < 0)
indent++;
}
else if (line.startsWith("<!--")) {
target.write (doIndent(indent) + line);
}
else {
target.write(doIndent(indent) + line);
}
line = reader.readLine();
}
} catch (Exception ex){
System.out.println ("XMLEditor::writeXML ()-" + ex.getMessage());
// ex.printStackTrace();
}
}
public static void streamToXML (Element rootElement, Writer writer) {
try {
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer transformer = tfactory.newTransformer();
transformer.transform(new javax.xml.transform.dom.DOMSource(rootElement), new StreamResult(writer));
writer.close();
writer = null;
} catch (Exception ex) {
System.out.println ("XMLUtility::streamToXML-->" + ex);
}
}
}