KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > aspects > persistence > FSStorage


1 /*
2   Copyright (C) 2001-2003 Laurent Martelli <laurent@aopsys.com>
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program 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 Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

17
18 package org.objectweb.jac.aspects.persistence;
19
20 import java.io.BufferedReader JavaDoc;
21 import java.io.BufferedWriter JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.FileDescriptor JavaDoc;
24 import java.io.FileInputStream JavaDoc;
25 import java.io.FileNotFoundException JavaDoc;
26 import java.io.FileOutputStream JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.InputStreamReader JavaDoc;
29 import java.io.OutputStream JavaDoc;
30 import java.io.OutputStreamWriter JavaDoc;
31 import java.io.PrintWriter JavaDoc;
32 import java.io.StreamTokenizer JavaDoc;
33 import java.io.Writer JavaDoc;
34 import java.util.Collection JavaDoc;
35 import java.util.Hashtable JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.List JavaDoc;
38 import java.util.Map JavaDoc;
39 import java.util.Properties JavaDoc;
40 import java.util.Set JavaDoc;
41 import java.util.Vector JavaDoc;
42 import org.apache.log4j.Logger;
43 import org.objectweb.jac.aspects.naming.NameGenerator;
44 import org.objectweb.jac.core.rtti.ClassItem;
45 import org.objectweb.jac.core.rtti.CollectionItem;
46 import org.objectweb.jac.core.rtti.FieldItem;
47 import org.objectweb.jac.util.Files;
48 import org.objectweb.jac.util.Log;
49 import org.objectweb.jac.util.Semaphore;
50 import org.objectweb.jac.util.Strings;
51
52 /**
53  * A FileSystem storage
54  */

55
56 public class FSStorage implements Storage {
57     static Logger logger = Logger.getLogger("persistence.storage");
58
59     // name -> oid
60
private Hashtable JavaDoc names = new Hashtable JavaDoc();
61     // oid -> name
62
private Hashtable JavaDoc oids = new Hashtable JavaDoc();
63     // oid -> classid
64
private Hashtable JavaDoc classes = new Hashtable JavaDoc();
65    
66     private File JavaDoc basedir;
67     private File JavaDoc oidsFile;
68     private File JavaDoc classesFile;
69
70     /* The encoding of files */
71     protected String JavaDoc encoding;
72
73     private long lastOID = 0;
74
75     Semaphore semaphore = new Semaphore(1);
76
77     NameGenerator nameGen;
78     File JavaDoc nameCountersFile;
79
80     /**
81      * Create a new file system storage with the default encoding
82      * @param basedirName name of the directory where to store data files
83      */

84     public FSStorage(PersistenceAC ac,
85                      String JavaDoc basedirName) throws Exception JavaDoc {
86         this(ac,basedirName,System.getProperty("file.encoding"));
87     }
88
89     /**
90      * Create a new file system storage
91      * @param basedirName name of the directory where to store data files
92      * @param encoding the encoding to use for files
93      */

94     public FSStorage(PersistenceAC ac,
95                      String JavaDoc basedirName, String JavaDoc encoding)
96         throws Exception JavaDoc
97     {
98         this.ac = ac;
99         logger.debug("new FSStorage(basedir="+basedirName+", encoding="+encoding+")");
100         this.encoding = encoding;
101         basedir = new File JavaDoc(Files.expandFileName(basedirName));
102         if (!basedir.isAbsolute()) {
103             basedir = new File JavaDoc(org.objectweb.jac.core.Jac.getJacRoot(),basedir.toString());
104         }
105         if (! basedir.isDirectory()) {
106             basedir.mkdirs();
107         }
108
109         nameGen = new NameGenerator();
110
111         nameCountersFile = new File JavaDoc(basedir,"nameCounters");
112         try {
113             nameCountersFile.createNewFile();
114             readNameCounters();
115         } catch(Exception JavaDoc e) {
116             e.printStackTrace();
117         }
118
119         classesFile = new File JavaDoc(basedir,"classes");
120         try {
121             classesFile.createNewFile();
122             readClasses();
123         } catch(Exception JavaDoc e) {
124             e.printStackTrace();
125         }
126
127         oidsFile = new File JavaDoc(basedir,"oids");
128         //try {
129
oidsFile.createNewFile();
130             readOids();
131             /*
132         } catch(Exception e) {
133             e.printStackTrace();
134         }
135             */

136       
137         updateJacNames();
138     }
139
140     PersistenceAC ac;
141
142     protected String JavaDoc id;
143     public String JavaDoc getId() {
144         return id;
145     }
146     public void setId(String JavaDoc id) {
147         this.id = id;
148     }
149
150     protected void updateJacNames() {
151         try {
152             Iterator JavaDoc it = names.entrySet().iterator();
153             Hashtable JavaDoc newNames = new Hashtable JavaDoc();
154             while (it.hasNext()) {
155                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
156                 LongOID oid = (LongOID)entry.getValue();
157                 String JavaDoc name = (String JavaDoc)entry.getKey();
158                 if (name.indexOf('#')==-1) {
159                     String JavaDoc classname =
160                         Strings.getShortClassName((String JavaDoc)classes.get(oid)).toLowerCase();
161                     if (name.startsWith(classname) &&
162                         name.length()>classname.length() &&
163                         name.charAt(classname.length())!='#')
164                     {
165                         String JavaDoc newName = classname+"#"+name.substring(classname.length());
166                         it.remove();
167                         newNames.put(newName,oid);
168                         oids.put(oid,newName);
169                     }
170                 }
171             }
172             names.putAll(newNames);
173             writeOids();
174         } catch (Exception JavaDoc e) {
175             logger.error("Failed to update jac names");
176         }
177     }
178
179     /**
180      * Safely close the storage. Waits for all operations to terminate.
181      */

182     public void close() {
183         // wait for completion of deleteObject
184
semaphore.acquire();
185         logger.info("FSStorage shutdown hook completed");
186     }
187
188     /**
189      * Read the "oids" file
190      */

191     void readOids() throws Exception JavaDoc
192     {
193         oidsFile.createNewFile();
194         StreamTokenizer JavaDoc tokens = getStreamTokenizer(oidsFile);
195
196         boolean corruptedCounter = false;
197         while (tokens.nextToken() != StreamTokenizer.TT_EOF) {
198             logger.debug("token : "+tokens.sval+"/"+tokens.nval+" "+tokens.ttype);
199             LongOID oid = ac.parseLongOID(tokens.sval,this);
200             long oidval = oid.getOID();
201             if (oidval>lastOID)
202                 lastOID = oidval;
203             tokens.nextToken();
204             logger.debug("token : "+tokens.sval+"/"+tokens.nval+" "+tokens.ttype);
205             String JavaDoc name = tokens.sval;
206             String JavaDoc classid = getClassID(oid);
207             if (names.containsKey(name)) {
208                 logger.error("Corrupted storage! OIDs "+
209                              names.get(name)+" and "+oid+" have the same name "+name+
210                              ". Assigning new name to "+oid);
211                 name = newName(classid);
212                 logger.error(" new name is "+name);
213             }
214             oids.put(oid,name);
215             names.put(name,oid);
216
217             // Ensure counters integrity
218
try {
219                 long count = nameGen.getCounterFromName(name);
220                 long current = nameGen.getCounter(classid);
221                 if (current!=-1 && current <= count) {
222                     logger.error("Corrupted counter for "+classid+". Adjusting "+current+"->"+(count+1));
223                     nameGen.setCounter(classid,count+1);
224                     corruptedCounter = true;
225                 }
226             } catch(Exception JavaDoc e) {
227             }
228         }
229         if (corruptedCounter) {
230             writeNameCounters();
231         }
232     }
233
234     /**
235      * Writer the "oids" file
236      */

237     void writeOids() throws Exception JavaDoc
238     {
239         logger.debug("writeOids");
240         PrintWriter JavaDoc writer = getPrintWriter(oidsFile,false,false);
241         try {
242             Iterator JavaDoc it = oids.entrySet().iterator();
243             while (it.hasNext()) {
244                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
245                 writer.println(((OID)entry.getKey()).localId()+" "+entry.getValue());
246             }
247         } finally {
248             writer.close();
249         }
250     }
251
252     /**
253      * Read the "nameCounters" file
254      */

255     void readNameCounters() throws IOException JavaDoc, FileNotFoundException JavaDoc
256     {
257         nameCountersFile.createNewFile();
258         StreamTokenizer JavaDoc tokens = getStreamTokenizer(nameCountersFile);
259         while (tokens.nextToken() != StreamTokenizer.TT_EOF) {
260             String JavaDoc className = tokens.sval;
261             tokens.nextToken();
262             Long JavaDoc counter = new Long JavaDoc(tokens.sval);
263             logger.debug(className+" -> "+counter);
264             nameGen.put(className,counter);
265         }
266     }
267
268     FileDescriptor JavaDoc nameCountersFD;
269     /**
270      * Write the "nameCounters" file
271      */

272     void writeNameCounters() throws IOException JavaDoc {
273         logger.debug("writeNameCounters");
274         PrintWriter JavaDoc writer;
275         FileOutputStream JavaDoc stream = new FileOutputStream JavaDoc(nameCountersFile.toString(),false);
276         writer = getPrintWriter(stream,false);
277         writeMap(nameGen,writer);
278     }
279
280     public Map JavaDoc getNameCounters() {
281         return nameGen;
282     }
283
284     public void updateNameCounters(Map JavaDoc counters) throws IOException JavaDoc {
285         nameGen.update(counters);
286         writeNameCounters();
287     }
288
289     /**
290      * Write the content of a Map to a File, using the toString() of
291      * the keys and values. Does nothing if the map is empty.
292      *
293      * @param map the map
294      * @param file the file
295      */

296     void writeMapToFile(Map JavaDoc map, File JavaDoc file) throws IOException JavaDoc {
297         if (map.isEmpty()) {
298             file.delete();
299         } else {
300             PrintWriter JavaDoc writer = getPrintWriter(file,false,false);
301             try {
302                 Iterator JavaDoc it = map.entrySet().iterator();
303                 while (it.hasNext()) {
304                     Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
305                     writer.println(entry.getKey().toString()+" "+entry.getValue());
306                 }
307             } finally {
308                 writer.close();
309             }
310         }
311     }
312
313     void writeMap(Map JavaDoc map, PrintWriter JavaDoc writer) throws IOException JavaDoc {
314         try {
315             Iterator JavaDoc it = map.entrySet().iterator();
316             while (it.hasNext()) {
317                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
318                 writer.println(entry.getKey().toString()+" "+entry.getValue());
319             }
320         } finally {
321             writer.close();
322         }
323     }
324
325     void readClasses() throws Exception JavaDoc
326     {
327         logger.debug("readClasses");
328         classesFile.createNewFile();
329         StreamTokenizer JavaDoc tokens = getStreamTokenizer(classesFile);
330         while (tokens.nextToken() != StreamTokenizer.TT_EOF) {
331             LongOID oid = new LongOID(this,Long.parseLong(tokens.sval));
332             long oidval = oid.getOID();
333             if (oidval>lastOID)
334                 lastOID = oidval;
335             tokens.nextToken();
336             String JavaDoc classid = tokens.sval;
337             logger.debug(oid.toString()+" -> "+classid);
338             classes.put(oid,classid);
339         }
340     }
341
342     void writeClasses() throws Exception JavaDoc
343     {
344         logger.debug("writeClasses");
345         writeMapToFile(classes,classesFile);
346     }
347
348     protected StreamTokenizer JavaDoc getStreamTokenizer(File JavaDoc file)
349         throws FileNotFoundException JavaDoc, IOException JavaDoc
350     {
351         StreamTokenizer JavaDoc tokens =
352             new StreamTokenizer JavaDoc(
353                 new BufferedReader JavaDoc(
354                     new InputStreamReader JavaDoc(
355                         new FileInputStream JavaDoc(file),
356                         encoding)));
357         tokens.resetSyntax();
358         tokens.wordChars('\000','\377');
359         tokens.whitespaceChars(' ',' ');
360         tokens.whitespaceChars('\t','\t');
361         tokens.whitespaceChars('\n','\n');
362         tokens.whitespaceChars('\r','\r');
363         return tokens;
364     }
365
366     public OID createObject(String JavaDoc className) throws Exception JavaDoc
367     {
368         semaphore.acquire();
369         PrintWriter JavaDoc writer = null;
370         try {
371             lastOID++;
372             LongOID oid = new LongOID(this,lastOID);
373             classes.put(oid,className);
374             writer = new PrintWriter JavaDoc(getWriter(classesFile,true),true);
375             writer.println(oid.localId()+" "+className);
376             return oid;
377         } finally {
378             if (writer!=null)
379                 writer.close();
380             semaphore.release();
381         }
382     }
383
384     public void deleteObject(OID oid) throws Exception JavaDoc
385     {
386         semaphore.acquire();
387         try {
388             logger.debug("deleteObject("+oid+")");
389             String JavaDoc name = (String JavaDoc)oids.get(oid);
390             if (name!=null) {
391                 names.remove(name);
392                 oids.remove(oid);
393                 writeOids();
394             } else {
395                 logger.warn("FSStorage.deleteObject: oid "+
396                                oid+" does not have name");
397                 logger.debug("names = "+classes);
398             }
399             if (classes.containsKey(oid)) {
400                 classes.remove(oid);
401                 writeClasses();
402             } else {
403                 logger.warn("FSStorage.deleteObject: oid "+
404                                oid+" does not have a class");
405                 logger.debug("classes = "+classes);
406             }
407         } catch(Exception JavaDoc e) {
408             e.printStackTrace();
409         } finally {
410             logger.debug("deleteObject("+oid+") DONE");
411             semaphore.release();
412         }
413         // *** TODO: WE SHOULD ALSO REMOVE COLLECTIONS OWNED BY THE
414
// *** DELETED OBJECT
415
}
416
417     public void setField(OID oid, FieldItem field, Object JavaDoc value)
418         throws Exception JavaDoc
419     {
420         logger.debug("setField("+oid+","+field+","+value+")");
421         Properties JavaDoc props = new Properties JavaDoc();
422         File JavaDoc objectFile = new File JavaDoc(basedir,oid.localId());
423         objectFile.createNewFile();
424         props.load(new FileInputStream JavaDoc(objectFile));
425         props.setProperty(
426             field.getName(),
427             ValueConverter.objectToString(this,value));
428         props.store(new FileOutputStream JavaDoc(objectFile),getClassID(oid)+" "+oid.localId());
429     }
430
431     public void updateField(OID oid, FieldItem field, Object JavaDoc value)
432         throws Exception JavaDoc
433     {
434         logger.debug("updateField("+oid+","+field+","+value+")");
435         setField(oid,field,value);
436     }
437
438     /** oid -> Properties */
439     Hashtable JavaDoc cache = new Hashtable JavaDoc();
440
441     public Object JavaDoc getField(OID oid, FieldItem field)
442         throws Exception JavaDoc
443     {
444         logger.debug("getField("+oid+","+field+")");
445         Object JavaDoc ret = null;
446         Properties JavaDoc props = (Properties JavaDoc)cache.get(oid);
447         if (props==null) {
448             props = new Properties JavaDoc();
449             File JavaDoc objectFile = new File JavaDoc(basedir,oid.localId());
450             if (objectFile.exists())
451                 props.load(new FileInputStream JavaDoc(objectFile));
452             cache.put(oid,props);
453         }
454         String JavaDoc value = (String JavaDoc)props.get(field.getName());
455         if (value != null) {
456             ret = ValueConverter.stringToObject(this,value);
457         } else {
458             if (field.isPrimitive()) {
459                 logger.warn("no such field in storage "+oid+","+field.getName());
460             }
461             ret = null;
462         }
463         logger.debug(" -> "+ret);
464         return ret;
465     }
466
467     protected Properties JavaDoc getFields(OID oid) throws IOException JavaDoc
468     {
469         Properties JavaDoc props = new Properties JavaDoc();
470         File JavaDoc f = new File JavaDoc(basedir,oid.localId());
471         if (f.exists())
472             props.load(new FileInputStream JavaDoc(f));
473         return props;
474     }
475
476     public StorageField[] getFields(OID oid, ClassItem cl, FieldItem[] fields)
477         throws Exception JavaDoc
478     {
479         Properties JavaDoc props = getFields(oid);
480         StorageField ret[] = new StorageField[fields.length];
481         int count = 0;
482         for (int i=0; i<fields.length; i++) {
483             if (!fields[i].isCalculated() && !fields[i].isTransient()) {
484                 String JavaDoc value = (String JavaDoc)props.get(fields[i].getName());
485                 if (value!=null)
486                     ret[i] =
487                         new StorageField(
488                             cl,
489                             fields[i],
490                             ValueConverter.stringToObject(this,value));
491                 else
492                     ret[i] = new StorageField(cl,fields[i],null);
493             }
494         }
495         return ret;
496     }
497
498     // Collection methods
499

500     protected long getCollectionSize(OID cid) throws Exception JavaDoc
501     {
502         return getList(cid).size();
503     }
504
505     public OID getCollectionID(OID oid, CollectionItem collection)
506         throws Exception JavaDoc
507     {
508         return (OID)getField(oid,collection);
509     }
510
511     // List methods
512

513     public void clearList(OID cid) throws Exception JavaDoc
514     {
515         saveList(cid,new Vector JavaDoc());
516     }
517
518     public List JavaDoc getList(OID oid, CollectionItem collection)
519         throws Exception JavaDoc
520     {
521         logger.debug("getList("+oid+","+collection+")");
522         return getList(getCollectionID(oid,collection));
523     }
524
525     public List JavaDoc getList(OID cid)
526         throws Exception JavaDoc
527     {
528         logger.debug("getList("+cid+")");
529         File JavaDoc file = new File JavaDoc(basedir,cid.localId());
530         Vector JavaDoc ret = new Vector JavaDoc();
531         if (file.exists()) {
532             StreamTokenizer JavaDoc tokens = getStreamTokenizer(file);
533             while (tokens.nextToken() != StreamTokenizer.TT_EOF) {
534                 try {
535                     ret.add(
536                         ValueConverter.stringToObject(
537                             this,
538                             Strings.unslashify(tokens.sval)));
539                 } catch (Throwable JavaDoc e) {
540                     logger.error("failed to list element: "+tokens.sval,e);
541                 }
542             }
543         }
544         logger.debug("getList returns "+ret);
545         return ret;
546     }
547
548     public long getListSize(OID cid) throws Exception JavaDoc {
549         logger.debug("getListSize("+cid+")");
550
551         File JavaDoc file = new File JavaDoc(basedir,cid.localId());
552         long size = 0;
553         if (file.exists()) {
554             StreamTokenizer JavaDoc tokens = getStreamTokenizer(file);
555             while (tokens.nextToken() != StreamTokenizer.TT_EOF) {
556                 size++;
557             }
558         }
559
560         return size;
561     }
562
563     public Object JavaDoc getListItem(OID cid, long index)
564         throws Exception JavaDoc, IndexOutOfBoundsException JavaDoc
565     {
566         logger.debug("getListItem("+cid+","+index+")");
567
568         File JavaDoc file = new File JavaDoc(basedir,cid.localId());
569         Vector JavaDoc ret = new Vector JavaDoc();
570         long current = 0;
571         if (file.exists()) {
572             StreamTokenizer JavaDoc tokens = getStreamTokenizer(file);
573             while (tokens.nextToken() != StreamTokenizer.TT_EOF) {
574                 if (current==index) {
575                     return
576                         ValueConverter.stringToObject(
577                             this,Strings.unslashify(tokens.sval));
578                 }
579                 current++;
580             }
581         }
582
583         throw new IndexOutOfBoundsException JavaDoc(cid+"["+index+"]");
584     }
585
586     public boolean listContains(OID cid, Object JavaDoc value)
587         throws Exception JavaDoc
588     {
589         logger.debug("listContains("+cid+","+value+")");
590         return getList(cid).contains(value);
591     }
592
593     protected void saveList(OID cid, List JavaDoc list)
594         throws IOException JavaDoc
595     {
596         logger.debug("saveList("+cid+","+list+")");
597         File JavaDoc file = new File JavaDoc(basedir,cid.localId());
598         logger.debug("file = "+file);
599         if (list.isEmpty()) {
600             file.delete();
601         } else {
602             PrintWriter JavaDoc writer = getPrintWriter(file,false,true);
603             try {
604                 for (int i=0; i<list.size(); i++) {
605                     String JavaDoc value =
606                         ValueConverter.objectToString(this,list.get(i));
607                     logger.debug(" -> "+value);
608                     writer.println(Strings.slashify(value));
609                 }
610             } finally {
611                 writer.close();
612             }
613         }
614     }
615
616     public void addToList(OID cid, long position, Object JavaDoc value)
617         throws Exception JavaDoc
618     {
619         logger.debug("addToList("+cid+","+position+","+value+")");
620         List JavaDoc list = getList(cid);
621         list.add((int)position,value);
622         saveList(cid,list);
623     }
624
625     public void addToList(OID cid, Object JavaDoc value)
626         throws Exception JavaDoc
627     {
628         logger.debug("addToList("+cid+","+value+")");
629
630         PrintWriter JavaDoc writer = getPrintWriter((LongOID)cid,true,true);
631         try {
632             writer.println(
633                 Strings.slashify(ValueConverter.objectToString(this,value)));
634         } finally {
635             writer.close();
636         }
637     }
638
639     public void setListItem(OID cid, long index, Object JavaDoc value)
640         throws Exception JavaDoc
641     {
642         List JavaDoc list = getList(cid);
643         list.set((int)index,value);
644         saveList(cid,list);
645     }
646
647     public void removeFromList(OID cid, long position)
648         throws Exception JavaDoc
649     {
650         List JavaDoc list = getList(cid);
651         list.remove((int)position);
652         saveList(cid,list);
653     }
654
655     public void removeFromList(OID cid, Object JavaDoc value)
656         throws Exception JavaDoc
657     {
658         List JavaDoc list = getList(cid);
659         list.remove(value);
660         saveList(cid,list);
661     }
662
663     public long getIndexInList(OID cid, Object JavaDoc value)
664         throws Exception JavaDoc
665     {
666         List JavaDoc list = getList(cid);
667         return list.indexOf(value);
668     }
669
670     public long getLastIndexInList(OID cid, Object JavaDoc value)
671         throws Exception JavaDoc
672     {
673         List JavaDoc list = getList(cid);
674         return list.lastIndexOf(value);
675     }
676
677
678     // Set methods
679

680     public void clearSet(OID cid) throws Exception JavaDoc
681     {
682         saveList(cid,new Vector JavaDoc());
683     }
684
685     public List JavaDoc getSet(OID oid, CollectionItem collection)
686         throws Exception JavaDoc
687     {
688         return getSet(getCollectionID(oid,collection));
689     }
690
691     public List JavaDoc getSet(OID cid)
692         throws Exception JavaDoc
693     {
694         return getList(cid);
695     }
696
697     public long getSetSize(OID cid) throws Exception JavaDoc {
698         return getCollectionSize(cid);
699     }
700
701     public boolean addToSet(OID cid, Object JavaDoc value)
702         throws Exception JavaDoc
703     {
704         logger.debug("addToSet("+cid+","+value+")");
705         List JavaDoc list = getList(cid);
706         boolean ret = list.add(value);
707         saveList(cid,list);
708         return ret;
709     }
710
711     public boolean removeFromSet(OID cid, Object JavaDoc value)
712         throws Exception JavaDoc
713     {
714         logger.debug("addToSet("+cid+","+value+")");
715         List JavaDoc list = getList(cid);
716         boolean ret = list.remove(value);
717         saveList(cid,list);
718         return ret;
719     }
720
721     public boolean setContains(OID cid, Object JavaDoc value)
722         throws Exception JavaDoc
723     {
724         return getList(cid).contains(value);
725     }
726
727     // Map methods
728

729     public Map JavaDoc getMap(OID oid, CollectionItem collection)
730         throws Exception JavaDoc
731     {
732         return getMap(getCollectionID(oid,collection));
733     }
734
735     public Map JavaDoc getMap(OID cid)
736         throws Exception JavaDoc
737     {
738         logger.debug("getMap("+cid+")");
739         File JavaDoc file = new File JavaDoc(basedir,cid.localId());
740         Hashtable JavaDoc ret = new Hashtable JavaDoc();
741         if (file.exists()) {
742             StreamTokenizer JavaDoc tokens = getStreamTokenizer(file);
743             while (tokens.nextToken() != StreamTokenizer.TT_EOF) {
744                 Object JavaDoc key =
745                     ValueConverter.stringToObject(
746                         this,Strings.unslashify(tokens.sval));
747                 tokens.nextToken();
748                 Object JavaDoc value =
749                     ValueConverter.stringToObject(
750                         this,Strings.unslashify(tokens.sval));
751                 logger.debug(" -> "+key+","+value);
752                 ret.put(key,value);
753             }
754         }
755         return ret;
756     }
757
758     public long getMapSize(OID cid) throws Exception JavaDoc {
759         return getCollectionSize(cid);
760     }
761
762     protected void saveMap(OID cid, Map JavaDoc map)
763         throws IOException JavaDoc
764     {
765         logger.debug("saveMap("+cid+","+map+")");
766         File JavaDoc file = new File JavaDoc(basedir,cid.localId());
767         if (map.isEmpty()) {
768             file.delete();
769         } else {
770             logger.debug("file = "+file);
771             PrintWriter JavaDoc writer = getPrintWriter(file,false,true);
772             try {
773                 Set JavaDoc entrySet = map.entrySet();
774                 Iterator JavaDoc i = entrySet.iterator();
775                 while (i.hasNext()) {
776                     Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
777                     String JavaDoc value =
778                         ValueConverter.objectToString(this,entry.getValue());
779                     String JavaDoc key =
780                         ValueConverter.objectToString(this,entry.getKey());
781                     logger.debug(" -> "+key+","+value);
782                     writer.println(Strings.slashify(key)+" "+Strings.slashify(value));
783                 }
784             } finally {
785                 writer.close();
786             }
787         }
788     }
789
790     public void clearMap(OID cid) throws Exception JavaDoc
791     {
792         saveMap(cid,new Hashtable JavaDoc());
793     }
794
795     public Object JavaDoc putInMap(OID cid, Object JavaDoc key, Object JavaDoc value)
796         throws Exception JavaDoc
797     {
798         Map JavaDoc map = getMap(cid);
799         Object JavaDoc ret = map.put(key,value);
800         saveMap(cid,map);
801         return ret;
802     }
803
804     public Object JavaDoc getFromMap(OID cid, Object JavaDoc key)
805         throws Exception JavaDoc
806     {
807         return getMap(cid).get(key);
808     }
809
810     public boolean mapContainsKey(OID cid, Object JavaDoc key)
811         throws Exception JavaDoc
812     {
813         return getMap(cid).containsKey(key);
814     }
815
816     public boolean mapContainsValue(OID cid, Object JavaDoc value)
817         throws Exception JavaDoc
818     {
819         return getMap(cid).containsValue(value);
820     }
821
822     public Object JavaDoc removeFromMap(OID cid, Object JavaDoc key)
823         throws Exception JavaDoc
824     {
825         logger.debug("removeFromMap("+cid+","+key+")");
826         Map JavaDoc map = getMap(cid);
827         Object JavaDoc ret = map.remove(key);
828         saveMap(cid,map);
829         return ret;
830     }
831
832     // others...
833

834     public void removeField(OID oid, FieldItem field, Object JavaDoc value)
835         throws Exception JavaDoc
836     {}
837
838     public synchronized String JavaDoc newName(String JavaDoc className) throws Exception JavaDoc {
839         semaphore.acquire();
840         try {
841             String JavaDoc name = nameGen.generateName(className);
842             writeNameCounters();
843             return name;
844         } finally {
845             semaphore.release();
846         }
847     }
848
849     public OID getOIDFromName(String JavaDoc name) throws Exception JavaDoc {
850         return (OID)names.get(name);
851     }
852
853     public String JavaDoc getNameFromOID(OID oid) throws Exception JavaDoc {
854         return (String JavaDoc)oids.get(oid);
855     }
856
857     public void bindOIDToName(OID oid,String JavaDoc name) throws Exception JavaDoc
858     {
859         semaphore.acquire();
860         PrintWriter JavaDoc writer = null;
861         try {
862             names.put(name,oid);
863             oids.put(oid,name);
864             writer = getPrintWriter(oidsFile,true,true);
865             writer.println(oid.localId()+" "+name);
866         } finally {
867             if (writer!=null)
868                 writer.close();
869             semaphore.release();
870         }
871     }
872
873     public void deleteName(String JavaDoc name) throws Exception JavaDoc
874     {}
875
876     public String JavaDoc getClassID(OID oid) throws Exception JavaDoc {
877         logger.debug("getClassID("+oid+") -> "+(String JavaDoc)classes.get(oid));
878         return (String JavaDoc)classes.get(oid);
879     }
880
881     public Collection JavaDoc getRootObjects() throws Exception JavaDoc {
882         return oids.keySet();
883     }
884
885     public Collection JavaDoc getObjects(ClassItem cl) throws Exception JavaDoc {
886         logger.debug("getObjects("+cl+")");
887         if (cl == null) {
888             return classes.keySet();
889         } else {
890             Vector JavaDoc ret = new Vector JavaDoc();
891             getObjects(cl,ret);
892             return ret;
893         }
894     }
895
896     /**
897      * Gets all instances of a class and its subclasses.
898      * @param cl the class
899      * @param objects instances of the class are added to this collection
900      */

901     protected void getObjects(ClassItem cl, Vector JavaDoc objects) throws Exception JavaDoc {
902         logger.debug("getObjects("+cl+")");
903         Set JavaDoc entries = classes.entrySet();
904         Iterator JavaDoc i = entries.iterator();
905         while(i.hasNext()) {
906             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
907             logger.debug("testing "+entry.getValue());
908             if (cl==null || entry.getValue().equals(cl.getName())) {
909                 objects.add(entry.getKey());
910             }
911         }
912         i = cl.getChildren().iterator();
913         while(i.hasNext()) {
914             ClassItem subclass = (ClassItem)i.next();
915             getObjects(subclass,objects);
916         }
917     }
918
919
920     public void startTransaction() {
921     }
922
923     public void commit() {
924     }
925
926     public void rollback() {
927     }
928
929     protected PrintWriter JavaDoc getPrintWriter(OID oid, boolean append, boolean autoFlush)
930         throws IOException JavaDoc
931     {
932         return getPrintWriter(new File JavaDoc(basedir,oid.localId()),append,autoFlush);
933     }
934
935     protected PrintWriter JavaDoc getPrintWriter(File JavaDoc file, boolean append, boolean autoFlush)
936         throws IOException JavaDoc
937     {
938         return
939             new PrintWriter JavaDoc(
940                 // The default buffer size is much too big
941
new BufferedWriter JavaDoc(getWriter(file,append),1024),
942                 autoFlush);
943     }
944
945     protected PrintWriter JavaDoc getPrintWriter(OutputStream JavaDoc stream, boolean autoFlush)
946         throws IOException JavaDoc
947     {
948         return
949             new PrintWriter JavaDoc(
950                 new BufferedWriter JavaDoc(
951                     new OutputStreamWriter JavaDoc(stream,encoding),
952                     1024), // The default buffer size is much too big
953
autoFlush);
954     }
955
956     protected Writer JavaDoc getWriter(File JavaDoc file, boolean append) throws IOException JavaDoc {
957         return
958             new OutputStreamWriter JavaDoc(
959                 new FileOutputStream JavaDoc(file.toString(),append),
960                 encoding);
961
962     }
963 }
964
Popular Tags