1 16 17 package org.apache.naming.modules.fs; 18 19 import java.io.File ; 20 import java.io.FileOutputStream ; 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.util.Arrays ; 24 import java.util.Hashtable ; 25 import java.util.Vector ; 26 27 import javax.naming.Name ; 28 import javax.naming.NameAlreadyBoundException ; 29 import javax.naming.NamingEnumeration ; 30 import javax.naming.NamingException ; 31 import javax.naming.directory.Attributes ; 32 import javax.naming.directory.DirContext ; 33 34 import org.apache.naming.core.BaseDirContext; 35 import org.apache.naming.core.NamingContextEnumeration; 36 import org.apache.naming.core.NamingEntry; 37 import org.apache.tomcat.util.res.StringManager; 38 39 56 public class FileDirContext extends BaseDirContext { 57 58 private static org.apache.commons.logging.Log log= 59 org.apache.commons.logging.LogFactory.getLog( FileDirContext.class ); 60 61 63 protected StringManager sm = 64 StringManager.getManager("org.apache.naming.res"); 65 66 protected static final int BUFFER_SIZE = 2048; 67 68 70 71 74 public FileDirContext() { 75 super(); 76 } 77 78 79 82 public FileDirContext(Hashtable env) { 83 super(env); 84 } 85 86 87 89 90 93 protected File base = null; 94 95 96 99 protected String absoluteBase = null; 100 101 102 105 protected boolean caseSensitive = true; 106 107 108 111 protected String docBase = null; 112 113 115 116 126 public void setDocBase(String docBase) { 127 128 if (docBase == null) 130 throw new IllegalArgumentException 131 (sm.getString("resources.null")); 132 133 base = new File (docBase); 135 try { 136 base = base.getCanonicalFile(); 137 } catch (IOException e) { 138 } 140 141 if (!base.exists() || !base.isDirectory() || !base.canRead()) 143 throw new IllegalArgumentException 144 (sm.getString("fileResources.base", docBase)); 145 this.absoluteBase = base.getAbsolutePath(); 146 147 this.docBase = docBase; 149 150 } 151 152 155 public String getDocBase() { 156 return (this.docBase); 157 } 158 159 160 163 public void setCaseSensitive(boolean caseSensitive) { 164 this.caseSensitive = caseSensitive; 165 } 166 167 168 171 public boolean isCaseSensitive() { 172 return caseSensitive; 173 } 174 175 176 178 179 182 public void release() { 183 caseSensitive = true; 184 absoluteBase = null; 185 base = null; 186 super.release(); 187 } 188 189 public void setAttribute( String name, Object v ) { 190 new Throwable ().printStackTrace(); 191 if (log.isDebugEnabled()) 192 log.debug(name + " " + v ); 193 } 194 195 197 205 public Object lookup(Name nameObj, boolean resolveLinkx) 206 throws NamingException 207 { 208 if( log.isDebugEnabled() ) { 209 log.debug( "lookup " + nameObj ); 210 log.debug( nameObj.get(0)); 211 } 212 if( "fs:".equals( nameObj.get(0).toString() )) 213 nameObj=nameObj.getSuffix(1); 214 215 String name=nameObj.toString(); 217 Object result = null; 218 File file = file(name); 219 220 if (file == null) 221 throw new NamingException 222 (sm.getString("resources.notFound", name)); 223 224 if (file.isDirectory()) { 225 FileDirContext tempContext = new FileDirContext(env); 226 tempContext.setDocBase(file.getPath()); 227 result = tempContext; 228 } else { 229 result = file; } 234 235 return result; 236 } 237 238 239 253 public void unbind(Name nameObj) 254 throws NamingException 255 { 256 if( "fs:".equals( nameObj.get(0).toString() )) 257 nameObj=nameObj.getSuffix(1); 258 String name=nameObj.toString(); 259 if( log.isDebugEnabled() ) log.debug( "unbind " + name ); 260 File file = file(name); 261 262 if (file == null) 263 throw new NamingException 264 (sm.getString("resources.notFound", name)); 265 266 if (!file.delete()) 267 throw new NamingException 268 (sm.getString("resources.unbindFailed", name)); 269 270 } 271 272 273 284 public void rename(Name oldNameO, Name newNameO) 285 throws NamingException 286 { 287 String oldName=oldNameO.toString(); 288 String newName=newNameO.toString(); 289 File file = file(oldName); 290 291 if (file == null) 292 throw new NamingException 293 (sm.getString("resources.notFound", oldName)); 294 295 File newFile = new File (base, newName); 296 297 file.renameTo(newFile); 298 } 299 300 301 314 public NamingEnumeration list(Name nameN) 315 throws NamingException 316 { 317 String name=nameN.toString(); 318 if( log.isDebugEnabled() ) log.debug( "list " + name ); 319 File file = file(name); 320 321 if (file == null) 322 throw new NamingException 323 (sm.getString("resources.notFound", name)); 324 325 Vector entries = list(file); 326 327 return new NamingContextEnumeration(entries.elements(), this, false); 328 329 } 330 331 332 345 public NamingEnumeration listBindings(Name nameN) 346 throws NamingException 347 { 348 String name=nameN.toString(); 349 if( log.isDebugEnabled() ) log.debug( "listBindings " + name ); 350 351 File file = file(name); 352 353 if (file == null) 354 throw new NamingException 355 (sm.getString("resources.notFound", name)); 356 357 Vector entries = list(file); 358 359 return new NamingContextEnumeration(entries.elements(), this, true); 360 361 } 362 363 364 389 public void destroySubcontext(Name name) 390 throws NamingException 391 { 392 unbind(name); 393 } 394 395 396 413 public String getNameInNamespace() 414 throws NamingException { 415 return docBase; 416 } 417 418 419 421 422 434 public Attributes getAttributes(Name nameN, String [] attrIds) 435 throws NamingException 436 { 437 String name=nameN.toString(); 438 if( log.isDebugEnabled() ) log.debug( "getAttributes " + name ); 439 440 File file = file(name); 442 443 if (file == null) 444 throw new NamingException 445 (sm.getString("resources.notFound", name)); 446 447 return new FileAttributes(file); 448 449 } 450 451 466 public void bind(Name nameN, Object obj, Attributes attrs) 467 throws NamingException { 468 469 String name=nameN.toString(); 470 472 File file = new File (base, name); 473 if (file.exists()) 474 throw new NameAlreadyBoundException 475 (sm.getString("resources.alreadyBound", name)); 476 477 rebind(name, obj, attrs); 478 } 479 480 481 499 public void rebind(Name nameN, Object obj, Attributes attrs) 500 throws NamingException { 501 String name=nameN.toString(); 502 503 506 File file = new File (base, name); 507 508 InputStream is = null; 509 516 if (obj instanceof InputStream ) { 518 is = (InputStream ) obj; 519 } else if (obj instanceof DirContext ) { 520 if (file.exists()) { 521 if (!file.delete()) 522 throw new NamingException 523 (sm.getString("resources.bindFailed", name)); 524 } 525 if (!file.mkdir()) 526 throw new NamingException 527 (sm.getString("resources.bindFailed", name)); 528 } 529 if (is == null) 530 throw new NamingException 531 (sm.getString("resources.bindFailed", name)); 532 533 535 try { 536 FileOutputStream os = null; 537 byte buffer[] = new byte[BUFFER_SIZE]; 538 int len = -1; 539 try { 540 os = new FileOutputStream (file); 541 while (true) { 542 len = is.read(buffer); 543 if (len == -1) 544 break; 545 os.write(buffer, 0, len); 546 } 547 } finally { 548 if (os != null) 549 os.close(); 550 is.close(); 551 } 552 } catch (IOException e) { 553 throw new NamingException 554 (sm.getString("resources.bindFailed", e)); 555 } 556 } 557 558 559 576 public DirContext createSubcontext(Name nameN, Attributes attrs) 577 throws NamingException 578 { 579 String name=nameN.toString(); 580 File file = new File (base, name); 581 if (file.exists()) 582 throw new NameAlreadyBoundException 583 (sm.getString("resources.alreadyBound", name)); 584 if (!file.mkdir()) 585 throw new NamingException 586 (sm.getString("resources.bindFailed", name)); 587 return (DirContext ) lookup(name); 588 } 589 590 592 593 602 protected String normalize(String path) { 603 604 String normalized = path; 605 606 if (normalized.indexOf('\\') >= 0) 608 normalized = normalized.replace('\\', '/'); 609 if (!normalized.startsWith("/")) 610 normalized = "/" + normalized; 611 612 while (true) { 614 int index = normalized.indexOf("//"); 615 if (index < 0) 616 break; 617 normalized = normalized.substring(0, index) + 618 normalized.substring(index + 1); 619 } 620 621 while (true) { 623 int index = normalized.indexOf("/./"); 624 if (index < 0) 625 break; 626 normalized = normalized.substring(0, index) + 627 normalized.substring(index + 2); 628 } 629 630 while (true) { 632 int index = normalized.indexOf("/../"); 633 if (index < 0) 634 break; 635 if (index == 0) 636 return (null); int index2 = normalized.lastIndexOf('/', index - 1); 638 normalized = normalized.substring(0, index2) + 639 normalized.substring(index + 3); 640 } 641 642 return (normalized); 644 645 } 646 647 648 655 protected File file(String name) { 656 657 File file = new File (base, name); 658 if (file.exists() && file.canRead()) { 659 660 String canPath = null; 662 try { 663 canPath = file.getCanonicalPath(); 664 } catch (IOException e) { 665 } 666 if (canPath == null) 667 return null; 668 669 if (!canPath.startsWith(absoluteBase)) { 670 return null; 671 } 672 673 if ((caseSensitive) && (File.separatorChar == '\\')) { 675 String fileAbsPath = file.getAbsolutePath(); 676 if (fileAbsPath.endsWith(".")) 677 fileAbsPath = fileAbsPath + "/"; 678 String absPath = normalize(fileAbsPath); 679 if (canPath != null) 680 canPath = normalize(canPath); 681 if ((absoluteBase.length() < absPath.length()) 682 && (absoluteBase.length() < canPath.length())) { 683 absPath = absPath.substring(absoluteBase.length() + 1); 684 if ((canPath == null) || (absPath == null)) 685 return null; 686 if (absPath.equals("")) 687 absPath = "/"; 688 canPath = canPath.substring(absoluteBase.length() + 1); 689 if (canPath.equals("")) 690 canPath = "/"; 691 if (!canPath.equals(absPath)) 692 return null; 693 } 694 } 695 696 } else { 697 if( log.isDebugEnabled() ) log.debug( file + " " + 698 file.exists() + " " + 699 file.canRead() ); 700 return null; 701 } 702 return file; 703 704 } 705 706 707 713 protected Vector list(File file) { 714 715 Vector entries = new Vector (); 716 if (!file.isDirectory()) 717 return entries; 718 String [] names = file.list(); 719 Arrays.sort(names); if (names == null) 721 return entries; 722 NamingEntry entry = null; 723 724 for (int i = 0; i < names.length; i++) { 725 726 File currentFile = new File (file, names[i]); 727 Object object = null; 728 if (currentFile.isDirectory()) { 729 FileDirContext tempContext = new FileDirContext(env); 730 tempContext.setDocBase(file.getPath()); 731 object = tempContext; 732 } else { 733 object = currentFile; 735 } 736 entry = new NamingEntry(names[i], object, null, NamingEntry.ENTRY); 737 entries.addElement(entry); 738 739 } 740 741 return entries; 742 743 } 744 745 } 746 747 | Popular Tags |