Source Code Cross Referenced for XSLTransform.java in  » XML » xom » nu » xom » xslt » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » xom » nu.xom.xslt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright 2002-2005 Elliotte Rusty Harold
002:           
003:           This library is free software; you can redistribute it and/or modify
004:           it under the terms of version 2.1 of the GNU Lesser General Public 
005:           License as published by the Free Software Foundation.
006:           
007:           This library is distributed in the hope that it will be useful,
008:           but WITHOUT ANY WARRANTY; without even the implied warranty of
009:           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
010:           GNU Lesser General Public License for more details.
011:           
012:           You should have received a copy of the GNU Lesser General Public
013:           License along with this library; if not, write to the 
014:           Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
015:           Boston, MA 02111-1307  USA
016:           
017:           You can contact Elliotte Rusty Harold by sending e-mail to
018:           elharo@metalab.unc.edu. Please include the word "XOM" in the
019:           subject line. The XOM home page is located at http://www.xom.nu/
020:         */
021:
022:        package nu.xom.xslt;
023:
024:        import java.util.HashMap;
025:        import java.util.Iterator;
026:        import java.util.Map;
027:
028:        import javax.xml.transform.ErrorListener;
029:        import javax.xml.transform.OutputKeys;
030:        import javax.xml.transform.Source;
031:        import javax.xml.transform.Templates;
032:        import javax.xml.transform.Transformer;
033:        import javax.xml.transform.TransformerConfigurationException;
034:        import javax.xml.transform.TransformerException;
035:        import javax.xml.transform.TransformerFactoryConfigurationError;
036:        import javax.xml.transform.TransformerFactory;
037:
038:        import org.xml.sax.SAXParseException;
039:
040:        import nu.xom.Document;
041:        import nu.xom.Element;
042:        import nu.xom.NodeFactory;
043:        import nu.xom.Nodes;
044:        import nu.xom.XMLException;
045:
046:        /**
047:         * <p>
048:         * Serves as an interface to a TrAX aware XSLT processor such as Xalan
049:         * or Saxon. The following example shows how to apply an XSL 
050:         * Transformation to a XOM document and get the transformation result 
051:         * in the form of a XOM <code>Nodes</code>:</p>
052:         * <blockquote><pre>public static Nodes transform(Document in) 
053:         *   throws XSLException, ParsingException, IOException {
054:         *     Builder builder = new Builder();
055:         *     Document stylesheet = builder.build("mystylesheet.xsl");
056:         *     XSLTransform transform = new XSLTransform(stylesheet);
057:         *     return transform.transform(doc);
058:         * } </pre></blockquote>
059:         *
060:         * <p>
061:         *  XOM relies on TrAX to perform the transformation.
062:         *  The <code>javax.xml.transform.TransformerFactory</code> Java 
063:         *  system property determines which XSLT engine TrAX uses. Its 
064:         *  value should be the fully qualified name of the implementation 
065:         *  of the abstract <code>javax.xml.transform.TransformerFactory</code>
066:         *  class. Values of this property for popular XSLT processors include:
067:         *  </p>
068:         *  <ul>
069:         *   <li>Saxon 6.x: 
070:         *    <code>com.icl.saxon.TransformerFactoryImpl</code>
071:         *   </li>
072:         *   <li>Saxon 7.x and 8.x: 
073:         *    <code>net.sf.saxon.TransformerFactoryImpl</code>
074:         *   </li>
075:         *   <li>Xalan interpretive: 
076:         *    <code>org.apache.xalan.processor.TransformerFactoryImpl</code>
077:         *   </li>
078:         *   <li>Xalan XSLTC: 
079:         *    <code>org.apache.xalan.xsltc.trax.TransformerFactoryImpl</code>
080:         *   </li>
081:         *   <li>jd.xslt: 
082:         *    <code>jd.xml.xslt.trax.TransformerFactoryImpl</code>
083:         *   </li>
084:         *   <li>Oracle: 
085:         *    <code>oracle.xml.jaxp.JXSAXTransformerFactory</code>
086:         *   </li>
087:         *   <li>Java 1.5 bundled Xalan: 
088:         *    <code>com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl</code>
089:         *   </li>
090:         *  </ul>
091:         *  <p>
092:         *   This property can be set in all the usual ways a Java system 
093:         *   property can be set. TrAX picks from them in this order:</p>
094:         *   <ol>
095:         *   <li>The most recent value specified by invoking 
096:         *   <code>System.setProperty("javax.xml.transform.TransformerFactory", 
097:         *   "<i><code>classname</code></i>")</code></li>
098:         *   <li>The value specified at the command line using the 
099:         * <samp>-Djavax.xml.transform.TransformerFactory=<i>classname</i></samp>
100:         *      option to the <b>java</b> interpreter</li>
101:         *    <li>The class named in the  <code>lib/jaxp.properties</code> 
102:         *       properties file in the JRE directory, in a line like this one:
103:         * <pre>javax.xml.parsers.DocumentBuilderFactory=<i>classname</i></pre>
104:         *    </li>
105:         *    <li>The class named in the 
106:         * <code>META-INF/services/javax.xml.transform.TransformerFactory</code>
107:         *   file in the JAR archives available to the runtime</li>
108:         *   <li>Finally, if all of the above options fail,
109:         *    a default implementation is chosen. In Sun's JDK 1.4.0 and 1.4.1,
110:         *    this is Xalan 2.2d10. In JDK 1.4.2, this is Xalan 2.4. 
111:         *    In JDK 1.4.2_02, this is Xalan 2.4.1.
112:         *    In JDK 1.4.2_03, 1.5 beta 2, and 1.5 RC1 this is Xalan 2.5.2. 
113:         *    In JDK 1.4.2_05, this is Xalan 2.4.1. (Yes, Sun appears to have
114:         *    reverted to 2.4.1 in 1.4.2_05.)
115:         *    </li>
116:         *    </ol>
117:         *
118:         * @author Elliotte Rusty Harold
119:         * @version 1.1b3
120:         */
121:        public final class XSLTransform {
122:
123:            /**
124:             * <p>
125:             * The compiled form of the XSLT stylesheet that this object
126:             * represents. This can be safely used across multiple threads
127:             * unlike a <code>Transformer</code> object.
128:             * </p>
129:             */
130:            private Templates templates;
131:            private NodeFactory factory;
132:            private Map parameters = new HashMap();
133:            private static ErrorListener errorsAreFatal = new FatalListener();
134:
135:            private static class FatalListener implements  ErrorListener {
136:
137:                public void warning(TransformerException exception) {
138:                }
139:
140:                public void error(TransformerException exception)
141:                        throws TransformerException {
142:                    throw exception;
143:                }
144:
145:                public void fatalError(TransformerException exception)
146:                        throws TransformerException {
147:                    throw exception;
148:                }
149:
150:            }
151:
152:            // I could use one TransformerFactory field instead of local
153:            // variables but then I'd have to synchronize it; and it would
154:            // be hard to change the class used to transform
155:
156:            /**
157:             * <p>
158:             *  Creates a new <code>XSLTransform</code> by
159:             *  reading the stylesheet from the specified source.
160:             * </p>
161:             *
162:             * @param source TrAX <code>Source</code> object from 
163:             *      which the input document is read
164:             * 
165:             * @throws XSLException when an <code>IOException</code>, 
166:             *     format error, or something else prevents the stylesheet 
167:             *     from being compiled 
168:             */
169:            private XSLTransform(Source source) throws XSLException {
170:
171:                try {
172:                    TransformerFactory factory = TransformerFactory
173:                            .newInstance();
174:                    factory.setErrorListener(errorsAreFatal);
175:                    this .templates = factory.newTemplates(source);
176:                } catch (TransformerFactoryConfigurationError error) {
177:                    throw new XSLException(
178:                            "Could not locate a TrAX TransformerFactory", error);
179:                } catch (TransformerConfigurationException ex) {
180:                    throw new XSLException("Syntax error in stylesheet", ex);
181:                }
182:
183:            }
184:
185:            /**
186:             * <p>
187:             * Creates a new <code>XSLTransform</code> by
188:             * reading the stylesheet from the supplied document.
189:             * </p>
190:             * 
191:             * @param stylesheet document containing the stylesheet
192:             * 
193:             * @throws XSLException when the supplied document
194:             *      is not syntactically correct XSLT
195:             */
196:            public XSLTransform(Document stylesheet) throws XSLException {
197:                this (stylesheet, new NodeFactory());
198:            }
199:
200:            /**
201:             * <p>
202:             * Creates a new <code>XSLTransform</code> by
203:             * reading the stylesheet from the supplied document.
204:             * The supplied factory will be used to create all nodes
205:             * in the result tree, so that a transform can create 
206:             * instances of subclasses of the standard XOM classes. 
207:             * Because an XSL transformation generates a list of nodes rather
208:             * than a document, the factory's <code>startMakingDocument</code> 
209:             * and <code>finishMakingDocument</code> methods are not called.
210:             * </p>
211:             * 
212:             * @param stylesheet document containing the stylesheet
213:             * @param factory the factory used to build nodes in the result tree
214:             * 
215:             * @throws XSLException when the supplied document
216:             *      is not syntactically correct XSLT
217:             */
218:            public XSLTransform(Document stylesheet, NodeFactory factory)
219:                    throws XSLException {
220:
221:                this (new XOMSource(stylesheet));
222:                if (factory == null)
223:                    this .factory = new NodeFactory();
224:                else
225:                    this .factory = factory;
226:
227:            }
228:
229:            /**
230:             * <p>
231:             * Creates a new <code>Nodes</code> from the
232:             * input <code>Document</code> by applying this object's
233:             * stylesheet. The original <code>Document</code> is not 
234:             * changed.
235:             * </p>
236:             *
237:             * @param in document to transform
238:             * 
239:             * @return a <code>Nodes</code> containing the result of the
240:             *     transformation
241:             * 
242:             * @throws XSLException if the transformation fails, normally
243:             *     due to an XSLT error
244:             */
245:            public Nodes transform(Document in) throws XSLException {
246:                return transform(new XOMSource(in));
247:            }
248:
249:            /**
250:             * <p>
251:             * Supply a parameter to transformations performed by this object.
252:             * The value is normally a <code>Boolean</code>, 
253:             * <code>Double</code>, or <code>String</code>. However, it may be
254:             * another type if the underlying XSLT processor supports that
255:             * type. Passing null for the value removes the parameter.
256:             * </p>
257:             * 
258:             * @param name the name of the parameter
259:             * @param value the value of the parameter
260:             */
261:            public void setParameter(String name, Object value) {
262:                this .setParameter(name, null, value);
263:            }
264:
265:            /**
266:             * <p>
267:             * Supply a parameter to transformations performed by this object.
268:             * The value is normally a <code>Boolean</code>, 
269:             * <code>Double</code>, or <code>String</code>. However, it may be
270:             * another type if the underlying XSLT processor supports that
271:             * type. Passing null for the value removes the parameter.
272:             * </p>
273:             * 
274:             * @param name the name of the parameter
275:             * @param namespace the namespace URI of the parameter
276:             * @param value the value of the parameter
277:             */
278:            public void setParameter(String name, String namespace, Object value) {
279:
280:                if (namespace == null || "".equals(namespace)) {
281:                    _setParameter(name, value);
282:                } else {
283:                    _setParameter("{" + namespace + "}" + name, value);
284:                }
285:
286:            }
287:
288:            private void _setParameter(String name, Object value) {
289:
290:                if (value == null) {
291:                    parameters.remove(name);
292:                } else {
293:                    parameters.put(name, value);
294:                }
295:
296:            }
297:
298:            /**
299:             * <p>
300:             * Creates a new <code>Nodes</code> object from the
301:             * input <code>Nodes</code> object by applying this object's
302:             * stylesheet. The original <code>Nodes</code> object is not 
303:             * changed.
304:             * </p>
305:             *
306:             * @param in document to transform
307:             * 
308:             * @return a <code>Nodes</code> containing the result of 
309:             *     the transformation
310:             * 
311:             * @throws XSLException if the transformation fails, normally
312:             *     due to an XSLT error
313:             */
314:            public Nodes transform(Nodes in) throws XSLException {
315:
316:                if (in.size() == 0)
317:                    return new Nodes();
318:                XOMSource source = new XOMSource(in);
319:                return transform(source);
320:
321:            }
322:
323:            /**
324:             * <p>
325:             * Creates a new <code>Nodes</code> object from the
326:             * input <code>Source</code> object by applying this object's
327:             * stylesheet. 
328:             * </p>
329:             *
330:             * @param in TrAX <code>Source</code> to transform
331:             * 
332:             * @return a <code>Nodes</code> object containing the result of 
333:             *     the transformation
334:             * 
335:             * @throws XSLException if the transformation fails, normally
336:             *     due to an XSLT error
337:             */
338:            private Nodes transform(Source in) throws XSLException {
339:
340:                try {
341:                    XOMResult out = new XOMResult(factory);
342:                    Transformer transformer = templates.newTransformer();
343:                    // work around Xalan bug
344:                    transformer.setOutputProperty(OutputKeys.METHOD, "xml");
345:                    // work around a Xalan 2.7.0 bug
346:                    transformer.setErrorListener(errorsAreFatal);
347:                    Iterator iterator = parameters.keySet().iterator();
348:                    while (iterator.hasNext()) {
349:                        String key = (String) iterator.next();
350:                        Object value = parameters.get(key);
351:                        transformer.setParameter(key, value);
352:                    }
353:                    transformer.transform(in, out);
354:                    return out.getResult();
355:                } catch (Exception ex) {
356:                    // workaround bugs that wrap RuntimeExceptions
357:                    Throwable cause = ex;
358:                    if (cause instanceof  TransformerException) {
359:                        TransformerException tex = (TransformerException) cause;
360:                        Throwable nested = tex.getException();
361:                        if (nested != null) {
362:                            cause = nested;
363:                            if (cause instanceof  SAXParseException) {
364:                                nested = ((SAXParseException) cause)
365:                                        .getException();
366:                                if (nested != null)
367:                                    cause = nested;
368:                            }
369:                        }
370:                    }
371:                    throw new XSLException(ex.getMessage(), cause);
372:                }
373:
374:            }
375:
376:            /**
377:             * <p>
378:             * Builds a <code>Document</code> object from a 
379:             * <code>Nodes</code> object. This is useful when the stylesheet
380:             * is known to produce a well-formed document with a single root 
381:             * element. That is, the <code>Node</code> returned contains
382:             * only comments, processing instructions, and exactly one 
383:             * element. If the stylesheet produces anything else, 
384:             * this method throws <code>XMLException</code>.
385:             * </p>
386:             * 
387:             * @param nodes the nodes to be placed in the new document
388:             * 
389:             * @return a document containing the nodes
390:             * 
391:             * @throws XMLException if <code>nodes</code> does not contain
392:             *     exactly one element or if it contains any text nodes or
393:             *     attributes
394:             */
395:            public static Document toDocument(Nodes nodes) {
396:
397:                Element root = null;
398:                int rootPosition = 0;
399:                for (int i = 0; i < nodes.size(); i++) {
400:                    if (nodes.get(i) instanceof  Element) {
401:                        rootPosition = i;
402:                        root = (Element) nodes.get(i);
403:                        break;
404:                    }
405:                }
406:
407:                if (root == null) {
408:                    throw new XMLException("No root element");
409:                }
410:
411:                Document result = new Document(root);
412:
413:                for (int i = 0; i < rootPosition; i++) {
414:                    result.insertChild(nodes.get(i), i);
415:                }
416:
417:                for (int i = rootPosition + 1; i < nodes.size(); i++) {
418:                    result.appendChild(nodes.get(i));
419:                }
420:
421:                return result;
422:
423:            }
424:
425:            /**
426:             * <p>
427:             *  Returns a string form of this <code>XSLTransform</code>, 
428:             *  suitable for debugging.
429:             * </p>
430:             *
431:             * @return debugging string
432:             */
433:            public String toString() {
434:                return "[" + getClass().getName() + ": " + templates + "]";
435:            }
436:
437:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.