KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > meshcms > util > DirectoryParser


1 /*
2  * MeshCMS - A simple CMS based on SiteMesh
3  * Copyright (C) 2004-2007 Luciano Vernaschi
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * You can contact the author at http://www.cromoteca.com
20  * and at info@cromoteca.com
21  */

22
23 package org.meshcms.util;
24
25 import java.io.*;
26 import java.util.*;
27
28 /**
29  * Base class to perform operations on the contents of a directory.
30  *
31  * <p>Override the method <code>preProcessDirectory</code>,
32  * <code>postProcessDirectory</code> and
33  * <code>processFile</code> to define the actions to be taken for files and
34  * directories included in the processed directory. You can also override
35  * <code>preProcess</code> and <code>postProcess</code> to do additional
36  * operations before and after the directory parsing.</p>
37  *
38  * <p>The directory to be parsed must be specified before starting by calling
39  * on of the <code>setInitialDir</code> methods. Then you can start the parsing
40  * by calling <code>process</code> or asinchronously by creating a new thread
41  * and starting it.</p>
42  *
43  * <p>Please note that this class is <em>not</em> recursive by default. You must
44  * call <code>setRecursive(true)</code> before processing if you want it to
45  * process directory contents too.</p>
46  *
47  * @author Luciano Vernaschi
48  */

49 public class DirectoryParser extends Thread JavaDoc {
50   protected File initialDir;
51
52   protected boolean recursive = false;
53   protected boolean processStartDir = false;
54   protected boolean processDirBeforeContent = true;
55
56   private Comparator comparator;
57
58   /**
59    * If true, directories will be processed recursively (default false).
60    *
61    * @param recursive it the directories will be processed recursively
62    */

63   public void setRecursive(boolean recursive) {
64     this.recursive = recursive;
65   }
66
67   /**
68    * If true, <code>processDirectory</code> will be called for the
69    * base directory too (default false).
70    *
71    * @param processStartDir if to process the base directory too.
72    *
73    * @see #processDirectory
74    */

75   public void setProcessStartDir(boolean processStartDir) {
76     this.processStartDir = processStartDir;
77   }
78
79   /**
80    * If true, <code>processDirectory</code> will be called
81    * for a directory before processing its contents (default true).
82    *
83    * @see #processDirectory
84    * @deprecated implement {@link #preProcessDirectory} or {@link #postProcessDirectory} accordingly
85    */

86   public void setProcessDirBeforeContent(boolean processDirBeforeContent) {
87     this.processDirBeforeContent = processDirBeforeContent;
88   }
89
90   /**
91    * @return whether directories will be processed recursively or not.
92    *
93    * @see #setRecursive
94    */

95   public boolean isRecursive() {
96     return recursive;
97   }
98
99   /**
100    * @return whether <code>processDirectory</code> will be called for the
101    * base directory too.
102    *
103    * @see #processDirectory
104    * @see #setProcessStartDir
105    */

106   public boolean isProcessStartDir() {
107     return processStartDir;
108   }
109
110   /**
111    * @return whether <code>processDirectory</code> will be called
112    * for a directory before processing its contents.
113    *
114    * @see #processDirectory
115    * @see #setProcessDirBeforeContent
116    *
117    * @deprecated implement {@link #preProcessDirectory} or {@link #postProcessDirectory} accordingly
118    */

119   public boolean isProcessDirBeforeContent() {
120     return processDirBeforeContent;
121   }
122
123   /**
124    * If true, files and directories will be sorted used a
125    * <code>FileNameComparator</code>.
126    *
127    * @see FileNameComparator
128    */

129   public void setSorted(boolean sorted) {
130     if (sorted) {
131       comparator = new FileNameComparator();
132     } else {
133       comparator = null;
134     }
135   }
136
137   /**
138    * @return whether files and directories will be sorted used a
139    * <code>FileNameComparator</code> or not.
140    *
141    * @see FileNameComparator
142    * @see #setSorted
143    */

144   public boolean isSorted() {
145     return comparator != null;
146   }
147
148   /**
149    * Sets the directory to be processed. An istance of <code>File</code> is
150    * created and {@link #setInitialDir(File)} is called.
151    *
152    * @param dir the file path as a <code>String</code>
153    */

154   public void setInitialDir(String JavaDoc dir) {
155     setInitialDir(Utils.isNullOrEmpty(dir) ? null : new File(dir));
156   }
157
158   /**
159    * Sets the directory to be processed.
160    *
161    * @param dir the directory path as a <code>File</code>
162    */

163   public void setInitialDir(File dir) {
164     initialDir = dir;
165   }
166
167   /**
168    * @return the directory to be processed.
169    */

170   public File getInitialDir() {
171     return initialDir;
172   }
173
174   /**
175    * Starts processing (in a separate thread if instantiated properly).
176    */

177   public void run() {
178     process();
179   }
180
181   /**
182    * Starts processing.
183    */

184   public void process() {
185     if (initialDir == null || !initialDir.exists()) {
186       return;
187     }
188
189     if (preProcess()) {
190       parse(initialDir, Path.ROOT);
191     }
192
193     postProcess();
194   }
195
196   private void parse(File file, Path path) {
197     if (file.isDirectory()) {
198       if (recursive || path.getElementCount() == 0) {
199         boolean ok = true;
200
201         if (mustProcessDir(path)) {
202           ok = preProcessDirectory(file, path);
203
204           // support deprecated processDirBeforeContent
205
if (processDirBeforeContent) {
206             ok &= processDirectory(file, path);
207           }
208         }
209
210         if (ok) {
211           File[] list = file.listFiles();
212
213           if (comparator != null) {
214             Arrays.sort(list, comparator);
215           }
216
217           for (int i = 0; i < list.length; i++) {
218             parse(list[i], path.add(list[i].getName()));
219           }
220         }
221       }
222
223       if (mustProcessDir(path)) {
224         postProcessDirectory(file, path);
225
226         // support deprecated processDirBeforeContent
227
if (!processDirBeforeContent) {
228           processDirectory(file, path);
229         }
230       }
231     } else if (file.isFile()) {
232       processFile(file, path);
233     }
234   }
235
236   private boolean mustProcessDir(Path path) {
237     return processStartDir || path.getElementCount() != 0;
238   }
239
240   /**
241    * This method is called during the process, but before any element has been
242    * processed. If it returns false, no processing will take place.
243    *
244    * <p>The base implementation does nothing and returns true.</p>
245    *
246    * @return always true
247    */

248   protected boolean preProcess() {
249     return true;
250   }
251
252   /**
253    * This method is called at the end of the processing. It is called even if
254    * {@link #preProcess} returned false.
255    *
256    * <p>The base implementation does nothing.</p>
257    */

258   protected void postProcess() {
259   }
260
261   /**
262    * This method will be called for any directory found while parsing the base
263    * directory. You can return false to block processing the contents of the
264    * directory (provided that {@link #isProcessDirBeforeContent} returns true,
265    * otherwise contents have been processed already).
266    *
267    * @param file the directory to be processed
268    * @param path the path of the directory (relative to the base directory)
269    *
270    * @return always true
271    *
272    * @deprecated use {@link #preProcessDirectory} and {@link #postProcessDirectory} instead
273    */

274   protected boolean processDirectory(File file, Path path) {
275     return true;
276   }
277
278   protected boolean preProcessDirectory(File file, Path path) {
279     return true;
280   }
281
282   protected void postProcessDirectory(File file, Path path) {
283   }
284
285   /**
286    * This method will be called for any file found while parsing the base
287    * directory.
288    *
289    * @param file the file to be processed
290    * @param path the path of the file (relative to the base directory)
291    */

292   protected void processFile(File file, Path path) {
293   }
294 }
295
Popular Tags