Java tutorial
/* * 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: TransformThread.java 470245 2006-11-02 06:34:33Z minchau $ */ 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); } } }