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 configFilename, String 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 38 public void simpleInit(String targetDir) throws IOException 39 { String 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 55 public static boolean compare(DirectoryConfig a, DirectoryConfig b) 56 { 57 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 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 a_keys = a.subDirDefs.keys(); 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 return true; 113 } 114 115 122 public boolean belongsToSite(String filename) throws IOException 123 { 124 filename = prepareRelativeFilename(filename); 125 return ( matchFileName(filename) > 0 ); 126 } 127 128 135 public String getTargetDirectory(String filename) throws IOException 136 { 137 filename = prepareRelativeFilename(filename); 138 return getTargetDir(filename); 139 } 140 141 String prepareRelativeFilename(String filename) throws IOException 142 { 143 char psc = File.separatorChar; 144 if ( filename.startsWith("." + psc) ) return filename; 145 if ( (filename.length() > 0 && filename.charAt(0) == psc) 147 || (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 return "." + psc + filename; 153 } 154 155 String removeDoubleSeparators(String filename) 156 { 157 String res = filename; 158 char psc = File.separatorChar; 159 String 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 173 class DirectoryConfig 174 { 175 final static String COMMENT_TAG = "#"; 176 final static String DIRECTORY_OPEN_TAG = "<Directory *>"; 177 final static String DIRECTORY_CLOSE_TAG = "</Directory>"; 178 final static String INCLUDE_DIRECTORY_TAG = "IncludeDirectory *"; 179 final static String EXCLUDE_DIRECTORY_TAG = "ExcludeDirectory *"; 180 final static String INCLUDE_FILE_TAG = "IncludeFile *"; 181 final static String EXCLUDE_FILE_TAG = "ExcludeFile *"; 182 final static String TARGET_DIR_TAG = "TargetDir *"; 183 184 final static String NEWLINE = System.getProperty("line.separator"); 185 188 Hashtable subDirDefs = new Hashtable(); 189 String 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 line; 199 FileNameMatcher fnm = new FileNameMatcher(); 201 while ( (line = in.readLine()) != null ) 202 { 203 lineNumber++; 204 line = line.trim(); 206 if ( line.length() == 0 || line.startsWith(COMMENT_TAG) ) 208 { 209 continue; 210 } 211 String s = fnm.getMatchResult(DIRECTORY_OPEN_TAG, line, 0); 212 if ( s != null ) 214 { 215 DirectoryConfig dc = new DirectoryConfig(); 216 dc.init(in, lineNumber, true); 218 subDirDefs.put(removeQuotes(s), dc); 219 continue; 220 } 221 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 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 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 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 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 s = fnm.getMatchResult(TARGET_DIR_TAG, line, 0); 261 if ( s != null ) 262 { 263 targetDir = removeQuotes(s); 264 continue; 266 } 267 throw new IOException("Syntax error or unknown expression in line " + lineNumber + ":" + NEWLINE + line); 269 } 270 if ( !needCloseTag ) 273 { 274 fileRules.add(new IncludeRule(IncludeRule.INCLUDE, "*")); 275 dirRules.add(new IncludeRule(IncludeRule.INCLUDE, "*")); 276 } 277 } 278 279 285 String getTargetDir(String dirname) 286 { 287 String psc = File.separator; 289 String dir = dirname; 290 int i = dirname.indexOf(psc); 292 if ( i >= 0 ) 293 { 294 dir = dirname.substring(0, i); 295 String rest = dirname.substring(i + 1, dirname.length()); 296 DirectoryConfig dc = (DirectoryConfig)subDirDefs.get(dir); 298 if ( dc != null ) 299 { 300 String r = dc.getTargetDir(rest); 302 if ( r != null ) 303 { 304 return r; 306 } 307 } 308 } 309 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 330 int matchFileName(String filename) 331 { 332 String f = filename; 334 String psc = File.separator; 335 int i = f.indexOf(psc); 337 if ( i >= 0 ) 338 { 339 String dir = f.substring(0, i); 340 String rest = f.substring(i + 1, f.length()); 341 if ( evaluateRules(dirRules, dir) < 0 ) 343 { 344 return -1; 346 } 347 DirectoryConfig dc = (DirectoryConfig)subDirDefs.get(dir); 349 if ( dc != null && dc.matchFileName(rest) != 0 ) 350 { 351 return dc.matchFileName(rest); 352 } 353 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 i = evaluateRules(fileRules, f); 364 return i; 366 } 367 return 1; 368 } 369 370 int evaluateRules(Vector rules, String name) 371 { 372 int r = 0; 373 374 for ( int i = 0; i < rules.size(); i++) 376 { 377 IncludeRule rule = (IncludeRule)rules.get(i); 378 r = rule.evaluate(name); 380 if ( r != 0 ) 381 { 382 return r; 383 } 384 } 385 return r; 386 } 387 388 String removeQuotes(String 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 toString() 405 { 406 String 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 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 pattern; 444 static FileNameMatcher matcher = null; 445 446 IncludeRule(int type, String 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 name) 457 { 458 if ( matcher.matches(pattern, name) ) 459 { 460 return type; 461 } 462 return NO_MATCH; 463 } 464 465 public String toString() 466 { 467 return (type == INCLUDE ? "i " : "x ") + pattern; 468 } 469 470 public boolean equals(Object 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 |