KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > util > DirectoryLister


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.util;
11
12 import java.io.File JavaDoc;
13 import java.util.Enumeration JavaDoc;
14 import java.util.StringTokenizer JavaDoc;
15 import java.util.Vector JavaDoc;
16
17 import org.mmbase.util.logging.Logger;
18 import org.mmbase.util.logging.Logging;
19
20 /**
21  * Directories contains methods for retrieving all file entries starting from a given path.
22  * It also goes down the directory tree in search for file entries.
23  * A wildcard can be used in searching for file entries.
24  * It also contains sort methods to sort file entries.
25  * Used by a device buidlers (i.e. Cameras), and by SCAN
26  * @application SCAN or Devices
27  * @author David V van Zeventer
28  * @version $Id: DirectoryLister.java,v 1.14 2005/08/31 11:46:55 nklasens Exp $
29  */

30 public class DirectoryLister {
31
32     // logger
33
private static Logger log = Logging.getLoggerInstance(DirectoryLister.class.getName());
34
35     /**
36      * Adds all elements from Vector v2 to Vector v1.
37      */

38     private Vector JavaDoc vectorJoin (Vector JavaDoc v1, Vector JavaDoc v2) {
39         for (Enumeration JavaDoc e = v2.elements (); e.hasMoreElements ();) {
40             v1.addElement (e.nextElement ());
41         }
42         return v1;
43     }
44
45     /**
46      * Creates a vector with all files in a specified directory. If the
47      * directory has sub-directories, these sub-directories are scanned
48      * recursively. Not just filenames are stored in the vector, but the
49      * complete pathnames.
50      */

51     private Vector JavaDoc _directory (String JavaDoc dir, String JavaDoc ext) {
52         Vector JavaDoc v = new Vector JavaDoc ();
53         File JavaDoc d = new File JavaDoc (dir); //Create a new fileobj for this directory
54
String JavaDoc [] files = d.list (); //List files and store in files array.
55
String JavaDoc path = null;
56
57         if(files==null) {
58             log.error("Cannot read in directory - "+dir);
59             return v;
60         }
61
62         for (int i = 0; i < files.length; i++) {
63             path = dir + File.separator + files[i]; //Build full pathname for this entry.
64
d = new File JavaDoc (path); //Assign new fileobject for this newly build path.
65

66             if ( !d.isDirectory() && files[i].endsWith(ext) ) { //fileobj d is not a directory
67
v.addElement(path); //AND has the right extension.
68
} else {
69                 if (d.isDirectory()) { //fileobj d is a directory.
70
vectorJoin (v, _directory (path, ext));
71                 }
72             }
73         }
74         return v;
75     }
76
77     /**
78      * Returns all filepaths that follow a certain pattern.
79      * @param args The requeststring to be used. This string consists of a directory,
80      * followed by an extension.
81      * @return a <code>vector</code> containing all filepaths requested.
82      */

83     public Vector JavaDoc getDirectories(String JavaDoc args) {
84         String JavaDoc methodname ="getDirectories";
85         Vector JavaDoc v = new Vector JavaDoc ();
86         String JavaDoc fileSpec=null;
87
88         log.debug(methodname+": Getting dirs using args: "+args);
89
90          StringTokenizer JavaDoc st = new StringTokenizer JavaDoc (args, ";");
91          while (st.hasMoreTokens ()) {
92
93             /* fileSpec is a string that consists of a directory, followed by a '*.',
94              * followed by an extension.
95              * i.e. /usr/lib/pclown/*.jokes
96              */

97              fileSpec = st.nextToken ();
98
99              /* In the HTML-file, the file-specification should have one of the following formats:
100               * 1. To list all the files in directory <dir>:
101               * /<dir>
102               * example: /data/import
103               * 2. To list files in directory <dir> ending with extension <ext>:
104               * /<dir>/*.<ext>
105               * example: /data/import/*.wav
106               */

107             File JavaDoc f = new File JavaDoc (fileSpec);
108             if (f.isDirectory ()) {
109                 vectorJoin (v, _directory (fileSpec, ""));
110             } else {
111                 // Ok, so the specified filename is not a directory,
112
// but a file specification with wildcards.
113
int li = fileSpec.lastIndexOf ('/');
114                 /* split fileSpec in it's parts, i.e.
115                  * dir = "/usr/lib/pclown"
116                  * file = "*.jokes"
117                  * ext = ".jokes"
118                  */

119                 String JavaDoc dir = fileSpec.substring (0, li);
120                 String JavaDoc file = fileSpec.substring (li + 1);
121                 String JavaDoc ext = file.substring (1);
122                 f = new File JavaDoc (dir);
123                     if (f.isDirectory ()) vectorJoin (v, _directory (dir, ext));
124                 }
125             }
126             return v;
127         }
128
129     /**
130      * Creates a Vector with File-objs by using the
131      * directories vector. Used by {#link #sortDirectoriesOnModTime}
132      */

133     private Vector JavaDoc createFilesVector(Vector JavaDoc directories) {
134         Vector JavaDoc filesvec = new Vector JavaDoc();
135         String JavaDoc filepathname=null;
136         File JavaDoc file=null;
137
138         Enumeration JavaDoc dirs_enum = directories.elements();
139         while (dirs_enum.hasMoreElements()) {
140             filepathname = (String JavaDoc)dirs_enum.nextElement();
141             file = new File JavaDoc(filepathname);
142             filesvec.addElement(file); //Add file to filesvec.
143
}
144         return filesvec;
145     }
146
147     /**
148      * Sorts a Vector containing file pathnames on modification time.
149      * @return a new sorted <code>Vector</code> containing filepathnames.
150      */

151     public Vector JavaDoc sortDirectoriesOnModTime(Vector JavaDoc directories) {
152         String JavaDoc methodname = "sortDirectoriesOnModTime";
153         CompareInterface filecmp = new FileCompare();
154         SortedVector sortedfilesvec = new SortedVector(filecmp); //Create new sortedvec.
155
Vector JavaDoc dirs_sorted= new Vector JavaDoc();
156         File JavaDoc file=null;
157
158         Vector JavaDoc filesvec = createFilesVector(directories); //Create filesvector.
159
log.debug(methodname+": filesvec= "+filesvec);
160
161         //Sort the filesvec on modification time.
162
Enumeration JavaDoc filesvec_enum = filesvec.elements(); //Enumerate all filesvec elements.
163
while (filesvec_enum.hasMoreElements()) {
164             sortedfilesvec.addSorted(filesvec_enum.nextElement()); //Add fileobj to sortedvec.
165
}
166         log.debug(methodname+": sortedfilesvec= "+sortedfilesvec);
167
168         Enumeration JavaDoc sortedfilesvec_enum = sortedfilesvec.elements();
169         while (sortedfilesvec_enum.hasMoreElements()) {
170             file = (File JavaDoc)sortedfilesvec_enum.nextElement();
171             dirs_sorted.addElement(file.getPath()); //Add filepathname to new sortedvec.
172
}
173         log.debug(methodname+": dirs_sorted = "+dirs_sorted);
174         return dirs_sorted;
175     }
176
177     /**
178      * Sort a Vector containing file pathnames using a comparefield argument.
179      * First creates XFile objs from vector.
180      * It then adds these objs to a SortedVector obj (sorted on comparefield)..
181      * @return a <code>Vector</code> with 2 items : filepath & moddate
182      */

183     public Vector JavaDoc sortDirectories(Vector JavaDoc directories, String JavaDoc comparefield) {
184
185         String JavaDoc methodname = "sortDirectories";
186         CompareInterface xfilecmp = new XFileCompare(comparefield); //Compare implementation that will be used, also specifying comparefield.
187
SortedVector sortedxfiles = new SortedVector(xfilecmp); //SortedVector containing xfileobjs.
188
Vector JavaDoc sorteddirs = new Vector JavaDoc(); //Sorted Vector containing the xfile fields stored as strings.
189
XFile xfile=null;
190         int modtime=0;
191         String JavaDoc filepath =null;
192
193         log.debug(methodname+": Sorting dirs using comparefield:"+comparefield);
194
195         Enumeration JavaDoc dirs_enum = directories.elements();
196         while (dirs_enum.hasMoreElements()) {
197             filepath = (String JavaDoc)dirs_enum.nextElement();
198             xfile = new XFile(filepath);
199             sortedxfiles.addSorted(xfile); //Add xfile obj to sortedxfilesvector.
200
}
201
202         Enumeration JavaDoc xfiles_enum = sortedxfiles.elements();
203         while (xfiles_enum.hasMoreElements()) { //Enumerate xfiles vector and create return vector.
204
xfile = (XFile)xfiles_enum.nextElement();
205             filepath = xfile.getFilePath();
206             //Get modtime field and subtract offset.
207
modtime = (int) ((xfile.getModTime()-DateSupport.getMilliOffset())/1000);
208             //Add filepath and modtime to sorteddirs vector
209
sorteddirs.addElement(filepath);
210             sorteddirs.addElement(time2DateAndTime_NoYear(modtime));
211         }
212
213         return sorteddirs;
214     }
215
216     /**
217      * This method creates a vector with 3 items:
218      * ITEM1=fileentry, ITEM2=moddate,
219      * ITEM3=previewfilename if exists else fileentry.
220      */

221      public Vector JavaDoc createThreeItems(Vector JavaDoc sorted,StringTagger tagger) {
222         String JavaDoc methodname = "createThreeItems";
223         Vector JavaDoc merged = new Vector JavaDoc();
224         String JavaDoc typefmt=null,previewfmt=null,path=null,indexsymbol=null;
225         Enumeration JavaDoc sort_enum=null;
226
227         log.debug(methodname+": Creating 3 items vector.");
228         typefmt = tagger.Value("TYPEFORMAT"); //eg. fullsize.#.jpg
229
previewfmt = tagger.Value("PREVIEWFORMAT"); //eg. fullsize-s.#.jpg
230
indexsymbol= tagger.Value("INDEXSYMBOL"); //eg. #
231

232         sort_enum = sorted.elements();
233         if(sort_enum.hasMoreElements()) {
234             //Retrieve path using a sorted entry.
235
path = (String JavaDoc)sort_enum.nextElement();
236             int lastSlash = path.lastIndexOf('/');
237             path = path.substring(0,lastSlash+1);
238
239             //Check parameters and create a 3 items vector.
240
if ((typefmt!=null)&&(previewfmt!=null)&&(indexsymbol!=null)) { //All params provided.
241
log.debug(methodname+": TYPEFMT="+typefmt+" PREVIEWFMT="+previewfmt+" INDEXSYMBOL="+indexsymbol+" PROVIDED ->Creating vector");
242
243                 typefmt =path+typefmt; //Add path to typefmt & previewfmt
244
previewfmt=path+previewfmt;
245
246                 sort_enum = sorted.elements(); //Find sorted entry & date
247
while (sort_enum.hasMoreElements()) {
248
249                     String JavaDoc sentry = (String JavaDoc) sort_enum.nextElement();
250
251                     //Check if the sorted entry equals the typeformat
252
if(checkEntryformat(indexsymbol,typefmt,sentry)) {
253                         merged.addElement(sentry); //ITEM1
254
String JavaDoc date = (String JavaDoc) sort_enum.nextElement();
255                         merged.addElement(date); //ITEM2
256

257                         //Create preview entry & check if exists in sorted vector.
258
String JavaDoc pentry = createPreviewEntry(indexsymbol,typefmt,previewfmt,sentry);
259                         if (sorted.contains(pentry)) {
260                             merged.addElement(pentry); //ITEM3
261
} else {
262                             merged.addElement(sentry); //ITEM3=ITEM1
263
}
264                     }else{ //sorted entry is other ->skip date
265
String JavaDoc skipdate=(String JavaDoc)sort_enum.nextElement(); //Skipping date
266
log.debug("skipping date " + skipdate);
267                     }
268                 }//while loop
269
} else if ((typefmt==null)&&(previewfmt==null)&&(indexsymbol==null)) { //All params empty.
270
log.debug(methodname+": TYPEFMT & PREVIEWFMT & INDEXSYMBOL EMPTY -> Creating std vector where ITEM3=ITEM1");
271
272                 sort_enum = sorted.elements();
273                 while (sort_enum.hasMoreElements()) { //Create std vector.
274
String JavaDoc sentry = (String JavaDoc) sort_enum.nextElement();
275                     merged.addElement(sentry); //ITEM1
276
String JavaDoc date = (String JavaDoc) sort_enum.nextElement();
277                     merged.addElement(date); //ITEM2
278
merged.addElement(sentry); //ITEM3=ITEM1
279
}
280             } else { //1 OR 2 params are empty.
281
log.debug(methodname+": Error typefmt="+typefmt+" previewfmt="+previewfmt+" indexsymbol="+indexsymbol+" ->Returning empty vector.");
282             }
283         }
284         return merged;
285     }
286
287     /**
288      * Checks if the entry is compatible with the type format.
289      */

290     private boolean checkEntryformat(String JavaDoc indexsymbol,String JavaDoc typefmt,String JavaDoc entry) {
291         boolean compatible=false;
292         int digits = 0;
293         int pos = typefmt.indexOf(indexsymbol);
294         String JavaDoc ls_typefmt = typefmt.substring(0,pos);
295         String JavaDoc ls_entry = entry.substring(0,pos);
296         if(ls_entry.equals(ls_typefmt)) { //Leftside compare
297
boolean checkHex = indexsymbol.equals("$");
298             while ( ((entry.charAt(pos+digits)>='0')&&(entry.charAt(pos+digits)<='9'))
299                 || ( checkHex
300                     && (((entry.charAt(pos+digits)>='a') && (entry.charAt(pos+digits)<='f'))
301                         || ((entry.charAt(pos+digits)>='A') && (entry.charAt(pos+digits)<='F'))))) {
302                 digits++; //Count digits in entry.
303
}
304             if (entry.charAt(pos+digits)==typefmt.charAt(pos+1)) {
305                 String JavaDoc rs_typefmt = typefmt.substring(pos+1);
306                 String JavaDoc rs_entry = entry.substring(pos+digits);
307                 if (rs_entry.equals(rs_typefmt)) { //Rightside compare
308
compatible=true;
309                 }
310             }
311         }
312         return compatible;
313     }
314
315     /**
316      * Creates preview entry from original entry by cutting out the file
317      * number and replacing the index symbol in previewfmt with this number.
318      * <br />
319      * Eg:entry = fullsize.36.jpg -> <br />
320      * previewentry = fullsize-s.36.jpg <br />
321      * previewfmt= fullsize-s.#.jpg
322      */

323     private String JavaDoc createPreviewEntry(String JavaDoc indexsymbol,String JavaDoc typefmt,String JavaDoc previewfmt,String JavaDoc entry) {
324         int digits=0;
325         int pos = typefmt.indexOf(indexsymbol);
326         while ((entry.charAt(pos+digits)>='0')&&(entry.charAt(pos+digits)<='9')) {
327             digits++;
328         }
329         String JavaDoc number = entry.substring(pos,pos+digits); //Cut out number eg. scan43.jpg ->43
330
StringObject pfmt = new StringObject(previewfmt);
331         String JavaDoc pentry = pfmt.replace(indexsymbol,number).toString();
332         return pentry;
333     }
334
335
336     /**
337      * Converts the integer timevalue to a String containing
338      * hours, minutes, seconds, monthday, month and year in that order.
339      */

340     private String JavaDoc time2DateAndTime(int time) {
341         return DateSupport.getTime(time)+" "+DateSupport.getMonthDay(time)+" "+DateStrings.DUTCH_DATESTRINGS.getShortMonth(DateSupport.getMonthInt(time))+" "+DateSupport.getYear(time);
342     }
343     /**
344      * Converts the integer timevalue to a String containing
345      * hours, minutes, seconds, monthday, month in that order.
346      */

347     private String JavaDoc time2DateAndTime_NoYear(int time) {
348         return DateSupport.getTime(time)+" "+DateSupport.getMonthDay(time)+" "+DateStrings.DUTCH_DATESTRINGS.getShortMonth(DateSupport.getMonthInt(time));
349     }
350
351
352     /**
353      * Reverses the elementorder in a vector.
354      */

355     public Vector JavaDoc reverse(Vector JavaDoc v) {
356
357         Vector JavaDoc rev = new Vector JavaDoc();
358         int index= 0;
359         int size = v.size();
360
361         for (int i=1;i<=size;i++) {
362             index = size - i; // index=size - offset
363
rev.addElement(v.elementAt(index));
364         }
365         return rev;
366     }
367
368     /**
369      * Reverses the elementorder in a vector, taking into consideration that
370      * the vector consists of sets of elements (items).
371      */

372     public Vector JavaDoc reverse(Vector JavaDoc v,int items) {
373
374         Vector JavaDoc rev = new Vector JavaDoc();
375         int index=0, sets=0;
376         int size = v.size();
377
378         if ((size%items!=0) || (items>size)) {
379             log.debug("Reverse: Incompatible pair: Vectorsize: "+size+" Itemsnumber: "+items+
380                       ", Returning old vector instead");
381             return v;
382         }
383
384         sets = size/items; // #sets of elements in vector, eg 12/3= 4 sets.
385

386         for (int i=1;i<=sets;i++) {
387             for (int item=0;item<items;item++) {
388                 index = size - i*items + item; // index=size - offset + itemnr
389
rev.addElement(v.elementAt(index));
390             }
391         }
392         return rev;
393     }
394 }
395
Popular Tags