001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.xsl;
031:
032: import com.caucho.log.Log;
033: import com.caucho.server.util.CauchoSystem;
034: import com.caucho.util.ExceptionWrapper;
035: import com.caucho.vfs.MergePath;
036: import com.caucho.vfs.Path;
037: import com.caucho.vfs.ReadStream;
038: import com.caucho.vfs.Vfs;
039: import com.caucho.vfs.WriteStream;
040: import com.caucho.xml.Html;
041: import com.caucho.xml.Xml;
042: import com.caucho.xml.XmlParser;
043: import com.caucho.loader.*;
044:
045: import org.w3c.dom.Document;
046:
047: import javax.xml.transform.Templates;
048: import javax.xml.transform.TransformerConfigurationException;
049: import java.io.IOException;
050: import java.util.ArrayList;
051: import java.util.HashMap;
052: import java.util.Properties;
053: import java.util.logging.Logger;
054:
055: /**
056: * Public facade for creating stylesheets. The Xsl factory
057: * creates standard XSL stylesheets. A Stylesheet object represents
058: * a compiled stylesheet. You'll need to create a Transformer to
059: * actually perform any transformations.
060: *
061: * <code><pre>
062: * import java.io.*;
063: * import javax.xml.transform.*;
064: * import javax.xml.transform.stream.*;
065: * import org.xml.sax.*;
066: *
067: * import com.caucho.xsl.*;
068: *
069: * ...
070: *
071: * TransformerFactory factory = new Xsl();
072: * StreamSource xslSource = new StreamSource("mystyle.xsl");
073: * Transformer transformer = factory.newTransformer(xslSource);
074: *
075: * StreamSource xmlSource = new StreamSource("test.xml");
076: * StreamResult htmlResult = new StreamResult("test.html");
077: *
078: * transformer.transform(xmlSource, htmlResult);
079: * </pre></code>
080: */
081: public class Xsl extends AbstractStylesheetFactory {
082: static final Logger log = Log.open(Xsl.class);
083:
084: public Xsl() {
085: }
086:
087: /**
088: * Parses the XSL into a DOM document.
089: *
090: * @param rs the input stream.
091: */
092: protected Document parseXSL(ReadStream rs)
093: throws TransformerConfigurationException {
094: try {
095: Xml parser = new Xml();
096:
097: return parser.parseDocument(rs);
098: } catch (Exception e) {
099: throw new XslParseException(e);
100: }
101: }
102:
103: public static void main(String[] args) {
104: String xslName = "default.xsl";
105: String dest = null;
106: String suffix = null;
107: String toc = "";
108: int i = 0;
109: String conf = CauchoSystem.getResinConfig();
110: boolean isStrict = true;
111: ArrayList<String> argList = new ArrayList<String>();
112: ArrayList<String> keyList = new ArrayList<String>();
113: ArrayList<String> valueList = new ArrayList<String>();
114:
115: while (i < args.length) {
116: if (args[i].equals("-xsl")) {
117: xslName = args[i + 1];
118: i += 2;
119: } else if (args[i].equals("-lite")
120: || args[i].equals("-stylescript")) {
121: isStrict = false;
122: i += 1;
123: } else if (args[i].equals("-o")) {
124: dest = args[i + 1];
125: i += 2;
126: } else if (args[i].equals("-suffix")) {
127: suffix = args[i + 1];
128: i += 2;
129: } else if (args[i].startsWith("-A")) {
130: argList.add(args[i].substring(2));
131: i += 1;
132: } else if (args[i].startsWith("-P")) {
133: String v = args[i].substring(2);
134: int p = v.indexOf('=');
135: String key;
136: String value;
137:
138: if (p >= 0) {
139: key = v.substring(0, p);
140: value = v.substring(p + 1);
141: } else {
142: key = v;
143: value = "";
144: }
145:
146: keyList.add(key);
147: valueList.add(value);
148:
149: i += 1;
150: } else if (args[i].equals("-conf")) {
151: conf = args[i + 1];
152: i += 2;
153: } else if (args[i].equals("-h") || args[i].equals("-help")) {
154: usage();
155: return;
156: } else
157: break;
158: }
159:
160: /*
161: Path cfg = CauchoSystem.getResinHome().lookup(conf);
162: if (cfg.exists()) {
163: try {
164: Registry.setRegistry(Registry.parse(cfg));
165: } catch (IOException e) {
166: } catch (SAXException e) {
167: }
168: }
169: */
170:
171: Path destDir = null;
172: if (dest != null)
173: destDir = Vfs.lookup(dest);
174: else if (suffix == null)
175: destDir = Vfs.lookup("stdout:");
176:
177: if (args.length - i > 1 && (dest == null || destDir.isFile())
178: && suffix == null) {
179: System.err
180: .println("multiple sources require a destination directory");
181: System.exit(1);
182: }
183:
184: try {
185: MergePath stylePath = new MergePath();
186: stylePath.addMergePath(Vfs.lookup(xslName).getParent());
187: stylePath.addMergePath(Vfs.lookup());
188: stylePath.addMergePath(CauchoSystem.getResinHome().lookup(
189: "xsl"));
190:
191: ClassLoader loader = Thread.currentThread()
192: .getContextClassLoader();
193:
194: if (loader instanceof DynamicClassLoader) {
195: DynamicClassLoader dynLoader = (DynamicClassLoader) loader;
196: String resourcePath = dynLoader
197: .getResourcePathSpecificFirst();
198: stylePath.addClassPath(resourcePath);
199: }
200:
201: // stylePath.addClassPath(
202:
203: /*
204: Path []stylePath = new Path[] {
205: Pwd.lookup(xslName).getParent(),
206: Pwd.lookup(),
207: CauchoSystem.getResinHome().lookup("xsl")};
208: */
209: Path[] scriptPath = new Path[] { Vfs.lookup(),
210: Vfs.lookup(xslName).getParent(),
211: CauchoSystem.getResinHome().lookup("scripts") };
212:
213: Path xslPath = stylePath.lookup(xslName);
214: if (xslPath == null) {
215: System.out.println("can't find `" + xslName + "'");
216: System.exit(1);
217: }
218:
219: AbstractStylesheetFactory xsl;
220:
221: if (isStrict)
222: xsl = new Xsl();
223: else
224: xsl = new StyleScript();
225:
226: xsl.setStylePath(stylePath);
227:
228: Templates stylesheet;
229:
230: stylesheet = xsl.newTemplates(xslName);
231:
232: for (; i < args.length; i++) {
233: String name = args[i];
234:
235: Path xmlPath = Vfs.lookup(name);
236:
237: HashMap<String, Object> argMap = new HashMap<String, Object>();
238:
239: String[] childArgs = new String[argList.size() + 1];
240: argList.toArray(childArgs);
241: childArgs[childArgs.length - 1] = name;
242:
243: argMap.put("arguments", childArgs);
244: argMap.put("File", Vfs.lookup());
245:
246: ReadStream is = xmlPath.openRead();
247: Document doc = null;
248: try {
249: if (isStrict)
250: doc = new Xml().parseDocument(is);
251: else {
252: XmlParser parser = new Html();
253: parser.setEntitiesAsText(true);
254: doc = parser.parseDocument(is);
255: }
256: } finally {
257: is.close();
258: }
259:
260: //Document result = xsl.transform(doc, argMap);
261: Document result = null;
262:
263: Path destPath = null;
264: if (dest != null)
265: destPath = Vfs.lookup(dest);
266: else if (suffix != null)
267: destPath = xmlPath.getParent();
268: else
269: destPath = Vfs.lookup("stdout:");
270:
271: if (suffix != null) {
272: int p = name.lastIndexOf('.');
273: if (p == -1) {
274: System.err.println("suffix missing for `"
275: + name + "'");
276: System.exit(1);
277: }
278:
279: String destName = name.substring(0, p);
280: if (dest == null) {
281: p = destName.lastIndexOf('/');
282: if (p >= 0)
283: destName = destName.substring(p + 1);
284: }
285:
286: if (!destPath.isFile())
287: destPath = destPath.lookup(destName + '.'
288: + suffix);
289: else {
290: System.err
291: .println("illegal output combination");
292: System.exit(1);
293: }
294: } else if (destPath.isDirectory())
295: destPath = destPath.lookup(name);
296:
297: try {
298: destPath.getParent().mkdirs();
299: } catch (IOException e) {
300: }
301:
302: WriteStream os = destPath.openWrite();
303:
304: try {
305: Properties output = stylesheet
306: .getOutputProperties();
307:
308: String encoding = (String) output.get("encoding");
309: String mimeType = (String) output.get("mime-type");
310: String method = (String) output.get("method");
311:
312: if (encoding == null
313: && (method == null || !method
314: .equals("html")))
315: encoding = "UTF-8";
316:
317: TransformerImpl transformer = (TransformerImpl) stylesheet
318: .newTransformer();
319:
320: if (encoding != null)
321: os.setEncoding(encoding);
322:
323: transformer.setProperty("caucho.pwd", Vfs.lookup());
324:
325: for (int j = 0; j < keyList.size(); j++) {
326: String key = (String) keyList.get(j);
327: String value = (String) valueList.get(j);
328:
329: transformer.setParameter(key, value);
330: }
331:
332: transformer.transform(doc, os);
333: } finally {
334: os.close();
335: }
336: }
337: } catch (Throwable e) {
338: while ((e instanceof ExceptionWrapper)
339: && ((ExceptionWrapper) e).getRootCause() != null)
340: e = ((ExceptionWrapper) e).getRootCause();
341:
342: e.printStackTrace();
343: } finally {
344: System.exit(0);
345: }
346: }
347:
348: private static void usage() {
349: System.err.println("xsl [-xsl stylesheet] file1 file2 ...");
350: System.err.println(" -xsl stylesheet : select a stylesheet");
351: System.err
352: .println(" -o filename : output filename/directory");
353: System.err.println(" -suffix suffix : replacement suffix");
354: System.err.println(" -stylescript : StyleScript");
355: System.err.println(" -Pkey=value : template parameter");
356: System.err.println(" -h : this help message");
357: }
358: }
|