KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > taskdefs > GenerateSSIs


1 /*
2  * Copyright (C) 2003 Christian Cryder [christianc@granitepeaks.com]
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * $Id: GenerateSSIs.java,v 1.4 2004/02/01 05:16:32 christianc Exp $
19  */

20 package org.enhydra.barracuda.taskdefs;
21
22 import org.apache.tools.ant.*;
23 import org.apache.tools.ant.types.*;
24 import org.apache.tools.ant.util.*;
25
26 import java.io.*;
27 import java.util.*;
28
29 /**
30  * The purpose of this taskdef is to parse a source file (or fileset)
31  * and create ssi's from it. This is useful for the mockup process, when
32  * you want to edit your mockups in a single HTML file and then have
33  * pieces of it automatically written out to .ssi files.
34  *
35  * <p>The tags are valid HTML comments that follow a format that looks
36  * like this (where 'foo' can be the name of any ssi file):
37  *
38  * <p><!-- start foo.ssi -->
39  * <br>...
40  * <br><!-- end foo.ssi -->
41  *
42  * <p>When the taskdef sees these tags it will write the contents to the
43  * target ssi file IFF the source file is newer than the ssi file or
44  * force="true".
45  *
46  * <p>The taskdef also allows you to specify a touchpattern (defaults to *.shtml);
47  * if the taskdef writes ssi files in that directory, it will also update the
48  * timestamp on all the files in that directory that match the touch pattern. This
49  * is useful for causing XMLC to automatically recompile these files the next time
50  * you do a full build.
51  *
52  * @author <a HREF="mailto:christianc@granitepeaks.com">Christian Cryder</a>
53  */

54 public class GenerateSSIs extends Task {
55     protected File file = null; // the source file
56
protected List filesets = new ArrayList();
57
58     protected String JavaDoc touchpattern = "**/*.shtml";
59     protected boolean force = false;
60     protected int verbosity = Project.MSG_VERBOSE;
61
62     /**
63      * Sets a single source file to copy.
64      */

65     public void setFile(File file) {
66         this.file = file;
67     }
68
69     /**
70      * Specify a pattern of files to be touched if we end up rewriting
71      * any .ssi files (this defaults to *.shtml")
72      */

73     public void setTouchpattern(String JavaDoc touchPattern) {
74         this.touchpattern = touchPattern;
75     }
76
77     /**
78      * Force the regeneration of SSIs
79      */

80     public void setForce(boolean force) {
81         this.force = force;
82     }
83
84     /**
85      * Used to force listing of all names of copied files.
86      */

87     public void setVerbose(boolean verbose) {
88         if (verbose) {
89             this.verbosity = Project.MSG_INFO;
90         } else {
91             this.verbosity = Project.MSG_VERBOSE;
92         }
93     }
94
95     /**
96      * Adds a set of files (nested fileset attribute).
97      */

98     public void addFileset(FileSet set) {
99         filesets.add(set);
100     }
101
102     /**
103      * Performs the copy operation.
104      */

105     public void execute() throws BuildException {
106         // make sure we don't have an illegal set of options
107
validateAttributes();
108
109         List fileList = new ArrayList();
110
111         // deal with the single file
112
if (file!=null) {
113             if (file.exists()) {
114                 fileList.add(file);
115             } else {
116                 String JavaDoc message = "Could not find file "+file.getAbsolutePath()+" to generate ssi files from.";
117                 log(message);
118                 throw new BuildException(message);
119             }
120          // deal with the filesets
121
} else {
122             for (int i=0; i<filesets.size(); i++) {
123                 FileSet fs = (FileSet) filesets.get(i);
124                 DirectoryScanner ds = fs.getDirectoryScanner(this.getProject());
125                 File fromDir = fs.getDir(this.getProject());
126
127                 File baseDir = ds.getBasedir();
128                 String JavaDoc[] srcFiles = ds.getIncludedFiles();
129
130                 for (int j=0; j<srcFiles.length; j++) {
131                     fileList.add(new File(baseDir, srcFiles[j]));
132                 }
133             }
134         }
135
136         //now process our file list
137
processFiles(fileList);
138     }
139
140     /**
141      * Ensure we have a consistent and legal set of attributes, and set
142      * any internal flags necessary based on different combinations
143      * of attributes.
144      */

145     protected void validateAttributes() throws BuildException {
146         if (file==null && filesets.size()==0) {
147             throw new BuildException("Specify at least one source - a file or a fileset.");
148         }
149
150         if (file!=null && file.exists() && file.isDirectory()) {
151             throw new BuildException("Use a fileset to generate ssis on directories.");
152         }
153     }
154
155     /**
156      * process the list of qualified files. We will read each of these files
157      * looking for tags that indicate output should be redirected to a .ssi
158      * file. The tags are valid HTML comments that follow a format that looks
159      * like this:
160      *
161      * <p><!-- start foo.ssi -->
162      * <br>...
163      * <br><!-- end foo.ssi -->
164      */

165     protected void processFiles(List fileList) {
166         Iterator it = fileList.iterator();
167         int writeCnt = 0;
168         int touchCnt = 0;
169         Map touchedDirs = new HashMap();
170         while (it.hasNext()) {
171             File f = (File) it.next();
172             boolean notified = false;
173             log("Processing file: "+f, verbosity);
174
175             try {
176                 BufferedReader in = new BufferedReader(new FileReader(f));
177                 BufferedWriter out = null;
178                 String JavaDoc nextLine = null;
179                 String JavaDoc targetSSI = null;
180                 while (true) {
181                     nextLine=in.readLine();
182                     if (nextLine==null) {
183                         if (out!=null) {
184                             out.flush();
185                             out.close();
186                             out = null;
187                         }
188                         break;
189                     }
190
191                     //if out==null then we are in between tags...check for
192
//the starting flag
193
if (out==null) {
194                         //look for the start flag; if not present continue
195
int spos = nextLine.indexOf("<!-- start ");
196                         if (spos<0) continue;
197                         int epos = nextLine.indexOf(".ssi -->", spos);
198                         if (epos<0) continue;
199
200                         //get the target ssi name
201
targetSSI = nextLine.substring(spos+11, epos+4);
202 // log("Start tag for: "+targetSSI, verbosity);
203

204                         //look for the target ssi file
205
File ssi = new File(f.getParent(), targetSSI);
206                         if (force || !ssi.exists() || f.lastModified()>ssi.lastModified()) {
207                             if (!notified) {
208                                 log("File "+f+" has been modified...");
209                                 notified = true;
210                                 touchedDirs.put(f.getParent(), f.getParentFile());
211                             }
212                             log("...Writing "+ssi, verbosity);
213                             writeCnt++;
214                             out = new BufferedWriter(new FileWriter(ssi));
215 //csc_012804_1 - don't include the ssi comment id tag in the generated file
216
//csc_012804_1 out.write(nextLine.substring(spos));
217
out.write(nextLine.substring(epos+8)); //csc_012804_1
218
out.newLine();
219                         }
220
221                     //otherwise check for an ending flag and write the output
222
} else {
223                         //look for the end tag; if not present continue
224
String JavaDoc eflg = "<!-- end "+targetSSI+" -->";
225                         int spos = nextLine.indexOf(eflg);
226                         if (spos<0) {
227                             out.write(nextLine);
228                             out.newLine();
229                         } else {
230 // log("End tag for: "+targetSSI, verbosity);
231
//csc_012804_1 - don't include the ssi comment id tag in the generated file
232
//csc_012804_1 out.write(nextLine.substring(0, spos+eflg.length()));
233
out.write(nextLine.substring(0, spos)); //csc_012804_1
234
out.newLine();
235                             out.flush();
236                             out.close();
237                             out = null;
238                             continue;
239                         }
240                     }
241                 }
242                 in.close();
243
244             } catch (IOException e) {
245                 log("Unable to read file:"+f, Project.MSG_ERR);
246                 log("IOException "+e, Project.MSG_ERR);
247             }
248         }
249
250         //now touch all the appropriate files
251
if (touchpattern!=null && touchedDirs.size()>0) {
252             it = touchedDirs.values().iterator();
253             while (it.hasNext()) {
254                 File baseDir = (File) it.next();
255                 log("Touching "+baseDir+", pattern=\""+touchpattern+"\"");
256                 FileSet fs = new FileSet();
257                 fs.setDir(baseDir);
258                 fs.setIncludes(touchpattern);
259                 DirectoryScanner ds = fs.getDirectoryScanner(this.getProject());
260                 String JavaDoc[] touchFiles = ds.getIncludedFiles();
261                 long millis = System.currentTimeMillis();
262                 for (int j=0; j<touchFiles.length; j++) {
263                     File tf = new File(baseDir, touchFiles[j]);
264                     log("...Touching "+tf, verbosity);
265                     tf.setLastModified(millis);
266                     touchCnt++;
267                 }
268             }
269         }
270
271         //log it
272
if (writeCnt>0 || touchCnt>0) {
273             log("Created "+writeCnt+" .ssi files, touched "+touchCnt+" "+touchpattern+" files.");
274         }
275     }
276 }
277
Popular Tags