1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package atg.epub;
18
19 import java.io.File;
20 import java.io.FileOutputStream;
21 import java.io.FileReader;
22 import java.io.BufferedReader;
23 import java.io.FileWriter;
24 import java.io.IOException;
25 import java.sql.Connection;
26 import java.sql.DriverManager;
27 import java.sql.SQLException;
28 import java.sql.PreparedStatement;
29 import java.sql.ResultSet;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.ArrayList;
33
34 import atg.dtm.TransactionDemarcation;
35 import atg.dtm.TransactionDemarcationException;
36 import atg.epub.project.Process;
37 import atg.epub.project.ProcessHome;
38 import atg.epub.project.ProjectConstants;
39 import atg.nucleus.GenericService;
40 import atg.process.action.ActionConstants;
41 import atg.process.action.ActionException;
42 import atg.repository.MutableRepository;
43 import atg.repository.Repository;
44 import atg.repository.RepositoryException;
45 import atg.repository.RepositoryItem;
46 import atg.security.Persona;
47 import atg.security.ThreadSecurityManager;
48 import atg.security.User;
49 import atg.userdirectory.UserDirectoryUserAuthority;
50 import atg.versionmanager.VersionManager;
51 import atg.versionmanager.WorkingContext;
52 import atg.versionmanager.Workspace;
53 import atg.versionmanager.exceptions.VersionException;
54 import atg.workflow.ActorAccessException;
55 import atg.workflow.MissingWorkflowDescriptionException;
56 import atg.workflow.WorkflowConstants;
57 import atg.workflow.WorkflowException;
58 import atg.workflow.WorkflowManager;
59 import atg.workflow.WorkflowView;
60
61 import atg.adapter.gsa.xml.ImportItem;
62 import atg.adapter.gsa.xml.ImportFailedItem;
63 import atg.adapter.gsa.xml.ImportFileParser;
64 import atg.adapter.gsa.xml.ReferenceItemGenerator;
65 import atg.adapter.gsa.xml.ImportWorkerThread;
66 import atg.adapter.util.RepositoryUtils;
67
68 import javax.ejb.CreateException;
69 import javax.servlet.ServletContext;
70 import javax.transaction.TransactionManager;
71
72 /***
73 * This class provides an import service, which enables customers to import their data into a versioned repository.
74 *
75 * The service works on a single xml file and imports its contents into the versioned repository.
76 *
77 * You may choose between the early and late workflows. /Content Administration/import-late.wdl for late and
78 * /Content Administration/import-early.wdl for early.
79 *
80 * @author Patrick Mc Erlean
81 * @version $Id: //user/pmcerlean/main/Import/src/classes/atg/epub/ImportService.java#2 $
82 */
83 public class ImportService extends GenericService
84 {
85
86 public static String CLASS_VERSION = "$Id: //user/pmcerlean/main/Import/src/classes/atg/epub/ImportService.java#2 $$Change: 490318 $";
87
88
89 public static final String M_SERVICE_STATUS_WAITING_TO_START = "Service: Waiting to start";
90 public static final String M_SERVICE_STATUS_PROJECT_CREATION = "Project : Creating";
91 public static final String M_SERVICE_STATUS_PRE_DATA_IMPORT = "Data Import : Preparing";
92 public static final String M_SERVICE_STATUS_DATA_IMPORT_BATCH_CREATION = "Data Import : Creating the batches";
93 public static final String M_SERVICE_STATUS_DATA_IMPORT_ADD_UPDATE_PHASE = "Data Import : Add Update phase";
94 public static final String M_SERVICE_STATUS_DATA_IMPORT_REFERENCE_UPDATE_PHASE = "Data Import : Reference Update phase";
95 public static final String M_SERVICE_STATUS_DATA_IMPORT_DELETE_PHASE = "Data Import : Delete phase";
96 public static final String M_SERVICE_STATUS_DATA_IMPORT_PROCESSING_FAILED_DELETIONS = "Data Import : Processing failed deletions";
97 public static final String M_SERVICE_STATUS_PROJECT_ADVANCE_WORKFLOW = "Project : Advance workflow";
98 public static final String M_SERVICE_STATUS_COMPLETED_SUCCESSFULLY = "Service : Completed successfully";
99 public static final String M_SERVICE_STATUS_COMPLETED_WITH_ERRORS = "Service : Completed successfully (Check error file)";
100 public static final String M_SERVICE_STATUS_CANCELLED = "Service : Import cancelled";
101 public static final String M_SERVICE_STATUS_FATAL_ERROR_THRESHOLD_REACHED = "Service : Fatal Error : Import error threshold reached";
102 public static final String M_SERVICE_STATUS_FATAL_ERROR_THREAD_DIED = "Service : Fatal Error : ";
103 public static final String M_SERVICE_STATUS_FATAL_ERROR_IO = "Service : Fatal Error : IO Problem";
104 public static final String M_SERVICE_STATUS_FATAL_ERROR_DATABASE = "Service : Fatal Error : Database problem";
105 public static final String M_SERVICE_STATUS_FATAL_ERROR_THREADS = "Service : Fatal Error : Threading problem";
106
107 public static final int PHASE_ADD_UPDATE = 0;
108 public static final int PHASE_REFERENCE_UPDATE = 1;
109 public static final int PHASE_DELETE = 2;
110
111 public static final String M_SEGMENT_FILE_STUB = "IMPORT_SEGMENT_";
112 public static final String M_SEGMENT_FILE_EXTENSION = ".xml";
113 public static final String M_FAILURES_FILENAME = "IMPORT_FAILURES.log";
114
115 public static final String M_TAG_ADD_ITEM_START = "<add-item";
116 public static final String M_TAG_ADD_ITEM_END = "</add-item";
117 public static final String M_TAG_UPDATE_ITEM_START = "<update-item";
118 public static final String M_TAG_UPDATE_ITEM_END = "</update-item";
119 public static final String M_TAG_REMOVE_ITEM_START = "<remove-item";
120 public static final String M_TAG_REMOVE_ITEM_END = "</remove-item";
121
122 public static final String M_ITEM_CATALOG = "catalog";
123 public static final String M_ITEM_CATEGORY = "category";
124 public static final String M_ITEM_PRODUCT = "product";
125 public static final String M_ITEM_SKU = "sku";
126 public static final String M_ITEM_MEDIA_EXTERNAL = "media-external";
127 public static final String M_ITEM_FOLDER = "folder";
128
129 public static final int THREAD_STATUS_STARTED = 0;
130 public static final int THREAD_STATUS_NOTIFIED = 1;
131 public static final int THREAD_STATUS_PROCESSING = 2;
132 public static final int THREAD_STATUS_PHASE_COMPLETED = 3;
133
134
135
136
137 private TransactionManager mTransactionManager = null;
138
139 /***
140 * @return Returns the transactionManager.
141 */
142 public TransactionManager getTransactionManager()
143 {
144 return mTransactionManager;
145 }
146
147 /***
148 * @param pTransactionManager The transactionManager to set.
149 */
150 public void setTransactionManager (TransactionManager pTransactionManager)
151 {
152 mTransactionManager = pTransactionManager;
153 }
154
155
156
157
158 private VersionManager mVersionManager = null;
159
160 /***
161 * @return Returns the versionManager.
162 */
163 public VersionManager getVersionManager()
164 {
165 return mVersionManager;
166 }
167
168 /***
169 * @param pVersionManager The versionManager to set.
170 */
171 public void setVersionManager (VersionManager pVersionManager)
172 {
173 mVersionManager = pVersionManager;
174 }
175
176
177
178
179 private WorkflowManager mWorkflowManager = null;
180
181 /***
182 * @return Returns the workflowManager.
183 */
184 public WorkflowManager getWorkflowManager()
185 {
186 return mWorkflowManager;
187 }
188
189 /***
190 * @param pWorkflowManager The workflowManager to set.
191 */
192 public void setWorkflowManager (WorkflowManager pWorkflowManager)
193 {
194 mWorkflowManager = pWorkflowManager;
195 }
196
197
198
199
200 private UserDirectoryUserAuthority mUserAuthority = null;
201
202 /***
203 * Returns the UserAuthority
204 */
205 public UserDirectoryUserAuthority getUserAuthority()
206 {
207 return mUserAuthority;
208 }
209
210 /***
211 * Sets the UserAuthority
212 */
213 public void setUserAuthority (UserDirectoryUserAuthority pUserAuthority)
214 {
215 mUserAuthority = pUserAuthority;
216 }
217
218
219
220
221 private String mPersonaPrefix = "Profile$login$";
222
223 /***
224 * Returns the PersonaPrefix which is supplied for login
225 */
226 public String getPersonaPrefix()
227 {
228 return mPersonaPrefix;
229 }
230
231 /***
232 * Sets the PersonaPrefix
233 */
234 public void setPersonaPrefix(String pPersonaPrefix)
235 {
236 mPersonaPrefix = pPersonaPrefix;
237 }
238
239
240
241
242 private String mUserName = "publishing";
243
244 /***
245 * Returns the UserName which is supplied upon check-in and for logging in.
246 */
247 public String getUserName()
248 {
249 return mUserName;
250 }
251
252 /***
253 * Sets the UserName
254 */
255 public void setUserName (String pUserName)
256 {
257 mUserName = pUserName;
258 }
259
260
261
262
263 private String mWorkflowName = "/Content Administration/import-early.wdl";
264
265 /***
266 * Returns the workflowName property
267 */
268 public String getWorkflowName()
269 {
270 return mWorkflowName;
271 }
272
273 /***
274 * Sets the workflowName property
275 */
276 public void setWorkflowName (String string)
277 {
278 mWorkflowName = string;
279 }
280
281
282
283
284 private String mTaskOutcomeId = "4.1.1";
285
286 /***
287 * @return Returns the taskOutcomeId.
288 */
289 public String getTaskOutcomeId ()
290 {
291 return mTaskOutcomeId;
292 }
293
294 /***
295 * @param pTaskOutcomeId The taskOutcomeId to set.
296 */
297 public void setTaskOutcomeId (String pTaskOutcomeId)
298 {
299 mTaskOutcomeId = pTaskOutcomeId;
300 }
301
302
303
304
305 private String mProjectName = "Content Administration Import";
306
307 /***
308 * @return Returns the projectName.
309 */
310 public String getProjectName()
311 {
312 return mProjectName;
313 }
314
315 /***
316 * @param pProjectName The projectName to set.
317 */
318 public void setProjectName (String pProjectName)
319 {
320 mProjectName = pProjectName;
321 }
322
323
324
325
326 private int mItemBatchSize = 1000;
327
328 /***
329 * @return Returns the itemBatchSize.
330 */
331 public int getItemBatchSize()
332 {
333 return mItemBatchSize;
334 }
335
336 /***
337 * @param pItemBatchSize The itemBatchSize to set.
338 */
339 public void setItemBatchSize (int pItemBatchSize)
340 {
341 mItemBatchSize = pItemBatchSize;
342 }
343
344
345
346
347 private int mMaxImportThreads = 20;
348
349 /***
350 * @return Returns the maxImportThreads.
351 */
352 public int getMaxImportThreads()
353 {
354 return mMaxImportThreads;
355 }
356
357 /***
358 * @param pMaxImportThreads The maxImportThreads to set.
359 */
360 public void setMaxImportThreads (int pMaxImportThreads)
361 {
362 mMaxImportThreads = pMaxImportThreads;
363 }
364
365
366
367
368 private String mImportFilename;
369
370 /***
371 * @return Returns the importFilename.
372 */
373 public String getImportFilename()
374 {
375 return mImportFilename;
376 }
377
378 /***
379 * @param pMaxImportThreads The maxImportThreads to set.
380 */
381 public void setImportFilename (String pImportFilename)
382 {
383 mImportFilename = pImportFilename;
384 }
385
386
387
388
389 private Repository mTargetRepository;
390
391 /***
392 * @return Returns the targetRepository.
393 */
394 public Repository getTargetRepository()
395 {
396 return mTargetRepository;
397 }
398
399 /***
400 * @param pTargetRepository The targetRepository to set.
401 */
402 public void setTargetRepository (Repository pTargetRepository)
403 {
404 mTargetRepository = pTargetRepository;
405 }
406
407
408
409
410 private int mErrorThresholdPerBatch = 10;
411
412 /***
413 * @return Returns the errorThresholdPerBatch.
414 */
415 public int getErrorThresholdPerBatch()
416 {
417 return mErrorThresholdPerBatch;
418 }
419
420 /***
421 * @param pErrorThresholdPerBatch The percentage error threshold per batch to set.
422 */
423 public void setErrorThresholdPerBatch (int pErrorThresholdPerBatch)
424 {
425 mErrorThresholdPerBatch = pErrorThresholdPerBatch;
426 }
427
428
429
430
431 private int mErrorThresholdPerImport = 10;
432
433 /***
434 * @return Returns the errorThresholdPerImport.
435 */
436 public int getErrorThresholdPerImport()
437 {
438 return mErrorThresholdPerImport;
439 }
440
441 /***
442 * @param pErrorThresholdPerImport The percentage error threshold per import to set.
443 */
444 public void setErrorThresholdPerImport (int pErrorThresholdPerImport)
445 {
446 mErrorThresholdPerImport = pErrorThresholdPerImport;
447 }
448
449
450
451
452
453 private long mThreadMonitorInterval;
454
455 public long getThreadMonitorInterval ()
456 {
457 return mThreadMonitorInterval;
458 }
459
460 public void setThreadMonitorInterval (long pThreadMonitorInterval)
461 {
462 mThreadMonitorInterval = pThreadMonitorInterval;
463 }
464
465
466
467
468
469 private String mDatabaseDriver;
470
471 public String getDatabaseDriver ()
472 {
473 return mDatabaseDriver;
474 }
475
476 public void setDatabaseDriver (String pDatabaseDriver)
477 {
478 mDatabaseDriver = pDatabaseDriver;
479 }
480
481
482
483
484
485 private String mDatabaseUrl;
486
487 public String getDatabaseUrl ()
488 {
489 return mDatabaseUrl;
490 }
491
492 public void setDatabaseUrl (String pDatabaseUrl)
493 {
494 mDatabaseUrl = pDatabaseUrl;
495 }
496
497
498
499
500
501 private String mDatabaseUsername;
502
503 public String getDatabaseUsername ()
504 {
505 return mDatabaseUsername;
506 }
507
508 public void setDatabaseUsername (String pDatabaseUsername)
509 {
510 mDatabaseUsername = pDatabaseUsername;
511 }
512
513
514
515
516
517 private String mDatabasePassword;
518
519 public String getDatabasePassword ()
520 {
521 return mDatabasePassword;
522 }
523
524 public void setDatabasePassword (String pDatabasePassword)
525 {
526 mDatabasePassword = pDatabasePassword;
527 }
528
529
530
531
532
533 private Connection mDatabaseConnection = null;
534
535 private String mServiceStatus = M_SERVICE_STATUS_WAITING_TO_START;
536
537 public String getServiceStatus ()
538 {
539 return mServiceStatus;
540 }
541
542 private String mImportDirectory;
543
544 /***
545 * @return Returns the importDirectory.
546 */
547 public String getImportDirectory()
548 {
549 return mImportDirectory;
550 }
551
552 public void setImportDirectory(String pImportDirectory)
553 {
554 mImportDirectory = pImportDirectory;
555 }
556
557 private Workspace mWorkspace;
558
559 public Workspace getWorkspace()
560 {
561 return mWorkspace;
562 }
563
564 private ReferenceItemGenerator mReferenceItemGenerator;
565
566 /***
567 * @return Returns the importReferenceGenerator.
568 */
569 public ReferenceItemGenerator getReferenceItemGenerator()
570 {
571 return mReferenceItemGenerator;
572 }
573
574 public boolean getCancelCommandReceived()
575 {
576 return mCancelCommandReceived;
577 }
578
579 private boolean mCancelCommandReceived = false;
580
581 private ArrayList mFailedDeletions = new ArrayList();
582
583 /***
584 * @return Returns the failedDeletions.
585 */
586 public ArrayList getFailedDeletions()
587 {
588 return mFailedDeletions;
589 }
590
591 private boolean mDataImportErrors = false;
592
593 /***
594 * @return Returns the failedDeletions.
595 */
596 public void setDataImportErrors()
597 {
598 mDataImportErrors = true;
599 }
600
601 private int mSegmentCount = 0;
602 private User mNewUser;
603 private ImportWorkerThread[] mImportWorkerThreads = null;
604 private int[] mImportWorkerThreadsStatus = null;
605 private Process mProcess;
606 private int mTotalAssets = 0;
607 private long mAssetsPerSecondExcludingCheckin;
608 private long mAssetsPerSecondIncludingCheckin;
609 private long mTotalTime;
610 private FileWriter mFailedItemsFileWriter;
611 private int mFailedBatches = 0;
612 private boolean mErrorThresholdReached = false;
613 private ArrayList mIndexNames;
614
615
616
617
618 public ImportService()
619 {
620 }
621
622
623 /***
624 * This is the main execution method for the service. This method sets the security
625 * context on the thread for the user specified in the userName property. Next, it creates a project
626 * and then calls importData(). Next, it attempts to advance the project's workflow. Finally, it
627 * unsets the security context.
628 */
629
630 public boolean executeImport()
631 throws Exception
632 {
633 String workspaceName;
634 ProcessHome processHome;
635 String projectName;
636 TransactionDemarcation transactionDemarcation = new TransactionDemarcation();
637 boolean rollback = true;
638 int indexOfLastSeparator;
639 ImportTimer checkinTimer;
640 boolean importSuccess = true;
641
642 System.out.println ("********* ENTER *****************");
643
644
645
646 mSegmentCount = 0;
647 mNewUser = null;
648 mImportWorkerThreads = null;
649 mImportWorkerThreadsStatus = null;
650 mProcess = null;
651 mTotalAssets = 0;
652 mAssetsPerSecondExcludingCheckin = 0;
653 mAssetsPerSecondIncludingCheckin = 0;
654 mTotalTime = 0;
655 mFailedItemsFileWriter = null;
656 mFailedBatches = 0;
657 mErrorThresholdReached = false;
658 mCancelCommandReceived = false;
659
660
661
662 mServiceStatus = M_SERVICE_STATUS_PROJECT_CREATION;
663
664
665
666 try
667 {
668 transactionDemarcation.begin (getTransactionManager());
669
670 assumeUserIdentity();
671
672 projectName = getProjectName();
673
674 processHome = ProjectConstants.getPersistentHomes().getProcessHome();
675
676 mProcess = processHome.createProcessForImport (projectName, getWorkflowName(), false);
677
678 workspaceName = mProcess.getProject().getWorkspace();
679
680 mWorkspace = getVersionManager().getWorkspaceByName(workspaceName);
681
682 WorkingContext.pushDevelopmentLine (mWorkspace);
683
684 System.out.println ("SERVICE: Import Project Created. Id: " + mProcess.getProject().getId() + " Name: " + mProcess.getProject().getDisplayName());
685 rollback = false;
686 }
687 catch(VersionException e)
688 {
689 throw e;
690 }
691 catch (TransactionDemarcationException e)
692 {
693 throw e;
694 }
695 catch (CreateException e)
696 {
697 throw e;
698 }
699 catch (WorkflowException e)
700 {
701 throw e;
702 }
703 catch (ActionException e)
704 {
705 throw e;
706 }
707 catch (Exception e)
708 {
709 throw e;
710 }
711 finally
712 {
713 try
714 {
715 transactionDemarcation.end(rollback);
716 }
717 catch (TransactionDemarcationException tde)
718 {
719 throw tde;
720 }
721 }
722
723
724
725 if (mCancelCommandReceived)
726 {
727 System.out.println ("SERVICE: Import cancellation request received prior to data import. Delete the project and complete");
728 deleteProject ();
729 mServiceStatus = M_SERVICE_STATUS_CANCELLED;
730 return (false);
731 }
732
733
734
735 mServiceStatus = M_SERVICE_STATUS_PRE_DATA_IMPORT;
736
737
738
739 indexOfLastSeparator = getImportFilename().lastIndexOf(File.separator);
740
741 if (indexOfLastSeparator == -1)
742 {
743 mImportDirectory = "";
744 }
745 else
746 {
747 mImportDirectory = getImportFilename().substring (0, indexOfLastSeparator);
748 }
749
750
751
752 if (createFailedItemLogFile () == false)
753 {
754 System.out.println ("SERVICE: Item log file creation failed. Delete the project and complete");
755 deleteProject ();
756 mServiceStatus = M_SERVICE_STATUS_FATAL_ERROR_IO;
757 return (false);
758 }
759
760
761
762 if (createReferenceItemGenerator ())
763 {
764
765
766 if (mCancelCommandReceived)
767 {
768 System.out.println ("SERVICE: Import cancellation request received prior to data import (but after temporary reference generation). Delete the project and complete");
769 deleteProject ();
770 mServiceStatus = M_SERVICE_STATUS_CANCELLED;
771 return (false);
772 }
773
774
775
776 System.out.println ("SERVICE: Disabling the indexes");
777
778 if (disableIndexes () == false)
779 {
780 System.out.println ("SERVICE: Data import was unsuccessful. Unable to disable the indexes");
781 deleteProject ();
782 return (false);
783 }
784
785
786
787 importSuccess = importData ();
788
789
790
791 System.out.println ("SERVICE: Rebuilding the indexes");
792
793 if (rebuildIndexes () == false)
794 {
795 System.out.println ("SERVICE: Unable to rebuild the indexes");
796
797
798 }
799
800 if (!importSuccess)
801 {
802
803
804 System.out.println ("SERVICE: Data import was unsuccessful. Delete the project and complete");
805 deleteProject ();
806 return (false);
807 }
808 }
809 else
810 {
811 System.out.println ("SERVICE: failed to create the temporary reference items. Delete the project and complete");
812 deleteProject ();
813 mServiceStatus = M_SERVICE_STATUS_FATAL_ERROR_DATABASE;
814 return (false);
815 }
816
817 mServiceStatus = M_SERVICE_STATUS_PROJECT_ADVANCE_WORKFLOW;
818
819
820
821 System.out.println ("SERVICE: Data import complete. Check-in the project");
822
823 transactionDemarcation = new TransactionDemarcation();
824 rollback = true;
825
826 try
827 {
828 transactionDemarcation.begin (getTransactionManager());
829
830 checkinTimer = new ImportTimer ("CHECKIN TIME");
831 checkinTimer.start ();
832
833 advanceWorkflow (mProcess);
834
835 checkinTimer.stop ();
836 checkinTimer.display ();
837
838 mTotalTime += checkinTimer.getTime();
839
840 mAssetsPerSecondIncludingCheckin = mTotalAssets / (mTotalTime / 1000);
841
842 System.out.println ("SERVICE: ASSETS: " + mTotalAssets +
843 " ASSETS PER SECOND (Including Check In): " + mAssetsPerSecondIncludingCheckin);
844 rollback = false;
845 }
846 catch (TransactionDemarcationException e)
847 {
848 throw e;
849 }
850 catch (WorkflowException e)
851 {
852 throw e;
853 }
854 catch (ActionException e)
855 {
856 throw e;
857 }
858 catch (Exception e)
859 {
860 throw e;
861 }
862 finally
863 {
864 WorkingContext.popDevelopmentLine();
865 releaseUserIdentity();
866 try
867 {
868 transactionDemarcation.end(rollback);
869 }
870 catch (TransactionDemarcationException tde)
871 {
872 throw tde;
873 }
874 }
875
876 if (mDataImportErrors)
877 {
878 mServiceStatus = M_SERVICE_STATUS_COMPLETED_WITH_ERRORS;
879 }
880 else
881 {
882 mServiceStatus = M_SERVICE_STATUS_COMPLETED_SUCCESSFULLY;
883 }
884
885 return (true);
886 }
887
888
889 /***
890 * This method cancels the import.
891 */
892 public void cancelImport ()
893 {
894 synchronized (this)
895 {
896 mCancelCommandReceived = true;
897 }
898
899 return;
900 }
901
902
903 /***
904 * This method advances the workflow to the next state. If using an unaltered copy of the import-late
905 * or import-early workflows, then the taskOutcomeId property should not need to be changed
906 * (default is '4.1.1'). If you are using a different workflow or an altered version of the import-xxxx
907 * workflows, then the taskOutcomeId can be found in the wdl file for the respective workflow.
908 *
909 * @param pProcess the atg.epub.project.Process object (the project)
910 */
911 private void advanceWorkflow
912 (
913 Process pProcess
914 ) throws WorkflowException, ActionException
915 {
916 RepositoryItem processWorkflow = pProcess.getProject().getWorkflow();
917 String workflowProcessName = processWorkflow.getPropertyValue("processName").toString();
918 String subjectId = pProcess.getId();
919
920 try
921 {
922
923
924 WorkflowView wv = getWorkflowManager().getWorkflowView (ThreadSecurityManager.currentUser());
925
926 wv.fireTaskOutcome (workflowProcessName, WorkflowConstants.DEFAULT_WORKFLOW_SEGMENT,
927 subjectId,
928 getTaskOutcomeId(),
929 ActionConstants.ERROR_RESPONSE_DEFAULT);
930 }
931 catch (MissingWorkflowDescriptionException e)
932 {
933 System.out.println ("SERVICE: Advance Workflow Failed: MissingWorkflowDescriptionException: " + e.getMessage());
934 throw e;
935 }
936 catch (ActorAccessException e)
937 {
938 System.out.println ("SERVICE: Advance Workflow Failed: ActorAccessException: " + e.getMessage());
939 throw e;
940 }
941 catch (ActionException e)
942 {
943 System.out.println ("SERVICE: Advance Workflow Failed: ActionException: " + e.getMessage());
944 throw e;
945 }
946 catch (UnsupportedOperationException e)
947 {
948 System.out.println ("SERVICE: Advance Workflow Failed: UnsupportedOperationException: " + e.getMessage());
949 throw e;
950 }
951 }
952
953
954 /***
955 * This method sets the security context for the current thread so that the code executes correctly
956 * against secure resources.
957 *
958 * @return true if the identity was assumed, false otherwise
959 */
960 protected boolean assumeUserIdentity()
961 {
962 if (getUserAuthority () == null)
963 {
964 return false;
965 }
966
967 mNewUser = new User();
968
969 Persona persona = (Persona) getUserAuthority().getPersona(getPersonaPrefix() + getUserName());
970
971 if (persona == null)
972 {
973 return false;
974 }
975
976
977
978 mNewUser.addPersona(persona);
979
980
981
982 ThreadSecurityManager.setThreadUser (mNewUser);
983
984 return true;
985 }
986
987
988 /***
989 * This method unsets the security context on the current thread.
990 */
991 protected void releaseUserIdentity ()
992 {
993 ThreadSecurityManager.setThreadUser (null);
994 }
995
996
997 /***
998 * This method runs a multi-threaded data import.
999 */
1000 private boolean importData ()
1001 {
1002
1003
1004 int numberOfThreads = 0;
1005
1006 ImportTimer totalTimer = new ImportTimer ("TOTAL TIME");
1007 ImportTimer addUpdatePhaseTimer = new ImportTimer ("Add - Update Phase Time");
1008 ImportTimer referenceUpdatePhaseTimer = new ImportTimer ("Reference - Update Phase Time");
1009 ImportTimer deletePhaseTimer = new ImportTimer ("Delete Phase Time");
1010
1011 mServiceStatus = M_SERVICE_STATUS_DATA_IMPORT_BATCH_CREATION;
1012
1013
1014
1015 mSegmentCount = segmentImportFile ();
1016
1017 if (mSegmentCount == 0)
1018 {
1019 System.out.println ("SERVICE: There are no segments");
1020 mServiceStatus = M_SERVICE_STATUS_FATAL_ERROR_IO;
1021 return (false);
1022 }
1023
1024
1025
1026 if (mCancelCommandReceived)
1027 {
1028 System.out.println ("SERVICE: Import cancellation request received prior worker thread creation. Return data import failure");
1029 mServiceStatus = M_SERVICE_STATUS_CANCELLED;
1030 return (false);
1031 }
1032
1033 mServiceStatus = M_SERVICE_STATUS_DATA_IMPORT_ADD_UPDATE_PHASE;
1034
1035
1036
1037
1038 numberOfThreads = initiateImportWorkerThreads (mSegmentCount);
1039
1040 if (mCancelCommandReceived)
1041 {
1042 mServiceStatus = M_SERVICE_STATUS_FATAL_ERROR_THREADS;
1043 return (false);
1044 }
1045
1046
1047 System.out.println ("SERVICE: Sleeping for " + (numberOfThreads + 1) + " seconds to allow all threads to get started");
1048
1049 try
1050 {
1051 Thread.sleep (1000 * (numberOfThreads + 1));
1052 }
1053 catch (InterruptedException e)
1054 {
1055 }
1056
1057
1058
1059 totalTimer.start();
1060
1061 System.out.println ("SERVICE: ****** ADD / UPDATE phase");
1062
1063 addUpdatePhaseTimer.start();
1064
1065 startPhase (PHASE_ADD_UPDATE);
1066
1067
1068
1069 if (waitForPhaseCompletion () == false)
1070 {
1071 terminateImportWorkerThreads ();
1072 return (false);
1073 }
1074
1075 addUpdatePhaseTimer.stop();
1076 addUpdatePhaseTimer.display();
1077
1078
1079
1080 try
1081 {
1082 mReferenceItemGenerator.persistReferenceItemList ();
1083 }
1084 catch (IOException e)
1085 {
1086 System.out.println ("SERVICE: IOException: " + e.getMessage());
1087 }
1088
1089
1090
1091 mServiceStatus = M_SERVICE_STATUS_DATA_IMPORT_REFERENCE_UPDATE_PHASE;
1092
1093 System.out.println ("SERVICE: ****** REFERENCE UPDATE phase");
1094
1095 referenceUpdatePhaseTimer.start();
1096
1097 startPhase (PHASE_REFERENCE_UPDATE);
1098
1099
1100
1101 if (waitForPhaseCompletion () == false)
1102 {
1103 System.out.println ("SERVICE: REFERENCE / UPDATE phase terminated. Terminate any running worker threads and return data import failure");
1104 terminateImportWorkerThreads ();
1105 return (false);
1106 }
1107
1108 referenceUpdatePhaseTimer.stop();
1109 referenceUpdatePhaseTimer.display();
1110
1111
1112
1113 System.out.println ("SERVICE: ****** DELETE phase");
1114
1115 mServiceStatus = M_SERVICE_STATUS_DATA_IMPORT_DELETE_PHASE;
1116
1117 deletePhaseTimer.start();
1118
1119 startPhase (PHASE_DELETE);
1120
1121
1122
1123 if (waitForPhaseCompletion () == false)
1124 {
1125 System.out.println ("SERVICE: DELETE phase terminated. Terminate any running worker threads and return data import failure");
1126 terminateImportWorkerThreads ();
1127 return (false);
1128 }
1129
1130 deletePhaseTimer.stop();
1131 deletePhaseTimer.display();
1132
1133
1134
1135 terminateImportWorkerThreads ();
1136
1137 if (mCancelCommandReceived)
1138 {
1139 System.out.println ("SERVICE: Import cancellation request received prior to processing failed deletions. Return data import failure");
1140 mServiceStatus = M_SERVICE_STATUS_CANCELLED;
1141 return (false);
1142 }
1143
1144 mServiceStatus = M_SERVICE_STATUS_DATA_IMPORT_PROCESSING_FAILED_DELETIONS;
1145
1146 processFailedDeletions ();
1147
1148
1149
1150 mReferenceItemGenerator.deleteAllDummyReferenceItems ();
1151
1152 totalTimer.stop();
1153 totalTimer.display();
1154
1155
1156
1157 mTotalTime += totalTimer.getTime();
1158
1159 mAssetsPerSecondExcludingCheckin = mTotalAssets / (totalTimer.getTime() / 1000);
1160
1161 System.out.println ("SERVICE: ASSETS: " + mTotalAssets +
1162 " ASSETS PER SECOND (Excluding Check In): " + mAssetsPerSecondExcludingCheckin);
1163
1164 if (mCancelCommandReceived)
1165 {
1166 System.out.println ("SERVICE: Import cancellation request received during failed deletion processing. Return data import failure");
1167 return (false);
1168 }
1169 else
1170 {
1171 return (true);
1172 }
1173 }
1174
1175
1176 /***
1177 * This method creates and starts the appropriate number of import worker threads.
1178 */
1179 private int initiateImportWorkerThreads (int pSegmentCount)
1180 {
1181 int numberOfThreads = 0;
1182 int segmentsPerThread = 0;
1183 int startSegment = 1;
1184 int endSegment = 1;
1185 int extras = 0;
1186
1187
1188
1189 if (pSegmentCount > getMaxImportThreads())
1190 {
1191 numberOfThreads = getMaxImportThreads();
1192 segmentsPerThread = pSegmentCount / numberOfThreads;
1193 extras = pSegmentCount % numberOfThreads;
1194 }
1195 else
1196 {
1197 numberOfThreads = pSegmentCount;
1198 segmentsPerThread = 1;
1199 extras = 0;
1200 }
1201
1202 mImportWorkerThreads = new ImportWorkerThread[numberOfThreads];
1203 mImportWorkerThreadsStatus = new int[numberOfThreads];
1204
1205
1206
1207 for (int index = 0; index < numberOfThreads; index++)
1208 {
1209 if (extras > 0)
1210 {
1211 endSegment = startSegment + segmentsPerThread;
1212 extras--;
1213 }
1214 else
1215 {
1216 endSegment = startSegment + segmentsPerThread - 1;
1217 }
1218
1219
1220
1221 mImportWorkerThreads[index] = new ImportWorkerThread (index, this, startSegment, endSegment);
1222 mImportWorkerThreadsStatus[index] = THREAD_STATUS_STARTED;
1223 mImportWorkerThreads[index].start ();
1224
1225
1226
1227 startSegment = endSegment + 1;
1228 }
1229
1230 return (numberOfThreads);
1231 }
1232
1233
1234 /***
1235 * This method starts the import for the specified phase.
1236 */
1237 private void startPhase (int pPhase)
1238 {
1239 mFailedBatches = 0;
1240
1241 for (int index = 0; index < mImportWorkerThreads.length; index++)
1242 {
1243
1244
1245 mImportWorkerThreads[index].setPhase (pPhase);
1246
1247
1248
1249 synchronized (mImportWorkerThreads[index])
1250 {
1251 mImportWorkerThreadsStatus[index] = THREAD_STATUS_NOTIFIED;
1252 mImportWorkerThreads[index].notify ();
1253 }
1254 }
1255
1256 return;
1257 }
1258
1259
1260 /***
1261 * This method waits for the specified phase to complete.
1262 */
1263 private boolean waitForPhaseCompletion ()
1264 {
1265 int activeThreads;
1266
1267 while (true)
1268 {
1269
1270
1271
1272
1273
1274 activeThreads = 0;
1275
1276 for (int index = 0; index < mImportWorkerThreads.length; index++)
1277 {
1278 if (mImportWorkerThreads[index].isAlive() == false)
1279 {
1280
1281
1282 if (getCancelCommandReceived())
1283 {
1284 if (mErrorThresholdReached)
1285 {
1286 mServiceStatus = M_SERVICE_STATUS_FATAL_ERROR_THRESHOLD_REACHED;
1287 }
1288 else
1289 {
1290 mServiceStatus = M_SERVICE_STATUS_CANCELLED;
1291 }
1292 }
1293 else
1294 {
1295 mServiceStatus = M_SERVICE_STATUS_FATAL_ERROR_THREADS;
1296 }
1297
1298 return (false);
1299 }
1300
1301 if (mImportWorkerThreadsStatus[index] != THREAD_STATUS_PHASE_COMPLETED)
1302 {
1303
1304
1305 activeThreads++;
1306 }
1307 }
1308
1309
1310
1311 if (activeThreads == 0)
1312 {
1313
1314
1315 break;
1316 }
1317
1318
1319
1320 try
1321 {
1322 Thread.sleep (mThreadMonitorInterval);
1323 }
1324 catch (InterruptedException e)
1325 {
1326 }
1327 }
1328
1329 return (true);
1330 }
1331
1332
1333 /***
1334 * This method starts the appropriate number of import worker threads.
1335 */
1336 private void terminateImportWorkerThreads ()
1337 {
1338
1339
1340 for (int index = 0; index < mImportWorkerThreads.length; index++)
1341 {
1342 if (mImportWorkerThreads[index].isAlive())
1343 {
1344 mImportWorkerThreads[index].interrupt();
1345 }
1346 }
1347
1348
1349
1350 for (int index = 0; index < mImportWorkerThreads.length; index++)
1351 {
1352 try
1353 {
1354 mImportWorkerThreads[index].join();
1355 }
1356 catch (InterruptedException e)
1357 {
1358 }
1359 }
1360
1361 return;
1362 }
1363
1364 public synchronized void notifyThreadStatus (int pThreadIndex, String pName, int pStatus)
1365 {
1366 mImportWorkerThreadsStatus[pThreadIndex] = pStatus;
1367 }
1368
1369 public synchronized void processFailedDeletions ()
1370 {
1371 int pass = 1;
1372 List toRemove = mFailedDeletions;
1373 ImportItem importItem;
1374 MutableRepository targetRepository = (MutableRepository) getTargetRepository();
1375 boolean rollback = true;
1376 RepositoryItem itemToRemove = null;
1377
1378 if (toRemove.size() == 0)
1379 {
1380 return;
1381 }
1382
1383 while (!toRemove.isEmpty() && pass < 25)
1384 {
1385 Iterator iterator = toRemove.iterator();
1386
1387 while (iterator.hasNext())
1388 {
1389 TransactionDemarcation transactionDemarcation = new TransactionDemarcation();
1390
1391 try
1392 {
1393 transactionDemarcation.begin (getTransactionManager(),TransactionDemarcation.REQUIRED);
1394
1395 importItem = (ImportItem) iterator.next();
1396
1397 itemToRemove = targetRepository.getItem (importItem.getItemId(), importItem.getItemDescriptor());
1398
1399 if (itemToRemove != null)
1400 {
1401 RepositoryUtils.removeReferencesToItem (itemToRemove);
1402 targetRepository.removeItem (importItem.getItemId(), importItem.getItemDescriptor());
1403 }
1404
1405 rollback = false;
1406 }
1407 catch (RepositoryException e)
1408 {
1409
1410 }
1411 catch (TransactionDemarcationException e)
1412 {
1413
1414 }
1415 finally
1416 {
1417 try
1418 {
1419 transactionDemarcation.end (rollback);
1420
1421 if (!rollback)
1422 {
1423 iterator.remove();
1424 }
1425 }
1426 catch (TransactionDemarcationException e)
1427 {
1428 }
1429 }
1430 }
1431
1432 pass++;
1433 }
1434 }
1435
1436
1437 /***
1438 * This method segments the import file into chunks of items. Each chunk is
1439 * stored in a temporary file for processing. Chunk size is dictated by
1440 * the mItemBatchSize property.
1441 */
1442 private int segmentImportFile ()
1443 {
1444 File importFile = null;
1445 int segmentCount = 0;
1446 int itemCount = 0;
1447 File segmentFile = null;
1448 FileWriter segmentFileWriter = null;
1449 String segmentFilename = null;
1450 boolean createNewFile = true;
1451 boolean writeLineToRecord = false;
1452 String line;
1453 ArrayList additions = new ArrayList ();
1454 ArrayList others = new ArrayList ();
1455 StringBuffer record = new StringBuffer ();
1456 boolean addRecord = false;
1457
1458 int numberOfCatalogItems = 0;
1459 int numberOfCategoryItems = 0;
1460 int numberOfProductItems = 0;
1461 int numberOfSkuItems = 0;
1462 int numberOfMediaExternalItems = 0;
1463 int numberOfFolderItems = 0;
1464
1465 mTotalAssets = 0;
1466
1467
1468
1469 if (getImportFilename() == null)
1470 {
1471 System.out.println ("No import file specified.");
1472 return (0);
1473 }
1474
1475
1476
1477 importFile = new File (getImportFilename());
1478
1479 if (!importFile.exists())
1480 {
1481 System.out.println ("The specified import file does not exist.");
1482 return (0);
1483 }
1484
1485
1486
1487 try
1488 {
1489 BufferedReader bufferedReader = new BufferedReader (new FileReader (importFile));
1490
1491 while ((line = bufferedReader.readLine()) != null)
1492 {
1493
1494
1495 if (line.contains (M_TAG_ADD_ITEM_START) ||
1496 line.contains(M_TAG_UPDATE_ITEM_START) || line.contains(M_TAG_REMOVE_ITEM_START))
1497 {
1498
1499
1500 if (line.contains (M_ITEM_CATALOG))
1501 {
1502 numberOfCatalogItems++;
1503 }
1504 else if (line.contains (M_ITEM_CATEGORY))
1505 {
1506 numberOfCategoryItems++;
1507 }
1508 else if (line.contains (M_ITEM_PRODUCT))
1509 {
1510 numberOfProductItems++;
1511 }
1512 else if (line.contains (M_ITEM_SKU))
1513 {
1514 numberOfSkuItems++;
1515 }
1516 else if (line.contains (M_ITEM_MEDIA_EXTERNAL))
1517 {
1518 numberOfMediaExternalItems++;
1519 }
1520 else if (line.contains (M_ITEM_FOLDER))
1521 {
1522 numberOfFolderItems++;
1523 }
1524
1525
1526
1527 record = new StringBuffer ();
1528
1529 record.append (line + "\n");
1530
1531 if (line.contains (M_TAG_ADD_ITEM_START))
1532 {
1533 addRecord = true;
1534 }
1535 else
1536 {
1537 addRecord = false;
1538 }
1539
1540
1541
1542 if (createNewFile)
1543 {
1544
1545
1546 segmentFilename = M_SEGMENT_FILE_STUB + (segmentCount + 1) + M_SEGMENT_FILE_EXTENSION;
1547 segmentFile = new File (mImportDirectory, segmentFilename);
1548 segmentFile.createNewFile();
1549 segmentFileWriter = new FileWriter (segmentFile, false);
1550
1551
1552
1553 segmentFileWriter.write ("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + "\n");
1554 segmentFileWriter.write ("<!DOCTYPE gsa-template SYSTEM \"dynamosystemresource:/atg/dtds/gsa/gsa_1.0.dtd\">" + "\n");
1555 segmentFileWriter.write ("<gsa-template>" + "\n");
1556 segmentFileWriter.flush ();
1557
1558 segmentCount++;
1559
1560 createNewFile = false;
1561 }
1562
1563 writeLineToRecord = true;
1564
1565 itemCount++;
1566 mTotalAssets++;
1567
1568 if (itemCount >= getItemBatchSize())
1569 {
1570 createNewFile = true;
1571 }
1572 }
1573 else if (line.contains (M_TAG_ADD_ITEM_END) ||
1574 line.contains(M_TAG_UPDATE_ITEM_END) || line.contains(M_TAG_REMOVE_ITEM_END))
1575 {
1576 record.append (line + "\n");
1577
1578 if (addRecord)
1579 {
1580 additions.add (record.toString());
1581 }
1582 else
1583 {
1584 others.add (record.toString());
1585 }
1586
1587 writeLineToRecord = false;
1588
1589
1590
1591 if (createNewFile)
1592 {
1593
1594
1595 if (additions.size() > 0)
1596 {
1597 segmentFileWriter.write ("<import-items>\n");
1598
1599 Iterator additionsIterator = additions.iterator();
1600
1601 while (additionsIterator.hasNext())
1602 {
1603 String additionString = (String) additionsIterator.next();
1604 segmentFileWriter.write (additionString + "\n");
1605 }
1606
1607 segmentFileWriter.write ("</import-items>\n");
1608 }
1609
1610
1611
1612 if (others.size() > 0)
1613 {
1614 Iterator othersIterator = others.iterator();
1615
1616 while (othersIterator.hasNext())
1617 {
1618 String otherString = (String) othersIterator.next();
1619 segmentFileWriter.write (otherString + "\n");
1620 }
1621 }
1622
1623
1624
1625 additions.clear();
1626 others.clear();
1627
1628
1629
1630 segmentFileWriter.write ("</gsa-template>" + "\n");
1631 segmentFileWriter.flush ();
1632 segmentFileWriter.close();
1633
1634 itemCount = 0;
1635 }
1636 }
1637 else if (writeLineToRecord)
1638 {
1639 record.append (line + "\n");
1640 }
1641 }
1642
1643
1644
1645 if (createNewFile == false)
1646 {
1647 if (additions.size() > 0)
1648 {
1649 segmentFileWriter.write ("<import-items>\n");
1650
1651 Iterator additionsIterator = additions.iterator();
1652
1653 while (additionsIterator.hasNext())
1654 {
1655 String additionString = (String) additionsIterator.next();
1656 segmentFileWriter.write (additionString + "\n");
1657 }
1658
1659 segmentFileWriter.write ("</import-items>\n");
1660 }
1661
1662
1663
1664 if (others.size() > 0)
1665 {
1666 Iterator othersIterator = others.iterator();
1667
1668 while (othersIterator.hasNext())
1669 {
1670 String otherString = (String) othersIterator.next();
1671 segmentFileWriter.write (otherString + "\n");
1672 }
1673 }
1674
1675 segmentFileWriter.write ("</gsa-template>" + "\n");
1676 segmentFileWriter.flush ();
1677 segmentFileWriter.close();
1678 }
1679 }
1680 catch (IOException io)
1681 {
1682 System.out.println ("IOException: " + io.getMessage());
1683 }
1684
1685 return segmentCount;
1686 }
1687
1688 private boolean createReferenceItemGenerator ()
1689 {
1690 boolean createdSuccessfully = true;
1691
1692
1693
1694 mReferenceItemGenerator = new ReferenceItemGenerator (this);
1695
1696 try
1697 {
1698 mReferenceItemGenerator.initialiseReferenceItemGenerator ();
1699 }
1700 catch (RepositoryException e)
1701 {
1702 System.out.println ("SERVICE: RepositoryException: " + e.getMessage());
1703 createdSuccessfully = false;
1704 }
1705 catch (IOException e)
1706 {
1707 System.out.println ("SERVICE: IOException: " + e.getMessage());
1708 createdSuccessfully = false;
1709 }
1710
1711 return (createdSuccessfully);
1712 }
1713
1714 private boolean createFailedItemLogFile ()
1715 {
1716 boolean success = true;
1717 String failedItemsFilename = getImportDirectory() + File.separator + M_FAILURES_FILENAME;
1718
1719 File failedItemsFile = new File (failedItemsFilename);
1720
1721 try
1722 {
1723 failedItemsFile.createNewFile();
1724 mFailedItemsFileWriter = new FileWriter (failedItemsFile, false);
1725 }
1726 catch (IOException e)
1727 {
1728 System.out.println ("IOException: " + e.getMessage());
1729 return (false);
1730 }
1731
1732 return (true);
1733 }
1734
1735 public synchronized void logBatchFailure (int pSegmentIndex, int pPhase)
1736 {
1737 float errorPercentage = 0;
1738
1739 logFailureMessage ("======== FAILED BATCH ======== (Phase " + pPhase + ")\n");
1740 logFailureMessage ("BATCH FILE: " + M_SEGMENT_FILE_STUB + pSegmentIndex + M_SEGMENT_FILE_EXTENSION + "\n");
1741 logFailureMessage ("ERROR MESSAGE: Batch rejected or import cancellation received\n");
1742
1743 mFailedBatches++;
1744
1745
1746
1747 errorPercentage = ((float) mFailedBatches / (float) mSegmentCount) * 100;
1748
1749 if (errorPercentage >= getErrorThresholdPerImport())
1750 {
1751
1752
1753 System.out.println ("SERVICE: The import error threshold has been reached. Cancelling the import... ");
1754 mErrorThresholdReached = true;
1755 cancelImport ();
1756 }
1757 }
1758
1759 public void logFailedItem (ImportFailedItem pFailedItem, int pPhase)
1760 {
1761 logFailureMessage ("======== FAILED ITEM ======== (Phase " + pPhase + ")\n");
1762 logFailureMessage ("TYPE: " + pFailedItem.getItemDescriptor() + "\n");
1763 logFailureMessage ("ID: " + pFailedItem.getItemId() + "\n");
1764
1765 switch (pFailedItem.getAction())
1766 {
1767 case ImportItem.M_ACTION_ADD:
1768
1769 logFailureMessage ("ACTION: add-item" + "\n");
1770
1771 break;
1772
1773 case ImportItem.M_ACTION_UPDATE:
1774
1775 logFailureMessage ("ACTION: update-item" + "\n");
1776
1777 break;
1778
1779 case ImportItem.M_ACTION_DELETE:
1780
1781 logFailureMessage ("ACTION: remove-item" + "\n");
1782
1783 break;
1784 }
1785
1786 logFailureMessage ("BATCH FILE: " + pFailedItem.getBatchFilename() + "\n");
1787 logFailureMessage ("ERROR MESSAGE: " + pFailedItem.getMessage() + "\n");
1788 }
1789
1790 public synchronized void logFailureMessage (String pMessage)
1791 {
1792 try
1793 {
1794 mFailedItemsFileWriter.write (pMessage);
1795 mFailedItemsFileWriter.flush();
1796 }
1797 catch (IOException e)
1798 {
1799 }
1800 }
1801
1802 private void deleteProject ()
1803 {
1804 if (mProcess.getProject() != null)
1805 {
1806 try
1807 {
1808 mProcess.getProject().delete (mNewUser.toString());
1809 }
1810 catch (Exception e)
1811 {
1812 }
1813 }
1814 }
1815
1816 private boolean disableIndexes ()
1817 {
1818 String indexQueryText;
1819 String indexDisableText;
1820 PreparedStatement indexQueryStatement;
1821 PreparedStatement indexDisableStatement;
1822 ResultSet indexResults;
1823 String indexName;
1824 Iterator indexIterator;
1825
1826
1827
1828 if (databaseConnect () == false)
1829 {
1830 return (false);
1831 }
1832
1833 mIndexNames = new ArrayList ();
1834
1835
1836
1837 try
1838 {
1839 indexQueryText = "select a.index_name from user_indexes a, user_constraints b " +
1840 "where b.CONSTRAINT_NAME != a.index_name and " +
1841 "b.CONSTRAINT_TYPE = 'P' and " +
1842 "a.table_name = b.table_name and " +
1843 "a.generated = 'N' and " +
1844 "a.INDEX_TYPE = 'NORMAL'";
1845
1846 indexQueryStatement = mDatabaseConnection.prepareStatement (indexQueryText);
1847 indexResults = indexQueryStatement.executeQuery();
1848
1849 while (indexResults.next())
1850 {
1851 indexName = indexResults.getString (1);
1852 mIndexNames.add (indexName);
1853 }
1854
1855 indexResults.close();
1856 indexQueryStatement.close();
1857 }
1858 catch (SQLException e)
1859 {
1860 System.out.println ("SQLException when querying: " + e.getMessage());
1861 return (false);
1862 }
1863
1864
1865
1866 try
1867 {
1868 indexIterator = mIndexNames.iterator();
1869
1870 while (indexIterator.hasNext())
1871 {
1872 indexName = (String) indexIterator.next();
1873
1874 indexDisableText = "alter index " + indexName + " unusable";
1875 indexDisableStatement = mDatabaseConnection.prepareStatement (indexDisableText);
1876 indexDisableStatement.executeUpdate();
1877 indexDisableStatement.close();
1878 }
1879 }
1880 catch (SQLException e)
1881 {
1882 System.out.println ("SQLException when disabling: " + e.getMessage());
1883 return (false);
1884 }
1885
1886
1887
1888 databaseDisconnect ();
1889
1890 return (true);
1891 }
1892
1893 private boolean rebuildIndexes ()
1894 {
1895 String indexRebuildText;
1896 PreparedStatement indexRebuildStatement;
1897 String indexName;
1898 Iterator indexIterator;
1899
1900
1901
1902 if (databaseConnect () == false)
1903 {
1904 return (false);
1905 }
1906
1907
1908
1909 try
1910 {
1911 indexIterator = mIndexNames.iterator();
1912
1913 while (indexIterator.hasNext())
1914 {
1915 indexName = (String) indexIterator.next();
1916
1917 indexRebuildText = "alter index " + indexName + " rebuild";
1918 indexRebuildStatement = mDatabaseConnection.prepareStatement (indexRebuildText);
1919 indexRebuildStatement.executeUpdate();
1920 indexRebuildStatement.close();
1921 }
1922 }
1923 catch (SQLException e)
1924 {
1925 System.out.println ("SQLException when rebuilding: " + e.getMessage());
1926 return (false);
1927 }
1928
1929
1930
1931 databaseDisconnect ();
1932
1933 return (true);
1934 }
1935
1936 private boolean databaseConnect ()
1937 {
1938 try
1939 {
1940 Class.forName (mDatabaseDriver);
1941 }
1942 catch (ClassNotFoundException e)
1943 {
1944 System.out.println ("ClassNotFoundException: " + e.getMessage());
1945 return (false);
1946 }
1947
1948 try
1949 {
1950 mDatabaseConnection = DriverManager.getConnection (mDatabaseUrl, mDatabaseUsername,
1951 mDatabasePassword);
1952 }
1953 catch (SQLException e)
1954 {
1955 System.out.println ("SQLException: " + e.getMessage());
1956 return (false);
1957 }
1958
1959 return (true);
1960 }
1961
1962 private boolean databaseDisconnect ()
1963 {
1964 try
1965 {
1966 mDatabaseConnection.close ();
1967 }
1968 catch (SQLException e)
1969 {
1970 System.out.println ("Failed to disconnect from the database: " + e.getMessage());
1971 return (false);
1972 }
1973
1974 return (true);
1975 }
1976
1977 public static void main(String[] args)
1978 {
1979 ImportService service = new ImportService();
1980
1981
1982 service.mDatabaseDriver="oracle.jdbc.driver.OracleDriver";
1983 service.mDatabaseUrl="jdbc:oracle:thin:@McErlean-60:1521:ADMIN";
1984 service.mDatabaseUsername="publishing";
1985 service.mDatabasePassword="publishing";
1986
1987 service.disableIndexes();
1988 service.rebuildIndexes();
1989 }
1990 }