Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/flexstor/flexdbserver/services/checkincheckout/CheckInService.java


1   /*
2    * CheckInService.java
3    *
4    * Copyright $Date: 2003/08/11 02:22:49 $ FLEXSTOR.net Inc.
5    *
6    * This work is licensed for use and distribution under license terms found at
7    * http://www.flexstor.org/license.html
8    *
9    */
10  
11  package com.flexstor.flexdbserver.services.checkincheckout;
12  
13  import java.util.Enumeration;
14  import java.util.Hashtable;
15  import java.util.Vector;
16  
17  import com.flexstor.common.data.ActionData;
18  import com.flexstor.common.data.ActionResult;
19  import com.flexstor.common.data.AssetRecordData;
20  import com.flexstor.common.resources.Resources;
21  import com.flexstor.common.threadmgr.ThreadCallbackI;
22  import com.flexstor.common.threadmgr.ThreadConsumerI;
23  import com.flexstor.flexdbserver.services.Service;
24  import com.flexstor.flexdbserver.services.ServiceContext;
25  import com.flexstor.flexdbserver.transactionmanager.TransMngCheckIn;
26  
27  /**
28   * <P>
29   * CheckInService <BR>
30   * <BLOCKQUOTE>
31   *    Checks in new versions of assets after modifications, making such assets the current assets
32   *    in the system. Older versions are kept in the system.
33   * </BLOCKQUOTE>
34   * </P>
35   *
36   * <P>
37   * Input Data Object <BR>
38   * <BLOCKQUOTE>
39   *    com.flexstor.common.data.ActionData
40   * </BLOCKQUOTE>
41   * </P>
42   *
43   * <P>
44   * Output Data Object <BR>
45   * <BLOCKQUOTE>
46   *    com.flexstor.common.dataActionResult
47   * </BLOCKQUOTE>
48   * </P>
49   *
50   * <P>
51   * Programmable Properties (passed inside data object) <BR>
52   * <BLOCKQUOTE>
53   *   Specific Properties (apply to each individual asset) <BR>
54   * <BLOCKQUOTE>
55   * <P>
56   *       MacBinaryFormat: Indicates whether the file represented by this asset is in
57   *       MacBinary format or not (defaults to false). <BR>
58   *       Data type: Boolean <BR>
59   *       Legal values: true or false <BR>
60   * </P>
61   * <P>
62   *       RegenerateThumbnails: Indicates if the CheckInService needs to call the
63   *       ImportActionDataService to regenerate the thumbnail (defaults to false). <BR>
64   *       Data type: Boolean <BR>
65   *       Legal values: true or false <BR>
66   * </P>
67   * <P>
68   *       VersionNo: The version number of the asset to check in. <BR>
69   *       Data type: String <BR>
70   *       Legal values: any String <BR>
71   * </P>
72   * <P>
73   *       VersionNoPrevious: The version number of the asset, previous to being checked in. <BR>
74   *       Data type: String <BR>
75   *       Legal values: Any String <BR>
76   * </P>
77   * <P>
78   *       CheckInDateTime: The date and time this asset was checked in. <BR>
79   *       Data type: String <BR>
80   *       Legal values: String of the form MM-DD-YYYY hh24:mi:ss <BR>
81   * </P>
82   * <P>
83   *       SourceLocation: Full path, including name, of file to be checked in. <BR>
84   *       Data type: String <BR>
85   *       Legal values: Full path to the file, including name <BR>
86   * </P>
87   * <P>
88   *       KeepLowres: If set to true, it will preserve the old low resolution asset synchronized
89   *       with the old asset prior being to checked in (defaults to true). <BR>
90   *       Data type: Boolean <BR>
91   *       Legal values: true or false <BR>
92   * </P>
93   * </BLOCKQUOTE>
94   * </BLOCKQUOTE>
95   * </P>
96   */
97  public class CheckInService
98     implements Service, ThreadCallbackI
99  {
100    // To get the version number from MKS
101    public final static String IDENTIFIER="$Id: CheckInService.java,v 1.5 2003/08/11 02:22:49 aleric Exp $";
102    
103    protected ActionData   data            = null;
104    protected ActionResult result          = null;
105    protected Vector         vRecords        = new Vector();
106    protected Vector         vBadRecords     = new Vector();
107    protected int            nManagerRunning = 0;
108    protected String         sThisService    = "";
109    
110    private int id = -1;
111    
112    /**
113     * Calls before the service is initialized (before initData is called) to 
114     * pass information about the environment in which the service is running.
115     * This environment consists of information about the properties set for the
116     * service in one of these files (services.config, roletype_services.config,
117     * or *.ctl), plus methods to access other information such as an instance
118     * of the service broker to invoke other services, the transaction id for
119     * the service, file separator character and local path for the installation
120     * directory and configuration directory.
121     * 
122     * @param context Holds information about the environment in which the service
123     *                is running.
124     */
125    public void setServiceContext( ServiceContext context )
126    {
127       id = context.getTransactionId();
128    }
129    
130    /**
131    * A data initialization method called at the beginning of the service.
132    * The input argument, ActionData must be cast into its subclass in order
133    * to extract the CheckInService specific data from it.
134    */
135    public void initData(ActionData actionData)
136    {
137       this.data = actionData;
138       //6232=Check-In Service
139       sThisService = Resources.get(6232) + " (" + id + ")";
140    }
141 
142    /**
143    * The start of the CheckIn Service.
144    */
145    public ActionResult go()
146    {
147       // Create subsets of data objects per server and start a new ServiceManager
148       //for each.
149       Hashtable htSubSets = createSubSets();
150       
151       if ( htSubSets != null && htSubSets.size() > 0 )
152       {
153          // Create one thread per data object SubSet and start a Service Manager
154          // synchronized to make sure we start all the threads before getting any response back
155          // from observables.
156          synchronized (this)
157          {
158             for (Enumeration e = htSubSets.keys(); e.hasMoreElements(); )
159             {
160                String sServerName = (String) e.nextElement();
161                ActionData dataSubSet = (ActionData)htSubSets.get(sServerName);
162                (new CheckInServiceManager( sServerName, dataSubSet, this )).startManager();
163                nManagerRunning++;
164             }
165          }
166       }
167       else
168          vBadRecords = data.getRecords();
169 
170       // while there are services still running, just wait until be notified of an update;
171       // if all services are done, exit loop and exit Check-In Service
172       synchronized (this)
173       {
174          while ( nManagerRunning > 0 )
175          {
176             try
177             {
178                this.wait();
179             }
180             catch (InterruptedException ie)
181             {
182                vBadRecords = data.getRecords();
183             }
184          }
185       }
186       
187       boolean bResult = true;
188       if ( vBadRecords.size() > 0 )
189          bResult = false;
190          
191       // Remove this persisted transaction from TransList.per
192       (new TransMngCheckIn( data.getTransId() )).setTransactionCompletedState(bResult);
193       
194       if ( bResult )
195          result = new ActionResult( true );
196       else
197       {
198          result = new ActionResult( false );
199          result.setBadRecords( vBadRecords );
200          // Update the list of record with the good ones only, if any
201          data.setRecords( vRecords );
202       }
203 
204       result.setData( data );
205       result.setId( data.getTransId() );
206       return result;
207    }
208    
209    /**
210    * create a Hashtable containing a list of objects to be sent to the service manager.
211    * key = server name; value = ServiceManagerData
212    */
213    private Hashtable createSubSets()
214    {
215       // Retrieve the vector of AssetRecordData and parse thru it; for each server name found
216       // create a ActionData for each new server and add the respective elements to it.
217       
218       Hashtable htSubSets = new Hashtable();
219       ActionData dataSubSet;
220       AssetRecordData currRecord;
221       String sServerName;
222 
223       vRecords = data.getRecords();
224       if ( vRecords != null)
225       {
226          for ( int i = 0; i < vRecords.size(); i++ )
227          {
228             AssetRecordData dummy = (AssetRecordData)vRecords.elementAt(i);
229             currRecord = (AssetRecordData)dummy.clone();
230             sServerName = currRecord.getServer();
231 
232             if ( sServerName != null )
233             {
234                dataSubSet = (ActionData) htSubSets.get( sServerName );
235                if ( dataSubSet == null )
236                {
237                   dataSubSet = (ActionData) data.clone();
238                   dataSubSet.addRecord( currRecord );
239                   htSubSets.put( sServerName, dataSubSet );
240                }
241                else
242                   dataSubSet.addRecord( currRecord );
243             }
244          }
245       }
246       return htSubSets;
247    }
248    
249    /**
250    * update the ImportData after the set of services are executed for
251    * a ImportData sub set.
252    **/
253    private synchronized void notify( ActionResult result )
254    {
255       Vector vBadRecs = null;
256       if ( result == null )
257          vBadRecs = data.getRecords();
258       else if ( !result.isSuccess() )
259          vBadRecs = result.getBadRecords();
260 
261       if ( vBadRecs != null && vBadRecs.size() > 0 )
262       {
263          AssetRecordData record;
264          for (int i = 0; i < vBadRecs.size(); i++ )
265          {
266             // Set records to bad and remove the Vector of good records
267             record = (AssetRecordData)vBadRecs.elementAt(i);
268             vBadRecords.addElement( record );
269             vRecords.removeElement( record );
270          }
271       }
272 
273       nManagerRunning--;
274       this.notifyAll();
275    }
276 
277    /**
278     * Called when a thread task is about to begin.
279     * @param consumer the instance that this task will run against.
280     * @param obj      the user defined parameter for this task.
281     */
282    public void threadTaskStart ( ThreadConsumerI consumer, Object obj ) {}
283 
284    /**
285     * Called when a thread task has just finished.
286     * @param consumer the instance that this task will run against.
287     * @param obj      the user defined parameter for this task.
288     */
289    public void threadTaskEnd ( ThreadConsumerI consumer, Object obj )
290    {
291       notify( ((CheckInServiceManager)consumer).getResult() );
292    }
293 }