1 17 18 19 package org.apache.naming.resources; 20 21 import java.io.File ; 22 import java.io.FileInputStream ; 23 import java.io.FileOutputStream ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.util.ArrayList ; 27 import java.util.Arrays ; 28 import java.util.Date ; 29 import java.util.Hashtable ; 30 31 import javax.naming.NameAlreadyBoundException ; 32 import javax.naming.NamingEnumeration ; 33 import javax.naming.NamingException ; 34 import javax.naming.OperationNotSupportedException ; 35 import javax.naming.directory.Attributes ; 36 import javax.naming.directory.DirContext ; 37 import javax.naming.directory.ModificationItem ; 38 import javax.naming.directory.SearchControls ; 39 40 import org.apache.naming.NamingContextBindingsEnumeration; 41 import org.apache.naming.NamingContextEnumeration; 42 import org.apache.naming.NamingEntry; 43 44 50 51 public class FileDirContext extends BaseDirContext { 52 53 private static org.apache.commons.logging.Log log= 54 org.apache.commons.logging.LogFactory.getLog( FileDirContext.class ); 55 56 58 59 62 protected static final int BUFFER_SIZE = 2048; 63 64 65 67 68 71 public FileDirContext() { 72 super(); 73 } 74 75 76 79 public FileDirContext(Hashtable env) { 80 super(env); 81 } 82 83 84 86 87 90 protected File base = null; 91 92 93 96 protected String absoluteBase = null; 97 98 99 102 protected boolean caseSensitive = true; 103 104 105 108 protected boolean allowLinking = false; 109 110 111 113 114 124 public void setDocBase(String docBase) { 125 126 if (docBase == null) 128 throw new IllegalArgumentException 129 (sm.getString("resources.null")); 130 131 base = new File (docBase); 133 try { 134 base = base.getCanonicalFile(); 135 } catch (IOException e) { 136 } 138 139 if (!base.exists() || !base.isDirectory() || !base.canRead()) 141 throw new IllegalArgumentException 142 (sm.getString("fileResources.base", docBase)); 143 this.absoluteBase = base.getAbsolutePath(); 144 super.setDocBase(docBase); 145 146 } 147 148 149 152 public void setCaseSensitive(boolean caseSensitive) { 153 this.caseSensitive = caseSensitive; 154 } 155 156 157 160 public boolean isCaseSensitive() { 161 return caseSensitive; 162 } 163 164 165 168 public void setAllowLinking(boolean allowLinking) { 169 this.allowLinking = allowLinking; 170 } 171 172 173 176 public boolean getAllowLinking() { 177 return allowLinking; 178 } 179 180 181 183 184 187 public void release() { 188 super.release(); 189 } 190 191 192 194 195 202 public Object lookup(String name) 203 throws NamingException { 204 Object result = null; 205 File file = file(name); 206 207 if (file == null) 208 throw new NamingException 209 (sm.getString("resources.notFound", name)); 210 211 if (file.isDirectory()) { 212 FileDirContext tempContext = new FileDirContext(env); 213 tempContext.setDocBase(file.getPath()); 214 tempContext.setAllowLinking(getAllowLinking()); 215 tempContext.setCaseSensitive(isCaseSensitive()); 216 result = tempContext; 217 } else { 218 result = new FileResource(file); 219 } 220 221 return result; 222 223 } 224 225 226 240 public void unbind(String name) 241 throws NamingException { 242 243 File file = file(name); 244 245 if (file == null) 246 throw new NamingException 247 (sm.getString("resources.notFound", name)); 248 249 if (!file.delete()) 250 throw new NamingException 251 (sm.getString("resources.unbindFailed", name)); 252 253 } 254 255 256 267 public void rename(String oldName, String newName) 268 throws NamingException { 269 270 File file = file(oldName); 271 272 if (file == null) 273 throw new NamingException 274 (sm.getString("resources.notFound", oldName)); 275 276 File newFile = new File (base, newName); 277 278 file.renameTo(newFile); 279 280 } 281 282 283 296 public NamingEnumeration list(String name) 297 throws NamingException { 298 299 File file = file(name); 300 301 if (file == null) 302 throw new NamingException 303 (sm.getString("resources.notFound", name)); 304 305 return new NamingContextEnumeration(list(file).iterator()); 306 307 } 308 309 310 323 public NamingEnumeration listBindings(String name) 324 throws NamingException { 325 326 File file = file(name); 327 328 if (file == null) 329 throw new NamingException 330 (sm.getString("resources.notFound", name)); 331 332 return new NamingContextBindingsEnumeration(list(file).iterator(), 333 this); 334 335 } 336 337 338 363 public void destroySubcontext(String name) 364 throws NamingException { 365 unbind(name); 366 } 367 368 369 379 public Object lookupLink(String name) 380 throws NamingException { 381 return lookup(name); 383 } 384 385 386 403 public String getNameInNamespace() 404 throws NamingException { 405 return docBase; 406 } 407 408 409 411 412 424 public Attributes getAttributes(String name, String [] attrIds) 425 throws NamingException { 426 427 File file = file(name); 429 430 if (file == null) 431 throw new NamingException 432 (sm.getString("resources.notFound", name)); 433 434 return new FileResourceAttributes(file); 435 436 } 437 438 439 453 public void modifyAttributes(String name, int mod_op, Attributes attrs) 454 throws NamingException { 455 456 } 457 458 459 473 public void modifyAttributes(String name, ModificationItem [] mods) 474 throws NamingException { 475 476 } 477 478 479 494 public void bind(String name, Object obj, Attributes attrs) 495 throws NamingException { 496 497 499 File file = new File (base, name); 500 if (file.exists()) 501 throw new NameAlreadyBoundException 502 (sm.getString("resources.alreadyBound", name)); 503 504 rebind(name, obj, attrs); 505 506 } 507 508 509 527 public void rebind(String name, Object obj, Attributes attrs) 528 throws NamingException { 529 530 533 File file = new File (base, name); 534 535 InputStream is = null; 536 if (obj instanceof Resource) { 537 try { 538 is = ((Resource) obj).streamContent(); 539 } catch (IOException e) { 540 } 541 } else if (obj instanceof InputStream ) { 542 is = (InputStream ) obj; 543 } else if (obj instanceof DirContext ) { 544 if (file.exists()) { 545 if (!file.delete()) 546 throw new NamingException 547 (sm.getString("resources.bindFailed", name)); 548 } 549 if (!file.mkdir()) 550 throw new NamingException 551 (sm.getString("resources.bindFailed", name)); 552 } 553 if (is == null) 554 throw new NamingException 555 (sm.getString("resources.bindFailed", name)); 556 557 559 try { 560 FileOutputStream os = null; 561 byte buffer[] = new byte[BUFFER_SIZE]; 562 int len = -1; 563 try { 564 os = new FileOutputStream (file); 565 while (true) { 566 len = is.read(buffer); 567 if (len == -1) 568 break; 569 os.write(buffer, 0, len); 570 } 571 } finally { 572 if (os != null) 573 os.close(); 574 is.close(); 575 } 576 } catch (IOException e) { 577 throw new NamingException 578 (sm.getString("resources.bindFailed", e)); 579 } 580 581 } 582 583 584 601 public DirContext createSubcontext(String name, Attributes attrs) 602 throws NamingException { 603 604 File file = new File (base, name); 605 if (file.exists()) 606 throw new NameAlreadyBoundException 607 (sm.getString("resources.alreadyBound", name)); 608 if (!file.mkdir()) 609 throw new NamingException 610 (sm.getString("resources.bindFailed", name)); 611 return (DirContext ) lookup(name); 612 613 } 614 615 616 629 public DirContext getSchema(String name) 630 throws NamingException { 631 throw new OperationNotSupportedException (); 632 } 633 634 635 646 public DirContext getSchemaClassDefinition(String name) 647 throws NamingException { 648 throw new OperationNotSupportedException (); 649 } 650 651 652 669 public NamingEnumeration search(String name, Attributes matchingAttributes, 670 String [] attributesToReturn) 671 throws NamingException { 672 return null; 673 } 674 675 676 691 public NamingEnumeration search(String name, Attributes matchingAttributes) 692 throws NamingException { 693 return null; 694 } 695 696 697 716 public NamingEnumeration search(String name, String filter, 717 SearchControls cons) 718 throws NamingException { 719 return null; 720 } 721 722 723 747 public NamingEnumeration search(String name, String filterExpr, 748 Object [] filterArgs, SearchControls cons) 749 throws NamingException { 750 return null; 751 } 752 753 754 756 757 766 protected String normalize(String path) { 767 768 String normalized = path; 769 770 if (File.separatorChar == '\\' && normalized.indexOf('\\') >= 0) 772 normalized = normalized.replace('\\', '/'); 773 if (!normalized.startsWith("/")) 774 normalized = "/" + normalized; 775 776 while (true) { 778 int index = normalized.indexOf("//"); 779 if (index < 0) 780 break; 781 normalized = normalized.substring(0, index) + 782 normalized.substring(index + 1); 783 } 784 785 while (true) { 787 int index = normalized.indexOf("/./"); 788 if (index < 0) 789 break; 790 normalized = normalized.substring(0, index) + 791 normalized.substring(index + 2); 792 } 793 794 while (true) { 796 int index = normalized.indexOf("/../"); 797 if (index < 0) 798 break; 799 if (index == 0) 800 return (null); int index2 = normalized.lastIndexOf('/', index - 1); 802 normalized = normalized.substring(0, index2) + 803 normalized.substring(index + 3); 804 } 805 806 return (normalized); 808 809 } 810 811 812 819 protected File file(String name) { 820 821 File file = new File (base, name); 822 if (file.exists() && file.canRead()) { 823 824 if (allowLinking) 825 return file; 826 827 String canPath = null; 829 try { 830 canPath = file.getCanonicalPath(); 831 } catch (IOException e) { 832 } 833 if (canPath == null) 834 return null; 835 836 if (!canPath.startsWith(absoluteBase)) { 838 return null; 839 } 840 841 if (caseSensitive) { 843 String fileAbsPath = file.getAbsolutePath(); 844 if (fileAbsPath.endsWith(".")) 845 fileAbsPath = fileAbsPath + "/"; 846 String absPath = normalize(fileAbsPath); 847 if (canPath != null) 848 canPath = normalize(canPath); 849 if ((absoluteBase.length() < absPath.length()) 850 && (absoluteBase.length() < canPath.length())) { 851 absPath = absPath.substring(absoluteBase.length() + 1); 852 if ((canPath == null) || (absPath == null)) 853 return null; 854 if (absPath.equals("")) 855 absPath = "/"; 856 canPath = canPath.substring(absoluteBase.length() + 1); 857 if (canPath.equals("")) 858 canPath = "/"; 859 if (!canPath.equals(absPath)) 860 return null; 861 } 862 } 863 864 } else { 865 return null; 866 } 867 return file; 868 869 } 870 871 872 878 protected ArrayList list(File file) { 879 880 ArrayList entries = new ArrayList (); 881 if (!file.isDirectory()) 882 return entries; 883 String [] names = file.list(); 884 if (names==null) { 885 887 log.warn(sm.getString("fileResources.listingNull", 888 file.getAbsolutePath())); 889 return entries; 890 } 891 892 Arrays.sort(names); if (names == null) 894 return entries; 895 NamingEntry entry = null; 896 897 for (int i = 0; i < names.length; i++) { 898 899 File currentFile = new File (file, names[i]); 900 Object object = null; 901 if (currentFile.isDirectory()) { 902 FileDirContext tempContext = new FileDirContext(env); 903 tempContext.setDocBase(file.getPath()); 904 tempContext.setAllowLinking(getAllowLinking()); 905 tempContext.setCaseSensitive(isCaseSensitive()); 906 object = tempContext; 907 } else { 908 object = new FileResource(currentFile); 909 } 910 entry = new NamingEntry(names[i], object, NamingEntry.ENTRY); 911 entries.add(entry); 912 913 } 914 915 return entries; 916 917 } 918 919 920 922 923 927 protected class FileResource extends Resource { 928 929 930 932 933 public FileResource(File file) { 934 this.file = file; 935 } 936 937 938 940 941 944 protected File file; 945 946 947 950 protected long length = -1L; 951 952 953 955 956 961 public InputStream streamContent() 962 throws IOException { 963 if (binaryContent == null) { 964 inputStream = new FileInputStream (file); 965 } 966 return super.streamContent(); 967 } 968 969 970 } 971 972 973 975 976 981 protected class FileResourceAttributes extends ResourceAttributes { 982 983 984 986 987 public FileResourceAttributes(File file) { 988 this.file = file; 989 } 990 991 993 994 protected File file; 995 996 997 protected boolean accessed = false; 998 999 1000 protected String canonicalPath = null; 1001 1002 1003 1005 1006 1009 public boolean isCollection() { 1010 if (!accessed) { 1011 collection = file.isDirectory(); 1012 accessed = true; 1013 } 1014 return super.isCollection(); 1015 } 1016 1017 1018 1023 public long getContentLength() { 1024 if (contentLength != -1L) 1025 return contentLength; 1026 contentLength = file.length(); 1027 return contentLength; 1028 } 1029 1030 1031 1036 public long getCreation() { 1037 if (creation != -1L) 1038 return creation; 1039 creation = file.lastModified(); 1040 return creation; 1041 } 1042 1043 1044 1049 public Date getCreationDate() { 1050 if (creation == -1L) { 1051 creation = file.lastModified(); 1052 } 1053 return super.getCreationDate(); 1054 } 1055 1056 1057 1062 public long getLastModified() { 1063 if (lastModified != -1L) 1064 return lastModified; 1065 lastModified = file.lastModified(); 1066 return lastModified; 1067 } 1068 1069 1070 1075 public Date getLastModifiedDate() { 1076 if (lastModified == -1L) { 1077 lastModified = file.lastModified(); 1078 } 1079 return super.getLastModifiedDate(); 1080 } 1081 1082 1083 1088 public String getName() { 1089 if (name == null) 1090 name = file.getName(); 1091 return name; 1092 } 1093 1094 1095 1100 public String getResourceType() { 1101 if (!accessed) { 1102 collection = file.isDirectory(); 1103 accessed = true; 1104 } 1105 return super.getResourceType(); 1106 } 1107 1108 1109 1114 public String getCanonicalPath() { 1115 if (canonicalPath == null) { 1116 try { 1117 canonicalPath = file.getCanonicalPath(); 1118 } catch (IOException e) { 1119 } 1121 } 1122 return canonicalPath; 1123 } 1124 1125 1126 } 1127 1128 1129} 1130 1131 | Popular Tags |