Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: javax/microedition/rms/RecordStore.java


1   /*
2    *  MicroEmulator
3    *  Copyright (C) 2001 Bartek Teodorczyk <barteo@it.pl>
4    *
5    *  This library is free software; you can redistribute it and/or
6    *  modify it under the terms of the GNU Lesser General Public
7    *  License as published by the Free Software Foundation; either
8    *  version 2.1 of the License, or (at your option) any later version.
9    *
10   *  This library is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   *  Lesser General Public License for more details.
14   *
15   *  You should have received a copy of the GNU Lesser General Public
16   *  License along with this library; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19   
20  package javax.microedition.rms;
21  
22  import java.util.Enumeration;
23  import java.util.Hashtable;
24  import java.util.Vector;
25  
26  
27  public class RecordStore 
28  {
29    /**
30     * @associates RecordStore 
31     */
32    private static Hashtable recordStores = new Hashtable();
33    
34    private String name;
35    private boolean open = false;
36    private int version = 0;
37    private long lastModified = 0;
38    private int nextRecordID = 1;
39  
40    /**
41     * @associates RecordListener 
42     */
43    private Vector recordListeners = new Vector();
44    private Hashtable records = new Hashtable();
45    
46    
47    private RecordStore(String name)
48    {
49      this.name = name;
50    }
51    
52    
53    public static void deleteRecordStore(String recordStoreName)
54        throws RecordStoreException, RecordStoreNotFoundException
55    {
56      RecordStore recordStore = (RecordStore) recordStores.get(recordStoreName);
57      if (recordStore == null) {
58        throw new RecordStoreNotFoundException();
59      }
60      if (recordStore.open) {
61        throw new RecordStoreException();
62      }
63      
64      recordStores.remove(recordStoreName);
65    }
66    
67    
68    public static RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary)
69        throws RecordStoreException, RecordStoreFullException, RecordStoreNotFoundException
70    {
71      RecordStore recordStore = (RecordStore) recordStores.get(recordStoreName);
72      if (recordStore == null) {
73        if (!createIfNecessary) {
74          throw new RecordStoreNotFoundException();
75        }
76        recordStore = new RecordStore(recordStoreName);
77        recordStores.put(recordStoreName, recordStore);
78      }
79      recordStore.open = true;
80      
81      return recordStore;
82    }
83    
84    
85    public void closeRecordStore()
86        throws RecordStoreNotOpenException, RecordStoreException
87    {
88      if (!open) {
89        throw new RecordStoreNotOpenException();
90      }
91      
92      recordListeners.removeAllElements();
93      open = false;
94    }
95    
96    
97    public static String[] listRecordStores()
98    {
99      String[] result = new String[recordStores.size()];
100     
101     int i = 0;
102     for (Enumeration e = recordStores.keys(); e.hasMoreElements(); ) {
103       result[i] = (String) e.nextElement();
104       i++;
105     }
106     
107     return result;
108   }
109   
110   
111   public String getName()
112   {
113     return name;
114   }
115   
116   
117   public int getVersion()
118       throws RecordStoreNotOpenException
119   {
120     if (!open) {
121       throw new RecordStoreNotOpenException();
122     }
123     
124     synchronized (this) {
125       return version;
126     }
127   }
128 
129 
130   public int getNumRecords()
131       throws RecordStoreNotOpenException
132   {
133     if (!open) {
134       throw new RecordStoreNotOpenException();
135     }
136     
137     synchronized (this) {
138       return records.size();
139     }
140   }
141 
142 
143   public int getSizeAvailable()
144   {
145     return (int) Runtime.getRuntime().freeMemory();
146   }
147 
148   
149   public long getLastModified()
150       throws RecordStoreNotOpenException
151   {
152     if (!open) {
153       throw new RecordStoreNotOpenException();
154     }
155 
156     synchronized (this) {
157       return lastModified;
158     }
159   }
160 
161 
162   public void addRecordListener(RecordListener listener)
163   {
164     if (!recordListeners.contains(listener)) {
165       recordListeners.addElement(listener);
166     }
167   }
168   
169   
170   public void removeRecordListener(RecordListener listener)
171   {
172     recordListeners.removeElement(listener);
173   }
174   
175   
176   public int getNextRecordID()
177       throws RecordStoreNotOpenException, RecordStoreException
178   {
179     if (!open) {
180       throw new RecordStoreNotOpenException();
181     }
182 
183     synchronized (this) {
184       return nextRecordID;
185     }
186   }
187   
188   
189   public int addRecord(byte[] data, int offset, int numBytes)
190       throws RecordStoreNotOpenException, RecordStoreException, RecordStoreFullException
191   {
192     if (!open) {
193       throw new RecordStoreNotOpenException();
194     }    
195     if (data == null && numBytes > 0) {
196       throw new NullPointerException();
197     }
198     
199     byte[] recordData = new byte[numBytes];
200     if (data != null) {
201       System.arraycopy(data, offset, recordData, 0, numBytes);
202     }
203     
204     int curRecordID;
205     synchronized (this) {
206       records.put(new Integer(nextRecordID), recordData);
207       version++;
208       curRecordID = nextRecordID;
209       nextRecordID++;
210       lastModified = System.currentTimeMillis();
211     }
212 
213     fireAddedRecordListener(curRecordID);
214     
215     return curRecordID;  
216   }
217   
218   
219   public void deleteRecord(int recordId)
220       throws RecordStoreNotOpenException, InvalidRecordIDException, RecordStoreException
221   {
222     if (!open) {
223       throw new RecordStoreNotOpenException();
224     }
225     
226     synchronized (this) {
227       if (records.remove(new Integer(recordId)) == null) {
228         throw new InvalidRecordIDException();
229       }
230       version++;
231       lastModified = System.currentTimeMillis();
232     }
233     
234     fireDeletedRecordListener(recordId);
235   }
236   
237 
238   public int getRecordSize(int recordId)
239       throws RecordStoreNotOpenException, InvalidRecordIDException, RecordStoreException
240   {
241     if (!open) {
242       throw new RecordStoreNotOpenException();
243     }
244 
245     synchronized (this) {
246       byte[] data = (byte[]) records.get(new Integer(recordId));
247       if (data == null) {
248         throw new InvalidRecordIDException();
249       }
250       
251       return data.length;
252     }
253   }
254   
255 
256   public int getRecord(int recordId, byte[] buffer, int offset)
257       throws RecordStoreNotOpenException, InvalidRecordIDException, RecordStoreException
258   {
259     int recordSize;
260     synchronized (this) {
261       recordSize = getRecordSize(recordId);
262       System.arraycopy(records.get(new Integer(recordId)), 0, buffer, offset, recordSize);
263     }
264     
265     return recordSize;
266   }
267   
268   
269   public byte[] getRecord(int recordId)
270       throws RecordStoreNotOpenException, InvalidRecordIDException, RecordStoreException
271   {
272     byte[] data;
273     
274     synchronized (this) {
275       data = new byte[getRecordSize(recordId)];
276       getRecord(recordId, data, 0);
277     }
278     
279     return data;
280   }
281   
282   
283   public void setRecord(int recordId, byte[] newData, int offset, int numBytes)
284       throws RecordStoreNotOpenException, InvalidRecordIDException, RecordStoreException, RecordStoreFullException
285   {
286     if (!open) {
287       throw new RecordStoreNotOpenException();
288     }
289 
290     byte[] recordData = new byte[numBytes];
291     System.arraycopy(newData, offset, recordData, 0, numBytes);
292 
293     synchronized (this) {
294       Integer id = new Integer(recordId);      
295       if (records.remove(id) == null) {
296         throw new InvalidRecordIDException();
297       }      
298       records.put(id, recordData);      
299       version++;
300       lastModified = System.currentTimeMillis();
301     }
302     
303     fireChangedRecordListener(recordId);
304   }
305 
306   
307   
308   public RecordEnumeration enumerateRecords(RecordFilter filter, RecordComparator comparator, boolean keepUpdated)
309       throws RecordStoreNotOpenException
310   {
311     if (!open) {
312       throw new RecordStoreNotOpenException();
313     }
314 
315     return new RecordEnumerationImpl(filter, comparator, keepUpdated);
316   }
317   
318   
319   private void fireAddedRecordListener(int recordId)
320   {
321     for (Enumeration e = recordListeners.elements(); e.hasMoreElements(); ) {
322       ((RecordListener) e.nextElement()).recordAdded(this, recordId);
323     }
324   }
325 
326   
327   private void fireChangedRecordListener(int recordId)
328   {
329     for (Enumeration e = recordListeners.elements(); e.hasMoreElements(); ) {
330       ((RecordListener) e.nextElement()).recordChanged(this, recordId);
331     }
332   }
333 
334   
335   private void fireDeletedRecordListener(int recordId)
336   {
337     for (Enumeration e = recordListeners.elements(); e.hasMoreElements(); ) {
338       ((RecordListener) e.nextElement()).recordDeleted(this, recordId);
339     }
340   }
341   
342   
343   class RecordEnumerationImpl implements RecordEnumeration
344   {
345    
346     RecordFilter filter;
347     RecordComparator comparator;
348     boolean keepUpdated;
349     
350     /**
351      * @associates EnumerationRecord 
352      */
353     Vector enumerationRecords = new Vector();
354     int currentRecord;
355     
356     
357     RecordListener recordListener = new RecordListener()
358     {
359       
360       public void recordAdded(RecordStore recordStore, int recordId)
361       {
362         rebuild();
363       }
364 
365       
366       public void recordChanged(RecordStore recordStore, int recordId)
367       {
368         rebuild();
369       }
370   
371       
372       public void recordDeleted(RecordStore recordStore, int recordId)
373       {
374         rebuild();
375       }
376     
377     };
378     
379     
380     RecordEnumerationImpl(RecordFilter filter, RecordComparator comparator, boolean keepUpdated)
381     {
382       this.filter = filter;
383       this.comparator = comparator;
384       this.keepUpdated = keepUpdated;
385 
386       rebuild();
387       
388       if (keepUpdated) {
389         addRecordListener(recordListener);
390       }
391     }    
392     
393   
394     public int numRecords()
395     {
396       return enumerationRecords.size();
397     }
398   
399     
400     public byte[] nextRecord()
401         throws InvalidRecordIDException, RecordStoreNotOpenException, RecordStoreException
402     {
403       if (!open) {
404         throw new RecordStoreNotOpenException();
405       }      
406 
407       if (currentRecord >= numRecords()) {
408         throw new InvalidRecordIDException();
409       }
410 
411       byte[] result = ((EnumerationRecord) enumerationRecords.elementAt(currentRecord)).value;
412       currentRecord++;      
413       
414       return result;
415     }
416   
417     
418     public int nextRecordId()
419         throws InvalidRecordIDException
420     {
421       if (currentRecord >= numRecords()) {
422         throw new InvalidRecordIDException();
423       }
424 
425       int result = ((EnumerationRecord) enumerationRecords.elementAt(currentRecord)).recordId;
426       currentRecord++;
427       
428       return result;
429     }
430   
431     
432 
433     public byte[] previousRecord()
434         throws InvalidRecordIDException, RecordStoreNotOpenException, RecordStoreException
435     {
436       if (!open) {
437         throw new RecordStoreNotOpenException();
438       }      
439       if (currentRecord < 0) {
440         throw new InvalidRecordIDException();
441       }
442 
443       byte[] result = ((EnumerationRecord) enumerationRecords.elementAt(currentRecord)).value;
444       currentRecord--;
445       
446       return result;
447     }
448   
449     
450     public int previousRecordId()
451         throws InvalidRecordIDException
452     {
453       if (currentRecord < 0) {
454         throw new InvalidRecordIDException();
455       }
456 
457       int result = ((EnumerationRecord) enumerationRecords.elementAt(currentRecord)).recordId;
458       currentRecord--;
459 
460       return result;
461     }
462   
463     
464     public boolean hasNextElement()
465     {
466       if (currentRecord == numRecords()) {
467         return false;
468       } else {
469         return true;
470       }
471     }
472   
473     
474     public boolean hasPreviousElement()
475     {
476       if (currentRecord == 0) {
477         return false;
478       } else {
479         return true;
480       }
481     }
482   
483     
484     public void reset()
485     {
486       currentRecord = 0;
487     }
488   
489     
490     public void rebuild()
491     {
492       enumerationRecords.removeAllElements();
493       
494       int position;
495       for (Enumeration e = records.keys(); e.hasMoreElements(); ) {
496         Object key = e.nextElement();
497         if (filter != null && !filter.matches((byte[]) records.get(key))) {
498           continue;
499         }
500         byte[] tmp_data = (byte[]) records.get(key);
501         // here should be better sorting
502         if (comparator != null) {
503           for (position = 0; position < enumerationRecords.size(); position++) {
504             if (comparator.compare(tmp_data, (byte[]) enumerationRecords.elementAt(position)) 
505                 == RecordComparator.FOLLOWS) {
506               break;
507             }
508           }
509         } else {
510           position = enumerationRecords.size();
511         }
512         enumerationRecords.insertElementAt(
513             new EnumerationRecord(((Integer) key).intValue(), tmp_data), position);
514       }
515       currentRecord = 0;
516     }
517   
518     
519     public void keepUpdated(boolean keepUpdated)
520     {
521       if (keepUpdated) {
522         if (!this.keepUpdated) {
523           rebuild();
524           addRecordListener(recordListener);
525         }
526       } else {
527         removeRecordListener(recordListener);
528       }
529       
530       this.keepUpdated = keepUpdated;
531     }
532   
533     
534     public boolean isKeptUpdated()
535     {
536       return keepUpdated;
537     }
538   
539     
540     public void destroy()
541     {
542     }
543     
544     
545     class EnumerationRecord
546     {
547       
548       int recordId;
549       byte[] value;
550       
551       
552       EnumerationRecord(int recordId, byte[] value)
553       {
554         this.recordId = recordId;
555         this.value = value;
556       }
557       
558     }
559     
560   }
561   
562 }
563