new js api
[org.ibex.core.git] / src / org / ibex / js / Directory.java
1 // Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL] 
2 package org.ibex.js; 
3
4 import org.ibex.util.*; 
5 import java.util.*;
6 import java.io.*;
7
8 // FEATURE: support for move
9 // FEATURE: support for bytestreams
10 // FEATURE: cache directories so we can do equality checking on them?
11 // FEATURE: autoconvert "true" to true and "0.3" to 0.3 on readback
12
13 /** 
14  * A crude mechanism for using a filesystem as object storage.
15  *
16  *  This object represents a directory; writing a string, number, or
17  *  boolean to any of its properties will create a file with the
18  *  (encoded) property name as its filename and the "stringified"
19  *  value as its contents.
20  *
21  *  Writing 'null' to one of this object's properties will
22  *  [recursively if necessary] delete the corresponding directory
23  *  entry.
24  *  
25  *  Writing any other object to one of this object's properties will
26  *  create a new Directory object and copy the other object's keys()
27  *  into the new Directory.  This means that assigning one directory
28  *  to a property of another directory will <i>copy</i> the directory,
29  *  not move it.  There is currently no way to move directories.
30  *
31  *  If an object is written to a property that already has an entry,
32  *  the old one is deleted (equivalent to writing 'null') first.
33  * 
34  *  WARNING: when instantiating a Directory object with a file
35  *  argument that points to a non-directory File, this class will
36  *  delete that file and create a directory!
37  */
38 public class Directory extends JS {
39
40     File f;
41
42     /** 
43      *  Create the directory object.  Existing directories will be
44      *  preserved; if a file is present it will be obliterated.
45      */ 
46     // FIXME: Update this for new API
47     /*public Directory(File f) throws IOException {
48         this.f = f;
49         if (!f.exists()) new Directory(new File(f.getParent()));
50         if (!f.isDirectory()) destroy(f);
51         f.mkdirs();
52     }
53
54     private static void destroy(File f) throws IOException {
55         if (!f.exists()) return;
56         if (f.isDirectory()) {
57             String[] entries = f.list();
58             for(int i=0; i<entries.length; i++) destroy(new File(f.getAbsolutePath() + File.separatorChar + entries[i]));
59         }
60         f.delete();
61     }
62
63     public void put(Object key0, Object val) throws JSExn {
64         try {
65             if (key0 == null) return;
66             String key = toString(key0);
67             File f2 = new File(f.getAbsolutePath() + File.separatorChar + FileNameEncoder.encode(key));
68             destroy(f2);
69             if (val == null) return;
70             if (val instanceof JS) {
71                 Directory d2 = new Directory(f2);
72                 Enumeration e = ((JS)val).keys();
73                 while(e.hasMoreElements()) {
74                     String k = (String)e.nextElement();
75                     Object v = ((JS)val).get(k);
76                     d2.put(k, v);
77                 }
78             } else {
79                 OutputStream out = new FileOutputStream(f2);
80                 Writer w = new OutputStreamWriter(out);
81                 w.write(toString(val));
82                 w.flush();
83                 out.close();
84             }
85         } catch (IOException ioe) {
86             throw new JSExn.IO(ioe);
87         }
88     }
89
90     public Object get(Object key0) throws JSExn {
91         try {
92             if (key0 == null) return null;
93             String key = toString(key0);
94             File f2 = new File(f.getAbsolutePath() + File.separatorChar + FileNameEncoder.encode(key));
95             if (!f2.exists()) return null;
96             if (f2.isDirectory()) return new Directory(f2);
97             char[] chars = new char[((int)f2.length()) * 2];
98             int numchars = 0;
99             Reader r = new InputStreamReader(new FileInputStream(f2));
100             while(true) {
101                 int numread = r.read(chars, numchars, chars.length - numchars);
102                 if (numread == -1) return new String(chars, 0, numchars);
103                 numchars += numread;
104             }
105         } catch (IOException ioe) {
106             throw new JSExn.IO(ioe);
107         }
108     }
109
110     public Enumeration keys() {
111         final String[] elements = f.list();
112         return new Enumeration() {
113                 int i = 0;
114                 public boolean hasMoreElements() { return i < elements.length; }
115                 public Object nextElement() { return FileNameEncoder.decode(elements[i++]); }
116             };
117     }*/
118 }