Ignore:
Timestamp:
2004-10-13T14:48:20+13:00 (20 years ago)
Author:
mdewsnip
Message:

Finally committing the (many) changes to the GLI to use the new metadata code... I hope this doesn't have too many bugs in it and committing it now doesn't stuff anyone up! (Katherine said I could commit it, so blame her if anything goes wrong).

Location:
trunk/gli/src/org/greenstone/gatherer/collection
Files:
1 added
3 edited

Legend:

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

    r8253 r8313  
    4848import org.greenstone.gatherer.cdm.CollectionMetaManager;
    4949import org.greenstone.gatherer.file.FileNode;
    50 import org.greenstone.gatherer.msm.MetadataXMLFileManager;
    51 import org.greenstone.gatherer.msm.MetadataSetManager;
    5250import org.greenstone.gatherer.util.StaticStrings;
    5351import org.greenstone.gatherer.util.Utility;
     
    6462    /** A reference to the Collection Design Manager. */
    6563    public CollectionDesignManager cdm;
    66     /** A reference to the Greenstone Directory Metadata Manager. */
    67     public MetadataXMLFileManager gdm;
    68     /** A reference to the Metadata Set Manager. */
    69     public MetadataSetManager msm;
    7064    /** true if an error has occurred during construction */
    7165    public boolean error = false;
     
    119113    public void destroy() {
    120114    cdm.destroy();
    121     gdm.destroy();
    122     msm.destroy();
    123115    Configuration.setCollectionConfiguration(null);
    124116    if (Gatherer.g_man != null) {
     
    127119    cdm = null;
    128120    document = null;
    129     gdm = null;
    130     msm = null;
    131121    }
    132122   
     
    170160    }
    171161
    172     public MetadataXMLFileManager getGDM() {
    173     return gdm;
    174     }
    175    
    176162    /** Retrieve the short name for this collection.
    177163     * @return The name as a <strong>String</strong>.
  • trunk/gli/src/org/greenstone/gatherer/collection/CollectionManager.java

    r8253 r8313  
    6262import org.greenstone.gatherer.gui.WarningDialog;
    6363import org.greenstone.gatherer.gui.tree.WorkspaceTree;
    64 import org.greenstone.gatherer.msm.ElementWrapper;
    65 import org.greenstone.gatherer.msm.MetadataXMLFileManager;
    66 import org.greenstone.gatherer.msm.GreenstoneArchiveParser;
    67 import org.greenstone.gatherer.msm.LegacyCollectionImporter;
    68 import org.greenstone.gatherer.msm.MetadataSet;
    69 import org.greenstone.gatherer.msm.MetadataSetManager;
    70 import org.greenstone.gatherer.msm.MSMEvent;
    71 import org.greenstone.gatherer.msm.MSMListener;
    72 import org.greenstone.gatherer.msm.MSMProfiler;
     64import org.greenstone.gatherer.metadata.DocXMLFileManager;
     65import org.greenstone.gatherer.metadata.MetadataSet;
     66import org.greenstone.gatherer.metadata.MetadataSetManager;
     67import org.greenstone.gatherer.metadata.MetadataXMLFileManager;
     68import org.greenstone.gatherer.metadata.ProfileXMLFileManager;
    7369import org.greenstone.gatherer.shell.GShell;
    7470import org.greenstone.gatherer.shell.GShellEvent;
     
    8985 */
    9086public class CollectionManager
    91     implements GShellListener, MSMListener {
    92     /** A reference to the metadata set manager. */
    93     public MetadataSetManager msm;
     87    implements GShellListener {
     88
    9489    /** Are we currently in the process of building? */
    9590    private boolean building = false;
     
    10095    /** The collection_model. */
    10196    private FileSystemModel collection_model = null;
    102     /** The workspace model. This becomes invalid on a collection change. */
    103     // private FileSystemModel workspace_model = null;
    10497    /** An inner class listener responsible for noting tree changes and resetting saved when they occur. */
    10598    private FMTreeModelListener fm_tree_model_listener = null;
     
    127120    this.collection = null;
    128121    }
     122
     123
    129124    /** Add a special directory mapping.
    130125     * @param name The name for this directory mapping as a <strong>String</strong>.
    131126     * @param file The directory this mapping maps to as a <strong>File</strong>.
    132127     */
    133     public void addDirectoryMapping(String name, File file) {
     128    public void addDirectoryMapping(String name, File file)
     129    {
    134130    // Update the information stored in the Gatherer config
    135131    Configuration.addDirectoryMapping(name, file);
     
    137133    Gatherer.g_man.refreshWorkspaceTree(WorkspaceTree.FOLDER_SHORTCUTS_CHANGED);
    138134    }
     135
     136
    139137    /** This method calls the builcol.pl scripts via a GShell so as to not lock up the processor.
    140138     * @see org.greenstone.gatherer.Configuration
     
    147145     * @see org.greenstone.gatherer.util.Utility
    148146     */
    149     public void buildCollection() {
     147    private void buildCollection() {
    150148    DebugStream.println("CollectionManager.buildCollection()");
    151149    building = true;
     
    227225    lock_file.delete();
    228226    if(lock_file.exists()) {
    229        System.err.println("Lockfile was not successfully deleted.");
    230     }
    231     collection.msm.destroy();
     227        System.err.println("Lockfile was not successfully deleted.");
     228    }
     229
     230    MetadataSetManager.clearMetadataSets();
     231    MetadataXMLFileManager.clearMetadataXMLFiles();
     232    DocXMLFileManager.clearDocXMLFiles();
     233    ProfileXMLFileManager.clearProfileXMLFile();
     234
    232235    collection = null;
    233236    collection_model = null;
     
    324327     * @param metadata_sets if the user has decided to select several metadata sets with which to initially populate the GLI then this is an ArrayList of metadata set file names, otherwise its null
    325328     */
    326     public void createCollection(String description, String email, String name, String title, File base_collection_directory, ArrayList metadata_sets) {
    327     boolean cancelled = false;
    328 
     329    public void createCollection(String description, String email, String name, String title, File base_collection_directory, ArrayList metadata_sets)
     330    {
    329331    try {
    330332        // first make sure that the collect directory exists
     
    340342        // *******************
    341343        //check that this creation has worked - simply by checking for the existence of the collect.cfg file
    342         String a_dir;
     344        String collection_dir;
    343345        if (Gatherer.GS3) {
    344         a_dir = Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, name);
     346        collection_dir = Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, name);
    345347        } else {
    346         a_dir = Utility.getCollectionDir(Configuration.gsdl_path, name);
    347         }
    348         File config_file = new File(Utility.getConfigFile(a_dir));
     348        collection_dir = Utility.getCollectionDir(Configuration.gsdl_path, name);
     349        }
     350        File config_file = new File(Utility.getConfigFile(collection_dir));
    349351        if (!config_file.exists()) {
    350352        // no point continuing
     
    356358       
    357359        // ACTIVE_DIR/log/
    358         File log_dir_temp = new File(Utility.getLogDir(a_dir)+"temp.dat");
     360        File log_dir_temp = new File(Utility.getLogDir(collection_dir)+"temp.dat");
    359361        File log_dir = log_dir_temp.getParentFile();
    360362        log_dir.mkdirs();
     
    364366
    365367        // Make sure an import folder exists
    366         File import_directory = new File(Utility.getImportDir(a_dir));
     368        File import_directory = new File(Utility.getImportDir(collection_dir));
    367369        if (!import_directory.exists()) {
    368370        import_directory.mkdirs();
     
    372374
    373375        // Now create the collection object around the directory.
    374         collection = new Collection(new File(a_dir, name + ".col"));
    375         collection.msm = new MetadataSetManager();
    376         msm = collection.msm; // Legacy
    377         collection.msm.load();
    378 
    379         // Import default metadata sets if any.
    380         for(int i = 0; metadata_sets != null && i < metadata_sets.size(); i++) {
    381         MetadataSet metadata_set = (MetadataSet) metadata_sets.get(i);
    382         collection.msm.importMDS(metadata_set.getFile(), false);
    383         }
    384 
    385         boolean skip_import_phase = false;
     376        collection = new Collection(new File(collection_dir, name + ".col"));
     377
     378        MetadataSetManager.clearMetadataSets();
     379        MetadataXMLFileManager.clearMetadataXMLFiles();
     380        DocXMLFileManager.clearDocXMLFiles();
     381
     382        // Import default metadata sets, if any
     383        for (int i = 0; metadata_sets != null && i < metadata_sets.size(); i++) {
     384        importMetadataSet((MetadataSet) metadata_sets.get(i));
     385        }
     386
     387        ProfileXMLFileManager.loadProfileXMLFile(new File(collection_dir, Utility.META_DIR));
    386388
    387389        // Before we create the CollectionDesignManager we have to check if we are basing it upon some other collection.
    388         if(base_collection_directory != null) {
    389            DebugStream.println("Basing new collection on existing one: " + base_collection_directory);
    390            collection.setBaseCollection(base_collection_directory.getAbsolutePath());
    391            // copy over other needed directories
    392            copyExtraBaseCollStuff(new File(a_dir), base_collection_directory);
    393         // Try to import any existing metadata sets for this collection. Look in base_collection_directory/metadata and import any metadata sets found.
    394         File base_metadata = new File(base_collection_directory, Utility.META_DIR);
    395         if(base_metadata.exists()) {
    396             DebugStream.println("Found the metadata directory.");
    397             File[] possible_metadata_sets = base_metadata.listFiles();
    398             for(int i = 0; possible_metadata_sets != null && i < possible_metadata_sets.length; i++) {
    399             String filename = possible_metadata_sets[i].getName();
    400             if(filename.endsWith(".mds")) {
    401                 DebugStream.println("+ Found a metadata set. Importing: " + possible_metadata_sets[i].getAbsolutePath());
    402                 collection.msm.importMDS(possible_metadata_sets[i], false);
    403                 skip_import_phase = true;
    404             }
     390        if (base_collection_directory != null) {
     391        DebugStream.println("Basing new collection on existing one: " + base_collection_directory);
     392        collection.setBaseCollection(base_collection_directory.getAbsolutePath());
     393        // copy over other needed directories
     394        copyExtraBaseCollStuff(new File(collection_dir), base_collection_directory);
     395        // Try to import any existing metadata sets for this collection
     396        // Look in base_collection_directory/metadata and import any metadata sets found.
     397        File base_metadata_directory = new File(base_collection_directory, Utility.META_DIR);
     398        ArrayList base_metadata_sets = MetadataSetManager.listMetadataSets(base_metadata_directory);
     399        if (base_metadata_sets != null) {
     400            for (int i = 0; i < base_metadata_sets.size(); i++) {
     401            importMetadataSet((MetadataSet) base_metadata_sets.get(i));
    405402            }
    406403        }
     
    408405            DebugStream.println("This base collection has no metadata directory.");
    409406        }
    410         // If no sets were imported, then create a new metadata with this new collections name.
    411         if(collection.msm.getSets().size() == 0) {
     407
     408        // If no sets were imported...
     409        if (MetadataSetManager.getMetadataSets().size() == 0) {
    412410            // Prompt the user so that they can choose at least one initial metadata set. We're sneaky here and just create a ncm_prompt
    413411            DebugStream.println("This collection has no metadata sets. Present the user with the metadata set selection prompt.");
    414412            NewCollectionMetadataPrompt ncm_prompt = new NewCollectionMetadataPrompt();
    415413            // If cancelled then they really do mean to start a collection with no metadata sets.
    416             if(!ncm_prompt.isCancelled()) {
     414            if (!ncm_prompt.isCancelled()) {
    417415            ArrayList initial_sets = ncm_prompt.getSets();
    418             for(int i = 0; initial_sets != null && i < initial_sets.size(); i++) {
    419                 MetadataSet metadata_set = (MetadataSet) initial_sets.get(i);
    420                 collection.msm.importMDS(metadata_set.getFile(), false);
    421                 metadata_set = null;
     416            for (int i = 0; initial_sets != null && i < initial_sets.size(); i++) {
     417                importMetadataSet((MetadataSet) initial_sets.get(i));
    422418            }
    423             initial_sets = null;
    424419            }
    425420            ncm_prompt.dispose();
    426421            ncm_prompt = null;
    427422        }
    428         // Do a dry metadata import run over the entire base collection, recording profile mappings. We do this by finding the archive files, and then iterating over them using the GreenstoneArchiveParser to retrieve metadata from them. We then process the importing of new metadata elements using the selectElement prompt used in a file action metadata import. However the big change is that we don't actually import any metadata, just create importing profiles.
    429         if(!skip_import_phase) {
    430             File base_archive = new File(base_collection_directory, Utility.ARCHIVES_DIR);
    431             if(base_archive.exists()) {
    432             DebugStream.println("+ Archive directory found. Inspecting archives for metadata information.");
    433             ArrayList metadata_elements = GreenstoneArchiveParser.extractMetadataElements(base_archive);
    434             for(int i = 0; !cancelled && i < metadata_elements.size(); i++) {
    435                 String metadata_name = (String) metadata_elements.get(i);
    436                 ElementWrapper target = collection.msm.prompt.selectElement(metadata_name);
    437                 cancelled = Gatherer.c_man.getCollection().msm.prompt.wasDialogCancelled();
    438                 if(!cancelled) {
    439                 if(target != null) {
    440                     collection.msm.profiler.addAction(base_collection_directory.getAbsolutePath(), metadata_name, target.getName());
    441                 }
    442                 else {
    443                     collection.msm.profiler.addAction(base_collection_directory.getAbsolutePath(), metadata_name, null);
    444                 }
    445                 }
    446             }
    447             // Hopefully mappings should now be in place for metadata extracted from this collection.
    448             }
    449             else {
    450             DebugStream.println("+ Searching files for metadata.xml information.");
    451             // Find the import directory
    452             File base_import = new File(base_collection_directory, Utility.IMPORT_DIR);
    453             if(base_import.exists()) {
    454                 searchForMetadata(base_import);
    455             }
    456             }
    457         }
    458         // And if that fails then we must have been asked by Satan himself to build the very digital collections of hell, because they don't match any goodly greenstone collection I have ever seen, so you can't blame me if I can't import them.
    459423
    460424        // Now we update our collect.cfg
    461425        DebugStream.println("Copy and update collect.cfg from base collection.");
    462         updateCollectionCFG(new File(base_collection_directory, Utility.CONFIG_FILE), new File(a_dir, Utility.CONFIG_FILE), description, email, title);
     426        updateCollectionCFG(new File(base_collection_directory, Utility.CONFIG_FILE), new File(collection_dir, Utility.CONFIG_FILE), description, email, title);
    463427        }
    464428
    465429        // Always import the extracted metadata set if we didn't already
    466         if(collection.msm.getSet(Utility.EXTRACTED_METADATA_NAMESPACE) == null) {
    467            collection.msm.importMDS(new File(Utility.METADATA_DIR + Utility.EXTRACTED_METADATA_NAMESPACE + StaticStrings.METADATA_SET_EXTENSION), false);
     430        if (MetadataSetManager.getMetadataSet(MetadataSetManager.EXTRACTED_METADATA_NAMESPACE) == null) {
     431        File extracted_metadata_set_file = new File(Utility.METADATA_DIR + Utility.EXTRACTED_METADATA_NAMESPACE + StaticStrings.METADATA_SET_EXTENSION);
     432        importMetadataSet(new MetadataSet(extracted_metadata_set_file));
    468433        }
    469434
    470435        collection.cdm = new CollectionDesignManager(new File(getCollectionConfig()));
    471        
     436
    472437        // Now that we have a CDM, update several settings, such as if we created this collection by basing it on another, set it as public automatically
    473         if(base_collection_directory != null) {
     438        if (base_collection_directory != null) {
    474439        // Update the creator and maintainer
    475440        CollectionMeta creator_collectionmeta = new CollectionMeta(collection.cdm.collect_config.getCreator());
     
    479444        maintainer_collectionmeta.setValue(email);
    480445        maintainer_collectionmeta = null;
     446
    481447        // Update the collection title
    482448        CollectionMeta collection_name_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR);
    483449        collection_name_collectionmeta.setValue(title);
    484450        collection_name_collectionmeta = null;
     451
    485452        // And now the description
    486453        CollectionMeta collection_extra_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR);
    487454        collection_extra_collectionmeta.setValue(description);
    488455        collection_extra_collectionmeta = null;
     456
    489457        // All collections based on others are automatically public
    490458        CollectionMeta public_collectionmeta = new CollectionMeta(collection.cdm.collect_config.getPublic());
    491459        public_collectionmeta.setValue(StaticStrings.TRUE_STR);
    492460        public_collectionmeta = null;
     461
    493462        // Finally reset the icons
    494463        CollectionMeta icon_collection_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR);
     
    499468        icon_collection_small_collectionmeta = null;
    500469        }
    501        
    502         collection.gdm = new MetadataXMLFileManager();
    503470
    504471        progress.setProgress(3);
    505472
    506         // Has to be done after creating metadata set manager.
    507         File gmeta_dir_temp = new File(getCollectionMetadata()+"temp.dat");
    508         File gmeta_dir = gmeta_dir_temp.getParentFile();
    509         gmeta_dir.mkdirs();
    510         if(progress != null) {
    511         progress.setNote("GMeta created");
    512         }
    513         progress.setProgress(4);
    514 
    515         progress.setProgress(6);
    516         // Register ourselves as being interested in what the msm has to say.
    517         collection.msm.addMSMListener(this);
    518473        // Create a lock file.
    519         File lock_file = new File(a_dir, LOCK_FILE);
     474        File lock_file = new File(collection_dir, LOCK_FILE);
    520475        FileOutputStream out = new FileOutputStream(lock_file);
    521476        out.write(LOCK_FILE.getBytes());
    522477        out.close();
    523478        out = null;
     479
    524480        progress.setProgress(7);
    525         String args[] = new String[1];
    526         args[0] = name;
    527         progress.setNote(Dictionary.get("CollectionManager.Session_Ready", args));
     481        progress.setNote(Dictionary.get("CollectionManager.Session_Ready", name));
    528482        progress.close();
    529483    }
     
    543497    }
    544498    }
     499
    545500
    546501    public void createLockFile(File destination) {
     
    569524    }
    570525
    571     /** Method that is called whenever an element within a set is changed or modified. We want to mark the collection so that it needs saving again.
    572      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
    573      * @see org.greenstone.gatherer.collection.Collection
    574      */
    575     public void elementChanged(MSMEvent event) {
    576     // This means the state of the collections has changed, so we should set saved to false.
    577     collection.setSaved(false);
    578     }
    579     /** Used to retrieve the build options associated with the currently loaded collection. If none yet exist, default ones are created.
    580      * @return A <strong>BuildOptions</strong> object containing the build options for the current collection.
    581      * @see org.greenstone.gatherer.collection.Collection
    582      */
    583     /* private BuildOptions getBuildOptions() {
    584     return collection.build_options;
    585     } */
    586526
    587527    /** Retrieve the current collection.
     
    591531    return collection;
    592532    }
     533
     534
    593535    /** Constructs the absolute filename of the collection archive directory, which should resemble "$GSDLHOME/collect/&lt;col_name&gt;/archive/"
    594536     * @return A <strong>String</strong> containing the filename.
     
    630572        return Utility.getConfigFile(Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, collection.getName()));
    631573    } else {
    632     return Utility.getConfigFile(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
     574        return Utility.getConfigFile(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
    633575    }
    634576    }
     
    660602        return Utility.getEtcDir(Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, collection.getName()));
    661603    } else {
    662     return Utility.getEtcDir(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
     604        return Utility.getEtcDir(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
    663605    }
    664606    }
     
    674616        return Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, collection.getName()) + collection.getName() + ".col";
    675617    } else {
    676     return Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()) + collection.getName() + ".col";
     618        return Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()) + collection.getName() + ".col";
    677619    }
    678620    }
     
    688630        return Utility.getImagesDir(Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, collection.getName()));
    689631    } else {
    690     return Utility.getImagesDir(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
     632        return Utility.getImagesDir(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
    691633    }
    692634    }
     
    748690    }
    749691
    750     /** This method either returns the title of the current collection, or a placeholder string of 'No Collection'.
    751      * @return A <strong>String</strong> which represents what we wish to display for a collection title.
    752      * @see org.greenstone.gatherer.collection.Collection
    753      */
    754     /* private String getCollectionTitle() {
    755     if(collection != null) {
    756         return collection.getTitle();
    757     }
    758     return Dictionary.get("Collection.No_Collection");
    759     } */
     692
     693    static public String getCollectionMetadataDirectory()
     694    {
     695    if (Gatherer.GS3) {
     696        return Utility.getMetadataDir(Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, collection.getName()));
     697    } else {
     698        return Utility.getMetadataDir(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
     699    }
     700    }
     701   
    760702
    761703    /** Retrieve the record set (tree model) associated with the current collection. */
     
    827769        index_dir = index_dir.getParentFile();
    828770        if(index_dir.exists()) {
    829            DebugStream.println("Old Index = " + index_dir.getAbsolutePath()+", testing for deletability");
    830            if (!canDelete(index_dir)) {
    831            // tell the user
    832            JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Delete_Index"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
    833            // tell the gui manager
    834            // a message for the building log
    835            GShellEvent event = new GShellEvent(this, 0, GShell.IMPORT, Dictionary.get("CollectionManager.Cannot_Delete_Index_Log"), GShell.ERROR);
    836            Gatherer.g_man.create_pane.message(event);
    837            event = new GShellEvent(this, 0, GShell.IMPORT, "", GShell.ERROR);
    838            Gatherer.g_man.create_pane.processComplete(event);
    839            importing = false;
    840            return;
    841            }
    842            
     771        DebugStream.println("Old Index = " + index_dir.getAbsolutePath()+", testing for deletability");
     772        if (!canDelete(index_dir)) {
     773            // tell the user
     774            JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Delete_Index"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
     775            // tell the gui manager
     776            // a message for the building log
     777            GShellEvent event = new GShellEvent(this, 0, GShell.IMPORT, Dictionary.get("CollectionManager.Cannot_Delete_Index_Log"), GShell.ERROR);
     778            Gatherer.g_man.create_pane.message(event);
     779            event = new GShellEvent(this, 0, GShell.IMPORT, "", GShell.ERROR);
     780            Gatherer.g_man.create_pane.processComplete(event);
     781            importing = false;
     782            return;
     783        }
    843784        }
    844785
     
    879820    }
    880821
     822
     823    public void importMetadataSet(MetadataSet external_metadata_set)
     824    {
     825    // Copy the .mds file into the collection's "metadata" folder...
     826    File external_metadata_set_file = external_metadata_set.getMetadataSetFile();
     827
     828    // ...but not if it is the redundant "hidden.mds" file
     829    if (external_metadata_set_file.getName().equals("hidden.mds")) {
     830        return;
     831    }
     832
     833    // ...and only if it doesn't already exist
     834    File metadata_set_file = new File(getCollectionMetadata(), external_metadata_set_file.getName());
     835    if (!metadata_set_file.exists()) {
     836        try {
     837        Gatherer.f_man.getQueue().copyFile(external_metadata_set_file, metadata_set_file, null);
     838        }
     839        catch (Exception ex) {
     840        ex.printStackTrace();
     841        }
     842
     843        // Load it into the MetadataSetManager
     844        MetadataSetManager.loadMetadataSet(metadata_set_file);
     845    }
     846    }
     847
     848
    881849    /** Determine if we are currently in the middle of importing (and thus, in this case, we can't allow the log writer to exit). Boy was this a mission to track down. The cascade of crap rolls out something like this: Joe Schmo clicks 'Build Collection', which calls the importCollection() method above, which in turn saves the collection with a saveTask, which fires a collectionChanged message once its finished, which drives the list of logs shown on the create pane to update, which fires a itemChanged() event to the OptionsPane who dutifully tells the current log writer thread to finish up writing (all zero lines its been asked to write) and then die. Wereapon Joe Schmo gets a pretty log to look at, but it isn't actually being written to file so the next time he tries to view it faeces hits the air motion cooling device. Joy.
    882850     * @return true if the gli is currently importing
     
    891859     * @see org.greenstone.gatherer.Gatherer
    892860     * @see org.greenstone.gatherer.collection.Collection
    893      * @see org.greenstone.gatherer.msm.MetadataSetManager
    894      * @see org.greenstone.gatherer.msm.MSMListener
    895861     * @see org.greenstone.gatherer.util.Utility
    896862     */
    897     public boolean loadCollection(String location) {
    898     DebugStream.println("Load Collection '" + location + "'");
    899     String[] args2 = new String[1];
    900     args2[0] = location;
    901     boolean result = false;
     863    public boolean loadCollection(String location)
     864    {
     865    DebugStream.println("Loading collection " + location + "...");
    902866    boolean non_gatherer_collection = false;
     867
    903868    // Check we have actually been given a .col file.
    904     if(!location.endsWith(".col")) {
    905         JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Not_Col_File", args2), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
     869    if (!location.endsWith(".col")) {
     870        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Not_Col_File", location), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
    906871        DebugStream.println("CollectionManager.loadCollection: Haven't been given a .col file.");
    907872        return false;
    908873    }
     874
    909875    // Check that there is the collection configuration file available
    910 
    911876    File collection_file = new File(location);
    912877    // Ensure that the directory exists.
    913878    File collection_directory = collection_file.getParentFile();
    914     if(!collection_directory.exists()) {
     879    if (!collection_directory.exists()) {
    915880        // we cant open this
    916881        collection_directory = null;
     
    926891
    927892    // Special case of a user trying to open an old greenstone collection.
    928     File metadata_directory = new File(collection_directory, Utility.META_DIR);
    929     if(!metadata_directory.exists()) {
    930 
    931         DebugStream.println("CollectionManager.loadCollection: trying to load up a non-gatherer collection");
     893    File collection_metadata_directory = new File(collection_directory, Utility.META_DIR);
     894    if (!collection_metadata_directory.exists()) {
     895        DebugStream.println("Loading non-gatherer collection...");
    932896        non_gatherer_collection = true;
    933897    }
    934898
     899    // Now determine if a lock already exists on this collection.
    935900    String name = collection_directory.getName();
    936901    File lock_file = new File(collection_file.getParentFile(), LOCK_FILE);
    937     // Now determine if a lock already exists on this collection.
    938     int choice = LockFileDialog.YES_OPTION;
    939     if(lock_file.exists()) {
     902    if (lock_file.exists()) {
    940903        LockFileDialog dialog = new LockFileDialog(Gatherer.g_man, name, lock_file);
    941         choice = dialog.getChoice();
     904        int choice = dialog.getChoice();
    942905        dialog.dispose();
    943906        dialog = null;
    944     }
    945 
    946     if(choice != LockFileDialog.YES_OPTION) {
    947         // user has cancelled
    948         lock_file = null;
    949         collection_directory = null;
    950         collection_config_file = null;
    951         return false;
    952     }
    953 
    954 
     907
     908        if (choice != LockFileDialog.YES_OPTION) {
     909        // user has cancelled
     910        lock_file = null;
     911        collection_directory = null;
     912        collection_config_file = null;
     913        return false;
     914        }
     915
     916        lock_file.delete();
     917    }
     918
     919    boolean result = false;
    955920    try {
    956         if(lock_file.exists()) {
    957         lock_file.delete();
    958         }
    959921        // Create a lock file.
    960922        createLockFile(lock_file);
     
    964926        System.err.println("Cannot write lock file!");
    965927        String args[] = new String[2];
    966         args[0] = args2[0];
     928        args[0] = location;
    967929        args[1] = Dictionary.get("FileActions.Write_Not_Permitted_Title");
    968930        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Open_With_Reason", args), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
     
    970932        return false;
    971933        }
     934
    972935        // Open the collection file
    973936        this.collection = new Collection(collection_file);
     
    975938        collection = null;
    976939        // Remove lock file
    977         if(lock_file.exists()) {
     940        if (lock_file.exists()) {
    978941            lock_file.delete();
    979942        }
     
    981944        }
    982945
    983         collection.msm = new MetadataSetManager();
    984         msm = collection.msm; // Legacy
    985         collection.msm.load();
    986         // if non-gatherer collection, need to add some metadata sets
     946        MetadataSetManager.clearMetadataSets();
     947        MetadataSetManager.loadMetadataSets(collection_metadata_directory);
     948
     949        ProfileXMLFileManager.loadProfileXMLFile(collection_metadata_directory);
     950 
     951        // If this is a non-GLI (legacy) collection, ask the user to choose some metadata sets
    987952        if (non_gatherer_collection) {
    988953        if (!addSomeMetadataSets(collection_directory)) {
    989             // for now - return of false means its been cancelled. Any error messages should be sent from the function itself
    990954            lock_file = null;
    991955            collection_directory = null;
     
    993957            return false;
    994958        }
    995         }
     959
     960        // Recurse the import folder tree, backing up the metadata.xml files before they are edited
     961        LegacyCollectionImporter.backupMetadataXMLFiles(collection_directory);
     962        }
     963
     964        // Read through the metadata.xml files in the import directory, building up the metadata value trees
     965        File collection_import_directory = new File(collection_directory, Utility.IMPORT_DIR);
     966        MetadataXMLFileManager.clearMetadataXMLFiles();
     967        MetadataXMLFileManager.loadMetadataXMLFiles(collection_import_directory);
     968
     969        // Read through the doc.xml files in the archives directory
     970        File collection_archives_directory = new File(collection_directory, Utility.ARCHIVES_DIR);
     971        DocXMLFileManager.clearDocXMLFiles();
     972        DocXMLFileManager.loadDocXMLFiles(collection_archives_directory);
    996973
    997974        collection.cdm = new CollectionDesignManager(collection_config_file);
    998975        if (non_gatherer_collection) {
    999         // We first recurse the Import folder tree, reading in any metadata.xml files, and then altering the non-namespaced element names to be valid GLI names
    1000         LegacyCollectionImporter lci = new LegacyCollectionImporter(collection_directory, collection.cdm);
    1001         lci.backupMetadataXMLFiles(collection_directory);
    1002         lci.importMetadata();
    1003         lci.updateClassifiers();
    1004         lci = null;
    1005         }
    1006         // Whether the collection is legacy or not, we should now be able to prepare the MetadataXMLFileManager
    1007         collection.gdm = new MetadataXMLFileManager();
     976        // Change the classifiers to use the namespaced element names
     977        LegacyCollectionImporter.updateClassifiers(collection.cdm);
     978        }
    1008979
    1009980        // Tell everyone that it worked.
    1010         String[] args = new String[1];
    1011         args[0] = name;
    1012         DebugStream.println(Dictionary.get("CollectionManager.Loading_Successful", args));
    1013         // Now we need to hook up classes that depend on messages from the metadata set manager to keep their content fresh.
    1014         collection.msm.addMSMListener(this);
     981        DebugStream.println(Dictionary.get("CollectionManager.Loading_Successful", name));
     982
    1015983        // We're done. Let everyone know.
    1016         if(Gatherer.g_man != null) {
    1017         // workspace_model = null;
     984        if (Gatherer.g_man != null) {
    1018985        Gatherer.g_man.collectionChanged(ready());
    1019986        }
    1020987        result = true;
    1021     } catch (Exception error) {
     988    }
     989    catch (Exception error) {
    1022990        // There is obviously no existing collection present.
    1023991        DebugStream.printStackTrace(error);
    1024992        if(error.getMessage() != null) {
    1025993        String[] args = new String[2];
    1026         args[0] = args2[0];
     994        args[0] = location;
    1027995        args[1] = error.getMessage();
    1028996        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Open_With_Reason", args), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
    1029997        }
    1030998        else {
    1031         JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Open", args2), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
     999        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Open", location), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
    10321000        }
    10331001    }
     
    10371005    collection_config_file = null;
    10381006
    1039     args2 = null;
    10401007    return result;
    10411008    }
     
    11471114    public synchronized void message(GShellEvent event) {
    11481115    }
    1149     /** Called whenever the metadata value changes in some way, such as the addition of a new value. We want to mark the collection so that it needs saving again.
    1150      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
    1151      * @see org.greenstone.gatherer.collection.Collection
    1152      */
    1153     public void metadataChanged(MSMEvent event) {
    1154     // Again this change means we need to save the collection again.
    1155     collection.setSaved(false);
    1156     }
     1116
    11571117    /** This call is fired whenever a process within a GShell created by this class begins.
    11581118     * @param event A <strong>GShellEvent</strong> containing information about the GShell process.
     
    12821242    return file;
    12831243    }
     1244
     1245
     1246    public void removeMetadataSet(MetadataSet metadata_set)
     1247    {
     1248    System.err.println("Removing metadata set...");
     1249
     1250    // Delete the .mds file from the collection's "metadata" folder...
     1251    File metadata_set_file = metadata_set.getMetadataSetFile();
     1252
     1253    // ...but not if it is the "ex.mds" file
     1254    if (metadata_set_file.getName().equals("ex.mds")) {
     1255        return;
     1256    }
     1257
     1258    // ...and only if it exists
     1259    if (metadata_set_file.exists()) {
     1260        metadata_set_file.delete();
     1261
     1262        // Unload it from the MetadataSetManager
     1263        MetadataSetManager.unloadMetadataSet(metadata_set);
     1264    }
     1265    }
     1266
     1267
    12841268    /** Used to check whether all open collections have a 'saved' state.
    12851269     * @return A <i>boolean</i> which is <i>true</i> if the collection has been saved.
     
    13131297    }
    13141298
    1315     /** Method that is called whenever the metadata set collection changes in some way, such as the addition of a new set or the merging of two sets. We want to mark the collection so that it needs saving again.
    1316      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
    1317      * @see org.greenstone.gatherer.collection.Collection
    1318      */
    1319     public void setChanged(MSMEvent event) {
    1320     // Invalidate saved
    1321     collection.setSaved(false);
    1322     }
    1323 
    13241299    public void setClosingThread(boolean set) {
    13251300    if(set) {
     
    13311306    }
    13321307
    1333     /** Updates the given workspace tree model to reference the private cache of the currently loaded collection. */
    1334     /* private void updatePrivateWorkspace(DefaultTreeModel model) {
    1335     // Add Private workspace if a collection has been loaded.
    1336     if(ready() && !Configuration.get("workflow.mirror", true)) {
    1337         FileNode root = (FileNode)model.getRoot();
    1338                 // Remove old private workspace
    1339         FileNode old = (FileNode)model.getChild(root, 2);
    1340         model.removeNodeFromParent(old);
    1341                 // Create and insert new.
    1342         FileNode private_workspace = new FileNode(new File(getCollectionCache()), Dictionary.get("Tree.Private"));
    1343         model.insertNodeInto(private_workspace, root, 2);
    1344     }
    1345     } */
    1346     /** Called whenever the value tree of an metadata element changes in some way, such as the addition of a new value. We want to mark the collection so that it needs saving again.
    1347      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
    1348      * @see org.greenstone.gatherer.collection.Collection
    1349      */
    1350     public void valueChanged(MSMEvent event) {
    1351     collection.setSaved(false);
    1352     }
    13531308
    13541309    /** I started giving the user the choice of using an existing meta set or creating a new one. The second option being so that they didn't have to add/merge/ignore each element, they could all be added automatically. However, I am not sure where the merge prompt gets called from, and it is not essential, so I am leaving it for now - it should be added back in and finished. [kjdon] */
     
    13641319
    13651320    /*if (meta_choice == ExternalCollectionPrompt.NEW_META_SET) {
    1366         NewMetaSetPrompt nmsp = new NewMetaSetPrompt();
    1367         if (nmsp.isCancelled()) {
    1368         return false;
    1369 }
    1370         String namespace_str = nmsp.getNamespace();
    1371         String name_str = nmsp.getName();
    1372         MetadataSet set = Gatherer.c_man.msm.addSet(namespace_str, name_str);
    1373     } else if (meta_choice == ExternalCollectionPrompt.EXISTING_META_SET) {
     1321      NewMetaSetPrompt nmsp = new NewMetaSetPrompt();
     1322      if (nmsp.isCancelled()) {
     1323      return false;
     1324      }
     1325      String namespace_str = nmsp.getNamespace();
     1326      String name_str = nmsp.getName();
     1327      // MetadataSet set = Gatherer.c_man.msm.addSet(namespace_str, name_str);
     1328      } else if (meta_choice == ExternalCollectionPrompt.EXISTING_META_SET) {
    13741329    */
    13751330    // now we reuse the newcoll metadata prompt for the user to select metadata sets
     
    13811336    // Import default metadata sets if any.
    13821337    for(int i = 0; metadata_sets != null && i < metadata_sets.size(); i++) {
    1383         MetadataSet metadata_set = (MetadataSet) metadata_sets.get(i);
    1384         collection.msm.importMDS(metadata_set.getFile(), false);
    1385     }
    1386     /*} else {
    1387       return false;
    1388       }*/
     1338        importMetadataSet((MetadataSet) metadata_sets.get(i));
     1339    }
     1340
    13891341    // Always import the extracted metadata set
    1390     collection.msm.importMDS(new File(Utility.METADATA_DIR + Utility.EXTRACTED_METADATA_NAMESPACE + StaticStrings.METADATA_SET_EXTENSION), false);
     1342    File extracted_metadata_set_file = new File(Utility.METADATA_DIR + Utility.EXTRACTED_METADATA_NAMESPACE + StaticStrings.METADATA_SET_EXTENSION);
     1343    importMetadataSet(new MetadataSet(extracted_metadata_set_file));
    13911344
    13921345    return true;
    13931346    }
    13941347
    1395 
    1396 //      // now try to load in existing metadata, delete the existing metadata.xml files, then save the new ones.
    1397 //      private boolean findAndLoadExistingMetadata(File collection_dir)
    1398 //      {
    1399 //      TreeModel collection_tree = getRecordSet();
    1400 //      FileNode root_node = (FileNode) collection_tree.getRoot();
    1401 //      if (searchForMetadata(collection_tree, root_node) == false) {
    1402 //          return false;
    1403 //      }
    1404 //      collection.gdm.save(root_node);
    1405 //      return true;
    1406 //      }
    14071348
    14081349    // used as arg in the perl scripts
     
    14231364    }
    14241365
     1366
    14251367    /** Install collection by moving its files from building to index after a successful build.
    14261368     * @see org.greenstone.gatherer.Gatherer
    14271369     * @see org.greenstone.gatherer.util.Utility
    14281370     */
    1429     private boolean installCollection() {
     1371    private boolean installCollection()
     1372    {
    14301373    DebugStream.println("Build complete. Moving files.");
    14311374
     
    15061449
    15071450
    1508     private boolean searchArchivesForMetadata(File archive_directory) {
    1509     /** @todo - ensure GreenstoneArchiveParser works as expected. */
    1510     return true;
    1511     }
    1512 
    1513     /** now this returns true if successful, false if unsuccessful or cancelled */
    1514     private boolean searchForMetadata(File current_file) {
    1515     boolean success = true;
    1516        if(current_file.isFile() && current_file.getName().equals(Utility.METADATA_XML)) {
    1517            success = collection.msm.searchForMetadata(null, new FileNode(current_file), false, true); // A dummy run only.
    1518        }
    1519        else {
    1520            File[] children_files = current_file.listFiles();
    1521            for(int i = 0; success && children_files != null && i < children_files.length; i++) {
    1522                success = searchForMetadata(children_files[i]);
    1523            }
    1524        }
    1525        return success;
    1526      }
    1527    
    1528     private boolean searchForMetadata(TreeModel collection_tree, FileNode current_node) {
    1529     File source_file = current_node.getFile();
    1530     String source_file_name = source_file.getName();
    1531     if (source_file_name.equals(Utility.METADATA_XML) || source_file_name.equals("CVS")) {
    1532         return true;
    1533     }
    1534     if (collection.msm.searchForMetadata(current_node, current_node, false)== false) {
    1535         return false;
    1536     }
    1537     int num_children = collection_tree.getChildCount(current_node);
    1538     for (int i=0; i<num_children; i++) {
    1539         FileNode child = (FileNode)collection_tree.getChild(current_node, i);
    1540         if (searchForMetadata(collection_tree, child)==false) {
    1541         return false;
    1542         }
    1543     }
    1544     return true;
    1545     }
    1546 
    1547     private void updateCollectionCFG(File base_cfg, File new_cfg, String description, String email, String title) {
     1451    private void updateCollectionCFG(File base_cfg, File new_cfg, String description, String email, String title)
     1452    {
    15481453    boolean first_name = true;
    15491454    boolean first_extra = true;
    15501455    String collection_path = (base_cfg.getParentFile().getParentFile()).getAbsolutePath();
    1551    
    1552     HashMap mappings = collection.msm.profiler.getActions(collection_path);
    1553     if(mappings == null) {
    1554         DebugStream.println("Mappings is null, which is odd. Leaving all configuration commands which use metadata as they are.");
    1555     }
    1556    
     1456
    15571457    // Now read in base_cfg line by line, parsing important onces and/or replacing them with information pertinent to our collection. Each line is then written back out to the new collect.cfg file.
    15581458    try {
     
    16201520                text.append(token);
    16211521                String temp_metadata = tokenizer.nextToken();
    1622                 String replacement = null;
    1623                 if(mappings != null) {
    1624                     replacement = (String) mappings.get(temp_metadata);
    1625                 }
    1626                 if(replacement != null) {
     1522                String replacement = ProfileXMLFileManager.getMetadataElementFor(temp_metadata);
     1523                if (replacement != null && !replacement.equals("")) {
    16271524                    token = replacement;
    16281525                    old_metadata = temp_metadata;
     
    16411538                text.append(token);
    16421539                String temp_metadata = tokenizer.nextToken();
    1643                 String replacement = null;
    1644                 if(mappings != null) {
    1645                     replacement = (String) mappings.get(temp_metadata);
    1646                 }
    1647                 if(replacement != null) {
     1540                String replacement = ProfileXMLFileManager.getMetadataElementFor(temp_metadata);
     1541                if (replacement != null && !replacement.equals("")) {
    16481542                    token = replacement;
    16491543                }
     
    16811575            old_metadata = null;
    16821576            write(out, command);
    1683          } else {
    1684              // the rest of the commands just want a string - we read in all the tokens from the tokeniser and get rid of it.
     1577        } else {
     1578            // the rest of the commands just want a string - we read in all the tokens from the tokeniser and get rid of it.
    16851579            StringBuffer new_command = new StringBuffer(command_type_str);
    16861580            while (tokenizer.hasMoreTokens()) {
     
    16941588            // we really want to build up the whole command here
    16951589            boolean format_command = command_type_str.equals(Utility.CFG_FORMAT);
    1696             // Replace mapping strings
    1697             if(mappings != null) {
    1698             for(Iterator keys = mappings.keySet().iterator(); keys.hasNext(); ) {
     1590            HashMap metadata_mapping = ProfileXMLFileManager.getMetadataMapping();
     1591            if (metadata_mapping != null) {
     1592            Iterator keys = metadata_mapping.keySet().iterator();
     1593            while (keys.hasNext()) {
    16991594                String target = (String) keys.next();
    1700                 String replacement = (String) mappings.get(target);
    1701                 if(format_command) {
    1702                 target = "\\[" + target + "\\]";
    1703                 replacement = "{Or}{[" + replacement + "]," + target + "}";
     1595                String replacement = (String) metadata_mapping.get(target);
     1596                if (replacement != null && !replacement.equals("")) {
     1597                if (format_command) {
     1598                    target = "\\[" + target + "\\]";
     1599                    replacement = "{Or}{[" + replacement + "]," + target + "}";
     1600                }
     1601                command = command.replaceAll(target, replacement);
    17041602                }
    1705                 command = command.replaceAll(target, replacement);
    17061603            }
    17071604            }
     1605
    17081606            write(out, command);
    1709          }
     1607        }
    17101608        tokenizer = null;
    17111609        }
     
    17271625    out.newLine();
    17281626    }
     1627
    17291628
    17301629    /** The CollectionManager class is getting too confusing by half so I'll implement this TreeModelListener in a private class to make responsibility clear. */
  • trunk/gli/src/org/greenstone/gatherer/collection/SaveCollectionTask.java

    r8243 r8313  
    4343import org.greenstone.gatherer.DebugStream;
    4444import org.greenstone.gatherer.Gatherer;
     45import org.greenstone.gatherer.metadata.MetadataSetManager;
    4546import org.greenstone.gatherer.util.Utility;
    4647
     
    6667    static final private int COPY_COLLECTION      = 4;
    6768    static final private int MAKE_COLLECTION      = 5;
    68     static final private int METADATA_SAVED       = 6;
    69     static final private int METADATA_XML_SAVED   = 7;
    7069    static final private int OPEN_COLLECTION      = 8;
    7170    static final private int RESTORE_COLLECTION   = 9;
     
    112111    // spd.setMillisToDecideToPopup(100);
    113112    // spd.setMillisToPopup(100);
    114     // 0. Force all remaining metadata.xml files to load.
     113
    115114    // 1. Perform a regular collection save on what we will later refer to as the origin collection.
    116115    ///ystem.err.println("1. Save origin.");
     
    119118    args[0] = collection.getName() + ".col";
    120119    try {
    121         // Block until all of the metadata files have been read in.
    122         collection.gdm.waitUntilComplete();
    123         // Write out the metadata xml files. The destroy below is meant to do this, but never does.
    124         collection.gdm.save();
    125         // spd.setProgress(getValue(METADATA_XML_SAVED));
    126 
    127120        File file = new File(tmp_loc);
    128121        // Create backup
     
    131124        backup.deleteOnExit();
    132125        if(!file.renameTo(backup)) {
    133             DebugStream.println("Error in CollectionManager.load(): FileRenamedException");
     126            DebugStream.println("Error in SaveCollectionTask.run(): FileRenamedException");
    134127        }
    135128        }
     
    143136        // spd.setProgress(getValue(COLLECTION_CFG_SAVED));
    144137
    145         // Write out the metadata files.
    146         Gatherer.c_man.msm.save();
    147         // spd.setProgress(getValue(METADATA_SAVED));
     138        // Write hfiles for the loaded metadata elements into the collection "etc" directory
     139        MetadataSetManager.writeHierarchyFiles(new File(Gatherer.c_man.getCollectionEtc()));
    148140
    149141        collection.setSaved(true);
     
    307299        return (int)((double)70 * multiplier);
    308300    case COLLECTION_CFG_SAVED:
    309     case METADATA_SAVED:
    310     case METADATA_XML_SAVED:
    311301        return (int)((double)10 * multiplier);
    312302        // Save As
     
    325315    }
    326316}
    327 
    328 
    329 
    330 
    331 
Note: See TracChangeset for help on using the changeset viewer.