KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > genclass > map > MapAccessor


1 /**
2  * Copyright (C) 2001-2004 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library 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 GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; 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.speedo.genclass.map;
19
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collection JavaDoc;
22 import java.util.Collections JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.HashSet JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.Set JavaDoc;
28
29 import javax.jdo.PersistenceManager;
30
31 import org.objectweb.jorm.api.PExceptionIO;
32 import org.objectweb.jorm.api.PIndexedElem;
33 import org.objectweb.jorm.naming.api.PName;
34 import org.objectweb.speedo.api.Debug;
35 import org.objectweb.speedo.genclass.GenClassAccessor;
36 import org.objectweb.speedo.genclass.GenClassElement;
37 import org.objectweb.speedo.genclass.SpeedoGenClassHome;
38 import org.objectweb.speedo.genclass.api.SpeedoGenClassProxy;
39 import org.objectweb.speedo.metadata.SpeedoFetchGroup;
40 import org.objectweb.speedo.mim.api.DetachedLifeCycle;
41 import org.objectweb.speedo.mim.api.LifeCycle;
42 import org.objectweb.speedo.mim.api.SpeedoAccessor;
43 import org.objectweb.speedo.mim.api.SpeedoProxy;
44 import org.objectweb.speedo.pm.api.ProxyManager;
45 import org.objectweb.util.monolog.api.BasicLevel;
46
47 public class MapAccessor
48         extends GenClassAccessor
49         implements Map JavaDoc {
50
51     /**
52      * A map containing the indexed elements of the genclass. It associates each
53      * element to its index. This map does NOT contain the deleted elements.
54      */

55     protected Map JavaDoc map = null;
56
57     /**
58      * Instanciates and initializes a new map with an initial size.
59      */

60     public MapAccessor(SpeedoGenClassProxy _jdoProxy) {
61         super(_jdoProxy);
62         this.elements = new ArrayList JavaDoc();
63         this.map = (Map JavaDoc) jdoProxy.createGenClass();
64     }
65
66     public void makePersistent(ProxyManager pm) {
67         if (Debug.ON && getLogger() != null) {
68             logger.log(BasicLevel.DEBUG, "makePersistent");
69         }
70         if (elements.size() > 0) {
71             ((SpeedoGenClassHome) getSpeedoProxy().getSpeedoHome())
72                 .makePersistent(pm, values().iterator(), null);
73         }
74     }
75     public void deletePersistent(ProxyManager pm) {
76         clear();
77     }
78
79     public void setElements(Object JavaDoc o) {
80         clear();
81         if (o != null) {
82             putAll(((Map JavaDoc) o));
83         }
84     }
85
86     public void loadFieldsFromAccessor(SpeedoAccessor sa) {
87         MapAccessor ma = (MapAccessor) sa;
88         map.clear();
89         map.putAll(ma.map);
90         supportDelta = ma.supportDelta;
91         elements.clear();
92         elements.addAll(ma.elements);
93         jdoSetStatus(ma.jdoGetStatus());
94     }
95
96     public boolean speedoAdd(Object JavaDoc elemToAdd, Object JavaDoc hints) {
97         put(hints, elemToAdd, false);
98         return true;
99     }
100
101     public boolean speedoRemove(Object JavaDoc elemToRemove, Object JavaDoc hints) {
102         return remove(hints, false) != null;
103     }
104
105     public void detachCopy(ProxyManager pm, Map JavaDoc detachCtx, SpeedoAccessor fieldsClone, Collection JavaDoc fgHints){
106         ((MapAccessor)fieldsClone).map = new HashMap JavaDoc();
107         ((MapAccessor)fieldsClone).loadFieldsFromAccessor(this);
108         //copy the elements in the map: collection is no more available when the proxy is not active
109
((MapAccessor)fieldsClone).map.clear();
110         boolean valueToFetch = false;
111         Collection JavaDoc fgHintsToSend = new ArrayList JavaDoc();
112         synchronized(fgHints){
113             Collection JavaDoc copyFgHints = new ArrayList JavaDoc(fgHints);
114             Iterator JavaDoc it2 = copyFgHints.iterator();
115             while(it2.hasNext() && !valueToFetch){
116                 String JavaDoc s = (String JavaDoc) it2.next();
117                 int idxValue = s.indexOf(SpeedoFetchGroup.FG_VALUE);
118                 if(s.indexOf(SpeedoFetchGroup.FG_KEY) != -1)
119                     fgHints.remove(s);
120                 else if(idxValue != -1){
121                     valueToFetch = true;
122                     fgHints.remove(s);
123                     String JavaDoc add = s.substring(idxValue+SpeedoFetchGroup.FG_VALUE.length());
124                     if(add.length() > 0){
125                         fgHintsToSend.add(add);
126                     }
127                 }
128             }
129         }
130         //get an interator on the PIndexed elements
131
Iterator JavaDoc it = ((GenClassAccessor) fieldsClone).elements.iterator();
132         while(it.hasNext()){
133             //get the PIndexElement
134
MapElem iElem = (MapElem) it.next();
135             //get the speedo proxy associated
136
SpeedoProxy sp = (SpeedoProxy) iElem.getElement(pm);
137             Object JavaDoc key = iElem.getIndex();
138             SpeedoProxy clone = null;
139             if(detachCtx != null)
140                 clone = (SpeedoProxy) detachCtx.get(sp);
141             if(clone == null){
142                 synchronized(fgHints){
143                     if(valueToFetch){
144                         // get the clone of the speedo proxy
145
clone = (SpeedoProxy) pm.speedoDetachCopy(sp, detachCtx, fgHintsToSend);
146                     }
147                 }
148             }
149             //add it in the map of elements reachable when the proxy is no more active
150
((MapAccessor)fieldsClone).map.put(key, clone);
151         }
152         ((GenClassAccessor) fieldsClone).jdoSetStatus(LifeCycle.TRANSIENT);
153     }
154     
155     public void attachCopy(ProxyManager pm, Map JavaDoc attachCtx, SpeedoAccessor fieldsClone, boolean makeTransactional) {
156         MapAccessor ma = (MapAccessor) fieldsClone;
157         //get an iterator on the PIndexed elements of the collection
158
Iterator JavaDoc it = ma.map.entrySet().iterator();
159         while(it.hasNext()){
160             //get the detached speedo proxy
161
SpeedoProxy spDetached = (SpeedoProxy) it.next();
162             SpeedoProxy sp = (SpeedoProxy) attachCtx.get(spDetached);
163             if(sp == null){
164                 attachCtx.put(spDetached, sp);
165                 sp = (SpeedoProxy) pm.speedoAttachCopy(spDetached, makeTransactional, attachCtx);
166             }
167             /*
168             //add only the dirty elements
169             if(spDetached.getReferenceAccessor().getDetachedStatus() == DetachedLifeCycle.DETACHED_DIRTY){
170                 //ne doit on pas enlever l'element out-of-date avant d'ajouter cet element modifie
171                 Object key = itKey.next();
172                 //put the element of the collection attribute in the elements attribute (the opposite of the jdoDetachCopy method)
173                 put(key, sp, true);
174             } */

175         }
176     }
177     
178     public void refresh(ProxyManager pm, Map JavaDoc refreshCtx, Collection JavaDoc fgHints){
179         commonRefreshRetrieve(pm, refreshCtx, fgHints, true);
180     }
181     
182     public void retrieve(ProxyManager pm, Map JavaDoc retrieveCtx, Collection JavaDoc fgHints){
183         commonRefreshRetrieve(pm, retrieveCtx, fgHints, false);
184     }
185     
186     /**
187      *
188      * @param pm
189      * @param ctx
190      * @param fgHints
191      * @param refresh: if true, call refresh, else call retrieve
192      */

193     private void commonRefreshRetrieve(ProxyManager pm, Map JavaDoc ctx, Collection JavaDoc fgHints, boolean refresh){
194         boolean valueToFetch = false;
195         Collection JavaDoc fgHintsToSend = new ArrayList JavaDoc();
196         synchronized(fgHints){
197             Collection JavaDoc copyFgHints = new ArrayList JavaDoc(fgHints);
198             Iterator JavaDoc it2 = copyFgHints.iterator();
199             while(it2.hasNext() && !valueToFetch){
200                 String JavaDoc s = (String JavaDoc) it2.next();
201                 int idxValue = s.indexOf(SpeedoFetchGroup.FG_VALUE);
202                 if(s.indexOf(SpeedoFetchGroup.FG_KEY) != -1)
203                     fgHints.remove(s);
204                 else if(idxValue != -1){
205                     valueToFetch = true;
206                     fgHints.remove(s);
207                     String JavaDoc add = s.substring(idxValue+SpeedoFetchGroup.FG_VALUE.length());
208                     if(add.length() > 0){
209                         fgHintsToSend.add(add);
210                     }
211                 }
212             }
213         }
214         //get an interator on the PIndexed elements
215
Iterator JavaDoc it = this.elements.iterator();
216         while(it.hasNext()){
217             //get the PIndexElement
218
MapElem iElem = (MapElem) it.next();
219             //get the speedo proxy associated
220
SpeedoProxy sp = (SpeedoProxy) iElem.getElement(pm);
221             if(ctx != null && !ctx.containsKey(sp.getPName())){
222                 synchronized(fgHints){
223                     if(valueToFetch){
224                         if (refresh) {
225                             //refresh
226
pm.speedoRefresh(sp, ctx, fgHintsToSend);
227                         } else {
228                             //retrieve
229
pm.speedoRetrieve(sp, ctx, fgHintsToSend);
230                         }
231                     }
232                 }
233             }
234         }
235     }
236     
237     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value, boolean withCoherence) {
238         MapElem element = null;
239         Object JavaDoc res = map.get(key);
240         if(detachedStatus != DetachedLifeCycle.DETACHED_NONE)
241             return res;
242         if (res == null) {
243             // Put a new entry in the map
244
element = (MapElem) createPIndexedElem();
245             element.setIndex(key);
246             elements.add(element);
247             map.put(key, element);
248         } else {
249             // Mark as modify
250
element = (MapElem) res;
251             element.setStatus(PIndexedElem.ELEM_MODIFIED);
252             res = element.getElement(jdoProxy.jdoGetPersistenceManager());
253         }
254         element.setElement(value);
255
256         if (value instanceof SpeedoProxy) {
257             ((SpeedoGenClassHome) getSpeedoProxy().getSpeedoHome())
258                 .makePersistent(null, (SpeedoProxy) value,
259                         (SpeedoGenClassProxy) getSpeedoProxy());
260         }
261         if (withCoherence) {
262             Object JavaDoc _o = value;
263             if (_o instanceof PName) {
264                 _o = element.getElement(jdoProxy.jdoGetPersistenceManager());
265             }
266             if (_o instanceof SpeedoProxy) {
267                 jdoProxy.fireSpeedoElementAdded(_o);
268             }
269         }
270         return res;
271     }
272
273     public Object JavaDoc remove(Object JavaDoc key, boolean withCoherence) {
274         GenClassElement gcelem = (GenClassElement) map.get(key);
275         if (gcelem == null) {
276             return null;
277         }
278         gcelem.setStatus(PIndexedElem.ELEM_DELETED);
279         Object JavaDoc value = get(key);
280         map.remove(key);
281         if (withCoherence) {
282             Object JavaDoc _o = gcelem.getElement(jdoProxy.jdoGetPersistenceManager());
283             if (_o != null) {
284                 jdoProxy.fireSpeedoElementRemoved(_o);
285             }
286         }
287         return value;
288     }
289
290     // ------------------------------------------------------------------------
291
// IMPLEMENTATION OF THE Map INTERFACE
292
// ------------------------------------------------------------------------
293

294     public int size() {
295         return map.size();
296     }
297
298     public boolean isEmpty() {
299         return map.isEmpty();
300     }
301
302     public boolean containsKey(Object JavaDoc key) {
303         return map.containsKey(key);
304     }
305
306     public boolean containsValue(Object JavaDoc value) {
307         // TODO: support the containsValue method on Map
308
return false;
309     }
310
311     public Object JavaDoc get(Object JavaDoc key) {
312         Object JavaDoc value = map.get(key);
313         if (value == null) {
314             return null;
315         } else {
316             //if the state is detached
317
if(detachedStatus != DetachedLifeCycle.DETACHED_NONE)
318                 return value;
319             else
320                 return ((MapElem) value).getElement(
321                         jdoProxy.jdoGetPersistenceManager());
322         }
323     }
324
325     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
326         return put(key, value, true);
327     }
328
329     public Object JavaDoc remove(Object JavaDoc key) {
330         return remove(key, true);
331     }
332
333     public void putAll(Map JavaDoc t) {
334         Iterator JavaDoc i = t.entrySet().iterator();
335         while (i.hasNext()) {
336             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
337             put(entry.getKey(), entry.getValue());
338         }
339     }
340
341     public void clear() {
342         Iterator JavaDoc i = elements.iterator();
343         PersistenceManager pm = null;
344         while (i.hasNext()) {
345             GenClassElement gcelem = (GenClassElement) i.next();
346             gcelem.setStatus(PIndexedElem.ELEM_DELETED);
347             if (pm == null) {
348                 pm = jdoProxy.jdoGetPersistenceManager();
349             }
350             Object JavaDoc _o = gcelem.getElement(pm);
351             if (_o != null) {
352                 jdoProxy.fireSpeedoElementRemoved(_o);
353             }
354         }
355         map.clear();
356         supportDelta = false;
357     }
358
359     public Set JavaDoc keySet() {
360         return Collections.unmodifiableSet(map.keySet());
361     }
362
363     public Collection JavaDoc values() {
364         ArrayList JavaDoc res = new ArrayList JavaDoc(elements.size());
365         for(int i=(elements.size()-1); i>=0; i--) {
366             MapElem me = (MapElem) elements.get(i);
367             if (me.getElemStatus() != PIndexedElem.ELEM_DELETED) {
368                 res.add(me.getElement());
369             }
370         }
371         return Collections.unmodifiableCollection(res);
372     }
373
374     public Set JavaDoc entrySet() {
375         Set JavaDoc res = new HashSet JavaDoc(elements.size());
376         for(int i=(elements.size()-1); i>=0; i--) {
377             MapElem me = (MapElem) elements.get(i);
378             if (me.getElemStatus() != PIndexedElem.ELEM_DELETED) {
379                 res.add(new MyMapEntry(me));
380             }
381         }
382         return Collections.unmodifiableSet(res);
383     }
384
385     private class MyMapEntry implements Map.Entry JavaDoc {
386         MapElem me;
387
388         public MyMapEntry(MapElem _me) {
389             this.me = _me;
390         }
391
392         public Object JavaDoc getKey() {
393             return me.getIndex();
394         }
395
396         public Object JavaDoc getValue() {
397             return me.getElement();
398         }
399
400         public Object JavaDoc setValue(Object JavaDoc value) {
401             Object JavaDoc res = me.getElement();
402             me.setStatus(PIndexedElem.ELEM_MODIFIED);
403             me.setElement(value);
404             return res;
405         }
406     }
407
408     // ------------------------------------------------------------------------
409
// IMPLEMENTATION OF THE PGenClassAccessor INTERFACE
410
// ------------------------------------------------------------------------
411
public PIndexedElem createPIndexedElem(GenClassAccessor gca) {
412         return new MapElem(gca);
413     }
414
415     public void paAdd(PIndexedElem elem, Object JavaDoc conn) throws PExceptionIO {
416         GenClassElement gcelem = (GenClassElement) elem;
417         // the elem is read from the DS, set it to unmodified.
418
gcelem.setStatus(PIndexedElem.ELEM_UNMODIFIED);
419         elements.add(gcelem);
420         map.put(gcelem.getIndex(), gcelem);
421     }
422
423     public int paGetNbElem() {
424         return size();
425     }
426
427     public Iterator JavaDoc paIterator() {
428         return elements.iterator();
429     }
430
431     public void paSetNbElem(int nbelem) {
432         if (nbelem == -1) {
433             elements = new ArrayList JavaDoc();
434         } else {
435             elements = new ArrayList JavaDoc(nbelem);
436         }
437         map = (Map JavaDoc) jdoProxy.createGenClass();
438     }
439
440     public void forceDetachedDirty() {
441     }
442
443     public void restoreDetachedNone() {
444     }
445
446     
447 }
448
Popular Tags