View Javadoc

1   /* (c) Copyright 2003 Caleigo AB, All rights reserved. 
2    * 
3    * This library is free software; you can redistribute it and/or
4    * modify it under the terms of the GNU Lesser General Public
5    * License as published by the Free Software Foundation; either
6    * version 2.1 of the License, or (at your option) any later version.
7    * 
8    * This library is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   * Lesser General Public License for more details.
12   * 
13   * You should have received a copy of the GNU Lesser General Public
14   * License along with this library; if not, write to the Free Software
15   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16   *  
17   */
18  package org.caleigo.core;
19  
20  
21  import java.util.*;
22  
23  import org.caleigo.core.event.*;
24  import org.caleigo.toolkit.util.*;
25  
26  /*** The ActionQueue class containes an ordred queue of perform requests with
27   * ITransactionEntityAction objects and connected relevant action data.
28    *
29   * @author  Dennis Zikovic
30   * @version 1.00
31   *
32   *//*
33   *
34   * WHEN        WHO               WHY & WHAT
35   * -----------------------------------------------------------------------------
36   * 2002-10-07  Dennis Zikovic    Creation
37   */
38  public class ActionQueue
39  {
40      // Constants ---------------------------------------------------------------
41      
42      // Data members ------------------------------------------------------------
43      private List mActionList;
44      
45      // Constructors ------------------------------------------------------------
46      
47      /*** Creates a new instance of ActionQueue
48       */
49      public ActionQueue()
50      {
51          mActionList = new LinkedList();
52      }
53      
54      // Superclass overrides ----------------------------------------------------
55      
56      // Action methods ----------------------------------------------------------
57      
58      /*** Action method tha will add all queued actions on the transaction in the
59       * order they were added to the called ActionQueue. Note that the queue will
60       * not be cleraed automatically when this method is called. <BR><BR>
61       *
62       * 
63       */
64      public void prepareTransaction(IDataTransaction transaction)
65      {
66          for(int j=0; j<mActionList.size(); j++)
67          {
68              ActionRequest request = (ActionRequest)mActionList.get(j);
69              if(request!=null)
70                  request.prepareTransaction(transaction);
71          }
72      }
73      
74      // Access methods ----------------------------------------------------------
75      
76      /*** Adds the provided action request to the queue with the provided 
77       * data bundle.
78       */
79      public void addAction(ITransactionEntityAction entityAction, IDataBundle dataBundle)
80      {
81          if(entityAction.getDataBundleDescriptor()!=dataBundle.getDataBundleDescriptor())
82              throw new IllegalArgumentException("Incompatible data bundle descriptors!");
83          
84          if(entityAction.getCodeName().equals(IEntityDescriptor.STORE_ACTION))
85              mActionList.add(new DirtyOnlyRequest(entityAction, dataBundle));
86          else
87              mActionList.add(new ActionRequest(entityAction, dataBundle));
88      }
89      
90      /*** Adds the provided action request to the queue with the provided entity.
91       */
92      public void addAction(ITransactionEntityAction entityAction, IEntity entity)
93      {
94          if(!(entityAction instanceof IUnaryEntityAction))
95              throw new IllegalArgumentException("Action must be IUnaryEntityAction!");       
96          IDataBundle dataBundle = entityAction.getDataBundleDescriptor().createActionData();
97          if(entity!=null && dataBundle.getDataBundleDescriptor().getEntityDescriptor(0)!=entity.getEntityDescriptor())
98              throw new IllegalArgumentException("Provided entity does not meet action data requirements!");
99          dataBundle.setData(0, entity);
100         this.addAction(entityAction, dataBundle);
101     }
102     
103     /*** Clears all queued actions from the called ActionQueue.
104      */
105     public void clear()
106     {
107         for(int j=0; j<mActionList.size(); j++)
108             ((ActionRequest)mActionList.get(j)).finalizeTransaction();
109         mActionList.clear();
110     }
111     
112     /*** Clears all queued actions request of the provided action from 
113      * the called ActionQueue.
114      */
115     public void clear(ITransactionEntityAction action)
116     {
117         ActionRequest current = null;
118         Iterator it = mActionList.iterator();
119         while(it.hasNext())
120         {
121             current = (ActionRequest)it.next();
122             if(current.getAction().equals(action))
123             {
124                 current.finalizeTransaction();
125                 it.remove();
126             }
127         }
128     }
129     
130     /*** Clears all queued IUnaryEntityAction requests of the specified type 
131      * targeted on the provided entity. If action is null all IUnaryEntityAction 
132      * requests on the targeted entity is removed.
133      */
134     public void clear(IUnaryEntityAction action, IEntity entity)
135     {
136         ActionRequest current = null;
137         Iterator it = mActionList.iterator();
138         while(it.hasNext())
139         {
140             current = (ActionRequest)it.next();
141             if((action==null || current.getAction()==action) && current.getDataBundle().getDataBundleDescriptor().getItemCount()==1 && current.getDataBundle().getData(0).equals(entity))
142             {
143                 current.finalizeTransaction();
144                 it.remove();
145             }
146         }
147     }
148     
149     /*** Returns the true if no action request are queued.
150      */
151     public boolean isEmpty()
152     {
153         return mActionList.isEmpty();
154     }
155     
156     /*** Returns the number of queued entity actions.
157      */
158     public int getActionCount()
159     {
160         return mActionList.size();
161     }
162     
163     /*** Returns the indexed action object from the queue.
164      */
165     public ITransactionEntityAction getAction(int index)
166     {
167         return ((ActionRequest)mActionList.get(index)).getAction();
168     }
169     
170     /*** Returns the indexed action data object from the queue.
171      */
172     public IDataBundle getActionData(int index)
173     {
174         return ((ActionRequest)mActionList.get(index)).getDataBundle();
175     }
176         
177     /*** Access method that returns an iterator for all contained action objects
178      * in the called ActionQueue.
179      */
180     public Iterator getActions()
181     {
182         return new Iterators.WrapIterator(mActionList.iterator())
183                 {
184                     public Object next() 
185                     {
186                         return ((ActionRequest)mIterator.next()).getAction();
187                     }
188                 };
189     }
190     
191     // Internal classes --------------------------------------------------------
192     
193     /*** Queue item that groups an ITransactionEntityAction with execution data
194      * together as an quable item. 
195      */
196     protected static class ActionRequest
197     {
198         // Data members --------------------------------------------------------
199         private ITransactionEntityAction mEntityAction;
200         private IDataBundle mDataBundle;
201         
202         // Constructors --------------------------------------------------------        
203         public ActionRequest(ITransactionEntityAction action, IDataBundle dataBundle)
204         {
205             mEntityAction = action;
206             mDataBundle = dataBundle;
207         }
208         
209         // Action methods ------------------------------------------------------        
210         public void prepareTransaction(IDataTransaction transaction)
211         {
212             mEntityAction.prepareTransaction(mDataBundle, transaction);
213         }        
214         
215         public void finalizeTransaction()
216         {
217         }
218         
219         // Action methods ------------------------------------------------------
220         public ITransactionEntityAction getAction()
221         {
222             return mEntityAction;
223         }
224         
225         public IDataBundle getDataBundle()
226         {
227             return mDataBundle;
228         }
229     }
230     
231     /*** Queue item that groups an ITransactionEntityAction with execution data
232      * together as an quable item. This request will remove itself from the
233      * the queue automatically when target entity becomes non-dirty.
234      */
235     protected class DirtyOnlyRequest extends ActionRequest implements IEntityChangeListener
236     {
237         // Constructors --------------------------------------------------------        
238         public DirtyOnlyRequest(ITransactionEntityAction action, IDataBundle dataBundle)
239         {
240             super(action, dataBundle);
241             if(action.getDataBundleDescriptor().getItemCount()==1 && action.getDataBundleDescriptor().getItemType(0)==IDataBundleDescriptor.ENTITY)
242                 ((IEntity)dataBundle.getData(0)).addEntityChangeListener(this);
243         }
244         
245         // Superclass overrides ------------------------------------------------
246         public void finalizeTransaction()
247         {
248             if(this.getAction().getDataBundleDescriptor().getItemCount()==1 && this.getDataBundle().getDataBundleDescriptor().getItemType(0)==IDataBundleDescriptor.ENTITY)
249                 ((IEntity)this.getDataBundle().getData(0)).removeEntityChangeListener(this);
250         }
251         
252         // IEntityChangeListener implementation --------------------------------
253         public void dataChanged(EntityChangeEvent event)
254         {
255         }
256         
257         public void statusChanged(EntityChangeEvent event)
258         {
259             if(event.getSourceEntity().isPersistent() && !event.getSourceEntity().isDirty())
260                 mActionList.remove(this);
261         }
262     }
263 }