blob: fe67d5b723fe7f646ae4548b39e69f1f3549db07 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Doug Satchwell (Chase Technology Ltd) - initial API and implementation
* David Carver (Intalio) - bug 213776 - URI Resolver
*******************************************************************************/
package org.eclipse.wst.xsl.jaxp.debug.invoker;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.URIResolver;
import org.eclipse.wst.xsl.jaxp.debug.invoker.internal.ConfigurationException;
import org.eclipse.wst.xsl.jaxp.debug.invoker.internal.CreationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* The definition of the transformation pipeline.
* <p>
* This class is loaded on both the Eclipse classpath and the transformation
* process's classpath. The whole definition is serialized to an XML document by
* the Eclipse launcher, and is then read by the transformation process when
* launched.
* </p>
*
* @author Doug Satchwell
*/
public class PipelineDefinition {
private String sourceURL;
private String targetFile;
private final List<TransformDefinition> transformDefs = new ArrayList<TransformDefinition>();
private final Set<TypedValue> attributes = new HashSet<TypedValue>();
private boolean useEmbedded;
/**
* Create a new empty instance of this.
*/
public PipelineDefinition() {
}
/**
* Create a new instance of this by reading the specified XML file.
*
* @param launchFile
* the XSL file to load
* @throws SAXException
* if problems occur during parsing
* @throws IOException
* if problems occur during parsing
* @throws ParserConfigurationException
* if problems occur during parsing
*/
public PipelineDefinition(File launchFile) throws SAXException,
IOException, ParserConfigurationException {
this(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
new BufferedInputStream(new FileInputStream(launchFile))));
}
/**
* Create a new instance of this from the specified document
*
* @param doc
* the Document to create this from
*/
public PipelineDefinition(Document doc) {
Element rootEl = doc.getDocumentElement();
Element attributesEl = (Element) rootEl.getElementsByTagName(
"Attributes").item(0); //$NON-NLS-1$
NodeList attributeEls = attributesEl.getElementsByTagName("Attribute"); //$NON-NLS-1$
for (int i = 0; i < attributeEls.getLength(); i++) {
Element attributeEl = (Element) attributeEls.item(i);
String name = attributeEl.getAttribute("name"); //$NON-NLS-1$
String type = attributeEl.getAttribute("type"); //$NON-NLS-1$
String value = attributeEl.getAttribute("value"); //$NON-NLS-1$
addAttribute(new TypedValue(name, type, value));
}
Element transformsEl = (Element) rootEl.getElementsByTagName(
"Transforms").item(0); //$NON-NLS-1$
String useEmbedded = transformsEl.getAttribute("useEmbedded"); //$NON-NLS-1$
boolean embedded = Boolean.getBoolean(useEmbedded);
setUseEmbedded(embedded);
if (!embedded) {
NodeList transformEls = transformsEl
.getElementsByTagName("Transform"); //$NON-NLS-1$
for (int i = 0; i < transformEls.getLength(); i++) {
Element transformEl = (Element) transformEls.item(i);
TransformDefinition tdef = TransformDefinition
.fromXML(transformEl);
addTransformDef(tdef);
}
}
}
/**
* Configure the invoker from this.
*
* @param invoker
* the invoker to configure
* @throws ConfigurationException
* if an exception occurs during configuration
*/
public void configure(IProcessorInvoker invoker)
throws ConfigurationException {
Map<String, Object> attVals = new ConcurrentHashMap<String, Object>();
for (Iterator<TypedValue> iter = attributes.iterator(); iter.hasNext();) {
TypedValue att = iter.next();
Object value;
try {
value = att.createValue();
} catch (CreationException e) {
throw new ConfigurationException(e.getMessage(), e);
}
attVals.put(att.name, value);
}
invoker.setAttributes(attVals);
for (Iterator<TransformDefinition> iter = transformDefs.iterator(); iter
.hasNext();) {
TransformDefinition tdef = iter.next();
Map<String, Object> params = setParams(tdef);
URL url = getStyleSheetURL(tdef);
Properties properties = tdef.getOutputProperties();
URIResolver resolver = getResolver(tdef);
addStyleSheet(invoker, tdef, params, url, properties, resolver);
}
}
private void addStyleSheet(IProcessorInvoker invoker,
TransformDefinition tdef, Map<String, Object> params, URL url,
Properties properties, URIResolver resolver)
throws ConfigurationException {
try {
invoker.addStylesheet(url, params, properties, resolver);
} catch (TransformerConfigurationException e) {
throw new ConfigurationException(
Messages.getString("PipelineDefinition.10") + tdef.getStylesheetURL(), null); //$NON-NLS-1$
}
}
private URIResolver getResolver(TransformDefinition tdef)
throws ConfigurationException {
URIResolver resolver = null;
if (tdef.getResolverClass() != null) {
try {
Class resolverClass = Class.forName(tdef.getResolverClass());
resolver = (URIResolver) resolverClass.newInstance();
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
throw new ConfigurationException(
Messages.getString("PipelineDefinition.10") + tdef.getResolverClass(), null); //$NON-NLS-1$
} catch (ClassNotFoundException e) {
}
}
return resolver;
}
private URL getStyleSheetURL(TransformDefinition tdef)
throws ConfigurationException {
URL url = null;
try {
url = new URL(tdef.getStylesheetURL());
} catch (MalformedURLException e) {
throw new ConfigurationException(
Messages.getString("PipelineDefinition.9") + tdef.getStylesheetURL(), e); //$NON-NLS-1$
}
return url;
}
private Map<String, Object> setParams(TransformDefinition tdef)
throws ConfigurationException {
Map<String, Object> params = null;
try {
params = tdef.getParametersAsMap();
} catch (CreationException e) {
throw new ConfigurationException(Messages
.getString("PipelineDefinition.8"), e); //$NON-NLS-1$
}
return params;
}
/**
* Get the set of attributes defined.
*
* @return the set of attributes
*/
public Set<TypedValue> getAttributes() {
return attributes;
}
/**
* Add a attribute to this configuration
*
* @param attribute
* the attribute to add
*/
public void addAttribute(TypedValue attribute) {
attributes.add(attribute);
}
/**
* Remove a attribute from the set of attributes
*
* @param attribute
* the attribute to remove
*/
public void removeAttribute(TypedValue attribute) {
attributes.remove(attribute);
}
/**
* Get the list of <code>TransformDefinition</code>'s.
*
* @return the list of transform definitions
*/
public List<TransformDefinition> getTransformDefs() {
return transformDefs;
}
/**
* Add a transform definition to this.
*
* @param tdef
* the transform definition to add
*/
public void addTransformDef(TransformDefinition tdef) {
transformDefs.add(tdef);
}
/**
* Remove a transform definition from this.
*
* @param tdef
* the transform definition to remove
*/
public void removeTransformDef(TransformDefinition tdef) {
transformDefs.remove(tdef);
}
/**
* Set whether to use an XSL declaration embedded in the XML file
*
* @param embedded
* true to use embedded
*/
public void setUseEmbedded(boolean embedded) {
useEmbedded = embedded;
}
/**
* Get whether to use an XSL declaration embedded in the XML file
*
* @return true if embedded
*/
public boolean useEmbedded() {
return useEmbedded;
}
/**
* Serialize this to a DOM Document.
*
* @return the serialized document
* @throws ParserConfigurationException
* if a problem occurs during serialization
*/
public Document toXML() throws ParserConfigurationException {
Document doc = newDocument();
Element rootEl = doc.createElement("Pipeline"); //$NON-NLS-1$
rootEl.setAttribute("source", sourceURL); //$NON-NLS-1$
rootEl.setAttribute("target", targetFile); //$NON-NLS-1$
doc.appendChild(rootEl);
Element attributesEl = doc.createElement("Attributes"); //$NON-NLS-1$
rootEl.appendChild(attributesEl);
for (Iterator<TypedValue> iter = attributes.iterator(); iter.hasNext();) {
TypedValue attribute = (TypedValue) iter.next();
Element attributeEl = doc.createElement("Attribute"); //$NON-NLS-1$
attributeEl.setAttribute("name", attribute.name); //$NON-NLS-1$
attributeEl.setAttribute("type", attribute.type); //$NON-NLS-1$
attributeEl.setAttribute("value", attribute.value); //$NON-NLS-1$
attributesEl.appendChild(attributeEl);
}
rootEl.setAttribute("useEmbedded", String.valueOf(useEmbedded)); //$NON-NLS-1$
if (!useEmbedded) {
Element transformsEl = doc.createElement("Transforms"); //$NON-NLS-1$
rootEl.appendChild(transformsEl);
for (Iterator<TransformDefinition> iter = transformDefs.iterator(); iter
.hasNext();) {
TransformDefinition tdef = (TransformDefinition) iter.next();
Element tdefEl = tdef.asXML(doc);
transformsEl.appendChild(tdefEl);
}
}
return doc;
}
private static Document newDocument() throws ParserConfigurationException {
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
return doc;
}
}