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  import java.lang.reflect.Method;
21  
22  import org.caleigo.core.IDataTransaction.*;
23  import org.caleigo.toolkit.log.Log;
24  
25  /*** 
26   *
27   * @author  mha
28   * @version 1.00
29   *
30   */ /*
31   *
32   * WHEN        WHO               WHY & WHAT
33   * -----------------------------------------------------------------------------
34   * Mar 15, 2004  Mattias Hagstrand    Creation
35   */
36  public class AsyncTransactionHandler
37  {
38      // Constants ---------------------------------------------------------------
39      protected final static int STARTED = 1;
40      protected final static int FINISHED = 2;
41      protected final static int COMPLETED = 3;
42      protected final static int CANCELED = 4;
43      protected final static int FAILED = 5;
44      
45      public final static int COMMIT_SUCCEEDED = 1;
46      public final static int COMMIT_CANCELED = 2;
47      public final static int COMMIT_FAILED = 3;
48      
49      // Class members -----------------------------------------------------------
50      private static Class sDefaultAsyncTransactionHandlerClass;
51      
52      // Static methods ----------------------------------------------------------
53      public static void setDefaultAsyncTransactionHandlerClass(Class handlerClass)
54      {
55          if (!AsyncTransactionHandler.class.isAssignableFrom(handlerClass))
56              throw new IllegalArgumentException("Handler class must be an AsyncTransactionHandler sub class");
57              
58          try
59          {
60              handlerClass.getConstructor(new Class[0]);
61          } catch (Exception e)
62          {
63              throw new IllegalArgumentException("Handler class must have a default constructor");
64          }
65          
66          sDefaultAsyncTransactionHandlerClass = handlerClass;
67      }
68      
69      public static AsyncTransactionHandler create()
70      {
71          if (sDefaultAsyncTransactionHandlerClass == null)
72              throw new IllegalStateException("No default transaction handler has been set");
73  
74          AsyncTransactionHandler handler = null;
75          try
76          {
77              handler = (AsyncTransactionHandler) sDefaultAsyncTransactionHandlerClass.getConstructor(new Class[0]).newInstance(new Object[0]);
78          } catch (Exception e)
79          {
80              Log.printError(null, "Failed to create default transaction handler", e);
81          }
82                  
83          return handler;
84      }
85      
86      // Data members ------------------------------------------------------------
87      private Object mCallbackObject;
88      private String mCallbackMethodName;
89      
90      // Constructors ------------------------------------------------------------
91      
92      // Access methods ----------------------------------------------------------
93      
94      /*** Sets the method that should be invoked when the transaction has finished.
95       * This method is invoked before the corresponding doOn-method is invoked.
96       * 
97       * Note: The callback method must not declare one int parameter that will be
98       * set to one of COMMIT_SUCCEEDED, COMMIT_CANCELED or COMMIT_FAILED.
99       */
100     public void setCallback(Object callbackObject, String methodName)
101     {
102         if (callbackObject == null)
103             throw new IllegalArgumentException("callbackObject must not be null");
104         if (methodName == null)
105             throw new IllegalArgumentException("methodName must not be null");
106             
107         try
108         {
109             callbackObject.getClass().getMethod(methodName, new Class[] {Integer.TYPE});
110         } catch (Exception e)
111         {
112             throw new IllegalArgumentException("The callback method was not found");
113         }
114         
115         mCallbackObject = callbackObject;
116         mCallbackMethodName = methodName;
117     }
118     
119     public Job commit(IDataTransaction transaction)
120     {
121         Job job = transaction.commitAsynchroniesly(null);
122         job.addProgressListener(new ProgressListener());
123         
124         return job;
125     }
126     
127     // Help methods ------------------------------------------------------------
128     
129     /*** Invoked when the commit execution starts.
130      */
131     protected void doOnCommitStarted()
132     {
133     }
134     
135     /*** Invoked when the commit execution has finished. Execution finishes when
136      * the commit has completed, has been canceled or has failed. This method is
137      * invoked before one of doOnCommitCompleted, doOnCommitCanceled or
138      * doOnCommitFailed is invoked.
139      */
140     protected void doOnCommitFinished()
141     {
142     }
143     
144     /*** Invoked when the commit execution has completed.
145      */
146     protected void doOnCommitCompleted()
147     {
148     }
149     
150     /*** Invoked when the commit execution has been successfully canceled.
151      */
152     protected void doOnCommitCanceled()
153     {
154     }
155     
156     /*** Invoked when the commit execution has failed.
157      */
158     protected void doOnCommitFailed()
159     {
160     }
161     
162     /*** Invoked when one of the doOn-methods should be invoked. Extending classes
163      * should not change the behaviour of this method, but should make sure that
164      * it is executed in a thread safe manner. Typically, is GUI operations needs
165      * to be performed in the doOn-methods this method should be run in the dispatcher
166      * thread.
167      */
168     protected void performNotification(int type)
169     {
170         switch (type)
171         {
172             case STARTED:
173                 this.doOnCommitStarted();
174                 break;
175             case FINISHED:
176                 this.doOnCommitFinished();
177                 break;
178             case COMPLETED:
179                 this.invokeCallback(COMMIT_SUCCEEDED);
180                 this.doOnCommitCompleted();
181                 break;
182             case CANCELED:
183                 this.invokeCallback(COMMIT_CANCELED);
184                 this.doOnCommitCanceled();
185                 break;
186             case FAILED:
187                 this.invokeCallback(COMMIT_FAILED);
188                 this.doOnCommitFailed();
189                 break;
190         }
191     }
192     
193     private void invokeCallback(int status)
194     {
195         if (mCallbackObject != null)
196         {
197             try
198             {
199                 Method callbackMethod = mCallbackObject.getClass().getMethod(mCallbackMethodName, new Class[] {Integer.TYPE});
200                 callbackMethod.invoke(mCallbackObject, new Object[] {new Integer(status)});
201             } catch (Exception e)
202             {
203                 Log.printError(this, "Failed to invoke callback", e);
204             }
205         }
206     }
207     
208     // Nested classes ----------------------------------------------------------
209     private class ProgressListener implements IDataTransaction.IProgressListener
210     {
211         public void jobStarted(ProgressEvent e)
212         {
213             performNotification(STARTED);
214         }
215         
216         public void jobCompleted(ProgressEvent e)
217         {
218             performNotification(FINISHED);
219             performNotification(COMPLETED);
220         }
221         
222         public void jobCanceled(ProgressEvent e)
223         {
224             performNotification(FINISHED);
225             performNotification(CANCELED);
226         }
227         
228         public void jobFailed(ProgressEvent e)
229         {
230             performNotification(FINISHED);
231             performNotification(FAILED);
232         }
233         
234         public void progressChanged(ProgressEvent e)
235         {
236         }
237     }
238 }