Source Code Cross Referenced for XSLTProcess.java in  » Build » ANT » org » apache » tools » ant » taskdefs » 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 » Build » ANT » org.apache.tools.ant.taskdefs 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         *
0017:         */
0018:
0019:        package org.apache.tools.ant.taskdefs;
0020:
0021:        import java.io.File;
0022:        import java.util.Enumeration;
0023:        import java.util.Iterator;
0024:        import java.util.Vector;
0025:        import org.apache.tools.ant.AntClassLoader;
0026:        import org.apache.tools.ant.BuildException;
0027:        import org.apache.tools.ant.DirectoryScanner;
0028:        import org.apache.tools.ant.DynamicConfigurator;
0029:        import org.apache.tools.ant.Project;
0030:        import org.apache.tools.ant.types.Mapper;
0031:        import org.apache.tools.ant.types.Path;
0032:        import org.apache.tools.ant.types.Reference;
0033:        import org.apache.tools.ant.types.Resource;
0034:        import org.apache.tools.ant.types.ResourceCollection;
0035:        import org.apache.tools.ant.types.XMLCatalog;
0036:        import org.apache.tools.ant.types.resources.FileResource;
0037:        import org.apache.tools.ant.types.resources.Resources;
0038:        import org.apache.tools.ant.types.resources.Union;
0039:        import org.apache.tools.ant.util.FileNameMapper;
0040:        import org.apache.tools.ant.util.FileUtils;
0041:
0042:        /**
0043:         * Processes a set of XML documents via XSLT. This is
0044:         * useful for building views of XML based documentation.
0045:         *
0046:         *
0047:         * @since Ant 1.1
0048:         *
0049:         * @ant.task name="xslt" category="xml"
0050:         */
0051:
0052:        public class XSLTProcess extends MatchingTask implements  XSLTLogger {
0053:            /** destination directory */
0054:            private File destDir = null;
0055:
0056:            /** where to find the source XML file, default is the project's basedir */
0057:            private File baseDir = null;
0058:
0059:            /** XSL stylesheet as a filename */
0060:            private String xslFile = null;
0061:
0062:            /** XSL stylesheet as a {@link org.apache.tools.ant.types.Resource} */
0063:            private Resource xslResource = null;
0064:
0065:            /** extension of the files produced by XSL processing */
0066:            private String targetExtension = ".html";
0067:
0068:            /** name for XSL parameter containing the filename */
0069:            private String fileNameParameter = null;
0070:
0071:            /** name for XSL parameter containing the file directory */
0072:            private String fileDirParameter = null;
0073:
0074:            /** additional parameters to be passed to the stylesheets */
0075:            private Vector params = new Vector();
0076:
0077:            /** Input XML document to be used */
0078:            private File inFile = null;
0079:
0080:            /** Output file */
0081:            private File outFile = null;
0082:
0083:            /** The name of the XSL processor to use */
0084:            private String processor;
0085:
0086:            /** Classpath to use when trying to load the XSL processor */
0087:            private Path classpath = null;
0088:
0089:            /** The Liason implementation to use to communicate with the XSL
0090:             *  processor */
0091:            private XSLTLiaison liaison;
0092:
0093:            /** Flag which indicates if the stylesheet has been loaded into
0094:             *  the processor */
0095:            private boolean stylesheetLoaded = false;
0096:
0097:            /** force output of target files even if they already exist */
0098:            private boolean force = false;
0099:
0100:            /** XSL output properties to be used */
0101:            private Vector outputProperties = new Vector();
0102:
0103:            /** for resolving entities such as dtds */
0104:            private XMLCatalog xmlCatalog = new XMLCatalog();
0105:
0106:            /** Name of the TRAX Liaison class */
0107:            private static final String TRAX_LIAISON_CLASS = "org.apache.tools.ant.taskdefs.optional.TraXLiaison";
0108:
0109:            /** Utilities used for file operations */
0110:            private static final FileUtils FILE_UTILS = FileUtils
0111:                    .getFileUtils();
0112:
0113:            /**
0114:             * Whether to style all files in the included directories as well.
0115:             *
0116:             * @since Ant 1.5
0117:             */
0118:            private boolean performDirectoryScan = true;
0119:
0120:            /**
0121:             * factory element for TraX processors only
0122:             * @since Ant 1.6
0123:             */
0124:            private Factory factory = null;
0125:
0126:            /**
0127:             * whether to reuse Transformer if transforming multiple files.
0128:             * @since 1.5.2
0129:             */
0130:            private boolean reuseLoadedStylesheet = true;
0131:
0132:            /**
0133:             * AntClassLoader for the nested <classpath> - if set.
0134:             *
0135:             * <p>We keep this here in order to reset the context classloader
0136:             * in execute.  We can't use liaison.getClass().getClassLoader()
0137:             * since the actual liaison class may have been loaded by a loader
0138:             * higher up (system classloader, for example).</p>
0139:             *
0140:             * @since Ant 1.6.2
0141:             */
0142:            private AntClassLoader loader = null;
0143:
0144:            /**
0145:             * Mapper to use when a set of files gets processed.
0146:             *
0147:             * @since Ant 1.6.2
0148:             */
0149:            private Mapper mapperElement = null;
0150:
0151:            /**
0152:             * Additional resource collections to process.
0153:             *
0154:             * @since Ant 1.7
0155:             */
0156:            private Union resources = new Union();
0157:
0158:            /**
0159:             * Whether to use the implicit fileset.
0160:             *
0161:             * @since Ant 1.7
0162:             */
0163:            private boolean useImplicitFileset = true;
0164:
0165:            /**
0166:             * The default processor is trax
0167:             * @since Ant 1.7
0168:             */
0169:            public static final String PROCESSOR_TRAX = "trax";
0170:
0171:            /**
0172:             * Creates a new XSLTProcess Task.
0173:             */
0174:            public XSLTProcess() {
0175:            } //-- XSLTProcess
0176:
0177:            /**
0178:             * Whether to style all files in the included directories as well;
0179:             * optional, default is true.
0180:             *
0181:             * @param b true if files in included directories are processed.
0182:             * @since Ant 1.5
0183:             */
0184:            public void setScanIncludedDirectories(boolean b) {
0185:                performDirectoryScan = b;
0186:            }
0187:
0188:            /**
0189:             * Controls whether the stylesheet is reloaded for every transform.
0190:             *
0191:             * <p>Setting this to true may get around a bug in certain
0192:             * Xalan-J versions, default is false.</p>
0193:             * @param b a <code>boolean</code> value
0194:             * @since Ant 1.5.2
0195:             */
0196:            public void setReloadStylesheet(boolean b) {
0197:                reuseLoadedStylesheet = !b;
0198:            }
0199:
0200:            /**
0201:             * Defines the mapper to map source to destination files.
0202:             * @param mapper the mapper to use
0203:             * @exception BuildException if more than one mapper is defined
0204:             * @since Ant 1.6.2
0205:             */
0206:            public void addMapper(Mapper mapper) {
0207:                if (mapperElement != null) {
0208:                    throw new BuildException(
0209:                            "Cannot define more than one mapper", getLocation());
0210:                }
0211:                mapperElement = mapper;
0212:            }
0213:
0214:            /**
0215:             * Adds a collection of resources to style in addition to the
0216:             * given file or the implicit fileset.
0217:             *
0218:             * @param rc the collection of resources to style
0219:             * @since Ant 1.7
0220:             */
0221:            public void add(ResourceCollection rc) {
0222:                resources.add(rc);
0223:            }
0224:
0225:            /**
0226:             * Add a nested &lt;style&gt; element.
0227:             * @param rc the configured Resources object represented as &lt;style&gt;.
0228:             * @since Ant 1.7
0229:             */
0230:            public void addConfiguredStyle(Resources rc) {
0231:                if (rc.size() != 1) {
0232:                    throw new BuildException(
0233:                            "The style element must be specified"
0234:                                    + " with exactly one nested resource.");
0235:                }
0236:                setXslResource((Resource) rc.iterator().next());
0237:            }
0238:
0239:            /**
0240:             * API method to set the XSL Resource.
0241:             * @param xslResource Resource to set as the stylesheet.
0242:             * @since Ant 1.7
0243:             */
0244:            public void setXslResource(Resource xslResource) {
0245:                this .xslResource = xslResource;
0246:            }
0247:
0248:            /**
0249:             * Adds a nested filenamemapper.
0250:             * @param fileNameMapper the mapper to add
0251:             * @exception BuildException if more than one mapper is defined
0252:             * @since Ant 1.7.0
0253:             */
0254:            public void add(FileNameMapper fileNameMapper)
0255:                    throws BuildException {
0256:                Mapper mapper = new Mapper(getProject());
0257:                mapper.add(fileNameMapper);
0258:                addMapper(mapper);
0259:            }
0260:
0261:            /**
0262:             * Executes the task.
0263:             *
0264:             * @exception BuildException if there is an execution problem.
0265:             * @todo validate that if either in or our is defined, then both are
0266:             */
0267:            public void execute() throws BuildException {
0268:                if ("style".equals(getTaskType())) {
0269:                    log(
0270:                            "Warning: the task name <style> is deprecated. Use <xslt> instead.",
0271:                            Project.MSG_WARN);
0272:                }
0273:
0274:                File savedBaseDir = baseDir;
0275:
0276:                DirectoryScanner scanner;
0277:                String[] list;
0278:                String[] dirs;
0279:
0280:                if (xslResource == null && xslFile == null) {
0281:                    throw new BuildException("specify the "
0282:                            + "stylesheet either as a filename in style "
0283:                            + "attribute or as a nested resource",
0284:                            getLocation());
0285:
0286:                }
0287:                if (xslResource != null && xslFile != null) {
0288:                    throw new BuildException("specify the "
0289:                            + "stylesheet either as a filename in style "
0290:                            + "attribute or as a nested resource but not "
0291:                            + "as both", getLocation());
0292:                }
0293:
0294:                if (inFile != null && !inFile.exists()) {
0295:                    throw new BuildException("input file " + inFile.toString()
0296:                            + " does not exist", getLocation());
0297:                }
0298:
0299:                try {
0300:                    if (baseDir == null) {
0301:                        baseDir = getProject().resolveFile(".");
0302:                    }
0303:
0304:                    liaison = getLiaison();
0305:
0306:                    // check if liaison wants to log errors using us as logger
0307:                    if (liaison instanceof  XSLTLoggerAware) {
0308:                        ((XSLTLoggerAware) liaison).setLogger(this );
0309:                    }
0310:
0311:                    log("Using " + liaison.getClass().toString(),
0312:                            Project.MSG_VERBOSE);
0313:
0314:                    if (xslFile != null) {
0315:                        // If we enter here, it means that the stylesheet is supplied
0316:                        // via style attribute
0317:                        File stylesheet = getProject().resolveFile(xslFile);
0318:                        if (!stylesheet.exists()) {
0319:                            stylesheet = FILE_UTILS.resolveFile(baseDir,
0320:                                    xslFile);
0321:                            /*
0322:                             * shouldn't throw out deprecation warnings before we know,
0323:                             * the wrong version has been used.
0324:                             */
0325:                            if (stylesheet.exists()) {
0326:                                log("DEPRECATED - the 'style' attribute should be relative "
0327:                                        + "to the project's");
0328:                                log("             basedir, not the tasks's basedir.");
0329:                            }
0330:                        }
0331:                        FileResource fr = new FileResource();
0332:                        fr.setProject(getProject());
0333:                        fr.setFile(stylesheet);
0334:                        xslResource = fr;
0335:                    }
0336:
0337:                    // if we have an in file and out then process them
0338:                    if (inFile != null && outFile != null) {
0339:                        process(inFile, outFile, xslResource);
0340:                        return;
0341:                    }
0342:
0343:                    /*
0344:                     * if we get here, in and out have not been specified, we are
0345:                     * in batch processing mode.
0346:                     */
0347:
0348:                    //-- make sure destination directory exists...
0349:                    checkDest();
0350:
0351:                    if (useImplicitFileset) {
0352:                        scanner = getDirectoryScanner(baseDir);
0353:                        log("Transforming into " + destDir, Project.MSG_INFO);
0354:
0355:                        // Process all the files marked for styling
0356:                        list = scanner.getIncludedFiles();
0357:                        for (int i = 0; i < list.length; ++i) {
0358:                            process(baseDir, list[i], destDir, xslResource);
0359:                        }
0360:                        if (performDirectoryScan) {
0361:                            // Process all the directories marked for styling
0362:                            dirs = scanner.getIncludedDirectories();
0363:                            for (int j = 0; j < dirs.length; ++j) {
0364:                                list = new File(baseDir, dirs[j]).list();
0365:                                for (int i = 0; i < list.length; ++i) {
0366:                                    process(baseDir, dirs[j] + File.separator
0367:                                            + list[i], destDir, xslResource);
0368:                                }
0369:                            }
0370:                        }
0371:                    } else { // only resource collections, there better be some
0372:                        if (resources.size() == 0) {
0373:                            throw new BuildException("no resources specified");
0374:                        }
0375:                    }
0376:                    processResources(xslResource);
0377:                } finally {
0378:                    if (loader != null) {
0379:                        loader.resetThreadContextLoader();
0380:                        loader.cleanup();
0381:                        loader = null;
0382:                    }
0383:                    liaison = null;
0384:                    stylesheetLoaded = false;
0385:                    baseDir = savedBaseDir;
0386:                }
0387:            }
0388:
0389:            /**
0390:             * Set whether to check dependencies, or always generate;
0391:             * optional, default is false.
0392:             *
0393:             * @param force true if always generate.
0394:             */
0395:            public void setForce(boolean force) {
0396:                this .force = force;
0397:            }
0398:
0399:            /**
0400:             * Set the base directory;
0401:             * optional, default is the project's basedir.
0402:             *
0403:             * @param dir the base directory
0404:             **/
0405:            public void setBasedir(File dir) {
0406:                baseDir = dir;
0407:            }
0408:
0409:            /**
0410:             * Set the destination directory into which the XSL result
0411:             * files should be copied to;
0412:             * required, unless <tt>in</tt> and <tt>out</tt> are
0413:             * specified.
0414:             * @param dir the name of the destination directory
0415:             **/
0416:            public void setDestdir(File dir) {
0417:                destDir = dir;
0418:            }
0419:
0420:            /**
0421:             * Set the desired file extension to be used for the target;
0422:             * optional, default is html.
0423:             * @param name the extension to use
0424:             **/
0425:            public void setExtension(String name) {
0426:                targetExtension = name;
0427:            }
0428:
0429:            /**
0430:             * Name of the stylesheet to use - given either relative
0431:             * to the project's basedir or as an absolute path; required.
0432:             *
0433:             * @param xslFile the stylesheet to use
0434:             */
0435:            public void setStyle(String xslFile) {
0436:                this .xslFile = xslFile;
0437:            }
0438:
0439:            /**
0440:             * Set the optional classpath to the XSL processor
0441:             *
0442:             * @param classpath the classpath to use when loading the XSL processor
0443:             */
0444:            public void setClasspath(Path classpath) {
0445:                createClasspath().append(classpath);
0446:            }
0447:
0448:            /**
0449:             * Set the optional classpath to the XSL processor
0450:             *
0451:             * @return a path instance to be configured by the Ant core.
0452:             */
0453:            public Path createClasspath() {
0454:                if (classpath == null) {
0455:                    classpath = new Path(getProject());
0456:                }
0457:                return classpath.createPath();
0458:            }
0459:
0460:            /**
0461:             * Set the reference to an optional classpath to the XSL processor
0462:             *
0463:             * @param r the id of the Ant path instance to act as the classpath
0464:             *          for loading the XSL processor
0465:             */
0466:            public void setClasspathRef(Reference r) {
0467:                createClasspath().setRefid(r);
0468:            }
0469:
0470:            /**
0471:             * Set the name of the XSL processor to use; optional, default trax.
0472:             * Other values are "xalan" for Xalan1
0473:             *
0474:             * @param processor the name of the XSL processor
0475:             */
0476:            public void setProcessor(String processor) {
0477:                this .processor = processor;
0478:            }
0479:
0480:            /**
0481:             * Whether to use the implicit fileset.
0482:             *
0483:             * <p>Set this to false if you want explicit control with nested
0484:             * resource collections.</p>
0485:             * @param useimplicitfileset set to true if you want to use implicit fileset
0486:             * @since Ant 1.7
0487:             */
0488:            public void setUseImplicitFileset(boolean useimplicitfileset) {
0489:                useImplicitFileset = useimplicitfileset;
0490:            }
0491:
0492:            /**
0493:             * Add the catalog to our internal catalog
0494:             *
0495:             * @param xmlCatalog the XMLCatalog instance to use to look up DTDs
0496:             */
0497:            public void addConfiguredXMLCatalog(XMLCatalog xmlCatalog) {
0498:                this .xmlCatalog.addConfiguredXMLCatalog(xmlCatalog);
0499:            }
0500:
0501:            /**
0502:             * Pass the filename of the current processed file as a xsl parameter
0503:             * to the transformation. This value sets the name of that xsl parameter.
0504:             *
0505:             * @param fileNameParameter name of the xsl parameter retrieving the
0506:             *                          current file name
0507:             */
0508:            public void setFileNameParameter(String fileNameParameter) {
0509:                this .fileNameParameter = fileNameParameter;
0510:            }
0511:
0512:            /**
0513:             * Pass the directory name of the current processed file as a xsl parameter
0514:             * to the transformation. This value sets the name of that xsl parameter.
0515:             *
0516:             * @param fileDirParameter name of the xsl parameter retrieving the
0517:             *                         current file directory
0518:             */
0519:            public void setFileDirParameter(String fileDirParameter) {
0520:                this .fileDirParameter = fileDirParameter;
0521:            }
0522:
0523:            /**
0524:             * Load processor here instead of in setProcessor - this will be
0525:             * called from within execute, so we have access to the latest
0526:             * classpath.
0527:             *
0528:             * @param proc the name of the processor to load.
0529:             * @exception Exception if the processor cannot be loaded.
0530:             */
0531:            private void resolveProcessor(String proc) throws Exception {
0532:                String classname;
0533:                if (proc.equals(PROCESSOR_TRAX)) {
0534:                    classname = TRAX_LIAISON_CLASS;
0535:                } else {
0536:                    //anything else is a classname
0537:                    classname = proc;
0538:                }
0539:                Class clazz = loadClass(classname);
0540:                liaison = (XSLTLiaison) clazz.newInstance();
0541:            }
0542:
0543:            /**
0544:             * Load named class either via the system classloader or a given
0545:             * custom classloader.
0546:             *
0547:             * As a side effect, the loader is set as the thread context classloader
0548:             * @param classname the name of the class to load.
0549:             * @return the requested class.
0550:             * @exception Exception if the class could not be loaded.
0551:             */
0552:            private Class loadClass(String classname) throws Exception {
0553:                if (classpath == null) {
0554:                    return Class.forName(classname);
0555:                } else {
0556:                    loader = getProject().createClassLoader(classpath);
0557:                    loader.setThreadContextLoader();
0558:                    Class c = Class.forName(classname, true, loader);
0559:                    return c;
0560:                }
0561:            }
0562:
0563:            /**
0564:             * Specifies the output name for the styled result from the
0565:             * <tt>in</tt> attribute; required if <tt>in</tt> is set
0566:             *
0567:             * @param outFile the output File instance.
0568:             */
0569:            public void setOut(File outFile) {
0570:                this .outFile = outFile;
0571:            }
0572:
0573:            /**
0574:             * specifies a single XML document to be styled. Should be used
0575:             * with the <tt>out</tt> attribute; ; required if <tt>out</tt> is set
0576:             *
0577:             * @param inFile the input file
0578:             */
0579:            public void setIn(File inFile) {
0580:                this .inFile = inFile;
0581:            }
0582:
0583:            /**
0584:             * Throws a BuildException if the destination directory hasn't
0585:             * been specified.
0586:             * @since Ant 1.7
0587:             */
0588:            private void checkDest() {
0589:                if (destDir == null) {
0590:                    String msg = "destdir attributes must be set!";
0591:                    throw new BuildException(msg);
0592:                }
0593:            }
0594:
0595:            /**
0596:             * Styles all existing resources.
0597:             *
0598:             * @since Ant 1.7
0599:             */
0600:            private void processResources(Resource stylesheet) {
0601:                Iterator iter = resources.iterator();
0602:                while (iter.hasNext()) {
0603:                    Resource r = (Resource) iter.next();
0604:                    if (!r.isExists()) {
0605:                        continue;
0606:                    }
0607:                    File base = baseDir;
0608:                    String name = r.getName();
0609:                    if (r instanceof  FileResource) {
0610:                        FileResource f = (FileResource) r;
0611:                        base = f.getBaseDir();
0612:                        if (base == null) {
0613:                            name = f.getFile().getAbsolutePath();
0614:                        }
0615:                    }
0616:                    process(base, name, destDir, stylesheet);
0617:                }
0618:            }
0619:
0620:            /**
0621:             * Processes the given input XML file and stores the result
0622:             * in the given resultFile.
0623:             *
0624:             * @param baseDir the base directory for resolving files.
0625:             * @param xmlFile the input file
0626:             * @param destDir the destination directory
0627:             * @param stylesheet the stylesheet to use.
0628:             * @exception BuildException if the processing fails.
0629:             */
0630:            private void process(File baseDir, String xmlFile, File destDir,
0631:                    Resource stylesheet) throws BuildException {
0632:
0633:                File outF = null;
0634:                File inF = null;
0635:
0636:                try {
0637:                    long styleSheetLastModified = stylesheet.getLastModified();
0638:                    inF = new File(baseDir, xmlFile);
0639:
0640:                    if (inF.isDirectory()) {
0641:                        log("Skipping " + inF + " it is a directory.",
0642:                                Project.MSG_VERBOSE);
0643:                        return;
0644:                    }
0645:
0646:                    FileNameMapper mapper = null;
0647:                    if (mapperElement != null) {
0648:                        mapper = mapperElement.getImplementation();
0649:                    } else {
0650:                        mapper = new StyleMapper();
0651:                    }
0652:
0653:                    String[] outFileName = mapper.mapFileName(xmlFile);
0654:                    if (outFileName == null || outFileName.length == 0) {
0655:                        log("Skipping " + inFile
0656:                                + " it cannot get mapped to output.",
0657:                                Project.MSG_VERBOSE);
0658:                        return;
0659:                    } else if (outFileName == null || outFileName.length > 1) {
0660:                        log("Skipping " + inFile + " its mapping is ambiguos.",
0661:                                Project.MSG_VERBOSE);
0662:                        return;
0663:                    }
0664:
0665:                    outF = new File(destDir, outFileName[0]);
0666:
0667:                    if (force || inF.lastModified() > outF.lastModified()
0668:                            || styleSheetLastModified > outF.lastModified()) {
0669:                        ensureDirectoryFor(outF);
0670:                        log("Processing " + inF + " to " + outF);
0671:
0672:                        configureLiaison(stylesheet);
0673:                        setLiaisonDynamicFileParameters(liaison, inF);
0674:                        liaison.transform(inF, outF);
0675:                    }
0676:                } catch (Exception ex) {
0677:                    // If failed to process document, must delete target document,
0678:                    // or it will not attempt to process it the second time
0679:                    log("Failed to process " + inFile, Project.MSG_INFO);
0680:                    if (outF != null) {
0681:                        outF.delete();
0682:                    }
0683:
0684:                    throw new BuildException(ex);
0685:                }
0686:
0687:            } //-- processXML
0688:
0689:            /**
0690:             * Process the input file to the output file with the given stylesheet.
0691:             *
0692:             * @param inFile the input file to process.
0693:             * @param outFile the destination file.
0694:             * @param stylesheet the stylesheet to use.
0695:             * @exception BuildException if the processing fails.
0696:             */
0697:            private void process(File inFile, File outFile, Resource stylesheet)
0698:                    throws BuildException {
0699:                try {
0700:                    long styleSheetLastModified = stylesheet.getLastModified();
0701:                    log(
0702:                            "In file " + inFile + " time: "
0703:                                    + inFile.lastModified(), Project.MSG_DEBUG);
0704:                    log("Out file " + outFile + " time: "
0705:                            + outFile.lastModified(), Project.MSG_DEBUG);
0706:                    log("Style file " + xslFile + " time: "
0707:                            + styleSheetLastModified, Project.MSG_DEBUG);
0708:                    if (force
0709:                            || inFile.lastModified() >= outFile.lastModified()
0710:                            || styleSheetLastModified >= outFile.lastModified()) {
0711:                        ensureDirectoryFor(outFile);
0712:                        log("Processing " + inFile + " to " + outFile,
0713:                                Project.MSG_INFO);
0714:                        configureLiaison(stylesheet);
0715:                        setLiaisonDynamicFileParameters(liaison, inFile);
0716:                        liaison.transform(inFile, outFile);
0717:                    } else {
0718:                        log("Skipping input file " + inFile
0719:                                + " because it is older than output file "
0720:                                + outFile + " and so is the stylesheet "
0721:                                + stylesheet, Project.MSG_DEBUG);
0722:                    }
0723:                } catch (Exception ex) {
0724:                    log("Failed to process " + inFile, Project.MSG_INFO);
0725:                    if (outFile != null) {
0726:                        outFile.delete();
0727:                    }
0728:                    throw new BuildException(ex);
0729:                }
0730:            }
0731:
0732:            /**
0733:             * Ensure the directory exists for a given file
0734:             *
0735:             * @param targetFile the file for which the directories are required.
0736:             * @exception BuildException if the directories cannot be created.
0737:             */
0738:            private void ensureDirectoryFor(File targetFile)
0739:                    throws BuildException {
0740:                File directory = targetFile.getParentFile();
0741:                if (!directory.exists()) {
0742:                    if (!directory.mkdirs()) {
0743:                        throw new BuildException("Unable to create directory: "
0744:                                + directory.getAbsolutePath());
0745:                    }
0746:                }
0747:            }
0748:
0749:            /**
0750:             * Get the factory instance configured for this processor
0751:             *
0752:             * @return the factory instance in use
0753:             */
0754:            public Factory getFactory() {
0755:                return factory;
0756:            }
0757:
0758:            /**
0759:             * Get the XML catalog containing entity definitions
0760:             *
0761:             * @return the XML catalog for the task.
0762:             */
0763:            public XMLCatalog getXMLCatalog() {
0764:                xmlCatalog.setProject(getProject());
0765:                return xmlCatalog;
0766:            }
0767:
0768:            /**
0769:             * Get an enumeration on the outputproperties.
0770:             * @return the outputproperties
0771:             */
0772:            public Enumeration getOutputProperties() {
0773:                return outputProperties.elements();
0774:            }
0775:
0776:            /**
0777:             * Get the Liason implementation to use in processing.
0778:             *
0779:             * @return an instance of the XSLTLiason interface.
0780:             */
0781:            protected XSLTLiaison getLiaison() {
0782:                // if processor wasn't specified, see if TraX is available.  If not,
0783:                // default it to xalan, depending on which is in the classpath
0784:                if (liaison == null) {
0785:                    if (processor != null) {
0786:                        try {
0787:                            resolveProcessor(processor);
0788:                        } catch (Exception e) {
0789:                            throw new BuildException(e);
0790:                        }
0791:                    } else {
0792:                        try {
0793:                            resolveProcessor(PROCESSOR_TRAX);
0794:                        } catch (Throwable e1) {
0795:                            e1.printStackTrace();
0796:                            throw new BuildException(e1);
0797:                        }
0798:                    }
0799:                }
0800:                return liaison;
0801:            }
0802:
0803:            /**
0804:             * Create an instance of an XSL parameter for configuration by Ant.
0805:             *
0806:             * @return an instance of the Param class to be configured.
0807:             */
0808:            public Param createParam() {
0809:                Param p = new Param();
0810:                params.addElement(p);
0811:                return p;
0812:            }
0813:
0814:            /**
0815:             * The Param inner class used to store XSL parameters
0816:             */
0817:            public static class Param {
0818:                /** The parameter name */
0819:                private String name = null;
0820:
0821:                /** The parameter's value */
0822:                private String expression = null;
0823:
0824:                private String ifProperty;
0825:                private String unlessProperty;
0826:                private Project project;
0827:
0828:                /**
0829:                 * Set the current project
0830:                 *
0831:                 * @param project the current project
0832:                 */
0833:                public void setProject(Project project) {
0834:                    this .project = project;
0835:                }
0836:
0837:                /**
0838:                 * Set the parameter name.
0839:                 *
0840:                 * @param name the name of the parameter.
0841:                 */
0842:                public void setName(String name) {
0843:                    this .name = name;
0844:                }
0845:
0846:                /**
0847:                 * The parameter value
0848:                 * NOTE : was intended to be an XSL expression.
0849:                 * @param expression the parameter's value.
0850:                 */
0851:                public void setExpression(String expression) {
0852:                    this .expression = expression;
0853:                }
0854:
0855:                /**
0856:                 * Get the parameter name
0857:                 *
0858:                 * @return the parameter name
0859:                 * @exception BuildException if the name is not set.
0860:                 */
0861:                public String getName() throws BuildException {
0862:                    if (name == null) {
0863:                        throw new BuildException("Name attribute is missing.");
0864:                    }
0865:                    return name;
0866:                }
0867:
0868:                /**
0869:                 * Get the parameter's value
0870:                 *
0871:                 * @return the parameter value
0872:                 * @exception BuildException if the value is not set.
0873:                 */
0874:                public String getExpression() throws BuildException {
0875:                    if (expression == null) {
0876:                        throw new BuildException(
0877:                                "Expression attribute is missing.");
0878:                    }
0879:                    return expression;
0880:                }
0881:
0882:                /**
0883:                 * Set whether this param should be used.  It will be
0884:                 * used if the property has been set, otherwise it won't.
0885:                 * @param ifProperty name of property
0886:                 */
0887:                public void setIf(String ifProperty) {
0888:                    this .ifProperty = ifProperty;
0889:                }
0890:
0891:                /**
0892:                 * Set whether this param should NOT be used. It
0893:                 * will not be used if the property has been set, otherwise it
0894:                 * will be used.
0895:                 * @param unlessProperty name of property
0896:                 */
0897:                public void setUnless(String unlessProperty) {
0898:                    this .unlessProperty = unlessProperty;
0899:                }
0900:
0901:                /**
0902:                 * Ensures that the param passes the conditions placed
0903:                 * on it with <code>if</code> and <code>unless</code> properties.
0904:                 * @return true if the task passes the "if" and "unless" parameters
0905:                 */
0906:                public boolean shouldUse() {
0907:                    if (ifProperty != null
0908:                            && project.getProperty(ifProperty) == null) {
0909:                        return false;
0910:                    } else if (unlessProperty != null
0911:                            && project.getProperty(unlessProperty) != null) {
0912:                        return false;
0913:                    }
0914:
0915:                    return true;
0916:                }
0917:            } // Param
0918:
0919:            /**
0920:             * Create an instance of an output property to be configured.
0921:             * @return the newly created output property.
0922:             * @since Ant 1.5
0923:             */
0924:            public OutputProperty createOutputProperty() {
0925:                OutputProperty p = new OutputProperty();
0926:                outputProperties.addElement(p);
0927:                return p;
0928:            }
0929:
0930:            /**
0931:             * Specify how the result tree should be output as specified
0932:             * in the <a href="http://www.w3.org/TR/xslt#output">
0933:             * specification</a>.
0934:             * @since Ant 1.5
0935:             */
0936:            public static class OutputProperty {
0937:                /** output property name */
0938:                private String name;
0939:
0940:                /** output property value */
0941:                private String value;
0942:
0943:                /**
0944:                 * @return the output property name.
0945:                 */
0946:                public String getName() {
0947:                    return name;
0948:                }
0949:
0950:                /**
0951:                 * set the name for this property
0952:                 * @param name A non-null String that specifies an
0953:                 * output property name, which may be namespace qualified.
0954:                 */
0955:                public void setName(String name) {
0956:                    this .name = name;
0957:                }
0958:
0959:                /**
0960:                 * @return the output property value.
0961:                 */
0962:                public String getValue() {
0963:                    return value;
0964:                }
0965:
0966:                /**
0967:                 * set the value for this property
0968:                 * @param value The non-null string value of the output property.
0969:                 */
0970:                public void setValue(String value) {
0971:                    this .value = value;
0972:                }
0973:            }
0974:
0975:            /**
0976:             * Initialize internal instance of XMLCatalog
0977:             * @throws BuildException on error
0978:             */
0979:            public void init() throws BuildException {
0980:                super .init();
0981:                xmlCatalog.setProject(getProject());
0982:            }
0983:
0984:            /**
0985:             * Loads the stylesheet and set xsl:param parameters.
0986:             *
0987:             * @param stylesheet the file from which to load the stylesheet.
0988:             * @exception BuildException if the stylesheet cannot be loaded.
0989:             * @deprecated since Ant 1.7
0990:             */
0991:            protected void configureLiaison(File stylesheet)
0992:                    throws BuildException {
0993:                FileResource fr = new FileResource();
0994:                fr.setProject(getProject());
0995:                fr.setFile(stylesheet);
0996:                configureLiaison(fr);
0997:            }
0998:
0999:            /**
1000:             * Loads the stylesheet and set xsl:param parameters.
1001:             *
1002:             * @param stylesheet the resource from which to load the stylesheet.
1003:             * @exception BuildException if the stylesheet cannot be loaded.
1004:             * @since Ant 1.7
1005:             */
1006:            protected void configureLiaison(Resource stylesheet)
1007:                    throws BuildException {
1008:                if (stylesheetLoaded && reuseLoadedStylesheet) {
1009:                    return;
1010:                }
1011:                stylesheetLoaded = true;
1012:
1013:                try {
1014:                    log("Loading stylesheet " + stylesheet, Project.MSG_INFO);
1015:                    // We call liason.configure() and then liaison.setStylesheet()
1016:                    // so that the internal variables of liaison can be set up
1017:                    if (liaison instanceof  XSLTLiaison2) {
1018:                        ((XSLTLiaison2) liaison).configure(this );
1019:                    }
1020:
1021:                    if (liaison instanceof  XSLTLiaison3) {
1022:                        // If we are here we can set the stylesheet as a
1023:                        // resource
1024:                        ((XSLTLiaison3) liaison).setStylesheet(stylesheet);
1025:                    } else {
1026:                        // If we are here we cannot set the stylesheet as
1027:                        // a resource, but we can set it as a file. So,
1028:                        // we make an attempt to get it as a file
1029:                        if (stylesheet instanceof  FileResource) {
1030:                            liaison.setStylesheet(((FileResource) stylesheet)
1031:                                    .getFile());
1032:                        } else {
1033:                            throw new BuildException(liaison.getClass()
1034:                                    .toString()
1035:                                    + " accepts the stylesheet only as a file",
1036:                                    getLocation());
1037:                        }
1038:                    }
1039:                    for (Enumeration e = params.elements(); e.hasMoreElements();) {
1040:                        Param p = (Param) e.nextElement();
1041:                        if (p.shouldUse()) {
1042:                            liaison.addParam(p.getName(), p.getExpression());
1043:                        }
1044:                    }
1045:                } catch (Exception ex) {
1046:                    log("Failed to transform using stylesheet " + stylesheet,
1047:                            Project.MSG_INFO);
1048:                    throw new BuildException(ex);
1049:                }
1050:            }
1051:
1052:            /**
1053:             * Sets file parameter(s) for directory and filename if the attribute
1054:             * 'filenameparameter' or 'filedirparameter' are set in the task.
1055:             *
1056:             * @param  liaison    to change parameters for
1057:             * @param  inFile     to get the additional file information from
1058:             * @throws Exception  if an exception occurs on filename lookup
1059:             *
1060:             * @since Ant 1.7
1061:             */
1062:            private void setLiaisonDynamicFileParameters(XSLTLiaison liaison,
1063:                    File inFile) throws Exception {
1064:                if (fileNameParameter != null) {
1065:                    liaison.addParam(fileNameParameter, inFile.getName());
1066:                }
1067:                if (fileDirParameter != null) {
1068:                    String fileName = FileUtils
1069:                            .getRelativePath(baseDir, inFile);
1070:                    File file = new File(fileName);
1071:                    // Give always a slash as file separator, so the stylesheet could be sure about that
1072:                    // Use '.' so a dir+"/"+name would not result in an absolute path
1073:                    liaison.addParam(fileDirParameter,
1074:                            (file.getParent() != null) ? file.getParent()
1075:                                    .replace('\\', '/') : ".");
1076:                }
1077:            }
1078:
1079:            /**
1080:             * Create the factory element to configure a trax liaison.
1081:             * @return the newly created factory element.
1082:             * @throws BuildException if the element is created more than one time.
1083:             */
1084:            public Factory createFactory() throws BuildException {
1085:                if (factory != null) {
1086:                    throw new BuildException("'factory' element must be unique");
1087:                }
1088:                factory = new Factory();
1089:                return factory;
1090:            }
1091:
1092:            /**
1093:             * The factory element to configure a transformer factory
1094:             * @since Ant 1.6
1095:             */
1096:            public static class Factory {
1097:
1098:                /** the factory class name to use for TraXLiaison */
1099:                private String name;
1100:
1101:                /**
1102:                 * the list of factory attributes to use for TraXLiaison
1103:                 */
1104:                private Vector attributes = new Vector();
1105:
1106:                /**
1107:                 * @return the name of the factory.
1108:                 */
1109:                public String getName() {
1110:                    return name;
1111:                }
1112:
1113:                /**
1114:                 * Set the name of the factory
1115:                 * @param name the name of the factory.
1116:                 */
1117:                public void setName(String name) {
1118:                    this .name = name;
1119:                }
1120:
1121:                /**
1122:                 * Create an instance of a factory attribute.
1123:                 * @param attr the newly created factory attribute
1124:                 */
1125:                public void addAttribute(Attribute attr) {
1126:                    attributes.addElement(attr);
1127:                }
1128:
1129:                /**
1130:                 * return the attribute elements.
1131:                 * @return the enumeration of attributes
1132:                 */
1133:                public Enumeration getAttributes() {
1134:                    return attributes.elements();
1135:                }
1136:
1137:                /**
1138:                 * A JAXP factory attribute. This is mostly processor specific, for
1139:                 * example for Xalan 2.3+, the following attributes could be set:
1140:                 * <ul>
1141:                 *  <li>http://xml.apache.org/xalan/features/optimize (true|false) </li>
1142:                 *  <li>http://xml.apache.org/xalan/features/incremental (true|false) </li>
1143:                 * </ul>
1144:                 */
1145:                public static class Attribute implements  DynamicConfigurator {
1146:
1147:                    /** attribute name, mostly processor specific */
1148:                    private String name;
1149:
1150:                    /** attribute value, often a boolean string */
1151:                    private Object value;
1152:
1153:                    /**
1154:                     * @return the attribute name.
1155:                     */
1156:                    public String getName() {
1157:                        return name;
1158:                    }
1159:
1160:                    /**
1161:                     * @return the output property value.
1162:                     */
1163:                    public Object getValue() {
1164:                        return value;
1165:                    }
1166:
1167:                    /**
1168:                     * Not used.
1169:                     * @param name not used
1170:                     * @return null
1171:                     * @throws BuildException never
1172:                     */
1173:                    public Object createDynamicElement(String name)
1174:                            throws BuildException {
1175:                        return null;
1176:                    }
1177:
1178:                    /**
1179:                     * Set an attribute.
1180:                     * Only "name" and "value" are supported as names.
1181:                     * @param name the name of the attribute
1182:                     * @param value the value of the attribute
1183:                     * @throws BuildException on error
1184:                     */
1185:                    public void setDynamicAttribute(String name, String value)
1186:                            throws BuildException {
1187:                        // only 'name' and 'value' exist.
1188:                        if ("name".equalsIgnoreCase(name)) {
1189:                            this .name = value;
1190:                        } else if ("value".equalsIgnoreCase(name)) {
1191:                            // a value must be of a given type
1192:                            // say boolean|integer|string that are mostly used.
1193:                            if ("true".equalsIgnoreCase(value)) {
1194:                                this .value = Boolean.TRUE;
1195:                            } else if ("false".equalsIgnoreCase(value)) {
1196:                                this .value = Boolean.FALSE;
1197:                            } else {
1198:                                try {
1199:                                    this .value = new Integer(value);
1200:                                } catch (NumberFormatException e) {
1201:                                    this .value = value;
1202:                                }
1203:                            }
1204:                        } else {
1205:                            throw new BuildException("Unsupported attribute: "
1206:                                    + name);
1207:                        }
1208:                    }
1209:                } // -- class Attribute
1210:
1211:            } // -- class Factory
1212:
1213:            /**
1214:             * Mapper implementation of the "traditional" way &lt;xslt&gt;
1215:             * mapped filenames.
1216:             *
1217:             * <p>If the file has an extension, chop it off.  Append whatever
1218:             * the user has specified as extension or ".html".</p>
1219:             *
1220:             * @since Ant 1.6.2
1221:             */
1222:            private class StyleMapper implements  FileNameMapper {
1223:                public void setFrom(String from) {
1224:                }
1225:
1226:                public void setTo(String to) {
1227:                }
1228:
1229:                public String[] mapFileName(String xmlFile) {
1230:                    int dotPos = xmlFile.lastIndexOf('.');
1231:                    if (dotPos > 0) {
1232:                        xmlFile = xmlFile.substring(0, dotPos);
1233:                    }
1234:                    return new String[] { xmlFile + targetExtension };
1235:                }
1236:            }
1237:
1238:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.