001: /*
002: Copyright (C) 2004 David Bucciarelli (davibu@interfree.it)
003:
004: This program is free software; you can redistribute it and/or
005: modify it under the terms of the GNU General Public License
006: as published by the Free Software Foundation; either version 2
007: of the License, or (at your option) any later version.
008:
009: This program is distributed in the hope that it will be useful,
010: but WITHOUT ANY WARRANTY; without even the implied warranty of
011: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: GNU General Public License for more details.
013:
014: You should have received a copy of the GNU General Public License
015: along with this program; if not, write to the Free Software
016: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: */
018:
019: package org.homedns.dade.jcgrid.vfs;
020:
021: import java.io.*;
022: import java.util.*;
023: import java.security.*;
024:
025: import org.apache.log4j.*;
026:
027: import org.homedns.dade.jcgrid.message.*;
028: import org.homedns.dade.jcgrid.util.*;
029:
030: public class vfsSession implements Serializable {
031: private final static String className = vfsSession.class.getName();
032: private static Logger log = Logger.getLogger(className);
033: private static Logger logDetail = Logger.getLogger("DETAIL."
034: + className);
035:
036: private static final long serialVersionUID = 1L;
037:
038: private final static String hexMap[] = { "0", "1", "2", "3", "4",
039: "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" };
040:
041: private String path;
042: private Hashtable fileList;
043: private long size;
044: private boolean inUse;
045:
046: public vfsSession(String dir) throws Exception {
047: if (log.isDebugEnabled())
048: log.debug("Start vfsSession(" + dir + ")");
049:
050: path = dir;
051:
052: // Check if the directory exists
053:
054: File pathDir = new File(path);
055: if (!pathDir.exists()) {
056: // I fit doesn't exist create the directory
057: pathDir.mkdirs();
058: }
059:
060: fileList = null;
061: inUse = false;
062:
063: if (log.isDebugEnabled())
064: log.debug("End vfsSession()");
065: }
066:
067: //---------------------------- Delete --------------------------------------
068:
069: private void deleteImpl(File root) throws IOException {
070: if (log.isDebugEnabled())
071: log.debug("Start deleteImpl(" + root + ")");
072:
073: String[] l = root.list();
074: for (int i = 0; i < l.length; i++) {
075: String p = root.getAbsolutePath() + File.separator + l[i];
076:
077: File f = new File(p);
078: if (f.isDirectory()) {
079: log.warn("VFS session removing directory: " + p);
080: this .deleteImpl(f);
081: f.delete();
082: } else
083: f.delete();
084: }
085:
086: boolean res = (l.length == 0);
087:
088: if (log.isDebugEnabled())
089: log.debug("End deleteImpl()");
090: }
091:
092: public void delete() throws IOException {
093: if (log.isDebugEnabled())
094: log.debug("Start delete()");
095:
096: File f = new File(path);
097: this .deleteImpl(f);
098:
099: if (log.isDebugEnabled())
100: log.debug("End delete()");
101:
102: }
103:
104: private boolean deleteEmptyDirectoriesImpl(File root)
105: throws IOException {
106: if (log.isDebugEnabled())
107: log.debug("Start deleteEmptyDirectoriesImpl(" + root + ")");
108:
109: String[] l = root.list();
110: for (int i = 0; i < l.length; i++) {
111: String p = root.getAbsolutePath() + File.separator + l[i];
112:
113: File f = new File(p);
114: if (f.isDirectory()) {
115: if (this .deleteEmptyDirectoriesImpl(f)) {
116: log.warn("VFS session removing empty directory: "
117: + p);
118: f.delete();
119: }
120: }
121: }
122:
123: boolean res = (l.length == 0);
124:
125: if (log.isDebugEnabled())
126: log.debug("End deleteEmptyDirectoriesImpl(" + res + ")");
127:
128: return res;
129: }
130:
131: public void deleteEmptyDirectories() throws IOException {
132: if (log.isDebugEnabled())
133: log.debug("Start deleteEmptyDirectories()");
134:
135: File f = new File(path);
136: this .deleteEmptyDirectoriesImpl(f);
137:
138: if (log.isDebugEnabled())
139: log.debug("End deleteEmptyDirectories()");
140:
141: }
142:
143: //--------------------------------------------------------------------------
144:
145: public void removeNode(String name) {
146: if (log.isDebugEnabled())
147: log.debug("Start removeNode(" + name + ")");
148:
149: vfsNode n = (vfsNode) fileList.get(name);
150: if (n != null) {
151: size -= n.getSize();
152: fileList.remove(name);
153: }
154:
155: File f = new File(path + name);
156: f.delete();
157:
158: if (log.isDebugEnabled())
159: log.debug("End removeNode()");
160:
161: }
162:
163: private String toHexString(byte[] data) {
164: if (logDetail.isDebugEnabled())
165: logDetail.debug("Start toHexString(" + data + ")");
166:
167: StringBuffer result = new StringBuffer();
168:
169: for (int i = 0; i < data.length; i++) {
170: int l = ((((int) data[i])) & 0xF0) >> 4;
171: int r = ((int) data[i]) & 0x0F;
172:
173: result.append(hexMap[l] + hexMap[r]);
174: }
175:
176: String res = result.toString();
177:
178: if (logDetail.isDebugEnabled())
179: logDetail.debug("End toHexString(" + res + ")");
180:
181: return res;
182: }
183:
184: private String generateUniqueID(File f) throws IOException,
185: NoSuchAlgorithmException, NoSuchProviderException {
186: if (log.isDebugEnabled())
187: log.debug("Start generateUniqueID(" + f + ")");
188:
189: byte[] buf = new byte[8192];
190: int bytesRead;
191:
192: FileInputStream fis = new FileInputStream(f);
193: MessageDigest md5 = MessageDigest.getInstance("MD5", "SUN");
194:
195: while ((bytesRead = fis.read(buf)) != -1) {
196: md5.update(buf, 0, bytesRead);
197: }
198:
199: fis.close();
200: String res = this .toHexString(md5.digest());
201:
202: if (log.isDebugEnabled())
203: log.debug("End generateUniqueID(" + res + ")");
204:
205: return res;
206: }
207:
208: public void addNode(String name) throws IOException,
209: NoSuchAlgorithmException, NoSuchProviderException {
210: if (log.isDebugEnabled())
211: log.debug("Start addNode(" + name + ")");
212:
213: File f = new File(path + name);
214: if (log.isDebugEnabled())
215: log.debug(" Name: " + name);
216:
217: String id = this .generateUniqueID(new File(path + name));
218: if (log.isDebugEnabled())
219: log.debug(" MD5: " + id);
220:
221: long s = f.length();
222: if (log.isDebugEnabled())
223: log.debug(" Size: " + s);
224:
225: fileList.put(name, new vfsNode(name, id, s));
226: size += s;
227:
228: if (log.isDebugEnabled())
229: log.debug("End addNode()");
230:
231: }
232:
233: public Vector notIncludedNodes(vfsSession s) {
234: if (log.isDebugEnabled())
235: log.debug("Start notIncludedNodes(" + s + ")");
236:
237: Vector v = new Vector();
238: for (Iterator i = fileList.keySet().iterator(); i.hasNext();) {
239: String name = (String) i.next();
240: vfsNode n = (vfsNode) fileList.get(name);
241:
242: if (!s.includes(n))
243: v.add(name);
244: }
245:
246: if (log.isDebugEnabled())
247: log.debug("End notIncludedNodes(" + v + ")");
248:
249: return v;
250: }
251:
252: public boolean includes(vfsNode node) {
253: if (log.isDebugEnabled())
254: log.debug("Start includes(" + node + ")");
255:
256: boolean res;
257:
258: vfsNode n = (vfsNode) fileList.get(node.getName());
259: if (n == null)
260: res = false;
261: else
262: res = n.equals(node);
263:
264: if (log.isDebugEnabled())
265: log.debug("End includes(" + res + ")");
266:
267: return res;
268: }
269:
270: public void syncVFSSession(GridMessageChannel serverChannel)
271: throws Exception {
272: if (log.isDebugEnabled())
273: log.debug("Start syncVFSSession(" + serverChannel + ")");
274:
275: // Sending the list of files
276:
277: serverChannel.send(new GridMessageVFSSessionBegin(this ));
278:
279: // Wait for file requests
280:
281: for (;;) {
282: GridMessage msg = serverChannel.recv();
283:
284: if (log.isDebugEnabled())
285: log.debug(" Received grid message: " + msg);
286:
287: if (msg instanceof GridMessageVFSSessionEnd) {
288: if (log.isDebugEnabled())
289: log.debug(" Received VFS session end");
290: break;
291: } else if (msg instanceof GridMessageVFSSessionFileRequest) {
292: if (log.isDebugEnabled())
293: log.debug(" Received VFS session file request");
294:
295: String n = ((GridMessageVFSSessionFileRequest) msg)
296: .getName();
297: log.warn("VFS session sending: " + n);
298:
299: // Read the file
300:
301: File f = new File(path + n);
302: long fsize = f.length();
303: if (log.isDebugEnabled())
304: log.debug(" File size: " + fsize);
305: // TODO: 4GB limit
306: byte[] data = new byte[(int) fsize];
307:
308: FileInputStream fis = new FileInputStream(f);
309: fis.read(data);
310: fis.close();
311:
312: serverChannel.send(new GridMessageVFSSessionFileResult(
313: data));
314: } else
315: log
316: .warn("Unknown message in ClientHandlerThread.run(): "
317: + msg);
318: }
319:
320: if (log.isDebugEnabled())
321: log.debug("End syncVFSSession()");
322: }
323:
324: //----------------------------- Start & Stop -------------------------------
325:
326: private void scann(File root, int realRootPathIndex)
327: throws IOException, NoSuchAlgorithmException,
328: NoSuchProviderException {
329: if (log.isDebugEnabled())
330: log.debug("Start scann(" + root + "," + realRootPathIndex
331: + ")");
332:
333: String[] l = root.list();
334:
335: for (int i = 0; i < l.length; i++) {
336: String p = root.getAbsolutePath() + File.separator + l[i];
337: log.warn(" VFS scanning: " + p);
338:
339: File f = new File(p);
340: if (f.isDirectory())
341: this .scann(f, realRootPathIndex);
342: else if (f.isFile()) {
343: String name = p.substring(realRootPathIndex);
344: this .addNode(name);
345: } else
346: log.warn(" VFS " + l[i] + " is not a normal file");
347: }
348:
349: if (log.isDebugEnabled())
350: log.debug("End scann()");
351: }
352:
353: public void start() throws Exception {
354: if (log.isDebugEnabled())
355: log.debug("Start start()");
356:
357: fileList = new Hashtable();
358: size = 0;
359:
360: log.warn("VFS starting on path: " + path);
361: File f = new File(path);
362:
363: if (!f.exists())
364: throw new Exception("The path " + path + " doesn't exist");
365:
366: this .scann(f, f.getAbsolutePath().length());
367:
368: if (log.isDebugEnabled())
369: log.debug("End start()");
370: }
371:
372: //------------------------------- Get & Set --------------------------------
373:
374: public vfsNode getNode(String name) {
375: if (logDetail.isDebugEnabled())
376: logDetail.debug("Start getNode(" + name + ")");
377:
378: vfsNode n = (vfsNode) fileList.get(name);
379:
380: if (logDetail.isDebugEnabled())
381: logDetail.debug("End getNode(" + n + ")");
382:
383: return n;
384: }
385:
386: public String getPath() {
387: if (logDetail.isDebugEnabled())
388: logDetail.debug("Start getPath()");
389: if (logDetail.isDebugEnabled())
390: logDetail.debug("End getPath(" + path + ")");
391:
392: return path;
393: }
394:
395: public long getSize() {
396: if (logDetail.isDebugEnabled())
397: logDetail.debug("Start getSize()");
398: if (logDetail.isDebugEnabled())
399: logDetail.debug("End getSize(" + size + ")");
400:
401: return size;
402: }
403:
404: public void setInUse(boolean use) {
405: if (logDetail.isDebugEnabled())
406: logDetail.debug("Start setInUse(" + use + ")");
407:
408: inUse = use;
409:
410: if (logDetail.isDebugEnabled())
411: logDetail.debug("End setInUse()");
412: }
413:
414: public boolean getInUse() {
415: if (logDetail.isDebugEnabled())
416: logDetail.debug("Start getInUse()");
417: if (logDetail.isDebugEnabled())
418: logDetail.debug("End getInUse(" + inUse + ")");
419:
420: return inUse;
421: }
422: }
|