KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > mdr > persistence > jdbcimpl > JdbcPrimaryIndex


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.jdbcimpl;
20
21 import org.netbeans.mdr.persistence.btreeimpl.btreestorage.*;
22 import org.netbeans.mdr.persistence.*;
23
24 import java.io.*;
25 import java.text.*;
26 import java.util.*;
27
28 /**
29  * JdbcPrimaryIndex implements primary index storage using JDBC.
30  *
31  * @author John V. Sichi
32  * @version $Id: JdbcPrimaryIndex.java,v 1.6 2006/06/30 20:56:10 jtulach Exp $
33  */

34 class JdbcPrimaryIndex
35     extends JdbcSinglevaluedIndex implements MDRCache.OverflowHandler
36 {
37     // NOTE: around cache access sequences, we synchronize on
38
// the parent storage, not on "this", to prevent deadlock
39
private final MDRCache cache;
40
41     // NOTE: most of this class was ripped from BtreeDatabase
42
static final int MDR_CACHE_SIZE = 1024;
43     static final int MDR_CACHE_THRESHHOLD = 1000;
44     
45     JdbcPrimaryIndex()
46     {
47         cache = new MDRCache(
48             MDR_CACHE_SIZE,
49             this,
50             MDR_CACHE_THRESHHOLD,
51             null);
52     }
53
54     // implement MDRCache.OverflowHandler
55
public void cacheThreshholdReached(MDRCache cache, int size)
56         throws StorageException
57     {
58         flushChanges();
59     }
60
61     void shutDown()
62     {
63         cache.shutDown();
64     }
65
66     void flushChanges()
67         throws StorageException
68     {
69         // TODO: optimize with batched JDBC calls where supported
70

71         try {
72             int modStatus = cache.getModStatus();
73             MOFID id;
74             Object JavaDoc value;
75             while (modStatus != 0) {
76                 // First, persistently delete everything that needs it
77
if ((modStatus & MDRCache.M_DELETED) != 0) {
78                     Iterator delIter = cache.getDeleted().iterator();
79                     while (delIter.hasNext()) {
80                         id = (MOFID)delIter.next();
81                         super.removeImpl(id);
82                     }
83                 }
84
85                 // Next, modify what needs modification
86
if ((modStatus & MDRCache.M_DIRTY) != 0) {
87                     Iterator dirtyIter = cache.getDirty().iterator();
88                     while (dirtyIter.hasNext()) {
89                         Map.Entry entry = (Map.Entry) dirtyIter.next();
90                         id = (MOFID) entry.getKey();
91                         value = entry.getValue();
92                         super.replaceImpl(id,value);
93                     }
94                 }
95             
96                 // Last, add what needs adding
97
if ((modStatus & MDRCache.M_NEW) != 0) {
98                     Iterator newIter = cache.getNew().iterator();
99                     while (newIter.hasNext()) {
100                         Map.Entry entry = (Map.Entry) newIter.next();
101                         id = (MOFID) entry.getKey();
102                         value = entry.getValue();
103                         super.addImpl(id,value);
104                     }
105                 }
106                 
107                 modStatus = cache.getModStatus();
108             }
109         } finally {
110             cache.updateSize();
111         }
112     }
113
114     private MOFID makeMOFID(Object JavaDoc key) throws StorageException
115     {
116         if (key instanceof MOFID) {
117             return (MOFID) key;
118         } else {
119             throw new IllegalArgumentException JavaDoc(
120                 "Argument must be of org.netbeans.mdr.persistence.MOFID type");
121         }
122     }
123
124     void objectStateChanged(Object JavaDoc key) throws StorageException
125     {
126         cache.setDirty(makeMOFID(key));
127     }
128
129     private boolean exists(MOFID key) throws StorageException
130     {
131         if (cache.get(key) != null) {
132             return true;
133         } else if (cache.isDeleted(key)) {
134             return false;
135         } else {
136             return super.getIfExists(key) != null;
137         }
138     }
139     
140     private void noSuchRecord(Object JavaDoc key) throws StorageException
141     {
142         throw new StorageBadRequestException(
143             MessageFormat.format("No record exists with key {0}",
144                 new Object JavaDoc[] {key} ) );
145     }
146     
147     private void addToCache(MOFID key, Object JavaDoc value) throws StorageException
148     {
149         cache.put(key, value);
150         cache.setNew(key);
151     }
152     
153     private void replaceInCache(MOFID key, Object JavaDoc value)
154         throws StorageException
155     {
156         boolean isNew = cache.isNew(key);
157         
158         cache.replace(key, value);
159         
160         if (isNew) {
161             cache.setNew(key);
162         } else {
163             cache.setDirty(key);
164         }
165     }
166     
167     // override JdbcSinglevaluedIndex
168
public boolean put(
169         Object JavaDoc key,Object JavaDoc value) throws StorageException
170     {
171         synchronized(storage) {
172             MOFID mKey = makeMOFID(key);
173             if (!exists(mKey)) {
174                 addToCache(mKey,value);
175                 return false;
176             } else {
177                 replaceInCache(mKey,value);
178                 return true;
179             }
180         }
181     }
182     
183     // override JdbcSinglevaluedIndex
184
public void replace(Object JavaDoc key, Object JavaDoc value)
185         throws StorageException, StorageBadRequestException
186     {
187         synchronized(storage) {
188             MOFID mKey = makeMOFID(key);
189         
190             if (!exists(mKey)) {
191                 noSuchRecord(mKey);
192             }
193
194             replaceInCache(mKey, value);
195         }
196     }
197     
198     // override JdbcSinglevaluedIndex
199
public Object JavaDoc get(Object JavaDoc key)
200         throws StorageException, StorageBadRequestException
201     {
202         Object JavaDoc retval = getIfExists(key);
203         if (retval == null) {
204             noSuchRecord(key);
205         }
206
207         return retval;
208     }
209
210     // override JdbcSinglevaluedIndex
211
public Object JavaDoc getObject(Object JavaDoc key, SinglevaluedIndex repos)
212         throws StorageException
213     {
214         return get(key);
215     }
216
217     // override JdbcSinglevaluedIndex
218
public Object JavaDoc getIfExists(Object JavaDoc key) throws StorageException
219     {
220         synchronized(storage) {
221             MOFID mKey = makeMOFID(key);
222             Object JavaDoc retval;
223             retval = cache.get(mKey);
224             if (retval == null) {
225                 if (cache.isDeleted(mKey)) {
226                     return null;
227                 }
228                 retval = super.getIfExists(mKey);
229                 if (retval != null) {
230                     cache.put(mKey, retval);
231                 }
232             }
233
234             return retval;
235         }
236     }
237     
238     // override JdbcSinglevaluedIndex
239
public Object JavaDoc getObjectIfExists(Object JavaDoc key, SinglevaluedIndex repos)
240         throws StorageException
241     {
242         return getIfExists(key);
243     }
244
245     // NOTE: it's a pain to implement keySet() and values() correctly,
246
// and as far as I can tell they're never used for primary indexes
247

248     // override JdbcSinglevaluedIndex
249
public Collection values()
250         throws StorageException
251     {
252         throw new RuntimeException JavaDoc("oops, not yet implemented");
253     }
254     
255     // override JdbcIndex
256
public Set keySet() throws StorageException
257     {
258         throw new RuntimeException JavaDoc("oops, not yet implemented");
259     }
260
261     // override JdbcIndex
262
public void add(
263         Object JavaDoc key, Object JavaDoc value) throws StorageException
264     {
265         synchronized(storage) {
266             MOFID mKey = makeMOFID(key);
267             if (exists(mKey)) {
268                 throw new StorageBadRequestException(
269                     MessageFormat.format("Record with key {0} already exists",
270                         new Object JavaDoc[] {mKey} ) );
271             }
272             addToCache(mKey, value);
273         }
274     }
275     
276     // override JdbcIndex
277
public boolean remove(Object JavaDoc key) throws StorageException
278     {
279         synchronized(storage) {
280             MOFID mKey = makeMOFID(key);
281             if (!exists(mKey)) {
282                 return false;
283             } else {
284                 cache.remove(mKey);
285                 return true;
286             }
287         }
288     }
289 }
290
291 // End JdbcPrimaryIndex.java
292
Popular Tags