Source code: com/flexstor/flexdbserver/services/asset/OPIMatchService.java
1 /*
2 * OPIMatchService.java
3 *
4 * Copyright $Date: 2003/08/11 02:22:29 $ FLEXSTOR.net Inc.
5 *
6 * This work is licensed for use and distribution under license terms found at
7 * http://www.flexstor.org/license.html
8 *
9 */
10
11 package com.flexstor.flexdbserver.services.asset;
12
13 import java.util.Date;
14 import java.util.Enumeration;
15 import java.util.Hashtable;
16 import java.util.Vector;
17
18 import com.flexstor.common.constants.AssetRolesI;
19 import com.flexstor.common.constants.RsrcForkConstantsI;
20 import com.flexstor.common.data.ActionData;
21 import com.flexstor.common.data.ActionResult;
22 import com.flexstor.common.data.ejb.disguiserecord.AssetRoleData;
23 import com.flexstor.common.data.ejb.disguiserecord.DisguiseAssetRecordData;
24 import com.flexstor.common.data.ejb.disguiserecord.DisguiseRecordData;
25 import com.flexstor.common.data.ejb.disguiserecord.LowresRoleData;
26 import com.flexstor.common.errorlogger.FlexError;
27 import com.flexstor.common.importprocessor.ImportCtlData;
28 import com.flexstor.common.importprocessor.ImportData;
29 import com.flexstor.common.importprocessor.ImportResult;
30 import com.flexstor.common.io.xfile.FlexXFile;
31 import com.flexstor.common.resources.Resources;
32 import com.flexstor.common.settings.Settings;
33 import com.flexstor.common.util.Checksum;
34 import com.flexstor.common.util.Diagnostic;
35 import com.flexstor.ejb.bucket.persist.ServerBucketExtendData;
36 import com.flexstor.ejb.disguise.persist.ServerDisguiseExtendData;
37 import com.flexstor.flexdbserver.disguise.DisguiseLoader;
38 import com.flexstor.flexdbserver.disguise.DisguiseLoaderException;
39 import com.flexstor.flexdbserver.services.Service;
40 import com.flexstor.flexdbserver.services.ServiceContext;
41 import com.flexstor.flexdbserver.services.lowres.LowresPath;
42 import com.flexstor.flexdbserver.util.DisguiseAssetRecordPopulator;
43 import com.flexstor.flexdbserver.util.PathBuilder;
44
45 /**
46 * <P>
47 * OPIMatchService <BR>
48 * <BLOCKQUOTE>
49 * Finds the low resolution file associated with each primary input asset according to the
50 * specifications in the input control (*.ctl) file. Creates a child asset for each low resolution file found.
51 * </BLOCKQUOTE>
52 * </P>
53 *
54 * <P>
55 * Input Data Object <BR>
56 * <BLOCKQUOTE>
57 * com.flexstor.common.importprocessor.ImportData
58 * </BLOCKQUOTE>
59 * </P>
60 *
61 * <P>
62 * Output Data Object <BR>
63 * <BLOCKQUOTE>
64 * com.flexstor.common.importprocessor.ImportData
65 * </BLOCKQUOTE>
66 * </P>
67 *
68 * <P>
69 * Programmable Properties (passed inside data object) <BR>
70 * <BLOCKQUOTE>
71 * Global Properties (apply to all assets) <BR>
72 * <BLOCKQUOTE>
73 * <P>
74 * LOWRESDIRECTORY: From input control (*.ctl) file, the optional subdirectory containing
75 * the match files. <BR>
76 * Data type: String <BR>
77 * Legal values: Relative path <BR>
78 * </P>
79 * <P>
80 * LOWRESEXTENSION: From input control (*.ctl) file, the optional extension to match. <BR>
81 * Data type: String <BR>
82 * Legal values: Any legal extension <BR>
83 * </P>
84 * <P>
85 * LOWFILELISTBASE: From input control (*.ctl) file, indicates exclusion.<BR>
86 * Data type: String <BR>
87 * Legal values: Any legal directory name<BR>
88 * </P>
89 * <P>
90 * HIGHFILELISTBASE: From input control (*.ctl) file, the base subdirectory for searching for match.<BR>
91 * Data type: String <BR>
92 * Legal values: Any legal directory name<BR>
93 * </P>
94 * <P>
95 * MATCHBASE: From input control (*.ctl) file, the base subdirectory for the output low resolution asset.<BR>
96 * Data type: String <BR>
97 * Legal values: Any legal directory name<BR>
98 * </P>
99 * </BLOCKQUOTE>
100 * </BLOCKQUOTE>
101 * </P>
102 */
103 public class OPIMatchService
104 implements Service
105 {
106 public final static String IDENTIFIER = "$id";
107
108 protected ImportData refImportData = null;
109 protected ImportCtlData refCtlData = null;
110 protected ServerDisguiseExtendData refExtendDataDisguise = null;
111 protected OPITypesDat refOpiTypesDat = null;
112 protected String sDirSeparator = "";
113 protected String sUserId = "";
114 protected String sServer = null;
115 protected String sMatchType = null;
116 protected String sThisService = null;
117 protected Vector vDisguiseBuckets = null;
118
119 /************************ DEBUG MODE SWITCH *********************/
120 /** When true, this bypasses any Server Extend Disguise access **/
121 protected boolean bDebugMode = false;
122 /****************************************************************/
123
124 protected ServiceContext context;
125 protected int id = -1;
126 protected String fileSeparator;
127 protected String sInstallPath;
128 protected String sConfigPath;
129
130 /**
131 * Calls before the service is initialized (before initData is called) to
132 * pass information about the environment in which the service is running.
133 * This environment consists of information about the properties set for the
134 * service in one of these files (services.config, roletype_services.config,
135 * or *.ctl), plus methods to access other information such as an instance
136 * of the service broker to invoke other services, the transaction id for
137 * the service, file separator character and local path for the installation
138 * directory and configuration directory.
139 *
140 * @param context Holds information about the environment in which the service
141 * is running.
142 */
143 public void setServiceContext( ServiceContext context )
144 {
145 this.context = context;
146 id = context.getTransactionId();
147 fileSeparator = context.getFileSeparator();
148 sInstallPath = context.getInstallPath();
149 sConfigPath = context.getConfigPath();
150 }
151
152 /**
153 *
154 *
155 */
156 public void initData(ActionData actionData)
157 {
158 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Match Service: " + "Initializing...");
159
160 // Set the global reference
161 refImportData = (ImportData)actionData;
162
163 // Get the ctl data object
164 refCtlData = refImportData.getCtlDataRef();
165 sUserId = refCtlData.getValuePerKey("USERID");
166
167 // Get the Extended Disguise structure used for Asset creation
168 setupServerExtendDisguise();
169
170 sDirSeparator = System.getProperty("file.separator");
171
172 if (bDebugMode == true)
173 {
174 System.out.println("MATCH TEST MODE - EXTENDED DISGUISE IS BYPASSED");
175 }
176
177 sServer = Settings.getString( Settings.APP_SERVER_HOST );
178
179 //6794=OPI Match Service
180 sThisService = Resources.get(6794) + " (" + id + ")";
181
182 } // initData
183
184
185 /**
186 *
187 *
188 */
189 public ActionResult go()
190 {
191 // Process all files in the ImportData object
192 System.out.println("OPI match starting...");
193 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "OPI match starting...");
194
195 boolean bResult = true;
196
197 // First thing to do is check in roletype_services.config for the MATCH_TYPE property,
198 // if it has not been set we abort this service and subsequent services.
199 sMatchType = context.getProperty( "MatchType" );
200 if ( sMatchType == null || sMatchType.equals("") )
201 {
202 //6793=File type for match file not specified in roletype_services.config.
203 refImportData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6793) );
204 bResult = false;
205 }
206 else
207 {
208 if (refImportData == null)
209 {
210 bResult = false;
211 }
212
213 else
214 {
215 DisguiseRecordData refRecordData = refImportData.getDisguiseRecordRef();
216 Vector assetRecords = null;
217 if(refRecordData != null )
218 {
219 //Get all Primary Assets
220 assetRecords = refRecordData.getPrimaryAssets();
221 if(assetRecords != null)
222 {
223 Enumeration assets = assetRecords.elements();
224
225 // Processs each asset in each element in ImportData as required
226 while(assets.hasMoreElements())
227 {
228 DisguiseAssetRecordData anAsset = (DisguiseAssetRecordData)assets.nextElement();
229 if(anAsset != null)
230 {
231 // Find the match for this assets file
232 bResult = MatchFrimaryAsset(anAsset, refRecordData);
233 }// Asset not null
234
235 }// while
236
237 }// assetrecord not null
238
239 else
240 {
241 //Resources.get( 5526, String.valueOf(id) )
242 refImportData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, "No Assets to match") );
243 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Match Service: " + "No Assets to match");
244 }
245
246 }// refDisguiseRecord not null
247 } // refImportData else
248 }
249 // Set the result for the client
250 // Create the return object, serialization handled by superclass
251 ImportResult refResult = new ImportResult(bResult);
252 refResult.setImportData(refImportData);
253 if (!bResult)
254 {
255 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Match Service: " + "match error");
256 refImportData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, "Match error") );
257 }
258
259 return refResult;
260 } // go
261
262
263 /**
264 *
265 *
266 */
267 protected boolean MatchFrimaryAsset(DisguiseAssetRecordData anAsset,
268 DisguiseRecordData refRecordData)
269 {
270 // Get the primary type for this parent asset
271 AssetRoleData roleData = anAsset.getAssetRole();
272 if (roleData == null)
273 {
274 return true;
275 }
276
277 String sPrimaryType = roleData.getAssetFileType();
278
279 // Determine the OPI vendor type
280 int nAppleTalkVendor = anAsset.getAppleTalkVendor();
281 if (nAppleTalkVendor == RsrcForkConstantsI.XINET)
282 {
283 // FOR NOW, just do a normal match
284 findMatch(anAsset);
285 }
286
287 else // Not XINET
288 {
289 // Try to find the normal match for this asset's file
290 if (findMatch(anAsset) == false)
291 {
292 // Normal match not found
293 // Is the parent a supported OPI type?
294 if (((nAppleTalkVendor == RsrcForkConstantsI.IPT) && (isSupportedType("IPT", sPrimaryType) == true)) ||
295 ((nAppleTalkVendor == RsrcForkConstantsI.HELIOS) && (isSupportedType("HELIOS", sPrimaryType) == true)))
296 {
297 // Type is supported in opi_types.dat but the lowres was not found so
298 // remove parent asset from ImportData to be picked up on the next
299 // hotdir scan when maybe the lowres will be available.
300 refRecordData.deleteAsset( anAsset );
301
302 // Write error message, to be emailed later
303 refImportData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER,
304 "Match not found, Primary asset will be removed for this import session: "
305 + anAsset.getServer() + sDirSeparator
306 + anAsset.getLocation() + sDirSeparator
307 + anAsset.getFileName()) );
308 }
309 } // findMatch if
310 } // getAppleTalkVendor() else
311
312 return true; // bResult
313 } // MatchPrimaryAsset
314
315
316
317 /**
318 *
319 *
320 */
321 protected boolean isSupportedType(String sOpiType, String sPrimaryType)
322 {
323 if (refOpiTypesDat == null)
324 {
325 // Create an OPITypesDat instance which will read the contents of the opi_types.dat file
326 // into a self-contained vector
327 // First get the filename
328 String sOpiTypesDatFile = sConfigPath;
329 if (sOpiTypesDatFile.endsWith(sDirSeparator) == false)
330 {
331 sOpiTypesDatFile += sDirSeparator;
332 }
333
334 sOpiTypesDatFile += "opi_types.dat";
335
336 // Create the instance
337 refOpiTypesDat = new OPITypesDat(sOpiTypesDatFile);
338 } // refOpiTypesDat if
339
340 // Check the instance vector for the specified type
341 return refOpiTypesDat.isTypeSupported(sOpiType, sPrimaryType);
342 } // isSupportedType
343
344
345 /**
346 *
347 *
348 */
349 protected boolean findMatch(DisguiseAssetRecordData refPrimaryAsset)
350 {
351 // Get the asset's filename and path
352 String sLocation = refPrimaryAsset.getLocation();
353 String sFileName = refPrimaryAsset.getFileName();
354
355 if(sLocation != null && sFileName != null)
356 {
357 String sMatchLocation = "";
358 String sMatchFileName = "";
359 String sOutputPath = "";
360 long nMatchFileSize = 0;
361
362 Hashtable htProperties = new Hashtable();
363 // Get some user options from the CTL data
364 htProperties.put( "LOWRESDIRECTORY", refCtlData.getValuePerKey("LOWRESDIRECTORY") );
365 htProperties.put( "LOWRESEXTENSION", refCtlData.getValuePerKey("LOWRESEXTENSION") );
366 htProperties.put( "MATCHBASE", refCtlData.getValuePerKey("MATCHBASE") );
367 htProperties.put( "LOWFILELISTBASE", refCtlData.getValuePerKey("LOWFILELISTBASE") );
368 htProperties.put( "HIGHFILELISTBASE", refCtlData.getValuePerKey("HIGHFILELISTBASE") );
369
370 // Get properties for assets
371 htProperties.put( "LOCATION", sLocation );
372 htProperties.put( "FILENAME", sFileName );
373
374 String[] saResult = LowresPath.retrieveLowresPath( htProperties );
375
376 String sResult = saResult[0];
377 if ( sResult.equals("path") )
378 sOutputPath = saResult[1];
379 else
380 {
381 if ( sResult.equals("error") )
382 refImportData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, saResult[1]) );
383 else
384 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, saResult[1]);
385
386 return true;
387 }
388
389 // Does the file exist?
390 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Match path: " + sOutputPath);
391 if (sOutputPath.equals("") == false)
392 {
393 sOutputPath = PathBuilder.constructPath( sServer, sOutputPath, false );
394 FlexXFile fMatchFile = new FlexXFile(sOutputPath);
395 if ((fMatchFile != null) && (fMatchFile.exists() == true))
396 {
397 // Get the checksum
398 Checksum refChecksum = new Checksum();
399 long lChecksum = refChecksum.getChecksum(sOutputPath);
400
401 // Get the filesize
402 nMatchFileSize = fMatchFile.length();
403
404 // Set the location path and the filename from the full match path
405 sMatchLocation = fMatchFile.getLocalParent();
406 if ( sMatchLocation.endsWith(sDirSeparator) == false )
407 sMatchLocation += fileSeparator;
408
409 // Remove leading slash if it exists
410 if (sMatchLocation.startsWith(sDirSeparator) == true)
411 {
412 sMatchLocation = sMatchLocation.substring(1);
413 }
414
415 sMatchFileName = fMatchFile.getName();
416
417 // Match was found, so create a child asset for the match file
418 createMatchAsset(refPrimaryAsset,
419 sMatchLocation,
420 sMatchFileName,
421 nMatchFileSize,
422 lChecksum);
423
424 } // fMatchFile if
425
426 else
427 {
428 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Match file not found");
429 }
430 } // sOutputPath if
431
432 else
433 {
434 refImportData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, "Match path is null") );
435 }
436 } // sLocation if
437
438 else
439 {
440 refImportData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, "Primary path or file name is null") );
441 }
442
443 return true;
444 } // findMatch
445
446
447 /**
448 *
449 *
450 */
451 protected boolean createMatchAsset(DisguiseAssetRecordData refPrimaryAsset,
452 String sMatchLocation,
453 String sMatchFileName,
454 long nMatchSize,
455 long nChecksum)
456 {
457 boolean bNewChild;
458 // Check if a Lowres asset was already defined for this primary asset
459 DisguiseAssetRecordData refMatchAsset = refPrimaryAsset.getChildAsset(AssetRolesI.LOWRES);
460 if ( refMatchAsset != null )
461 {
462 bNewChild = false;
463 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Updating the match child asset");
464 }
465 else
466 {
467 // Create the child match asset
468 refMatchAsset = new DisguiseAssetRecordData();
469 bNewChild = true;
470 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Creating the match child asset");
471 }
472
473 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Match location : " + sMatchLocation);
474 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Match file name: " + sMatchFileName);
475
476
477 // Set asset Field Record Data
478 try
479 {
480 DisguiseAssetRecordPopulator assetPopulator = new DisguiseAssetRecordPopulator(refExtendDataDisguise.getId());
481 assetPopulator.setAttributes( refMatchAsset,
482 refPrimaryAsset.getServer(),
483 sMatchLocation,
484 sMatchFileName,
485 sUserId,
486 new Date(),
487 new Date(),
488 nChecksum,
489 nMatchSize,
490 AssetRolesI.LOWRES,
491 refPrimaryAsset.getAppleTalkVendor() );
492 }
493 catch ( DisguiseLoaderException dle )
494 {
495 refImportData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, "Could not set extended asset disguise data") );
496 return false;
497 }
498
499 // Set ASSET ROLE
500 //AssetRoleData refAssetRole = refMatchAsset.getAssetRole();
501 AssetRoleData refAssetRole = new LowresRoleData();
502 refAssetRole.setAssetFileType( sMatchType );
503 refMatchAsset.setAssetRole( refAssetRole );
504 refMatchAsset.setAssetRoleId(AssetRolesI.LOWRES);
505
506 // Add the child to the parent
507 if ( bNewChild )
508 refPrimaryAsset.addChildAsset(refMatchAsset);
509
510 return true;
511 } // createMatchAsset
512
513
514 /**
515 * Use this for test purposes only, when OAS is not used
516 *
517 */
518 public void setInstallPath(String sInstPath)
519 {
520 sInstallPath = sInstPath;
521 }
522
523
524 /**
525 *
526 *
527 */
528 protected void setupServerExtendDisguise()
529 {
530 String sDisguise = refCtlData.getValuePerKey("APPLICATION NAME");
531 getDisguise(sDisguise);
532 } // setupServerExtendDisguise
533
534 /**
535 *
536 *
537 */
538 public boolean getDisguise(String sDisguise)
539 {
540 if (bDebugMode == true)
541 {
542 return true;
543 }
544
545 // **** For debug only, comment out for real ****
546 /* if (bTest == true)
547 {
548 sDisguise = initializeDebugGateway();
549 }
550 */
551 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Match Service: " + "Getting server extend disguise");
552
553 try
554 {
555 refExtendDataDisguise = DisguiseLoader.getDisguise(sDisguise);
556 vDisguiseBuckets = refExtendDataDisguise.getBucketDataObjects();
557 }
558
559 catch (DisguiseLoaderException e)
560 {
561 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Match Service: " + "Error getting server extend disguise, " + e.getOriginalException().toString());
562 refImportData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, "Error getting server extend disguise, " + e.getOriginalException().toString()) );
563 return false;
564 }
565
566 /* if (bTest == true)
567 {
568 printDisguiseExtend(refExtendDataDisguise, sDisguise);
569 }
570 */
571 return true;
572 } // getExtendDataDisguise
573
574 /**
575 *
576 *
577 */
578 public ServerBucketExtendData findBucket(String sLabel, int nType)
579 {
580 // Find the bucket with the specified characteristics
581 ServerBucketExtendData refBucket = null;
582
583 if (vDisguiseBuckets == null)
584 {
585 return null;
586 }
587
588 // Scan all buckets in the disguise
589 for (int i=0; i<vDisguiseBuckets.size(); i++)
590 {
591 refBucket = (ServerBucketExtendData)vDisguiseBuckets.elementAt(i);
592 // Vector vFieldData = refBucket.getFieldDataObjects();
593
594 if ((sLabel.equals(refBucket.getLabel()) == true) &&
595 (refBucket.getBucketType() == nType))
596 {
597 return refBucket;
598 } // switch
599 } // for
600
601 return null;
602 } // findBucket
603
604 /**
605 *
606 *
607 */
608 protected String removeSlashes(String sPath)
609 {
610 // Remove first slash if it exists
611 if (sPath.startsWith(sDirSeparator) == true)
612 {
613 sPath = sPath.substring(1);
614 }
615
616 // Remove last slash if it exists
617 if (sPath.endsWith(sDirSeparator) == true)
618 {
619 sPath = sPath.substring(0, sPath.length() - 1);
620 }
621
622 return sPath;
623 } // remove slashes
624
625
626 } // OPIMatchService