KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > mim > lib > SpeedoHomeImpl


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.mim.lib;
19
20 import org.objectweb.jorm.api.PClassMapping;
21 import org.objectweb.jorm.api.PException;
22 import org.objectweb.perseus.persistence.api.PersistenceException;
23 import org.objectweb.perseus.persistence.api.RolledBackPersistenceException;
24 import org.objectweb.perseus.persistence.api.TransactionalPersistenceManager;
25 import org.objectweb.speedo.api.Debug;
26 import org.objectweb.speedo.api.ExceptionHelper;
27 import org.objectweb.speedo.metadata.SpeedoFetchGroup;
28 import org.objectweb.speedo.mim.api.DetachedLifeCycle;
29 import org.objectweb.speedo.mim.api.SpeedoHome;
30 import org.objectweb.speedo.mim.api.SpeedoAccessor;
31 import org.objectweb.speedo.mim.api.SpeedoProxy;
32 import org.objectweb.speedo.pm.api.ProxyManager;
33 import org.objectweb.speedo.pm.api.ProxyManagerFactory;
34 import org.objectweb.speedo.query.api.QueryDefinition;
35 import org.objectweb.speedo.usercache.api.UserCache;
36 import org.objectweb.speedo.usercache.lib.CompositeUserCache;
37 import org.objectweb.speedo.usercache.lib.UserCacheImpl;
38 import org.objectweb.speedo.workingset.api.Transaction;
39 import org.objectweb.util.monolog.api.BasicLevel;
40 import org.objectweb.util.monolog.api.Logger;
41
42 import java.util.ArrayList JavaDoc;
43 import java.util.Arrays JavaDoc;
44 import java.util.Collection JavaDoc;
45 import java.util.Collections JavaDoc;
46 import java.util.Iterator JavaDoc;
47 import java.util.List JavaDoc;
48 import java.util.Map JavaDoc;
49
50 import javax.jdo.InstanceCallbacks;
51 import javax.jdo.JDOException;
52 import javax.jdo.JDOUserException;
53 import javax.jdo.listener.AttachLifecycleListener;
54 import javax.jdo.listener.ClearLifecycleListener;
55 import javax.jdo.listener.CreateLifecycleListener;
56 import javax.jdo.listener.DeleteLifecycleListener;
57 import javax.jdo.listener.DetachLifecycleListener;
58 import javax.jdo.listener.DirtyLifecycleListener;
59 import javax.jdo.listener.InstanceLifecycleEvent;
60 import javax.jdo.listener.InstanceLifecycleListener;
61 import javax.jdo.listener.LoadLifecycleListener;
62 import javax.jdo.listener.StoreLifecycleListener;
63
64 /**
65  * @author S.Chassande-Barrioz
66  */

67 public abstract class SpeedoHomeImpl implements SpeedoHome {
68
69     /**
70      * The InstanceLifecycleListener instances registered for the current class
71      * lifecycleListener[LISTENER_ATTACH_IDX] contains AttachLifecycleListener
72      * lifecycleListener[LISTENER_DETACH_IDX] contains DetachLifecycleListener
73      * ...
74      */

75     private InstanceLifecycleListener[][] lifecycleListener = null;
76
77     protected TransactionalPersistenceManager tpm = null;
78
79     protected ProxyManagerFactory pmf = null;
80     
81     byte cachePolicy = CACHED;
82     
83     boolean isFieldLockingLevel = false;
84     boolean prefetchOnQuery = true;
85     boolean prefetchOnExtent = true;
86     boolean prefetchOnGenClass = true;
87     
88     protected Map JavaDoc namedQueries = null;
89     
90     public SpeedoHomeImpl() {
91     }
92     
93     public SpeedoHomeImpl(TransactionalPersistenceManager _tpm,
94             ProxyManagerFactory _pmf) {
95         this.tpm = _tpm;
96         this.pmf = _pmf;
97     }
98     
99     /**
100      * @return false because it corresponds to most of case
101      * Subclass to change the behavior
102      */

103     protected boolean isAbstract() {
104         return false;
105     }
106     
107     /**
108      * Create a new instance of a SpeedoProxy which the clas is given in
109      * parameter. The default implementation does a
110      * simple 'clazz.newInstance()'.
111      */

112     protected SpeedoProxy newSpeedoProxyInstance(Class JavaDoc clazz) throws Exception JavaDoc {
113         return (SpeedoProxy) clazz.newInstance();
114     }
115
116     // IMPLEMENTATION OF THE ProxyHome INTERFACE //
117
//-------------------------------------------//
118

119     public boolean isCacheable() {
120         return (cachePolicy & CACHED) != 0;
121     }
122
123     public boolean allLoaded() {
124         return (cachePolicy & ALL) != 0;
125     }
126     
127     public boolean hasToFix() {
128         return (cachePolicy & FIXED) != 0;
129     }
130     
131     public void setCachePolicy(byte v) {
132         cachePolicy = v;
133     }
134
135     public boolean isFieldLockingLevel() {
136         return isFieldLockingLevel;
137     }
138
139     public void setFieldLockingLevel(boolean val) {
140         isFieldLockingLevel = val;
141     }
142     
143     /**
144      * This default implementation does nothing and returns null.
145      * Subclass to change the behavior
146      */

147     public Collection JavaDoc fgGetNestedFetchGroups(String JavaDoc fgName) {
148         return null;
149     }
150
151     /**
152      * This default implementation returns always false.
153      * Subclass to change the behavior
154      */

155     public boolean fgIsDefined(String JavaDoc fgName) {
156         return false;
157     }
158
159     /**
160      * This default implementation does nothing and returns null.
161      * Subclass to change the behavior
162      */

163     public Collection JavaDoc fgGetFieldsToLoad(String JavaDoc fgName) {
164         return null;
165     }
166     
167     /**
168      * @return the PersistenceManagerFactory which represents the data support
169      * inside which the proxy is persistent.
170      */

171     public final ProxyManagerFactory getProxyManagerFactory() {
172         return pmf;
173     }
174
175     /**
176      * It assignes a PersistenceManagerFactory
177      * @param _pmf is the PersistenceManagerFactory which represents the data
178      * support inside which the proxy is persistent.
179      */

180     public final void setProxyManagerFactory(ProxyManagerFactory _pmf) {
181         this.pmf = _pmf;
182     }
183
184
185     /**
186      * @return the TransactionalPersistenceManager which manage the
187      * concurrency, loading, ... of the proxy.
188      */

189     public final TransactionalPersistenceManager getTransactionalPersistenceManager() {
190         return tpm;
191     }
192
193     /**
194      * It assignes a TransactionalPersistenceManager
195      * @param _tpm is the TransactionalPersistenceManager which manage the
196      * concurrency, loading, ... of the proxy.
197      */

198     public final void setTransactionalPersistenceManager(TransactionalPersistenceManager _tpm) {
199         this.tpm = _tpm;
200     }
201
202     /**
203      * Notifies the transactional persistency manager of a read intention for
204      * the given persistent instance.
205      * @param sp is the SpeedoProxy which the read access is requested.
206      * @param fields the ids of the fields that may be accessed by the caller
207      * of this method. If the i-th bit of 'fields' is set to 1, then the i-th
208      * field of the given speedo accessor may be accessed by the caller of this
209      * method.
210      */

211     public final SpeedoAccessor readIntention(SpeedoProxy sp, long[] fields) {
212         if (!sp.jdoIsActive()) {
213             SpeedoAccessor sa = sp.getReferenceAccessor();
214             if (sa == null) {
215                 sp.setReferenceAccessor(sp.createAccessor());
216             }
217             return sa;
218         }
219         ProxyManager pm = pmf.lookup();
220         if (pm == null) {
221             throw new JDOUserException("When a persistent object is used (read), a PersistenceManager is needed");
222         }
223         Transaction t = (Transaction) pm.currentTransaction();
224         try {
225             SpeedoAccessor sa = (SpeedoAccessor) tpm.readIntention(t, sp, null);
226             sa.loadFields(pm, fields);
227             return sa;
228         } catch (RolledBackPersistenceException e) {
229             throw t.rollBackOnInternalError(e);
230         } catch (PersistenceException e) {
231             throw new JDOException ("Impossible to notify a read intention",
232                     ExceptionHelper.getNested(e));
233         }
234     }
235
236     public final SpeedoAccessor writeIntention(SpeedoProxy sp, long[] fields) {
237         return writeIntention(sp, fields, null);
238     }
239     
240     /**
241      * Notifies the transactional persistency manager of a write intention for
242      * the given persistent instance.
243      *
244      * @param sp is the SpeedoProxy which the write access is requested.
245      * @param fields the ids of the fields that may be accessed by the caller
246      * of this method. If the i-th bit of 'fields' is set to 1, then the i-th
247      * field of the given speedo accessor may be accessed by the caller of this
248      * method.
249      */

250     public SpeedoAccessor writeIntention(SpeedoProxy sp, long[] fields, Object JavaDoc thinLock) {
251         if (!sp.jdoIsActive()) {
252             SpeedoAccessor sa = sp.getReferenceAccessor();
253             if (sa == null) {
254                 sp.setReferenceAccessor(sp.createAccessor());
255             }
256             return sa;
257         }
258         ProxyManager pm = pmf.lookup();
259         if (pm == null) {
260             throw new JDOUserException("When a persistent object is used (read), a PersistenceManager is needed");
261         }
262         Transaction t = (Transaction) pm.currentTransaction();
263         try {
264             SpeedoAccessor sa = (SpeedoAccessor) tpm.writeIntention(t, sp,
265                     isFieldLockingLevel ? thinLock : null);
266             sa.loadFields(pm, fields);
267             return sa;
268         } catch (RolledBackPersistenceException e) {
269             throw t.rollBackOnInternalError(e);
270         } catch (PersistenceException e) {
271             throw new JDOException ("Impossible to notify a write intention",
272                 ExceptionHelper.getNested(e));
273         }
274     }
275
276     /**
277      * It retrieves the SpeedoAccessor instance used in the current context.
278      * If the proxy is not active then the reference accessor is returned.
279      * If there is an active then the $classNameFields used in the context is
280      * returned. Be careul, if the persistent object is not used in the current
281      * context, then a null value will be returned, because no SpeedoAccessor
282      * is registered in the working set.
283      */

284     public final SpeedoAccessor getSpeedoAccessor(SpeedoProxy sp) {
285         if (!sp.jdoIsActive()) {
286             return sp.getReferenceAccessor();
287         }
288         ProxyManager pm = pmf.lookup();
289         if (pm == null) {
290             throw new JDOUserException("When a persistent object is used (read or write), a PersistenceManager is needed");
291         }
292         return (SpeedoAccessor) ((Transaction) pm.currentTransaction())
293             .lookup(sp.getPName());
294     }
295
296     public final SpeedoProxy detachCopy(SpeedoProxy sp,
297             ProxyManager pm,
298             Map JavaDoc map,
299             Object JavaDoc clone,
300             Collection JavaDoc fgHints) {
301         Logger logger = getLogger();
302         if (Debug.ON && logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
303             logger.log(BasicLevel.DEBUG, "detachCopy()");
304         }
305         if (!isAbstract() && clone == null){
306             try {
307                 //instanciate the SpeedoProxy clone
308
clone = newSpeedoProxyInstance(sp.getClass());
309                 SpeedoProxy spClone = (SpeedoProxy)clone;
310                 spClone.setEncodedPName(pm.getObjectId(sp));
311                 spClone.setCeAge(0);
312                 spClone.jdoIsActive(false);
313                 //instanciate the clone of the fields
314
SpeedoAccessor fieldsClone = sp.createAccessor();
315                 spClone.setReferenceAccessor(fieldsClone);
316                 fieldsClone.setSpeedoProxy(spClone);
317                 //put the association between the speedoproxy and its clone into the map
318
if(map != null)
319                     map.put(sp, clone);
320                 synchronized(fgHints){
321                     readIntention(sp, null).detachCopy(pm, map, fieldsClone, fgHints);
322                 }
323                 //mark the state as detached
324
fieldsClone.setDetachedStatus(DetachedLifeCycle.DETACHED_CLEAN);
325             } catch(Exception JavaDoc e){
326                 throw new JDOUserException("Detach cannot be performed", new Exception JavaDoc[]{ExceptionHelper.getNested(e)});
327             }
328         }
329         return (SpeedoProxy)clone;
330     }
331
332     public final void attachCopy(SpeedoProxy sp,
333         ProxyManager pm,
334         Map JavaDoc map,
335         Object JavaDoc clone,
336         SpeedoAccessor sa,
337         boolean makeTransactional) {
338
339         if(map != null) {
340             if( (SpeedoProxy) map.get(clone) == sp)
341                 return;
342             map.put(clone, sp);
343             //check the validity version
344
if (!sa.checkVersion(((SpeedoProxy)clone).getReferenceAccessor())) {
345                 throw new JDOException("The detached copy is no more valid.");
346             }
347             sa.attachCopy(pm, map,
348                 ((SpeedoProxy) clone).getReferenceAccessor(),
349                 makeTransactional);
350         }
351     }
352
353
354     public final Collection JavaDoc fgGetFieldsToLoad(String JavaDoc fgName, boolean onlyDirectRef){
355         Collection JavaDoc c = fgGetFieldsToLoad(fgName);
356         if(onlyDirectRef){
357             Iterator JavaDoc it = c.iterator();
358             while(it.hasNext()) {
359                 String JavaDoc s = (String JavaDoc) it.next();
360                 if(s.indexOf(SpeedoFetchGroup.FG_DOT) != -1
361                         || s.indexOf(SpeedoFetchGroup.FG_SHARP) != -1
362                         || s.indexOf(SpeedoFetchGroup.FG_SLASH) != -1
363                         || s.indexOf(SpeedoFetchGroup.FG_KEY) != -1
364                         || s.indexOf(SpeedoFetchGroup.FG_VALUE) != -1) {
365                     it.remove();
366                 }
367             }
368         }
369         return c;
370     }
371     
372     public void setPrefetchOnExtent(boolean prefetch) {
373         this.prefetchOnExtent = prefetch;
374     }
375     
376
377     public boolean getPrefetchOnExtent() {
378         return prefetchOnExtent;
379     }
380     public void setPrefetchOnGenClass(boolean prefetch) {
381         this.prefetchOnGenClass = prefetch;
382     }
383     public boolean getPrefetchOnGenClass() {
384         return prefetchOnGenClass;
385     }
386     public void setPrefetchOnQuery(boolean prefetch) {
387         this.prefetchOnQuery = prefetch;
388     }
389     public boolean getPrefetchOnQuery() {
390         return prefetchOnQuery;
391     }
392     
393     public void initSH() {
394     }
395     
396     public Class JavaDoc getClassForQuery(String JavaDoc className, String JavaDoc queryName) {
397         try {
398             return getClass().getClassLoader().loadClass(className);
399         } catch (ClassNotFoundException JavaDoc e) {
400             throw new JDOUserException("Class '" + className
401                     + "' used in the query '" + queryName
402                     + "' defined in by the class '" + getClassName()
403                     + "' is not available. See the inner class loading problem: ", e);
404         }
405     }
406     
407     public final QueryDefinition addNamedQuery(String JavaDoc name, QueryDefinition query) {
408         return (QueryDefinition) namedQueries.put(name, query);
409     }
410     public final QueryDefinition removeNamedQuery(String JavaDoc name) {
411         return (QueryDefinition) namedQueries.remove(name);
412     }
413     public final QueryDefinition getNamedQuery(String JavaDoc name) {
414         return (QueryDefinition) namedQueries.get(name);
415     }
416     
417     public String JavaDoc getPath() {
418         return getClassName();
419     }
420     
421     //IMPLEMENTATION OF THE UserCacheHelper INTERFACE //
422
//------------------------------------------------//
423

424     protected UserCache[] userCaches = new UserCache[0];
425
426     protected synchronized UserCache addUserCache(String JavaDoc userCacheName, String JavaDoc[] fields, int id) {
427         UserCacheImpl uc = new UserCacheImpl();
428         uc.setName(userCacheName);
429         uc.setIndexFieldNames(fields);
430         uc.setId(id);
431         uc.setActive(true);
432         if (id >= userCaches.length) {
433             UserCache[] newUserCaches = new UserCache[id+1];
434             System.arraycopy(userCaches, 0, newUserCaches, 0, userCaches.length);
435             userCaches = newUserCaches;
436         }
437         userCaches[id] = uc;
438         return uc;
439     }
440
441     /**
442      * This method is implemented by the generated XXXHome class
443      */

444     public boolean activeUserCache(String JavaDoc cacheName) {
445         return false;
446     }
447     public UserCache getUserCache(int cacheId) {
448         if (cacheId < 0
449                 || cacheId >= userCaches.length
450                 || userCaches[cacheId] == null) {
451             return null;
452         }
453         return userCaches[cacheId];
454     }
455     
456     public UserCache getUserCache(Collection JavaDoc fieldNames) {
457         PClassMapping[] pcms = null;
458         try {
459             pcms = getSubPCMs();
460         } catch (PException e) {
461             throw new JDOException("Impossible to fetch home of sub class of "
462                     + getClassName(), e);
463         }
464         if (pcms == null || pcms.length == 0) {
465             return getUserCacheOfTheClass(fieldNames);
466         }
467         ArrayList JavaDoc ucs = null;
468         //get the user cache of this class
469
UserCache uc = getUserCacheOfTheClass(fieldNames);
470         //if it not null, add it to the list
471
if(uc != null) {
472              if (ucs == null) {
473                 ucs = new ArrayList JavaDoc();
474             }
475             ucs.add(uc);
476         }
477         //then do the same for each subclass
478
for (int i = 0; i < pcms.length; i++) {
479             uc = ((SpeedoHomeImpl) pcms[i])
480                 .getUserCacheOfTheClass(fieldNames);
481             if (uc != null) {
482                 if (ucs == null) {
483                     ucs = new ArrayList JavaDoc();
484                 }
485                 ucs.add(uc);
486             }
487         }
488         if (ucs != null) {
489             return new CompositeUserCache((UserCache[])
490                     ucs.toArray(new UserCache[ucs.size()]));
491         }
492         return null;
493     }
494     
495     private UserCache getUserCacheOfTheClass(Collection JavaDoc fieldNames) {
496         for(int i=0; i<userCaches.length; i++) {
497             if (userCaches[i] != null && userCaches[i].isActive()) {
498                 String JavaDoc[] fns = userCaches[i].getIndexFieldNames();
499                 List JavaDoc l = Arrays.asList(fns);
500                 if (fns.length == fieldNames.size()
501                         && fieldNames.containsAll(l)
502                         && l.containsAll(fieldNames)
503                         ) {
504                     return userCaches[i];
505                 }
506             }
507         }
508         return null;
509     }
510         
511     public Collection JavaDoc getActiveUserCache() {
512         if (userCaches == null || userCaches.length == 0) {
513             return Collections.EMPTY_LIST;
514         }
515         ArrayList JavaDoc al = new ArrayList JavaDoc();
516         for(int i=0; i<userCaches.length; i++) {
517             if (userCaches[i] != null && userCaches[i].isActive()) {
518                 al.add(userCaches[i]);
519             }
520         }
521         return al;
522     }
523     public void userCacheEntryUnbound(Object JavaDoc oid) {
524         if (userCaches == null || userCaches.length == 0) {
525             return;
526         }
527         for(int i=0; i<userCaches.length; i++) {
528             if (userCaches[i] != null && userCaches[i].isActive()) {
529                 userCaches[i].unbindFromOID(oid);
530             }
531         }
532     }
533     
534     /**
535      * Adds a listener for the current class
536      * @param listener is the new listener
537      */

538     public void addInstanceLifeCycleListener(InstanceLifecycleListener listener) {
539         getLifecycleListener();
540         if (listener instanceof AttachLifecycleListener) {
541             addListener(InstanceLifecycleEvent.ATTACH, listener);
542         }
543         if (listener instanceof DetachLifecycleListener) {
544             addListener(InstanceLifecycleEvent.DETACH, listener);
545         }
546         if (listener instanceof ClearLifecycleListener) {
547             addListener(InstanceLifecycleEvent.CLEAR, listener);
548         }
549         if (listener instanceof CreateLifecycleListener) {
550             addListener(InstanceLifecycleEvent.CREATE, listener);
551         }
552         if (listener instanceof DeleteLifecycleListener) {
553             addListener(InstanceLifecycleEvent.DELETE, listener);
554         }
555         if (listener instanceof DirtyLifecycleListener) {
556             addListener(InstanceLifecycleEvent.DIRTY, listener);
557         }
558         if (listener instanceof LoadLifecycleListener) {
559             addListener(InstanceLifecycleEvent.LOAD, listener);
560         }
561         if (listener instanceof StoreLifecycleListener) {
562             addListener(InstanceLifecycleEvent.STORE, listener);
563         }
564     }
565
566     /**
567      * Remove a listener for the current class
568      * @param listener is the listener to forget
569      */

570     public void removeInstanceLifeCycleListener(InstanceLifecycleListener listener) {
571         getLifecycleListener();
572         if (listener instanceof AttachLifecycleListener) {
573             removeListener(InstanceLifecycleEvent.ATTACH, listener);
574         }
575         if (listener instanceof DetachLifecycleListener) {
576             removeListener(InstanceLifecycleEvent.DETACH, listener);
577         }
578         if (listener instanceof ClearLifecycleListener) {
579             removeListener(InstanceLifecycleEvent.CLEAR, listener);
580         }
581         if (listener instanceof CreateLifecycleListener) {
582             removeListener(InstanceLifecycleEvent.CREATE, listener);
583         }
584         if (listener instanceof DeleteLifecycleListener) {
585             removeListener(InstanceLifecycleEvent.DELETE, listener);
586         }
587         if (listener instanceof DirtyLifecycleListener) {
588             removeListener(InstanceLifecycleEvent.DIRTY, listener);
589         }
590         if (listener instanceof LoadLifecycleListener) {
591             removeListener(InstanceLifecycleEvent.LOAD, listener);
592         }
593         if (listener instanceof StoreLifecycleListener) {
594             removeListener(InstanceLifecycleEvent.STORE, listener);
595         }
596     }
597     
598     /**
599      * Instanciates the array of listener, the first time.
600      */

601     private void getLifecycleListener() {
602         if (lifecycleListener == null) {
603             lifecycleListener = new InstanceLifecycleListener[8][];
604         }
605     }
606     
607     /**
608      * Adds the listener for a particular type. If the listener is already
609      * present, the listener is not added.
610      * @param eventType specifies the type of the listener. This index corresponds
611      * to an index into the #lifecycleListener array.
612      * @param l is the listener to add
613      */

614     private synchronized void addListener(int eventType, InstanceLifecycleListener l) {
615         if (lifecycleListener[eventType] == null) {
616             lifecycleListener[eventType] = new InstanceLifecycleListener[]{l};
617         } else {
618             List JavaDoc list = Arrays.asList(lifecycleListener[eventType]);
619             if (!list.contains(l)) {
620                 list.add(l);
621                 lifecycleListener[eventType] = (InstanceLifecycleListener[])
622                     list.toArray(new InstanceLifecycleListener[0]);
623             }
624         }
625     }
626     
627     /**
628      * Removes the listener for a particular type.
629      * @param eventType specifies the type of the listener. This index corresponds
630      * to an index into the #lifecycleListener array.
631      * @param l is the listener to remove
632      */

633     private synchronized void removeListener(int eventType, InstanceLifecycleListener l) {
634         if (lifecycleListener[eventType] == null || lifecycleListener[eventType].length == 0) {
635             return;
636         }
637         if (lifecycleListener[eventType].length == 1 && lifecycleListener[eventType][0] == l) {
638             lifecycleListener[eventType] = null;
639         } else {
640             InstanceLifecycleListener[] neo =
641                 new InstanceLifecycleListener[lifecycleListener[eventType].length -1];
642             int pos = 0;
643             for(int i=0; i<lifecycleListener[eventType].length; i++) {
644                 if (lifecycleListener[eventType][i] != l) {
645                     neo[pos++] = lifecycleListener[eventType][i];
646                 }
647             }
648         }
649     }
650     
651     public void sendEvent(int eventType, Object JavaDoc source, Object JavaDoc target, boolean pre) {
652         if (source instanceof InstanceCallbacks) {
653             switch(eventType) {
654             case InstanceLifecycleEvent.CLEAR:
655                 if (pre) {
656                     ((InstanceCallbacks) source).jdoPreClear();
657                 }
658                 break;
659             case InstanceLifecycleEvent.DELETE:
660                 if (pre) {
661                     ((InstanceCallbacks) source).jdoPreDelete();
662                 }
663                 break;
664             case InstanceLifecycleEvent.LOAD:
665                 if (!pre) {
666                     ((InstanceCallbacks) source).jdoPostLoad();
667                 }
668                 break;
669             case InstanceLifecycleEvent.STORE:
670                 if (pre) {
671                     ((InstanceCallbacks) source).jdoPreStore();
672                 }
673                 break;
674             }
675         }
676         if (lifecycleListener == null || lifecycleListener[eventType] == null) {
677             return;
678         }
679         InstanceLifecycleEvent ev = new InstanceLifecycleEvent(source, eventType, target);
680         for(int i=0; i<lifecycleListener[eventType].length; i++) {
681             switch(eventType) {
682             case InstanceLifecycleEvent.ATTACH:
683                 if (pre) {
684                     ((AttachLifecycleListener) lifecycleListener[eventType][i]).preAttach(ev);
685                 } else {
686                     ((AttachLifecycleListener) lifecycleListener[eventType][i]).postAttach(ev);
687                 }
688                 break;
689             case InstanceLifecycleEvent.DETACH:
690                 if (pre) {
691                     ((DetachLifecycleListener) lifecycleListener[eventType][i]).preDetach(ev);
692                 } else {
693                     ((DetachLifecycleListener) lifecycleListener[eventType][i]).postDetach(ev);
694                 }
695                 break;
696             case InstanceLifecycleEvent.CREATE:
697                 if (!pre) {
698                     ((CreateLifecycleListener) lifecycleListener[eventType][i]).postCreate(ev);
699                 }
700                 break;
701             case InstanceLifecycleEvent.DELETE:
702                 if (pre) {
703                     ((DeleteLifecycleListener) lifecycleListener[eventType][i]).preDelete(ev);
704                 } else {
705                     ((DeleteLifecycleListener) lifecycleListener[eventType][i]).postDelete(ev);
706                 }
707                 break;
708             case InstanceLifecycleEvent.LOAD:
709                 if (!pre) {
710                     ((LoadLifecycleListener) lifecycleListener[eventType][i]).postLoad(ev);
711                 }
712                 break;
713             case InstanceLifecycleEvent.STORE:
714                 if (pre) {
715                     ((StoreLifecycleListener) lifecycleListener[eventType][i]).preStore(ev);
716                 } else {
717                     ((StoreLifecycleListener) lifecycleListener[eventType][i]).postStore(ev);
718                 }
719                 break;
720             case InstanceLifecycleEvent.DIRTY:
721                 if (pre) {
722                     ((DirtyLifecycleListener) lifecycleListener[eventType][i]).preDirty(ev);
723                 } else {
724                     ((DirtyLifecycleListener) lifecycleListener[eventType][i]).postDirty(ev);
725                 }
726                 break;
727             case InstanceLifecycleEvent.CLEAR:
728                 if (pre) {
729                     ((ClearLifecycleListener) lifecycleListener[eventType][i]).preClear(ev);
730                 } else {
731                     ((ClearLifecycleListener) lifecycleListener[eventType][i]).postClear(ev);
732                 }
733                 break;
734             }
735         }
736         
737     }
738 }
739
Popular Tags