001    /*
002    @license.text@
003     */
004    package biz.hammurapi.ant;
005    
006    import java.io.File;
007    import java.io.FileInputStream;
008    import java.util.ArrayList;
009    import java.util.Collection;
010    import java.util.Iterator;
011    
012    import org.apache.tools.ant.BuildException;
013    import org.apache.tools.ant.DirectoryScanner;
014    import org.apache.tools.ant.Task;
015    import org.apache.tools.ant.types.FileSet;
016    import org.w3c.dom.Document;
017    
018    import biz.hammurapi.xml.dom.DOMUtils;
019    
020    /**
021     * This task applies a stylesheet to XML files. Output file name is calculated from XPath expression.
022     * @author Pavel Vlasov
023     * @ant.task name="Style" category="Common"
024     * @revision $Revision$
025     */
026    public class StyleTask extends Task {
027    
028            private File outputDir;
029            
030            private String fileName;
031            
032            private Collection fileSets = new ArrayList();
033            
034            private File style;
035            
036            /**
037             * Output directory.
038             * @ant.required
039             * @param outputDir
040             */
041            public void setOutputDir(File outputDir) {
042                    this.outputDir = outputDir;
043            }
044            
045            /**
046             * XPath expression for file name. Use / for file separator.
047             * @ant.required
048             * @param fileName
049             */
050            public void setFileName(String fileName) {
051                    this.fileName = fileName;
052            }
053            
054            /**
055             * Adds file set
056             * @ant.not-required
057             * @param fileSet
058             */
059            public void addFileSet(FileSet fileSet) {
060                    fileSets.add(fileSet);
061            }
062            
063            /**
064             * Style
065             * @ant.required
066             * @param style
067             */
068            public void setStyle(File style) {
069                    this.style = style;
070            }
071            
072            public void execute() throws BuildException {
073                    try {
074                            Iterator it=fileSets.iterator();
075                            while (it.hasNext()) {
076                                    FileSet fs=(FileSet) it.next();
077                                    DirectoryScanner ds = fs.getDirectoryScanner(getProject());
078                                    String[] files=ds.getIncludedFiles();
079                                    for (int i=0; i<files.length; i++) {
080                                            File in = new File(ds.getBasedir(), files[i]);
081                                            Document doc = DOMUtils.parse(in);
082                                            
083                                            String fn = DOMUtils.eval(doc.getDocumentElement(), fileName).toString().replace('/', File.separatorChar);
084                                            File out = new File(outputDir, fn);
085                                            
086                                            File parentDir = out.getParentFile();
087                                            if (!parentDir.exists()) {
088                                                    if (!parentDir.mkdirs()) {
089                                                            throw new BuildException("Could not create directory: "+parentDir.getAbsolutePath());
090                                                    }
091                                            }
092                                            
093                                            DOMUtils.style(doc, out, new FileInputStream(style), null);
094                                    }
095                            }
096                    } catch (Exception e) {
097                            throw new BuildException(e);
098                    }
099            }
100            
101    }