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>   </TD> <TD ALIGN=CENTER>   </TD> <TD ALIGN=CENTER> ALL </TD> <TD ALIGN=CENTER>   </TD>
90 * </TR>
91 * <TR><TH> Highres </TH> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER>   </TD> <TD ALIGN=CENTER>   </TD></TR>
92 * <TR><TH> Lowres </TH> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER>   </TD> <TD ALIGN=CENTER>   </TD></TR>
93 * <TR><TH> Thumbnail </TH> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER>   </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>   </TD> <TD ALIGN=CENTER>   </TD></TR>
95 * <TR><TH> Video </TH> <TD ALIGN=CENTER>   </TD> <TD ALIGN=CENTER>   </TD> <TD ALIGN=CENTER>   </TD> <TD ALIGN=CENTER>   </TD></TR>
96 * <TR><TH> Audio </TH> <TD ALIGN=CENTER>   </TD> <TD ALIGN=CENTER>   </TD> <TD ALIGN=CENTER>   </TD> <TD ALIGN=CENTER>   </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>   </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>   </TD> <TD ALIGN=CENTER>   </TD></TR>
105 * <TR><TH> CHLDREN </TH> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER>   </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>   </TD> <TD ALIGN=CENTER>   </TD></TR>
107 * <TR><TH> TEMP_PARENT </TH> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER>   </TD> <TD ALIGN=CENTER>   </TD></TR>
108 * <TR><TH> TEMP_CHILDREN </TH> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER>   </TD> <TD ALIGN=CENTER>   </TD></TR>
109 * <TR><TH> TEMP_ALL </TH> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER> X </TD> <TD ALIGN=CENTER>   </TD> <TD ALIGN=CENTER>   </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