KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > core > PersistenceBrokerAbstractImpl


1 package org.apache.ojb.broker.core;
2
3 /* Copyright 2003-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import org.apache.ojb.broker.PBLifeCycleEvent;
19 import org.apache.ojb.broker.PBLifeCycleListener;
20 import org.apache.ojb.broker.PBListener;
21 import org.apache.ojb.broker.PBStateEvent;
22 import org.apache.ojb.broker.PBStateListener;
23 import org.apache.ojb.broker.PersistenceBrokerEvent;
24 import org.apache.ojb.broker.PersistenceBrokerException;
25 import org.apache.ojb.broker.PersistenceBrokerInternal;
26 import org.apache.ojb.broker.util.configuration.Configuration;
27 import org.apache.ojb.broker.util.configuration.ConfigurationException;
28 import org.apache.ojb.broker.util.logging.LoggerFactory;
29
30 /**
31  * Abstract Implementation of the {@link org.apache.ojb.broker.PersistenceBroker}
32  * encapsulating the used PB-event/listener concept.
33  *
34  * @see org.apache.ojb.broker.PersistenceBroker
35  * @see org.apache.ojb.broker.PBLifeCycleListener
36  * @see org.apache.ojb.broker.PersistenceBrokerAware
37  * @see org.apache.ojb.broker.PBStateListener
38  *
39  * @author Created by Charles on 12-Sep-2002 08:04:47
40  * @author Armin Waibel
41  * @version $Id: PersistenceBrokerAbstractImpl.java,v 1.6.2.3 2005/12/21 22:25:00 tomdz Exp $
42  */

43 public abstract class PersistenceBrokerAbstractImpl implements PersistenceBrokerInternal
44 {
45     private static final PBStateListener[] NO_STATE_LISTENERS = new PBStateListener[0];
46     private static final PBLifeCycleListener[] NO_LIFECYCLE_LISTENERS = new PBLifeCycleListener[0];
47
48     private boolean txCheck;
49
50     /**
51      * Array containing all permanent {@link org.apache.ojb.broker.PBStateListener}
52      * instances.
53      */

54     private PBStateListener[] permanentStateListeners = NO_STATE_LISTENERS;
55
56     /**
57      * Array containing all temporary {@link org.apache.ojb.broker.PBStateListener}
58      * instances.
59      */

60     private PBStateListener[] temporaryStateListeners = NO_STATE_LISTENERS;
61
62     /**
63      * Array containing all permanent {@link org.apache.ojb.broker.PBLifeCycleListener}
64      * instances.
65      */

66     private PBLifeCycleListener[] permanentLifeCycleListeners = NO_LIFECYCLE_LISTENERS;
67
68     /**
69      * Array containing all temporary {@link org.apache.ojb.broker.PBLifeCycleListener}
70      * instances.
71      */

72     private PBLifeCycleListener[] temporaryLifeCycleListeners = NO_LIFECYCLE_LISTENERS;
73
74     /**
75      * Override if needed.
76      *
77      * @see org.apache.ojb.broker.util.configuration.Configurable#configure(Configuration)
78      */

79     public void configure(Configuration pConfig) throws ConfigurationException
80     {
81         txCheck = pConfig.getBoolean("TxCheck", false);
82     }
83
84     /**
85      * Returns <em>true</em> if the development checks are enabled.
86      *
87      * @see #setTxCheck(boolean)
88      */

89     public boolean isTxCheck()
90     {
91         return txCheck;
92     }
93
94     /**
95      * This setting can be helpful during development if the PersistenceBroker transaction
96      * demarcation was used (this is true in most cases). If set 'true' on PB#store(...)
97      * and PB#delete(...) methods calls OJB check for active PB-tx and if no active tx is
98      * found a error is logged. This can help to avoid store/delete calls without a running
99      * PB-tx while development. Default setting is 'false'.
100      * <p/>
101      * <strong>Note:</strong> When using OJB in a managed
102      * environment <em>without</em> OJB-caching, it's valid to use store/delete
103      * calls without a running PB-tx.
104      *
105      * @param txCheck Set <em>true</em> to enable the checks
106      */

107     public void setTxCheck(boolean txCheck)
108     {
109         this.txCheck = txCheck;
110     }
111
112     /**
113      * @see org.apache.ojb.broker.PersistenceBroker#addListener(PBListener listener)
114      */

115     public void addListener(PBListener listener) throws PersistenceBrokerException
116     {
117         addListener(listener, false);
118     }
119
120     /**
121      * @see org.apache.ojb.broker.PersistenceBroker#addListener(PBListener listener, boolean permanent)
122      */

123     public void addListener(PBListener listener, boolean permanent) throws PersistenceBrokerException
124     {
125         if (listener instanceof PBStateListener)
126         {
127             if (permanent)
128             {
129                 if (!contains(permanentStateListeners, listener))
130                 {
131                     PBStateListener[] newListeners = new PBStateListener[permanentStateListeners.length + 1];
132                     System.arraycopy(permanentStateListeners, 0, newListeners, 0, permanentStateListeners.length);
133                     newListeners[newListeners.length - 1] = (PBStateListener) listener;
134                     permanentStateListeners = newListeners;
135                 }
136             }
137             else
138             {
139                 if (!contains(temporaryStateListeners, listener))
140                 {
141                     PBStateListener[] newListeners = new PBStateListener[temporaryStateListeners.length + 1];
142                     System.arraycopy(temporaryStateListeners, 0, newListeners, 0, temporaryStateListeners.length);
143                     newListeners[newListeners.length - 1] = (PBStateListener) listener;
144                     temporaryStateListeners = newListeners;
145                 }
146             }
147         }
148
149         if (listener instanceof PBLifeCycleListener)
150         {
151             if (permanent)
152             {
153                 if (!contains(permanentLifeCycleListeners, listener))
154                 {
155                     PBLifeCycleListener[] newListeners = new PBLifeCycleListener[permanentLifeCycleListeners.length + 1];
156                     System.arraycopy(permanentLifeCycleListeners, 0, newListeners, 0, permanentLifeCycleListeners.length);
157                     newListeners[newListeners.length - 1] = (PBLifeCycleListener) listener;
158                     permanentLifeCycleListeners = newListeners;
159                 }
160             }
161             else
162             {
163                 if (!contains(temporaryLifeCycleListeners, listener))
164                 {
165                     PBLifeCycleListener[] newListeners = new PBLifeCycleListener[temporaryLifeCycleListeners.length + 1];
166                     System.arraycopy(temporaryLifeCycleListeners, 0, newListeners, 0, temporaryLifeCycleListeners.length);
167                     newListeners[newListeners.length - 1] = (PBLifeCycleListener) listener;
168                     temporaryLifeCycleListeners = newListeners;
169                 }
170             }
171         }
172     }
173
174     /**
175      * @see org.apache.ojb.broker.PersistenceBroker#removeListener(PBListener listener)
176      */

177     public void removeListener(PBListener listener) throws PersistenceBrokerException
178     {
179         if (listener instanceof PBStateListener)
180         {
181             if (contains(permanentStateListeners, listener))
182             {
183                 PBStateListener[] newListeners = new PBStateListener[permanentStateListeners.length - 1];
184                 int pos = 0;
185
186                 for (int i = 0; i < permanentStateListeners.length; i++)
187                 {
188                     if (permanentStateListeners[i] != listener)
189                     {
190                         newListeners[pos++] = permanentStateListeners[i];
191                     }
192                 }
193                 permanentStateListeners = newListeners;
194             }
195
196             if (contains(temporaryStateListeners, listener))
197             {
198                 PBStateListener[] newListeners = new PBStateListener[temporaryStateListeners.length - 1];
199                 int pos = 0;
200
201                 for (int i = 0; i < temporaryStateListeners.length; i++)
202                 {
203                     if (temporaryStateListeners[i] != listener)
204                     {
205                         newListeners[pos++] = temporaryStateListeners[i];
206                     }
207                 }
208                 temporaryStateListeners = newListeners;
209             }
210         }
211
212         if (listener instanceof PBLifeCycleListener)
213         {
214             if (contains(permanentLifeCycleListeners, listener))
215             {
216                 PBLifeCycleListener[] newListeners = new PBLifeCycleListener[permanentLifeCycleListeners.length - 1];
217                 int pos = 0;
218
219                 for (int i = 0; i < permanentLifeCycleListeners.length; i++)
220                 {
221                     if (permanentLifeCycleListeners[i] != listener)
222                     {
223                         newListeners[pos++] = permanentLifeCycleListeners[i];
224                     }
225                 }
226                 permanentLifeCycleListeners = newListeners;
227             }
228
229             if (contains(temporaryLifeCycleListeners, listener))
230             {
231                 PBLifeCycleListener[] newListeners = new PBLifeCycleListener[temporaryLifeCycleListeners.length - 1];
232                 int pos = 0;
233
234                 for (int i = 0; i < temporaryLifeCycleListeners.length; i++)
235                 {
236                     if (temporaryLifeCycleListeners[i] != listener)
237                     {
238                         newListeners[pos++] = temporaryLifeCycleListeners[i];
239                     }
240                 }
241                 temporaryLifeCycleListeners = newListeners;
242             }
243         }
244     }
245
246     protected boolean contains(PBListener[] listeners, PBListener listener)
247     {
248         for (int i = listeners.length - 1; i >= 0; i--)
249         {
250             if (listeners[i] == listener) return true;
251         }
252
253         return false;
254     }
255
256     /**
257      * @see org.apache.ojb.broker.PersistenceBroker#removeAllListeners(boolean)
258      */

259     public void removeAllListeners(boolean permanent) throws PersistenceBrokerException
260     {
261         if (permanent)
262         {
263             // remove permanent listeners as well
264
permanentStateListeners = NO_STATE_LISTENERS;
265             permanentLifeCycleListeners = NO_LIFECYCLE_LISTENERS;
266         }
267
268         temporaryStateListeners = NO_STATE_LISTENERS;
269         temporaryLifeCycleListeners = NO_LIFECYCLE_LISTENERS;
270     }
271
272     /**
273      * @see org.apache.ojb.broker.PersistenceBroker#removeAllListeners()
274      */

275     public void removeAllListeners() throws PersistenceBrokerException
276     {
277         removeAllListeners(false);
278     }
279
280     public void fireBrokerEvent(PersistenceBrokerEvent event)
281     {
282         if (event instanceof PBLifeCycleEvent)
283         {
284             fireBrokerEvent((PBLifeCycleEvent) event);
285         }
286         else if (event instanceof PBStateEvent)
287         {
288             fireBrokerEvent((PBStateEvent) event);
289         }
290         else
291         {
292             LoggerFactory.getDefaultLogger().error(
293                     PersistenceBrokerAbstractImpl.class.getName() + ": Unkown PersistenceBrokerEvent was fired " + event);
294         }
295     }
296
297     public void fireBrokerEvent(PBLifeCycleEvent event)
298     {
299         if (event.getPersitenceBrokerAware() != null)
300         {
301             // first we do the persistent object callback
302
performCallBack(event);
303         }
304
305         // copy array references so they can't change in the middle of iteration
306
PBLifeCycleListener[] permanent = permanentLifeCycleListeners;
307         PBLifeCycleListener[] temporary = temporaryLifeCycleListeners;
308
309         // now we notify the listeners
310
for (int i = permanent.length - 1; i >= 0; i--)
311         {
312             notifiyObjectLifeCycleListener(permanent[i], event);
313         }
314
315         for (int i = temporary.length - 1; i >= 0; i--)
316         {
317             notifiyObjectLifeCycleListener(temporary[i], event);
318         }
319     }
320
321     public void fireBrokerEvent(PBStateEvent event)
322     {
323         // copy array references so they can't change in the middle of iteration
324
PBStateListener[] permanent = permanentStateListeners;
325         PBStateListener[] temporary = temporaryStateListeners;
326
327         // now we notify the listeners
328
for (int i = permanent.length - 1; i >= 0; i--)
329         {
330             notifiyStateListener(permanent[i], event);
331         }
332
333         for (int i = temporary.length - 1; i >= 0; i--)
334         {
335             notifiyStateListener(temporary[i], event);
336         }
337     }
338
339     private void performCallBack(PBLifeCycleEvent event)
340     {
341         // Check for null
342
if (event.getPersitenceBrokerAware() == null) return;
343         switch (event.getEventType().typeId())
344         {
345             case PBLifeCycleEvent.TYPE_AFTER_LOOKUP:
346                 event.getPersitenceBrokerAware().afterLookup(event.getTriggeringBroker());
347                 break;
348             case PBLifeCycleEvent.TYPE_BEFORE_UPDATE:
349                 event.getPersitenceBrokerAware().beforeUpdate(event.getTriggeringBroker());
350                 break;
351             case PBLifeCycleEvent.TYPE_AFTER_UPDATE:
352                 event.getPersitenceBrokerAware().afterUpdate(event.getTriggeringBroker());
353                 break;
354             case PBLifeCycleEvent.TYPE_BEFORE_INSERT:
355                 event.getPersitenceBrokerAware().beforeInsert(event.getTriggeringBroker());
356                 break;
357             case PBLifeCycleEvent.TYPE_AFTER_INSERT:
358                 event.getPersitenceBrokerAware().afterInsert(event.getTriggeringBroker());
359                 break;
360             case PBLifeCycleEvent.TYPE_BEFORE_DELETE:
361                 event.getPersitenceBrokerAware().beforeDelete(event.getTriggeringBroker());
362                 break;
363             case PBLifeCycleEvent.TYPE_AFTER_DELETE:
364                 event.getPersitenceBrokerAware().afterDelete(event.getTriggeringBroker());
365                 break;
366         }
367     }
368
369     private void notifiyStateListener(PBStateListener listener, PBStateEvent stateEvent)
370     {
371         switch (stateEvent.getEventType().typeId())
372         {
373             case PBStateEvent.KEY_BEFORE_COMMIT:
374                 listener.beforeCommit(stateEvent);
375                 break;
376             case PBStateEvent.KEY_AFTER_COMMIT:
377                 listener.afterCommit(stateEvent);
378                 break;
379             case PBStateEvent.KEY_BEFORE_BEGIN:
380                 listener.beforeBegin(stateEvent);
381                 break;
382             case PBStateEvent.KEY_AFTER_BEGIN:
383                 listener.afterBegin(stateEvent);
384                 break;
385             case PBStateEvent.KEY_BEFORE_CLOSE:
386                 listener.beforeClose(stateEvent);
387                 break;
388             case PBStateEvent.KEY_AFTER_OPEN:
389                 listener.afterOpen(stateEvent);
390                 break;
391             case PBStateEvent.KEY_AFTER_ROLLBACK:
392                 listener.afterRollback(stateEvent);
393                 break;
394             case PBStateEvent.KEY_BEFORE_ROLLBACK:
395                 listener.beforeRollback(stateEvent);
396                 break;
397         }
398     }
399
400     private void notifiyObjectLifeCycleListener(PBLifeCycleListener listener, PBLifeCycleEvent lifeEvent)
401     {
402         switch (lifeEvent.getEventType().typeId())
403         {
404             case PBLifeCycleEvent.TYPE_AFTER_LOOKUP:
405                 listener.afterLookup(lifeEvent);
406                 break;
407             case PBLifeCycleEvent.TYPE_BEFORE_UPDATE:
408                 listener.beforeUpdate(lifeEvent);
409                 break;
410             case PBLifeCycleEvent.TYPE_AFTER_UPDATE:
411                 listener.afterUpdate(lifeEvent);
412                 break;
413             case PBLifeCycleEvent.TYPE_BEFORE_INSERT:
414                 listener.beforeInsert(lifeEvent);
415                 break;
416             case PBLifeCycleEvent.TYPE_AFTER_INSERT:
417                 listener.afterInsert(lifeEvent);
418                 break;
419             case PBLifeCycleEvent.TYPE_BEFORE_DELETE:
420                 listener.beforeDelete(lifeEvent);
421                 break;
422             case PBLifeCycleEvent.TYPE_AFTER_DELETE:
423                 listener.afterDelete(lifeEvent);
424                 break;
425         }
426     }
427
428     /*
429     arminw:
430     get the PB state event here, this helps to
431     avoid object instantiation for any event call
432     */

433     protected final PBStateEvent AFTER_OPEN_EVENT = new PBStateEvent(this, PBStateEvent.Type.AFTER_OPEN);
434     protected final PBStateEvent AFTER_BEGIN_EVENT = new PBStateEvent(this, PBStateEvent.Type.AFTER_BEGIN);
435     protected final PBStateEvent AFTER_COMMIT_EVENT = new PBStateEvent(this, PBStateEvent.Type.AFTER_COMMIT);
436     protected final PBStateEvent AFTER_ROLLBACK_EVENT = new PBStateEvent(this, PBStateEvent.Type.AFTER_ROLLBACK);
437     protected final PBStateEvent BEFORE_BEGIN_EVENT = new PBStateEvent(this, PBStateEvent.Type.BEFORE_BEGIN);
438     protected final PBStateEvent BEFORE_COMMIT_EVENT = new PBStateEvent(this, PBStateEvent.Type.BEFORE_COMMIT);
439     protected final PBStateEvent BEFORE_ROLLBACK_EVENT = new PBStateEvent(this, PBStateEvent.Type.BEFORE_ROLLBACK);
440     protected final PBStateEvent BEFORE_CLOSE_EVENT = new PBStateEvent(this, PBStateEvent.Type.BEFORE_CLOSE);
441
442     /*
443     arminw:
444     here we could get the PB state event, this helps to
445     avoid object instantiation on every event
446     NOTE: It's a little critical, because caller shouldn't forget
447     to set the target object using #setTargetObject(...) method.
448     This means that we use the same event object with changed
449     fields.
450     TODO: find a better solution (and performant)
451     */

452     protected PBLifeCycleEvent BEFORE_STORE_EVENT =
453             new PBLifeCycleEvent(this, PBLifeCycleEvent.Type.BEFORE_INSERT);
454     protected PBLifeCycleEvent AFTER_STORE_EVENT =
455             new PBLifeCycleEvent(this, PBLifeCycleEvent.Type.AFTER_INSERT);
456     protected PBLifeCycleEvent BEFORE_DELETE_EVENT =
457             new PBLifeCycleEvent(this, PBLifeCycleEvent.Type.BEFORE_DELETE);
458     protected PBLifeCycleEvent AFTER_DELETE_EVENT =
459             new PBLifeCycleEvent(this, PBLifeCycleEvent.Type.AFTER_DELETE);
460     protected PBLifeCycleEvent AFTER_LOOKUP_EVENT =
461             new PBLifeCycleEvent(this, PBLifeCycleEvent.Type.AFTER_LOOKUP);
462     protected PBLifeCycleEvent BEFORE_UPDATE_EVENT =
463             new PBLifeCycleEvent(this, PBLifeCycleEvent.Type.BEFORE_UPDATE);
464     protected PBLifeCycleEvent AFTER_UPDATE_EVENT =
465             new PBLifeCycleEvent(this, PBLifeCycleEvent.Type.AFTER_UPDATE);
466 }
467
468
Popular Tags