001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package de.schlund.pfixcore.util;
020:
021: import java.io.File;
022: import java.io.FileInputStream;
023: import java.io.FileNotFoundException;
024: import java.io.FileOutputStream;
025: import java.io.IOException;
026: import java.util.HashSet;
027: import java.util.Set;
028:
029: import javax.xml.transform.Result;
030: import javax.xml.transform.Source;
031: import javax.xml.transform.Transformer;
032: import javax.xml.transform.TransformerConfigurationException;
033: import javax.xml.transform.TransformerException;
034: import javax.xml.transform.TransformerFactory;
035: import javax.xml.transform.TransformerFactoryConfigurationError;
036: import javax.xml.transform.URIResolver;
037: import javax.xml.transform.dom.DOMResult;
038: import javax.xml.transform.dom.DOMSource;
039: import javax.xml.transform.sax.SAXTransformerFactory;
040: import javax.xml.transform.sax.TransformerHandler;
041: import javax.xml.transform.stream.StreamResult;
042: import javax.xml.transform.stream.StreamSource;
043:
044: import org.apache.tools.ant.BuildException;
045: import org.xml.sax.InputSource;
046: import org.xml.sax.SAXException;
047: import org.xml.sax.XMLReader;
048: import org.xml.sax.helpers.DefaultHandler;
049: import org.xml.sax.helpers.XMLReaderFactory;
050:
051: import de.schlund.pfixxml.config.CustomizationHandler;
052: import de.schlund.pfixxml.config.GlobalConfigurator;
053: import de.schlund.pfixxml.util.TransformerHandlerAdapter;
054:
055: /**
056: * Transforms projects.xml.in to projects.xml, doing customization.
057: *
058: * @author Sebastian Marsching <sebastian.marsching@1und1.de>
059: */
060: public class XsltCustomizeXmlTask extends XsltGenericTask {
061:
062: private String docroot;
063:
064: private Set<XsltParam> params = new HashSet<XsltParam>();
065:
066: protected void executeSetup() {
067: super .executeSetup();
068:
069: // Initialize PathFactory, as it is needed by the CustomizationHandler
070: if (docroot == null) {
071: throw new BuildException("Attribute docroot not set!");
072: }
073: try {
074: GlobalConfigurator.setDocroot(docroot);
075: } catch (IllegalStateException e) {
076: // Ignore exception as there is no problem
077: // if the docroot has already been configured
078: }
079: }
080:
081: public String getDocroot() {
082: return docroot;
083: }
084:
085: public void setDocroot(String value) {
086: this .docroot = value;
087: }
088:
089: public void addConfiguredParam(XsltParam param) {
090: this .params.add(param);
091: }
092:
093: protected void doTransformation() throws BuildException {
094: URIResolver customizationResolver = new CustomizationResolver();
095: try {
096: Transformer trans = TransformerFactory.newInstance()
097: .newTransformer(new StreamSource(stylefile));
098: trans.setURIResolver(customizationResolver);
099: File temp;
100: try {
101: temp = File.createTempFile("temptransform", ".xml");
102: } catch (IOException e) {
103: throw new BuildException(
104: "Could not create temporary file", e);
105: }
106: temp.deleteOnExit();
107: FileOutputStream fos = new FileOutputStream(temp);
108: StreamResult sr = new StreamResult(fos);
109: customize(in, sr);
110:
111: // Flush output to make sure it is avaiable for the
112: // next transformation step
113: fos.flush();
114: fos.close();
115:
116: for (XsltParam param : params) {
117: trans.setParameter(param.getName(), param
118: .getExpression());
119: }
120:
121: // Pass FileOutputStream instead of File to
122: // circumvent a bug in certain Xalan versions
123: trans.transform(new StreamSource(temp), new StreamResult(
124: new FileOutputStream(out)));
125: temp.delete();
126: } catch (TransformerConfigurationException e) {
127: throw new BuildException("Could not create transformer", e);
128: } catch (TransformerFactoryConfigurationError e) {
129: throw new BuildException("Could not create transformer", e);
130: } catch (IOException e) {
131: throw new BuildException("I/O-Error during transformation",
132: e);
133: } catch (TransformerException e) {
134: throw new BuildException("Parsing of " + in + " failed!", e);
135: }
136: }
137:
138: private static void customize(File input, Result result)
139: throws FileNotFoundException, TransformerException {
140: XMLReader xreader;
141: try {
142: xreader = XMLReaderFactory.createXMLReader();
143: } catch (SAXException e) {
144: throw new RuntimeException("Could not create XMLReader", e);
145: }
146: TransformerFactory tf = TransformerFactory.newInstance();
147: if (tf.getFeature(SAXTransformerFactory.FEATURE)) {
148: SAXTransformerFactory stf = (SAXTransformerFactory) tf;
149: TransformerHandler th;
150: try {
151: th = stf.newTransformerHandler();
152: } catch (TransformerConfigurationException e) {
153: throw new RuntimeException(
154: "Failed to configure TransformerFactory!", e);
155: }
156:
157: th.setResult(result);
158: DefaultHandler dh = new TransformerHandlerAdapter(th);
159: DefaultHandler cushandler = new CustomizationHandler(dh);
160: xreader.setContentHandler(cushandler);
161: xreader.setDTDHandler(cushandler);
162: xreader.setErrorHandler(cushandler);
163: xreader.setEntityResolver(cushandler);
164:
165: try {
166: xreader.parse(new InputSource(
167: new FileInputStream(input)));
168: } catch (FileNotFoundException e) {
169: throw e;
170: } catch (IOException e) {
171: throw new TransformerException(e);
172: } catch (SAXException e) {
173: throw new TransformerException(e);
174: }
175: } else {
176: throw new RuntimeException(
177: "Could not get instance of SAXTransformerFactory!");
178: }
179:
180: }
181:
182: private class CustomizationResolver implements URIResolver {
183:
184: public Source resolve(String href, String base)
185: throws TransformerException {
186: DOMResult dr = new DOMResult();
187: try {
188: customize(new File(href), dr);
189: } catch (FileNotFoundException e) {
190: return null;
191: }
192: return new DOMSource(dr.getNode());
193: }
194:
195: }
196:
197: }
|