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

Quick Search    Search Deep

Source code: com/flexstor/flexdbserver/services/asset/ImportRsrcForkService.java


1   /*
2    * ImportRsrcForkService.java
3    *
4    * Copyright $Date: 2003/08/11 02:22:29 $ 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.asset;
12  
13  import java.util.Iterator;
14  import java.util.Vector;
15  
16  import com.flexstor.common.constants.ActionPropertiesI;
17  import com.flexstor.common.constants.AssetRolesI;
18  import com.flexstor.common.constants.RsrcForkConstantsI;
19  import com.flexstor.common.constants.ServicesI;
20  import com.flexstor.common.data.ActionData;
21  import com.flexstor.common.data.ActionResult;
22  import com.flexstor.common.data.AssetRecordData;
23  import com.flexstor.common.data.ejb.disguiserecord.AssetRoleData;
24  import com.flexstor.common.data.ejb.disguiserecord.DisguiseAssetRecordData;
25  import com.flexstor.common.data.ejb.disguiserecord.DisguiseRecordData;
26  import com.flexstor.common.errorlogger.FlexError;
27  import com.flexstor.common.importprocessor.ImportData;
28  import com.flexstor.common.importprocessor.ImportResult;
29  import com.flexstor.common.io.xfile.FlexXFile;
30  import com.flexstor.common.resources.Resources;
31  import com.flexstor.common.services.ServiceArgumentsI;
32  import com.flexstor.common.services.ServiceBrokerI;
33  import com.flexstor.common.services.SrvcNotAvailException;
34  import com.flexstor.common.util.Diagnostic;
35  import com.flexstor.common.util.FlexDbServerHost;
36  import com.flexstor.common.util.ServerList;
37  import com.flexstor.flexdbserver.services.Service;
38  import com.flexstor.flexdbserver.services.ServiceContext;
39  
40  
41  /**
42   * <P>
43   * ImportResourceForkService <BR>
44   * <BLOCKQUOTE>
45   *    Converts Macintosh files stored in either UNIX or NT file systems to MacBinary format and vice versa. This
46   *    service supports files stored using the following AppleTalk vendors and softwares: Helios, IPT, Xinet, and
47   *    DAVE. <BR>
48   *
49   *    The following rules will be applied for updating or creating new assets: <BR>
50   *       <BLOCKQUOTE>
51   *       If action = combine or action = separate:
52   *          <BLOCKQUOTE>
53   *          If Input Asset is equal to Output Asset:
54   *             <BLOCKQUOTE>
55   *             Input asset path will be replaced with path of output file.
56   *             </BLOCKQUOTE>
57   *          If Input Asset is not equal to Output Asset and Output Asset exists:
58   *             <BLOCKQUOTE>
59   *             Output asset path will be replaced with path of output file.
60   *             </BLOCKQUOTE>
61   *          If Input Asset is not equal to Output Assetand Output Asset does not exist:
62   *             <BLOCKQUOTE>
63   *             Creates a new asset which is added as child of the input asset and which path points to the the
64   *             output file path.
65   *             </BLOCKQUOTE>
66   *          </BLOCKQUOTE>
67   *       If action = copy:
68   *          <BLOCKQUOTE>
69   *          If Input Asset is equal to Output Asset:
70   *             <BLOCKQUOTE>
71   *             Paths are not replaced.
72   *             </BLOCKQUOTE>
73   *          If Input Asset is not equal to Output Asset and Output Asset exists:
74   *             <BLOCKQUOTE>
75   *             Output asset path will be replaced with path of output file.
76   *             </BLOCKQUOTE>
77   *          If Input Asset is not equal to Output Assetand Output Asset does not exist:
78   *             <BLOCKQUOTE>
79   *             Creates a new asset which is added as child of the input asset and which path points to the the
80   *             output file path.
81   *             </BLOCKQUOTE>
82   *          </BLOCKQUOTE>
83   *       If action = move:
84   *          <BLOCKQUOTE>
85   *          If Input Asset is equal to Output Asset:
86   *             <BLOCKQUOTE>
87   *             Input asset path will be replaced with path of output file.
88   *             </BLOCKQUOTE>
89   *          If Input Asset is not equal to Output Asset and Output Asset exists:
90   *             <BLOCKQUOTE>
91   *             Output asset path will be replaced with path of output file. <BR>
92   *             Input asset is deleted from ImportData object.
93   *             </BLOCKQUOTE>
94   *          If Input Asset is not equal to Output Assetand Output Asset does not exist:
95   *             <BLOCKQUOTE>
96   *             Input asset is deleted from ImportData object.
97   *             </BLOCKQUOTE>
98   *          </BLOCKQUOTE>
99   *       If action = delete:
100  *          <BLOCKQUOTE>
101  *          If Input Asset is equal to Output Asset:
102  *             <BLOCKQUOTE>
103  *             Input asset is deleted from ImportData object.
104  *             </BLOCKQUOTE>
105  *          If Input Asset is not equal to Output Asset and Output Asset exists:
106  *             <BLOCKQUOTE>
107  *             Input asset is deleted from ImportData object.
108  *             </BLOCKQUOTE>
109  *          If Input Asset is not equal to Output Assetand Output Asset does not exist:
110  *             <BLOCKQUOTE>
111  *             Input asset is deleted from ImportData object.
112  *             </BLOCKQUOTE>
113  *          </BLOCKQUOTE>
114  *       </BLOCKQUOTE>
115  * </BLOCKQUOTE>
116  * </P>
117  *
118  * Configurable Properties in roletype_services.config (or *.ctl file if run as a preservice) <BR>
119  *
120  * <TABLE BORDER="1" CELLPADDING="3" CELLSPACING="3">
121  * <CAPTION ALIGN=TOP>
122  *    <B> In/Out Properties for Assets </B>
123  * </CAPTION>
124  *     <TR>
125  *        <FONT SIZE=+1><B>
126  *        <TH WIDTH="120">Attribute</TH>
127  *                                   <TH WIDTH="30">IN</TH>           <TH WIDTH="30">OUT</TH>          <TH WIDTH="30">Default IN</TH>  <TH WIDTH="30">Default OUT</TH>
128  *        </B></FONT>
129  *     </TR>
130  *     <TR>
131  *        <TH ALIGN=LEFT><FONT SIZE=+1><B>ROLE</B></FONT></TH>
132  *                                   <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> ALL </TD>      <TD ALIGN=CENTER> ALL </TD>
133  *     </TR>
134  *     <TR><TH> Highres </TH>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
135  *     <TR><TH> Lowres </TH>         <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
136  *     <TR><TH> Thumbnail </TH>      <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
137  *     <TR><TH> Layout </TH>         <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
138  *     <TR><TH> Video </TH>          <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
139  *     <TR><TH> Audio </TH>          <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
140  *     <TR>
141  *        <TH ALIGN=LEFT><FONT SIZE=+1><B>TYPE</B></FONT></TH>
142  *                                   <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> ALL </TD>    <TD ALIGN=CENTER> ALL </TD></TR>
143  *     </TR>
144  *     <TR>
145  *        <TH ALIGN=LEFT><FONT SIZE=+1><B>FLAG</B></FONT></TH>
146  *     </TR>
147  *     <TR><TH> PARENT </TH>         <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD></TR>
148  *     <TR><TH> CHLDREN </TH>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
149  *     <TR><TH> ALL </TH>            <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
150  *     <TR><TH> TEMP_PARENT </TH>    <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
151  *     <TR><TH> TEMP_CHILDREN </TH>  <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
152  *     <TR><TH> TEMP_ALL </TH>       <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
153  * </TABLE>
154  *
155  * <P>
156  *   action: The action to be performed by this ImportResourceForkService. <BR>
157  *   Legal values: combine, copy, separate, or delete
158  * </P>
159  * <P>
160  *   destination: Path where output files will be located if action specified is combine,
161  *   copy, or separate. This property is not used if action is delete. <BR>
162  *   Legal values: Full path
163  * </P>
164  *
165  * <P>
166  * Input Data Object <BR>
167  * <BLOCKQUOTE>
168  *    com.flexstor.common.importprocessor.ImportData
169  * </BLOCKQUOTE>
170  * </P>
171  *
172  * <P>
173  * Output Data Object <BR>
174  * <BLOCKQUOTE>
175  *    com.flexstor.common.importprocessor.ImportResult
176  * </BLOCKQUOTE>
177  * </P>
178  */
179 public class ImportRsrcForkService
180    implements Service
181 {
182    // To get the version number from MKS
183    public final static String IDENTIFIER="$Id: ImportRsrcForkService.java,v 1.4 2003/08/11 02:22:29 aleric Exp $";
184 
185    // These constants are used in when processing the result
186    private final static int SAME_ASSET = 0;
187    private final static int DIFF_ASSET = 1;
188    private final static int NEW_ASSET  = 2;
189 
190    protected ServiceContext    context;
191    protected ServiceBrokerI    serviceBroker;
192    protected int                 id = -1;
193    protected String              fileSeparator;
194    private  ImportData         importData;
195    private  DisguiseRecordData disguiseRecord;
196    private  String               sThisService;
197    private  String sRoleIn, sRoleOut, sTypeIn, sTypeOut, sFlagIn, sFlagOut;
198    private  int                  nAppleTalkVendor = 0;
199    private  int                  nAction = RsrcForkConstantsI.NONE;
200 
201    /**
202     * Calls before the service is initialized (before initData is called) to 
203     * pass information about the environment in which the service is running.
204     * This environment consists of information about the properties set for the
205     * service in one of these files (services.config, roletype_services.config,
206     * or *.ctl), plus methods to access other information such as an instance
207     * of the service broker to invoke other services, the transaction id for
208     * the service, file separator character and local path for the installation
209     * directory and configuration directory.
210     * 
211     * @param context Holds information about the environment in which the service
212     *                is running.
213     */
214    public void setServiceContext( ServiceContext context )
215    {
216       this.context = context;
217       id = context.getTransactionId();
218       fileSeparator = context.getFileSeparator();
219    }
220    
221    public void initData(ActionData actionData)
222    {
223       importData = (ImportData) actionData;
224 
225       //6932=Import Resource Fork Service
226       sThisService = Resources.get(6932) + " (" + id + ")";
227    }
228 
229    public ActionResult go()
230    {
231       boolean bSuccess = false;
232 
233       // Get the action for this resource fork service
234       nAction = getActionId( (String) context.getProperty("action") );
235       if ( nAction == -1 )
236       {
237          //6295=No Action Specified for service.
238          importData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6295) );
239          ImportResult result = new ImportResult(false);
240          result.setImportData(importData);
241          return result;
242       }
243 
244       // Get Role, Type and Flag values from property list (AssetService)
245       sRoleIn  = context.getProperty(ServiceArgumentsI.ROLE_DATA_SOURCE);
246       sTypeIn  = context.getProperty(ServiceArgumentsI.TYPE_DATA_SOURCE);
247       sFlagIn  = context.getProperty(ServiceArgumentsI.FLAG_DATA_SOURCE);
248       sRoleOut = context.getProperty(ServiceArgumentsI.ROLE_DATA_DESTINATION);
249       sTypeOut = context.getProperty(ServiceArgumentsI.TYPE_DATA_DESTINATION);
250       sFlagOut = context.getProperty(ServiceArgumentsI.FLAG_DATA_DESTINATION);
251 
252       Vector vAssetsIn = null;
253       Vector vAssetsOut = null;
254       if ( importData != null && (disguiseRecord = importData.getDisguiseRecordRef()) != null )
255       {
256          vAssetsIn = disguiseRecord.getAssets( sRoleIn, sTypeIn, sFlagIn );
257          vAssetsOut = disguiseRecord.getAssets( sRoleOut, sTypeOut, sFlagOut );
258       }
259 
260       if ( vAssetsIn != null && vAssetsIn.size() > 0 )
261       {
262          try
263          {
264             ActionResult result = new ActionResult(true);
265 
266             // Lets find out whether we need to run the SetDestinationService or the destination paths
267             // were already set.
268             String sMode = (String) context.getProperty("mode");
269             if ( sMode == null || sMode.equals("") || !sMode.equalsIgnoreCase("DESTINATIONSET") )
270             {
271                importData.setServiceName(ServicesI.SETDESTINATION_SERVICE);
272                result = (ActionResult) serviceBroker.invokeImmediately(importData, context.getProperties());
273             }
274             
275             if ( result != null && result.isSuccess() )
276             {
277                importData = (ImportData) result.getData();
278                importData.setServiceName(ServicesI.ACTIONDATA_CREATE_SERVICE);
279                result = (ActionResult) serviceBroker.invokeImmediately(importData, context.getProperties());
280                if ( result != null && result.isSuccess() )
281                {
282                   ActionData actionData = (ActionData) result.getData();
283 
284                   // Set the destination location.
285                   // If the action is SEPARATE_FORKS and the record is not in MACBINARY_FORMAT, remove it from list,
286                   // we will assume they are already separated.
287                   //String sDestination = getProperty("destinationbase");
288                   // Add this test here to prevent existing installation to fail if destinationbase is not set
289                   //if ( sDestination == null || sDestination.equals("") )
290                   //   sDestination = getProperty("destination");
291                   Vector vRecords = actionData.getRecords();
292                   AssetRecordData record;
293                   Boolean bMacbinary;
294                   for ( Iterator i = vRecords.iterator(); i.hasNext(); )
295                   {
296                      record = (AssetRecordData) i.next();
297 
298                      //if ( sDestination != null )
299                      //   record.setString( ActionPropertiesI.DESTINATION_LOCATION, sDestination );
300 
301                      if ( nAction == RsrcForkConstantsI.SEPARATE_FORKS )
302                      {
303                         bMacbinary = record.getBoolean( ActionPropertiesI.MACBINARY_FORMAT );
304                         if ( bMacbinary == null || !bMacbinary.booleanValue() )
305                            i.remove();
306                         else
307                         {
308                            // Set the appletalk vendor to be the appletalk vendor of the server
309                            nAppleTalkVendor = ServerList.getAppleTalkVendor(FlexDbServerHost.getLocalHostName());
310                            record.setAppleTalkVendor( new Integer(nAppleTalkVendor) );
311                         }
312                      }
313                   }
314 
315                   if ( vRecords.size() > 0 )
316                   {
317                      // If the nAction is SEPARATE_FORKS or COMBINE_FORKS (in which case, the file name will change), we
318                      // will need to insert the new names into ASSETS_INPROCESS, to avoid importing those assets through
319                      // the hot directory
320                      if ( nAction == RsrcForkConstantsI.SEPARATE_FORKS || nAction == RsrcForkConstantsI.COMBINE_FORKS )
321                         updateAssetsInProcess( actionData, nAction );
322 
323                      // Now call the ResourceForkService
324                      actionData.setInteger( ActionPropertiesI.RESOURCEFORK_ACTION, new Integer(nAction) );
325                      actionData.setServiceName(ServicesI.RESOURCEFORK_SERVICE);
326                      result = (ActionResult) serviceBroker.invokeImmediately(actionData);
327                      // Process the result by updating the import data object; it will be
328                      // false only if all assets failed
329                      if ( processResult( result, vAssetsIn, vAssetsOut ) )
330                         bSuccess = true;
331                   }
332                   else // nothing to do, so succeed
333                      bSuccess = true;
334                }
335             }
336          }
337          catch ( SrvcNotAvailException rsnae ) {}
338       }
339       else
340       {
341          //6290=Could not find assets of the following role, type and flag: %%1 %%2 %%3
342          importData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6290, new String[] { sRoleIn, sTypeIn, sFlagIn } ) );
343          bSuccess = false;
344       }
345 
346       ImportResult result = new ImportResult(bSuccess);
347       result.setImportData(importData);
348       return result;
349    }
350 
351    private int getActionId( String sAction )
352    {
353       if ( sAction == null )
354          return -1;
355 
356       sAction = sAction.toUpperCase();
357       if ( sAction.equals("COMBINE") )
358          return RsrcForkConstantsI.COMBINE_FORKS;
359       else if ( sAction.equals("COPY") )
360          return RsrcForkConstantsI.COPY_FORKS;
361       else if ( sAction.equals("MOVE") )
362          return RsrcForkConstantsI.MOVE_FORKS;
363       else if ( sAction.equals("SEPARATE") )
364          return RsrcForkConstantsI.SEPARATE_FORKS;
365       else if ( sAction.equals("DELETE") )
366          return RsrcForkConstantsI.DELETE_FORKS;
367       else
368          return -1;
369    }
370 
371    private void updateAssetsInProcess( ActionData actionData, int nAction )
372    {
373       // Get the list of records
374       Vector vRecords = actionData.getRecords();
375       Vector vModRecords = new Vector();
376       AssetRecordData clone;
377       String sFileName;
378       int nDotBinIndex;
379       for ( int i = 0; i < vRecords.size(); i++ )
380       {
381          clone = (AssetRecordData)((AssetRecordData)vRecords.elementAt(i)).clone();
382          sFileName = clone.getFileName();
383          if ( nAction == RsrcForkConstantsI.SEPARATE_FORKS )
384          {
385             if ( (nDotBinIndex = sFileName.lastIndexOf( ".bin" )) != -1 )
386                clone.setFileName( sFileName.substring( 0, nDotBinIndex ) );
387          }
388          else if ( nAction == RsrcForkConstantsI.COMBINE_FORKS )
389             clone.setFileName( clone.getFileName() + ".bin" );
390 
391          vModRecords.addElement( clone );
392       }
393 
394       AssetsInProcessUpdate assetsInProcess = new AssetsInProcessUpdate();
395       //6932=Import Resource Fork Service
396       assetsInProcess.addToAssetsInProcess( vModRecords, id, Resources.get(6932) );
397    }
398 
399    private boolean processResult( ActionResult result, Vector vAssetsIn, Vector vAssetsOut )
400    {
401       if ( result == null )
402          return false;
403 
404       Vector vGoodRecords = result.getGoodRecords();
405       if ( vGoodRecords == null || vGoodRecords.size() == 0 )
406          return false;
407 
408       AssetRecordData record;
409       DisguiseAssetRecordData assetIn, assetOut;
410 
411       // Remove bad records from import data object
412       Vector vBadRecords = result.getBadRecords();
413       if ( vBadRecords != null && vBadRecords.size() > 0 )
414       {
415          for ( int i = 0; i < vBadRecords.size(); i++ )
416          {
417             record = (AssetRecordData) vBadRecords.elementAt(i);
418             assetIn = getInputAsset( record, vAssetsIn );
419             if ( assetIn != null )
420                disguiseRecord.deleteAsset(assetIn);
421          }
422       }
423 
424       int[] naAssetInOutRelation = new int[1];
425 
426       for ( int i = 0; i < vGoodRecords.size(); i++ )
427       {
428          record = (AssetRecordData) vGoodRecords.elementAt(i);
429          assetIn = getInputAsset( record, vAssetsIn );
430          switch (nAction)
431          {
432             case RsrcForkConstantsI.COMBINE_FORKS:
433                assetOut = getOutputAsset( assetIn, vAssetsIn, vAssetsOut, naAssetInOutRelation );
434                assetOut.addProperty( ActionPropertiesI.MACBINARY_FORMAT, new Boolean(true) );
435                switch( naAssetInOutRelation[0] )
436                {
437                   // If assetIn == assetOut we should clone assetIn and make it a TEMP CHILD of assetOut
438                   // to be later removed
439                   // NOTE: Must call setPath(...) after cloning assetIn; otherwise file name of assetOut
440                   // will be equal to file name of assetIn
441                   case SAME_ASSET:
442                      DisguiseAssetRecordData clone = (DisguiseAssetRecordData)assetIn.cloneAsset(false);
443                      clone.getAssetRole().setTempRole(true);
444                      assetOut.addChildAsset( clone );
445                      setPath( record, assetOut, assetIn );
446                      break;
447                   // If assetIn != assetOut we assume that assetOut will be a CHILD of assetIn
448                   case NEW_ASSET:
449                      setPath( record, assetOut, assetIn );
450                      assetIn.addChildAsset( assetOut );
451                      break;
452                   case DIFF_ASSET:
453                      setPath( record, assetOut, assetIn );
454                      break;
455                }
456                break;
457             case RsrcForkConstantsI.COPY_FORKS:
458                assetOut = getOutputAsset( assetIn, vAssetsIn, vAssetsOut, naAssetInOutRelation );
459                // If assetIn == assetOut, we don't need to set new paths; assume that we just needed
460                // a new copy of the asset somewhere else, without keeping track of it in the data object.
461                switch( naAssetInOutRelation[0] )
462                {
463                   // If assetIn != assetOut, just update the path for assetOut; assetOut will be a CHILD of assetIn
464                   // Update path if NEW_ASSET and if DIFF_ASSET
465                   case NEW_ASSET:
466                      assetIn.addChildAsset( assetOut );
467                   case DIFF_ASSET:
468                      setPath( record, assetOut, assetIn );
469                      break;
470                }
471                break;
472             case RsrcForkConstantsI.MOVE_FORKS:
473                assetOut = getOutputAsset( assetIn, vAssetsIn, vAssetsOut, naAssetInOutRelation );
474                setPath( record, assetOut, assetIn );
475                // If assetIn != assetOut and assetIn is not a parent, delete assetIn since assetOut will
476                // replace assetIn
477                switch( naAssetInOutRelation[0] )
478                {
479                   case DIFF_ASSET:
480                      if ( !assetIn.isPrimaryParent() )
481                         disguiseRecord.deleteAsset(assetIn);
482                      break;
483                   case NEW_ASSET:
484                      assetIn.addChildAsset( assetOut );
485                      break;
486                }
487                break;
488             case RsrcForkConstantsI.SEPARATE_FORKS:
489                assetOut = getOutputAsset( assetIn, vAssetsIn, vAssetsOut, naAssetInOutRelation );
490                assetOut.addProperty( ActionPropertiesI.MACBINARY_FORMAT, new Boolean(false) );
491                assetOut.setAppleTalkVendor( nAppleTalkVendor );
492                switch( naAssetInOutRelation[0] )
493                {
494                   // If assetIn == assetOut we should clone assetIn and make it a TEMP CHILD of assetOut
495                   // to be later removed
496                   // NOTE: Must call setPath(...) after cloning assetIn; otherwise file name of assetOut
497                   // will be equal to file name of assetIn
498                   case SAME_ASSET:
499                      DisguiseAssetRecordData clone = (DisguiseAssetRecordData)assetIn.cloneAsset(false);
500                      clone.getAssetRole().setTempRole(true);
501                      assetOut.addChildAsset( clone );
502                      setPath( record, assetOut, assetIn );
503                      break;
504                   // If assetIn != assetOut we assume that assetOut will be a CHILD of assetIn
505                   case NEW_ASSET:
506                      setPath( record, assetOut, assetIn );
507                      assetIn.addChildAsset( assetOut );
508                      break;
509                   case DIFF_ASSET:
510                      setPath( record, assetOut, assetIn );
511                      break;
512                }
513                break;
514             case RsrcForkConstantsI.DELETE_FORKS:
515                if ( !assetIn.isPrimaryParent() )
516                   disguiseRecord.deleteAsset(assetIn);
517                break;
518          }
519       }
520       return true;
521    }
522 
523    private DisguiseAssetRecordData getInputAsset( AssetRecordData record, Vector vAssetsIn )
524    {
525       DisguiseAssetRecordData asset;
526       if ( vAssetsIn == null )
527          return null;
528          
529       String sFileName = record.getFileName();
530       
531       // If the action was SEPARATE_FORKS, then the filename in the record does not contain
532       // the .bin extension; the resource fork service updated with the filename and removed it
533       if ( nAction == RsrcForkConstantsI.SEPARATE_FORKS )
534          sFileName += RsrcForkConstantsI.MACBINARY_EXT;
535          
536       for ( Iterator i = vAssetsIn.iterator(); i.hasNext(); )
537       {
538          asset = (DisguiseAssetRecordData) i.next();
539          if ( record.getServer().equals( asset.getServer() )
540             && record.getLocation().equals( asset.getLocation() )
541                && sFileName.equals( asset.getFileName() ) )
542          {
543             return asset;
544          }
545       }
546       return null;
547    }
548 
549    private DisguiseAssetRecordData getOutputAsset( DisguiseAssetRecordData assetIn, Vector vAssetsIn, Vector vAssetsOut, int[] naAssetInOutRelation )
550    {
551       DisguiseAssetRecordData assetOut;
552       int index = vAssetsIn.indexOf( assetIn );
553       try
554       {
555          assetOut = (DisguiseAssetRecordData)vAssetsOut.elementAt(index);
556          if ( assetOut.equals(assetIn) )
557             naAssetInOutRelation[0] = SAME_ASSET;
558          else
559             naAssetInOutRelation[0] = DIFF_ASSET;
560       }
561       catch ( NullPointerException npe )
562       {
563          Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Creating new assetOut" );
564          naAssetInOutRelation[0] = NEW_ASSET;
565          assetOut = new DisguiseAssetRecordData();
566 
567          String sType = sTypeOut;
568          if ( sType.equals(ServiceArgumentsI.DEFAULT_TYPE) )
569             sType = assetIn.getAssetFileType();
570 
571          if ( sType != null && !sType.equals(ServiceArgumentsI.DEFAULT_TYPE) )
572          {
573             // If role and type are default, use the ones in the assetIn, if these are also default,
574             // it means that this service is run as a pre-service and there is not need to set the role.
575             int nRoleOutId = assetIn.getAssetRoleId();
576             if ( sRoleOut.equals( ServiceArgumentsI.DEFAULT_ROLE ) == false )
577                nRoleOutId = getRoleId( sRoleOut );
578 
579             if ( nRoleOutId != 0 )
580             {
581                AssetRoleData role = AssetRoleData.getAssetRoleData(nRoleOutId);
582                role.setAssetFileType(sType);
583                if ( sFlagOut.equals("TEMP") )
584                   role.setTempRole(true);
585                assetOut.setAssetRole(role);
586             }
587          }
588       }
589       catch ( ArrayIndexOutOfBoundsException aioobe )
590       {
591          Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Creating new assetOut" );
592          naAssetInOutRelation[0] = NEW_ASSET;
593          assetOut = new DisguiseAssetRecordData();
594          assetIn.addChildAsset( assetOut );
595 
596          String sType = sTypeOut;
597          if ( sType.equals(ServiceArgumentsI.DEFAULT_TYPE) )
598             sType = assetIn.getAssetFileType();
599 
600          if ( sType != null && !sType.equals(ServiceArgumentsI.DEFAULT_TYPE) )
601          {
602             // If role and type are default, use the ones in the assetIn, if these are also default,
603             // it means that this service is run as a pre-service and there is not need to set the role.
604             int nRoleOutId = assetIn.getAssetRoleId();
605             if ( sRoleOut.equals( ServiceArgumentsI.DEFAULT_ROLE ) == false )
606                nRoleOutId = getRoleId( sRoleOut );
607                
608             if ( nRoleOutId != 0 )
609             {
610                AssetRoleData role = AssetRoleData.getAssetRoleData(nRoleOutId);
611                role.setAssetFileType(sType);
612                if ( sFlagOut.equals("TEMP") )
613                   role.setTempRole(true);
614                assetOut.setAssetRole(role);
615             }
616          }
617       }
618       return assetOut;
619    }
620 
621    private void setPath( AssetRecordData record, DisguiseAssetRecordData assetOut, DisguiseAssetRecordData assetIn )
622    {
623       assetOut.setServer( assetIn.getServer() );
624       assetOut.setFileName( record.getDestinationFileName() );
625       String sDestLoc = (new FlexXFile(record.getDestinationLocation())).getLocalPath();
626       if ( sDestLoc.startsWith(fileSeparator) )
627          sDestLoc = sDestLoc.substring(1);
628       if ( !sDestLoc.endsWith(fileSeparator) )
629          sDestLoc += fileSeparator;
630       assetOut.setLocation( sDestLoc );
631    }
632 
633    private int getRoleId( String sRole )
634    {
635       // Get the proper Role Id
636       if ( sRole.equalsIgnoreCase("LOWRES") )
637          return AssetRolesI.LOWRES;
638       else if ( sRole.equalsIgnoreCase("THUMBNAIL") )
639          return AssetRolesI.THUMBNAIL;
640       else if ( sRole.equalsIgnoreCase("LAYOUT") )
641          return AssetRolesI.LAYOUT;
642       else if ( sRole.equalsIgnoreCase("AUDIO") )
643          return AssetRolesI.AUDIO;
644       else if ( sRole.equalsIgnoreCase("VIDEO") )
645          return AssetRolesI.VIDEO;
646       else  if ( sRole.equalsIgnoreCase("ALL") )
647          return -1;
648       else
649          return AssetRolesI.HIGHRES; // HIGHRES is the default
650    }
651 }