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

Quick Search    Search Deep

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


1   /*
2    * MilService.java
3    *
4    * Copyright $Date: 2003/08/11 02:22:28 $ 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.io.FileReader;
14  import java.io.IOException;
15  import java.io.StreamTokenizer;
16  import java.util.Date;
17  import java.util.Enumeration;
18  import java.util.StringTokenizer;
19  import java.util.Vector;
20  
21  import com.flexstor.common.constants.BucketConstantsI;
22  import com.flexstor.common.constants.SequenceConstantsI;
23  import com.flexstor.common.data.ActionData;
24  import com.flexstor.common.data.ActionResult;
25  import com.flexstor.common.data.ejb.disguiserecord.AssetRoleData;
26  import com.flexstor.common.data.ejb.disguiserecord.DisguiseAssetRecordData;
27  import com.flexstor.common.data.ejb.disguiserecord.DisguiseBucketRecordData;
28  import com.flexstor.common.data.ejb.disguiserecord.DisguiseElementRecordData;
29  import com.flexstor.common.data.ejb.disguiserecord.DisguiseFieldRecordData;
30  import com.flexstor.common.data.ejb.disguiserecord.DisguiseRecordData;
31  import com.flexstor.common.data.ejb.disguiserecord.HighresRoleData;
32  import com.flexstor.common.data.ejb.disguiserecord.ThumbnailRoleData;
33  import com.flexstor.common.gateway.SequenceGateway;
34  import com.flexstor.common.gateway.exceptions.TransactionFailedException;
35  import com.flexstor.common.importprocessor.ImportCtlData;
36  import com.flexstor.common.importprocessor.ImportData;
37  import com.flexstor.common.importprocessor.ImportResult;
38  import com.flexstor.common.io.xfile.FlexXFile;
39  import com.flexstor.common.services.ServiceArgumentsI;
40  import com.flexstor.common.util.Diagnostic;
41  import com.flexstor.ejb.bucket.persist.ServerBucketExtendData;
42  import com.flexstor.ejb.disguise.persist.ServerDisguiseExtendData;
43  import com.flexstor.ejb.field.persist.ServerFieldExtendData;
44  import com.flexstor.flexdbserver.disguise.DisguiseLoader;
45  import com.flexstor.flexdbserver.services.Service;
46  import com.flexstor.flexdbserver.services.ServiceContext;
47  
48  /**
49   * <P>
50   * MilService <BR>
51   * <BLOCKQUOTE>
52   *    The MilService provides functionality for creating assets and attaching metadata from
53   *    a data file which is in a specific format.  These data files, which may list several
54   *    assets, are called Mil files.  This was done for a specific customer and may not
55   *    be of general use.  If creating assets and populating metadata fields is desired, consider
56   *    the XMLActionDataService.
57   * </BLOCKQUOTE>
58   * </P>
59   *
60   * <P>
61   * Configurable Properties in services.config <BR>
62   * <BLOCKQUOTE>
63   *    None
64   * </BLOCKQUOTE>
65   * </P>
66   *
67   * <P>
68   * Configurable Properties in hotdirectory control file <BR>
69   * <BLOCKQUOTE>
70   *    makeXMilTemp<br>
71   *    Legal values: N or Y<br>
72   *    This is used to inform the service if the Mil file itself should be set to TEMP.
73   *    The default is to not set it to TEMP.
74   * </BLOCKQUOTE>
75   * <BLOCKQUOTE>
76   *    HighresExtension, ThumbnailExtension<br>
77   *    These are the default extensions to append to the basename of the asset.  If not
78   *    specified, the defaults of .tif and .jpg are used.
79   * </BLOCKQUOTE>
80   * </P>
81   * Configurable Properties in roletype_services.config <BR>
82   *
83   * <!-- THE ACTUAL TABLE:                                                     -->
84   *
85   * <TABLE BORDER="1" CELLPADDING="3" CELLSPACING="3">
86   * <CAPTION ALIGN=TOP>
87   *    <B> In/Out Properties for Assets </B>
88   * </CAPTION>
89   *     <TR>
90   *        <FONT SIZE=+1><B>
91   *        <TH WIDTH="120">Attribute</TH>
92   *                                   <TH WIDTH="30">IN</TH>           <TH WIDTH="30">OUT</TH>          <TH WIDTH="30">Default IN</TH>  <TH WIDTH="30">Default OUT</TH>
93   *        </B></FONT>
94   *     </TR>
95   *     <TR>
96   *        <TH ALIGN=LEFT><FONT SIZE=+1><B>ROLE</B></FONT></TH><TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> ALL </TD>    <TD ALIGN=CENTER> ALL </TD>
97   *     </TR>
98   *     <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>
99   *     <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>
100  *     <TR><TH> Thumbnail </TH>      <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
101  *     <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>
102  *     <TR><TH> Video </TH>          <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
103  *     <TR><TH> Audio </TH>          <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
104  *     <TR>
105  *        <TH ALIGN=LEFT><FONT SIZE=+1><B>TYPE</B></FONT></TH>
106  *                                   <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> ALL </TD>    <TD ALIGN=CENTER> ALL </TD></TR>
107  *     </TR>
108  *     <TR>
109  *        <TH ALIGN=LEFT><FONT SIZE=+1><B>FLAG</B></FONT></TH>
110  *     </TR>
111  *     <TR><TH> PARENT </TH>         <TD ALIGN=CENTER> * </TD>    <TD ALIGN=CENTER> * </TD>    <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> X </TD></TR>
112  *     <TR><TH> CHLDREN </TH>        <TD ALIGN=CENTER> * </TD>    <TD ALIGN=CENTER> * </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
113  *     <TR><TH> ALL </TH>            <TD ALIGN=CENTER> * </TD>    <TD ALIGN=CENTER> * </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
114  *     <TR><TH> TEMP_PARENT </TH>    <TD ALIGN=CENTER> * </TD>    <TD ALIGN=CENTER> * </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
115  *     <TR><TH> TEMP_CHILDREN </TH>  <TD ALIGN=CENTER> * </TD>    <TD ALIGN=CENTER> * </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
116  *     <TR><TH> TEMP_ALL </TH>       <TD ALIGN=CENTER> * </TD>    <TD ALIGN=CENTER> * </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
117  * </TABLE>
118  *
119  *  *The normal output from the service is an Import Data Object that contains several
120  *  elements.  Each element consists of a high resolution parent and a thumbnail child.
121  *
122  * <P>
123  * Input Data Object <BR>
124  * <BLOCKQUOTE>
125  *    com.flexstor.common.importprocessor.ImportData
126  * </BLOCKQUOTE>
127  * </P>
128  *
129  * <P>
130  * Output Data Object <BR>
131  * <BLOCKQUOTE>
132  *    com.flexstor.common.importprocessor.ImportResult
133  * </BLOCKQUOTE>
134  * </P>
135  */
136 public class MilService
137    implements Service
138 {
139   // Used for logging errors
140   public  final static String       IDENTIFIER = "$Id: MilService.java,v 1.4 2003/08/11 02:22:28 aleric Exp $"; 
141 
142   protected ServiceContext             context;
143   // The data object
144   private ImportData                 refImportData     = null;
145 
146   private ServerDisguiseExtendData   myServDisgExtend  = null;
147   private DisguiseRecordData         refDisguiseRecord = null;
148   private ServerBucketExtendData []  allBucketExtend   = null;
149 
150   private SequenceGateway            seqGateway        = null;
151 
152   private static String sDisguise = new String();
153 
154   // sLevelEntries is the   Bucket,FieldName  string
155   private static String sLevelEntries [] = new String[8];
156   // sLevelBucket is the    Bucket            from that string
157   private static String sLevelBucket [] = new String[8];
158   // sLevelField is the            FieldName  from that string
159   private static String sLevelField [] = new String[8];
160 
161   private static int totalLevels   = 0;
162 
163   // asset level info to be used when creating assets
164   private static String servername = null;
165   private static Date   receivedDate = null;
166   private static String ctlUserId = null;
167 
168   // HighresExtension and ThumbnailExtension can be set in the .ctl file
169   private static String sHighresExtension = null;
170   private static String sThumbnailExtension = null;
171 
172   protected boolean  shouldMakeMilTemp  = false;
173 
174   protected boolean  successful  = true;
175 
176   /**
177    * Calls before the service is initialized (before initData is called) to 
178    * pass information about the environment in which the service is running.
179    * This environment consists of information about the properties set for the
180    * service in one of these files (services.config, roletype_services.config,
181    * or *.ctl), plus methods to access other information such as an instance
182    * of the service broker to invoke other services, the transaction id for
183    * the service, file separator character and local path for the installation
184    * directory and configuration directory.
185    * 
186    * @param context Holds information about the environment in which the service
187    *                is running.
188    */
189   public void setServiceContext( ServiceContext context )
190   {
191      this.context = context;
192   }
193   
194    /**
195     * Data initialization method called at the beginning of the service.
196     *
197     * @param Action is the super class of the data wrapper object
198     *        which contains all the information for executing the service.
199     */
200    public void initData( ActionData actionData )
201    {
202       refImportData = (ImportData) actionData;
203 
204       //  Get some info from the .ctl file.  This should all be in the refImportData 
205       ImportCtlData refCtlData = refImportData.getCtlDataRef();
206       sDisguise = refCtlData.getValuePerKey("application name");
207       totalLevels = 0;
208       for (int lev=1; lev<8; lev++) {
209           sLevelEntries[lev] = refCtlData.getValuePerKey("level"+lev);
210           //System.out.println("sLevelEntries[lev] = >>>" + sLevelEntries[lev] + "<<<");
211           if ( ! (sLevelEntries[lev].equals("")) ) {
212              totalLevels++;
213              sLevelBucket[lev] = getBucketLabel(sLevelEntries[lev]);
214              sLevelField[lev] = getFieldLabel(sLevelEntries[lev]);
215           }
216       }
217 
218       ctlUserId = refCtlData.getValuePerKey("userid");
219 
220       String sMilTemp = new String();
221       sMilTemp = refCtlData.getValuePerKey("makeMilTemp").toUpperCase();
222 
223       if (sMilTemp.equals("Y")) {
224           shouldMakeMilTemp = true;
225       } else {
226           shouldMakeMilTemp = false;
227       }
228 
229       // Check if the extensions were set in the .ctl file
230       sHighresExtension = refCtlData.getValuePerKey("HighresExtension");
231       sThumbnailExtension = refCtlData.getValuePerKey("ThumbnailExtension");
232 
233       // If the extensions are not set, use the default values
234     // It's okay to check the equals after we check for null
235     // because java short-circuits the conditional (if the
236     // first condition is true, the second is never checked)
237       if ((sHighresExtension == null) || (sHighresExtension.equals(""))) {
238           sHighresExtension = new String(".tif");
239       }
240       if ((sThumbnailExtension == null) || (sThumbnailExtension.equals(""))) {
241           sThumbnailExtension = new String(".jpg");
242       }
243 
244       //System.out.println("BGP DEBUG: HighresExtension is >" + sHighresExtension + "<");
245       //System.out.println("BGP DEBUG: ThumbnailExtension is >" + sThumbnailExtension + "<");
246    }
247 
248 
249 
250    /**
251     * Start of the  Service
252     *
253     * @return a Result object with the an updated data object.
254     */
255    public ActionResult go()
256    {
257       DisguiseAssetRecordData aMilFileAsset = null;
258 
259       Diagnostic.trace(Diagnostic.APPSERVER_IMPORT,"MilService Started");
260 
261 
262 
263       successful = true;
264 
265       // get the input assets, according to the role, type and flag specified
266       // in remote_server.config or TypeServiceDat.config
267       String sRoleIn = context.getProperty(ServiceArgumentsI.ROLE_DATA_SOURCE);
268       String sTypeIn = context.getProperty(ServiceArgumentsI.TYPE_DATA_SOURCE);
269       String sFlagIn = context.getProperty(ServiceArgumentsI.FLAG_DATA_SOURCE);
270 
271       Diagnostic.trace(Diagnostic.APPSERVER_IMPORT, "Mil:Role = " + sRoleIn);
272       Diagnostic.trace(Diagnostic.APPSERVER_IMPORT, "Mil:Type = " + sTypeIn);
273       Diagnostic.trace(Diagnostic.APPSERVER_IMPORT, "Mil:Flag = " + sFlagIn);
274 
275 
276       ImportResult result = null;
277 
278       if( refImportData == null )
279       {
280           result = new ImportResult(false);
281           return result;
282       }
283 
284       // Get the reference to the DisguiseRecordData
285       refDisguiseRecord = refImportData.getDisguiseRecordRef();
286       if( refDisguiseRecord == null ) {
287           successful = false;
288       }
289 
290 
291       try {
292           myServDisgExtend = DisguiseLoader.getDisguise(sDisguise);
293       }
294       catch (Exception e) {
295           Diagnostic.trace(Diagnostic.APPSERVER_IMPORT,"Exception getting disguise: " + e);
296           e.printStackTrace();
297       }
298 
299 
300       // This is a vector of ServerBucketExtendData Objects  (all our buckets)
301       Vector myBucketDataObjects = myServDisgExtend.getBucketDataObjects();
302 
303       // I'd like an array of SBEDs for all buckets, please.
304       allBucketExtend = new ServerBucketExtendData[myBucketDataObjects.size()];
305 
306       for (int i=0; i<allBucketExtend.length; i++) {
307           allBucketExtend[i] = (ServerBucketExtendData) myBucketDataObjects.elementAt(i);
308       }
309 
310       Vector vAssetsIn = null;
311 
312       if( sRoleIn==null || sTypeIn==null || sFlagIn==null )
313       {
314           successful = false;
315       }
316       else
317       {
318           vAssetsIn = refDisguiseRecord.getAssets(sRoleIn, sTypeIn, sFlagIn);
319           if( vAssetsIn != null )
320           {
321               Enumeration assets = vAssetsIn.elements();
322 
323               // Process each asset in each element in ImportData
324               while(assets.hasMoreElements())
325               {
326                   aMilFileAsset = (DisguiseAssetRecordData)assets.nextElement();
327 
328                   String assetFileName =  aMilFileAsset.getFileName();
329                   String fullPathName = "/" + aMilFileAsset.getLocation() + assetFileName;
330                   Diagnostic.trace(Diagnostic.APPSERVER_IMPORT, "An asset is found: " + fullPathName);
331 
332                   aMilFileAsset.setUserId("Hi There");
333                   servername = aMilFileAsset.getServer();
334                   receivedDate = aMilFileAsset.getReceived();
335 
336                   // If we set this asset to be temp, it won't import and we can DeleteTEMP it
337                   if (shouldMakeMilTemp == true) {
338                       AssetRoleData ourAssetRole = aMilFileAsset.getAssetRole();
339                       ourAssetRole.setTempRole(true);
340                       aMilFileAsset.setAssetRole(ourAssetRole);
341                   }
342 
343                   try
344                   {
345                       parseMilFile(fullPathName);
346                   }
347                   catch (Exception e)
348                   {
349                       Diagnostic.trace(Diagnostic.APPSERVER_IMPORT,"Exception parsing Mil file: " + e);
350                       e.printStackTrace();
351                   }
352               }
353           }
354           else
355               successful = false;
356       }
357 
358 
359 
360 
361       Diagnostic.trace(Diagnostic.APPSERVER_IMPORT, "Done with MilFile service");
362 
363       result = new ImportResult(true);
364 
365       result.setImportData(refImportData);
366       return result;
367    }
368 
369 
370    private int parseMilFile(String milFilePath)
371        throws Exception
372    {
373 
374        FlexXFile aMilFile = new FlexXFile(milFilePath);
375        FileReader milIn = null;
376 
377        int theTType = 0;
378 
379 
380        if(aMilFile.exists() == true)
381        {
382           // create a reader for the file
383           try {
384               milIn = new FileReader(milFilePath);
385           } catch (IOException ioe) {
386               Diagnostic.trace(Diagnostic.APPSERVER_IMPORT,"Unable to open mil file!");
387               return 0 ;
388           }
389 
390           StreamTokenizer stLine = new StreamTokenizer(milIn);
391           stLine.resetSyntax();
392           stLine.wordChars('\u0020','\u00FF');
393           stLine.whitespaceChars('|','|');
394 
395           String sOneLine [] = new String[5];
396           int i = 0;
397 
398           while (theTType != StreamTokenizer.TT_EOF)
399           {
400               try {
401                   theTType = stLine.nextToken();
402                   switch (theTType) {
403                   // an end of line means that we've got a set of regions
404                   case StreamTokenizer.TT_EOL:
405                       // since the last line mayn't end with a newline, an eof
406                       //    would also mean that we've got a set of regions
407                       // May 11, 2000:  David Zumbro said that he'd end the last
408                 //                line with a newline before the end of file
409                       //                so I'm commenting out this case.  -bgp
410                   //case stLine.TT_EOF:
411                       i = 0;
412                       parseIndexData(sOneLine);
413                       break;
414                   case StreamTokenizer.TT_WORD:
415                       sOneLine[i] = stLine.sval;
416                       //System.out.println("sOneLine[" + i + "] = " + stLine.sval);
417                       //System.out.println("sVal: [" + sOneLine[i] + "]");
418                       i++;
419                       break;
420                   default:
421                       break;
422                   }
423              } catch (IOException ioe) {
424                 Diagnostic.trace(Diagnostic.APPSERVER_IMPORT,"IO Exception");
425                 return 0 ;
426              }
427           }
428 
429 
430        } else {
431            // then something is quite wrong
432            Diagnostic.trace(Diagnostic.APPSERVER_IMPORT, "File doesn't exist: " + aMilFile.getPath());
433            return 0 ;
434        }
435 
436        return 1;
437     }
438 
439 
440 
441 
442     protected boolean parseIndexData(String [] sRegions) 
443     {
444        // If our array is not 5, then we don't have a whole line
445        // read properly and so we shouldn't even try to process it.
446        if (sRegions.length == 5) {
447 
448            // The 2nd Region (index [1]) is the one with the "index data"
449            // This is the tilde separated region that needs to be parsed
450            StringTokenizer stIndexData = new StringTokenizer(sRegions[1],"~",true);
451            //System.out.println("You've got " + stIndexData.countTokens() + " tokens in this stIndexData ");
452 
453            // create a vector to hold the index data
454            Vector vIndexData = new Vector(4,1);
455            String sCurrentField = new String();
456            String sPreviousField = new String("~");
457 
458            // This loop fills the vIndexData vector with all the index data
459            //   We had to jump through a couple hoops to handle situations
460            //   where the first or last item in the index data might be blank.
461            while (stIndexData.hasMoreTokens() == true)
462            {
463                sCurrentField = stIndexData.nextToken();
464                // HOOP 1: if the first token is our delimiter, we need to insert a "blank" token first
465                if (sCurrentField.equals("~")) {
466                    if (sCurrentField.equals(sPreviousField)) {
467                        //System.out.println("stIndexData is " + ">>><<<");
468                        vIndexData.addElement(null);
469                    }
470                } else {
471                    //System.out.println("stIndexData is " + ">>>" + sCurrentField + "<<<");
472                    vIndexData.addElement(sCurrentField);
473                }
474                sPreviousField = sCurrentField;
475            }
476            // HOOP 2: if the last token is our delimiter, we need to insert a "blank" token first
477            if (sCurrentField.equals("~")) {
478                //System.out.println("stIndexData is " + ">>><<<");
479                vIndexData.addElement(null);
480            }
481 
482            // vIndexData now contains our index data, it will be mapped
483            // according to the levelX data in the hotdir.ctl file
484 
485 
486           processMilLine(sRegions,vIndexData);
487 
488            // Print everything out (Used during debugging)
489            /*for (int j=0; j<5; j++) {
490                if (j == 1) {
491                    //System.out.println("print vector");
492                    for (int k=0; k<vIndexData.size(); k++) {
493                        Diagnostic.trace(Diagnostic.APPSERVER_IMPORT, "   index data [" + k + "] = >>>" + vIndexData.elementAt(k) + "<<<");
494                        //System.out.println("BGP: sRegion[1]indexdata [" + k + "] = >>>" + vIndexData.elementAt(k) + "<<<");
495                    }
496                } else {
497                    Diagnostic.trace(Diagnostic.APPSERVER_IMPORT, "sRegions[" + j + "] = >>>" + sRegions[j] + "<<<");
498                    //System.out.println("BGP: sRegions[" + j + "] = >>>" + sRegions[j] + "<<<");
499                }
500            }*/
501 
502 
503            return true;
504       } else {
505            return false;
506       }
507    }
508 
509 
510   private boolean processMilLine(String [] sRegions, Vector vIndexData) {
511       /*for (int j=0; j<5; j++) {
512           if (j == 1) {
513               //System.out.println("print vector");
514           } else {
515               Diagnostic.trace(Diagnostic.APPSERVER_IMPORT, "sRegions[" + j + "] = >>>" + sRegions[j] + "<<<");
516               //System.out.println("BGP: sRegions[" + j + "] = >>>" + sRegions[j] + "<<<");
517           }
518       }*/
519 
520 
521       // refBucket will be the current bucket that we'll attach to
522       DisguiseBucketRecordData refBucket = null;
523 
524       int startLevel = 1;
525       int endLevel = 1;
526 
527       if ( totalLevels > vIndexData.size() ) {
528           Diagnostic.trace(Diagnostic.APPSERVER_IMPORT,"Too many levels("+totalLevels+") for index data!");
529           return false;
530       }
531 
532       for (int lev=1; lev<=totalLevels; lev++) {
533           //Diagnostic.trace(Diagnostic.APPSERVER_IMPORT," index data "+(lev-1)+" is >>>"+vIndexData.elementAt(lev-1)+"<<<");
534           // if this level name is the same as the next level, we're still
535           // in the same bucket.  Try to get all the field labels for one
536           // bucket before processing.
537           if (sLevelBucket[lev].equals(sLevelBucket[lev+1])) {
538               // Then the next level will be part of the same bucket.
539               //System.out.println("BGP: --> Current LevelEntry: " + sLevelEntries[lev]);
540               endLevel++;
541           } else {
542               // Then the next level will be a different bucket.
543               //System.out.println("BGP: --> Current LevelEntry: " + sLevelEntries[lev]);
544               //System.out.println("BGP: --> The next level would be a different bucket");
545               //System.out.println("BGP:     SO Process from " + startLevel + " to " + endLevel);
546               // 
547               // pass  1. the bucket we should attach this new bucket to
548               //       2. our index data vector,
549               //       3. the starting Level to process.
550               //       4. the ending Level to process.
551               // 
552               refBucket = beefyStuff(refBucket, vIndexData, startLevel, endLevel);
553               // after processing those levels, refresh our counters
554               startLevel = endLevel = lev + 1;
555           }
556       }
557 
558 
559       // If this is the bucket that contains a field label of "Document #"
560       // (as specified in the spec) that's great.  If not, we'll need to
561       // add the bucket that does contain that label.
562       // sRegions[0] is supposed to be the document number value
563 
564       refBucket = insertDocNumber(refBucket,sRegions[0]);
565       // the bucket that comes back to us should be the Document# level bucket
566 
567 
568       /*
569        *
570        * Create the element
571        *
572        */
573       DisguiseElementRecordData refElement = new DisguiseElementRecordData();
574 
575       // attach the element to the bucket
576       refBucket.addElement(refElement);
577 
578       // SANITY CHECK FOR making sure our elements are being added
579       //DisguiseElementRecordData [] tmpElements = null;
580       //tmpElements = refBucket.getElements();
581       //if (tmpElements != null) System.out.println("BGP SANITYCHECK: You have " + tmpElements.length + " elements");
582 
583       // We still need to set the BucketId for the Element level
584       refElement.setBucketStructId(findBucketId(BucketConstantsI.ELEMENT_BUCKET).getId());
585 
586 
587       /*
588        *
589        * Create the asset
590        *    Highres first
591        */
592       DisguiseAssetRecordData refAsset = new DisguiseAssetRecordData();
593       // attach the asset to the element (be sure to fill the data...)
594       refElement.setParentAsset(refAsset);
595       refAsset.setBucketStructId(findBucketId(BucketConstantsI.ASSET_BUCKET).getId());
596       refElement.setRecordId(getSequence());
597 
598       // sRegions[4] is the path and filename
599       StringTokenizer stPathAndFile = new StringTokenizer(sRegions[4],"/",false);
600       StringBuffer sbLocation = new StringBuffer();
601       int totalTokens = stPathAndFile.countTokens();
602       for (int i=0; i<totalTokens-1; i++) {
603           if (i != 0) sbLocation = sbLocation.append("/");
604           sbLocation = sbLocation.append(stPathAndFile.nextToken());
605       }
606       String sFileName = stPathAndFile.nextToken();
607       String sLocation = new String(sbLocation.toString());
608 
609       //System.out.println("BGP:  The location of " + sRegions[4] + " is " + sLocation);
610       //System.out.println("BGP:  The filename of " + sRegions[4] + " is " + sFileName);
611 
612       refAsset.setLocation(sLocation);
613       refAsset.setFileName(sFileName);
614       refAsset.setServer(servername);
615       refAsset.setReceived(receivedDate);
616       refAsset.setUserId(ctlUserId);
617       refAsset.setAssetRole(new HighresRoleData());
618 
619       /*
620        *    Now the Thumbnail
621        */
622       DisguiseAssetRecordData refThumbAsset = new DisguiseAssetRecordData();
623       if (sFileName.endsWith(sHighresExtension) ) {
624           // attach the asset to the element (be sure to fill the data...)
625           refAsset.addChildAsset(refThumbAsset);
626           refThumbAsset.setBucketStructId(findBucketId(BucketConstantsI.ASSET_BUCKET).getId());
627           refElement.setRecordId(getSequence());
628           String sThumbFileName = sFileName.substring(0,sFileName.lastIndexOf(sHighresExtension));
629           sThumbFileName = sThumbFileName.concat(sThumbnailExtension);
630           refThumbAsset.setLocation(sLocation);
631           refThumbAsset.setFileName(sThumbFileName);
632           refThumbAsset.setServer(servername);
633           refThumbAsset.setReceived(receivedDate);
634           refThumbAsset.setUserId(ctlUserId);
635           refThumbAsset.setAssetRole(new ThumbnailRoleData());
636           refThumbAsset.setDefaultView(true);
637       } else {
638           refAsset.setDefaultView(true);
639       }
640 
641       /*
642        *    Fill in "Page #" Asset level data field for the highres
643        */
644       refAsset.addUserData("Page Number",sRegions[2]);
645       refThumbAsset.addUserData("Page Number",sRegions[2]);
646 
647       return true;
648   }
649 
650 
651 
652    /*
653     *  Figure out if we are at the "Document #" level
654     *  If we are, set "Document #"
655     *  Otherwise, 
656     *       see if it exists
657     *       create if necessary
658     *       set "Document #"
659     *  return the document bucket
660     */
661     protected DisguiseBucketRecordData insertDocNumber(DisguiseBucketRecordData refBucket,
662                                                          String sDocumentNumber) {
663       // refBucket is the last bucket we worked with.
664       //    It *might* be the bucket level containing the "Document #" field label
665 
666 
667       // curBucketID is the id of the bucket level we're currently at
668       int curBucketID = refBucket.getBucketStructId();
669       ServerFieldExtendData tmpSFED = null;
670 
671       Vector vExtendFields = null;
672 
673       //ServerBucketExtendData refExtendBucket = null;
674 
675 
676       /*
677        * First, figure out what bucket "Document #" is on
678        */
679       // docBucketID will be the ID of the bucket that has "Document #"
680       int docBucketID = 0;
681 
682       for (int i=0; i<allBucketExtend.length; i++) {
683           //refExtendBucket = findNormalBucket(allBucketExtend[i].getLabel());
684           vExtendFields = allBucketExtend[i].getFieldDataObjects();
685 
686           //System.out.println("BGP: allBucketExtend["+i+"].getLabel() is " + allBucketExtend[i].getLabel() );
687           // check every fieldLabel until we find it.
688           for (int j=0; j<vExtendFields.size() ; j++) {
689               tmpSFED = (ServerFieldExtendData) vExtendFields.elementAt(j);
690               //System.out.println("BGP: tmpSFED.getLabel " + tmpSFED.getLabel() );
691               if (tmpSFED.getLabel().equals("Document #")) {
692                   docBucketID = allBucketExtend[i].getId();
693                   break;
694               }
695           }
696 
697           if (docBucketID != 0) {
698               break;
699           }
700       }
701 
702       /*
703        * Next, see if that's the bucket level we've got.
704        */
705 
706       // If we're at the right bucket level, we'll modify the bucket
707       if (curBucketID == docBucketID) {
708           // this loop will set the "Document #" data field
709           for (int j=0; j<vExtendFields.size() ; j++) {
710               tmpSFED = (ServerFieldExtendData) vExtendFields.elementAt(j);
711               //System.out.println("BGP: tmpSFED.getLabel " + tmpSFED.getLabel() );
712               if (tmpSFED.getLabel().equals("Document #")) {
713                   refBucket.addValue(sDocumentNumber);
714               }
715           }
716       } else {
717           // Otherwise, we'll need to create the bucket (and attach it)
718           // before putting the data in it.  (scan for existance, too)
719           DisguiseBucketRecordData tmpBucket = new DisguiseBucketRecordData();
720           tmpBucket.setBucketStructId(docBucketID);
721           // this loop will set the data fields
722           for (int j=0; j<vExtendFields.size() ; j++) {
723               tmpSFED = (ServerFieldExtendData) vExtendFields.elementAt(j);
724               //System.out.println("BGP: tmpSFED.getLabel " + tmpSFED.getLabel() );
725               if (tmpSFED.getLabel().equals("Document #")) {
726                   tmpBucket.addValue(sDocumentNumber);
727               } else {
728                   tmpBucket.addValue("");
729               }
730           }
731           DisguiseBucketRecordData newOrExistingBucket = checkForExisting(refBucket,tmpBucket);
732           // if these buckets are the same, it's a new bucket so we'll actually add it
733           if (newOrExistingBucket == tmpBucket) {
734               refBucket.addBucketChild(newOrExistingBucket);
735               return newOrExistingBucket;
736           } else {
737               // otherwise, that bucket already exists, so DON'T add it again!
738               return newOrExistingBucket;
739           }
740       }
741 
742       return refBucket;
743     } // END OF insertDocNumber
744 
745 
746 
747    /*
748     *
749     * We can't just wildly create buckets because we will likely 
750     * have repeated data on the various levels.  So we must first
751     * scan through the buckets we have and see if this bucket is
752     * new or if it already exists
753     *
754     * if it is new, return the new bucket
755     * if it exists, return the existing one
756     */
757     protected DisguiseBucketRecordData beefyStuff(DisguiseBucketRecordData refBucket,
758                                                     Vector vIndexData,
759                                                     int startLevel, int endLevel) {
760         // refBucket   : is the bucket we should attach to (if top level bucket, this is null)
761         // vIndexData  : this is our tilde separated index data
762         // startLevel  : this is the first levelX we're to process
763         // endLevel    : this is the last levelX we're to process
764         ServerFieldExtendData  tmpSFED = null; 
765         String sTmpLabel = null;
766         String sTmpValue = null;
767         boolean fieldIsSet = false;
768 
769         // This is our temporary bucket
770         // we will return this if we're a new bucket
771         DisguiseBucketRecordData tmpBucket = new DisguiseBucketRecordData();
772 
773         // Find the right level of our bucket structure
774         ServerBucketExtendData refExtendBucket = findNormalBucket(sLevelBucket[startLevel]);
775 
776         int     nID           = refExtendBucket.getId();
777         Vector  vExtendFields = refExtendBucket.getFieldDataObjects();
778 
779 
780         // we make a temporary bucket out of our index data;
781         // we will later compare this bucket with our existing
782         // buckets so we don't add duplicates.
783 
784         tmpBucket.setBucketStructId(nID);
785         // we'll fill the data in our temporary bucket
786         for (int i=0; i<vExtendFields.size(); i++) {
787             tmpSFED = (ServerFieldExtendData) vExtendFields.elementAt(i);
788             sTmpLabel = tmpSFED.getLabel();
789 
790             fieldIsSet = false;
791             for (int lev = startLevel; lev <= endLevel; lev++ ) {
792                 //System.out.println("BGP: checking Level" + lev + " against ExtendField " + i);
793                 if (sTmpLabel.equals(sLevelField[lev])) {
794                     sTmpValue = (String) vIndexData.elementAt(lev-1);
795                     //System.out.println("BGP: adding data("+sTmpValue+") for " + sLevelField[lev]);
796                     fieldIsSet = true;
797                     if (sTmpValue == null) {
798                         tmpBucket.addValue("");
799                     } else {
800                         tmpBucket.addValue(sTmpValue);
801                     }
802                     break;
803                 }
804             }
805             if (fieldIsSet == false) {
806                 tmpBucket.addValue("");
807             }
808         }
809 
810 
811         // see if there is a bucket in refBucket with exactly the same field
812         // values as our new tmpBucket
813         DisguiseBucketRecordData newOrExistingBucket = checkForExisting(refBucket,tmpBucket);
814         // if these buckets are the same, it's a new bucket so we'll actually add it
815         if (newOrExistingBucket == tmpBucket) {
816             // If we have made it this far (e.g. past the bucket scan)
817             // that means we are a bucket with different field values
818             // (or we've got no existing buckets) and should be created.
819     
820             // If the refBucket is null, we're at the top level and
821             // thus we should add our new bucket to the refDisguiseRecord
822             if (refBucket == null) {
823                 refDisguiseRecord.addBucket(newOrExistingBucket);
824             } else {
825                 refBucket.addBucketChild(newOrExistingBucket);
826             }
827         } else {
828             // otherwise, that bucket already exists, so DON'T add it again!
829             return newOrExistingBucket;
830         }
831 
832         return tmpBucket;
833     } // END OF beefyStuff
834 
835 
836 
837    /**
838     *   Return the BucketExtendData of the element level bucket
839     */
840     ServerBucketExtendData findBucketId(int typeToSearchFor) {
841 
842         int bucketType = 0;
843 
844         for (int i=0; i<allBucketExtend.length; i++) {
845             bucketType = allBucketExtend[i].getBucketType();
846             if (bucketType == typeToSearchFor)
847                 return allBucketExtend[i];
848         }
849         return null;
850     }
851 
852 
853    /**
854     *   Return the BucketExtendData of the bucket matching a given label
855     */
856     ServerBucketExtendData findNormalBucket(String sBucketLabel) {
857 
858         for (int i=0; i<allBucketExtend.length; i++) {
859             if (sBucketLabel.equals(allBucketExtend[i].getLabel()) == true)
860                 return allBucketExtend[i];
861         }
862         return null;
863     }
864 
865 
866    /**
867     *
868     */
869    private long getSequence()
870    {
871       long nAssetId = -1;
872       try
873       {
874          if ( seqGateway == null )
875          {
876             seqGateway = new SequenceGateway();
877             seqGateway.connect();
878          }
879          nAssetId = seqGateway.getSequence( SequenceConstantsI.ASSET_ID, "ALL_ASSET_RECORD", "ASSET_ID" );
880          //Diagnostic.trace(Diagnostic.APPSERVER_IMPORT, "####### Sequence number is " + nAssetId);
881       }
882       catch(TransactionFailedException rtfe) {}
883       return nAssetId;
884    }
885 
886 
887   /**
888   *
889   *
890   */
891   protected String getBucketLabel(String sTemp) {
892     String sBucket = "";
893 
894     int nComma = sTemp.indexOf(",");
895     if (nComma > 0) {
896       sBucket = sTemp.substring(0, nComma);
897     }
898     return sBucket.trim();
899   } // getBucketLabel
900 
901 
902   /**
903   *
904   *
905   */
906   protected String getFieldLabel(String sTemp) {
907     String sField = "";
908 
909     int nComma = sTemp.indexOf(",");
910     if (nComma > 0) {
911       sField = sTemp.substring(nComma + 1);
912     }
913     return sField.trim();
914   } // getFieldLabel
915 
916 
917   /**
918   *
919   *
920   */
921   protected DisguiseBucketRecordData checkForExisting(DisguiseBucketRecordData refBucket,
922                                                         DisguiseBucketRecordData tmpBucket) {
923 
924         // We need to scan our existing buckets before creating a new bucket 
925         // If refBucket is null we should scan the top level
926         // Otherwise, we'll scan our existing one.
927         DisguiseBucketRecordData [] existingBuckets = null;
928         if (refBucket == null) {
929             existingBuckets = refDisguiseRecord.getBuckets();
930         } else {
931             existingBuckets = refBucket.getBuckets();
932         }
933 
934         // if existingBuckets is null, then we have no buckets
935         // in our refBucket and won't need to scan through them.
936         // if it's not null, then we have to scan.  Begin scan.
937         if (existingBuckets != null) {
938 
939             DisguiseFieldRecordData [] scanFieldValues = null;
940             DisguiseFieldRecordData [] tmpBucketFieldValues = null;
941 
942             // fetch the values from our existing bucket
943             tmpBucketFieldValues = tmpBucket.getValues();
944 
945             // scan through the buckets.  If we find an existing bucket
946             // whose values match our tmpBucket, we'll return the existing
947             // bucket.  If we do not find a matching existing bucket, we'll
948             // continue through and attach our tmpBucket to the parent.
949             for (int i=0; i < existingBuckets.length; i++) {
950                 //System.out.println("BGP: scanning an existing bucket");
951                 scanFieldValues = existingBuckets[i].getValues();
952                 // JFSA, let's make sure all the fields match before we declare a match
953                 int numFieldsThatMatch = 0;
954                 for (int j=0; j < tmpBucketFieldValues.length; j++) {
955                     // do our field values match?
956                     if (tmpBucketFieldValues[j].getValue().equals(  scanFieldValues[j].getValue()  )) {
957                         numFieldsThatMatch++;
958                         //System.out.println("BGP:   **** match " + numFieldsThatMatch + "/" + tmpBucketFieldValues.length);
959                     }
960                 }
961                 if (numFieldsThatMatch == tmpBucketFieldValues.length) {
962                     //System.out.println("BGP:   **** all fields matched - return existing. ");
963                     return existingBuckets[i];
964                 } 
965             }
966             //System.out.println("BGP: there were some existing buckets in this batch");
967             //System.out.println("BGP:   but the fields did not match.  return (new) tmpBucket");
968         } /*else {
969             System.out.println("BGP:  There were no existing buckets");
970         }*/
971         return tmpBucket;
972     } // END OF checkForExisting
973 }
974