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/XMLService.java


1   /*
2    * XMLService.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.io.File;
14  import java.io.IOException;
15  import java.util.Date;
16  import java.util.Enumeration;
17  import java.util.Hashtable;
18  import java.util.Vector;
19  
20  import org.apache.xerces.parsers.DOMParser;
21  import org.w3c.dom.Document;
22  import org.w3c.dom.Node;
23  import org.w3c.dom.NodeList;
24  import org.xml.sax.SAXException;
25  
26  import com.flexstor.common.constants.BucketConstantsI;
27  import com.flexstor.common.constants.SequenceConstantsI;
28  import com.flexstor.common.data.ActionData;
29  import com.flexstor.common.data.ActionResult;
30  import com.flexstor.common.data.ejb.disguiserecord.AssetRoleData;
31  import com.flexstor.common.data.ejb.disguiserecord.DisguiseAssetRecordData;
32  import com.flexstor.common.data.ejb.disguiserecord.DisguiseBucketRecordData;
33  import com.flexstor.common.data.ejb.disguiserecord.DisguiseElementRecordData;
34  import com.flexstor.common.data.ejb.disguiserecord.DisguiseRecordData;
35  import com.flexstor.common.data.ejb.disguiserecord.HighresRoleData;
36  import com.flexstor.common.data.ejb.disguiserecord.ThumbnailRoleData;
37  import com.flexstor.common.errorlogger.FlexError;
38  import com.flexstor.common.gateway.SequenceGateway;
39  import com.flexstor.common.gateway.exceptions.TransactionFailedException;
40  import com.flexstor.common.importprocessor.ImportCtlData;
41  import com.flexstor.common.importprocessor.ImportData;
42  import com.flexstor.common.importprocessor.ImportResult;
43  import com.flexstor.common.services.ServiceArgumentsI;
44  import com.flexstor.common.util.Diagnostic;
45  import com.flexstor.common.util.DiagnosticBase;
46  import com.flexstor.ejb.bucket.persist.ServerBucketExtendData;
47  import com.flexstor.ejb.disguise.persist.ServerDisguiseExtendData;
48  import com.flexstor.ejb.field.persist.ServerFieldExtendData;
49  import com.flexstor.flexdbserver.disguise.DisguiseLoader;
50  import com.flexstor.flexdbserver.services.Service;
51  import com.flexstor.flexdbserver.services.ServiceContext;
52  
53  
54  /**
55   * <P>
56   * BookXMLService <BR>
57   * <BLOCKQUOTE>
58   *    Creates an Import Data object from an XML file.  This service wound up being
59   *    fairly customer specific and should probably be deprecated.  The more general
60   *    XML asset creation service, which should be used in favor of this one, is the
61   *    XMLActionDataService.
62   * </BLOCKQUOTE>
63   * </P>
64   *
65   * <P>
66   * Configurable Properties in services.config <BR>
67   * <BLOCKQUOTE>
68   *    None
69   * </BLOCKQUOTE>
70   * </P>
71   *
72   * <P>
73   * Configurable Properties in Hot Directory Control File <BR>
74   * <BLOCKQUOTE>
75   *    FieldToSplitForSLF: If the value is booktechGenerate, the value for the server
76   *        is set to be the same as the server value where the XML file resides; the
77   *        location is generated by appending a number (based on the number contained 
78   *        in the file name) to the HighFileListBase from the hotdirectory control file; 
79   *        and the file name is made by appending .pdf onto the system_segment1 XML field.<br>
80   *        Otherwise, if the value is that of an XML tag in the file, the format for
81   *        the data in that tag must be of the form:  http://server/location/filename<br>
82   *    Note: Early August emails from the customer confirmed that the full URL wouldn't be
83   *    provided.  That is why the other process was created. <br>
84   *    Legal values: booktechGenerate or an XML tag in the file<br>
85   * </BLOCKQUOTE>
86   * <BLOCKQUOTE>
87   *    makeXMLTemp: This is used to inform the service if the XML file itself should
88   *    be set to TEMP.
89   *    The default is to set it to TEMP.<br>
90   *    Legal values: N or Y<br>
91   * </BLOCKQUOTE>
92   * </P>
93   *
94   * Configurable Properties in roletype_services.config <BR>
95   *
96   * <!-- THE ACTUAL TABLE:                                                     -->
97   *
98   * <TABLE BORDER="1" CELLPADDING="3" CELLSPACING="3">
99   * <CAPTION ALIGN=TOP>
100  *    <B> In/Out Properties for Assets </B>
101  * </CAPTION>
102  *     <TR>
103  *        <FONT SIZE=+1><B>
104  *        <TH WIDTH="120">Attribute</TH>
105  *                                   <TH WIDTH="30">IN</TH>           <TH WIDTH="30">OUT</TH>          <TH WIDTH="30">Default IN</TH>  <TH WIDTH="30">Default OUT</TH>
106  *        </B></FONT>
107  *     </TR>
108  *     <TR>
109  *        <TH ALIGN=LEFT><FONT SIZE=+1><B>ROLE</B></FONT></TH>
110  *                                   <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> ALL </TD>    <TD ALIGN=CENTER> ALL </TD></TR>
111  *     </TR>
112  *     <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>
113  *     <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>
114  *     <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>
115  *     <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>
116  *     <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>
117  *     <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>
118  *     <TR>
119  *        <TH ALIGN=LEFT><FONT SIZE=+1><B>TYPE</B></FONT></TH>
120  *                                   <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
121  *     </TR>
122  *     <TR>
123  *        <TH ALIGN=LEFT><FONT SIZE=+1><B>FLAG</B></FONT></TH>
124  *     </TR>
125  *     <TR><TH> PARENT </TH>         <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
126  *     <TR><TH> CHLDREN </TH>        <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
127  *     <TR><TH> ALL </TH>            <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
128  *     <TR><TH> TEMP_PARENT </TH>    <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> X </TD></TR>
129  *     <TR><TH> TEMP_CHILDREN </TH>  <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
130  *     <TR><TH> TEMP_ALL </TH>       <TD ALIGN=CENTER> X </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD>    <TD ALIGN=CENTER> &nbsp </TD></TR>
131  * </TABLE>
132  *
133  * <P>
134  *
135  * More Configurable Properties in roletype_services.config
136  * <BLOCKQUOTE>
137  * <P>
138  *  rlocation<I>X</I>: The "real" location. Numerous settings can be used. Start with X=0.<BR>
139  * </P>
140  * <P>
141  *  vlocation<I>X</I>: The "virtual" location to use in place of the "real" location.  <BR>
142  * </P>
143  * <P>
144  *  rserver<I>X</I>:  The "real" server.  Numerous settings can be used.  Start with X=0.<BR>
145  * </P>
146  * <P>
147  *  vserver<I>X</I>: The "virtual" server to use in place of the "real" server. <BR>
148  * </P>
149  * </BLOCKQUOTE>
150  *
151  * <P>
152  * Input Data Object <BR>
153  * <BLOCKQUOTE>
154  *    com.flexstor.common.importprocessor.ImportData
155  * </BLOCKQUOTE>
156  * </P>
157  *
158  * <P>
159  * Output Data Object <BR>
160  * <BLOCKQUOTE>
161  *    com.flexstor.common.importprocessor.ImportResult
162  * </BLOCKQUOTE>
163  * </P>
164  *
165  */
166 public class XMLService
167    implements Service
168 {
169 
170   protected Hashtable servers = new Hashtable();
171   protected Hashtable locations = new Hashtable();
172 
173   // Used for logging errors
174   public  final static String       IDENTIFIER = "$Id: XMLService.java,v 1.4 2003/08/11 02:22:29 aleric Exp $"; 
175   private String  sThisService = "XMLService";
176   protected ServiceContext context;
177   
178   String sRoleOut = null;
179   String sTypeOut = null;
180   String sFlagOut = null;
181 
182   // The data object
183   private ImportData                 refImportData     = null;
184   private ServerDisguiseExtendData   myServDisgExtend  = null;
185   private DisguiseRecordData         refDisguiseRecord = null;
186   private DisguiseBucketRecordData   refCurrentBucket  = null;
187   private ServerBucketExtendData []  allBucketExtend   = null;
188 
189   private SequenceGateway            seqGateway        = null;
190 
191   private static String sDisguise = new String();
192 
193   private static String sServerLocationFilename = null;
194 
195   // asset level info to be used when creating assets
196   private static Date   receivedDate = null;
197   private static String ctlUserId = null;
198   private static String sOurServer = null;
199   private static String sHighFileListBase = null;
200 
201   protected boolean  shouldMakeXMLTemp  = true;
202   protected boolean  bMajorFailure    = false;
203   protected boolean  bThisIsJitem    = false;
204 
205   protected boolean  successful  = true;
206   
207   /**
208    * Calls before the service is initialized (before initData is called) to 
209    * pass information about the environment in which the service is running.
210    * This environment consists of information about the properties set for the
211    * service in one of these files (services.config, roletype_services.config,
212    * or *.ctl), plus methods to access other information such as an instance
213    * of the service broker to invoke other services, the transaction id for
214    * the service, file separator character and local path for the installation
215    * directory and configuration directory.
216    * 
217    * @param context Holds information about the environment in which the service
218    *                is running.
219    */
220   public void setServiceContext( ServiceContext context )
221   {
222      this.context = context;
223   }
224 
225    /**
226     * Data initialization method called at the beginning of the service.
227     *
228     * @param Action is the super class of the data wrapper object
229     *        which contains all the information for executing the service.
230     */
231     public void initData( ActionData actionData )
232     {
233   refImportData = (ImportData) actionData;
234 
235   //  Get some info from the .ctl file.  This should all be in the refImportData 
236   ImportCtlData refCtlData = refImportData.getCtlDataRef();
237   sDisguise = refCtlData.getValuePerKey("application name");
238 
239   ctlUserId = refCtlData.getValuePerKey("userid");
240 
241   sServerLocationFilename = refCtlData.getValuePerKey("FieldToSplitForSLF");
242   sHighFileListBase = refCtlData.getValuePerKey("highfilelistbase");
243 
244   for ( int i = 0;; i++ )
245   {
246       if ( context.getProperty( "rlocation" + i ) != null )
247       {
248     if ( context.getProperty( "vlocation" + i ) != null )
249              locations.put( context.getProperty( "rlocation" + i ), context.getProperty( "vlocation" + i ) );
250       }
251       else
252     break;
253   }
254 
255   for ( int i = 0;; i++ )
256   {
257       if ( context.getProperty( "rserver" + i ) != null )
258       {
259     if ( context.getProperty( "vserver" + i ) != null )
260              servers.put( context.getProperty( "rserver" + i ), context.getProperty( "vserver" + i ) );
261       }
262       else
263     break;
264   }
265 
266   String sXMLTemp = refCtlData.getValuePerKey("makeXMLTemp").toUpperCase();
267 
268   if (sXMLTemp.equals("N")) {
269       shouldMakeXMLTemp  = false;
270   } else {
271       shouldMakeXMLTemp  = true;
272   }
273     }
274 
275 
276 
277    /**
278     * Start of the  Service
279     *
280     * @return a Result object with an updated data object.
281     */
282    public ActionResult go()
283    {
284       DisguiseAssetRecordData aXMLFileAsset = null;
285 
286       BGPDebug("XMLService Started");
287 
288       successful = true;
289 
290       // get the input assets, according to the role, type and flag specified
291       // in remote_server.config or TypeServiceDat.config
292       String sRoleIn = context.getProperty(ServiceArgumentsI.ROLE_DATA_SOURCE);
293       String sTypeIn = context.getProperty(ServiceArgumentsI.TYPE_DATA_SOURCE);
294       String sFlagIn = context.getProperty(ServiceArgumentsI.FLAG_DATA_SOURCE);
295 
296       BGPDebug("XML:Role(in) = " + sRoleIn);
297       BGPDebug("XML:Type(in) = " + sTypeIn);
298       BGPDebug("XML:Flag(in) = " + sFlagIn);
299 
300       sRoleOut = context.getProperty(ServiceArgumentsI.ROLE_DATA_DESTINATION);
301       sTypeOut = context.getProperty(ServiceArgumentsI.TYPE_DATA_DESTINATION);
302       sFlagOut = context.getProperty(ServiceArgumentsI.FLAG_DATA_DESTINATION);
303 
304       BGPDebug("XML:Role(out) = " + sRoleOut);
305       BGPDebug("XML:Type(out) = " + sTypeOut);
306       BGPDebug("XML:Flag(out) = " + sFlagOut);
307 
308 
309 
310       ImportResult result = null;
311 
312       if( refImportData == null )
313       {
314           result = new ImportResult(false);
315           return result;
316       }
317 
318       // Get the reference to the DisguiseRecordData
319       refDisguiseRecord = refImportData.getDisguiseRecordRef();
320       if( refDisguiseRecord == null ) {
321           successful = false;
322       }
323 
324 
325       try {
326           myServDisgExtend = DisguiseLoader.getDisguise(sDisguise);
327       }
328       catch (Exception e) {
329           BGPDebug("Exception getting disguise: " + e);
330           e.printStackTrace();
331       }
332 
333 
334       // This is a vector of ServerBucketExtendData Objects  (all our buckets)
335       Vector myBucketDataObjects = myServDisgExtend.getBucketDataObjects();
336 
337       // I'd like an array of SBEDs for all buckets, please.
338       allBucketExtend = new ServerBucketExtendData[myBucketDataObjects.size()];
339 
340       for (int i=0; i<allBucketExtend.length; i++) {
341           allBucketExtend[i] = (ServerBucketExtendData) myBucketDataObjects.elementAt(i);
342       }
343 
344       Vector vAssetsIn = null;
345       if( sRoleIn==null || sTypeIn==null || sFlagIn==null )
346       {
347           successful = false;
348       }
349       else
350       {
351           vAssetsIn = refDisguiseRecord.getAssets(sRoleIn, sTypeIn, sFlagIn);
352           if( vAssetsIn != null )
353           {
354               Enumeration assets = vAssetsIn.elements();
355 
356               // Process each asset in each element in ImportData
357               while(assets.hasMoreElements())
358               {
359                   aXMLFileAsset = (DisguiseAssetRecordData)assets.nextElement();
360 
361                   String assetFileName =  aXMLFileAsset.getFileName();
362                   String fullPathName = "/" + aXMLFileAsset.getLocation() + assetFileName;
363                   BGPDebug("An asset is found: "+fullPathName);
364 
365                   receivedDate = aXMLFileAsset.getReceived();
366                   sOurServer = aXMLFileAsset.getServer();
367 
368       // if we set the XML file to be temp, it won't import and we can DeleteTEMP it
369       if (shouldMakeXMLTemp == true) {
370                       BGPDebug("the XML file will be set to temp");
371           // the XML file should be a TEMP_PARENT  (ADD something to the .ctl file to
372           //          determine if we should set temp...)
373                       AssetRoleData theAssetRole = aXMLFileAsset.getAssetRole();
374                       theAssetRole.setTempRole(true);
375                       aXMLFileAsset.setAssetRole(theAssetRole);
376                   } // else it will import.
377 
378                   try
379                   {
380                 // reset this to 0 for each document I parse
381                 iLevel = 0;
382                 iPrevLevel = 0;
383                 iPrevType = 0;
384                 sPrevValue = null;
385                 iPrimaryParentLevel = 0;
386 
387                 // variables should be initialized to default values before
388                 // each XML file is parsed.
389           bThisIsJitem = false;
390 
391                       parseXMLfile(fullPathName);
392                       // if we had a major failure we were not successful
393                       if (bMajorFailure == true)
394                           successful = false;
395                       else
396                           successful = true;
397                   }
398                   catch (Exception e)
399                   {
400                       BGPDebug("Exception parsing XML file: " + e);
401                       e.printStackTrace();
402                       successful = false;
403                   }
404               }
405           }
406           else
407               successful = false;
408 
409       }
410 
411 
412 
413 
414       BGPDebug("Done with XML service");
415 
416       if( successful == false )
417       {
418           result = new ImportResult(false);
419       } else {
420           result = new ImportResult(true);
421           result.setImportData(refImportData);
422       }
423 
424       return result;
425    }
426 
427 
428 
429 
430 
431   /* 
432    *   parseXMLfile - 
433    */
434    private void parseXMLfile(String pathToFile) throws IOException, SAXException
435    {
436   DOMParser parser = new DOMParser();
437   //InputSource inSource = new InputSource(new FileReader(pathToFile));
438   parser.parse(pathToFile);
439   Document document = parser.getDocument();
440 
441   XMLprocess(document);
442 
443 
444         return;
445    }
446 
447 
448 
449 
450   /* 
451    *   I want to keep these variables close to where I use them
452    *   so I can remember their names.  After a while they can be
453    *   moved back to the top.
454    */
455    static String sCurrentTag = null;
456    static String sPreviousTag = null;
457    static int iLevel = 0;
458    static int iEntries = 0;
459    static int iNormalBuckets = 0;
460    static int iAssets = 0;
461    static boolean bDefViewDone = false;
462 
463    static int iPrimaryParentLevel = 0;
464    static int iPreviousTagLevel = 0;
465 
466    static Hashtable dataHash = new Hashtable();
467 
468    static DisguiseAssetRecordData [] assetArray = new DisguiseAssetRecordData[30];
469    static DisguiseElementRecordData refElement = null;
470 
471    static int iPrevLevel = 0;
472    static int iPrevType = 0;
473    static String sPrevValue = null;
474 
475 
476   /* 
477    *   XMLprocess - 
478    */
479    private void XMLprocess(Node node) 
480    {
481 
482   if (node == null) return;
483 
484   iLevel++;
485 
486   int iCurrType = node.getNodeType();
487   String sCurrVal = node.getNodeValue();
488 
489   // If the current type equals the previous type  AND  
490   //    the current level equals the previous level
491   // Then we're looking at special character handling so start appending.
492   if ((iCurrType == iPrevType) && (iPrevLevel == iLevel)) {
493       //BGPDebug("      Previous and Current types AND levels match.  Perhaps a '&' or '<'.");
494       //BGPDebug("     sCurrVal is "+sCurrVal);
495       sCurrVal = sPrevValue.concat(sCurrVal);
496       //BGPDebug("     new sCurrVal is "+sCurrVal);
497   }
498   iPrevLevel = iLevel;
499   iPrevType = iCurrType;
500   sPrevValue = sCurrVal;
501 
502   switch(iCurrType) {
503             case Node.DOCUMENT_NODE: 
504             {
505                 XMLprocess(((Document)node).getDocumentElement());
506                 // That's it, i think we're done
507                 //BGPDebug("  DOCUMENT_NODE ["+node.getNodeName()+"] found");
508                 break;
509             }
510       case Node.ELEMENT_NODE:
511       {
512     String sNodeName = node.getNodeName();
513                 sCurrentTag = sNodeName;
514 
515                 if (!sNodeName.equals("page"))
516                 {
517                     sCurrentTag = sNodeName;
518                     //BGPDebug(" xmlelement node [" + sNodeName + "]");
519                 }
520 
521 
522                 if (sNodeName.equals("entry"))
523     {
524               if (iEntries > 0) {
525                   BGPDebug(" !!!!!  This is not our first entry!");
526                   // handle it!
527               }
528               iEntries++;
529            iNormalBuckets = 0;
530            iAssets = 0;
531                 }
532     else if (sNodeName.equals("normal") || sNodeName.equals("element"))
533     {
534         // The first time we encounter "normal" we'll be starting our
535         // first bucket.  Don't bother to do much yet.
536 
537         // If we just finished our first bucket, we are at the
538         // top level and will need to add our recently gathered
539         // data to refDisguiseRecord via an addBucket call.
540               if (iNormalBuckets == 1)
541         {
542                     BGPDebug(" ---- adding first bucket");
543                     refCurrentBucket = createBucket();
544                     refDisguiseRecord.addBucket(refCurrentBucket);
545         }
546         // otherwise we've just finished an additional bucket
547         // and we should process what we just gathered
548         else if (iNormalBuckets > 1)
549         {
550                     BGPDebug(" ---- adding child bucket");
551                   DisguiseBucketRecordData prevBucket = refCurrentBucket;
552                   refCurrentBucket = createBucket();
553                     prevBucket.addBucketChild(refCurrentBucket);
554         }
555 
556               iNormalBuckets++;
557               dataHash.clear();
558                 }
559     else if (sNodeName.equals("asset"))
560     {
561               if (iNormalBuckets == 1)
562         {
563                     BGPDebug(" ---- adding first bucket because there was only one!");
564                     refCurrentBucket = createBucket();
565                     refDisguiseRecord.addBucket(refCurrentBucket);
566         }
567 
568                 BGPDebug(" ---- adding element");
569         // we just finished the element (or it is possible that there was
570         // no element); so create it and add it to latest bucket.
571               refElement = createElement();
572         refElement.setRecordId(getSequence());
573                 refCurrentBucket.addElement(refElement);
574               dataHash.clear();
575                 }
576     else if (sNodeName.equals("primary_parent"))
577     {
578               iAssets++;
579 
580                 BGPDebug("  asset(pp) is " + sNodeName );
581                 // There must only be one primary parent
582         iPrimaryParentLevel = iLevel;
583                 }
584     else if (sNodeName.equals("parent") || sNodeName.equals("default"))
585     {
586                 //BGPDebug(" level #"+iLevel+" is <"+sNodeName+">");
587               if (iAssets == 1)         // we just finished our primary parent
588         {
589                     BGPDebug(" ---- adding primary parent");
590                assetArray[iPrimaryParentLevel] = createAsset(sPreviousTag);
591                     //BGPDebug("    - attach directly to the refElement");
592                refElement.setParentAsset(assetArray[iPrimaryParentLevel]);
593         }
594         // otherwise we've just finished an additional parent/default
595         // and we should process what we previously gathered
596         else if (iAssets > 1)
597         {
598             // we're done with an asset (either parent or default)
599                     BGPDebug(" ---- done with a "+sPreviousTag);
600                     // BGPDebug("    - belongs on #"+iPreviousTagLevel+
601         //    " and attaches to #"+(iPreviousTagLevel-1));
602             // Create it (this will also fill it with data)
603                assetArray[iPreviousTagLevel] = createAsset(sPreviousTag);
604             // Attach it to its parent
605                assetArray[iPreviousTagLevel-1].addChildAsset(assetArray[iPreviousTagLevel]);
606         }
607 
608               iAssets++;
609               dataHash.clear();
610 
611                     sPreviousTag = sCurrentTag;
612                     iPreviousTagLevel = iLevel;
613                 }
614     else // we must have found a data tag
615     {
616                 // BGPDebug("  sNodeName is " + sNodeName );
617                     sCurrentTag = sNodeName;
618                 }
619 
620 
621     // Process the kids.
622                 NodeList children = node.getChildNodes();
623                 if( children!=null )
624                 {
625                     int length = children.getLength();
626                     for(int i=0;i<length;i++)
627                     {
628                     //BGPDebug(" :: GOING to process child "+(i+1)+" of "+length);
629                         XMLprocess(children.item(i));
630                     //BGPDebug(" :: DONE processing child "+i+" at level "+iLevel);
631                   iLevel--;
632                     }
633                 }
634 
635 
636     // We have to remember to process the last asset
637     if (iPrimaryParentLevel == iLevel) {
638                 if (sPreviousTag == null) {
639                     // if we have no previous tag, this is the primary parent
640                     BGPDebug(" ---- (lastly) adding primary parent");
641                assetArray[iPrimaryParentLevel] = createAsset(sPreviousTag);
642                     BGPDebug("    - attach directly to the refElement");
643                refElement.setParentAsset(assetArray[iPrimaryParentLevel]);
644            } else {
645                     // otherwise we've already done the primary parent
646                     BGPDebug(" ---- (lastly) done with a "+sPreviousTag);
647                     //BGPDebug("    - belongs on #"+iPreviousTagLevel+
648         //        " and attaches to #"+(iPreviousTagLevel-1));
649             // Create it (this will also fill it with data)
650                assetArray[iPreviousTagLevel] = createAsset(sPreviousTag);
651             // Attach it to its parent
652                assetArray[iPreviousTagLevel-1].addChildAsset(assetArray[iPreviousTagLevel]);
653            }
654     }
655 
656                 break;
657       }
658              case Node.TEXT_NODE:
659              {
660     // We'll trim() off the whitespace at the beginning and end.
661                 String value = sCurrVal.trim();
662     // and that may leave us with an empty string, but such is life.
663                 if(!value.equals(""))
664                 {
665                     //BGPDebug("Text found for "+sCurrentTag+",value ["+value+"]");
666 
667         // put the data into our hashtable
668               dataHash.put(sCurrentTag,value);
669                 }
670           break; 
671       }
672       case Node.ATTRIBUTE_NODE:
673       case Node.CDATA_SECTION_NODE:
674       case Node.COMMENT_NODE:
675       case Node.DOCUMENT_FRAGMENT_NODE:
676       case Node.DOCUMENT_TYPE_NODE:
677             case Node.ENTITY_NODE: 
678             case Node.ENTITY_REFERENCE_NODE: 
679       case Node.NOTATION_NODE:
680       case Node.PROCESSING_INSTRUCTION_NODE:
681       {
682                 BGPDebug("  ignored case.");    
683           break; 
684       }
685              default:
686       {
687                 BGPDebug("  Unanticipated case.");    
688           break; 
689       }
690   }
691    }
692 
693 
694 
695   /* 
696    *   createBucket()
697    */
698    DisguiseBucketRecordData createBucket()
699    {
700   //BGPDebug(" >>>> Create a bucket");
701 
702   DisguiseBucketRecordData  tmpBucket = new DisguiseBucketRecordData();
703   ServerFieldExtendData    tmpSFED   = null;
704   String        sTmpLabel = null;
705   String        sTmpValue = null;
706 
707   // We need the bucket label in order to retrieve extend info.
708   //   precondition: the hashtable must not be empty
709   //                 because we wouldn't know what bucket to create
710 
711   String sBucketLabel = (String) dataHash.keys().nextElement();
712         // How about some error checking for indexOf? what if there's no '.'?
713   sBucketLabel = sBucketLabel.substring(0,(sBucketLabel.indexOf('.')));
714   
715   // Retrieve the extend info for this bucket
716   ServerBucketExtendData refExtendBucket = findBucket(sBucketLabel);
717 
718         Vector  vExtendFields = refExtendBucket.getFieldDataObjects();
719 
720   // bucket id is necessary
721   tmpBucket.setBucketStructId(refExtendBucket.getId());
722 
723   // fill in the field data
724   for (int i=0; i<vExtendFields.size(); i++) {
725       tmpSFED = (ServerFieldExtendData) vExtendFields.elementAt(i);
726       sTmpLabel = tmpSFED.getLabel();
727       //BGPDebug("  . . . field label for "+sBucketLabel+" is "+sTmpLabel);
728 
729       // The XML has the Bucket name and a period preceding
730       // the Field name, so we need to fix it up. (Also fix Spaces)
731       sTmpLabel = sBucketLabel + "." + spaceToSpecial(sTmpLabel);
732 
733       // fetch the value from the hashtable
734       sTmpValue = (String) dataHash.get(sTmpLabel);
735       if (sTmpValue == null) {
736     tmpBucket.addValue("");
737       } else {
738     tmpBucket.addValue(sTmpValue);
739           BGPDebug("     + "+tmpSFED.getLabel()+" is >"+sTmpValue+"<");
740       }
741   }
742   printHashtable(dataHash,"Bucket");
743 
744   return tmpBucket;
745    }
746 
747   /* 
748    *   createElement()
749    */
750    DisguiseElementRecordData createElement()
751    {
752   //BGPDebug(" >>>> Create an element");
753 
754   DisguiseElementRecordData  tmpElement = new DisguiseElementRecordData();
755   ServerFieldExtendData         tmpSFED   = null;
756   String                          sTmpLabel = null;
757   String                          sTmpValue = null;
758 
759   ServerBucketExtendData refExtendBucket = findBucket(BucketConstantsI.ELEMENT_BUCKET);
760 
761   Vector  vExtendFields = refExtendBucket.getFieldDataObjects();
762 
763   // bucket id is necessary
764   tmpElement.setBucketStructId(refExtendBucket.getId());
765 
766   // if there is no element data, don't bother filling in the fields.
767   if (!dataHash.isEmpty()) {
768       // fill in the field data
769       for (int i=0; i<vExtendFields.size(); i++) {
770           tmpSFED = (ServerFieldExtendData) vExtendFields.elementAt(i);
771           sTmpLabel = tmpSFED.getLabel();
772           //BGPDebug("  . . . field label for ELEMENT is "+sTmpLabel);
773 
774     // The XML has the Bucket name and a period preceding
775     // the Field name, so we need to fix it up. (Also fix Spaces)
776           sTmpLabel = "ELEMENT." + spaceToSpecial(sTmpLabel);
777 
778     // fetch the value from the hashtable
779     sTmpValue = (String) dataHash.get(sTmpLabel);
780     if (sTmpValue == null) {
781         tmpElement.addValue("");
782     } else {
783         tmpElement.addValue(sTmpValue);
784         BGPDebug("     + "+tmpSFED.getLabel()+" is >"+sTmpValue+"<");
785     }
786       }
787   }
788   //printHashtable(dataHash,"Element");
789 
790   return tmpElement;
791    }
792 
793   /* 
794    *   createAsset(parent_or_default)
795    *  The "sAssetRole" fed into this createAsset() is not a true AssetRoleData
796    *    it is merely a string "parent" or "default" used as an XML tag and interpreted
797    *  as either a highres or thumbnail
798    */
799    DisguiseAssetRecordData createAsset(String sAssetRole)
800    {
801   //BGPDebug(" >>>> Create an asset ; role is "+sAssetRole);
802 
803   DisguiseAssetRecordData  tmpAsset = new DisguiseAssetRecordData();
804   ServerFieldExtendData    tmpSFED = null;
805   String        sTmpLabel = null;
806   String        sRealLabel = null;
807   String        sTmpValue = null;
808 
809 
810   ServerBucketExtendData refExtendBucket = findBucket(BucketConstantsI.ASSET_BUCKET);
811 
812   Vector  vExtendFields = refExtendBucket.getFieldDataObjects();
813 
814   // the bucketstruct id is necessary
815   tmpAsset.setBucketStructId(refExtendBucket.getId());
816 
817   tmpAsset.setReceived(receivedDate);
818   tmpAsset.setUserId(ctlUserId);
819 
820   // If we were not told what kind of asset this is, it must
821   // be the first one and we will declare it a parent (highres).
822   if (sAssetRole == null) sAssetRole = new String("parent");
823 
824   // a "parent" is a highres; a "default" is a thumbnail
825   if (sAssetRole.equals("parent")) {
826       //BGPDebug("    This is a parent.  Set role to Highres.");
827       tmpAsset.setAssetRole(new HighresRoleData());
828       tmpAsset.setAssetFileType(sTypeOut);
829   } else if (sAssetRole.equals("default")) {
830       BGPDebug("    This is a default.  Set role to Thumbnail.");
831       tmpAsset.setAssetRole(new ThumbnailRoleData());
832       // Check if we have set a Default View before.  If so, don't set it again.
833       if (!bDefViewDone) {
834           tmpAsset.setDefaultView(true);
835           bDefViewDone = true;
836       }
837   } else {
838       BGPDebug("Untold type of asset role (parent/default/etc).  This is not right.");
839   }
840 
841   // if this is a J-item, the children (which represent A-items) should be TEMP.
842         // (this won't change the actual J-item PDF file because the bThisIsJitem variable
843         // is set after this is checked.
844   if (bThisIsJitem == true) {
845       BGPDebug("  ::::::: next assets listed are part of a J-item");
846   /*
847       AssetRoleData theAssetRole = tmpAsset.getAssetRole();
848       theAssetRole.setTempRole(true);
849       tmpAsset.setAssetRole(theAssetRole);
850   */
851   }
852 
853   // if there is no asset data then it'll be hard to create a meaningful asset
854   //  (we should probably drop an error
855   if (dataHash.isEmpty()) {
856       BGPDebug("An empty XML asset was found.  This is probably not good.");
857   } else {
858       // fill in the field data
859       for (int i=0; i<vExtendFields.size(); i++) {
860     tmpSFED = (ServerFieldExtendData) vExtendFields.elementAt(i);
861     sRealLabel = tmpSFED.getLabel();
862     //BGPDebug("  . . . field label for ASSET is "+sTmpLabel);
863 
864     // The XML has the Bucket name and a period preceding
865     // the Field name, so we need to fix it up. (Also fix Spaces)
866     sTmpLabel = "ASSET." + spaceToSpecial(sRealLabel);
867 
868     // fetch the value from the hashtable
869     sTmpValue = (String) dataHash.get(sTmpLabel);
870     if (sTmpValue == null) {
871         //tmpAsset.addValue("");
872         // if a user-defined field has been left blank, I should put an
873         // empty string into the hashtable. (Don't bother with system fields)
874         if (!tmpSFED.isSystemRequired()) {
875       if (sRealLabel.indexOf(" ") == -1) {
876           //BGPDebug(sTmpLabel + " must be a user field.");
877           dataHash.put(sTmpLabel,"");
878                 tmpAsset.addUserData(sRealLabel,"");
879       }// else {
880        //   BGPDebug("["+sTmpLabel + "] has a space in it! skip.");
881        //}
882         }
883     } else {
884         tmpAsset.addValue(sTmpValue);
885         dataHash.put(sTmpLabel,sTmpValue);
886         tmpAsset.addUserData(sRealLabel,sTmpValue);
887         BGPDebug("adding user data("+sRealLabel+"==="+sTmpValue+")");
888         //BGPDebug("     + "+tmpSFED.getLabel()+" is >"+sTmpValue+"<");
889     }
890       }
891   }
892 
893 
894   // We need to handle the SERVER/location/filename
895   // if it has been placed in a URL format.
896 
897         if (sServerLocationFilename.length() == 0) {
898             BGPDebug("     * SLF is empty");
899         } else {
900       BGPDebug("     * SLF is "+sServerLocationFilename);
901       if (sServerLocationFilename.equals("booktechGenerate")) {
902           // Then we need to generate the server, location, and filename
903 
904     // for server: use the server info from whatever server we got the XML file
905                 tmpAsset.setServer(sOurServer);
906     BGPDebug("the server is now: " + tmpAsset.getServer());
907 
908     // for filename: use system_segment1 with ".pdf" appended
909     String sFileGuess = ((String)dataHash.get("ASSET.system_segment1")) + ".pdf";
910           tmpAsset.setFileName(sFileGuess);
911     BGPDebug("the filename is now: " + tmpAsset.getFileName());
912 
913     // for location: compute the "numbered directory" for the A-item number
914     //    and append it to the sHighFileListBase
915     String sLocationGuess = (String)dataHash.get("ASSET.system_segment1");
916     // check to make sure we didn't get a null or a zero length string
917     if ( (sLocationGuess == null) || (sLocationGuess.length() == 0) ) {
918         BGPDebug("!unable to generate numbered directory!");
919         bMajorFailure = true;
920     } else {
921         sLocationGuess = sLocationGuess.substring(1);
922         // Mail message from Mike Perera on Fri, 4 Aug 2000 gives formula as:
923         //     0-1000 = subdirectory 1
924         //     1001-2000 = 2
925         //     2001-3000 = 3
926         //     3001-4000 = 4
927         // which gets turned into (((Number - 1) / 1000) + 1)
928         int numberedDirectory = ((int)((Integer.parseInt(sLocationGuess) -1) / 1000)) +1;
929         sLocationGuess = sHighFileListBase + String.valueOf(numberedDirectory) + "/";
930         tmpAsset.setLocation(sLocationGuess);
931         BGPDebug("the location is now: " + tmpAsset.getLocation());
932 
933         // If this is a J-item, the file will not exist, so that's okay.
934         if (sFileGuess.startsWith("J")) {
935             // Also, if this is a J-item, the children should be TEMP.
936       bThisIsJitem = true;
937             BGPDebug("This is a J-item");
938         // else this is not a J-item, so the file should actually exist.
939         } else {
940       // test if the file actually exists.  If it doesn't, fail the service.
941       File PDFile = new File("/" + sLocationGuess + sFileGuess);
942       if (!(PDFile.isFile() && PDFile.canRead())) {
943           // If this is not a J-item 
944           BGPDebug("File "+PDFile.getPath()+" doesn't exist or can't be read.");
945           // 6070=File %%1 does not exist or permission (read/write) denied
946           new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6070,
947                 new String[] { PDFile.getPath() } );
948           bMajorFailure = true;
949       } //else carry on.
950         }
951     }
952       } else {
953           sTmpLabel = "ASSET." + spaceToSpecial(sServerLocationFilename);
954           sTmpValue = (String) dataHash.get(sTmpLabel);
955           if (sTmpValue != null) {
956         String sServer = null;
957         String sLocation = null;
958         String sFilename = null;
959     
960         // 07-14-2000  Various emails inform me that the ServerLocationFilename
961         // will be of the form http://SERVER/LOCA/TION/FILENAME
962               sTmpValue = (String) dataHash.get(sTmpLabel);
963                     // Some error checking would be good throughout to make sure it is valid.
964     
965         // strip off the http://
966         if (sTmpValue.startsWith("http://")) {
967             sTmpValue = sTmpValue.substring(7);
968         }
969     
970         // obtain the server
971                     // How about some error checking for indexOf? what if there's no '/'?
972         int iSlashIndex1 = sTmpValue.indexOf("/");
973         sServer = sTmpValue.substring(0,iSlashIndex1);
974               //BGPDebug("     sServer: "+sServer);
975               tmpAsset.setServer(sServer);
976     
977         // obtain the location
978                     // How about some error checking for indexOf? what if there's no '/'?
979         int iSlashIndex2 = sTmpValue.lastIndexOf("/");
980         sLocation = sTmpValue.substring(iSlashIndex1,iSlashIndex2);
981               //BGPDebug("     sLocation: "+sLocation);
982               tmpAsset.setLocation(sLocation);
983     
984         // obtain the filename
985         sFilename = sTmpValue.substring((iSlashIndex2) + 1);
986               //BGPDebug("     sFilename: "+sFilename);
987               tmpAsset.setFileName(sFilename);
988           }
989       }
990   }
991 
992   sTmpLabel = new String("Server");
993   sTmpLabel = "ASSET." + spaceToSpecial(sTmpLabel);
994   sTmpValue = (String) dataHash.get(sTmpLabel);
995   if (sTmpValue != null) {
996       tmpAsset.setServer(sTmpValue);
997   }
998   // We need to handle the server/LOCATION/filename
999   sTmpLabel = new String("Location");
1000  sTmpLabel = "ASSET." + spaceToSpecial(sTmpLabel);
1001  sTmpValue = (String) dataHash.get(sTmpLabel);
1002  if (sTmpValue != null) {
1003      tmpAsset.setLocation(sTmpValue);
1004  }
1005  // We need to handle the server/location/FILENAME
1006  sTmpLabel = new String("File Name");
1007  sTmpLabel = "ASSET." + spaceToSpecial(sTmpLabel);
1008  sTmpValue = (String) dataHash.get(sTmpLabel);
1009  if (sTmpValue != null) {
1010      tmpAsset.setFileName(sTmpValue);
1011  }
1012
1013  //printHashtable(dataHash,"Asset");
1014
1015  return tmpAsset;
1016   }
1017
1018  /* 
1019   *   specialToSpace()
1020   */
1021   String specialToSpace(String sSomeString)
1022   {
1023  return sSomeString.replace('_',' ');
1024   }
1025
1026  /* 
1027   *   spaceToSpecial()
1028   */
1029   String spaceToSpecial(String sSomeString)
1030   {
1031  return sSomeString.replace(' ','_');
1032   }
1033
1034  /* 
1035   *   printHashtable()
1036   */
1037   public void printHashtable(Hashtable hTable, String sLabel)
1038   {
1039       Enumeration dataKeys = hTable.keys();
1040       String keyString;
1041       String valString;
1042
1043  if (hTable.size() > 0) {
1044      while(dataKeys.hasMoreElements()) {
1045          keyString = (String) dataKeys.nextElement();
1046          valString = (String) hTable.get(keyString);
1047          BGPDebug("\t==="+sLabel+"===> " + keyString + " = " + valString);
1048      }
1049  } else {
1050      BGPDebug("\t==="+sLabel+"=== has no data");
1051  }
1052   }
1053
1054
1055   /**
1056    *   Return the BucketExtendData of the bucket matching a given label
1057    */
1058    ServerBucketExtendData findBucket(String sBucketLabel) {
1059
1060        for (int i=0; i<allBucketExtend.length; i++) {
1061            if (sBucketLabel.equalsIgnoreCase(allBucketExtend[i].getLabel()) == true)
1062                return allBucketExtend[i];
1063        }
1064  // if we make it this far, we didn't find a bucket with that label
1065  BGPDebug("Inavlid bucket.  No bucket found with label {"+sBucketLabel+"}");
1066        return null;
1067    }
1068
1069
1070   /**
1071    *   Return the BucketExtendData of the bucket matching a given type
1072    */
1073    ServerBucketExtendData findBucket(int typeToSearchFor) {
1074
1075        for (int i=0; i<allBucketExtend.length; i++) {
1076            if ((allBucketExtend[i].getBucketType()) == typeToSearchFor)
1077                return allBucketExtend[i];
1078        }
1079  // if we make it this far, we didn't find a bucket of that type
1080  BGPDebug("Inavlid bucket.  No bucket found of type {"+typeToSearchFor+"}");
1081        return null;
1082    }
1083
1084
1085  /* 
1086   *   BGPDebug(String of debug text)
1087   */
1088   void BGPDebug(String sSomeString)
1089   {
1090  boolean printMessages = true;
1091  if (printMessages == true) 
1092             Diagnostic.trace(DiagnosticBase.APPSERVER_IMPORT, sSomeString);
1093   }
1094
1095
1096   /*
1097    *   This method originally written by dnickel for booktech service
1098    */
1099    String translateServer( String serv )
1100    {
1101  if ( servers.get( serv ) != null )
1102      return (String)servers.get( serv );
1103
1104  return serv;
1105    }
1106
1107   /*
1108    *   This method originally written by dnickel for booktech service
1109    */
1110    String translateLocation( String loc )
1111    {
1112  Enumeration e = locations.keys();
1113  String rloc = null;
1114
1115  while ( e.hasMoreElements() )
1116  {
1117    rloc = (String)e.nextElement();
1118    if ( loc.startsWith(rloc) )
1119    {
1120       String offsetPath = loc.substring( rloc.length() );
1121       rloc = (String)locations.get( rloc ) + offsetPath;
1122       System.out.println("ERPUpdate: Virtual Location Detected [" + loc + "] >> [" + rloc + "]");
1123       return rloc;
1124    }
1125  }
1126      return loc;
1127    }
1128
1129
1130
1131   /**
1132    *
1133    */
1134   private long getSequence()
1135   {
1136      long nAssetId = -1;
1137      try
1138      {
1139         if ( seqGateway == null )
1140         {
1141            seqGateway = new SequenceGateway();
1142            seqGateway.connect();
1143         }
1144         nAssetId = seqGateway.getSequence( SequenceConstantsI.ASSET_ID, "ALL_ASSET_RECORD", "ASSET_ID" );
1145         //BGPDebug("####### Sequence number is " + nAssetId);
1146      }
1147      catch(TransactionFailedException rtfe) {}
1148      return nAssetId;
1149   }
1150
1151}
1152