Changeset 8586


Ignore:
Timestamp:
2004-11-17T13:20:30+13:00 (19 years ago)
Author:
mdewsnip
Message:

Made saving collections unthreaded -- this makes a lot of code, and at least one race condition, so away. Saving collections is quick enough that it doesn't matter if it is done on the main thread.

Location:
trunk/gli/src/org/greenstone/gatherer
Files:
2 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/src/org/greenstone/gatherer/collection/Collection.java

    r8313 r8586  
    188188    public void save() {
    189189    Utility.export(document, file);
     190    saved = true;
    190191    }
    191192
  • trunk/gli/src/org/greenstone/gatherer/collection/CollectionManager.java

    r8576 r8586  
    753753    public void importCollection() {
    754754    importing = true;
    755     if(!saved()) {
     755
     756    if (!saved()) {
    756757        DebugStream.println("CollectionManager.importCollection().forcesave");
    757758        import_monitor.saving();
    758         // Force save.
    759         try {
    760         SaveCollectionTask save_task = new SaveCollectionTask(collection);
    761         save_task.setImportAfter(true);
    762         save_task.start();
    763         }
    764         catch(Exception error) {
    765         DebugStream.printStackTrace(error);
    766         }
     759        saveCollection();
     760    }
     761
     762    DebugStream.println("CollectionManager.importCollection()");
     763    //check that we can remove the old index before starting import
     764    File index_dir = new File(getCollectionIndex(), "temp.txt");
     765    index_dir = index_dir.getParentFile();
     766    if(index_dir.exists()) {
     767        DebugStream.println("Old Index = " + index_dir.getAbsolutePath()+", testing for deletability");
     768        if (!canDelete(index_dir)) {
     769        // tell the user
     770        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Delete_Index"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
     771        // tell the gui manager
     772        // a message for the building log
     773        GShellEvent event = new GShellEvent(this, 0, GShell.IMPORT, Dictionary.get("CollectionManager.Cannot_Delete_Index_Log"), GShell.ERROR);
     774        Gatherer.g_man.create_pane.message(event);
     775        event = new GShellEvent(this, 0, GShell.IMPORT, "", GShell.ERROR);
     776        Gatherer.g_man.create_pane.processComplete(event);
     777        importing = false;
     778        return;
     779        }
     780    }
     781
     782    String collect_dir = getCollectDirectory();
     783
     784    String args[];
     785    String lang = Configuration.getLanguage();
     786    if((Utility.isWindows()) && (!Gatherer.isGsdlRemote)) {
     787        args = new String[8];
     788        args[0] = Configuration.perl_path;
     789        args[1] = "-S";
     790        args[2] = Configuration.getScriptPath() + "import.pl";
     791        args[3] = "-gli";
     792        args[4] = "-language";
     793        args[5] = lang;
     794        args[6] = "-collectdir";
     795        args[7] = collect_dir;
    767796    }
    768797    else {
    769         DebugStream.println("CollectionManager.importCollection()");
    770         //check that we can remove the old index before starting import
    771         File index_dir = new File(getCollectionIndex(), "temp.txt");
    772         index_dir = index_dir.getParentFile();
    773         if(index_dir.exists()) {
    774         DebugStream.println("Old Index = " + index_dir.getAbsolutePath()+", testing for deletability");
    775         if (!canDelete(index_dir)) {
    776             // tell the user
    777             JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Delete_Index"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
    778             // tell the gui manager
    779             // a message for the building log
    780             GShellEvent event = new GShellEvent(this, 0, GShell.IMPORT, Dictionary.get("CollectionManager.Cannot_Delete_Index_Log"), GShell.ERROR);
    781             Gatherer.g_man.create_pane.message(event);
    782             event = new GShellEvent(this, 0, GShell.IMPORT, "", GShell.ERROR);
    783             Gatherer.g_man.create_pane.processComplete(event);
    784             importing = false;
    785             return;
    786         }
    787         }
    788 
    789         String collect_dir = getCollectDirectory();
    790 
    791         String args[];
    792         String lang = Configuration.getLanguage();
    793         if((Utility.isWindows()) && (!Gatherer.isGsdlRemote)) {
    794         args = new String[8];
    795         args[0] = Configuration.perl_path;
    796         args[1] = "-S";
    797         args[2] = Configuration.getScriptPath() + "import.pl";
    798         args[3] = "-gli";
    799         args[4] = "-language";
    800         args[5] = lang;
    801         args[6] = "-collectdir";
    802         args[7] = collect_dir;
    803         }
    804         else {
    805         args = new String[6];
    806         args[0] = Configuration.getScriptPath() + "import.pl";
    807         args[1] = "-gli";
    808         args[2] = "-language";
    809         args[3] = lang;
    810         args[4] = "-collectdir";
    811         args[5] = collect_dir;
    812         }
    813         collect_dir = null;
    814         args = ArrayTools.add(args, collection.build_options.getImportValues());
    815         args = ArrayTools.add(args, collection.getName());
    816 
    817         GShell shell = new GShell(args, GShell.IMPORT, BUILDING, this, import_monitor, GShell.GSHELL_IMPORT);
    818         shell.addGShellListener(Gatherer.g_man.create_pane);
    819         shell.start();
    820         DebugStream.println("CollectionManager.importCollection().return");
    821     }
     798        args = new String[6];
     799        args[0] = Configuration.getScriptPath() + "import.pl";
     800        args[1] = "-gli";
     801        args[2] = "-language";
     802        args[3] = lang;
     803        args[4] = "-collectdir";
     804        args[5] = collect_dir;
     805    }
     806    collect_dir = null;
     807    args = ArrayTools.add(args, collection.build_options.getImportValues());
     808    args = ArrayTools.add(args, collection.getName());
     809
     810    GShell shell = new GShell(args, GShell.IMPORT, BUILDING, this, import_monitor, GShell.GSHELL_IMPORT);
     811    shell.addGShellListener(Gatherer.g_man.create_pane);
     812    shell.start();
     813    DebugStream.println("CollectionManager.importCollection().return");
     814
    822815    importing = false;
    823816    }
     
    12801273    return result;
    12811274    }
    1282     /** Saves a collection by serializing it to file.
    1283      * @param close_after <i>true</i> to cause the Gatherer to close the collection once save is complete, <i>false</i> otherwise.
    1284      * @param exit_after <i>true</i> to cause the Gatherer to exit once save is complete, <i>false</i> otherwise.
    1285      * @see org.greenstone.gatherer.Gatherer
    1286      * @see org.greenstone.gatherer.gui.GUIManager
    1287      * @see org.greenstone.gatherer.collection.Collection
    1288      */
    1289     public void saveCollection(boolean close_after, boolean exit_after) {
    1290     DebugStream.println("Save collection: " + collection.getName());
    1291     try {
    1292         SaveCollectionTask save_task = new SaveCollectionTask(collection, close_after, exit_after);
    1293         save_task.start();
    1294         // Run this in the same thread
    1295         //save_task.run();
    1296     }
    1297     catch(Exception error) {
    1298         DebugStream.printStackTrace(error);
    1299     }
    1300     }
     1275
     1276
     1277    /** Saves the currently loaded collection. */
     1278    public void saveCollection()
     1279    {
     1280    DebugStream.println("Saving collection " + collection.getName() + "...");
     1281
     1282    // Change cursor to hourglass
     1283    Gatherer.g_man.wait(true);
     1284
     1285    // Create a backup of the collection file, just in case anything goes wrong
     1286    File collection_file = new File(Gatherer.c_man.getCollectionFilename());
     1287    if (collection_file.exists()) {
     1288        File collection_file_backup = new File(collection_file.getAbsolutePath() + "~");
     1289        if (!collection_file.renameTo(collection_file_backup)) {
     1290        DebugStream.println("Error in CollectionManager.saveCollection(): could not create backup file.");
     1291        }
     1292        collection_file_backup.deleteOnExit();
     1293    }
     1294
     1295    // Write out the collection file
     1296    collection.save();
     1297
     1298    // Write out the collection configuration file
     1299    Gatherer.g_man.design_pane.saveConfiguration();
     1300
     1301    // Write hfiles for the loaded metadata elements into the collection "etc" directory
     1302    MetadataSetManager.writeHierarchyFiles(new File(Gatherer.c_man.getCollectionEtc()));
     1303
     1304    // Change cursor back to normal
     1305    Gatherer.g_man.wait(false);
     1306    }
     1307
    13011308
    13021309    public void setClosingThread(boolean set) {
  • trunk/gli/src/org/greenstone/gatherer/gui/GUIManager.java

    r8579 r8586  
    5656import org.greenstone.gatherer.collection.DeleteCollectionPrompt;
    5757import org.greenstone.gatherer.collection.ExportCollectionPrompt;
    58 import org.greenstone.gatherer.collection.SaveCollectionBox;
    5958import org.greenstone.gatherer.file.FileNode;
    6059import org.greenstone.gatherer.file.FileOpenActionListener;
     
    156155    // File Options.
    157156    // *************
    158     if(esrc == menu_bar.file_associations) {
     157    if (esrc == menu_bar.file_associations) {
    159158        Gatherer.assoc_man.edit();
    160159    }
    161     else if(esrc == menu_bar.file_close) {
    162         boolean cont = showSaveCollectionBox(true, false);
    163         // System.err.println("Here 1.");
    164         if(cont) {
    165         tab_pane.setSelectedComponent(gather_pane);
    166         }
    167     }
    168     else if(esrc == menu_bar.file_delete) {
     160    else if (esrc == menu_bar.file_close) {
     161        Gatherer.c_man.saveCollection();
     162        Gatherer.c_man.closeCollection();
     163        tab_pane.setSelectedComponent(gather_pane);
     164    }
     165    else if (esrc == menu_bar.file_delete) {
    169166        DeleteCollectionPrompt dcp = new DeleteCollectionPrompt();
    170         if(dcp.display()) {
     167        if (dcp.display()) {
    171168        Gatherer.c_man.closeCollection();
    172169        }
     
    175172        System.gc();
    176173    }
    177     else if(esrc == menu_bar.file_export) {
     174    else if (esrc == menu_bar.file_export) {
    178175        ExportCollectionPrompt ecp = new ExportCollectionPrompt();
    179176        ecp.display();
     
    181178        ecp = null;
    182179    }
    183     else if(esrc == menu_bar.file_exit) {
     180    else if (esrc == menu_bar.file_exit) {
    184181        exit();
    185182    }
    186         else if(esrc == menu_bar.file_new) {
     183        else if (esrc == menu_bar.file_new) {
    187184        showNewCollectionPrompt();
    188185    }
    189     else if(esrc == menu_bar.file_open) {
     186    else if (esrc == menu_bar.file_open) {
    190187        if (showLoadCollectionBox()) {
    191188        tab_pane.setSelectedComponent(gather_pane);
    192189        }
    193190    }
    194     else if(esrc == menu_bar.file_options) {
     191    else if (esrc == menu_bar.file_options) {
    195192        // Just incase the user has edited the GeneralSettings of a collection without losing focus afterwards. Well I'm forever losing foc... ooh shiney.
    196193        design_pane.loseFocus();
     
    198195        new Preferences();
    199196    }
    200     else if(esrc == menu_bar.file_save) {
    201         Gatherer.c_man.saveCollection(false, false);
     197    else if (esrc == menu_bar.file_save) {
     198        Gatherer.c_man.saveCollection();
    202199    }
    203200
     
    280277    }
    281278
     279
    282280    /** Any actions that should happen after the display of the Gatherer window can be called here. Currently only updates the browser pane if it is active to work around bug in Mozilla renderer implementation.
    283281     */
     
    288286    enrich_pane.afterDisplay();
    289287    }
     288
     289
    290290    public void closeCurrentCollection() {
    291 
    292     boolean cont = showSaveCollectionBox(true, false);
    293        
    294     if(cont) {
    295         tab_pane.setSelectedComponent(gather_pane);
    296     }
    297 
    298     }
     291    Gatherer.c_man.saveCollection();
     292    Gatherer.c_man.closeCollection();
     293    tab_pane.setSelectedComponent(gather_pane);
     294    }
     295
    299296
    300297    public void destroy() {
    301298    // Destroying create pane ensures the latest log has been closed
    302     if(create_pane != null) {
     299    if (create_pane != null) {
    303300        create_pane.destroy();
    304301    }
    305302    }
     303
    306304
    307305    /** Enabled events on the window to be trapped, creates all the visual components, then builds the tab and other layouts.
     
    412410    }
    413411    }
    414     /** When called this method ensures that all the things needing saving are saved before Gatherer.exit() is called. This includes a save collection prompt if necessary.
     412
     413
     414    /** This method ensures that all the things needing saving are saved before Gatherer.exit() is called.
    415415     */
    416416    public void exit() {
     
    418418    DebugStream.println("**** GUIManager exit called!");
    419419
    420     if(!Gatherer.c_man.ready() || design_pane.canSave()) {
    421 
     420    if (!Gatherer.c_man.ready() || design_pane.canSave()) {
    422421        if (Gatherer.isGsdlRemote) {           
    423422        // consider saving???
     
    425424        }
    426425        else {
    427 
    428         boolean cont = true;
    429         if(Gatherer.c_man.ready() && !Gatherer.c_man.saved()) {
    430             cont = showSaveCollectionBox(false, true);
    431         }
    432         else {
    433             // Deal to help
    434             if(help != null) {
    435             help.destroy();
    436             help = null;
    437             }
    438             DebugStream.println("**** Calling Gatherer.self.exit");
    439             Gatherer.self.exit();
    440         }
    441         }
    442     }
    443     }
     426        if (Gatherer.c_man.ready() && !Gatherer.c_man.saved()) {
     427            Gatherer.c_man.saveCollection();
     428        }
     429
     430        // Deal to help
     431        if (help != null) {
     432            help.destroy();
     433            help = null;
     434        }
     435        DebugStream.println("**** Calling Gatherer.self.exit");
     436        Gatherer.self.exit();
     437        }
     438    }
     439    }
     440
     441
    444442    /** Retrieve the filter, or if one already exists, spawn a linked copy. */
    445443    public Filter getFilter(DragTree tree) {
     
    687685    if(filename != null) {
    688686        // If there is already a collection open, save and close it.
    689         if(Gatherer.c_man.ready()) {
    690         showSaveCollectionBox(true, false);
    691         // Wait until it is closed.
    692         try {
    693             synchronized(this) {
    694                 while(Gatherer.c_man.reallyReady()) {
    695                 wait(10);
    696                 }
    697             }
    698         }
    699         catch(Exception error) {
    700                 DebugStream.println("Exception: " + error);
    701                 DebugStream.printStackTrace(error);
    702         }
     687        if (Gatherer.c_man.ready()) {
     688        Gatherer.c_man.saveCollection();
     689        Gatherer.c_man.closeCollection();
    703690        }
    704691       
     
    708695    return result;
    709696    }
     697
    710698
    711699    /** When called this method causes the MetadataAuditTable to display a nice dialog box which contains all the metadata assigned in the collection.
     
    727715    }
    728716    // Create the new collection (if not cancelled) in a new thread.
    729     if(!ncd_prompt.isCancelled() && (ncm_prompt == null || !ncm_prompt.isCancelled())) {
     717    if (!ncd_prompt.isCancelled() && (ncm_prompt == null || !ncm_prompt.isCancelled())) {
    730718        // If there is already a collection open, save and close it.
    731         if(Gatherer.c_man.ready()) {
    732         showSaveCollectionBox(true, false);
    733         // Wait until it is closed.
    734         try {
    735             synchronized(this) {
    736             while(Gatherer.c_man.reallyReady()) {
    737                 wait(10);
    738             }
    739             }
    740         }
    741         catch(Exception error) {
    742             DebugStream.println("Exception: " + error);
    743             DebugStream.printStackTrace(error);
    744         }
     719        if (Gatherer.c_man.ready()) {
     720        Gatherer.c_man.saveCollection();
     721        Gatherer.c_man.closeCollection();
    745722        }
    746723
    747724        // Create new collection.
    748725        CreationTask task = new CreationTask(ncd_prompt, ncm_prompt);
    749         // SwingUtilities.invokeLater(task);
    750726        task.start();
    751         // Close prompt.
    752727    }
    753728    // Done
     
    784759    }
    785760
    786 
    787     /** This method is used to open the save collection box/prompt on the screen.
    788      * @return A <i>boolean</i> which is <i>true</i> if the collection was saved successfully, <i>false</i> otherwise.
    789      */
    790     private boolean showSaveCollectionBox(boolean close_after, boolean exit_after)
    791     {
    792     Gatherer.c_man.setClosingThread(true);
    793     Gatherer.c_man.saveCollection(close_after, exit_after);
    794 
    795     // Wait until it is closed.
    796     try {
    797         synchronized(this) {
    798             while (Gatherer.c_man.reallyReady()) {
    799             wait(10);
    800             }
    801         }
    802     }
    803     catch (Exception exception) {
    804         DebugStream.printStackTrace(exception);
    805     }
    806 
    807     Gatherer.c_man.setClosingThread(false);
    808     return true;
    809     }
    810761
    811762    /** Any implementation of ChangeListener must include this method so we can be informed when the state of one of the registered objects changes. In this case we are listening to view changes within the tabbed pane.
Note: See TracChangeset for help on using the changeset viewer.