| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| /* |
| * $Id$ |
| */ |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.Properties; |
| |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.transform.Result; |
| import javax.xml.transform.Source; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.dom.DOMResult; |
| import javax.xml.transform.dom.DOMSource; |
| import javax.xml.transform.sax.SAXResult; |
| import javax.xml.transform.sax.SAXSource; |
| import javax.xml.transform.stream.StreamResult; |
| import javax.xml.transform.stream.StreamSource; |
| |
| import org.xml.sax.InputSource; |
| import org.xml.sax.helpers.DefaultHandler; |
| |
| /** |
| * What it does: this sample creates multiple threads |
| * and runs them. Each thread will be assigned a particular |
| * stylesheet. Each thread will run multiple transformations on |
| * various xml files using its own transformer. |
| * |
| * Note: the flavors used by the transformations can be |
| * configured below by changing SOURCE_FLAVOR and |
| * RESULT_FLAVOR. XSLTC can also be used by changing |
| * USE_XSLTC. |
| * |
| * Description of files included with the sample: |
| * |
| * foo0.xsl and foo1.xsl: foo0.xsl is the stylesheet used |
| * for transformations by thread #0, foo1.xsl is the stylesheet |
| * used by thread #1. |
| * |
| * foo0.xml and foo1.xml: foo0.xml and foo1.xml are the XML |
| * files used for the first and second transformations done |
| * by each thread. |
| * |
| * Output will go to *.out files in the TransformThread directory. |
| * |
| * @author <a href="mailto:richcao@ca.ibm.com">Richard Cao</a> |
| */ |
| public class TransformThread implements Runnable |
| { |
| // Flavors |
| public final static int STREAM = 0; |
| public final static int SAX = 1; |
| public final static int DOM = 2; |
| public final static String[] flavorNames = |
| new String[] { "Stream", "SAX", "DOM" }; |
| |
| // Configurable options |
| private static int SOURCE_FLAVOR = STREAM; |
| // private static int SOURCE_FLAVOR = SAX; |
| // private static int SOURCE_FLAVOR = DOM; |
| |
| private static int RESULT_FLAVOR = STREAM; |
| // private static int RESULT_FLAVOR = SAX; |
| // private static int RESULT_FLAVOR = DOM; |
| |
| private static boolean USE_XSLTC = false; |
| // private static boolean useXSLTC = true; |
| |
| |
| // Threads |
| private final static int NUM_THREADS = 2; |
| private static TransformThread INSTANCES[] = null; |
| protected Thread m_thread = null; |
| |
| // Number of transformations per thread |
| private final static int NUM_TRANSFORMATIONS = 2; |
| |
| // Files names and extensions |
| private final static String XML_IN_BASE = "foo"; |
| private final static String XML_EXT = ".xml"; |
| private final static String XSL_IN_BASE = "foo"; |
| private final static String XSL_EXT = ".xsl"; |
| private final static String FILE_OUT_BASE = "foo_"; |
| private final static String FILE_OUT_EXT = ".out"; |
| |
| // Thread identifier |
| private int m_thrdNum = -1; |
| |
| private InputStream[] m_inStream = null; |
| |
| private Source[] m_inSource = null; |
| private Result[] m_outResult = null; |
| |
| // One Transformer per thread since Transformers |
| // are _NOT_ thread-safe |
| private Transformer m_transformer = null; |
| |
| /** Constructs the TransformThread object |
| * @param thrdNum a unique identifier for this object |
| */ |
| public TransformThread(int thrdNum) |
| { |
| m_thrdNum = thrdNum; |
| |
| m_inStream = new InputStream[NUM_TRANSFORMATIONS]; |
| m_inSource = new Source[NUM_TRANSFORMATIONS]; |
| m_outResult = new Result[NUM_TRANSFORMATIONS]; |
| |
| try |
| { |
| initSource(); |
| initResult(); |
| |
| // ensure xslSourceURI is a valid URI |
| final String xslSourceFileName = XSL_IN_BASE + m_thrdNum + XSL_EXT; |
| final String xslSourceURI = (new File(xslSourceFileName)).toURL().toString(); |
| StreamSource xslSource = new StreamSource(xslSourceFileName); |
| xslSource.setSystemId(xslSourceURI); |
| |
| // Initialize the tranformer |
| m_transformer = |
| TransformerFactory.newInstance().newTransformer(xslSource); |
| m_thread = new Thread(this); |
| } |
| catch (Throwable e) |
| { |
| e.printStackTrace(); |
| System.exit(1); |
| } |
| } |
| |
| /** Initialize the results (m_outResult) according |
| * to RESULT_FLAVOR |
| */ |
| private void initResult() |
| { |
| try |
| { |
| for (int i = 0; i < NUM_TRANSFORMATIONS; i++) |
| { |
| switch (RESULT_FLAVOR) |
| { |
| case STREAM : |
| OutputStream outStream = |
| new FileOutputStream(FILE_OUT_BASE + "thread_" |
| + m_thrdNum + "_transformation_" + i + FILE_OUT_EXT); |
| |
| m_outResult[i] = new StreamResult(outStream); |
| break; |
| |
| case SAX : |
| DefaultHandler defaultHandler = new DefaultHandler(); |
| m_outResult[i] = new SAXResult(defaultHandler); |
| break; |
| |
| case DOM : |
| m_outResult[i] = new DOMResult(); |
| break; |
| } |
| } |
| } |
| catch (Exception e) |
| { |
| e.printStackTrace(); |
| System.exit(1); |
| } |
| } |
| |
| /** Initialize the sources (m_inSource) according |
| * to SOURCE_FLAVOR |
| */ |
| private void initSource() |
| { |
| try |
| { |
| for (int i = 0; i < NUM_TRANSFORMATIONS; i++) |
| { |
| // Ensure we get a valid URI |
| final String sourceXMLURI = (new File(XML_IN_BASE + i + XML_EXT)).toURL().toString(); |
| |
| // Open for input |
| m_inStream[i] = new FileInputStream(XML_IN_BASE + i + XML_EXT); |
| |
| switch (SOURCE_FLAVOR) |
| { |
| case STREAM : |
| m_inSource[i] = new StreamSource(m_inStream[i]); |
| break; |
| |
| case SAX : |
| m_inSource[i] = new SAXSource(new InputSource(m_inStream[i])); |
| break; |
| |
| case DOM : |
| try |
| { |
| DocumentBuilderFactory dfactory = |
| DocumentBuilderFactory.newInstance(); |
| |
| // Must always setNamespaceAware when |
| // building xsl stylesheets |
| dfactory.setNamespaceAware(true); |
| m_inSource[i] = |
| new DOMSource(dfactory.newDocumentBuilder().parse(m_inStream[i])); |
| } |
| catch (Exception e) |
| { |
| e.printStackTrace(); |
| } |
| break; |
| } |
| |
| if (m_inSource[i] != null) |
| { |
| // If we don't do this, the transformer |
| // won't know how to resolve relative URLs |
| // in the stylesheet. |
| m_inSource[i].setSystemId(sourceXMLURI); |
| } |
| } |
| } |
| catch (Exception e) |
| { |
| e.printStackTrace(); |
| System.exit(1); |
| } |
| } |
| |
| /** |
| * @see java.lang.Runnable#run() |
| */ |
| public void run() |
| { |
| try |
| { |
| // Perform multiple transformations with the same |
| // transformer |
| for (int i = 0; i < NUM_TRANSFORMATIONS; i++) |
| { |
| m_transformer.transform(m_inSource[i], m_outResult[i]); |
| } |
| } |
| catch (Exception e) |
| { |
| e.printStackTrace(); |
| System.exit(1); |
| } |
| } |
| |
| /** Creates thread instances |
| */ |
| private static void initThreads() |
| { |
| INSTANCES = new TransformThread[NUM_THREADS]; |
| |
| for (int count = 0; count < NUM_THREADS; count++) |
| { |
| INSTANCES[count] = new TransformThread(count); |
| } |
| } |
| |
| /** Sets the appropriate system properties if XSLTC is |
| * to be used (according to USE_XSLTC) |
| */ |
| private static void initSystemProperties() |
| { |
| if (USE_XSLTC) |
| { |
| // Set the TransformerFactory system property if XSLTC is required |
| // Note: To make this sample more flexible, load properties from a properties file. |
| // The setting for the Xalan Transformer is "org.apache.xalan.processor.TransformerFactoryImpl" |
| String key = "javax.xml.transform.TransformerFactory"; |
| String value = "org.apache.xalan.xsltc.trax.TransformerFactoryImpl"; |
| Properties props = System.getProperties(); |
| props.put(key, value); |
| System.setProperties(props); |
| } |
| } |
| |
| /** |
| * Usage: |
| * java TransformThread |
| */ |
| public static void main(String argv[]) |
| { |
| try |
| { |
| initSystemProperties(); |
| initThreads(); |
| |
| for (int count = 0; count < NUM_THREADS; count++) |
| { |
| INSTANCES[count].m_thread.start(); |
| } |
| } |
| catch (Throwable e) |
| { |
| e.printStackTrace(); |
| System.exit(1); |
| } |
| } |
| } |