1 18 package net.sf.drftpd.slave; 19 20 import java.io.FileNotFoundException ; 21 import java.io.IOException ; 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.Collections ; 25 import java.util.Comparator ; 26 import java.util.Hashtable ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 30 import net.sf.drftpd.FatalException; 31 import net.sf.drftpd.PermissionDeniedException; 32 33 import org.apache.log4j.Logger; 34 35 import se.mog.io.File; 36 37 42 public class RootBasket { 43 private static final Logger logger = Logger.getLogger(RootBasket.class); 44 private Collection _roots; 45 46 public RootBasket(Collection roots) throws IOException { 47 48 validateRoots(roots); 49 _roots = new ArrayList (roots); 50 } 51 52 public Root getARoot() { 53 long mostFree = 0; 54 Root mostFreeRoot = null; 55 for (Iterator iter = _roots.iterator(); iter.hasNext();) { 56 Root root = (Root) iter.next(); 57 long diskSpaceAvailable = root.getDiskSpaceAvailable(); 58 if (diskSpaceAvailable > mostFree) { 59 mostFree = diskSpaceAvailable; 60 mostFreeRoot = root; 61 } 62 } 63 if (mostFreeRoot == null) 64 throw new RuntimeException ("NoAvailableRootsException"); 65 return mostFreeRoot; 66 } 67 68 73 public File getARootFileDir(String dir) throws PermissionDeniedException { 74 Iterator iter = _roots.iterator(); 75 Root bestRoot = (Root) iter.next(); 76 while (iter.hasNext()) { 77 Root root = (Root) iter.next(); 78 if (bestRoot.isFull()) { 79 bestRoot = root; 80 continue; 81 } 82 if (root.lastModified() > bestRoot.lastModified()) { 83 if (root.isFull() && !bestRoot.isFull()) 84 continue; 85 bestRoot = root; 86 } 87 } 88 bestRoot.touch(); 89 File file = bestRoot.getFile(dir); 90 if (!file.exists()) { 91 if (!file.mkdirs()) { 92 throw new PermissionDeniedException( 93 "mkdirs failed on " + file.getPath()); 94 } 95 } 96 return file; 97 } 98 public File getFile(String path) throws FileNotFoundException { 100 return new File( 101 getRootForFile(path).getPath() + File.separatorChar + path); 102 } 103 104 107 public List getMultipleFiles(String path) throws FileNotFoundException { 108 ArrayList files = new ArrayList (); 109 for (Iterator iter = getMultipleRootsForFile(path).iterator(); 110 iter.hasNext(); 111 ) { 112 files.add(((Root) iter.next()).getFile(path)); 113 } 114 return files; 115 } 116 117 public List getMultipleRootsForFile(String path) 118 throws FileNotFoundException { 119 ArrayList roots = new ArrayList (); 120 for (Iterator iter = _roots.iterator(); iter.hasNext();) { 121 Root root = (Root) iter.next(); 122 if (root.getFile(path).exists()) 123 roots.add(root); 124 } 125 if (roots.size() == 0) 126 throw new FileNotFoundException ("Unable to find suitable root"); 127 return roots; 128 } 129 130 public Root getRootForFile(String path) throws FileNotFoundException { 131 for (Iterator iter = _roots.iterator(); iter.hasNext();) { 132 Root root = (Root) iter.next(); 133 File file = new File(root.getPath() + File.separatorChar + path); 134 if (file.exists()) 135 return root; 136 } 137 throw new FileNotFoundException (path + " wasn't found in any root"); 138 } 139 140 public long getTotalDiskSpaceAvailable() { 141 long totalDiskSpaceAvailable = 0; 142 143 for (Iterator iter = _roots.iterator(); iter.hasNext();) { 144 Root root = (Root) iter.next(); 145 File rootFile = root.getFile(); 146 totalDiskSpaceAvailable += rootFile.getDiskSpaceAvailable(); 147 } 148 return totalDiskSpaceAvailable; 149 } 150 151 public long getTotalDiskSpaceCapacity() { 152 long totalDiskSpaceCapacity = 0; 153 154 for (Iterator iter = _roots.iterator(); iter.hasNext();) { 155 Root root = (Root) iter.next(); 156 File rootFile = root.getFile(); 157 totalDiskSpaceCapacity += rootFile.getDiskSpaceCapacity(); 158 } 159 return totalDiskSpaceCapacity; 160 } 161 162 public Iterator iterator() { 163 return _roots.iterator(); 164 } 165 166 private static void validateRoots(Collection roots) throws IOException { 167 File mountsArr[] = File.listMounts(); 168 ArrayList mounts = new ArrayList (mountsArr.length); 169 for (int i = 0; i < mountsArr.length; i++) { 170 mounts.add(mountsArr[i]); 171 } 172 Collections.sort(mounts, new Comparator () { 173 public boolean equals(Object obj) { 174 return obj.getClass() == getClass(); 175 } 176 177 public int hashCode() { 178 return getClass().hashCode(); 179 } 180 181 public int compare(Object o1, Object o2) { 182 return compare((File) o1, (File) o2); 183 } 184 public int compare(File o1, File o2) { 185 int thisVal = o1.getPath().length(); 186 int anotherVal = o2.getPath().length(); 187 return ( 188 thisVal < anotherVal 189 ? 1 190 : (thisVal == anotherVal ? 0 : -1)); 191 } 192 }); 193 194 Hashtable usedMounts = new Hashtable (); 195 for (Iterator iter = roots.iterator(); iter.hasNext();) { 196 Object o = iter.next(); 197 if (!(o instanceof Root)) 198 throw new RuntimeException (); 199 Root root = (Root) o; 200 File rootFile = root.getFile(); 201 if (!rootFile.exists()) { 202 if (!rootFile.mkdirs()) { 203 throw new IOException ( 204 "mkdirs() failed on " + rootFile.getPath()); 205 } 206 } 207 if (!rootFile.exists()) 208 throw new FileNotFoundException ("Invalid root: " + rootFile); 209 String fullpath = rootFile.getAbsolutePath(); 210 for (Iterator iterator = mounts.iterator(); iterator.hasNext();) { 211 File mount = (File) iterator.next(); 212 if (fullpath.startsWith(mount.getPath())) { 213 logger.info(fullpath + " in mount " + mount.getPath()); 214 if (usedMounts.get(mount.getPath()) != null) { 215 throw new IOException ( 216 "Multiple roots in mount " + mount.getPath()); 217 } 218 usedMounts.put(mount.getPath(), new Object ()); 219 break; 220 } 221 } 222 223 for (Iterator iterator = roots.iterator(); iterator.hasNext();) { 224 Root root2 = (Root) iterator.next(); 225 if (root == root2) 226 continue; 227 if (root2.getPath().startsWith(root.getPath())) { 228 throw new FatalException( 229 "Overlapping roots: " 230 + root.getPath() 231 + " and " 232 + root2.getPath()); 233 } 234 } 235 } 236 } 237 238 public int getMaxPath() { 239 if (SlaveImpl.isWin32) { 240 int maxPath = 0; 241 for (Iterator iter = iterator(); iter.hasNext();) { 242 Root root = (Root) iter.next(); 243 maxPath = Math.max(root.getPath().length(), maxPath); 244 } return 256 - maxPath; 248 } 249 return -1; 250 } 251 } 252 | Popular Tags |