View Javadoc

1   /*
2    * Copyright 2008 ATG Import Service Project
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package atg.adapter.gsa.xml;
18  
19  import atg.adapter.gsa.EnumPropertyDescriptor;
20  import atg.adapter.gsa.GSAItemDescriptor;
21  import atg.adapter.gsa.GSAPropertyDescriptor;
22  import atg.adapter.secure.GenericSecuredRepository;
23  import atg.adapter.version.VersionRepository;
24  import atg.adapter.version.VersionUtils;
25  import atg.adapter.version.CurrentVersionItem;
26  import atg.core.util.StringUtils;
27  import atg.deployment.Deployment;
28  import atg.deployment.DeploymentManager;
29  import atg.deployment.DeploymentOptions;
30  import atg.dtm.TransactionDemarcation;
31  import atg.dtm.TransactionDemarcationException;
32  import atg.nucleus.GenericService;
33  import atg.repository.MutableRepository;
34  import atg.repository.MutableRepositoryItem;
35  import atg.repository.Query;
36  import atg.repository.QueryBuilder;
37  import atg.repository.QueryExpression;
38  import atg.repository.Repository;
39  import atg.repository.RepositoryException;
40  import atg.repository.RepositoryItem;
41  import atg.repository.RepositoryItemDescriptor;
42  import atg.repository.RepositoryPropertyDescriptor;
43  import atg.repository.RepositoryView;
44  import atg.repository.SortDirective;
45  import atg.repository.SortDirectives;
46  import atg.repository.dp.DerivedPropertyDescriptor;
47  import atg.epub.ImportService;
48  
49  import java.io.File;
50  import java.io.FileWriter;
51  import java.io.IOException;
52  import java.sql.Timestamp;
53  import java.util.ArrayList;
54  import java.util.Arrays;
55  import java.util.HashMap;
56  import java.util.Iterator;
57  import java.util.List;
58  import java.util.Map;
59  import java.util.Random;
60  import java.util.Set;
61  
62  import javax.transaction.InvalidTransactionException;
63  import javax.transaction.SystemException;
64  import javax.transaction.Transaction;
65  
66  /***
67   * This class is responsible for creating temporary "dummy" item descriptors
68   * that can act as a stand-in for required item properties.
69   */
70  
71  public class ReferenceItemGenerator
72  {
73    private static final String M_REFERENCE_LIST_FILENAME = "ReferenceList.xml";
74    
75    private boolean mLogging = false;
76    private ImportService mImportService;
77    private String mImportDirectory;
78    private FileWriter mReferenceListFileWriter;
79  
80    private Map mRepositoryToItemsMap = new HashMap(11);
81    private int mReferenceIndex = 1;
82  
83    private List mReferenceItemList = new ArrayList();
84    
85    public List getReferenceItemList()
86    {
87      return mReferenceItemList;
88    }
89  
90    File mLogFile;
91    FileWriter mLogFileWriter;
92  
93    public ReferenceItemGenerator (ImportService pImportService)
94    {
95      mImportService = pImportService;
96      mImportDirectory = mImportService.getImportDirectory();
97    }
98  
99    public void initialiseReferenceItemGenerator () throws RepositoryException, IOException
100   {
101     if (mLogging)
102     {
103       createLogFile ();
104     }
105 
106     logMessage ("REFERENCE ITEM GENERATOR: Generating the dummy (non-primary) items");
107     
108     try 
109     {
110       generateDummyItems ();
111     }
112     catch (RepositoryException e)
113     { 
114       throw (e);
115     }
116     catch (IOException e)
117     { 
118       throw (e);
119     }
120   }
121   
122   // -------------------------------------
123   /***
124    * Creates dummy items that will be used as temporary place holders.
125    * 
126    * @return The object used to create dummy items.
127    */
128   
129   public void generateDummyItems () throws RepositoryException, IOException
130   {
131     Repository targetRepository;
132     String targetRepositoryName;
133     String[] targetItemDescriptorNames;
134     RepositoryItemDescriptor targetItemDescriptor;
135     RepositoryPropertyDescriptor[] targetPropertyDescriptors;
136     String targetForeignRepositoryName;
137 
138     TransactionDemarcation transactionDemarcation = new TransactionDemarcation();
139     boolean rollback = false;
140 
141     try
142     {
143       transactionDemarcation.begin (mImportService.getTransactionManager());
144       
145       targetRepository = mImportService.getTargetRepository();
146       
147       targetRepositoryName = targetRepository.getRepositoryName();
148         
149       logMessage ("generateDummyItems: Processing target Repository: " + targetRepositoryName);
150 
151       targetItemDescriptorNames = targetRepository.getItemDescriptorNames();
152       
153       for (int i = 0; i < targetItemDescriptorNames.length; i++)
154       {
155         logMessage ("generateDummyItems: Processing Item Descriptor: " + targetItemDescriptorNames[i]);
156 
157         targetItemDescriptor = targetRepository.getItemDescriptor (targetItemDescriptorNames[i]);
158 
159         if (targetItemDescriptor == null)
160         {
161           throw new RepositoryException ("generateDummyItems: Could not find Item Descriptor");
162         }
163           
164         targetPropertyDescriptors =
165               (RepositoryPropertyDescriptor[]) ((GSAItemDescriptor) targetItemDescriptor).getPropertyDescriptors();
166 
167         logMessage ("generateDummyItems: Item Descriptor: " + targetItemDescriptorNames[i] +
168                                                         " Number of properties: " + targetPropertyDescriptors.length);
169 
170         for (int j = 0; j < targetPropertyDescriptors.length; j++)
171         {
172           if (targetPropertyDescriptors[j].isRequired() &&
173                          VersionUtils.deployable (targetPropertyDescriptors[j], targetItemDescriptor) &&
174                         (RepositoryItem.class.isAssignableFrom(targetPropertyDescriptors[j].getPropertyType())))
175           {
176             targetForeignRepositoryName = ((GenericService) targetPropertyDescriptors[j].getPropertyItemDescriptor().getRepository()).getAbsoluteName();
177  
178             logMessage ("generateDummyItems: Property Descriptor: " + targetItemDescriptorNames[i] +
179                                                                      " Target Repository: " + targetForeignRepositoryName);
180 
181             // print info message for each property that references another repository
182             
183             if (! targetRepositoryName.equals (targetForeignRepositoryName))
184             {
185               logMessage ("generateDummyItems: Reference to a foreign repository found");
186             }
187             
188             logMessage ("generateDummyItems: Finding or creating temp reference item in repository");
189 
190             findDummyReferenceItem (
191                          (MutableRepository) targetPropertyDescriptors[j].getPropertyItemDescriptor().getRepository(),
192                          targetPropertyDescriptors[j].getPropertyItemDescriptor().getItemDescriptorName(),
193                          (GSAPropertyDescriptor) targetPropertyDescriptors[j]);
194 
195             logMessage ("generateDummyItems: done with this property");
196           }
197         }
198       }
199       
200       rollback = false;
201     }
202     catch (TransactionDemarcationException e)
203     {
204       throw (new RepositoryException ("TransactionDemarcationException: " + e.getMessage()));
205     }
206     catch (RepositoryException e)
207     {
208       throw (e);
209     }
210     finally
211     {
212       try
213       {
214         transactionDemarcation.end (rollback);
215       }
216       catch (TransactionDemarcationException e)
217       {
218         throw (new RepositoryException ("TransactionDemarcationException: " + e.getMessage()));
219       }
220     }
221 
222     try
223     {
224       persistReferenceItemList ();
225     }
226     catch (IOException e)
227     {
228       throw (e);
229     }
230     
231     // TODO: Remove this as its only for debugging.
232     
233     displayCachedItems ();
234     
235     return;
236   }
237 
238   // -------------------------------------
239   /***
240    */
241 
242   public RepositoryItem findDummyReferenceItem
243   (
244     MutableRepository pRepository,
245     String pItemDescriptorName,
246     GSAPropertyDescriptor pPropertyDescriptor
247   ) throws RepositoryException
248   {
249     MutableRepositoryItem item = null;
250     String repositoryName = null;
251     boolean primaryKey = false;
252     Map itemDescriptorToItemMap;
253         
254     // Check if we are writing to a primary key table
255     
256     if (pPropertyDescriptor != null && pPropertyDescriptor.isJDBCPrimaryKeyNamesKnown())
257     {
258       primaryKey = pPropertyDescriptor.isJDBCPrimaryKey()[0];
259     }
260 
261     if (primaryKey)
262     {
263       logMessage ("findDummyReferenceItem: Property " + pPropertyDescriptor.getItemDescriptor().getItemDescriptorName() + "."
264           + pPropertyDescriptor.getName() + " is stored in a primary key column, primary key name=" + pPropertyDescriptor.getJDBCPrimaryKeyNames()[0]
265           + " A new temporary item will be created for this property.");
266     }
267     
268     // check for GenericService for unit tests
269     
270     if (pRepository instanceof GenericService)
271     {
272       repositoryName = ((GenericService) pRepository).getAbsoluteName();
273       logMessage ("findDummyReferenceItem: Repository Name: " + repositoryName);
274     }
275     else
276     {
277       throw new RuntimeException("ReferenceItemGenerator: Repository is not a GenericService");
278     }
279 
280     itemDescriptorToItemMap = (Map) mRepositoryToItemsMap.get (repositoryName);
281     
282     // Get the item from our map as long as it's not stored in a primary key column
283     
284     if (itemDescriptorToItemMap != null && !primaryKey)
285     {
286       item = (MutableRepositoryItem) itemDescriptorToItemMap.get (pItemDescriptorName);
287       
288       if (item != null)
289       {
290         logMessage ("findDummyReferenceItem: Found a suitable item that already exists: " + item.getRepositoryId());
291         return item;
292       }
293     }
294     
295     if (itemDescriptorToItemMap == null)
296     {
297       logMessage ("findDummyReferenceItem: Creating the map for the repository: " + repositoryName);
298       itemDescriptorToItemMap = new HashMap(13);
299       mRepositoryToItemsMap.put (repositoryName, itemDescriptorToItemMap);
300     }
301     
302     // Get the item from our map as long as it's not stored in a primary key column
303     
304     if (!primaryKey)
305     {
306       logMessage ("findDummyReferenceItem: Try to get a suiable item from the map");
307       item = (MutableRepositoryItem) itemDescriptorToItemMap.get (pItemDescriptorName);
308     }
309     
310     if (item == null)
311     {
312       // Don't use existing items for properties stored in a primary key.
313       
314       logMessage ("findDummyReferenceItem: No item yet...");
315 
316       if (!primaryKey)
317       {
318         logMessage ("findDummyReferenceItem: Look in the list");
319         item = findReferenceItemInList (repositoryName, pItemDescriptorName);
320       }
321       
322       if (item == null)
323       {
324         logMessage ("findDummyReferenceItem: No suitable item exists. Creating temp item reference in repository " +
325                                                repositoryName + " for item type " + pItemDescriptorName); //$NON-NLS-1$ //$NON-NLS-2$
326         item = createDummyItem (pRepository, pItemDescriptorName);
327         logMessage ("findDummyReferenceItem: Item Created");
328       }
329       
330       if (!itemDescriptorToItemMap.containsKey (pItemDescriptorName))
331       {
332         logMessage ("findDummyReferenceItem: The newly created item is not in the map so add it.");
333         itemDescriptorToItemMap.put (pItemDescriptorName, item);
334       }
335     }
336 
337     return item;
338   }
339 
340   private MutableRepositoryItem findReferenceItemInList
341   (
342     String pRepositoryPath,
343     String pItemDescriptorName 
344   ) throws RepositoryException
345   {
346     MutableRepositoryItem item = null;
347     ReferenceItem referenceItem = null;
348     Iterator iterator = null;
349     boolean itemFoundInList = false;
350     MutableRepository repository = null;
351     
352     iterator = mReferenceItemList.iterator();
353     
354     while ((iterator.hasNext()) && (!itemFoundInList))
355     {
356       referenceItem = (ReferenceItem) iterator.next();
357       
358       if ((referenceItem.getRepositoryPath().equals (pRepositoryPath)) &&
359               (referenceItem.getItemDescriptor().equals (pItemDescriptorName)))
360       {
361         itemFoundInList = true;
362       }
363     }
364     
365     if (itemFoundInList)
366     {
367       // Get the item in the repository.
368       
369       repository = (MutableRepository) mImportService.resolveName (referenceItem.getRepositoryPath());
370 
371       item = (MutableRepositoryItem) repository.getItem (referenceItem.getItemId(), referenceItem.getItemDescriptor());
372     }
373 
374     return item;
375   }
376   
377   // -------------------------------------
378   /***
379    * Creates a dummy repository item which is used when a required property of
380    * the given types needs to reference an asset.
381    */
382 
383   public MutableRepositoryItem createDummyItem
384   (
385     MutableRepository pRepository,
386     String pItemDescriptorName
387   ) throws RepositoryException
388   {
389     ReferenceItem referenceItem;
390     RepositoryPropertyDescriptor[] propertyDescriptors;
391     
392     // Create the item
393     
394     MutableRepositoryItem item = pRepository.createItem (pItemDescriptorName);
395   
396     // Create a ReferenceItem and add it to the index.
397     
398     referenceItem = new ReferenceItem ();
399     
400     referenceItem.setRepositoryPath(((GenericService) pRepository).getAbsoluteName());
401     referenceItem.setItemDescriptor(pItemDescriptorName);
402     referenceItem.setItemId(item.getRepositoryId());
403     
404     mReferenceItemList.add (referenceItem);
405     
406     propertyDescriptors = (RepositoryPropertyDescriptor[]) item.getItemDescriptor().getPropertyDescriptors();
407 
408     // Create a java.util.Random for generating property values of the temporary item.
409     
410     long seed = generateSeed();
411     
412     Random r = new Random(seed);
413 
414     for (int i = 0; i < propertyDescriptors.length; i++)
415     {
416       if (!propertyDescriptors[i].isRequired()) // skip non-required properties
417       {
418         continue;
419       }
420         
421       if (!propertyDescriptors[i].isWritable()) // skip non-writable properties
422       {
423         continue;
424       }
425       
426       if (propertyDescriptors[i].isIdProperty()) // skip id properties
427       {
428         continue;
429       }
430       
431       if (propertyDescriptors[i] instanceof DerivedPropertyDescriptor)
432       {
433         // skip derived properties
434         
435         logMessage ("createDummyItem: WARNING: The " +
436               pItemDescriptorName + "(" + pRepository.getRepositoryName() + ")" +
437               " required derived property");
438         
439         continue;
440       }
441       
442       // Get column lengths
443       
444       int columnLength = 10; //default to 10 if we don't know
445       
446       boolean columnLengthKnown = false;
447       
448       if (propertyDescriptors[i] instanceof GSAPropertyDescriptor)
449       {
450         GSAPropertyDescriptor gpd = (GSAPropertyDescriptor)propertyDescriptors[i];
451         columnLengthKnown = gpd.isJDBCColumnLengthsKnown();
452         if (columnLengthKnown)
453         {
454           columnLength = gpd.getJDBCColumnLengths()[0];
455         }
456       }
457       
458       Class classType = propertyDescriptors[i].getPropertyType();
459       
460       // --------------------------
461       // enumeration
462       // --------------------------
463       
464       if (propertyDescriptors[i] instanceof EnumPropertyDescriptor)
465       { //$NON-NLS-1$
466         EnumPropertyDescriptor enumPd = (EnumPropertyDescriptor) propertyDescriptors[i];
467         
468         if (enumPd.getUseCodeForValue())
469         {
470           Integer[] codes = enumPd.getEnumeratedCodes();
471           
472           if (codes != null && codes.length > 0)
473           {
474             item.setPropertyValue(propertyDescriptors[i].getName(), codes[0]);
475           }
476           else
477           {
478             throw new RepositoryException("ReferenceItemGenerator: no defined enum values" +
479                 " " + propertyDescriptors[i].getName() + " in descriptor" +
480                 " " + pItemDescriptorName);
481           }
482         }
483         else
484         {
485           String[] strings = enumPd.getEnumeratedValues();
486           
487           if (strings != null && strings.length > 0)
488           {
489             item.setPropertyValue(propertyDescriptors[i].getName(), strings[0]);
490           }
491           else
492           {
493             throw new RepositoryException ("ReferenceItemGenerator.noDefinedEnumValues" +
494                 " " + propertyDescriptors[i].getName() + " in descriptor" +
495                 " " + pItemDescriptorName);
496           }
497 
498         }
499       }
500       
501       // --------------------------
502       // String
503       // --------------------------
504       
505       else if (classType == String.class)
506       {
507         // Get a unique value no longer than column length
508         // Look out for UTF-8 Database columnLength might be in bytes, not number of characters
509         // To be safe, divide by 3 and subtract 1
510         
511         int safeNumChars = (columnLength/4)-1;
512         
513         item.setPropertyValue (propertyDescriptors[i].getName(), getRandomString(safeNumChars)); //$NON-NLS-1$
514       }
515       
516       // --------------------------
517       // Integer
518       // --------------------------
519       
520       else if (classType == Integer.class)
521       {
522         item.setPropertyValue (propertyDescriptors[i].getName(), new Integer(r.nextInt()));
523       }
524       
525       // --------------------------
526       // RepositoryItem
527       // --------------------------
528       
529       else if (classType == RepositoryItem.class)
530       {
531         RepositoryItemDescriptor refItemDesc = propertyDescriptors[i].getPropertyItemDescriptor();
532         
533         RepositoryItem refItem;
534         
535         if (item.getItemDescriptor() != refItemDesc)
536         {
537           refItem = findDummyReferenceItem (
538               (MutableRepository) refItemDesc.getRepository(), refItemDesc
539                   .getItemDescriptorName(), (GSAPropertyDescriptor)propertyDescriptors[i]);
540         }
541         else
542         {
543           refItem = item;
544         }
545         
546         item.setPropertyValue (propertyDescriptors[i].getName(), refItem);
547       }
548       
549       // --------------------------
550       // Timestamp
551       // --------------------------
552       
553       else if (classType == Timestamp.class)
554       {
555         item.setPropertyValue(propertyDescriptors[i].getName(), new Timestamp(r.nextLong()));
556       }
557       
558       // --------------------------
559       // Boolean
560       // --------------------------
561       
562       else if (classType == Boolean.class)
563       {
564         item.setPropertyValue(propertyDescriptors[i].getName(), Boolean.TRUE);
565       }
566       
567       // --------------------------
568       // Double
569       // --------------------------
570       
571       else if (classType == Double.class)
572       {
573         item.setPropertyValue(propertyDescriptors[i].getName(), new Double(r.nextDouble()));
574       }
575       
576       // --------------------------
577       // javax.sql.Date
578       // --------------------------
579       
580       else if (classType == java.sql.Date.class || classType == java.util.Date.class)
581       {
582         item.setPropertyValue(propertyDescriptors[i].getName(), new java.sql.Date(r.nextLong()));
583       }
584       
585       // --------------------------
586       // Short
587       // --------------------------
588       
589       else if (classType == Short.class)
590       {
591         item.setPropertyValue(propertyDescriptors[i].getName(), new Short((short)r.nextInt(16000)));
592       }
593       
594       // --------------------------
595       // Long
596       // --------------------------
597       
598       else if (classType == Long.class)
599       {
600         item.setPropertyValue(propertyDescriptors[i].getName(), new Long(r.nextLong()));
601       }
602       
603       // --------------------------
604       // Float
605       // --------------------------
606       
607       else if (classType == Float.class)
608       {
609         item.setPropertyValue(propertyDescriptors[i].getName(), new Float(r.nextFloat()));
610       }
611       
612       // --------------------------
613       // Byte
614       // --------------------------
615       
616       else if (classType == Byte.class)
617       {
618         byte [] b = new byte[1];
619         r.nextBytes(b);
620         item.setPropertyValue (propertyDescriptors[i].getName(), new Byte(b[0]));
621       }
622       
623       // --------------------------
624       // Character
625       // --------------------------
626       
627       else if (classType == Character.class)
628       {
629         byte [] c = new byte[1];
630         r.nextBytes(c);
631         item.setPropertyValue (propertyDescriptors[i].getName(), new Character((char)c[0]));
632       }
633       
634       // --------------------------
635       // Binary
636       // --------------------------
637       
638       else if (propertyDescriptors[i].getTypeName().equals("binary")) //$NON-NLS-1$
639       {
640         // Assuming that byte is not unique , so we aren't generating
641         // a random here.
642         item.setPropertyValue (propertyDescriptors[i].getName(), new byte[] { 0, 0 });
643       }
644       
645       // --------------------------
646       // Unknown/Unsupported
647       // --------------------------
648       
649       else
650       {
651         logMessage ("createDummyItem: the required property " + propertyDescriptors[i].getName() + //$NON-NLS-1$
652             " in descriptor " + item.getItemDescriptor().getItemDescriptorName() + //$NON-NLS-1$
653             " not populated " + classType.getName()); //$NON-NLS-1$
654         throw new RepositoryException("ReferenceItemGenerator: unknownPropertyType" +
655             " " + propertyDescriptors[i].getName() + " in descriptor " +
656             " " + pItemDescriptorName);
657       }
658     }
659 
660     pRepository.addItem (item);
661     pRepository.updateItem (item);
662 
663     return (item);
664   }
665 
666   /***
667    * 
668    */
669   public void persistReferenceItemList () throws IOException
670   {
671     File referenceListFile;
672     String referenceListFilename;
673     Iterator iterator;
674     
675     logMessage ("persistReferenceItemList: Persisting the reference item list");
676 
677     try
678     {
679       // Set up the file writer for the reference items.
680       
681       referenceListFilename = mImportDirectory + File.separator + M_REFERENCE_LIST_FILENAME;
682       
683       referenceListFile = new File (referenceListFilename);
684       
685       if (!referenceListFile.exists())
686       {
687         referenceListFile.createNewFile();
688       }
689       
690       mReferenceListFileWriter = new FileWriter (referenceListFile, false);
691     }
692     catch (IOException e)
693     {
694       throw (e);  
695     }
696     
697     logMessage ("persistReferenceItemList: Reference item file is ready for writing");
698     
699     // Process the list. 
700     
701     iterator = getReferenceItemList().iterator();
702     
703     while (iterator.hasNext())
704     {
705       ReferenceItem referenceItem = (ReferenceItem) iterator.next();
706       
707       // Write the item to the file.
708       
709       try
710       {
711         mReferenceListFileWriter.write ("<reference-item>" + "\n");
712         mReferenceListFileWriter.write ("\t" + "<repository-path>" +
713                                             referenceItem.getRepositoryPath() + "</repository-path>" + "\n");
714         mReferenceListFileWriter.write ("\t" + "<item-descriptor>" +
715                                             referenceItem.getItemDescriptor() + "</item-descriptor>" + "\n");
716         mReferenceListFileWriter.write ("\t" + "<item-id>" +
717                                             referenceItem.getItemId() + "</item-id>" + "\n");
718         mReferenceListFileWriter.write ("</reference-item>" + "\n");
719         mReferenceListFileWriter.flush();
720       }
721       catch (IOException e)
722       {
723         throw (e);
724       }
725     }
726 
727     logMessage ("persistReferenceItemList: Reference item file is complete");
728   }
729   
730   // -------------------------------------
731   /***
732    * Removes the dummy items from the destination repository
733    */
734   public synchronized void deleteAllDummyReferenceItems()
735   {
736     int pass = 1;
737     List itemsToRemove = null;
738     
739     logMessage ("deleteAllDummyReferenceItems: Getting the items to remove");
740 
741     itemsToRemove = getItemsToRemoveAsList ();
742     
743     if (itemsToRemove == null)
744     {
745       return;
746     }
747 
748     logMessage ("deleteAllDummyReferenceItems: Number of items to remove: " + itemsToRemove.size());
749 
750     while (!itemsToRemove.isEmpty() && pass < 25)
751     {
752       logMessage ("deleteAllDummyReferenceItems: Deletion pass: " + pass);
753 
754       deleteItemsFromList (itemsToRemove);
755       pass++;
756     }
757     
758     logMessage ("deleteAllDummyReferenceItems: Clear the map");
759 
760     clearRepositoryItemMap();
761     
762     logMessage ("deleteAllDummyReferenceItems: Clear the list");
763 
764     mReferenceItemList.clear();
765     
766     logMessage ("deleteAllDummyReferenceItems: Remove the reference file");
767 
768     removeReferenceListFile ();
769   }
770 
771   private List getItemsToRemoveAsList ()
772   {
773     ArrayList itemsToRemove = new ArrayList ();
774     RepositoryItem item = null;
775     ReferenceItem referenceItem = null;
776     Iterator iterator = null;
777     MutableRepository repository = null;
778     
779     logMessage ("getItemsToRemoveAsList: processing reference item list: " + mReferenceItemList.size());
780 
781     iterator = mReferenceItemList.iterator();
782     
783     while (iterator.hasNext())
784     {
785       referenceItem = (ReferenceItem) iterator.next();
786       
787       logMessage ("getItemsToRemoveAsList: Reference Item: " + referenceItem.getItemDescriptor() +
788                             " (" + referenceItem.getItemId() + ") Repository: " + referenceItem.getRepositoryPath());
789 
790       try
791       {
792         repository = (MutableRepository) mImportService.resolveName (referenceItem.getRepositoryPath());
793         
794         logMessage ("getItemsToRemoveAsList: Repository for item: " + repository.getRepositoryName());
795 
796         item = repository.getItem (referenceItem.getItemId(), referenceItem.getItemDescriptor());
797         
798         if (item != null)
799         {
800           logMessage ("getItemsToRemoveAsList: Add item to list: " + item.getRepositoryId());
801           itemsToRemove.add (item);
802         }
803       }
804       catch (RepositoryException e)
805       {
806         // Do nothing for now.
807         logMessage ("getItemsToRemoveAsList: RepositoryException: " + e.getMessage());
808       }
809     }
810     
811     logMessage ("getItemsToRemoveAsList: List built: " + itemsToRemove.size());
812 
813     return (itemsToRemove);
814   }
815   
816   private void deleteItemsFromList(List pList)
817   {
818     TransactionDemarcation td = new TransactionDemarcation();
819     boolean rollback = true;
820     MutableRepositoryItem item;
821     String repositoryPath;
822     String itemDescriptorName;
823     String itemId;
824     MutableRepository repository = null;
825     Map itemDescriptorToItemMap;
826     RepositoryItem itemToRemove = null;
827       
828     logMessage ("deleteItemsFromList: Processing list: " + pList.size());
829 
830     Iterator iterator = pList.iterator();
831       
832     while (iterator.hasNext())
833     {
834       try
835       {
836         td.begin (mImportService.getTransactionManager(),TransactionDemarcation.REQUIRED);        
837 
838         item = (MutableRepositoryItem) iterator.next();
839         
840         logMessage ("deleteItemsFromList: Processing Item: " + item.getRepositoryId());
841         
842         repositoryPath = ((GenericService) item.getRepository()).getAbsoluteName();
843         logMessage ("deleteItemsFromList: Item: Repository Path: " + repositoryPath);
844         
845         itemDescriptorName = item.getItemDescriptor().getItemDescriptorName();
846         logMessage ("deleteItemsFromList: Item: Item Desc Name: " + itemDescriptorName);
847         
848         itemId = item.getRepositoryId();
849         logMessage ("deleteItemsFromList: Item: Item Id: " + itemId);
850           
851         logMessage ("deleteItemsFromList: Attempting to remove temp reference item "
852                 + repositoryPath + ":" + itemDescriptorName + ":" + itemId);
853           
854         repository = null;
855         itemToRemove = null;
856 
857         logMessage ("deleteItemsFromList: Get the Item Descriptor to Item map");
858 
859         itemDescriptorToItemMap = (Map) mRepositoryToItemsMap.get (repositoryPath);
860           
861         // First try to find the cached item object
862           
863         if (itemDescriptorToItemMap != null)
864         {
865           logMessage ("deleteItemsFromList: Item Descriptor to Item map exists");
866 
867           itemToRemove = (RepositoryItem) itemDescriptorToItemMap.get (itemDescriptorName);
868             
869           logMessage ("deleteItemsFromList: Got removal item from cache (possibly)");
870 
871           if (itemToRemove != null)
872           {
873             logMessage ("deleteItemsFromList: Get the repository for the cached item");
874             repository = (MutableRepository) itemToRemove.getRepository();
875           }
876         }
877           
878         // If it's not cached, load it from the repository.
879           
880         if (itemToRemove == null)
881         {
882           logMessage ("deleteItemsFromList: Item to remove is not cached. get it.");
883 
884           repository = (MutableRepository) mImportService.resolveName (repositoryPath);
885            
886           logMessage ("deleteItemsFromList: Getting Item to remove from repository");
887 
888           itemToRemove = repository.getItem (itemId, itemDescriptorName);
889             
890           if (itemToRemove == null)
891           {
892             logMessage ("deleteItemsFromList: Temp reference item stored for deployment was not found in destination repository");
893             continue;
894           }
895         }
896           
897         if (itemDescriptorToItemMap != null)
898         {
899           logMessage ("deleteItemsFromList: Remove item descriptor from map");
900 
901           itemDescriptorToItemMap.remove (itemDescriptorName);
902             
903           if (itemDescriptorToItemMap.isEmpty())
904           {
905             logMessage ("deleteItemsFromList: Map is now empty so remove it.");
906             mRepositoryToItemsMap.remove (repositoryPath);
907           }
908         }
909           
910         // Remove the item.
911           
912         logMessage ("deleteItemsFromList: Removing the item");
913 
914         repository.removeItem (itemId, itemDescriptorName);
915 
916         rollback = false;
917       }
918       catch (RepositoryException e)
919       {
920         logMessage ("deleteItemsFromList: RepositoryException: " + e.getMessage());
921       } 
922       catch (TransactionDemarcationException e)
923       {
924         logMessage ("deleteItemsFromList: TransactionDemarcationException: " + e.getMessage());
925       }
926       finally
927       {
928         try
929         {
930           td.end(rollback);
931         
932           if (!rollback)
933           {
934             iterator.remove();
935           }
936         }
937         catch (TransactionDemarcationException e)
938         {
939           logMessage ("deleteItemsFromList: TransactionDemarcationException: " + e.getMessage());
940         }
941       }        
942     }
943 
944     logMessage ("deleteItemsFromList: Done");
945   }
946 
947   private void clearRepositoryItemMap()
948   {
949     Map itemDescriptorToItemMap;
950     Iterator iterator = mRepositoryToItemsMap.values().iterator();
951     
952     while (iterator.hasNext())
953     {
954       itemDescriptorToItemMap = (Map) iterator.next();
955       itemDescriptorToItemMap.clear();
956     }
957     
958     mRepositoryToItemsMap.clear();
959   }
960   
961   private void removeReferenceListFile ()
962   {
963     File referenceListFile;
964     String referenceListFilename;
965 
966     // Close the writer.
967     
968     try
969     {
970       mReferenceListFileWriter.close();
971     }
972     catch (IOException e)
973     {
974       logMessage ("deleteItemsFromList: Failed to close writer: " + e.getMessage());
975     }
976     
977     referenceListFilename = mImportDirectory + File.separator + M_REFERENCE_LIST_FILENAME;
978       
979     logMessage ("deleteItemsFromList: Reference file: " + referenceListFilename);
980 
981     referenceListFile = new File (referenceListFilename);
982       
983     if (referenceListFile.exists())
984     {
985       try
986       {
987         if (referenceListFile.delete())
988         {
989           logMessage ("deleteItemsFromList: Reference file deleted");
990         }
991         else
992         {
993           logMessage ("deleteItemsFromList: Reference file not deleted");
994         }
995       }
996       catch (SecurityException e)
997       {
998         logMessage ("deleteItemsFromList: SecurityException: " + e.getMessage());
999       }
1000     }
1001   }
1002   
1003   //-------------------------------------
1004   /***
1005    * Generates a *hopefully* unique seed
1006    */
1007 
1008   public long generateSeed()
1009   {
1010     int hash = Thread.currentThread().getName().hashCode();
1011     
1012     long freeMem = Runtime.getRuntime().freeMemory();
1013     
1014     long time = System.currentTimeMillis();
1015     
1016     return (freeMem + time + hash);
1017   }
1018 
1019   //-------------------------------------
1020   /***
1021    * Return a random strng of a given length
1022    */
1023 
1024   public static String getRandomString (int n)
1025   {
1026     char[] randStr = new char[n];
1027     int c  = 'A';
1028     int  r1 = 0;
1029     for (int i=0; i < n; i++)
1030     {
1031       r1 = (int)(Math.random() * 3);
1032       switch(r1)
1033       {
1034         case 0: c = '0' +  (int)(Math.random() * 10); break;
1035         case 1: c = 'a' +  (int)(Math.random() * 26); break;
1036         case 2: c = 'A' +  (int)(Math.random() * 26); break;
1037       }
1038       
1039       randStr[i] = (char)c;
1040     }
1041     
1042     return new String (randStr);
1043   }
1044   
1045   private void displayCachedItems ()
1046   {
1047     Map itemDescriptorToItemMap;
1048     String repositoryName;
1049     String itemDescriptorName;
1050     RepositoryItem item;
1051     Iterator iterator = mRepositoryToItemsMap.keySet().iterator();
1052     
1053     while (iterator.hasNext())
1054     {
1055       repositoryName = (String) iterator.next();
1056       
1057       logMessage ("ITEM CACHE: === Repository: " + repositoryName + " ===");
1058       
1059       itemDescriptorToItemMap = (Map) mRepositoryToItemsMap.get (repositoryName);
1060       
1061       Iterator iteratorItemMap = itemDescriptorToItemMap.keySet().iterator();
1062       
1063       while (iteratorItemMap.hasNext())
1064       {
1065         itemDescriptorName = (String) iteratorItemMap.next();
1066         
1067         item = (RepositoryItem) itemDescriptorToItemMap.get (itemDescriptorName);
1068         
1069         logMessage ("ITEM CACHE: Item Descriptor: " + itemDescriptorName + " Item Id: " + item.getRepositoryId());
1070       }
1071     }
1072   }
1073   
1074   private void logMessage (String pMessage)
1075   {
1076     if (mLogging)
1077     {
1078       try
1079       {
1080         mLogFileWriter.write (pMessage + "\n");
1081         mLogFileWriter.flush();
1082       }
1083       catch (IOException e)
1084       {
1085       }
1086     }
1087   }
1088   
1089   private void createLogFile ()
1090   {
1091     String logFilename = "C://Bol//BolImportData//logs//log_ReferenceItemGenerator.log";
1092     
1093     try
1094     {
1095       mLogFile = new File (logFilename);
1096       mLogFile.createNewFile();
1097       mLogFileWriter = new FileWriter (mLogFile, false);
1098     }
1099     catch (IOException e)
1100     {
1101       System.out.println ("IOException: " + e.getMessage());
1102     }    
1103   }
1104 }