Source Code Cross Referenced for XsltTransformer.java in  » J2EE » Pustefix » de » schlund » pfixcore » util » 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 » J2EE » Pustefix » de.schlund.pfixcore.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.util.HashMap;
023:        import java.util.Iterator;
024:
025:        import javax.xml.transform.Result;
026:        import javax.xml.transform.Source;
027:        import javax.xml.transform.Templates;
028:        import javax.xml.transform.Transformer;
029:        import javax.xml.transform.TransformerConfigurationException;
030:        import javax.xml.transform.TransformerException;
031:        import javax.xml.transform.TransformerFactory;
032:        import javax.xml.transform.sax.SAXSource;
033:        import javax.xml.transform.stream.StreamResult;
034:        import javax.xml.transform.stream.StreamSource;
035:
036:        import org.apache.tools.ant.BuildException;
037:        import org.apache.tools.ant.Project;
038:        import org.xml.sax.EntityResolver;
039:        import org.xml.sax.InputSource;
040:        import org.xml.sax.XMLReader;
041:
042:        import com.icl.saxon.TransformerFactoryImpl;
043:        import com.sun.org.apache.xerces.internal.parsers.SAXParser;
044:
045:        /**
046:         * @author adam
047:         *
048:         * To change the template for this generated type comment go to
049:         * Window - Preferences - Java - Code Generation - Code and Comments
050:         */
051:        public class XsltTransformer {
052:
053:            // sax feature ids, see http://xml.apache.org/xerces2-j/features.html 
054:
055:            /** Namespaces feature id (http://xml.org/sax/features/namespaces). See http://xml.apache.org/xerces2-j/features.html
056:             *  Xerces-Default: true */
057:            protected static final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
058:
059:            /** Namespace prefixes feature id (http://xml.org/sax/features/namespace-prefixes). See http://xml.apache.org/xerces2-j/features.html 
060:             *  Xerces-Default: false */
061:            protected static final String NAMESPACE_PREFIXES_FEATURE_ID = "http://xml.org/sax/features/namespace-prefixes";
062:
063:            /** Validation feature id (http://xml.org/sax/features/validation). See http://xml.apache.org/xerces2-j/features.html
064:             *  Xerces-Default: false */
065:            protected static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
066:
067:            /** Schema validation feature id (http://apache.org/xml/features/validation/schema). See http://xml.apache.org/xerces2-j/features.html
068:             *  Xerces-Default: false */
069:            protected static final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
070:
071:            /** Schema full checking feature id (http://apache.org/xml/features/validation/schema-full-checking). See http://xml.apache.org/xerces2-j/features.html
072:             *  Xerces-Default: false */
073:            protected static final String SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking";
074:
075:            /** Dynamic validation feature id (http://apache.org/xml/features/validation/dynamic). See http://xml.apache.org/xerces2-j/features.html
076:             *  Xerces-Default: false */
077:            protected static final String DYNAMIC_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/dynamic";
078:
079:            /** Load external DTD feature id (http://apache.org/xml/features/nonvalidating/load-external-dtd). Does not seem to control loading of external xml schema as of xerces 2.6.2. See http://xml.apache.org/xerces2-j/features.html
080:             *  Xerces-Default: true */
081:            protected static final String LOAD_EXTERNAL_DTD_FEATURE_ID = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
082:
083:            protected static final String[] FEATURES = { NAMESPACES_FEATURE_ID,
084:                    NAMESPACE_PREFIXES_FEATURE_ID, VALIDATION_FEATURE_ID,
085:                    SCHEMA_VALIDATION_FEATURE_ID,
086:                    SCHEMA_FULL_CHECKING_FEATURE_ID,
087:                    DYNAMIC_VALIDATION_FEATURE_ID, LOAD_EXTERNAL_DTD_FEATURE_ID };
088:
089:            protected TransformerFactory factory;
090:            protected Transformer transformer;
091:            protected File stylesheet;
092:            protected boolean isValidStylesheet = false;
093:            /** used by caching mechanism @see #validate() */
094:            protected File stylesheetOld;
095:            /** used by caching mechanism @see #validate() */
096:            protected long stylesheetOldLastModified;
097:            protected boolean cacheStylesheet = true;
098:            /** The In memory version of the stylesheet */
099:            protected Templates templates;
100:            /** holds additional {@link XsltParam} objects to be passed to the stylesheets */
101:            protected HashMap<String, XsltParam> params = new HashMap<String, XsltParam>(
102:                    20);
103:            protected boolean isValidParams = false;
104:            protected boolean isValidParser = false;
105:            /** controls {@link #VALIDATION_FEATURE_ID} and {@link #SCHEMA_VALIDATION_FEATURE_ID}; defaults to false */
106:            protected boolean isValidate = false;
107:            /** controls {@link #DYNAMIC_VALIDATION_FEATURE_ID}; defaults to false */
108:            protected boolean isValidateDynamic = false;
109:            /** controls {@link #NAMESPACES_FEATURE_ID}; defaults to true */
110:            protected boolean isNamespaceAware = true;
111:            protected EntityResolver entitiyResolver = null;
112:            protected XMLReader xmlReader = null;
113:            protected XsltErrorListener errorListener = null;
114:            /** never null */
115:            protected Project project = null;
116:
117:            /**
118:             * The Stylesheet needs to be set with {@link #setStylesheet(File)} when using the
119:             * default constructor.
120:             * @param project may not be null
121:             */
122:            public XsltTransformer(Project project) {
123:                this (project, null);
124:            }
125:
126:            /**
127:             * @param project must not be null
128:             * @param stylesheet may be null
129:             */
130:            public XsltTransformer(Project project, File stylesheet) {
131:                if (project == null) {
132:                    throw new NullPointerException("project=" + project
133:                            + "; stylesheet=" + stylesheet);
134:                }
135:                setProject(project);
136:                setStylesheet(stylesheet);
137:                // force Saxon (com.icl.saxon.TransformerFactoryImpl) because we have extension functions
138:                factory = new TransformerFactoryImpl();
139:                errorListener = new XsltErrorListener(getProject());
140:            }
141:
142:            public void transform(File baseDir, String infilename,
143:                    File destDir, String outfilename) {
144:                transform(new File(baseDir, infilename), new File(destDir,
145:                        outfilename));
146:            }
147:
148:            public void transform(File infile, File outfile) {
149:                // We have to validate here for XML Reader to be correctly initialized
150:                if (!isValid()) {
151:                    validate();
152:                }
153:                StreamResult result = new StreamResult(outfile);
154:                // TODO_AH check whether or not to prepend the systemid with file://
155:                InputSource is = new InputSource("file://"
156:                        + infile.getAbsolutePath());
157:                SAXSource source = new SAXSource(xmlReader, is);
158:                transform(source, result);
159:            }
160:
161:            public void transform(Source source, Result result) {
162:                if (!isValid()) {
163:                    validate();
164:                }
165:                try {
166:                    transformer.transform(source, result);
167:                } catch (TransformerException tex) {
168:                    // TODO_AH delete this misguided attempt to be nice. Seems like transformer never leaves a half-finished destination file.
169:                    // Trying to set the last modified time of the target file
170:                    // to 1970, so it get's transformed again on the next build.
171:                    // (Allowing the developer to still be able to
172:                    // take a look at the eventually half-finished result file).
173:                    //            try {
174:                    //                String systemId = result.getSystemId();
175:                    //                String filename = null;
176:                    //                if ( systemId != null && systemId.startsWith("file:") ) {
177:                    //                    filename = systemId.substring(5);
178:                    //                    if ( filename.startsWith("///") ) {
179:                    //                        filename = filename.substring(2);
180:                    //                    }
181:                    //                    File file = new File(filename);
182:                    //                    if ( file.exists() && file.canWrite() ) {
183:                    //                        file.setLastModified(0);
184:                    //                    }
185:                    //                }
186:                    //            } catch(Exception e) {
187:                    //                // this should not happen, anyways - better dump than hide it
188:                    //                e.printStackTrace();
189:                    //            }
190:                    throw new BuildException(tex.getMessageAndLocation()
191:                            + " - Transformation from source="
192:                            + source.getSystemId() + " to result="
193:                            + result.getSystemId() + " failed.", tex);
194:                }
195:            }
196:
197:            protected boolean isValid() {
198:                return (isValidParams == true && isValidStylesheet == true && isValidParser == true);
199:            }
200:
201:            /**
202:             * @throws BuildException on {@link #stylesheet} == null, {@link TransformerConfigurationException},  {@link XMLReader#setFeature(java.lang.String, boolean)}
203:             */
204:            protected void validate() {
205:                if (isValidStylesheet == false) {
206:                    if (stylesheet == null) {
207:                        throw new BuildException("No stylesheet specified");
208:                    } else {
209:                        try {
210:                            // check whether we have to reload the stylesheet or not
211:                            boolean reload = false;
212:                            long lastModified = stylesheet.lastModified();
213:                            reload = reload || (isCacheStylesheet() == false);
214:                            reload = reload
215:                                    || (stylesheet.equals(stylesheetOld) == false);
216:                            reload = reload
217:                                    || (lastModified > stylesheetOldLastModified);
218:                            if (reload) {
219:                                transformer = factory
220:                                        .newTransformer(new StreamSource(
221:                                                stylesheet));
222:                                // TODO_AH comment in custom ErrorListener
223:                                // transformer.setErrorListener(errorListener);
224:                                stylesheetOld = stylesheet;
225:                                stylesheetOldLastModified = lastModified;
226:                                isValidStylesheet = true;
227:                                isValidParams = false; // parameters have to be reapplied
228:                            }
229:                        } catch (TransformerConfigurationException e) {
230:                            stylesheetOld = null;
231:                            stylesheetOldLastModified = 0;
232:                            throw new BuildException(
233:                                    "Could not initialize XSLT Transformer (stylesheet=\""
234:                                            + stylesheet + "\")", e);
235:                        }
236:                    }
237:                }
238:                if (isValidParser == false) {
239:                    // force Xerces (org.apache.xerces.parsers.SAXParser) because xml schema validation features
240:                    this .xmlReader = new SAXParser();
241:                    try {
242:                        this .xmlReader.setFeature(VALIDATION_FEATURE_ID,
243:                                isValidate());
244:                        this .xmlReader.setFeature(SCHEMA_VALIDATION_FEATURE_ID,
245:                                isValidate());
246:                        this .xmlReader.setFeature(
247:                                DYNAMIC_VALIDATION_FEATURE_ID,
248:                                isValidateDynamic());
249:                        this .xmlReader.setFeature(NAMESPACES_FEATURE_ID,
250:                                isNamespaceAware());
251:                    } catch (Exception e) {
252:                        throw new BuildException(
253:                                "There was a problem configuring "
254:                                        + this .xmlReader + ". this="
255:                                        + this .toString(), e);
256:                    }
257:                    if (getEntitiyResolver() != null) {
258:                        this .xmlReader.setEntityResolver(getEntitiyResolver());
259:                    }
260:                    isValidParser = true;
261:                }
262:                if (isValidParams == false) {
263:                    // assert transformer != null : "Exception should have been thrown
264:                    // beforehand";
265:                    transformer.clearParameters();
266:                    for (Iterator<XsltParam> iter = params.values().iterator(); iter
267:                            .hasNext();) {
268:                        XsltParam param = iter.next();
269:                        transformer.setParameter(param.getName(), param
270:                                .getExpression());
271:                    }
272:                }
273:            }
274:
275:            /**
276:             * @return stylesheet or null
277:             */
278:            public File getStylesheet() {
279:                return stylesheet;
280:            }
281:
282:            /**
283:             * Sets a new Stylesheet File, which in turn creates a new {@link Transformer}.<br/>
284:             * Note: you have to re-apply your parameters, as they get lost with the old
285:             * transformer.
286:             * 
287:             * @param stylesheet or null
288:             * @see   #setParameter(String, Object)
289:             */
290:            public void setStylesheet(File stylesheet) {
291:                this .stylesheet = stylesheet;
292:                isValidStylesheet = false;
293:            }
294:
295:            /**
296:             * @throw IllegalArgumentException if param or param.getName() are null
297:             */
298:            public void setParameter(XsltParam param) {
299:                isValidParams = false;
300:                if (param == null || param.getName() == null) {
301:                    throw new IllegalArgumentException(
302:                            "param and param.getName() must not be null: "
303:                                    + String.valueOf(param));
304:                }
305:                params.put(param.getName(), param);
306:            }
307:
308:            public EntityResolver getEntitiyResolver() {
309:                return entitiyResolver;
310:            }
311:
312:            public void setEntitiyResolver(EntityResolver entitiyResolver) {
313:                if (entitiyResolver != this .entitiyResolver) {
314:                    this .isValidParser = false;
315:                }
316:                this .entitiyResolver = entitiyResolver;
317:            }
318:
319:            /**
320:             * Configures parser for input documents.
321:             * Affects following features:
322:             * <ul>
323:             * <li>{@link #VALIDATION_FEATURE_ID         }
324:             * <li>{@link #SCHEMA_VALIDATION_FEATURE_ID  }
325:             * </ul>  
326:             * Default: false  
327:             * @see   #validate()
328:             */
329:            public boolean isValidate() {
330:                return isValidate;
331:            }
332:
333:            /**
334:             * Configures parser for input documents.
335:             * Affects following features:
336:             * <ul>
337:             * <li>{@link #VALIDATION_FEATURE_ID         }
338:             * <li>{@link #SCHEMA_VALIDATION_FEATURE_ID  }
339:             * </ul><br>
340:             * Default: false  
341:             * @see   #validate()
342:             */
343:            public void setValidate(boolean validate) {
344:                if (validate != this .isValidate) {
345:                    this .isValidParser = false;
346:                }
347:                this .isValidate = validate;
348:            }
349:
350:            /**
351:             * Configures parser for input documents.
352:             * Affects following features:
353:             * <ul>
354:             * <li>{@link #DYNAMIC_VALIDATION_FEATURE_ID }
355:             * </ul><br> 
356:             * Default: false  
357:             * @see   #validate()
358:             */
359:            public boolean isValidateDynamic() {
360:                return isValidateDynamic;
361:            }
362:
363:            /**
364:             * Configures parser for input documents.
365:             * Affects following features:
366:             * <ul>
367:             * <li>{@link #DYNAMIC_VALIDATION_FEATURE_ID }
368:             * </ul><br>  
369:             * Default: false  
370:             * @see   #validate()
371:             */
372:            public void setValidateDynamic(boolean validateDynamic) {
373:                if (validateDynamic != this .isValidateDynamic
374:                        && this .isValidate == true) {
375:                    this .isValidParser = false;
376:                }
377:                this .isValidateDynamic = validateDynamic;
378:            }
379:
380:            /**
381:             * Configures parser for input documents.
382:             * Affects following features:
383:             * <ul>
384:             * <li>{@link #NAMESPACES_FEATURE_ID         }
385:             * </ul><br>  
386:             * Default: true  
387:             * @see   #validate()
388:             */
389:            public boolean isNamespaceAware() {
390:                return isNamespaceAware;
391:            }
392:
393:            /**
394:             * Configures parser for input documents.
395:             * Affects following features:
396:             * <ul>
397:             * <li>{@link #NAMESPACES_FEATURE_ID         }
398:             * </ul><br>  
399:             * Default: true  
400:             * @see   #validate()
401:             */
402:            public void setNamespaceAware(boolean isNamespaceAware) {
403:                if (isNamespaceAware != this .isNamespaceAware) {
404:                    this .isValidParser = false;
405:                }
406:                this .isNamespaceAware = isNamespaceAware;
407:            }
408:
409:            public void clearParameters() {
410:                isValidParams = false;
411:                params.clear();
412:            }
413:
414:            public Project getProject() {
415:                return project;
416:            }
417:
418:            protected void setProject(Project project) {
419:                this .project = project;
420:            }
421:
422:            public String toString() {
423:                return shortClassname(getClass().getName()) + "[transformer="
424:                        + transformer + "; isValidate=" + isValidate
425:                        + " isValidateDynamic=" + isValidateDynamic
426:                        + "; isNamespaceAware=" + isNamespaceAware
427:                        + "; params=" + params + "]";
428:            }
429:
430:            //
431:            //  Helper methods
432:            //
433:
434:            /**
435:             * @return classname without package prefix
436:             */
437:            public static String shortClassname(String classname) {
438:                try {
439:                    int idx = classname.lastIndexOf('.');
440:                    if (idx >= 0) {
441:                        classname = classname.substring(idx + 1, classname
442:                                .length());
443:                    }
444:                } catch (IndexOutOfBoundsException e) {
445:                    // This should never happen
446:                    e.printStackTrace();
447:                }
448:                return classname;
449:            }
450:
451:            public boolean isCacheStylesheet() {
452:                return cacheStylesheet;
453:            }
454:
455:            public void setCacheStylesheet(boolean cacheStylesheet) {
456:                if (cacheStylesheet == false) {
457:                    isValidStylesheet = false;
458:                    isValidParams = false;
459:                }
460:                this .cacheStylesheet = cacheStylesheet;
461:            }
462:
463:            //-- xslt extensions
464:            // TODO: move into separate class?
465:
466:            public static boolean exists(String file) {
467:                return new File(file).exists();
468:            }
469:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.