Global.helma.File (path)
Sourcecode in /home/hannes/helma/modules/helma/File.js:
22:   helma.File = function(path) {
23:      var BufferedReader            = java.io.BufferedReader;
24:      var File                      = java.io.File;
25:      var Reader                    = java.io.Reader;
26:      var Writer                    = java.io.Writer;
27:      var FileReader                = java.io.FileReader;
28:      var FileWriter                = java.io.FileWriter;
29:      var PrintWriter               = java.io.PrintWriter;
30:      var EOFException              = java.io.EOFException;
31:     var IOException               = java.io.IOException;
32:     var IllegalStateException     = java.lang.IllegalStateException;
33:     var IllegalArgumentException  = java.lang.IllegalArgumentException
34:  
35:     var self = this;
36:  
37:     var file;
38:     try {
39:        // immediately convert to absolute path - java.io.File is 
40:        // incredibly stupid when dealing with relative file names
41:        if (arguments.length > 1)
42:           file = new File(path, arguments[1]).getAbsoluteFile();
43:        else
44:           file = new File(path).getAbsoluteFile();
45:     } catch (e) {
46:        throw(e);
47:     }
48:  
49:     var readerWriter;
50:     var atEOF = false;
51:     var lastLine = null;
52:  
53:     var setError = function(e) {
54:        this.lastError = e;
55:     };
56:  
57:     this.lastError = null;
58:  
59:     this.toString = function() {
60:        return file.toString();
61:     };
62:  
63:     this.getName = function() {
64:        var name = file.getName();
65:        return (name == null ? "" : name);
66:     };
67:  
68:     this.isOpened = function() {
69:        return (readerWriter != null);
70:     };
71:  
72:     this.open = function() {
73:        if (self.isOpened()) {
74:           setError(new IllegalStateException("File already open"));
75:           return false;
76:        }
77:        // We assume that the BufferedReader and PrintWriter creation
78:        // cannot fail except if the FileReader/FileWriter fails.
79:        // Otherwise we have an open file until the reader/writer
80:        // get garbage collected.
81:        try{
82:           if (file.exists()) {
83:              readerWriter = new BufferedReader(new FileReader(file));
84:           } else {
85:              readerWriter = new PrintWriter(new FileWriter(file));
86:           }
87:           return true;
88:        } catch (e) {
89:           setError(e);
90:           return false;
91:        }
92:        return;
93:     };
94:  
95:     this.exists = function() {
96:        return file.exists();
97:     };
98:  
99:     this.getParent = function() {
100:        if (!file.getParent())
101:           return null;
102:        return new helma.File(file.getParent());
103:     };
104:  
105:     this.readln = function() {
106:        if (!self.isOpened()) {
107:           setError(new IllegalStateException("File not opened"));
108:           return null;
109:        }
110:        if (!(readerWriter instanceof BufferedReader)) {
111:           setError(new IllegalStateException("File not opened for reading"));
112:           return null;
113:        }
114:        if (atEOF) {
115:           setError(new EOFException());
116:           return null;
117:        }
118:        if (lastLine != null) {
119:           var line = lastLine;
120:           lastLine = null;
121:          return line;
122:       }
123:       var reader = readerWriter;
124:       // Here lastLine is null, return a new line
125:       try {
126:          var line = readerWriter.readLine();
127:          if (line == null) {
128:             atEOF = true;
129:             setError(new EOFException());
130:          }
131:          return line;
132:       } catch (e) {
133:          setError(e);
134:          return null;
135:       }
136:       return;
137:    };
138: 
139:    this.write = function(what) {
140:       if (!self.isOpened()) {
141:          setError(new IllegalStateException("File not opened"));
142:          return false;
143:       }
144:       if (!(readerWriter instanceof PrintWriter)) {
145:          setError(new IllegalStateException("File not opened for writing"));
146:          return false;
147:       }
148:       if (what != null) {
149:          readerWriter.print(what.toString());
150:       }
151:       return true;
152:    };
153: 
154:    this.writeln = function(what) {
155:       if (self.write(what)) {
156:          readerWriter.println();
157:          return true;
158:       }
159:       return false;
160:    };
161: 
162:    this.isAbsolute = function() {
163:       return file.isAbsolute();
164:    };
165: 
166:    this.remove = function() {
167:       if (self.isOpened()) {
168:          setError(new IllegalStateException("An openened file cannot be removed"));
169:          return false;
170:       }
171:       return file["delete"]();
172:    };
173: 
174:    /*
175:     * will list all files within a directory
176:     * you may pass a RegExp Pattern to return just
177:     * files matching this pattern
178:     * @example var xmlFiles = dir.list(/.*\.xml/);
179:     * @param RegExp pattern to test each file name against
180:     * @return Array the list of file names
181:     */
182:    this.list = function(pattern) {
183:       if (self.isOpened())
184:          return null;
185:       if (!file.isDirectory())
186:          return null;
187:       if (pattern) {
188:          var fileList = file.list();
189:          var result = [];
190:          for (var i in fileList) {
191:             if (pattern.test(fileList[i]))
192:                result.push(fileList[i]);
193:          }
194:          return result;
195:       }
196:       return file.list();   
197:    };
198: 
199:    this.flush = function() {
200:       if (!self.isOpened()) {
201:          setError(new IllegalStateException("File not opened"));
202:          return false;
203:       }
204:       if (readerWriter instanceof Writer) {
205:          try {
206:             readerWriter.flush();
207:          } catch (e) {
208:            setError(e);
209:            return false;
210:          }
211:       } else {
212:          setError(new IllegalStateException("File not opened for write"));
213:          return false; // not supported by reader
214:       }
215:       return true;
216:    };
217: 
218:    this.close = function() {
219:       if (!self.isOpened())
220:          return false;
221:       try {
222:          readerWriter.close();
223:          readerWriter = null;
224:          return true;
225:       } catch (e) {
226:          setError(e);
227:          readerWriter = null;
228:          return false;
229:       }
230:    };
231: 
232:    this.getPath = function() {
233:       var path = file.getPath();
234:       return (path == null ? "" : path);
235:    };
236: 
237:    this.error = function() {
238:       if (this.lastError == null) {
239:          return "";
240:       } else {
241:          var exceptionName = this.lastError.getClass().getName();
242:          var l = exceptionName.lastIndexOf(".");
243:          if (l > 0)
244:             exceptionName = exceptionName.substring(l + 1);
245:          return exceptionName + ": " + this.lastError.getMessage();
246:       }
247:    };
248: 
249:    this.clearError = function() {
250:       this.lastError = null;
251:       return;
252:    };
253: 
254:    this.canRead = function() {
255:       return file.canRead();
256:    };
257: 
258:    this.canWrite = function() {
259:       return file.canWrite();
260:    };
261: 
262:    this.getAbsolutePath = function() {
263:       var absolutPath = file.getAbsolutePath();
264:       return (absolutPath == null ? "" : absolutPath);
265:    };
266: 
267:    this.getLength = function() {
268:       return file.length();
269:    };
270: 
271:    this.isDirectory = function() {
272:       return file.isDirectory();
273:    };
274: 
275:    this.isFile = function() {
276:       return file.isFile();
277:    };
278: 
279:    this.lastModified = function() {
280:       return file.lastModified();
281:    };
282: 
283:    this.makeDirectory = function() {
284:       if (self.isOpened())
285:          return false;
286:       // don't do anything if file exists or use multi directory version
287:       return (file.exists() || file.mkdirs());   
288:    };
289: 
290:    this.renameTo = function(toFile) {
291:       if (toFile == null) {
292:          setError(new IllegalArgumentException("Uninitialized target File object"));
293:          return false;
294:       }
295:       if (self.isOpened()) {
296:          setError(new IllegalStateException("An openened file cannot be renamed"));
297:          return false;
298:       }
299:       if (toFile.isOpened()) {
300:          setError(new IllegalStateException("You cannot rename to an openened file"));
301:          return false;
302:       }
303:       return file.renameTo(new java.io.File(toFile.getAbsolutePath()));
304:    };
305: 
306:    this.eof = function() {
307:       if (!self.isOpened()) {
308:          setError(new IllegalStateException("File not opened"));
309:          return true;
310:       }
311:       if (!(readerWriter instanceof BufferedReader)) {
312:          setError(new IllegalStateException("File not opened for read"));
313:          return true;
314:       }
315:       if (atEOF)
316:          return true;
317:       if (lastLine != null)
318:          return false;
319:       try {
320:          lastLine = readerWriter.readLine();
321:          if (lastLine == null)
322:             atEOF = true;
323:          return atEOF;
324:       } catch (e) {
325:          setError(e);
326:          return true;
327:       }
328:    };
329: 
330:    this.readAll = function() {
331:       // Open the file for readAll
332:       if (self.isOpened()) {
333:          setError(new IllegalStateException("File already open"));
334:          return null;
335:       }
336:       try { 
337:          if (file.exists()) {
338:             readerWriter = new BufferedReader(new FileReader(file));
339:          } else {
340:             setError(new IllegalStateException("File does not exist"));
341:             return null;
342:          }
343:          if (!file.isFile()) {
344:             setError(new IllegalStateException("File is not a regular file"));
345:             return null;
346:          }
347:       
348:          // read content line by line to setup proper eol
349:          var buffer = new java.lang.StringBuffer(file.length() * 1.10);
350:          while (true) {
351:             var line = readerWriter.readLine();
352:             if (line == null)
353:                break;
354:             if (buffer.length() > 0)
355:                buffer.append("\n");  // EcmaScript EOL
356:             buffer.append(line);
357:          }
358:      
359:          // Close the file
360:          readerWriter.close();
361:          readerWriter = null;
362:          return buffer.toString();
363:       } catch (e) {
364:          readerWriter = null;
365:          setError(e);
366:          return null;
367:       }
368:    };
369: 
370:    // DANGER! DANGER! HIGH VOLTAGE!
371:    // this method removes a directory recursively
372:    // without any warning or precautious measures
373:    this.removeDirectory = function() {
374:       if (!file.isDirectory())
375:          return false;
376:       var arr = file.list();
377:       for (var i=0; i<arr.length; i++) {
378:          var f = new helma.File(file, arr[i]);
379:          if (f.isDirectory())
380:             f.removeDirectory();
381:          else
382:             f.remove();
383:       }
384:       file["delete"]();
385:       return true;
386:    };
387: 
388:    /**
389:     * recursivly lists all files below a given directory
390:     * you may pass a RegExp Pattern to return just
391:     * files matching this pattern
392:     * @param RegExp pattern to test each file name against
393:     * @returns Array the list of absolute file paths
394:     */
395:    this.listRecursive = function(pattern) {
396:       if (!file.isDirectory())
397:          return false;
398:       if (!pattern || pattern.test(file.getName()))
399:          var result = [file.getAbsolutePath()];
400:       else
401:          var result = [];
402:       var arr = file.list();
403:       for (var i=0; i<arr.length; i++) {
404:          var f = new helma.File(file, arr[i]);
405:          if (f.isDirectory())
406:             result = result.concat(f.listRecursive(pattern));
407:          else if (!pattern || pattern.test(arr[i]))
408:             result.push(f.getAbsolutePath());
409:       }
410:       return result;
411:    }
412: 
413:    /**
414:     * function makes a copy of a file over partitions
415:     * @param StringOrFile full path of the new file
416:     */
417:    this.hardCopy = function(dest) {
418:       var inStream = new java.io.BufferedInputStream(
419:          new java.io.FileInputStream(file)
420:       );
421:       var outStream = new java.io.BufferedOutputStream(
422:          new java.io.FileOutputStream(dest)
423:       );
424:       var buffer = java.lang.reflect.Array.newInstance(
425:          java.lang.Byte.TYPE, 4096
426:       );
427:       var bytesRead = 0;
428:       while ((bytesRead = inStream.read(buffer, 0, buffer.length)) != -1) {
429:          outStream.write(buffer, 0, bytesRead);
430:       }
431:       outStream.flush();
432:       inStream.close();
433:       outStream.close();
434:       return true;
435:    }
436: 
437:    /**
438:     * function moves a file to a new destination directory
439:     * @param String full path of the new file
440:     * @return Boolean true in case file could be moved, false otherwise
441:     */
442:    this.move = function(dest) {
443:       // instead of using the standard File method renameTo()
444:       // do a hardCopy and then remove the source file. This way
445:       // file locking shouldn't be an issue
446:       self.hardCopy(dest);
447:       // remove the source file
448:       file["delete"]();
449:       return true;
450:    }
451: 
452:    /**
453:     * returns file as ByteArray
454:     * useful for passing it to a function instead of an request object
455:     */
456:    this.toByteArray = function() {
457:       if (!this.exists())
458:          return null;
459:       var body = new java.io.ByteArrayOutputStream();
460:       var stream = new java.io.BufferedInputStream(
461:          new java.io.FileInputStream(this.getAbsolutePath())
462:       );
463:       var buf = java.lang.reflect.Array.newInstance(
464:          java.lang.Byte.TYPE, 1024
465:       );
466:       var read;
467:       while ((read = stream.read(buf)) > -1)
468:          body.write(buf, 0, read);
469:       stream.close();
470:       return body.toByteArray();
471:    };
472: 
473:    for (var i in this)
474:       this.dontEnum(i);
475: 
476:    return this;
477: }