KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > drftpd > slave > RootBasket


1 /*
2  * This file is part of DrFTPD, Distributed FTP Daemon.
3  *
4  * DrFTPD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * DrFTPD is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with DrFTPD; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package net.sf.drftpd.slave;
19
20 import java.io.FileNotFoundException JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.Collections JavaDoc;
25 import java.util.Comparator JavaDoc;
26 import java.util.Hashtable JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
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 //TODO SECURITY: verify so that we never get outside of a rootbasket root
38
/**
39  * @author mog
40  * @version $Id: RootBasket.java,v 1.28 2004/06/01 15:40:33 mog Exp $
41  */

42 public class RootBasket {
43     private static final Logger logger = Logger.getLogger(RootBasket.class);
44     private Collection JavaDoc _roots;
45
46     public RootBasket(Collection JavaDoc roots) throws IOException JavaDoc {
47         /** sanity checks **/
48         validateRoots(roots);
49         _roots = new ArrayList JavaDoc(roots);
50     }
51
52     public Root getARoot() {
53         long mostFree = 0;
54         Root mostFreeRoot = null;
55         for (Iterator JavaDoc 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 JavaDoc("NoAvailableRootsException");
65         return mostFreeRoot;
66     }
67
68     /**
69      * Get a directory specified by dir under an approperiate root for storing storing files in.
70      * @param directory to store file in
71      * @throws PermissionDeniedException If creation of dir failed in the slave root selected by getARootFileDir().
72      */

73     public File getARootFileDir(String JavaDoc dir) throws PermissionDeniedException {
74         Iterator JavaDoc 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     //Get root which has most of the tree structure that we have.
99
public File getFile(String JavaDoc path) throws FileNotFoundException JavaDoc {
100         return new File(
101             getRootForFile(path).getPath() + File.separatorChar + path);
102     }
103
104     /**
105      * Returns an ArrayList containing se.mog.io.File objects
106      */

107     public List JavaDoc getMultipleFiles(String JavaDoc path) throws FileNotFoundException JavaDoc {
108         ArrayList JavaDoc files = new ArrayList JavaDoc();
109         for (Iterator JavaDoc 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 JavaDoc getMultipleRootsForFile(String JavaDoc path)
118         throws FileNotFoundException JavaDoc {
119         ArrayList JavaDoc roots = new ArrayList JavaDoc();
120         for (Iterator JavaDoc 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 JavaDoc("Unable to find suitable root");
127         return roots;
128     }
129
130     public Root getRootForFile(String JavaDoc path) throws FileNotFoundException JavaDoc {
131         for (Iterator JavaDoc 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 JavaDoc(path + " wasn't found in any root");
138     }
139
140     public long getTotalDiskSpaceAvailable() {
141         long totalDiskSpaceAvailable = 0;
142
143         for (Iterator JavaDoc 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 JavaDoc 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 JavaDoc iterator() {
163         return _roots.iterator();
164     }
165
166     private static void validateRoots(Collection JavaDoc roots) throws IOException JavaDoc {
167         File mountsArr[] = File.listMounts();
168         ArrayList JavaDoc mounts = new ArrayList JavaDoc(mountsArr.length);
169         for (int i = 0; i < mountsArr.length; i++) {
170             mounts.add(mountsArr[i]);
171         }
172         Collections.sort(mounts, new Comparator JavaDoc() {
173             public boolean equals(Object JavaDoc obj) {
174                 return obj.getClass() == getClass();
175             }
176
177             public int hashCode() {
178                 return getClass().hashCode();
179             }
180
181             public int compare(Object JavaDoc o1, Object JavaDoc 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 JavaDoc usedMounts = new Hashtable JavaDoc();
195         for (Iterator JavaDoc iter = roots.iterator(); iter.hasNext();) {
196             Object JavaDoc o = iter.next();
197             if (!(o instanceof Root))
198                 throw new RuntimeException JavaDoc();
199             Root root = (Root) o;
200             File rootFile = root.getFile();
201             if (!rootFile.exists()) {
202                 if (!rootFile.mkdirs()) {
203                     throw new IOException JavaDoc(
204                         "mkdirs() failed on " + rootFile.getPath());
205                 }
206             }
207             if (!rootFile.exists())
208                 throw new FileNotFoundException JavaDoc("Invalid root: " + rootFile);
209             String JavaDoc fullpath = rootFile.getAbsolutePath();
210             for (Iterator JavaDoc 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 JavaDoc(
216                             "Multiple roots in mount " + mount.getPath());
217                     }
218                     usedMounts.put(mount.getPath(), new Object JavaDoc());
219                     break;
220                 }
221             }
222
223             for (Iterator JavaDoc 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 JavaDoc iter = iterator(); iter.hasNext();) {
242                 Root root = (Root) iter.next();
243                 maxPath = Math.max(root.getPath().length(), maxPath);
244             } //constant for win32, see
245
//http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q177/6/65.ASP&NoWebContent=1
246
// for more info
247
return 256 - maxPath;
248         }
249         return -1;
250     }
251 }
252
Popular Tags