Source code: com/flexstor/flexdbserver/services/asset/destination/MappedStructure.java
1 /*
2 * MappedStructure.java
3 *
4 * Copyright $Date: 2003/08/11 02:22:34 $ 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.destination;
12
13 import java.util.ArrayList;
14 import java.util.Enumeration;
15 import java.util.Hashtable;
16 import java.util.Iterator;
17 import java.util.TreeMap;
18 import java.util.Vector;
19
20 import com.flexstor.common.constants.ActionPropertiesI;
21 import com.flexstor.common.data.ejb.disguiserecord.DisguiseAssetRecordData;
22 import com.flexstor.common.data.ejb.disguiserecord.DisguiseBucketRecordData;
23 import com.flexstor.common.data.ejb.disguiserecord.DisguiseFieldRecordData;
24 import com.flexstor.common.data.ejb.disguiserecord.DisguiseRecordData;
25 import com.flexstor.common.data.ejb.search.MultiValueData;
26 import com.flexstor.common.errorlogger.FlexError;
27 import com.flexstor.common.gateway.SearchResultGateway;
28 import com.flexstor.common.gateway.exceptions.TransactionFailedException;
29 import com.flexstor.common.importprocessor.ImportCtlData;
30 import com.flexstor.common.importprocessor.ImportData;
31 import com.flexstor.common.importprocessor.ImportResult;
32 import com.flexstor.common.io.xfile.FlexXFile;
33 import com.flexstor.common.resources.Resources;
34 import com.flexstor.common.services.ServiceArgumentsI;
35 import com.flexstor.common.util.Diagnostic;
36 import com.flexstor.ejb.bucket.persist.ServerBucketExtendData;
37 import com.flexstor.ejb.disguise.persist.ServerDisguiseExtendData;
38 import com.flexstor.ejb.field.persist.ServerFieldExtendData;
39 import com.flexstor.flexdbserver.disguise.DisguiseLoader;
40 import com.flexstor.flexdbserver.disguise.DisguiseLoaderException;
41
42
43 public class MappedStructure
44 {
45 // To get the version number from MKS
46 public final static String IDENTIFIER="$Id: MappedStructure.java,v 1.5 2003/08/11 02:22:34 aleric Exp $";
47
48 private final static int VALUES_MISMATCH = -1;
49 private final static int DATABASE_VALUES = 0;
50 private final static int DATAOBJECT_VALUES = 1;
51
52 private String sThisService;
53 private String fileSeparator;
54 private String sDestination;
55 private String sCtlFileName;
56 private boolean bDoExactMatch;
57 private ServerDisguiseExtendData disguise;
58
59 /**
60 * Keep bucket ids in order of appearance in [mapfolders] section.
61 * Note that a bucket can appear in two or more consecutive levels; however this
62 * object only keeps the order of appearance once.
63 * This object is needed when comparing the traversal path of an asset with the
64 * buckets defined in the [mapfolders] section.
65 */
66 private ArrayList alBuckets = new ArrayList();
67 /**
68 * Holds a list of field ids present for each bucket in the [mapfolders] section.
69 * key = bucket structure id; value = ArrayList of field ids
70 * Used for retrieving field values when calling the retrieval bean.
71 * ArrayList is also used to construct path.
72 */
73 private Hashtable htFields = new Hashtable();
74 /**
75 * Holds a list of Bucket record ids grouped by bucket structure id.
76 * key = bucket structure id; value = ArrayList of record ids
77 * Used for retrieving field values when calling the retrieval bean.
78 */
79 private Hashtable htBucketIds = new Hashtable();
80 /**
81 * Holds a list of field values per bucket record id.
82 * key = bucket record id; value = MultivalueFieldData[]
83 * Used when creating the path for each asset.
84 */
85 private Hashtable htValuesPerRecord = new Hashtable();
86 /**
87 * Holds a list of field values per bucket. (No bucket id)
88 * key = bucket (DisguiseBucketRecordData object); value = MultivalueFieldData[]
89 * Used when creating the path for each asset.
90 */
91 private Hashtable htValuesPerBucket = new Hashtable();
92
93 /**
94 * If true, ignore values in the data object and only use those in the database to
95 * set the destination path
96 */
97 private boolean bUseDBValuesOnly;
98
99 public ImportResult setPaths( ImportData importData, Hashtable htProperties )
100 {
101 sThisService = (String) htProperties.get("servicename");
102 fileSeparator = System.getProperty("file.separator");
103
104 String sBoolean = (String) htProperties.get("UseDBValuesOnly");
105 bUseDBValuesOnly = sBoolean == null ? false : Boolean.valueOf(sBoolean).booleanValue();
106
107 // Get Role, Type and Flag values from property list (AssetService)
108 String sRoleIn = (String) htProperties.get(ServiceArgumentsI.ROLE_DATA_SOURCE);
109 String sTypeIn = (String) htProperties.get(ServiceArgumentsI.TYPE_DATA_SOURCE);
110 String sFlagIn = (String) htProperties.get(ServiceArgumentsI.FLAG_DATA_SOURCE);
111
112 try
113 {
114 sDestination = (String) htProperties.get("destinationbase");
115 if ( !sDestination.endsWith(fileSeparator) )
116 sDestination += fileSeparator;
117 }
118 catch ( NullPointerException npe )
119 {
120 //6518=Destination directory not specified. Cannot proceed.
121 importData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6518 ) );
122 ImportResult result = new ImportResult(false);
123 result.setImportData(importData);
124 return result;
125 }
126
127 // Retrieve the exactMatch property. If not specified defaults to false so we don't do
128 // an exact match.
129 bDoExactMatch = (new Boolean((String)htProperties.get("exactMatch"))).booleanValue();
130
131 boolean bResult = true;
132 DisguiseRecordData disguiseRecord;
133 if ( importData != null && (disguiseRecord = importData.getDisguiseRecordRef()) != null )
134 {
135 Vector vAssetsIn = disguiseRecord.getAssets( sRoleIn, sTypeIn, sFlagIn );
136 if ( vAssetsIn != null && vAssetsIn.size() > 0 )
137 {
138 //setInfo( vAssetsIn );
139 StringBuffer sbError = new StringBuffer("");
140
141 // Create an ArrayList which will hold the structure id for each bucket in the tmLevels TreeMap
142 // preserving the order assigned in the TreeMap and then a Hashtable that holds the field ids
143 // for each bucket. The ArrayList will be used to compare the position of the buckets in the
144 // ctl file with those in the traversal path of the asset; if the positions don't match, then
145 // exclude the asset from being processed. The Hashtable will be used to query the database and
146 // retrieving the values for those fields, which will be used to create the destination path
147 // of the asset.
148 String sError = getBucketAndFieldsInfo( (TreeMap) htProperties.get("levels") );
149 if ( sError == null )
150 {
151 // Parse through each asset, retrieve the traversal paths and compare them with the alBuckets to
152 // find out if the buckets match. If they do, retrieve the record id of each one and store them
153 // in a Hashtable that will hold the record id for each bucket. This Hashtable will be later use
154 // in conjunction with the htFields Hashtable to retrieve the field values from the database. If
155 // the buckets don't match for an asset, then exclude it from being processed.
156 sError = retrieveRecordIdsForBuckets( vAssetsIn, disguiseRecord );
157 if ( !vAssetsIn.isEmpty() )
158 {
159 if ( sError != null )
160 sbError.append( sError + "\r\n" );
161
162 // Query the database and get field values
163 sError = retrieveFieldValues();
164 if ( sError == null )
165 {
166 // Now create the destination path for each asset
167 sError = createPaths( vAssetsIn, disguiseRecord );
168 if ( sError != null )
169 sbError.append( sError + "\r\n" );
170
171 ImportCtlData ctlData = importData.getCtlDataRef();
172 ctlData.removeItem( "HIGHFILELISTBASE", ctlData.getValuePerKey("HIGHFILELISTBASE") );
173 ctlData.addValuePerKey( "HIGHFILELISTBASE" , (new FlexXFile(sDestination)).getLocalPath() );
174
175 if ( sbError.length() > 0 )
176 importData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, sbError.toString()) );
177
178 if ( vAssetsIn.isEmpty() )
179 bResult = false;
180
181 sError = null;
182 }
183 }
184 }
185 if ( sError != null )
186 {
187 importData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, sError) );
188 bResult = false;
189 }
190 }
191 else
192 {
193 //6290=Could not find assets of the following role, type and flag: %%1 %%2 %%3
194 importData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6290, new String[] { sRoleIn, sTypeIn, sFlagIn } ) );
195 bResult = false;
196 }
197 }
198 else
199 {
200 //6291=Cannot operate on an empty data object
201 importData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6291 ) );
202 bResult = false;
203 }
204
205 ImportResult result = new ImportResult(bResult);
206 result.setImportData(importData);
207 return result;
208 }
209
210 private String getBucketAndFieldsInfo( TreeMap tmLevels )
211 {
212 try
213 {
214 // Get the ctl file name for later use
215 // also remove this element from the TreeMap since we don't need it anymore
216 sCtlFileName = (String) tmLevels.remove( tmLevels.firstKey() );
217 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Ctl File Name is: " + sCtlFileName );
218
219 // Get the application name to load the disguise
220 // also remove this element from the TreeMap since we don't need it anymore
221 String sAppName = (String) tmLevels.remove( tmLevels.firstKey() );
222 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Application Name is: " + sAppName );
223 // Load it
224 disguise = DisguiseLoader.getDisguise( sAppName );
225 if ( disguise == null )
226 //6287=%%1 Application could not be loaded.
227 return Resources.get( 6287, sAppName );
228 }
229 catch ( DisguiseLoaderException rdle )
230 {
231 return rdle.toString();
232 }
233
234 // Retrieve the bucket id for each bucket specified and store it in the ArrayList
235 // also retrieve the field labels and store its id in the Hashtable
236 String sValue, sBucket, sField;
237 Integer nBucketId, nFieldId;
238 Vector vBuckets = disguise.getBucketDataObjects();
239 Vector vFields;
240 ServerBucketExtendData bucket = null;
241 ServerFieldExtendData field = null;
242 ArrayList alField;
243 for ( Iterator i = tmLevels.values().iterator(); i.hasNext(); )
244 {
245 sValue = (String) i.next();
246 sBucket = sValue.substring(0, sValue.indexOf(','));
247 sField = sValue.substring(sValue.indexOf(',') + 1);
248 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Bucket Label is: " + sBucket );
249 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Field Label is: " + sField );
250 // Trim values, in case there are blank spaces
251 sBucket = sBucket.trim();
252 sField = sField.trim();
253
254 if ( bucket == null || !bucket.getLabel().equals(sBucket) )
255 {
256 for ( Iterator j = vBuckets.iterator(); j.hasNext(); )
257 {
258 bucket = (ServerBucketExtendData) j.next();
259 if ( bucket.getLabel().equals(sBucket) )
260 break;
261 else
262 bucket = null;
263 }
264
265 if ( bucket == null )
266 // 6926=%%1 is not a valid bucket label in configuration file %%2.
267 return Resources.get( 6926, sBucket, sCtlFileName );
268 }
269
270 nBucketId = new Integer(bucket.getId());
271 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Bucket Id is: " + nBucketId.intValue() );
272 if ( !alBuckets.contains(nBucketId) )
273 {
274 alBuckets.add( nBucketId );
275 htFields.put( nBucketId, new ArrayList() );
276 }
277
278 vFields = bucket.getFieldDataObjects();
279 for ( Iterator k = vFields.iterator(); k.hasNext(); )
280 {
281 field = (ServerFieldExtendData) k.next();
282 if ( field.getLabel().equals(sField) )
283 break;
284 else
285 field = null;
286 }
287
288 if ( field == null )
289 // 6927=%%1 is not a valid field labed for %%2 bucket in configuration file %%3.
290 return Resources.get( 6927, sField, sBucket, sCtlFileName );
291
292 nFieldId = new Integer(field.getId());
293 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Field Id is: " + nFieldId.intValue() );
294 alField = (ArrayList) htFields.get(nBucketId);
295 alField.add(nFieldId);
296 }
297 return null;
298 }
299
300 private String retrieveRecordIdsForBuckets( Vector vAssetsIn, DisguiseRecordData disguiseRecord )
301 {
302 Vector vFailedFiles = new Vector(); // for logging
303 DisguiseAssetRecordData asset;
304 DisguiseBucketRecordData bucket;
305 Vector vTraversalPath;
306 Long nRecordId;
307 Integer nBucketId;
308 for ( Iterator i = vAssetsIn.iterator(); i.hasNext(); )
309 {
310 asset = (DisguiseAssetRecordData) i.next();
311 vTraversalPath = asset.getTraversalPath();
312 // Traversal path contains element bucket, which is not included in the alBuckets ArrayList,
313 // that's why we do vTraversalPath.size() - 1
314 // If the number of buckets in the traversal path is greater than in the [mapfolders] section
315 // we should stop processing this asset, since the bucket structure don't match; however if
316 // the number of buckets in the traversal path is less or equal to the ones in [mapfolders]
317 // then we can process it only if this is not an exact match.
318 if ( (vTraversalPath.size() - 1) > alBuckets.size() ||
319 (bDoExactMatch && (vTraversalPath.size() - 1) != alBuckets.size()) )
320 {
321 vFailedFiles.addElement( fileSeparator + asset.getLocation() + asset.getFileName() );
322 disguiseRecord.deleteAsset( asset );
323 i.remove();
324 continue; // failed; structure are not the same
325 }
326
327 for ( int j = 0; j < (vTraversalPath.size() - 1); j++ )
328 {
329 bucket = (DisguiseBucketRecordData) vTraversalPath.elementAt(j);
330
331 if ( bucket.getBucketStructId() != ((Integer)alBuckets.get(j)).intValue() )
332 {
333 vFailedFiles.addElement( fileSeparator + asset.getLocation() + asset.getFileName() );
334 disguiseRecord.deleteAsset( asset );
335 i.remove();
336 break; // failed; structure are not the same
337 }
338
339 if ( bucket.getRecordId() > 0 )
340 {
341 nRecordId = new Long( bucket.getRecordId() );
342 //Get the structure id and create an entry in htBucketIds if it doesn't exist
343 nBucketId = new Integer( bucket.getBucketStructId() );
344 if ( !htBucketIds.containsKey( nBucketId ) )
345 htBucketIds.put( nBucketId, new ArrayList() );
346
347 ArrayList alRecordIds = (ArrayList) htBucketIds.get( nBucketId );
348 if ( !alRecordIds.contains( nRecordId ) )
349 alRecordIds.add( nRecordId );
350 }
351 }
352 }
353
354 if ( vFailedFiles.isEmpty() )
355 return null;
356 else
357 {
358 // 6928=Bucket Structure for assets don't match that defined in configuration file %%1.
359 StringBuffer sb = new StringBuffer( Resources.get(6928, sCtlFileName) + "\r\n" );
360 for ( int i = 0; i < vFailedFiles.size(); i++ )
361 sb.append( (String) vFailedFiles.elementAt(i) + "\r\n" );
362
363 return sb.toString();
364 }
365 }
366
367 private String retrieveFieldValues()
368 {
369 // Query the database and get the field values for each bucket's record id that we have
370 SearchResultGateway searchGateway = null;
371 ArrayList alRecordIds;
372 Integer nBucketId;
373 try
374 {
375 for ( Enumeration e = htBucketIds.keys(); e.hasMoreElements(); )
376 {
377 nBucketId = (Integer) e.nextElement();
378 alRecordIds = (ArrayList) htBucketIds.get( nBucketId );
379 if ( !alRecordIds.isEmpty() )
380 {
381 Object[] LaRecordIds = alRecordIds.toArray();
382 // convert to long[]
383 long[] laRecordIds = new long[ LaRecordIds.length ];
384 for ( int i = 0; i < LaRecordIds.length; i++ )
385 laRecordIds[i] = ((Long)LaRecordIds[i]).longValue();
386
387 Object[] IaFieldIds = ((ArrayList)htFields.get(nBucketId)).toArray();
388 // convert to int[]
389 int[] iaFieldIds = new int[ IaFieldIds.length ];
390 for ( int j = 0; j < IaFieldIds.length; j++ )
391 iaFieldIds[j] = ((Integer)IaFieldIds[j]).intValue();
392
393 if ( searchGateway == null )
394 {
395 searchGateway = new SearchResultGateway();
396 searchGateway.connect();
397 }
398 Hashtable htValues = searchGateway.retrieveBucketData( iaFieldIds, laRecordIds );
399 if ( htValues != null )
400 htValuesPerRecord.putAll( htValues );
401 }
402 }
403 }
404 catch(TransactionFailedException rtfe)
405 {
406 return rtfe.toString();
407 }
408 finally
409 {
410 if ( searchGateway != null )
411 searchGateway.dispose();
412 }
413
414 return null;
415 }
416
417 private String createPaths( Vector vAssetsIn, DisguiseRecordData disguiseRecord )
418 {
419 // Will hold the name of each subfolder for later constructing the path
420 ArrayList alSubFolders = new ArrayList();
421 DisguiseAssetRecordData asset;
422 DisguiseBucketRecordData bucket;
423 Vector vTraversalPath;
424 MultiValueData[] objectValues = null, dbValues = null;
425 Long nRecordId;
426 Vector vFailedFiles = new Vector();
427 boolean bConstructPath;
428
429 for ( Iterator i = vAssetsIn.iterator(); i.hasNext(); )
430 {
431 asset = (DisguiseAssetRecordData) i.next();
432 vTraversalPath = asset.getTraversalPath();
433 bConstructPath = true;
434 alSubFolders = new ArrayList();
435
436 // do vTraversalPath.size() - 1 since last object is element and we are only handling buckets
437 for ( int j = 0; j < (vTraversalPath.size() - 1); j++ )
438 {
439 bucket = (DisguiseBucketRecordData) vTraversalPath.elementAt(j);
440
441 if ( !bUseDBValuesOnly )
442 objectValues = getValuesFromBucket( bucket, (ArrayList)htFields.get(new Integer(bucket.getBucketStructId())) );
443
444 if ( bucket.getRecordId() > 0 )
445 {
446 nRecordId = new Long( bucket.getRecordId() );
447 //Load field values from htValuesPerRecord
448 dbValues = (MultiValueData[]) htValuesPerRecord.get( nRecordId );
449 }
450 else
451 dbValues = null;
452
453 int nPick = bUseDBValuesOnly ? DATABASE_VALUES : pickValues( dbValues, objectValues );
454 if ( nPick == DATABASE_VALUES )
455 {
456 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Using DATABASE_VALUES!!!!" );
457 // Use database values to create path for asset
458 for ( int k = 0; k < dbValues.length; k++ )
459 alSubFolders.add( (dbValues[k].getFieldData())[0] );
460 }
461 else if ( nPick == DATAOBJECT_VALUES )
462 {
463 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Using DATAOBJECT_VALUES!!!!" );
464 // Use database values to create path for asset
465 for ( int k = 0; k < objectValues.length; k++ )
466 alSubFolders.add( (objectValues[k].getFieldData())[0] );
467 }
468 else
469 {
470 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "VALUES_MISMATCH!!!!" );
471 vFailedFiles.addElement( fileSeparator + asset.getLocation() + asset.getFileName() );
472 disguiseRecord.deleteAsset( asset );
473 i.remove();
474 bConstructPath = false;
475 break; // failed; values mismatched
476 }
477 }
478
479 if ( bConstructPath )
480 constructPath( asset, alSubFolders );
481 }
482
483 if ( vFailedFiles.isEmpty() )
484 return null;
485 else
486 {
487 // 6929=No field values where found to construct path.
488 StringBuffer sb = new StringBuffer( Resources.get(6929) + "\r\n" );
489 for ( int i = 0; i < vFailedFiles.size(); i++ )
490 sb.append( (String) vFailedFiles.elementAt(i) + "\r\n" );
491
492 return sb.toString();
493 }
494
495 }
496
497 private MultiValueData[] getValuesFromBucket( DisguiseBucketRecordData bucket, ArrayList alFieldIds )
498 {
499 MultiValueData[] values = (MultiValueData[]) htValuesPerBucket.get( bucket );
500 if ( values != null )
501 return values;
502
503 DisguiseFieldRecordData[] aFieldRecords = bucket.getValues();
504 if ( aFieldRecords != null )
505 {
506 values = new MultiValueData[ alFieldIds.size() ];
507 ServerFieldExtendData field;
508 int i = 0, j = 0;
509 int nFields = alFieldIds.size();
510 // Repeat the for loop until all field ids in alFieldIds are processed; the foor loop
511 // is wrapped around a while loop because the ids in alFieldIds might not be in the same
512 // order as the ids in field.
513 while ( i != nFields )
514 {
515 for ( Enumeration fieldEnum = disguise.getBucketFields(bucket.getBucketStructId()); fieldEnum.hasMoreElements(); )
516 {
517 field = (ServerFieldExtendData) fieldEnum.nextElement();
518 if ( field.getId() == ((Integer)alFieldIds.get(i)).intValue() )
519 {
520 if ( aFieldRecords[j] != null && aFieldRecords[j].getValue() != null && !(aFieldRecords[j].getValue().equals("")) )
521 values[i] = new MultiValueData( new String[] { aFieldRecords[j].getValue() } );
522 else
523 values[i] = new MultiValueData( new String[] { new String() } );
524 if ( ++i == nFields )
525 break;
526 }
527 j++;
528 }
529 j = 0;
530 }
531 htValuesPerBucket.put( bucket, values );
532 return values;
533 }
534 return null;
535 }
536
537 /*
538 * Whether to use the values from the database or from the data object will depend on
539 * the following rules:
540 * 1.- If both arrays are null, return failure.
541 * 2.- If database array is null, but data object array isn't; check values of data
542 * object array, and if at least one is empty, return failure; otherwise use it.
543 * 3.- Id data object array is null, but database array isn't; check values of database
544 * array, and if at least one is empty, return failure; otherwise use it.
545 * 4.- If both arrays aren't null, compare all values from each array, index per index:
546 * a.- If elements at index i in both array are empty, return failure
547 * b.- If element[i] in database array is empty, but element[i] in data object
548 * isn't, mark database array as unusable and if data object array is already
549 * marked as unusable, return failure; otherwise, continue.
550 * c.- If element[i] in data object array is empty, but element[i] in database
551 * isn't, mark data object array as unusable and if database array is already
552 * marked as unusable, return failure; otherwise, continue.
553 * d.- If both elements aren't empty, but they are not equal, return failure,
554 * otherwise, continue.
555 * e.- After all elements are compared and there is no failure so far:
556 * I.- If both arrays are marked as usable, use database array.
557 * II.- If database array is marked usable, but data object array isn't, use
558 * database array.
559 * III.- If data object array is marked usable, but database array isn't, use
560 * data object array.
561 * IV.- If both arrays are marked as unusable, return failure.
562 */
563 private int pickValues( MultiValueData[] dbValues, MultiValueData[] objectValues )
564 {
565 if ( dbValues == null && objectValues == null )
566 return VALUES_MISMATCH;
567 else if ( dbValues == null )
568 {
569 // If at least one value is not set, return; cannot construct the path
570 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Values from data object:" );
571 String sFieldValue;
572 for ( int i = 0; i < objectValues.length; i++ )
573 {
574 sFieldValue = (objectValues[i].getFieldData())[0];
575 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, " " + sFieldValue );
576 if ( sFieldValue.equals("") )
577 return VALUES_MISMATCH;
578 }
579 return DATAOBJECT_VALUES;
580 }
581 else if ( objectValues == null )
582 {
583 // If at least one value is not set, return; cannot construct the path
584 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Values from database:" );
585 String sFieldValue;
586 for ( int i = 0; i < dbValues.length; i++ )
587 {
588 sFieldValue = (dbValues[i].getFieldData())[0];
589 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, " " + sFieldValue );
590 if ( sFieldValue.equals("") )
591 return VALUES_MISMATCH;
592 }
593 return DATABASE_VALUES;
594 }
595 else
596 {
597 // If at least one value is not set, return; cannot construct the path
598 String sDBValue, sObjectValue;
599 boolean bUseDBValues = true, bUseObjectValues = true;
600 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Values from both object and database:" );
601 for ( int i = 0; i < dbValues.length; i++ )
602 {
603 sDBValue = (dbValues[i].getFieldData())[0];
604 sObjectValue = (objectValues[i].getFieldData())[0];
605 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, " database: " + sDBValue );
606 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, " object: " + sObjectValue );
607 if ( sDBValue.equals("") && sObjectValue.equals("") )
608 return VALUES_MISMATCH;
609 else if ( sDBValue.equals("") )
610 {
611 bUseDBValues = false;
612 if (!bUseObjectValues )
613 return VALUES_MISMATCH;
614 }
615 else if ( sObjectValue.equals("") )
616 {
617 bUseObjectValues = false;
618 if ( !bUseDBValues )
619 return VALUES_MISMATCH;
620 }
621 else if ( !sObjectValue.equals(sDBValue) )
622 return VALUES_MISMATCH;
623 }
624
625 if ( bUseDBValues && bUseObjectValues )
626 return DATABASE_VALUES;
627 else if ( bUseDBValues )
628 return DATABASE_VALUES;
629 else if ( bUseObjectValues )
630 return DATAOBJECT_VALUES;
631 else
632 return VALUES_MISMATCH;
633 }
634 }
635
636 private void constructPath( DisguiseAssetRecordData asset, ArrayList alSubFolders )
637 {
638 StringBuffer sbSubFolders = new StringBuffer("");
639 for ( int i = 0; i < alSubFolders.size(); i++ )
640 sbSubFolders.append( (String)alSubFolders.get(i) + fileSeparator );
641
642 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Destination for " + asset.getFileName() + " is " + sDestination + sbSubFolders.toString() );
643 asset.addProperty( ActionPropertiesI.DESTINATION_LOCATION, sDestination + sbSubFolders.toString() );
644 }
645 }