KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > mdr > persistence > memoryimpl > StorageImpl


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.mdr.persistence.memoryimpl;
20
21 import java.util.*;
22 import java.io.*;
23
24 import org.netbeans.mdr.persistence.*;
25 import org.netbeans.mdr.util.*;
26
27 //import org.w3c.dom.*;
28

29 /** Default memory implementation of the Storage.
30  * This implementation supports only one index with STORABLE values.
31  * @author Pavel Buzek, Martin Matula
32  * @version
33  */

34 public class StorageImpl implements Storage {
35     static final String JavaDoc PRIMARY_INDEX_NAME = "PI";
36     private static final int INDEX_SINGLEVALUED = 1;
37     private static final int INDEX_MULTIVALUED = 2;
38     private static final int INDEX_ORDERED = 3;
39
40     private final HashMap maps = new HashMap();
41     private final String JavaDoc storageId;
42     private final String JavaDoc fileName;
43     
44     private PrimaryIndexImpl primaryIndex;
45     private int lastMofId = 0;
46     
47     // variables related to transaction support
48
private Set newIndexes = new HashSet (); // stores names of all new, still existing, indexes created during current transaction
49
private HashMap removedIndexes = new HashMap (); // maps names to indexes created before the current transaction and dropped during the transaction
50

51     /** Creates new StorageImpl */
52     public StorageImpl(String JavaDoc name, String JavaDoc fileName) {
53         this.storageId = name;
54         this.fileName = fileName;
55     }
56     
57     public void writeMOFID (OutputStream outputStream, MOFID mofid) throws StorageException {
58         try {
59             if (storageId.equals(mofid.getStorageID())) {
60                 IOUtils.writeString(outputStream, null);
61             } else {
62                 IOUtils.writeString(outputStream, mofid.getStorageID());
63             }
64             IOUtils.writeLong(outputStream, mofid.getSerialNumber());
65         } catch (IOException ioException) {
66             throw new StorageIOException (ioException);
67         }
68     }
69     
70     public MOFID readMOFID (java.io.InputStream JavaDoc inputStream) throws StorageException {
71         try {
72             String JavaDoc storageId = IOUtils.readString(inputStream);
73             if (storageId == null) storageId = this.storageId;
74             long serial = IOUtils.readLong(inputStream);
75             return new MOFID(serial, storageId);
76         } catch (java.io.IOException JavaDoc ioException) {
77             throw new StorageIOException (ioException);
78         }
79     }
80
81     // used to pre-boot the storage
82
public synchronized void create(boolean replace, ObjectResolver resolver) throws StorageException {
83         if (fileName != null) {
84             if (!replace && exists()) {
85                 throw new StorageBadRequestException("Storage already exists");
86             }
87             new File(getName()).delete();
88         }
89         createPrimaryIndex();
90     }
91     
92     public synchronized void close() throws StorageException {
93         shutDown();
94     }
95     
96     public synchronized boolean delete() throws StorageException {
97         return new File(getName()).delete();
98     }
99     
100     public String JavaDoc getName() {
101         return this.fileName + ".mem";
102     }
103     
104     public String JavaDoc getStorageId() {
105         return this.storageId;
106     }
107     
108     public synchronized long getSerialNumber () {
109         return this.lastMofId++;
110     }
111     
112     public synchronized boolean exists() throws StorageException {
113         return new File(getName()).exists();
114     }
115     
116     public synchronized void open(boolean createOnNoExist, ObjectResolver resolver) throws StorageException {
117 // Logger.getDefault().log("Reading storage from XML document ...");
118
createPrimaryIndex();
119         if (fileName != null) {
120             try {
121                 if (!exists() && !createOnNoExist) {
122                     throw new StorageBadRequestException("Storage " + getName() + " does not exist.");
123                 }
124
125                 InputStream is = new BufferedInputStream(new FileInputStream(getName()));
126                 lastMofId = IOUtils.readInt(is);
127                 String JavaDoc id = IOUtils.readString(is);
128                 if (!storageId.equals(id)) {
129                     throw new StoragePersistentDataException("Invalid storage id in the persistent file: " + id + " (expected: " + storageId + ")");
130                 }
131                 primaryIndex.read(is);
132                 int size = IOUtils.readInt(is);
133                 for (int i = 0; i < size; i++) {
134                     Streamable index;
135                     switch (IOUtils.readInt(is)) {
136                         case INDEX_SINGLEVALUED:
137                             index = new SinglevaluedIndexImpl();
138                             break;
139                         case INDEX_MULTIVALUED:
140                             index = new MultivaluedOrderedIndexImpl();
141                             break;
142                         case INDEX_ORDERED:
143                             index = new MultivaluedOrderedIndexImpl();
144                             break;
145                         default:
146                             throw new StoragePersistentDataException("Unknown type of index.");
147                     }
148                     index.read(is);
149                     maps.put(((Index) index).getName(), index);
150                 }
151             } catch ( java.io.IOException JavaDoc e ) {
152                 if (e instanceof java.io.FileNotFoundException JavaDoc && createOnNoExist) {
153                     return;
154                 }
155                 throw (StorageIOException) Logger.getDefault().annotate(new StorageIOException(e), e);
156             }
157         }
158 // Logger.getDefault().log("Finished reading document.");
159
}
160     
161     public synchronized void objectStateWillChange(Object JavaDoc key) throws StorageException {
162         primaryIndex.willChange (key);
163     }
164     
165     public synchronized void objectStateChanged(Object JavaDoc key) throws StorageException {
166         primaryIndex.changed (key);
167     }
168     
169     public synchronized void rollBackChanges() throws StorageException {
170         // drop all indexes created during the transaction
171
Iterator iter = newIndexes.iterator();
172         while (iter.hasNext()) {
173             maps.remove(iter.next());
174         }
175         // restore all indexes existing before the transaction that have been removed by the transaction
176
iter = removedIndexes.keySet().iterator();
177         while (iter.hasNext()) {
178             String JavaDoc name = (String JavaDoc) iter.next ();
179             maps.put (name, removedIndexes.get (name));
180         }
181
182         // call rollback on all indexes
183
iter = maps.entrySet().iterator();
184         while (iter.hasNext()) {
185             Object JavaDoc index = ((Map.Entry)iter.next()).getValue();
186             if (index instanceof SinglevaluedIndexImpl)
187                 ((SinglevaluedIndexImpl) index).rollBackChanges();
188             else if (index instanceof MultivaluedIndexImpl)
189                 ((MultivaluedIndexImpl) index).rollBackChanges();
190         }
191         primaryIndex.rollBackChanges();
192     }
193     
194     synchronized void serialize() throws StorageException {
195         if (fileName == null) {
196             throw new StorageBadRequestException("No storage file name specified");
197         }
198         try {
199             OutputStream out = new BufferedOutputStream(new FileOutputStream(getName()));
200             IOUtils.writeInt(out, lastMofId);
201             IOUtils.writeString(out, storageId);
202             primaryIndex.write(out);
203             IOUtils.writeInt(out, maps.size());
204             for (Iterator it = maps.values().iterator(); it.hasNext();){
205                 Index index = (Index) it.next();
206                 if (index instanceof SinglevaluedIndexImpl) {
207                     out.write(INDEX_SINGLEVALUED);
208                 } else if (index instanceof MultivaluedOrderedIndexImpl) {
209                     out.write(INDEX_ORDERED);
210                 } else if (index instanceof MultivaluedIndexImpl) {
211                     out.write(INDEX_MULTIVALUED);
212                 } else {
213                     throw new DebugException("Invalid index class: " + index.getClass().getName());
214                 }
215                 ((Streamable) index).write(out);
216             }
217             out.close();
218         } catch (IOException e) {
219             throw (StorageIOException) Logger.getDefault().annotate(new StorageIOException(e), e);
220         }
221     }
222     
223     public synchronized void shutDown() throws StorageException {
224         commitChanges();
225     }
226     
227     public synchronized void commitChanges() throws StorageException {
228         newIndexes.clear();
229         removedIndexes.clear();
230         
231         // call commit on all indexes
232
Iterator iter = maps.entrySet().iterator();
233         while (iter.hasNext()) {
234             Object JavaDoc index = ((Map.Entry)iter.next()).getValue();
235             if (index instanceof SinglevaluedIndexImpl)
236                 ((SinglevaluedIndexImpl) index).commitChanges();
237             else if (index instanceof MultivaluedIndexImpl)
238                 ((MultivaluedIndexImpl) index).commitChanges();
239         }
240         primaryIndex.commitChanges();
241     }
242     
243     public synchronized SinglevaluedIndex getSinglevaluedIndex(String JavaDoc name) throws StorageException {
244         return (SinglevaluedIndex) getIndex(name);
245     }
246     
247     public synchronized MultivaluedIndex getMultivaluedIndex(String JavaDoc name) throws StorageException {
248         return (MultivaluedIndex) getIndex(name);
249     }
250     
251     public synchronized MultivaluedOrderedIndex getMultivaluedOrderedIndex(String JavaDoc name) throws StorageException {
252         return (MultivaluedOrderedIndex) getIndex(name);
253     }
254     
255     public synchronized void dropIndex(String JavaDoc name) throws StorageException {
256         Object JavaDoc index = maps.remove(name);
257         if ((index != null) && !newIndexes.remove(name))
258             removedIndexes.put (name, index);
259     }
260     
261     private synchronized void addIndex(String JavaDoc name, Index index) throws StorageException {
262         maps.put(name, index);
263         newIndexes.add (name);
264     }
265     
266 // public boolean supportsMultipleStorableIndexes() throws StorageException {
267
// return true;
268
// }
269

270     /** Creates SinglevaluedIndex.
271      * @param name Singlevalued name of the index
272      * @param type type of indexes values
273      * @return created index
274      */

275     public synchronized SinglevaluedIndex createSinglevaluedIndex(String JavaDoc name,EntryType keyType,EntryType valueType) throws StorageException {
276         if (valueType.equals(EntryType.STREAMABLE)) {
277             throw new StorageBadRequestException("Cannot create another primary index with STREAMABLE value type.");
278         }
279         SinglevaluedIndex sm = new SinglevaluedIndexImpl(name, this, keyType, valueType);
280         addIndex(name, sm);
281         return sm;
282     }
283     
284     /** Creates MultivaluedOrderedIndex.
285      * @param name
286      * @param type
287      * @return
288      */

289     public synchronized MultivaluedOrderedIndex createMultivaluedOrderedIndex(String JavaDoc name,EntryType keyType,EntryType valueType,boolean unique) throws StorageException {
290         MultivaluedOrderedIndex sm = new MultivaluedOrderedIndexImpl(name, this, keyType, valueType, unique);
291         addIndex(name, sm);
292         return sm;
293     }
294     
295     /** Creates MultivaluedIndex.
296      * @param name
297      * @param type type of indexes values
298      * @return created index
299      */

300     public synchronized MultivaluedIndex createMultivaluedIndex(String JavaDoc name,EntryType keyType,EntryType valueType,boolean unique) throws StorageException {
301         MultivaluedIndex sm = new MultivaluedOrderedIndexImpl(name, this, keyType, valueType, unique);
302         addIndex(name, sm);
303         return sm;
304     }
305     
306     /** Returns the primary index in this Storage. There is exactly one primary
307      * index in every storage.
308      */

309     public synchronized SinglevaluedIndex getPrimaryIndex() throws StorageException {
310         return this.primaryIndex;
311     }
312     
313     /** Creates primary index. Primary index is SinglevaluedIndex with STREAMABLE valueType.
314      */

315     private void createPrimaryIndex() throws StorageException {
316         this.primaryIndex = new PrimaryIndexImpl(this);
317         //addIndex(PRIMARY_INDEX_NAME, this.primaryIndex);
318
}
319     
320     /** Retrieve index by name.
321      * @param name name of the index
322      * @return index of the specified name
323      */

324     public synchronized Index getIndex(String JavaDoc name) throws StorageException {
325         return (Index) maps.get(name);
326     }
327 }
328
Popular Tags