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  
19  package org.caleigo.core;
20  
21  import java.util.*;
22  
23  import org.caleigo.core.exception.DataServiceException;
24  import org.caleigo.service.ServiceException;
25  import org.caleigo.toolkit.tunnel.*;
26  
27  
28  /***
29   *
30   * @author  Mattias Hagstrand
31   * @version 1.00
32   * 
33   *//* 
34   *
35   * WHEN        WHO               WHY & WHAT
36   * -----------------------------------------------------------------------------
37   * 2002-08-01  Mattias Hagstrand    Creation
38   */
39  public class TunneledDataService extends AbstractDataService implements org.caleigo.service.IProxyService
40  {
41      // Data members ------------------------------------------------------------
42      protected transient ITunnel mTunnel;
43      
44      // Constructors ------------------------------------------------------------
45      public TunneledDataService(Object serviceType,
46                                 Object serviceIdentity,
47                                 IDataSourceDescriptor dataSourceDescriptor,
48                                 ITunnel tunnel)
49      {
50          super(serviceType, serviceIdentity, dataSourceDescriptor);
51          mTunnel = tunnel;
52      }
53      
54      // IProxyService implementation --------------------------------------------
55      
56      /*** Returns <code>true</code> if this IProxyService can be reconnected to
57       * an IService.
58       */
59      public boolean isReconnectable()
60      {
61          return false;
62      }
63      
64      /*** Tries to reconnect to the provided service. If the reconnection fails
65       * or if this IProxyService doesn't support reconnection an exception is
66       * thrown.
67       */
68      public void reconnect(ITunnel tunnel) throws ServiceException
69      {
70          throw new ServiceException("Operation not supported");
71      }
72      
73      /*** Sets the ITunnel that should be used by this IProxyService.
74       */
75      public void setServiceTunnel(ITunnel tunnel)
76      {
77          mTunnel = tunnel;
78      }
79      
80      // Superclass overrides ----------------------------------------------------
81      public IDataTransaction newTransaction()
82      {
83          return new TunneledDataTransaction(getTimeout(),
84                                             getServiceInterfaceClass(),
85                                             getServiceType(),
86                                             getServiceIdentity(),
87                                             mTunnel);
88      }
89      
90      public boolean ping()
91      {
92          try
93          {
94              mTunnel.ping();
95              return true;
96          }
97          catch (TunnelException e)
98          {
99              return false;
100         }
101     }
102     
103     // Nested classes ----------------------------------------------------------
104     protected static class TunneledDataTransaction extends AbstractDataTransaction implements IMessageConsumer
105     {
106         // Data members --------------------------------------------------------
107         protected Class mServiceInterfaceClass;
108         protected Object mServiceType;
109         protected Object mServiceIdentity;
110         protected transient ITunnel mTunnel;
111         
112         // Constructors --------------------------------------------------------
113         public TunneledDataTransaction(int timeout,
114                                        Class serviceInterfaceClass,
115                                        Object serviceType,
116                                        Object serviceIdentity,
117                                        ITunnel tunnel)
118         {
119             super(timeout);
120             
121             mServiceInterfaceClass = serviceInterfaceClass;
122             mServiceType = serviceType;
123             mServiceIdentity = serviceIdentity;
124             mTunnel = tunnel;
125             
126             mTunnel.addMessageConsumer(this);
127         }
128         
129         // Superclass overrides ------------------------------------------------
130         
131         /*** Commit performs all the stored operations in the transaction. 
132          * If any of the operations fail a rollback on all operations will be
133          * automatically performed and a TransactionFailedException will be thrown.
134          */
135         public void commit() throws DataServiceException
136         {
137             TunneledDataServiceReturnMessage returnMessage = null;
138             try
139             {
140                 returnMessage = (TunneledDataServiceReturnMessage) mTunnel.ask(new TunneledDataServiceCommitMessage(mServiceInterfaceClass, mServiceType, mServiceIdentity, this));
141             }
142             catch (TunnelException e)
143             {
144                 throw new DataServiceException(e.getMessage());
145             }
146             
147             this.copyTransactionData(returnMessage.getOperations());
148         }
149         
150         public void abortTransaction() throws DataServiceException
151         {
152             try
153             {
154                 mTunnel.ask(new TunneledDataServiceAbortTransactionMessage(mServiceInterfaceClass, mServiceType, mServiceIdentity, this.getID()));
155             } catch (TunnelException e)
156             {
157                 throw new DataServiceException(e.getMessage());
158             }
159         }
160         
161         // IMessageConsumer implementation -------------------------------------
162         
163         public boolean acceptsMessage(Object message)
164         {
165             return (message instanceof TunneledDataServiceProgressMessage);
166         }
167         
168         public Object answerMessage(Object message)
169         {
170             return null;
171         }
172 
173         public void consumeMessage(Object message)
174         {
175             if (mJob != null)
176             {
177                 TunneledDataServiceProgressMessage progressMessage = (TunneledDataServiceProgressMessage) message;
178                 mJob.fireProgressChangedEvent(progressMessage.mMaxProgress, progressMessage.mCurrentProgress);
179             }
180         }
181         
182         // Help methods --------------------------------------------------------
183         protected void copyTransactionData(AbstractDataTransaction.DataOperation[] sourceDataOperations)
184         {
185             Enumeration targetDataOperations = this.getOperations();
186             //while(sourceDataOperations.hasMoreElements() && targetDataOperations.hasMoreElements())
187             for (int i = 0; i < sourceDataOperations.length && targetDataOperations.hasMoreElements(); i++)
188             {		
189                 //DataOperation sourceOperation = (DataOperation) sourceDataOperations.nextElement();
190                 DataOperation sourceOperation = sourceDataOperations[i];
191                 DataOperation targetOperation = (DataOperation) targetDataOperations.nextElement();
192                 switch(sourceOperation.getOperationType())
193                 {	
194                     case DataOperation.LOAD:
195                     case DataOperation.REFRESH:
196                         this.copyEntity(sourceOperation.getEntity(), targetOperation.getEntity());
197                     break;
198                     case DataOperation.QUERY:
199                         Iterator entities = sourceOperation.getEntitySelection().iterator();
200                         while (entities.hasNext())
201                             targetOperation.getEntitySelection().addEntity((IEntity) entities.next());
202                     break;
203                     case DataOperation.STORE:
204                     case DataOperation.DELETE:
205                         this.copyEntityStatusFlags(sourceOperation.getEntity(), targetOperation.getEntity());
206                     break;
207                 }
208             }
209         }
210         
211         protected void copyEntity(IEntity sourceEntity, IEntity targetEntity)
212         {
213             targetEntity.copyData(sourceEntity);
214             this.copyEntityStatusFlags(sourceEntity, targetEntity);
215         }
216         
217         protected void copyEntityStatusFlags(IEntity sourceEntity, IEntity targetEntity)
218         {
219             if (sourceEntity.isDirty())
220                 targetEntity.setStatusFlag(IEntity.DIRTY);
221             else
222                 targetEntity.clearStatusFlag(IEntity.DIRTY);
223             if (sourceEntity.isEmpty())
224                 targetEntity.setStatusFlag(IEntity.EMPTY);
225             else
226                 targetEntity.clearStatusFlag(IEntity.EMPTY);
227             if (sourceEntity.isPersistent())
228                 targetEntity.setStatusFlag(IEntity.PERSISTENT);
229             else
230                 targetEntity.clearStatusFlag(IEntity.PERSISTENT);
231         }
232     }
233     
234     protected abstract static class TunneledDataServiceMessage implements java.io.Serializable
235     {
236         // Data members --------------------------------------------------------
237         protected Class mServiceInterfaceClass;
238         protected Object mServiceType;
239         protected Object mServiceIdentity;
240         
241         // Constructors --------------------------------------------------------
242         public TunneledDataServiceMessage(Class serviceInterfaceClass,
243                                                 Object serviceType,
244                                                 Object serviceIdentity)
245         {
246             mServiceInterfaceClass = serviceInterfaceClass;
247             mServiceType = serviceType;
248             mServiceIdentity = serviceIdentity;
249         }
250     }
251     
252     protected static class TunneledDataServiceCommitMessage extends TunneledDataServiceMessage
253     {
254         // Data members --------------------------------------------------------
255         protected TunneledDataTransaction mTransaction;
256         
257         // Constructors --------------------------------------------------------
258         public TunneledDataServiceCommitMessage(Class serviceInterfaceClass,
259                                                 Object serviceType,
260                                                 Object serviceIdentity,
261                                                 TunneledDataTransaction transaction)
262         {
263             super(serviceInterfaceClass, serviceType, serviceIdentity);
264             mTransaction = transaction;
265         }
266         
267         // Access methods ------------------------------------------------------
268         public TunneledDataTransaction getTransaction()
269         {
270             return mTransaction;
271         }
272     }
273     
274     protected static class TunneledDataServiceAbortTransactionMessage extends TunneledDataServiceMessage
275     {
276         // Data members --------------------------------------------------------
277         private int mTransactionID;
278         
279         // Constructors --------------------------------------------------------
280         public TunneledDataServiceAbortTransactionMessage(Class serviceInterfaceClass,
281                                                           Object serviceType,
282                                                           Object serviceIdentity,
283                                                           int transactionID)
284         {
285             super(serviceInterfaceClass, serviceType, serviceIdentity);
286             mTransactionID = transactionID;
287         }
288         
289         // Access methods ------------------------------------------------------
290         public int getTransactionID()
291         {
292             return mTransactionID;
293         }
294     }
295     
296     protected static class TunneledDataServiceProgressMessage extends TunneledDataServiceMessage
297     {
298         // Data members --------------------------------------------------------
299         protected int mMaxProgress;
300         protected int mCurrentProgress;
301         
302         // Constructors --------------------------------------------------------
303         public TunneledDataServiceProgressMessage(Class serviceInterfaceClass,
304                                                   Object serviceType,
305                                                   Object serviceIdentity,
306                                                   int maxProgress,
307                                                   int currentProgress)
308         {
309             super(serviceInterfaceClass, serviceType, serviceIdentity);
310             mMaxProgress = maxProgress;
311             mCurrentProgress = currentProgress;
312         }
313     }
314     
315     protected static class TunneledDataServiceReturnMessage implements java.io.Serializable
316     {
317         // Data members --------------------------------------------------------
318         protected AbstractDataTransaction.DataOperation[] mOperations;
319         protected DataServiceException mException;
320         
321         // Constructors --------------------------------------------------------
322         public TunneledDataServiceReturnMessage(AbstractDataTransaction.DataOperation[] operations)
323         {
324             mOperations = operations;
325         }
326         
327         public TunneledDataServiceReturnMessage(DataServiceException exception)
328         {
329             mException = exception;
330         }
331         
332         // Access methods ------------------------------------------------------
333         public AbstractDataTransaction.DataOperation[] getOperations()
334             throws DataServiceException
335         {
336             if (mException != null)
337                 throw mException;
338             
339             return mOperations;
340         }
341     }
342 }