KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > webman > stager > SiteStructureConfigReader


1 package webman.stager;
2
3 import java.io.*;
4 import java.util.*;
5 import org.apache.log4j.Category;
6
7 public class SiteStructureConfigReader extends DirectoryConfig
8 {
9     boolean configRead = false;
10     static final Category CAT = Category.getInstance(SiteStructureConfigReader.class);
11     
12     public SiteStructureConfigReader(String JavaDoc configFilename, String JavaDoc targetDir) throws IOException
13     {
14         if ( configFilename != null )
15         {
16            init(new File(configFilename));
17         }
18         else
19         {
20             simpleInit(targetDir);
21         }
22     }
23
24     public SiteStructureConfigReader(File configfile) throws IOException
25     {
26         init(configfile);
27     }
28
29     /**
30      * simpleInit entspricht der Konfiguration
31      * <Directory ".">
32      * TargetDir "<targetDir>"
33      * IncludeDirectory "*"
34      * IncludeFile "*"
35      * </Directory>
36      *@param targetDir der Wert für TargetDir (also wohin die Site auf dem OnlineServer geschrieben wird)
37      */

38     public void simpleInit(String JavaDoc targetDir) throws IOException
39     { //das einfachste ist, genau eine solche Konfigurationsdatei zu simulieren.
40
String JavaDoc simpleConfig = "<Directory \".\">\nTargetDir \"" + targetDir + "\"\n";
41         simpleConfig += "IncludeDirectory \"*\"\nIncludeFile \"*\"\n</Directory>\n";
42         init(new BufferedReader(new StringReader(simpleConfig)), 0, false);
43     }
44     
45     public void init(File configfile) throws IOException
46     {
47         BufferedReader in = new BufferedReader(new FileReader(configfile));
48         init(in, 0, false);
49     }
50     
51     /**
52      * vergleicht sich mit einer anderen DirectoryConfig
53      * @return true bei inhaltlicher (bis auf jeweilige targetdirs) Übereinstimmung
54      */

55     public static boolean compare(DirectoryConfig a, DirectoryConfig b)
56     {
57         //Zuerst muss schon mal mindestens die Anzahl der jeweiligen Regeln stimmen!
58
CAT.debug("compare(): a.subDirDefs.size()=" + a.subDirDefs.size() + ", b.subDirDefs.size()=" + b.subDirDefs.size());
59         if ( a.subDirDefs.size() != b.subDirDefs.size() )
60         {
61             return false;
62         }
63         CAT.debug("compare(): a.dirRules.size()=" + a.dirRules.size() + ", b.dirRules.size()=" + b.dirRules.size());
64         if ( a.dirRules.size() != b.dirRules.size() )
65         {
66             return false;
67         }
68         CAT.debug("compare(): a.fileRules.size()=" + a.fileRules.size() + ", b.fileRules.size()=" + b.fileRules.size());
69         if ( a.fileRules.size() != b.fileRules.size() )
70         {
71             return false;
72         }
73         //Jetzt kommt der Einzelvergleich
74
CAT.debug("compare(): dirRules einzeln");
75         for ( int i=0; i<a.dirRules.size(); i++)
76         {
77             if ( !b.dirRules.contains(a.dirRules.elementAt(i)) )
78             {
79                 return false;
80             }
81         }
82         CAT.debug("compare(): fileRules einzeln");
83         for ( int i=0; i<a.fileRules.size(); i++)
84         {
85             if ( !b.fileRules.contains(a.fileRules.elementAt(i)) )
86             {
87                 return false;
88             }
89         }
90         Enumeration a_keys = a.subDirDefs.keys();
91         while ( a_keys.hasMoreElements() )
92         {
93             if ( !b.subDirDefs.containsKey(a_keys.nextElement()) )
94             {
95                 return false;
96             }
97         }
98         //jetzt rekursiv absteigen
99
a_keys = a.subDirDefs.keys(); //nochmal abfragen, weil ich wieder an den Anfang zurück muss
100
Enumeration b_keys = b.subDirDefs.keys();
101         CAT.debug("compare(): subDirDefs einzeln");
102         while ( a_keys.hasMoreElements() )
103         {
104             if ( !SiteStructureConfigReader.compare((DirectoryConfig)a.subDirDefs.get(a_keys.nextElement()),
105                                                     (DirectoryConfig)b.subDirDefs.get(b_keys.nextElement()))
106                )
107             {
108                 return false;
109             }
110         }
111         //wenn ich bis hierhin gekommen bin, ist alles ok.
112
return true;
113     }
114
115     /**
116      * "main" feature: belongs a file to the site?
117      * @param filename: name of file relative to webman-docroot
118      * e.g. ./documents/index.html or .\documents\index.html
119      * or documents/index.html or documents\index.html
120      * to check for directories, be sure to add a trailing file separator
121      */

122     public boolean belongsToSite(String JavaDoc filename) throws IOException
123     {
124         filename = prepareRelativeFilename(filename);
125         return ( matchFileName(filename) > 0 );
126     }
127
128     /**
129      * "main" feature: what is the target directory of a file
130      * works for file and directory names
131      * @param filename: name of file relative to webman-docroot
132      * e.g. ./documents/intern or .\documents\intern
133      * or documents/intern or documents\intern
134      */

135     public String JavaDoc getTargetDirectory(String JavaDoc filename) throws IOException
136     {
137         filename = prepareRelativeFilename(filename);
138         return getTargetDir(filename);
139     }
140
141     String JavaDoc prepareRelativeFilename(String JavaDoc filename) throws IOException
142     {
143         char psc = File.separatorChar;
144         if ( filename.startsWith("." + psc) ) return filename;
145         // testing /dirname or \dirname
146
if ( (filename.length() > 0 && filename.charAt(0) == psc)
147              // rejecting x:dirname
148
|| (filename.length() > 1 && filename.charAt(1) == ':')
149            ) throw new IOException("I told you not to use absolut file names with that method!");
150         filename = removeDoubleSeparators(filename);
151         // adding preceeding ./ for docroot - configuration
152
return "." + psc + filename;
153     }
154     
155     String JavaDoc removeDoubleSeparators(String JavaDoc filename)
156     {
157         String JavaDoc res = filename;
158         char psc = File.separatorChar;
159         String JavaDoc dpsc = "" + psc + psc;
160         int i;
161     
162         while ( (i = res.indexOf(dpsc)) >= 0 ) res = res.substring(0, i) + res.substring(i + 1, res.length());
163         return res;
164     }
165 }
166
167 /**
168  * tree implementation of config file
169  *
170  * @author $Author: torsten $
171  * @version $Revision: 1.13 $
172  */

173 class DirectoryConfig
174 {
175     final static String JavaDoc COMMENT_TAG = "#";
176     final static String JavaDoc DIRECTORY_OPEN_TAG = "<Directory *>";
177     final static String JavaDoc DIRECTORY_CLOSE_TAG = "</Directory>";
178     final static String JavaDoc INCLUDE_DIRECTORY_TAG = "IncludeDirectory *";
179     final static String JavaDoc EXCLUDE_DIRECTORY_TAG = "ExcludeDirectory *";
180     final static String JavaDoc INCLUDE_FILE_TAG = "IncludeFile *";
181     final static String JavaDoc EXCLUDE_FILE_TAG = "ExcludeFile *";
182     final static String JavaDoc TARGET_DIR_TAG = "TargetDir *";
183
184     final static String JavaDoc NEWLINE = System.getProperty("line.separator");
185     /**
186      * key is dirname:String value is config:DirectoryConfig
187      */

188     Hashtable subDirDefs = new Hashtable();
189     String JavaDoc targetDir = null;
190     Vector dirRules = new Vector();
191     Vector fileRules = new Vector();
192
193     DirectoryConfig(){}
194
195
196     void init(BufferedReader in, int lineNumber, boolean needCloseTag) throws IOException
197     {
198         String JavaDoc line;
199         //int startLine = lineNumber;
200
FileNameMatcher fnm = new FileNameMatcher();
201         while ( (line = in.readLine()) != null )
202         {
203             lineNumber++;
204             // remove whitespaces from both ends
205
line = line.trim();
206             // filtering out comment lines
207
if ( line.length() == 0 || line.startsWith(COMMENT_TAG) )
208             {
209                 continue;
210             }
211             String JavaDoc s = fnm.getMatchResult(DIRECTORY_OPEN_TAG, line, 0);
212             // starting subdir definition
213
if ( s != null )
214             {
215                 DirectoryConfig dc = new DirectoryConfig();
216                 //System.out.println("reading configuration for directory " + s + "<br>");
217
dc.init(in, lineNumber, true);
218                 subDirDefs.put(removeQuotes(s), dc);
219                 continue;
220             }
221             // ending subdir definition
222
if ( fnm.matches(DIRECTORY_CLOSE_TAG, line) )
223             {
224                 if ( !needCloseTag )
225                 {
226                     throw new IOException("no matching " + DIRECTORY_OPEN_TAG + " "
227                                                          + lineNumber + ":" + NEWLINE + line);
228                 }
229                     return;
230             }
231             // dir include rule
232
s = fnm.getMatchResult(INCLUDE_DIRECTORY_TAG, line, 0);
233             if ( s != null )
234             {
235                 dirRules.add(new IncludeRule(IncludeRule.INCLUDE, removeQuotes(s)));
236                 continue;
237             }
238             // dir exclude rule
239
s = fnm.getMatchResult(EXCLUDE_DIRECTORY_TAG, line, 0);
240             if ( s != null )
241             {
242                 dirRules.add(new IncludeRule(IncludeRule.EXCLUDE, removeQuotes(s)));
243                 continue;
244             }
245             // file include rule
246
s = fnm.getMatchResult(INCLUDE_FILE_TAG, line, 0);
247             if ( s != null )
248             {
249                 fileRules.add(new IncludeRule(IncludeRule.INCLUDE, removeQuotes(s)));
250                 continue;
251             }
252             // file exclude rule
253
s = fnm.getMatchResult(EXCLUDE_FILE_TAG, line, 0);
254             if ( s != null )
255             {
256                 fileRules.add(new IncludeRule(IncludeRule.EXCLUDE, removeQuotes(s)));
257                 continue;
258             }
259             // target dir tag
260
s = fnm.getMatchResult(TARGET_DIR_TAG, line, 0);
261             if ( s != null )
262             {
263                 targetDir = removeQuotes(s);
264                 //System.out.println("setting target dir to " + s + "<br>");
265
continue;
266             }
267             // Unknown Tag - throw Exception
268
throw new IOException("Syntax error or unknown expression in line " + lineNumber + ":" + NEWLINE + line);
269         }
270         // test if directory block is closed
271
// append default rules in upper most directory
272
if ( !needCloseTag )
273         {
274             fileRules.add(new IncludeRule(IncludeRule.INCLUDE, "*"));
275             dirRules.add(new IncludeRule(IncludeRule.INCLUDE, "*"));
276         }
277     }
278
279     /**
280      * @returns the target directory on the online server
281      * for the given directory of the editorial server or
282      * null if there's no matching configuration expression for that directory
283      * doesn't consider if that directory belongs to the site
284      */

285     String JavaDoc getTargetDir(String JavaDoc dirname)
286     {
287         //System.out.println("looking for target definition of " + dirname + "<br>");
288
String JavaDoc psc = File.separator;
289         String JavaDoc dir = dirname;
290         // if there's a matching sub dir definition, look there first
291
int i = dirname.indexOf(psc);
292         if ( i >= 0 )
293         {
294             dir = dirname.substring(0, i);
295             String JavaDoc rest = dirname.substring(i + 1, dirname.length());
296             // look in subdir config
297
DirectoryConfig dc = (DirectoryConfig)subDirDefs.get(dir);
298             if ( dc != null )
299             {
300                 //System.out.println("found sub dir definition for " + dir + "<br>");
301
String JavaDoc r = dc.getTargetDir(rest);
302                 if ( r != null )
303                 {
304                     //System.out.println("returning target definition for " + dirname + " (" + r + ")<br>");
305
return r;
306                 }
307             }
308         }
309         // return local pattern + dirname
310
//System.out.println("returning local target definition of " + dir + " (" + targetDir + ")<br>");
311
if ( targetDir != null )
312         {
313             if ( targetDir.endsWith(psc) )
314             {
315                 return targetDir + dirname;
316             }
317             else
318             {
319                 return targetDir + psc + dirname;
320             }
321         }
322         return null;
323     }
324
325     /**
326      * returns +1 if the file belongs to the site
327      * returns -1 if the file belongs not to the site
328      * returns 0 else
329      */

330     int matchFileName(String JavaDoc filename)
331     {
332         //System.out.println("evaluating rules for " + filename + "<br>");
333
String JavaDoc f = filename;
334         String JavaDoc psc = File.separator;
335         // if the file is in a sub dir, look there first
336
int i = f.indexOf(psc);
337         if ( i >= 0 )
338         {
339             String JavaDoc dir = f.substring(0, i);
340             String JavaDoc rest = f.substring(i + 1, f.length());
341             // evaluate directory rules
342
if ( evaluateRules(dirRules, dir) < 0 )
343             {
344                 //System.out.println("found exclude rule for directory " + dir + "<br>");
345
return -1;
346             }
347             // look in subdir config
348
DirectoryConfig dc = (DirectoryConfig)subDirDefs.get(dir);
349             if ( dc != null && dc.matchFileName(rest) != 0 )
350             {
351                 return dc.matchFileName(rest);
352             }
353             // extract pure filename
354
i = f.lastIndexOf(psc);
355             if ( i > -1 )
356             {
357                 f = f.substring(i + 1, f.length());
358             }
359         }
360         if ( f.length() > 0 )
361         {
362             // evaluate local file rules
363
i = evaluateRules(fileRules, f);
364             //if ( i < 0 ) System.out.println("found exclude rule for file " + f + "<br>");
365
return i;
366         }
367         return 1;
368     }
369
370     int evaluateRules(Vector rules, String JavaDoc name)
371     {
372         int r = 0;
373         
374         //System.out.println("name: " + name);
375
for ( int i = 0; i < rules.size(); i++)
376         {
377             IncludeRule rule = (IncludeRule)rules.get(i);
378             //System.out.println("rule: " + rule + " --> " + rule.evaluate(name));
379
r = rule.evaluate(name);
380             if ( r != 0 )
381             {
382                 return r;
383             }
384         }
385         return r;
386     }
387
388     String JavaDoc removeQuotes(String JavaDoc text)
389     {
390         text = text.trim();
391         int s = 0;
392         int e = text.length();
393         if ( text.charAt(s) == '"' || text.charAt(s) == '\'')
394         {
395             s++;
396         }
397         if ( text.charAt(e-1) == '"' || text.charAt(e-1) == '\'' )
398         {
399             e--;
400         }
401         return text.substring(s, e);
402     }
403
404     public String JavaDoc toString()
405     {
406         String JavaDoc res = "DirectoryConfig(TargetDir:" + targetDir + ", DirectoryNameRules(";
407     
408         for ( int i = 0; i < dirRules.size(); i++ )
409         {
410             res += dirRules.get(i) + ", ";
411         }
412         res = res.substring(0, res.length() - 2) + ")" + ", FileNameRules(";
413         for ( int i = 0; i < fileRules.size(); i++ )
414         {
415             res += fileRules.get(i) + ", ";
416         }
417         res = res.substring(0, res.length() - 2) + ")" + ", SubDirs(";
418         if ( subDirDefs.size() == 0 )
419         {
420             res += ")";
421         }
422         else
423         {
424             Enumeration keys = subDirDefs.keys();
425             while (keys.hasMoreElements())
426             {
427                 Object JavaDoc key = keys.nextElement();
428                 res += key + ":" + subDirDefs.get(key) + ", ";
429             }
430             res = res.substring(0, res.length() - 2);
431         }
432         return res + "))";
433     }
434 }
435
436 class IncludeRule
437 {
438     final static int INCLUDE = 1;
439     final static int EXCLUDE = -1;
440     final static int NO_MATCH = 0;
441     
442     int type;
443     String JavaDoc pattern;
444     static FileNameMatcher matcher = null;
445
446     IncludeRule(int type, String JavaDoc pattern)
447     {
448         this.type = type;
449         this.pattern = pattern;
450         if ( matcher == null )
451         {
452             matcher = new FileNameMatcher();
453         }
454     }
455
456     public int evaluate(String JavaDoc name)
457     {
458         if ( matcher.matches(pattern, name) )
459         {
460             return type;
461         }
462         return NO_MATCH;
463     }
464     
465     public String JavaDoc toString()
466     {
467         return (type == INCLUDE ? "i " : "x ") + pattern;
468     }
469     
470     public boolean equals(Object JavaDoc i)
471     {
472         if ( i == null || i.getClass() != getClass() )
473         {
474             return false;
475         }
476         return (((IncludeRule)i).type == type) && pattern.equals(((IncludeRule)i).pattern);
477     }
478     
479     public int hashCode()
480     {
481         return super.hashCode();
482     }
483 }
Popular Tags