Source code: com/flexstor/common/gui/imprt/ImportModel.java
1 /*
2 * ImportModel.java
3 *
4 * Copyright $Date: 2003/08/11 02:22:30 $ 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.common.gui.imprt;
12
13 import java.io.File;
14 import java.rmi.RemoteException;
15 import java.util.ArrayList;
16 import java.util.Date;
17 import java.util.Observable;
18 import java.util.Observer;
19 import java.util.Vector;
20
21 import com.flexstor.common.awt.appserver.AppServerClientAwtWrapper;
22 import com.flexstor.common.awt.dialogs.MessageBox;
23 import com.flexstor.common.awt.taskframe.TaskFrame;
24 import com.flexstor.common.awt.taskframe.TaskFrameManager;
25 import com.flexstor.common.constants.ActionPropertiesI;
26 import com.flexstor.common.constants.ServicesI;
27 import com.flexstor.common.data.ActionData;
28 import com.flexstor.common.data.ActionResult;
29 import com.flexstor.common.data.AssetRecordData;
30 import com.flexstor.common.data.TraversalInfo;
31 import com.flexstor.common.data.TraversalItem;
32 import com.flexstor.common.data.ejb.sequence.SequenceData;
33 import com.flexstor.common.disguise.DisguiseUtils;
34 import com.flexstor.common.disguise.DisplayUtils;
35 import com.flexstor.common.errorlogger.FlexError;
36 import com.flexstor.common.exceptions.ImportFailedException;
37 import com.flexstor.common.io.FileAccessProtocol;
38 import com.flexstor.common.io.xfile.FlexXFile;
39 import com.flexstor.common.io.xfile.XFileCopy;
40 import com.flexstor.common.modules.registry.BaseInstanceI;
41 import com.flexstor.common.resources.Resources;
42 import com.flexstor.common.settings.ImportSettingManagerI;
43 import com.flexstor.common.settings.ImportSettings;
44 import com.flexstor.common.settings.ImportSettingsI;
45 import com.flexstor.common.settings.Settings;
46 import com.flexstor.common.util.Diagnostic;
47 import com.flexstor.common.util.InetUtil;
48 import com.flexstor.common.util.ServerList;
49 import com.flexstor.common.util.UrlBuilder;
50
51 /**
52 * Data model for Import.
53 * @author Praveen Jani
54 */
55
56
57 public class ImportModel extends AbstractImportModel
58
59 {
60
61 /**
62 * The app server host name.
63 */
64 private String appServerHost = "";
65
66 /**
67 * App server host temp directory.
68 */
69 private String appServerHostTmpDir = "";
70
71 /**
72 * Import status.
73 */
74 private String sStatus = "";
75
76 /**
77 * The unique transaction number for this import session. All the loggings are done
78 * in respect if this number.
79 */
80 private int transactionNumber = -1;
81
82 /**
83 * Current base instance object. Represents the tree node where import is to be done. It is null
84 * when the Import is done from the main tool bar.
85 */
86 private BaseInstanceI currentAsset = null;
87
88 /**
89 * Flag that indicates whether import is done from the main tool bar or from the search
90 * retrieval.
91 */
92 private boolean bFromRetrieval = false;
93
94
95 /**
96 * The path for the import_gui directory.
97 */
98 private String IMPORT_GUI_PATH = Settings.getString ( Settings.IMPORT_GUI_DIRECTORY );
99
100 /**
101 * Name of the service to be called for the import.
102 */
103 private String SERVICE_NAME = ServicesI.IMPORT_ACTIONDATA_SERVICE;
104
105 /**
106 * Disguise utility class.
107 */
108 private DisplayUtils dUtils = new DisplayUtils ();
109
110 /**
111 * Status frame
112 */
113 private TaskFrame tfStatus = null;
114
115 /**
116 * Flag to indicate whether import is to be done immediately
117 * or to be queued.
118 */
119 private boolean bImportImmediately = false;
120
121 /**
122 * Flag to indicate whether import is to be done immediately
123 * or to be queued.
124 */
125 private Date queueDate = null;
126
127 /**
128 * App server remote file protocol
129 */
130
131 private String appServerRemoteProtocol;
132
133
134
135
136
137 /**
138 * Constructor, which is called when the Import frame is brought up from the main tool bar.
139 *
140 * @param manager The Import manager, that handles the database and WebNFS related operations.
141 */
142 public ImportModel ( ImportSettingManagerI manager )
143 {
144 super ( manager );
145 appServerHost = Settings.getString( Settings.APP_SERVER_HOST );
146 appServerHostTmpDir = Settings.getString( Settings.APP_SERVER_TMP_DIR );
147 appServerRemoteProtocol = Settings.getString( Settings.APP_SERVER_REMOTE_FILE_PROTOCOL );
148 }
149 /**
150 * Constructor that is called when the Import frame is brought from the search retrieval frame.
151 *
152 * @param manager The Import manager that handles the database ans WebNFS related operations.
153 * @param baseInstance Represents the node of the tree on the search retrieval frame. From the Import stand point, it can represent
154 * a normal bucket or an element.
155 */
156
157 public ImportModel ( ImportSettingManagerI manager, BaseInstanceI baseInstance )
158 {
159 this ( manager );
160 this.bFromRetrieval = true;
161 currentAsset = baseInstance;
162 }
163
164 /**
165 * Constructor.
166 *
167 * @param manager The Import manager that handles the database ans WebNFS related operations.
168 * @param setting Represents the current import setting.
169 */
170 public ImportModel ( ImportSettingManagerI mgr, ImportSettingsI setting )
171 {
172 this ( mgr );
173 setCurrentImportSetting ( setting );
174 }
175 /**
176 * Constructor.
177 *
178 * @param manager The Import manager that handles the database ans WebNFS related operations.
179 * @param setting Represents the current import setting.
180 * @param baseInstance Represents the current base instance.
181 */
182 public ImportModel ( ImportSettingManagerI mgr,
183 ImportSettingsI setting,
184 BaseInstanceI baseInstance )
185 {
186 this ( mgr, baseInstance );
187 setCurrentImportSetting ( setting );
188 }
189
190
191 /**
192 * Returns the base instance object. It represents the node of the tree on the search retrieval frame. From the Import stand point
193 * it can represent a normal bucket or an element.
194 *
195 * @return BaseInstanceI - Data object representing a normal bucket or element on the search retrieval
196 * frame tree.
197 * @since 3.0
198 * @see com.flexstor.common.module.registry.BaseInstanceI
199 */
200 public BaseInstanceI getCurrentAsset ()
201 {
202 return currentAsset;
203 }
204
205 /**
206 * Initializes the model. And checks if the installtion and configuration meets the basic
207 * requirements to do a Import. It includes :
208 *
209 * 1. There should be an import/upload subdirectory inside installation\conf.
210 * 2. It should have proper read/write/execute permissions.
211 *
212 * @return true\false - False if any of the above mentioned requirements are not met, true otherwise.
213 * @since 3.0
214 */
215 public boolean initialize ()
216 {
217 if ( ! properInstall() )
218 {
219 // message
220 MessageBox.showMessageDialog ( null, 6654 );
221 return false;
222 }
223 // Checks if IMPORT_GUI_DIRECTORY has sufficient permission
224 if ( !dirHasSufficientPermission() )
225 {
226 // message
227 MessageBox.showMessageDialog ( null, 6732, IMPORT_GUI_PATH );
228 return false;
229 }
230
231 if ( !loadUserDefaultImportSetting () )
232 {
233 if ( !loadSystemDefaultImportSetting() )
234 {
235 return false;
236 }
237 }
238 return true;
239 }
240
241 /**
242 * Loads the user's own default import setting.
243 *
244 * @return true\false - indicates whether properly loaded or not. There are reasons that it could return false
245 * for example, if there is no subdirectory under /conf/import/upload representing the user's
246 * default import setting or if the directory exist but does not have read\execute permissions.
247 * If this loading fails, system own default setting is loaded.
248 */
249 public boolean loadUserDefaultImportSetting()
250 {
251 if ( manager == null )
252 {
253 return false;
254 }
255
256 String userImportSetting = manager.getDefaultImportSetting();
257 if ( ( userImportSetting == null ) ||
258 ( userImportSetting.trim().equals ("") ) )
259 return false;
260
261 if ( importSettings == null )
262 importSettings = new ImportSettings();
263
264
265 String userCtl = IMPORT_GUI_PATH +userImportSetting+"/"+userImportSetting+".ctl";
266
267 // make the path compatible to the protocol specified in properties file
268 String path = makePathClientProtocolCompatible ( userCtl );
269 if ( importSettings.loadSettingsFromFile ( path ) )
270 {
271 importSettings.setString ( ImportSettingsI.NAME, userImportSetting, true );
272 importSettings.setString ( ImportSettingsI.CTL_PATH, path, true );
273 importSettings.setBoolean ( ImportSettingsI.SET_AS_DEFAULT, true, true );
274 importSettings.setString ( ImportSettingsI.USER_ID, Settings.getString ( Settings.USER_ID ), true );
275 importSettings.setBoolean ( ImportSettingsI.TO_CLASSIFY, !bFromRetrieval , true );
276
277 }
278 else
279 {
280 MessageBox.showMessageDialog ( null, 6656, userImportSetting+".ctl" );
281 return false;
282 }
283 return true;
284 }
285
286 /**
287 * Loads the systems own default import setting in case the user does not have his\her own default
288 * import setting Or the user's own default Import setting could not be loaded.
289 *
290 * @return true\false - indicates whether setting is properly loaded or not. There are reasons that it could return false
291 * for example, if there is no subdirectory under /conf/import/upload representing the system's
292 * default import setting or if the directory exist but does not have read\execute permissions.
293 * If this loading fails, Import can not proceed.
294 */
295 public boolean loadSystemDefaultImportSetting()
296 {
297
298 String defaultCtl = IMPORT_GUI_PATH + "default/default.ctl";
299
300 if ( importSettings == null )
301 importSettings = new ImportSettings();
302
303 String path = makePathClientProtocolCompatible ( defaultCtl );
304
305 if ( !importSettings.loadSettingsFromFile ( path ) )
306 {
307 MessageBox.showMessageDialog ( null, 6655, "default.ctl" );
308 return false;
309 }
310
311 importSettings.setString ( ImportSettingsI.NAME, "default", true );
312 importSettings.setString ( ImportSettingsI.CTL_PATH, path, true );
313 importSettings.setString ( ImportSettingsI.USER_ID, Settings.getString ( Settings.USER_ID ), true );
314
315 importSettings.setBoolean( ImportSettingsI.TO_CLASSIFY, !bFromRetrieval , true );
316
317 // importSettings.print();
318
319 return true;
320 }
321
322 /**
323 * Reloads current import setting.
324 * @return true\false - indicates whether setting is properly loaded or not. There are reasons that it could return false
325 * for example, if there is no subdirectory under /conf/import/upload representing the system's
326 * default import setting or if the directory exist but does not have read\execute permissions.
327 * If this loading fails, Import can not proceed.
328 */
329 public boolean reloadCurrentImportSetting()
330 {
331 if ( getCurrentImportSetting() != null )
332 {
333 if ( !getCurrentImportSetting().reload() )
334 {
335 MessageBox.showMessageDialog ( null, 6804, getCurrentImportSetting().getString ( ImportSettingsI.NAME) );
336 getCurrentImportSetting().init();
337 notifyAllObservers ( new Notification ( ImportSettingsI.SETTING_CHANGED, Boolean.TRUE ) );
338 return false;
339 }
340 notifyAllObservers ( new Notification ( ImportSettingsI.SETTING_CHANGED, Boolean.TRUE ) );
341 return true;
342 }
343 return false;
344 }
345
346 /**
347 * Check if Import can be performed.
348 *
349 * @return true\false
350 */
351 public boolean canPerform()
352 {
353 return false;
354 }
355
356
357 /**
358 * Function that actually imports the assets. Note that we DO NOT allow import using the system default import
359 * setting (known by the name 'default'), therefore it first checks if the user has selected some other
360 * import setting Or created one of his\her own. Then starts the process of creation of the ActionData
361 * object. Depending whether it is called from the search retrieval frame or from the main tool bar, traversal
362 * path is created for each asset record (representing files to be imported), these asset record data
363 * objects are then added to the ActionData, and appropriate service is called.
364 * Status frame is shown to let the user know about import process step by step.
365 *
366 * @since 3.0
367 */
368 // imports the file
369 public synchronized void importFiles()
370 {
371 ArrayList list = getFilesToBeImported();
372
373 if ( ( list == null ) || ( list.size() == 0 ) )
374 return; // nothing to do !
375
376 if ( getCurrentImportSetting() != null )
377 {
378 Object date = getCurrentImportSetting().getObject( ImportSettingsI.IMPORTTIME );
379 if ( date instanceof Date )
380 {
381 queueDate = ( Date ) date;
382 bImportImmediately = false;
383 }
384 else
385 {
386 queueDate = null;
387 bImportImmediately = true;
388 }
389 doImport(); // call the big one !
390 }
391 }
392
393 /**
394 * Attaches an observer.
395 *
396 * @param object Observer object.
397 * @since 3.0
398 */
399 //IObserve Interface
400 public void attachObserver( Object object )
401 {
402 super.addObserver ( ( Observer )object );
403 }
404
405 /**
406 * Detaches an observer
407 *
408 * @param object Observer object.
409 * @since 3.0
410 */
411 public void detachObserver( Object object )
412 {
413 super.deleteObserver ( ( Observer ) object );
414 }
415
416 /**
417 * Notifies all the observers.
418 *
419 * @since 3.0
420 */
421 public void notifyAllObservers()
422 {
423 super.setChanged();
424 super.notifyObservers();
425 super.clearChanged();
426 }
427
428 /**
429 * Notifies all the observers with a notifying object.
430 *
431 * @param object Notifying object.
432 * @since 3.0
433 */
434 public void notifyAllObservers( Object object )
435 {
436 super.setChanged();
437 super.notifyObservers( object );
438 super.clearChanged();
439 }
440 /**
441 * Implementation of Observer interface.
442 */
443 public void update ( Observable obs, Object obj ){}
444
445 /**
446 * Checks is the model has changed.
447 *
448 * @return true\false
449 * @since 3.0
450 */
451 public boolean isChanged()
452 {
453 return super.hasChanged();
454 }
455
456 /**
457 * Checks if the Import is supposed to be done from the retrieval search frame.
458 *
459 * @return true\false
460 * @since 3.0
461 */
462 public boolean isFromRetrieval()
463 {
464 return bFromRetrieval;
465 }
466
467 /**
468 * Checks if import process can proceed. It fails if an attempt is done to import assets
469 * using the default import setting.
470 *
471 * @return true\false
472 * @since 3.0
473 */
474 public boolean isDefaultImportSetting ()
475 {
476 if ( getCurrentImportSetting() != null )
477 {
478 String name = getCurrentImportSetting().getString( ImportSettingsI.NAME );
479 if ( name != null )
480 return name.trim().equals("default");
481 }
482 return false;
483 }
484 /**
485 * Checks if the disguise in the control is valid. If its from retrieval it can be a SYSTEM or
486 * STANDARD but if its from main tool bar it should be SYSTEM only. And as the same control file
487 * can be used for both, its possible that the user does not go to settings dialog to change the
488 * disguise.
489 *
490 * @return true\false
491 * @since 3.0
492 */
493 private boolean isValidDisguise ()
494 {
495 if ( getCurrentImportSetting() != null )
496 {
497 if ( bFromRetrieval ) // if from the search retrieval frame
498 {
499 if ( getCurrentAsset() != null )
500 {
501 try
502 {
503 if ( getCurrentAsset().getTraversalPath() != null )
504 {
505 dUtils.setCurrentDisguise ( getCurrentAsset().getTraversalPath().getDisguiseId() );
506 }
507 }
508 catch ( Exception exception ) // due to invalid disguise
509 {
510 // Invalid disguise
511 return false;
512 }
513
514 String disguiseInCtl = getCurrentImportSetting().getString ( ImportSettingsI.APPLICATION_NAME );
515 String disguiseToImportIn = dUtils.getDisguiseName();
516 if ( ( disguiseInCtl == null ) ||
517 ( disguiseToImportIn == null ) )
518 {
519 return false;
520 }
521 return disguiseInCtl.equals ( disguiseToImportIn );
522 }
523 }
524 else // from the main tool bar
525 {
526 String disguiseInCtl = getCurrentImportSetting().getString ( ImportSettingsI.APPLICATION_NAME );
527 // first check if this disguise is assigned to the user
528 if ( DisguiseUtils.doesDisguiseExist ( disguiseInCtl ) )
529 {
530 // now check if its a SYSTEM disguise
531 try
532 {
533 return DisguiseUtils.isSystemDisguise ( DisguiseUtils.getDisguiseId ( disguiseInCtl ) );
534 }
535 catch ( com.flexstor.common.disguise.exceptions.InvalidDisguiseException exception )
536 {
537 return false;
538 }
539 }
540 }
541 }
542 return false;
543 }
544 /**
545 * Checks is the installtion is proper for the import from the GUI. It fails if the ..
546 *
547 * 1. Either there is no //installtion/conf/import/upload/ subdirectory.
548 * 2. Ot the directory exists but does not have proper access permissions.
549 *
550 * @return true\false
551 */
552
553 // private functions
554 private boolean properInstall()
555 {
556 FlexXFile xFile = new FlexXFile( makePathClientProtocolCompatible( IMPORT_GUI_PATH ) );
557 System.out.println ( "Path to check "+makePathClientProtocolCompatible( IMPORT_GUI_PATH ) );
558 System.out.println ( "xFile.exists() "+xFile.exists() );
559 return xFile.exists();
560 }
561
562 /**
563 * Checks if the import_gui directory have sufficient access permissions.
564 *
565 * @return true\false
566 */
567 private boolean dirHasSufficientPermission()
568 {
569 FlexXFile xFile = new FlexXFile( makePathClientProtocolCompatible( IMPORT_GUI_PATH ) );
570 return ( xFile.exists() && xFile.canRead() && xFile.canWrite() );
571 }
572
573 /**
574 * Changes the file path to NFS path.
575 *
576 * @param path Path to be converted to NFS path.
577 * @return String - NFS path.
578 */
579 // makes a nfs path
580 private String makePathClientProtocolCompatible ( String path )
581 {
582 if ( path == null )
583 return null;
584
585 String newString = path.substring ( path.indexOf ("://"), path.length() );
586 newString = Settings.getString ( Settings.CLIENT_REMOTE_FILE_PROTOCOL ).toLowerCase() +newString;
587 return newString;
588 }
589
590 /**
591 * Checks if the path represents an local file.
592 *
593 * @param fileName The path of the file.
594 * @return true\false
595 */
596 private boolean isLocalFile( String fileName )
597 {
598 String[] protocols = FileAccessProtocol.getRemoteProtocolsNames ();
599 for ( int i=0; i<protocols.length; i++ )
600 {
601 if ( fileName.startsWith ( protocols[ i ] ) )
602 return false;
603 }
604 return true;
605 }
606
607
608 /**
609 * Returns the size of the file.
610 *
611 * @param f File path.
612 * @return int
613 */
614 private long getFileSize( String f )
615 {
616 if ( f != null )
617 {
618 File file = new File ( f );
619 if ( file.exists() )
620 {
621 return file.length();
622 }
623 }
624 return -1;
625 }
626
627 /**
628 * Checks if there is enough disk space. This function is called when local files are
629 * imported. These files are supposed to be copied from the local disk to a temperary direcroty
630 * on app server host. This function checks the space on the App server host. It called disk
631 * space service to accomplish the task.
632 *
633 * @param fileSize The size of the file.
634 * @return true\false
635 */
636 private boolean isEnoughDiskSpace( long fileSize )
637 {
638 showMessage( Resources.get( 6245 ) );
639
640 ActionData diskSpaceData = new ActionData();
641 diskSpaceData.setServiceName( ServicesI.DISKSPACE_SERVICE );
642 diskSpaceData.setString( ActionPropertiesI.VOLUME_PATH, appServerHostTmpDir );
643 diskSpaceData.setLong( ActionPropertiesI.DISK_SPACE_REQUIRED, new Long(fileSize) );
644
645 try
646 {
647 // RMI call to execute Disk Space Service
648 ActionResult arResult = AppServerClientAwtWrapper.invokeImmediately( diskSpaceData );
649
650 if ( arResult.isSuccess() )
651 {
652 showMessage( Resources.get( 6669 ) );
653 }
654 else
655 {
656 showMessage( Resources.get( 6670 ) );
657 return false;
658 }
659 }
660 catch( RemoteException e )
661 {
662 displayError( Resources.get( 6671 ), transactionNumber );
663
664 return false;
665 }
666
667 return true;
668 }
669
670 /**
671 * Returns the name of the file out of the file path.
672 *
673 * @param path The complete file path.
674 * @return String = file name
675 */
676 private String getFileName( String path )
677 {
678 if ( path != null )
679 {
680 return path.substring( path.lastIndexOf( System.getProperty( "file.separator" ) ) + 1 );
681 }
682 return null;
683 }
684
685 /**
686 * Deletes a file specified by the complete path.
687 *
688 * @param file The path of the file to be deleted.
689 * @return true\false - false if permission denied.
690 */
691 private boolean deleteFile( String file )
692 {
693 File fileToDelete = new File ( file );
694
695 if ( fileToDelete.exists() )
696 return ( fileToDelete.delete() );
697
698 return false;
699 }
700
701
702 /**
703 * Returns the Import status.
704 *
705 * @return String - FAILED\SUCCESS
706 */
707 public String getStatus ()
708 {
709 return sStatus;
710 }
711 /**
712 * Disposes the task frame shown while import immediately.
713 *
714 */
715
716 public void dispose ()
717 {
718 if ( tfStatus != null )
719 {
720 TaskFrameManager.removeFrame( tfStatus, false );
721 tfStatus = null;
722 }
723
724 }
725
726 /**
727 * Sets the Import process status.
728 *
729 * @param status The status. Defined in Notification class.
730 * @param notifyObservers whether the observers are to be notified Or not.
731 */
732 private void setImportStatus ( String status )
733 {
734 sStatus = status;
735 }
736
737 /**
738 * Shows message on the status frame.
739 *
740 * @param message Message to be shown.
741 */
742 private void showMessage ( String msg )
743 {
744 if ( tfStatus != null )
745 tfStatus.setMessage ( msg );
746 }
747
748 /**
749 * Displays the error occured.
750 *
751 * @param message The error to be displayed.
752 * @param transID
753 */
754 private void displayError ( String message, int transID )
755 {
756
757 showMessage (" Error : " +message);
758 logError ( message, transID );
759 }
760 /**
761 * Log the error.
762 */
763 private void logError ( String message, int transID )
764 {
765
766 String[] saResArgs = new String[1];
767 saResArgs[0] = transID > 0 ? String.valueOf( transID ) : " Transaction ID Not available " ;
768
769 try
770 {
771 // write to error log
772 new FlexError( FlexError.CRITICAL,
773 Settings.getString( Settings.USER_ID ),
774 InetUtil.getHostName() == null ? "" : InetUtil.getHostName(),
775 "Import Asset",
776 "ImportModel.class",
777 null,
778 6258,
779 saResArgs,
780 message );
781 }
782 catch ( Exception e ) {}
783 }
784
785 /**
786 * Returns the name of the current disguise name user is importing into.
787 *
788 * @return String - name of the disguise.
789 */
790 private String getCurrentDisguiseName ()
791 {
792 if ( getCurrentImportSetting() != null )
793 return getCurrentImportSetting().getString ( ImportSettingsI.APPLICATION_NAME );
794 return null;
795 }
796
797 /**
798 * Function, that depending on the type of the base instance, creates and returns traversalinfoitem
799 * data object.
800 *
801 * @param disguiseId The current disguise id.
802 * @param structurID The structure id.
803 * @param elementRecordID The element record id, which is a unique number provided by the sequence bean.
804 * @return TraversalItem
805 */
806 private TraversalItem getElementInfoItem ( int disguiseId, int structurID, int elementRecordID )
807 {
808 TraversalItem item = null;
809 if ( ( structurID >= 0 ) &&
810 ( disguiseId >= 0 ) )
811 {
812 // assume that the DisguieManager has loaded the disguises
813 // Only if it is a normal bucket otherwise return NULL
814 try
815 {
816 if ( dUtils.getBucketType ( structurID ) == DisplayUtils.NORMAL_BUCKET )
817 {
818 int elementBucketID = dUtils.getElementBucketId();
819 item = new TraversalItem ( elementRecordID, elementBucketID );
820 }
821 }
822 catch ( Exception exception ) // Only possibility is IllegalArgumentException
823 {
824 return null;
825 }
826 }
827 return item;
828 }
829
830 private void doImport ()
831 {
832 try
833 {
834
835 // performs initial validations .. like if the disguise is valid, the
836 // setting should not be default etc
837 performInitialValidations();
838
839 if ( bImportImmediately ) // otherwise we dont need the status frame
840 tfStatus = TaskFrameManager.getFrame( Resources.get( 6718 ), true );
841
842 ArrayList list = getFilesToBeImported();
843 // can not import more than one files in an empty element
844 int disguiseID = getDisguiseId( getCurrentDisguiseName() );
845 try
846 {
847 dUtils.setCurrentDisguise ( disguiseID );
848 }
849 catch ( Exception exception ) // due to invalid disguise
850 {
851 // Invalid disguise
852 MessageBox.showMessageDialog ( null, 6802 );
853 throw new ImportFailedException ( Resources.get ( 6802 ) );
854 }
855 if ( bFromRetrieval &&
856 ( dUtils.getBucketType ( currentAsset.getStructureId() ) == DisplayUtils.ELEMENT_BUCKET ) &&
857 list.size() > 1 )
858 {
859 MessageBox.showMessageDialog ( null, 6801 );
860 throw new ImportFailedException ( Resources.get ( 6801 ) );
861 }
862
863 if ( bImportImmediately ) // nothing to show oherwise
864 showMessage ( Resources.get ( 5095, ""+list.size() ));
865
866 transactionNumber = getUniqueTransactionID();
867 if ( transactionNumber < 0 )
868 {
869 // invalid transaction id ..
870 MessageBox.showMessageDialog ( null, 6726 );
871 throw new ImportFailedException ( Resources.get ( 6726 ) );
872 }
873
874 int structureID = -1;
875 int elementID = -1;
876 int bucket_id = -1;
877 SequenceData seqData = null;
878
879
880 int noOfFiles = list.size();
881 seqData = getUniqueElementBucketIDs( noOfFiles );
882 if ( seqData == null )
883 {
884 // could not fetch the bucket ids. Import Process can not proceed.
885 MessageBox.showMessageDialog ( null, 6716 );
886 throw new ImportFailedException ( Resources.get ( 6716 ) );
887 }
888
889 if ( disguiseID < 0 )
890 {
891 // Invalid disguies. Import Process can not proceed.
892 MessageBox.showMessageDialog ( null, 6802 );
893 throw new ImportFailedException ( Resources.get ( 6802 ) );
894 }
895 if ( !bFromRetrieval )
896 {
897 structureID = getStructureId( disguiseID, 0 );
898 if ( structureID < 0 )
899 {
900 //Invalid structure id. Import Process can not proceed.
901 MessageBox.showMessageDialog ( null, 6716 );
902 throw new ImportFailedException ( Resources.get ( 6716 ) );
903 }
904
905 elementID = getStructureId( disguiseID, 1 );
906 if ( elementID < 0 )
907 {
908 // Invalid element id. Import Process can not proceed.
909 MessageBox.showMessageDialog ( null, 6716 );
910 throw new ImportFailedException ( Resources.get ( 6716 ) );
911 }
912
913 bucket_id = ( int ) getUniqueBucketID();
914 if ( bucket_id < 0 )
915 {
916 // Invalid bucket id. Import Process can not proceed.
917 MessageBox.showMessageDialog ( null, 6716 );
918 throw new ImportFailedException ( Resources.get ( 6716 ) );
919 }
920 }
921 SequenceData assetData = getUniqueAssetIDs( noOfFiles );
922
923 if ( assetData == null )
924 {
925 //Invalid asset ids. Import Process can not proceed.
926 MessageBox.showMessageDialog ( null, 6716 );
927 throw new ImportFailedException ( Resources.get ( 6716 ) );
928 }
929
930 ActionData actionData = new ActionData();
931 actionData.setServiceName ( SERVICE_NAME );
932 ImportSettingsI setting = getCurrentImportSetting();
933 if ( setting == null )
934 {
935 MessageBox.showMessageDialog ( null, 6717 );
936 throw new ImportFailedException ( Resources.get ( 6717 ) );
937 }
938 // makePathClientProtocolCompatible calls makes the http or file path to a NFS path.
939 // String hotdir = makePathClientProtocolCompatible ( setting.getString ( ImportSettingsI.CTL_PATH ) );
940 // should be changed when the app server starts checking the type of the files itself.
941 // right now its only supports nfs ..
942 // this path should be a absolute path to the ctl file.
943 String hotdir = setting.getString ( ImportSettingsI.CTL_PATH );
944 if ( !hotdir.startsWith ( appServerRemoteProtocol ) )
945 {
946 hotdir = appServerRemoteProtocol + hotdir.substring ( hotdir.indexOf ( "://" ), hotdir.length() );
947 }
948 actionData.setString ( ActionData.HOT_DIRECTORY, hotdir );
949 actionData.setTransId ( transactionNumber );
950
951 // bImportImmediately = true :-> Import process should be done immediately
952 // bImportImmediately = false :-> Import process should be scheduled for 'queueDate'
953 if ( !bImportImmediately ) // otherwise no need to set the date. Import would be done immediately
954 {
955 actionData.setDate ( queueDate );
956 }
957
958 // create AssetRecordData data object for each of the assets and 'em to ActionData.
959 AssetRecordData assetRecordData = null;
960 // should be change once the appserver starts checking the file protocol itself
961 // right now it supports nfs only. So you gotta change all the paths to nfs
962 String sLocation = null;
963 for ( int i=0; i<noOfFiles; i++ )
964 {
965 sLocation = ( String ) list.get ( i );
966 assetRecordData = new AssetRecordData();
967 assetRecordData.setString ( AssetRecordData.SOURCE_LOCATION, sLocation );
968 assetRecordData.setRecordId ( ( int ) assetData.nextSequence() );
969 actionData.addRecord ( assetRecordData );
970 }
971 // Mac binary convertor. Needed only if its 'Mac - the apple'.
972 /*
973 *
974 */
975 /*MacBinaryConvertor macbinaryConvertor = null;
976
977 if ( OS.isMacintosh() )
978 {
979 macbinaryConvertor = new MacBinaryConvertor();
980 }
981 */
982
983 String sourceFile = null;
984 long sizeOfSourceSize = 0;
985 boolean isMacBinary = false;
986 int failedAssetCount = 0;
987 String hostServerTmpFile = null;
988 Vector assetsToImport = actionData.getRecords();
989
990 for ( int i = 0; i < assetsToImport.size(); i++ )
991 {
992 isMacBinary = false;
993
994 assetRecordData = ( AssetRecordData ) assetsToImport.elementAt( i );
995
996 sourceFile = assetRecordData.getString ( AssetRecordData.SOURCE_LOCATION );
997 sizeOfSourceSize = -1;
998
999 // check if the file is local.
1000 if ( isLocalFile( sourceFile ) )
1001 {
1002 // if its local and its mac the file residing at, then a bin file would be generated
1003 // for it and copied to the temp dir of the server
1004 /*
1005 if ( OS.isMacintosh() )
1006 {
1007 String macBinaryFile = sourceFile + ".bin";
1008
1009 if ( macbinaryConvertor.encode( sourceFile, macBinaryFile, 0 ) )
1010 {
1011 sourceFile = macBinaryFile;
1012 isMacBinary = true;
1013 }
1014 else
1015 {
1016 // if its import immediate then the files would be imported immediately and
1017 // the user would be notified with proceeding thru a status frame. All the errors
1018 // are also shown (& logged) otherwise they are just logged.
1019 if ( bImportImmediately )
1020 displayError ( Resources.get( 6721, sourceFile, macBinaryFile ), transactionNumber );
1021 else
1022 logError ( Resources.get( 6721, sourceFile, macBinaryFile ), transactionNumber );
1023 failedAssetCount++;
1024 continue;
1025 }
1026 }
1027 */
1028 //
1029 sizeOfSourceSize = getFileSize( sourceFile );
1030 // check the disk space using Disk Space Service.
1031 if ( !isEnoughDiskSpace( Math.round( sizeOfSourceSize * 1.1 ) ) )
1032 {
1033 if ( bImportImmediately )
1034 displayError ( Resources.get( 6722, sourceFile, appServerHost ), transactionNumber );
1035 else
1036 logError ( Resources.get( 6722, sourceFile, appServerHost ), transactionNumber );
1037 failedAssetCount++;
1038 continue;
1039 }
1040 // Copy the local files to the temp dir on server (App server host).
1041 hostServerTmpFile = UrlBuilder.buildURLString( FileAccessProtocol.getProtocolId ( Settings.getString ( Settings.CLIENT_REMOTE_FILE_PROTOCOL ).toLowerCase() ),
1042 appServerHost,
1043 appServerHostTmpDir + transactionNumber,
1044 getFileName( sourceFile ) );
1045
1046 assetRecordData.setString ( AssetRecordData.SERVER, ServerList.getServerName( appServerHost ) );
1047 assetRecordData.setString ( AssetRecordData.LOCATION, appServerHostTmpDir + transactionNumber );
1048 assetRecordData.setString ( AssetRecordData.FILENAME, getFileName( sourceFile ) );
1049
1050 // see if the file with the same name already exists in the temp dir of the
1051 // app server host.
1052 if ( ( new FlexXFile( hostServerTmpFile ) ).exists() )
1053 {
1054 if ( bImportImmediately )
1055 displayError ( Resources.get ( 6723, hostServerTmpFile ), transactionNumber );
1056 else
1057 logError ( Resources.get ( 6723, hostServerTmpFile ), transactionNumber );
1058 failedAssetCount++;
1059 continue;
1060 }
1061
1062 // All clear .. copy the file to temp dir of app server host
1063 XFileCopy ftpCopy = null;
1064 if ( Settings.getString( Settings.CLIENT_REMOTE_FILE_PROTOCOL ).toLowerCase().equals( FileAccessProtocol.FTP ) )
1065 ftpCopy = new XFileCopy();
1066
1067 boolean bCopySuccess = false;
1068 if ( ftpCopy != null )
1069 {
1070 ftpCopy.setCredentials( Settings.getString( Settings.FTP_CONNECTION_USER_ID ), Settings.getString( Settings.FTP_CONNECTION_PASSWORD ) );
1071 bCopySuccess = ftpCopy.copy( sourceFile, hostServerTmpFile );
1072 ftpCopy.disconnect();
1073 }
1074 else
1075 bCopySuccess = ( new XFileCopy() ).copy( sourceFile, hostServerTmpFile );
1076
1077 if ( !bCopySuccess )
1078 {
1079 if ( bImportImmediately )
1080 displayError ( Resources.get ( 6724, sourceFile, hostServerTmpFile ), transactionNumber );
1081 else
1082 logError ( Resources.get ( 6724, sourceFile, hostServerTmpFile ), transactionNumber );
1083 failedAssetCount++;
1084 continue;
1085 }
1086
1087 // delete the temperary bin file created intermediately.
1088 if ( isMacBinary )
1089 deleteFile( sourceFile );
1090
1091
1092 sourceFile = hostServerTmpFile;
1093 } // its local
1094 else // its not local
1095 {
1096 sLocation = assetRecordData.getString( AssetRecordData.SOURCE_LOCATION );
1097 FlexXFile xFile = new FlexXFile( sLocation );
1098 assetRecordData.setString ( AssetRecordData.SERVER, ServerList.getServerName( xFile.getServer () ) );
1099 String lPath = xFile.getLocalPath ();
1100 assetRecordData.setString ( AssetRecordData.FILENAME, xFile.getName() );
1101 // FlexXFile wraps up the FTP file now. And if its a FTP file the function getLocalPath
1102 // does not return a leading / but if its NFS it does and import processor
1103 // does not expect a slash.. mess for you ? Same here !
1104 if ( lPath.startsWith ("/") )
1105 assetRecordData.setString ( AssetRecordData.LOCATION, lPath.substring( 1, lPath.lastIndexOf ( "/" ) + 1) );
1106 else
1107 assetRecordData.setString ( AssetRecordData.LOCATION, lPath );
1108
1109 }
1110
1111
1112 // should be change as soon as the appserver starts supporting ftp as wel.
1113 // right now it only supports nfs.
1114 if ( !sourceFile.startsWith ( appServerRemoteProtocol ) )
1115 sourceFile = appServerRemoteProtocol + sourceFile.substring ( sourceFile.indexOf ( "://" ), sourceFile.length() );
1116
1117 assetRecordData.setString( AssetRecordData.SOURCE_LOCATION, sourceFile );
1118 assetRecordData.setMacBinaryFormat( new Boolean( isMacBinary ) );
1119 assetRecordData.setAppleTalkVendor( new Integer( ServerList.getAppleTalkVendor( appServerHost ) ) );
1120
1121 TraversalInfo tInfo = null;
1122 TraversalItem tItem = null;
1123 Vector traversalPath = null;
1124
1125 // If the Import is from retrieval, most of the information is fetched from the
1126 // tree nodes ( base insatance objects ) on the search retrieval tree.
1127 if ( bFromRetrieval )
1128 {
1129 if ( traversalPath == null )
1130 {
1131 traversalPath = new Vector();
1132 }
1133 tInfo = currentAsset.getTraversalPath();
1134 structureID = currentAsset.getStructureId();
1135 if ( structureID < 0 )
1136 {
1137 // if structureID is invalid Import can not proceed.
1138 MessageBox.showMessageDialog ( null, 6763 );
1139 throw new ImportFailedException ( Resources.get ( 6763 ) );
1140 }
1141 if ( ( tItem = getElementInfoItem( disguiseID, structureID, ( int ) seqData.nextSequence() ) ) != null )
1142 {
1143 tInfo.addTraversalItem ( tItem );
1144 }
1145 traversalPath.addElement ( tInfo );
1146 assetRecordData.setTraversalPathInfo ( traversalPath );
1147 }
1148 else
1149 {
1150 int elementBucketId = ( int ) seqData.nextSequence();
1151 tInfo = new TraversalInfo ();
1152 tInfo.setDisguiseId ( disguiseID );
1153 tItem = new TraversalItem ( bucket_id, structureID );
1154 tInfo.addTraversalItem ( tItem );
1155
1156 tItem = new TraversalItem ( elementBucketId, elementID );
1157 tInfo.addTraversalItem ( tItem );
1158
1159 if ( traversalPath == null )
1160 traversalPath = new Vector();
1161
1162 traversalPath.addElement ( tInfo );
1163 assetRecordData.setTraversalPathInfo ( traversalPath );
1164 }
1165 }// CREATES ROACTIONDATA WITH COLLECTION OF ROASSETRECORDDATA
1166 try
1167 {
1168 // though 'greater than' condition is not possible.
1169 if ( failedAssetCount >= actionData.getNumberOfRecords() )
1170 {
1171 throw new ImportFailedException ( Resources.get ( 6730 ) );
1172 }
1173 // if ( bImportImmediately ) call invokeImmediately
1174 // else call addQItem
1175 if ( bImportImmediately ) // Immediately
1176 {
1177 showMessage ( Resources.get ( 6362, SERVICE_NAME ) );
1178 ActionResult arResult = AppServerClientAwtWrapper.invokeImmediately ( actionData );
1179
1180 System.out.println ( "Import result "+arResult.isSuccess() );
1181 if ( arResult.isSuccess() )
1182 {
1183 showMessage ( Resources.get ( 6729 ) );
1184 setImportStatus ( Notification.SUCCESS );
1185 }
1186 else
1187 {
1188 showMessage ( Resources.get ( 6730 ) );
1189 setImportStatus ( Notification.FAILED );
1190 }
1191 }
1192 else // files are to be queued !!
1193 {
1194 ActionResult arResult = AppServerClientAwtWrapper.addQItem ( actionData );
1195 int nTransactionId = arResult.getId();
1196 if (nTransactionId > 0)
1197 {
1198 Diagnostic.trace( Diagnostic.CAT_IMPORT, "All files are being processed" );
1199 MessageBox.showMessageDialog( null, 6863, "" + nTransactionId );
1200 setImportStatus ( Notification.SUCCESS );
1201 }
1202 else
1203 {
1204 Diagnostic.trace( Diagnostic.CAT_IMPORT, "Service request not transmitted." );
1205 MessageBox.showMessageDialog( null, 6864 );
1206 setImportStatus ( Notification.FAILED );
1207 }
1208 }
1209 }
1210 catch ( RemoteException ex )
1211 {
1212 if ( bImportImmediately )
1213 {
1214 displayError ( Resources.get ( 6725 ), transactionNumber );
1215 showMessage ( Resources.get ( 6730 ) );
1216 }
1217 else
1218 {
1219 logError ( Resources.get ( 6725 ), transactionNumber );
1220 Diagnostic.trace( Diagnostic.CAT_IMPORT, "Service request not transmitted." );
1221 }
1222 setImportStatus ( Notification.FAILED );
1223 }
1224 catch ( Throwable e )
1225 {
1226 if ( bImportImmediately )
1227 {
1228 displayError ( e.getMessage(), transactionNumber );
1229 showMessage ( Resources.get ( 6730 ) );
1230 }
1231 else
1232 {
1233 logError ( e.getMessage(), transactionNumber );
1234 Diagnostic.trace( Diagnostic.CAT_IMPORT, "Service request not transmitted." );
1235 }
1236 setImportStatus ( Notification.FAILED );
1237 }
1238 }
1239 // we dont show any message dialog here as we expect that a proper
1240 // message dialog is already shown prior throwing this exception.
1241 catch ( com.flexstor.common.exceptions.ImportFailedException ex )
1242 {
1243 if ( bImportImmediately )
1244 {
1245 displayError ( ex.getMessage(), transactionNumber );
1246 showMessage ( Resources.get ( 6730 ) );
1247 }
1248 else
1249 {
1250 logError ( ex.getMessage(), transactionNumber );
1251 Diagnostic.trace( Diagnostic.CAT_IMPORT, "Service request not transmitted." );
1252 }
1253 setImportStatus ( Notification.FAILED );
1254 }
1255 }
1256 /**
1257 * Performs the initial validations before starting the actual
1258 * Import process. Like if the import settin is default, if
1259 * the current asset (if from retrieval) is null or the disguise
1260 * in the CTL file is not a valid one.
1261 */
1262 private void performInitialValidations ()
1263 throws ImportFailedException
1264 {
1265 if ( isDefaultImportSetting () )
1266 {
1267 MessageBox.showMessageDialog ( null, 6728 );
1268 throw new ImportFailedException ( Resources.get ( 6728 ) );
1269 }
1270 if ( bFromRetrieval && ( currentAsset == null ) )
1271 {
1272 // if currentAsset is null Import can not proceed.
1273 MessageBox.showMessageDialog ( null, 6763 );
1274 throw new ImportFailedException ( Resources.get ( 6763 ) );
1275 }
1276 // check for valid disguise in ctl file
1277
1278 if ( !isValidDisguise () )
1279 {
1280 MessageBox.showMessageDialog ( null, 6803, getCurrentDisguiseName() );
1281 throw new ImportFailedException ( Resources.get ( 6803, getCurrentDisguiseName() ) );
1282 }
1283 }
1284}
1285
1286