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

Quick Search    Search Deep

Source code: com/flexstor/remote/script/ScriptService.java


1   /*
2    * ScriptService.java
3    *
4    * Copyright $Date: 2003/08/11 02:22:36 $ 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.remote.script;
12  
13  import java.io.BufferedReader;
14  import java.io.DataOutputStream;
15  import java.io.File;
16  import java.io.FileInputStream;
17  import java.io.FileOutputStream;
18  import java.io.IOException;
19  import java.io.InputStream;
20  import java.io.InputStreamReader;
21  import java.rmi.RemoteException;
22  import java.text.DateFormat;
23  import java.util.Date;
24  import java.util.Enumeration;
25  import java.util.Hashtable;
26  import java.util.StringTokenizer;
27  import java.util.Vector;
28  
29  import com.flexstor.common.constants.ActionPropertiesI;
30  import com.flexstor.common.constants.AssetRolesI;
31  import com.flexstor.common.data.ActionData;
32  import com.flexstor.common.data.ActionResult;
33  import com.flexstor.common.data.ejb.disguiserecord.AssetRoleData;
34  import com.flexstor.common.data.ejb.disguiserecord.AudioRoleData;
35  import com.flexstor.common.data.ejb.disguiserecord.DisguiseAssetRecordData;
36  import com.flexstor.common.data.ejb.disguiserecord.DisguiseRecordData;
37  import com.flexstor.common.data.ejb.disguiserecord.ImageRoleData;
38  import com.flexstor.common.data.ejb.disguiserecord.LayoutRoleData;
39  import com.flexstor.common.data.ejb.disguiserecord.ThumbnailRoleData;
40  import com.flexstor.common.data.ejb.disguiserecord.VideoRoleData;
41  import com.flexstor.common.importprocessor.ImportCtlData;
42  import com.flexstor.common.importprocessor.ImportData;
43  import com.flexstor.common.importprocessor.ImportResult;
44  import com.flexstor.common.services.RMIServiceI;
45  import com.flexstor.common.services.ServiceArgumentsI;
46  import com.flexstor.common.services.remote.FlexRemoteService;
47  import com.flexstor.common.util.Diagnostic;
48  
49  /**
50   * <P>
51   * ScriptService <BR>
52   * <BLOCKQUOTE>
53   *     
54   * A remote Service which is used to obtain the data
55   * available in the ImportData structure.  The data is used 
56   * to create new Assets (Thumbnail, composite images etc..)
57   * and Asset Records in the database.  The data can be obtained
58   * one of two ways.
59   * <P>
60   * Input File: This input file is a text file containing the data
61   * from the ImportData structure.  This file can be read by a script
62   * or application which generates new Assets.  The script is then required
63   * to generate an output file that this Script Service will read to update
64   * the ImportData object before it is sent back for a database update.
65   *<P>
66   * AppleScript:  An Applescript Dictionary is generated for this ScriptService
67   * (by way of the ScriptableFrame class).  The data stored in the ImportData
68   * object can be obtained and manipulated through AppleScript calls.  No output
69   * file is needed when accessing the data through AppleScript
70   * 
71   *<P>
72   * </BLOCKQUOTE>
73   * </P>
74   *
75   * Configurable properties in roletype_services.config: <BR>
76   *
77   * <TABLE BORDER="1" CELLPADDING="3" CELLSPACING="3">
78   * <CAPTION ALIGN=TOP>
79   *    <B> In/Out Properties for Assets </B>
80   * </CAPTION>
81   *     <TR>
82   *        <FONT SIZE=+1><B>
83   *        <TH WIDTH="120">Attribute</TH>
84   *                                   <TH WIDTH="30">IN</TH>           <TH WIDTH="30">OUT</TH>          <TH WIDTH="30">Default IN</TH>  <TH WIDTH="30">Default OUT</TH>
85   *        </B></FONT>
86   *     </TR>
87   *     <TR>
88   *        <TH ALIGN=LEFT><FONT SIZE=+1><B>ROLE</B></FONT></TH>
89   *                                   <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> ALL </TD>      <TD ALIGN=CENTER> &nbsp </TD>
90   *     </TR>
91   *     <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>
92   *     <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>
93   *     <TR><TH> Thumbnail </TH>      <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> X </TD></TR>
94   *     <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>
95   *     <TR><TH> Video </TH>          <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
96   *     <TR><TH> Audio </TH>          <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
97   *     <TR>
98   *        <TH ALIGN=LEFT><FONT SIZE=+1><B>TYPE</B></FONT></TH>
99   *                                   <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> ALL </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
100  *     </TR>
101  *     <TR>
102  *        <TH ALIGN=LEFT><FONT SIZE=+1><B>FLAG</B></FONT></TH>
103  *     </TR>
104  *     <TR><TH> PARENT </TH>         <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
105  *     <TR><TH> CHLDREN </TH>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> X </TD>        <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> X </TD></TR>
106  *     <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>
107  *     <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>
108  *     <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>
109  *     <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>
110  * </TABLE>
111  * <P>
112  * <B>Configurable properties in services.config:</B> <BR>
113  * <BLOCKQUOTE>
114  *    objectname: The remote service class <BR>
115  *    Legal values: ScriptService
116  * </P>
117  *
118  * <P>
119  *    servername: This is the fully qualified server name or ip address.<BR>
120  *    Legal values: IE: 200.100.121.56, foo, foo.company.com <BR>
121  * </P>
122  * <P>
123  *    scriptname: The name of an application or script which ScriptService should launch<BR>
124  *    Legal values: any executable<BR>
125  * </P>
126  * <P>
127  *    accessmethod:  Defines the method used to update the ImportData object<BR>
128  *    Legal values: applescript, file <BR>
129  * </P>
130  * <P>
131  *    serverport: Defines the method used to obtain a reference to this service<BR>
132  *    Legal values: This must match the port specified for the Remote Asset Server (a command line argument) which will be used to run this service.  Default is 1099. <BR>
133  * </P>
134  * <P>
135  *    updatemethod:  Defines the method used to obtain a reference to this service<BR>
136  *    Legal values: rmi <BR>
137  * </P>
138  * <P>
139  *    max_instances: When set to 1, prevents ScriptService from running more than one instance of your script at time<BR>
140  *    Legal values: 1 is the recommended value for ScriptService<BR>
141  * </P>
142  * <P>
143  *    io_dir:  This argument allows the user to define a directory where all files associated with this service can be found.  The <scriptname>.in file is written here by ScriptService.  Your script should write the <scriptname>.out file here as well.   If this argument is not specified the directory where the RemoteAssetServer was executed from will be used.  <BR>
144  *    Legal values: This argument can be a relative path, or an absolute path. <BR>
145  * </P>
146  * <P>
147  *    command_line:  Command line arguments can be sent to the executable.  Arguments should be delimited by a caret.  The value specified in scriptname is always the first argument in the argument array passed to your executable.  <BR>
148  *    Example: 
149  *     scriptname=d:/remote_asset_server/services/myService.exe
150  *     command_line=/installpath /^-v
151  *     argv[0] = d:/remote_asset_server/services/myService.exe
152  *     argv[1] = /installpath/
153  *     argv[2] = -v<BR>
154  * </P>
155  * <P>
156  *    debug:   When set to true a debug log is generated in the current directory (or the directory defined in io_dir). <BR>
157  *    Legal values: true/false/0-9 <BR>
158  * </P>
159  *</BLOCKQUOTE>
160  * 
161  * <P>
162  * Input Data Object <BR>
163  * <BLOCKQUOTE>
164  *    com.flexstor.common.importprocessor.ImportData
165  * </BLOCKQUOTE>
166  * </P>
167  *
168  * <P>
169  * Output Data Object <BR>
170  * <BLOCKQUOTE>
171  *    com.flexstor.common.importprocessor.ImportResult
172  * </BLOCKQUOTE>
173  * </P>
174  *
175 * 
176 * This class needs to extend UnicastRemoteObject so it can be
177 * made available through RMI.  All methods in this class must throw RemoteException as a result.
178 *<P>
179 * RMIServiceI defines some methods that are required for interaction with Flexstor.db
180 * @see ScriptableFrame
181 */
182 public class ScriptService extends FlexRemoteService
183 implements RMIServiceI
184 {   
185     // To get the version number from MKS
186     public final static String IDENTIFIER="$Id: ScriptService.java,v 1.4 2003/08/11 02:22:36 aleric Exp $";
187 
188     ImportData impData = null;
189     String sOutputFilePath = null;
190     String sInputFilePath = null;
191     String sIOFileDirectory = null; // The directory where files going in and out can be found
192     String sRoleIn = null;
193     String sTypeIn = null;
194     String sFlagIn = null;
195     String secondarysRoleIn = null;
196     String secondarysTypeIn = null;
197     String secondarysFlagIn = null;
198     public String sRoleOut = null; // needed by ScriptableFrame also
199     public String sFlagOut = null; // needed by ScriptableFrame also
200     String sTypeOut = null;
201     String sErrorMsgs = null; // String to hold error message to be sent to FlexError from AssetServiceManager
202     Hashtable hAssetRecords = null;
203     String sUpdateMethod = null;
204     ScriptableFrame scriptableFrame = null;
205     String sScriptName = null;
206     boolean bUpdateDatabase = true;
207     String sVersion  = null;
208     int nDebug = 0;
209     Vector vUserKeys = null; // used to handle asset fields defined by user in disguise.
210     boolean bServiceSuccess = true;
211     String appServerFileSep= null;
212     
213     public ScriptService() throws RemoteException
214     {
215       StringTokenizer IDENTtokens = new StringTokenizer(IDENTIFIER);
216       IDENTtokens.nextToken(); // Id:
217       IDENTtokens.nextToken(); // Classname
218       sVersion = IDENTtokens.nextToken();
219       writeToConsole("\r\nNew ScriptService" + " version " + sVersion + "\r\n\r\n");
220     }
221 
222     /**
223     * run
224     * This method is called by Flexstor.db when it wants to start the service.
225     * @param theData  This is the ImportData structure
226     * @param properties These are properties which are defined in remote_server.config
227     * for the service being run.
228     * @return An ImportData object is returned after it has been updated either through
229     * AppleScript or by parsing an output file
230     *<P>
231     * The run method does the following:<BR>
232     * 1. Writes an input file for the script to read (if updatemethod = file)<BR>
233     * 2. Obtains the name of the script/application to be executed<BR>
234     * 3. When the script has completed if updatemethod = file it will read the output 
235     * file (generated by the script/application) and update the ImportData structure<BR>
236     * 4. Return the updated ImportData stucture to Flexstor.db where it is used to 
237     * update the Database.
238     * 
239     **/
240     public ActionResult run(ActionData theData, Hashtable properties) throws RemoteException
241     {
242         System.out.println("Running...");
243         // Reset Variables...
244          hAssetRecords = null;
245          bServiceSuccess = true;
246          sErrorMsgs = new String();
247          sOutputFilePath = null;
248          sInputFilePath = null;
249          sIOFileDirectory = null; // The directory where files going in and out can be found
250          sRoleIn = null;
251          sTypeIn = null;
252          sFlagIn = null;
253          secondarysRoleIn = null;
254          secondarysTypeIn = null;
255          secondarysFlagIn = null;
256          sRoleOut = null; // needed by ScriptableFrame also
257          sFlagOut = null; // needed by ScriptableFrame also
258          sTypeOut = null;
259          sUpdateMethod = null;
260          scriptableFrame = null;
261          sScriptName = null;
262          bUpdateDatabase = true;
263          nDebug = 0;
264          vUserKeys = null; // used to handle asset fields defined by user in disguise.
265          appServerFileSep= null;
266         
267         
268         // Check the Data object
269         if(theData == null)
270         {
271             logErrorMessage("The data object received is invalid");
272             throw new RemoteException("The data object received is invalid");
273         }
274         // Check the properties 
275         if(properties == null)
276         {
277             logErrorMessage("The data properties table recieved is invalid");
278             throw new RemoteException("The data properties table recieved is invalid");
279         }
280         
281         String sUpdateDatabase = (String)properties.get("updateDB");
282         if(sUpdateDatabase != null && sUpdateDatabase.equalsIgnoreCase("false"))
283         {
284             bUpdateDatabase = false;
285         }
286         sScriptName = (String)properties.get("arg1");
287         if(sScriptName == null || sScriptName.equals(""))
288         {// argument was changed from arg1 to scriptname
289             sScriptName = (String)properties.get("scriptname");
290         }
291         sIOFileDirectory = (String)properties.get("io_dir");
292         if(sIOFileDirectory == null)
293             sIOFileDirectory = "";
294         else if(!sIOFileDirectory.endsWith(File.separator))
295         {
296             sIOFileDirectory = sIOFileDirectory.concat(File.separator);
297         }
298         
299         String sDebug = (String)properties.get("debug");
300         if(sDebug != null)
301         { 
302             try{
303             nDebug = Integer.valueOf(sDebug).intValue();
304             }
305             catch(NumberFormatException e) 
306             {
307                if(sDebug.equalsIgnoreCase("true"))
308                   nDebug = 1;
309                else
310                   nDebug = 0;
311             }
312             File IODir = new File(sIOFileDirectory);
313             if(!IODir.canWrite())
314             {
315                System.out.println("Cannot write to " + sIOFileDirectory);
316                sIOFileDirectory = "";
317                IODir = new File(sIOFileDirectory);
318                System.out.println("Defaulting to " + IODir.getAbsolutePath());
319             }
320             if(nDebug > 0)
321                System.out.println("Debug ON - outputfile = " + IODir.getAbsolutePath() + " level=" + nDebug );
322             try
323             {
324                java.io.FileOutputStream fileout = new java.io.FileOutputStream(IODir.getAbsolutePath() + "ScriptService.log");
325                Diagnostic.addOutputDevice(fileout);
326             }
327             catch(java.io.IOException fnfe){logErrorMessage("Could not add outputfile for debug");}
328             Diagnostic.enableOutput(true);
329             Diagnostic.enableChecking(true);
330             Diagnostic.enableTimeStamp(true);
331             Diagnostic.setTraceLevel(nDebug);
332             Diagnostic.addTraceCategory(Diagnostic.CAT_SCRIPT_SVC);
333             
334             //Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Debugging version " + );
335         }
336         writeToConsole("\r\n*****************************************"
337                         + "\r\n  ScriptService " + sVersion + " running " + sScriptName 
338                         + "\r\n*****************************************");
339         impData  = (ImportData)theData;
340         int idx = sScriptName.lastIndexOf(File.separator);
341         String flatFileName = null;
342         if(idx == -1)
343             idx = sScriptName.indexOf("/");
344         if(idx != -1)
345         {
346             flatFileName = sScriptName.substring(idx + 1, sScriptName.length());
347         }
348         else
349             flatFileName = sScriptName;
350         
351         
352         sOutputFilePath = sIOFileDirectory + flatFileName + ".in"; // Output from here to a file
353         sInputFilePath = sIOFileDirectory + flatFileName + ".out"; // Input from a file to here
354         sUpdateMethod = ((String)properties.get("updatemethod"));
355         
356         //FlexXFile outfile = new FlexXFile(sInputFilePath);
357         File outfile = new File(sInputFilePath);
358         if(outfile.canRead())
359         {
360             outfile.delete();
361         }
362         
363       
364         // Assign globals
365         sRoleIn = (String)properties.get(ServiceArgumentsI.ROLE_DATA_SOURCE);//getProperty
366         sTypeIn = (String)properties.get(ServiceArgumentsI.TYPE_DATA_SOURCE);//getProperty
367         sFlagIn = (String)properties.get(ServiceArgumentsI.FLAG_DATA_SOURCE);//getProperty
368         sRoleOut =(String)properties.get(ServiceArgumentsI.ROLE_DATA_DESTINATION);//getProperty
369         sTypeOut =(String)properties.get(ServiceArgumentsI.TYPE_DATA_DESTINATION);//getProperty
370         sFlagOut = (String)properties.get(ServiceArgumentsI.FLAG_DATA_DESTINATION);//getProperty
371         secondarysRoleIn = (String)properties.get(ServiceArgumentsI.SECONDARY_ROLE_DATA_SOURCE);//getProperty
372         secondarysTypeIn = (String)properties.get(ServiceArgumentsI.SECONDARY_TYPE_DATA_SOURCE);//getProperty
373         secondarysFlagIn = (String)properties.get(ServiceArgumentsI.SECONDARY_FLAG_DATA_SOURCE);//getProperty
374         appServerFileSep = (String)properties.get(ServiceArgumentsI.FILE_SEPARATOR);
375         if(appServerFileSep == null)
376          appServerFileSep = File.separator;
377         // Build Hashtable structure with all the assets and thier data
378         buildAssetRecords(impData);  
379         writeToConsole("AssetRecords built");
380         if(sUpdateMethod != null && sUpdateMethod.equalsIgnoreCase("applescript"))
381         {   
382              Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Creating Applescript Frame for " + flatFileName);
383              scriptableFrame = new ScriptableFrame(hAssetRecords, this, flatFileName);
384         }
385         if(sUpdateMethod == null || sUpdateMethod.equalsIgnoreCase("file"))
386         {
387             writeToConsole( "Writing output file for " + sScriptName + "(" + sOutputFilePath + ")");
388             sUpdateMethod = "file";
389             writeInputFile(); 
390         }
391         
392         try
393         {
394             String commands = (String)properties.get("command_line");
395             String[] saCommand = null;
396             if(commands != null && commands != "")
397             {
398                StringTokenizer tokenizer = new StringTokenizer(commands,"^");
399                if(tokenizer != null)
400                {
401                   saCommand = new String[tokenizer.countTokens() +1];
402                   for(int y = 1; y < saCommand.length; y++)
403                   {
404                      saCommand[y] = tokenizer.nextToken();
405                   }
406                }               
407             }
408             else
409             {
410                saCommand = new String[1];
411             }
412             saCommand[0] = sScriptName;
413             
414             runProcess(saCommand);
415             writeToConsole("Updating ImportData");
416             if(!updateImportData())
417             {
418                bServiceSuccess = false;
419                writeToConsole("Update failed");
420             }
421             else
422                writeToConsole("Update successful " );
423         }
424         catch(InterruptedException e)
425         {
426             logErrorMessage(sScriptName + "Process was interrupted");
427             bServiceSuccess = false;
428         }
429         catch(IOException e)
430         {
431             logErrorMessage(sScriptName + " could not be executed " + e.getMessage());
432             bServiceSuccess = false;
433         }
434     
435         
436         writeToConsole(sScriptName + " Process Completed (" + bServiceSuccess + ")" );
437         Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, sScriptName + "Process Completed");
438         ImportResult result = new ImportResult(bServiceSuccess);
439             
440         if(impData == null)
441          Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "No Import Data to send back");
442         else
443         {
444          Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "ImpData transId " + impData.getTransID());
445         }
446         result.setImportData(impData);
447         if(sErrorMsgs != null && !sErrorMsgs.equals(""))
448         {
449          result.setString( ActionPropertiesI.MESSAGE_STRING, sErrorMsgs );
450          //Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Setting text to " + sErrorMsgs);
451         }
452         if(sUpdateMethod != null && sUpdateMethod.toLowerCase().equals("applescript"))
453         {
454             if(!scriptableFrame.isVisible())
455             {
456                Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Disposing " + sScriptName);
457                scriptableFrame.dispose();
458             }
459         }
460         if(nDebug > 9)
461         {
462             sOutputFilePath = sOutputFilePath + ".end";
463             sRoleIn = (String)properties.get("ALL");//getProperty
464             sTypeIn = (String)properties.get("ALL");//getProperty
465             sFlagIn = (String)properties.get("ALL");//getProperty
466             secondarysRoleIn = (String)properties.get("ALL");//getProperty
467             secondarysTypeIn = (String)properties.get("ALL");//getProperty
468             secondarysFlagIn = (String)properties.get("ALL");//getProperty
469             writeInputFile();
470         }
471         return result;
472     }
473     
474     public void setServiceResult(boolean bresult)
475     {
476       Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Setting result to " + bresult);
477       bServiceSuccess = bresult;  
478     }
479     
480     /** 
481     * Gets the [options] section of the .ctl file.
482     * This is used by AppleScript, when a text file is written this information appears first
483     * in the file.
484     * @return A string array with the contents of the [options] block from the .ctl file
485     * 
486     **/
487     public String[] getCtlOptions()
488     {
489         if(impData == null)
490             return null;
491         ImportCtlData ctlData = impData.getCtlDataRef();
492         if(ctlData == null)
493             return null;
494         return ctlData.getArraySectionData("options");    
495     }
496     
497     //private void runProcess(String argument) throws InterruptedException, IOException
498     private int runProcess(String[] arguments) throws InterruptedException, IOException
499     {
500         Process proc = null;
501         int exit = -1;
502         Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Getting runtime to exec " + sScriptName);
503         Runtime runtime = Runtime.getRuntime();
504         if(runtime != null)
505         {
506             System.out.println(sScriptName + " executing" );
507             Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, sScriptName + " executing");
508             boolean processEnded = false;
509             proc = runtime.exec(arguments);
510             Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Waiting for "+ sScriptName + " to finish." );
511             InputStream inStream = proc.getInputStream();
512             InputStream errStream = proc.getErrorStream();
513             
514             
515             if(inStream != null)
516             {
517                while(!processEnded) 
518                {
519                   // Wait for external process (script) to finish running.
520                   try 
521                   { 
522                      exit = proc.exitValue(); 
523                      processEnded = true; 
524                   } catch(IllegalThreadStateException e) {} // still running 
525                   
526                   int inAvail = inStream.available(); 
527                   if(inAvail > 0) 
528                   { 
529                      byte[] inbytes = new byte[inAvail]; 
530                      inStream.read(inbytes); 
531                      writeToConsole(new String(inbytes)); 
532                      System.out.flush(); 
533                   } 
534                   
535                   inAvail = errStream.available(); 
536                   if(inAvail > 0) 
537                   { 
538                      byte[] inbytes = new byte[inAvail]; 
539                      errStream.read(inbytes); 
540                      System.err.print(new String(inbytes)); 
541                      System.err.flush(); 
542                   } 
543                   try { 
544                   Thread.sleep(10); 
545                   } 
546                   catch(InterruptedException e) {} 
547                }
548             }
549             else
550             {
551                proc.waitFor();
552             }
553             System.out.println(sScriptName + " finished.");
554             Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, sScriptName + " finished.");           
555         }
556         else
557         {
558             logErrorMessage("Could not execute " + sScriptName + " Runtime could not be obtained.");
559         }
560         return exit;
561     }
562    
563    private int writeInputFile()
564    {
565       int nTotal = 0;
566       DataOutputStream outputstream = null;
567       
568       // Make the file to write to
569       File tmpFile = new File(sOutputFilePath);
570       
571       if(tmpFile != null)
572       {
573           // Create an outputStream to the file
574           try
575           {
576             outputstream = new DataOutputStream(new FileOutputStream(tmpFile));
577             Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, " writing options section");
578             nTotal += writeToOutputStream(outputstream, "[options]");
579             String[] saCtlData = getCtlOptions();
580             if(saCtlData != null)
581             {
582                 for (int i=0; i<saCtlData.length; i++)
583                 {
584                     if(!saCtlData[i].startsWith("#"))
585                         nTotal += writeToOutputStream(outputstream, saCtlData[i]);
586                 }  
587             }
588         
589             for (Enumeration enum = hAssetRecords.elements() ; enum.hasMoreElements() ;) 
590             {
591                 ScriptServiceRecord next = (ScriptServiceRecord)enum.nextElement();
592                 if(next != null)
593                 {
594                     Hashtable hData = next.getData();
595                     String sSectionHeader = next.getSectionHeader();
596                     Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, " writing data for " + sSectionHeader);
597                     nTotal += writeToOutputStream(outputstream, "[" + sSectionHeader + "]"); // Section Header
598                     nTotal += writeHashtableToOutputStream(hData, outputstream);
599                     // If any of the secondary properties have been set, information for
600                     // child assets will be written to the .in file
601                     if(secondarysRoleIn != null || secondarysTypeIn != null || secondarysFlagIn != null)
602                     {
603                        if(secondarysRoleIn == null)
604                           secondarysRoleIn = ServiceArgumentsI.DEFAULT_ROLE;
605                              
606                        if(secondarysTypeIn == null)
607                           secondarysTypeIn = ServiceArgumentsI.DEFAULT_TYPE;
608                              
609                        if(secondarysFlagIn ==  null)
610                           secondarysFlagIn = "ALL";
611                        
612                        Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, " getting child assets " + secondarysRoleIn + " " + secondarysTypeIn + " " + secondarysFlagIn + " from " + sSectionHeader);
613                        DisguiseAssetRecordData theRecord = next.getAsset();
614                        if(theRecord != null)
615                        {
616                           
617                           Vector childAssets = new Vector();
618                           theRecord.getChildren(childAssets, secondarysRoleIn, secondarysTypeIn, secondarysFlagIn);
619                           if(childAssets == null)
620                               Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, " null assets found " + sSectionHeader);
621                           else if(!childAssets.isEmpty())
622                           {
623                             Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, childAssets.size() + " assets found " + sSectionHeader);
624                             Hashtable childData = new Hashtable();
625                             Enumeration children = childAssets.elements();
626                             Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, " enumerating child assets " + sSectionHeader);
627                           
628                             while(children.hasMoreElements())
629                             {
630                               childData.clear();
631                               Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, " getting child data " + sSectionHeader);
632                           
633                               addAssetData((DisguiseAssetRecordData)children.nextElement(), childData);
634                               nTotal += writeToOutputStream(outputstream, "{");
635                               nTotal += writeHashtableToOutputStream(childData, outputstream);
636                               nTotal += writeToOutputStream(outputstream, "}");
637                             }
638                           }
639                           else
640                            Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, childAssets.size() + " assets found " + sSectionHeader);
641                        }
642                        else
643                        {
644                            Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "could not get parent record " + sSectionHeader);
645                        }
646                     }
647                 }
648             }
649 
650             try{
651             outputstream.close();
652             }catch(IOException e)
653             {}
654           }
655           catch(IOException e)
656           {
657             logErrorMessage("Could not write to " + sOutputFilePath);
658             return -1;
659           }
660       }
661       return nTotal;
662    }
663 
664    /**
665    * buildAssetRecords
666    * Populates the hAssetRecords Hashtable, which is used
667    * to write remoteScript.in and also to provide easy access
668    * to the Assets data by the ScriptableComponent class (AppleScript)
669    **/
670    private void buildAssetRecords(ImportData impData)
671    {
672         Vector assetRecords =  null;
673         //displayHash(hAssetRecords);
674         hAssetRecords = new Hashtable();
675         // Get a reference to the DisguiseRecordData so we can get the assets
676         DisguiseRecordData refDisguiseRecordData = impData.getDisguiseRecordRef();
677         Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC,"Role In= " + sRoleIn   );
678         Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Type In= " + sTypeIn  );
679         Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Flag In= " + sFlagIn  );
680         Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC,"Secondary Role In= " + secondarysRoleIn   );
681         Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Secondary Type In= " + secondarysTypeIn  );
682         Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Secondary Flag In= " + secondarysFlagIn  );
683         if(refDisguiseRecordData != null)
684         {
685             if(sRoleIn != null && sTypeIn != null && sFlagIn != null)
686             {
687                 // Get the assets 
688                 assetRecords = refDisguiseRecordData.getAssets(sRoleIn, sTypeIn, sFlagIn);//getPrimaryAssets();
689                 //System.out.println("Found " + assetRecords.size() + " assets for " + sScriptName);
690                 Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Found " + assetRecords.size() + " assets for " + sScriptName );
691                 
692                 Enumeration assets = assetRecords.elements();
693                 // Add Data to Hashtables
694                 Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Building information for " + sRoleIn + " fileType (" + sScriptName +")");
695 
696                 while( assets.hasMoreElements() )
697                 {
698                     
699                      Hashtable assetData = new Hashtable();
700                      DisguiseAssetRecordData asset = (DisguiseAssetRecordData)assets.nextElement();
701                      ScriptServiceRecord record = new ScriptServiceRecord(assetData, asset);
702                      
703                      String sSectionHeader = "";
704                      sSectionHeader += asset.getServer();
705                      sSectionHeader += ":/";
706                      sSectionHeader += asset.getLocation();
707                      sSectionHeader += asset.getFileName();
708                      record.setSectionHeader(sSectionHeader);
709                      
710                      hAssetRecords.put(sSectionHeader, record);
711                      Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Processing Asset " + sSectionHeader);
712                      addAssetData(asset, assetData);
713                 }
714             }
715         }
716    }
717    
718    private void addAssetData(DisguiseAssetRecordData asset, Hashtable assetData)
719    {
720         if(asset != null)
721         {
722             String sData = asset.getFileName();
723             // Get Role
724             AssetRoleData theRole = (AssetRoleData)asset.getAssetRole();
725             if(sData != null && theRole != null)
726             {
727                 // FileName
728                 assetData.put("filename", sData);
729              // Role Data
730                 // Role Name
731                 sData = AssetRolesI.roles[theRole.getAssetRoleId()];
732                 if(sData != null)
733                 {
734                     assetData.put("rolename", sData);// ImageType
735                 }
736                 // File Type
737                 sData = theRole.getAssetFileType();
738                 if(sData != null)
739                 {
740                     assetData.put("filetype", sData);
741                 }
742                 // RoleId
743                 int nRoleId = theRole.getAssetRoleId();
744                 sData = new Integer(nRoleId).toString();
745                 if(sData != null)
746                 {
747                     assetData.put("roleid", sData);
748                 }
749                 
750                 switch(nRoleId)
751                 {
752                     case AssetRolesI.HIGHRES:
753                     case AssetRolesI.LOWRES:
754                     case AssetRolesI.THUMBNAIL:
755                         addImageRoleData((ImageRoleData)theRole, assetData);
756                         break;
757                     case AssetRolesI.LAYOUT:
758                         addLayoutRoleData((LayoutRoleData)theRole, assetData);
759                         break;
760                     case AssetRolesI.AUDIO:
761                         addAudioRoleData((AudioRoleData)theRole, assetData);
762                         break;
763                     case AssetRolesI.VIDEO:
764                         addVideoRoleData((VideoRoleData)theRole, assetData);
765                         break;
766                     default:
767                         break;
768                 }
769                 //Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Adding Asset data ");
770                 // Asset Data
771                 
772                 // Record Id
773                 long recordid = asset.getRecordId(); 
774                 sData = new Long(recordid).toString();
775                 if(sData != null)
776                 {
777                   assetData.put("recordId", sData);
778                 }
779 
780                 // File Date
781                 Date dt = asset.getFileDate();
782                 if(dt != null)
783                 {
784                     sData = asset.getFileDate().toString();
785                     assetData.put("filedate", sData);
786                 }
787                 // File Size
788                 sData = new Long(asset.getFileSize()).toString();
789                 if(sData != null)
790                 {
791                     assetData.put("filesize", sData);
792                 }
793                 // Full Text Path
794                 sData = asset.getFullTextPath();
795                 if(sData != null)
796                 {
797                     assetData.put("fulltextpath", sData);
798                 }
799                 // Location
800                 sData = asset.getLocation();
801                 if(sData != null)
802                 {
803                     assetData.put("location", sData);
804                 }
805                 // Server
806                 sData = asset.getServer();
807                 if(sData != null)
808                 {
809                     assetData.put("server", sData);
810                 }
811                 // User Id
812                 sData = asset.getUserId();
813                 if(sData != null)
814                 {
815                     assetData.put("userid", sData);
816                 }
817 
818                 // User Data  
819                 Hashtable userData = asset.getUserData();
820                 
821                 if(userData != null && !userData.isEmpty())
822                 {
823                   //System.out.println("Looser Data found");
824                   Enumeration userKeys = userData.keys();
825                   while(userKeys.hasMoreElements())
826                   {
827                      Object aKey = userKeys.nextElement();
828                      //System.out.println("Looser Data next " + aKey);
829                      Object uData = userData.get(aKey);
830                      if(vUserKeys == null)
831                      {
832                         vUserKeys = new Vector();
833                      }
834                      //Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Adding user key " + aKey);
835                      vUserKeys.addElement(aKey);
836                      if(uData == null)
837                      {
838                         uData = "";                      
839                      }
840                      assetData.put(aKey, uData);
841                   }
842                 }
843                 //System.out.println("Looser Data done");
844             }
845             
846         }
847    }
848 
849    /**
850    * addImageRoleData
851    * Adds Role Data to the hashtable  which will be stored in hAssetRecords 
852    * (inside a ScriptServiceRecord object)
853    **/
854    private void addImageRoleData(ImageRoleData theRole, Hashtable assetData)
855    {
856         Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Adding Image Role Data");
857         if(theRole != null)
858         {
859            String sData = "";
860            // Color Depth
861            sData = new Float(theRole.getColorDepth()).toString();
862            if(sData != null)
863            {
864                 assetData.put("colordepth", sData);
865            }
866            // Color Space
867            sData = theRole.getColorSpace();
868            if(sData != null)
869            {
870                 assetData.put("colorspace", sData);
871            }
872      
873            // Height
874            sData = new Float(theRole.getHeight()).toString();
875            if(sData != null)
876            {
877                 assetData.put("height", sData);
878            }
879            // Width
880            sData = new Float(theRole.getWidth()).toString();
881            if(sData != null)
882            {
883                 assetData.put("width", sData);
884            }
885            // XRes
886            sData = new Float(theRole.getXRes()).toString();
887            if(sData != null)
888            {
889                 assetData.put("xres", sData);
890            }
891            // YRes
892            sData = new Float(theRole.getYRes()).toString();
893            if(sData != null)
894            {
895                 assetData.put("yres", sData);
896            }
897        }
898        else  
899         Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Image Role is null");
900    }
901    
902    private void addLayoutRoleData(LayoutRoleData theRole, Hashtable assetData)
903    {
904        Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Adding Layout Role Data");
905        if(theRole != null)
906        {
907             String sData = "";
908             // getNoOfPages
909             sData = new Integer(theRole.getNoOfPages()).toString();
910             if(sData != null)
911             {
912                 assetData.put("numberofpages", sData);
913             }
914             // getPageSize
915             sData = new Integer(theRole.getPageSize()).toString();
916             if(sData != null)
917             {
918                 assetData.put("pageSize", sData);
919             }
920             // isThumbAllPages
921             sData = theRole.isThumbAllPages() ? "true":"false";
922             if(sData != null)
923             {
924                 assetData.put("isallthumb", sData);
925             }
926        }
927        else  
928         Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Layout Role is null");
929    }
930    
931    private void addAudioRoleData(AudioRoleData theRole, Hashtable assetData)
932    {
933        if(theRole != null)
934        {
935             String sData = "";
936             // getAudioDuration
937             sData = new Integer(theRole.getAudioDuration()).toString();
938             if(sData != null)
939             {
940                 assetData.put("audioduration", sData);
941             }
942             // getComments
943             sData = theRole.getComments();
944             if(sData != null)
945             {
946                 assetData.put("comments", sData);
947             }
948             // getCompressionType
949             sData = theRole.getCompressionType();
950             if(sData != null)
951             {
952                 assetData.put("compressiontype", sData);
953             }
954             // getDescription
955             sData = theRole.getDescription();
956             if(sData != null)
957             {
958                 assetData.put("description", sData);
959             }
960             // getEnconding
961             sData = theRole.getEnconding();
962             if(sData != null)
963             {
964                 assetData.put("encoding", sData);
965             }
966             // getSampleSize
967             sData = new Integer(theRole.getSampleSize()).toString();
968             if(sData != null)
969             {
970                 assetData.put("samplesize", sData);
971             }
972             // getSamplingRate
973             sData = new Integer(theRole.getSamplingRate()).toString();
974             if(sData != null)
975             {
976                 assetData.put("samplingrate", sData);
977             }
978        }
979    }
980    
981    private void addVideoRoleData(VideoRoleData theRole, Hashtable assetData)
982    {
983        if(theRole != null)
984        {
985             String sData = "";
986             // getBitRate
987             sData = new Integer(theRole.getBitRate()).toString();
988             if(sData != null)
989             {
990                 assetData.put("bitrate", sData);
991             }
992             // getComments
993             sData = theRole.getComments();
994             if(sData != null)
995             {
996                 assetData.put("comments", sData);
997             }
998             // getDescription
999             sData = theRole.getDescription();
1000            if(sData != null)
1001            {
1002                assetData.put("description", sData);
1003            }
1004            // getFrameRate
1005            sData = theRole.getFrameRate();
1006            if(sData != null)
1007            {
1008                assetData.put("framerate", sData);
1009            }
1010            // getFrameResolution
1011            sData = theRole.getFrameResolution();
1012            if(sData != null)
1013            {
1014                assetData.put("fremeresolution", sData);
1015            }
1016            // getHeight
1017            sData = new Integer(theRole.getHeight()).toString();
1018            if(sData != null)
1019            {
1020                assetData.put("height", sData);
1021            }
1022            // getNumbOfFrames
1023            sData = new Integer(theRole.getNumbOfFrames()).toString();
1024            if(sData != null)
1025            {
1026                assetData.put("numberofframes", sData);
1027            }
1028            // getVideoDuration
1029            sData = new Integer(theRole.getVideoDuration()).toString();
1030            if(sData != null)
1031            {
1032                assetData.put("videoduration", sData);
1033            }
1034            // getWidth
1035            sData = new Integer(theRole.getWidth()).toString();
1036            if(sData != null)
1037            {
1038                assetData.put("width", sData);
1039            }
1040       }
1041   }
1042   
1043   private int writeHashtableToOutputStream(Hashtable hData, DataOutputStream outputstream)
1044   {
1045      int nWritten = 0;
1046      // Loop through Hashtable
1047      for (Enumeration enum2 = hData.keys() ; enum2.hasMoreElements() ;) 
1048      {
1049         
1050         String sKey = (String)enum2.nextElement();
1051         String sValue = null;
1052         if(sKey != null)
1053         {
1054               sValue = (String)hData.get(sKey);
1055               if(sValue != null)
1056               {
1057                     nWritten += writeToOutputStream(outputstream, sKey + "=" + sValue);
1058               }
1059         }
1060      }   
1061      return nWritten;
1062   }
1063   
1064   private int writeToOutputStream(DataOutputStream outputstream, String data)
1065   {
1066      //Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, 10, "Writing " + data);
1067      int nTotal = 0;
1068      
1069      if(data == null)
1070      {
1071         data = "Null value";
1072      }
1073      else
1074         nTotal += (data.length() + 1);
1075         
1076      try{
1077      outputstream.writeBytes(data);
1078      outputstream.writeByte(10);
1079      outputstream.flush();
1080      }
1081      catch(IOException e)
1082      {
1083         logErrorMessage("An error occurred while trying to write to " + sOutputFilePath);
1084         nTotal = -1;
1085      }
1086      return nTotal;
1087   }
1088   
1089   
1090   /**
1091   * Either reads the output file from the script, and parses the sections and 
1092   * updates the Asset Data
1093   * OR
1094   * calls updateComplete in ScriptableComp to make sure it has been called
1095   * which ensures that all data being updated through applescript gets to where
1096   * it needs to go.
1097   **/
1098   private boolean updateImportData()
1099   {
1100      Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC,"Role Out = " + sRoleOut  );
1101      Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Type Out= " + sTypeOut  );
1102      Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Flag Out= " + sFlagOut  );
1103      Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Update Method = " + sUpdateMethod  );
1104      if(sUpdateMethod != null && sUpdateMethod.equals("file"))
1105      {
1106            File inFile = new File(sInputFilePath);
1107            
1108            Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Updating ImportData " + sScriptName);
1109            
1110            try
1111            {
1112                //BufferedReader inStream = new BufferedReader(new InputStreamReader(new XFileInputStream(inFile)));
1113                BufferedReader inStream = new BufferedReader(new InputStreamReader(new FileInputStream(inFile)));
1114                  
1115                if(inFile != null)
1116                {
1117                    Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Reading output file " + sInputFilePath);
1118                    readOutputFile(inStream);
1119                    inStream.close();
1120                    return true;
1121                }
1122                else
1123                {
1124                  logErrorMessage("Could not read " + sInputFilePath);
1125                  return false;
1126                }
1127            }
1128            catch(IOException e)
1129            {
1130                logErrorMessage("IOException in Script Service " + sScriptName + "\n");
1131                logErrorMessage("Could not open a stream to " + sInputFilePath +"\n" + e.getMessage());
1132                return false;
1133            }  
1134      }
1135      else if(sUpdateMethod != null && sUpdateMethod.equals("applescript"))
1136      {   
1137             scriptableFrame.completeUpdate();
1138             scriptableFrame.dispose();
1139             return true;
1140      }
1141       
1142      writeToConsole("Update Method (" + sUpdateMethod + ") is unsupported, or does not require an update.");
1143      writeToConsole("No Update will be done.");
1144      return true;                     
1145   }// updateImportData
1146   
1147   private void readOutputFile(BufferedReader inStream)
1148   throws IOException
1149   {
1150      String sLineIn = null;
1151      boolean bSectionHasBegun = false;
1152      boolean bAssetHasBegun = false;
1153      boolean bErrorHasBegun = false;
1154      DisguiseAssetRecordData currentAsset = null;
1155      DisguiseAssetRecordData parentAsset = null;
1156      Vector vParentAssets = new Vector();
1157      Hashtable section = null;
1158      String sParentFileName = null;
1159      Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Reading output file");
1160      do
1161      {
1162            inStream.mark(256);
1163            sLineIn = inStream.readLine(); 
1164
1165            Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, 15, sLineIn);
1166            if(sLineIn != null)
1167            {
1168                sLineIn = sLineIn.trim();
1169                if(sLineIn.toLowerCase().startsWith("[error"))
1170                {
1171                   if(bAssetHasBegun) 
1172                   {   // If we have been reading an asset,
1173                       // we have now reached the end of the asset
1174                       // reset the buffer so the next line read will be the header again
1175                       // except next time it's read, we won't be in the middle of an asset
1176                       inStream.reset();
1177                       Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, 9, "Asset End");
1178                       processSection(section, currentAsset); // Add data from this section to ImportData
1179                        
1180                        bAssetHasBegun = false;
1181                        bSectionHasBegun = false;
1182                   }
1183                   else
1184                   {
1185                     Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, 9, "Error Section Begin");
1186                     section = new Hashtable();
1187                     bErrorHasBegun = true;
1188                   }
1189                }
1190                else if(sLineIn.startsWith("[") ) //Begin Asset
1191                {
1192                    if(bAssetHasBegun) 
1193                    {   // If we have been reading an asset,
1194                        // we have now reached the beginning of the next asset 
1195                        // NOTE: An asset may define seperate sections using {} (to indicate several child assets)
1196                        // or it may just list key value pairs without using the braces, in which case it's not a new asset
1197                        // merely changing the original's information
1198                    
1199                        // reset the buffer so the next line read will be the header again
1200                        // except next time bAssetHasBegun will be false, so a new asset will be created
1201                        inStream.reset(); 
1202                        Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, 9, "Asset End");
1203                        
1204                        //if(bProcessAtAssetEnd)
1205                        processSection(section, currentAsset); // Add data from this section to ImportData
1206                        
1207                        bAssetHasBegun = false;
1208                        bSectionHasBegun = false;
1209                        //bProcessAtAssetEnd = false;
1210                    }
1211                    else 
1212                    {
1213                        if(bErrorHasBegun)
1214                        {
1215                              processErrorSection(section);
1216                              bErrorHasBegun = false;
1217                        }
1218                        // New section begun
1219                        Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, 8, "Asset Begin");
1220                        bAssetHasBegun = true;
1221                        //bCreateNew = false; // create a new asset record when the next line is read (if it's not a '{')
1222                        // Get Record for original asset
1223                        sParentFileName = sLineIn.substring(1, sLineIn.length() - 1);
1224                        Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, 9, "Looking for " + sParentFileName);
1225                        ScriptServiceRecord record = (ScriptServiceRecord)hAssetRecords.get(sParentFileName);
1226                        if(record != null)
1227                            parentAsset = record.getAsset();
1228                        if(parentAsset != null)
1229                        {
1230                           // Add this original asset to a vector of 'parents', so if we encounter
1231                           // and embedded asset, we know where to put it.
1232                            Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, 9, "Found " + sParentFileName);
1233                            ScriptServiceRecord aHolder = new ScriptServiceRecord(new Hashtable(), parentAsset);
1234                            vParentAssets.removeAllElements();
1235                            vParentAssets.addElement(aHolder);//currentAsset);
1236                            // Set the current section as the originals section
1237                            // and the current asset as the original asset
1238                            // In case the file changes data for the original asset.
1239                            currentAsset = parentAsset;
1240                            section = record.getData();
1241                            Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, 9, "Current asset set to original- " + currentAsset.getRecordId());
1242                            bSectionHasBegun = true;
1243                        }
1244                        else
1245                        {
1246                            Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, "Could not find parent for " + sParentFileName + ".  It will not be added");
1247                        }
1248                        
1249                    }
1250                }
1251                else if(sLineIn.startsWith("{") )
1252                {
1253                    //bCreateNew = false; // a new section is starting, so don't create new asset records when then next line is read
1254                    // If we are currently reading a section,
1255                    // we have now just found an imbedded asset (a child asset)
1256                    if(bSectionHasBegun)
1257                    {
1258                        Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, 9, "Embedded section found, creating new child asset");
1259                        // Save the current hashtable and asset in a vector
1260                        ScriptServiceRecord holder = new ScriptServiceRecord(section, currentAsset);
1261                        //Diagnostic.trace(Diagnostic.CAT_SCRIPT_SVC, 9, "Storing object");
1262                        parentAsset = currentAsset;
1263