Package net.datacrow.core.modules

Source Code of net.datacrow.core.modules.DcModule

/******************************************************************************
*                                     __                                     *
*                              <-----/@@\----->                              *
*                             <-< <  \\//  > >->                             *
*                               <-<-\ __ /->->                               *
*                               Data /  \ Crow                               *
*                                   ^    ^                                   *
*                              info@datacrow.net                             *
*                                                                            *
*                       This file is part of Data Crow.                      *
*       Data Crow is free software; you can redistribute it and/or           *
*        modify it under the terms of the GNU General Public                 *
*       License as published by the Free Software Foundation; either         *
*              version 3 of the License, or any later version.               *
*                                                                            *
*        Data Crow is distributed in the hope that it will be useful,        *
*      but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.             *
*           See the GNU General Public License for more details.             *
*                                                                            *
*        You should have received a copy of the GNU General Public           *
*  License along with this program. If not, see http://www.gnu.org/licenses  *
*                                                                            *
******************************************************************************/

package net.datacrow.core.modules;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.KeyStroke;

import net.datacrow.console.ComponentFactory;
import net.datacrow.console.components.lists.DcObjectList;
import net.datacrow.console.components.panels.ChartPanel;
import net.datacrow.console.components.panels.QuickViewPanel;
import net.datacrow.console.components.tables.DcTable;
import net.datacrow.console.menu.MainFrameMenuBar;
import net.datacrow.console.views.MasterView;
import net.datacrow.console.views.View;
import net.datacrow.console.windows.filerenamer.FileRenamerDialog;
import net.datacrow.console.windows.filtering.FilterDialog;
import net.datacrow.console.windows.itemforms.ItemForm;
import net.datacrow.core.DataCrow;
import net.datacrow.core.DcRepository;
import net.datacrow.core.IconLibrary;
import net.datacrow.core.db.DatabaseManager;
import net.datacrow.core.migration.itemimport.CsvImporter;
import net.datacrow.core.migration.itemimport.ItemImporterHelper;
import net.datacrow.core.modules.xml.XmlField;
import net.datacrow.core.modules.xml.XmlModule;
import net.datacrow.core.objects.DcAssociate;
import net.datacrow.core.objects.DcField;
import net.datacrow.core.objects.DcMediaObject;
import net.datacrow.core.objects.DcObject;
import net.datacrow.core.objects.DcTemplate;
import net.datacrow.core.objects.helpers.Container;
import net.datacrow.core.objects.helpers.Item;
import net.datacrow.core.resources.DcResources;
import net.datacrow.core.security.SecurityCentre;
import net.datacrow.core.services.OnlineServices;
import net.datacrow.core.services.Servers;
import net.datacrow.core.services.plugin.IServer;
import net.datacrow.enhancers.IValueEnhancer;
import net.datacrow.fileimporters.FileImporter;
import net.datacrow.reporting.templates.ReportTemplates;
import net.datacrow.settings.DcModuleSettings;
import net.datacrow.settings.definitions.DcFieldDefinition;
import net.datacrow.settings.definitions.DcFieldDefinitions;
import net.datacrow.settings.definitions.QuickViewFieldDefinition;
import net.datacrow.settings.definitions.QuickViewFieldDefinitions;
import net.datacrow.settings.definitions.WebFieldDefinition;
import net.datacrow.settings.definitions.WebFieldDefinitions;
import net.datacrow.synchronizers.Synchronizer;
import net.datacrow.util.DcImageIcon;
import net.datacrow.util.StringUtils;

import org.apache.log4j.Logger;

/**
* A module represents items. The module dictates among other things where the
* items are stored, which views they can be displayed, which fields they have and
* which online services are available to update or search for new items.
* The module is where it all comes together. <br>
* Modules can have relationships between each other and come in different types. An
* important property of the module is the top module boolean which indicates if the
* module can be displayed within module bar and if the module can be disabled and or
* enabled by the user.<br>
* Furthermore is it important to know that modules are generic. They can be created
* from an {@link XmlModule} which holds a flexible XML definition of the module.<br>
* The {@link DcModules} class creates and holds all modules.
*
* @see XmlModule
* @see DcModules
* @see DcPropertyModule
* @see DcMediaModule
* @see DcChildModule
* @see DcMediaChildModule
* @see DcParentModule
* @see DcMediaParentModule 
*
* @author Robert Jan van der Waals
*/
public class DcModule implements Comparable<DcModule> {

    private static Logger logger = Logger.getLogger(DcModule.class.getName());
   
    public static final int _TYPE_MODULE = 0;
    public static final int _TYPE_PROPERTY_MODULE = 1;
    public static final int _TYPE_MEDIA_MODULE = 2;
    public static final int _TYPE_ASSOCIATE_MODULE = 3;
    public static final int _TYPE_EXTERNALREFERENCE_MODULE = 4;
    public static final int _TYPE_MAPPING_MODULE = 5;
    public static final int _TYPE_TEMPLATE_MODULE = 6;

    private final int type;
    private final int index;
   
    private int displayIndex;
    private int defaultSortFieldIdx;
    private int nameFieldIdx;
   
    private String label;
   
    private final String name;
    private final String tableName;
    private final String tableShortName;
    private final String description;
   
    private final String moduleResourceKey;
    private final String itemResourceKey;
    private final String itemPluralResourceKey;

    private final String systemObjectName;
    private final String systemObjectNamePlural;
   
    private final String objectName;
    private final String objectNamePlural;
   
    private boolean isValid = true;
    private boolean isNew = false;
    private boolean isDefaultDataLoaded = false;
   
    private net.datacrow.settings.Settings settings;
   
    private Class synchronizerClass;
    private Class objectClass;
    private Class importerClass;
   
    private int childIdx = -1;
    private int parentIdx = -1;
   
    private boolean hasSearchView = true;
    private boolean hasInsertView  = true;
   
    private boolean isServingMultipleModules = false;
   
    private DcImageIcon icon16;
    private DcImageIcon icon32;
   
    private String icon16filename;
    private String icon32filename;
   
    protected MasterView insertView;
    protected MasterView searchView;
    private FilterDialog filterForm;
    private ChartPanel chartPanel;
    private FileRenamerDialog fileRenamerDialog;
   
    private Map<Integer, DcField> fields = new HashMap<Integer, DcField>();
    private Map<Integer, DcField> systemFields = new HashMap<Integer, DcField>();
    private Collection<DcField> sortedFields;
   
    private OnlineServices services;

    private KeyStroke keyStroke;
   
    private boolean canBeLended = false;
    private boolean topModule = false;
    private boolean isFileBacked = false;
    private boolean isContainerManaged = false;
    private boolean hasDependingModules = true;
   
    private boolean hasImages = false;
    private boolean hasReferences = false;
   
    private XmlModule xmlModule;
   
    /**
     * Creates a new instance.
     * @param index The module index.
     * @param name The internal unique name of the module.
     * @param description The module description
     * @param objectName The name of the items belonging to this module.
     * @param objectNamePlural The plural name of the items belonging to this module.
     * @param tableName The database table name for this module.
     * @param tableShortName The database table short name for this module.
     * @param topModule Indicates if the module is a top module. Top modules are allowed
     * to be displayed in the module bar and can be enabled or disabled.
     */
    protected DcModule(int index,
                       String name,
                       String description,
                       String objectName,
                       String objectNamePlural,
                       String tableName,
                       String tableShortName,
                       boolean topModule) {

        this.index = index;
       
        Collection<IServer> servers = Servers.getInstance().getServers(index);
        if (servers != null) {
            this.services = new OnlineServices(index);
            for (IServer server : Servers.getInstance().getServers(index))
                services.addServer(server);
        }
       
        this.tableName = (tableName == null ? "" : tableName).toLowerCase();
        this.tableShortName  = (tableShortName == null ? (tableName != null ? tableName.substring(0, (tableName.length() > 5 ? 4 : 2)) : "") : tableShortName).toLowerCase();
        this.name = name;
        this.label = name;
        this.description = description;
       
        this.topModule = topModule;

        this.systemObjectName = objectName;
        this.systemObjectNamePlural = objectNamePlural;

        this.objectName = objectName;
        this.objectNamePlural = objectNamePlural;
       
        String s = isAbstract() ? label : tableName;
        if (s != null && s.length() > 1) s = s.substring(0, 1).toUpperCase() + s.substring(1);
       
        this.moduleResourceKey = "sys" + s;
        this.itemResourceKey = moduleResourceKey + "Item";
        this.itemPluralResourceKey = moduleResourceKey + "ItemPlural";
       
        // lower level determination of the type of module; avoiding instanceof calls in the future
        this.type =
            this instanceof DcAssociateModule ? _TYPE_ASSOCIATE_MODULE :
            this instanceof MappingModule ? _TYPE_MAPPING_MODULE :
            this instanceof DcPropertyModule ? _TYPE_PROPERTY_MODULE :
            this instanceof DcMediaModule ? _TYPE_MEDIA_MODULE :
            this instanceof TemplateModule ? _TYPE_TEMPLATE_MODULE :
            this instanceof ExternalReferenceModule ? _TYPE_EXTERNALREFERENCE_MODULE :
            _TYPE_MODULE;       
     }
   
    /**
     * Creates a new instance.
     * @param index The module index.
     * @param topModule Indicates if the module is a top module. Top modules are allowed
     * to be displayed in the module bar and can be enabled or disabled.
     * @param name The internal unique name of the module.
     * @param description The module description
     * @param objectName The name of the items belonging to this module.
     * @param objectNamePlural The plural name of the items belonging to this module.
     * @param tableName The database table name for this module.
     * @param tableShortName The database table short name for this module.
     */
    public DcModule(int index,
                    boolean topModule,
                    String name,
                    String description,
                    String objectName,
                    String objectNamePlural,
                    String tableName,
                    String tableShortName) {

        this(index, name, description, objectName, objectNamePlural, tableName,
             tableShortName, topModule);
       
        initializeSystemFields();
        initializeFields();
        initializeMultiReferenceFields();
        initializeSettings();
        initializeProperties();
    }
   
    /**
     * Creates a new module based on a XML definition.
     * @param module
     */
    public DcModule(XmlModule module) {
        this(module.getIndex(), module.getName(), module.getDescription(), module.getObjectName(),
             module.getObjectNamePlural(), module.getTableName(), module.getTableNameShort(),
             true);

        this.xmlModule = module;
       
        childIdx = module.getChildIndex();
        parentIdx = module.getParentIndex();
        label = module.getLabel();
       
        isFileBacked = module.isFileBacked();
        isContainerManaged = module.isContainerManaged();
        hasInsertView = module.hasInsertView();
        hasSearchView = module.hasSearchView();
        keyStroke = module.getKeyStroke();
        objectClass = module.getObjectClass();
        synchronizerClass = module.getSynchronizer();
        importerClass = module.getImporter();
        hasDependingModules = module.hasDependingModules();
       
        icon16filename = module.getIcon16Filename();
        icon32filename = module.getIcon32Filename();
        icon16 = new DcImageIcon(module.getIcon16());
        icon32 = new DcImageIcon(module.getIcon32());
       
        nameFieldIdx = module.getNameFieldIdx();
        canBeLended = module.canBeLend();
       
        displayIndex = module.getDisplayIndex();
        defaultSortFieldIdx = module.getDefaultSortFieldIdx();
       
        initializeSystemFields();
       
        if (module.getChildIndex() > -1)
            setChild(module.getChildIndex());
       
        for (XmlField xmlField : module.getFields())
            addField(new DcField(xmlField, getIndex()));
       
        initializeFields();
        initializeMultiReferenceFields();
        initializeSettings();
        initializeProperties();

        setServingMultipleModules(module.isServingMultipleModules());
       
        // Set it to disabled only if the XML module is defined as disabled.
        // There is no use case for this (yet).
        if (!module.isEnabled()) isEnabled(false);
    }
   
    public boolean hasReports() {
        return new ReportTemplates(true).hasReports(index);      
    }
   
    public int getType() {
        return type;
    }
   
    private void initializeProperties() {
        for (DcField field : getFields()) {
            if (field.getValueType() == DcRepository.ValueTypes._PICTURE)
                hasImages = true;
            else if (field.getValueType() == DcRepository.ValueTypes._DCOBJECTCOLLECTION ||
                    field.getValueType() == DcRepository.ValueTypes._DCOBJECTREFERENCE)
                hasReferences = true;
        }
    }
   
    public boolean isHasImages() {
        return hasImages;
    }

    public boolean isHasReferences() {
        return hasReferences;
    }

    public DcField getIconField() {
        for (DcField field : getFields()) {
            if (field.getValueType() == DcRepository.ValueTypes._ICON)
                return field;
        }
        return null;
    }
   
    /**
     * Indicates if the module is abstract. An abstract module represents items belonging
     * to other modules; it represents items from multiple modules. An abstract module does
     * not dictate where the items should be stored in the database, this is done by its
     * actual module. The media module is a good example of an abstract module.
     */
    public boolean isAbstract() {
        return getIndex() == DcModules._ITEM ||
               getIndex() == DcModules._MEDIA;
    }
   
    public int[] getSupportedViews() {
        return isAbstract() ? new int[] {MasterView._LIST_VIEW} : new int[] {MasterView._LIST_VIEW, MasterView._TABLE_VIEW};
    }
   
    /**
     * Returns whether this module is new for this installation.
     * New means that it was registered on startup.
     */
    public boolean isNew() {
        return isNew;
    }
   
    /**
     * Indicate this module as new for this installation
     * @param isNew
     */
    public void setNew(boolean isNew) {
        this.isNew = isNew;
    }

    /**
     * Indicate if this module is valid (fully functional).
     * Some processes register a new module temporarily. Since in that case the table has not been
     * created yet or not all referenced exist the module is in an invalid state.
     */
    public boolean isValid() {
        return isValid;
    }

    /**
     * Indicate if this module is valid (fully functional).
     * Some processes register a new module temporarily. Since in that case the table has not been
     * created yet or not all referenced exist the module is in an invalid state.
     * @param isValid
     */
    public void setValid(boolean isValid) {
        this.isValid = isValid;
    }

    public boolean isDefaultDataLoaded() {
        return isDefaultDataLoaded;
    }

    public void setDefaultDataLoaded(boolean b) {
        this.isDefaultDataLoaded = b;
    }

    /**
     * Indicates if the user is allowed to edit items belonging to this module.
     */
    public boolean isEditingAllowed() {
        return SecurityCentre.getInstance().getUser().isEditingAllowed(this);
    }

    /**
     * Indicates if this module is a child of another module.
     */
    public boolean isChildModule() {
        return getParent() != null;
    }
   
    /**
     * Indicates if this module is a parent to another module.
     */
    public boolean isParentModule() {
        return getChild() != null;
    }   
   
    /**
     * Retrieves the index of the module (unique!)
     */
    public int getIndex() {
        return index;
    }   

    /**
     * The small icon used to represent the module.
     */
    public DcImageIcon getIcon16() {
        return icon16;
    }
   
    /**
     * The large icon used to represent the module.
     */
    public DcImageIcon getIcon32() {
        return icon32;
    }

    public String getModuleResourceKey() {
        return moduleResourceKey;
    }
   
    public String getItemResourceKey() {
        return itemResourceKey;
    }

    public String getItemPluralResourceKey() {
        return itemPluralResourceKey;
    }
   
    /**
     * The name of the items belonging to this module.
     */
    public String getObjectName() {
        if (DcResources.getText(getItemResourceKey()) != null) {
            return DcResources.getText(getItemResourceKey());
        } else {
            return objectName;
        }
    }
   
    /**
     * The name of the items belonging to this module without translating it.
     */
    public String getSystemObjectName() {
        return systemObjectName;
    }   
   
    /**
     * The plural name of the items belonging to this module.
     */
    public String getObjectNamePlural() {
        if (DcResources.getText(getItemPluralResourceKey()) != null) {
            return DcResources.getText(getItemPluralResourceKey());
        } else {
            return objectNamePlural;
        }
    }

    /**
     * The plural name of the items belonging to this module without translating it.
     */
    public String getSystemObjectNamePlural() {
        return systemObjectNamePlural;
    }
   
   
    /**
     * The keys combination associated with this module.
     */
    public KeyStroke getKeyStroke() {
        return keyStroke;
    }   

    /**
     * Sets the small icon used to represent this module.
     * @param icon16
     */
    public void setIcon16(DcImageIcon icon16) {
        this.icon16 = icon16;
    }

    /**
     * Sets the large icon used to represent this module.
     * @param icon16
     */
    public void setIcon32(DcImageIcon icon32) {
        this.icon32 = icon32;
    }
   
    /**
     * Tells whether the module is enabled.
     * @see DcModuleSettings
     */
    public boolean isEnabled() {
        if (    SecurityCentre.getInstance().getUser() == null ||
                SecurityCentre.getInstance().getUser().isAuthorized(this))
            return settings.getBoolean(DcRepository.ModuleSettings.stEnabled);
        else
            return false;
    }

    /**
     * Marks the module as enabled or disabled.
     * @see DcModuleSettings
     */
    public void isEnabled(boolean b) {
        settings.set(DcRepository.ModuleSettings.stEnabled, b);
    }   

    /**
     * The name of this module.
     * @return
     */
    public String getName() {
        return name;
    }

    /**
     * The description for this module.
     */
    public  String getDescription() {
        return description;
    }   

    /**
     * The name of the table used to store its items.
     */
    public String getTableName() {
        return tableName;
    }

    /**
     * The short name of the table used to store its items.
     */
    public String getTableShortName() {
        return tableShortName;
    }

    /**
     * The online services available for this module.
     */
    public OnlineServices getOnlineServices() {
        return services;
    }

    /**
     * Indicates if this module has online services at its disposal.
     */
    public boolean deliversOnlineService() {
        return Servers.getInstance().getServers(getIndex()) != null;
    }

    /**
     * Tells if the module is created by a user.
     */
    public boolean isCustomModule() {
        return ((getIndex() < 50 ||
                (getIndex() >= 20000 && getIndex() < 30000)) ||
                 getIndex() >= 10000000) &&
                getType() != DcModule._TYPE_TEMPLATE_MODULE &&
                getType() != DcModule._TYPE_MAPPING_MODULE ;
    }

   
    /**
     * Creates a new instance of an item belonging to this module.
     */
    protected DcObject createItem() {
        try {
            try {
                return (DcObject) objectClass.getConstructors()[0].newInstance(new Object[] {});   
            } catch (Exception exp) {
                return (DcObject) objectClass.getConstructors()[0].newInstance(new Object[] {Integer.valueOf(getIndex())});
            }
        } catch (Exception e) {
            logger.error("Could not instantiate " + objectClass, e);
        }

        return null;
   

    public void release(DcObject dco) {
        dco.destroy();
    }
   
    /**
     * Creates a new instance of an item belonging to this module.
     */
    public synchronized final DcObject getItem() {
        return createItem();
   
   
    public DcField getFileField() {
        if (isFileBacked()) {
            return getField(DcObject._SYS_FILENAME);
        } else {
            for (DcField field : getFields()) {
                if (field.getFieldType() == ComponentFactory._FILELAUNCHFIELD ||
                    field.getFieldType() == ComponentFactory._FILEFIELD)
                    return field;
            }
            return null;
        }
    }
   
    public int getSystemDisplayFieldIdx() {
        return getDisplayFieldIdx();
    }
   
    /**
     * Educated guess..
     */
    public int getDisplayFieldIdx() {
        for (DcFieldDefinition definition : getFieldDefinitions().getDefinitions()) {
            if (definition.isDescriptive())
                return definition.getIndex();
        }
        return getDefaultSortFieldIdx();
    }
   
    public int[] getMinimalFields(Collection<Integer> include) {
        Collection<Integer> fields = new ArrayList<Integer>();
        for (DcFieldDefinition definition : getFieldDefinitions().getDefinitions())
            if (definition.isDescriptive() && definition.isEnabled())
                fields.add(Integer.valueOf(definition.getIndex()));
           
        if (!fields.contains(Integer.valueOf(getSystemDisplayFieldIdx())))
            fields.add(Integer.valueOf(getSystemDisplayFieldIdx()));
       
        if (include != null) {
            for (Integer field : include)
                if (!fields.contains(field))
                    fields.add(field);
        }
       
        if (getType() == _TYPE_ASSOCIATE_MODULE) {
            if (!fields.contains(Integer.valueOf(DcAssociate._A_NAME)))
                fields.add(Integer.valueOf(DcAssociate._A_NAME));
            if (!fields.contains(Integer.valueOf(DcAssociate._E_FIRSTNAME)))
                fields.add(Integer.valueOf(DcAssociate._E_FIRSTNAME));
            if (!fields.contains(Integer.valueOf(DcAssociate._F_LASTTNAME)))
                fields.add(Integer.valueOf(DcAssociate._F_LASTTNAME));
            if (!fields.contains(Integer.valueOf(DcAssociate._G_IS_COMPANY)))
                fields.add(Integer.valueOf(DcAssociate._G_IS_COMPANY));
        }
       
        if (getField(DcObject._ID) != null && !fields.contains(Integer.valueOf(DcObject._ID)))
            fields.add(Integer.valueOf(DcObject._ID));
       
        if (!fields.contains(Integer.valueOf(DcObject._SYS_DISPLAYVALUE)))
          fields.add(DcObject._SYS_DISPLAYVALUE)
       
        int[] result = new int[fields.size()];
        int i = 0;
        for (Integer field : fields)
            result[i++] = field.intValue();
       
        return result;
    }

    /**
     * Creates a new item form.
     * @param template The template to be applied on the item.
     * @param readonly Indicates if the item form should be opened in read only mode.
     * @param update Indicates if the item is an existing or a new item.
     * @param o The item to be displayed in the form.
     * @param applyTemplate Indicates if the supplied template should be applied.
     */
    public ItemForm getItemForm(DcTemplate template,
                                boolean readonly,
                                boolean update,
                                DcObject o,
                                boolean applyTemplate) {
        try {
            try {
                return (ItemForm) objectClass.getConstructors()[0].newInstance(new Object[] {});   
            } catch (Exception exp) {
                return (ItemForm) objectClass.getConstructors()[0].newInstance(new Object[] {Integer.valueOf(getIndex())});
            }
        } catch (Exception e) {
            logger.error("Could not instantiate " + objectClass, e);
        }

        return null;
   

    /**
     * The mass updater or synchronizer.
     * @return A synchronizer or null of not available.
     */
    public Synchronizer getSynchronizer() {
        if (synchronizerClass != null) {
            try {
                return (Synchronizer) synchronizerClass.getConstructors()[0].newInstance(new Object[] {});   
            } catch (Exception e) {
                logger.error("Could not instantiate " + synchronizerClass, e);
            }
        }
        return null;
    }

    public boolean isSearchViewInitialized() {
      return searchView != null;
    }
   
    /**
     * The insert view (shown in the new tab)
     */
    public MasterView getInsertView() {
        initializeUI();
        return insertView;
    }

    /**
     * Returns the search view.
     */
    public MasterView getSearchView() {
        initializeUI();
        return searchView;
    }

    /**
     * Returns the current search view.
     */
    public View getCurrentSearchView() {
        initializeUI();
        return getSearchView() != null ? getSearchView().getCurrent() : null;
    }

    /**
     * Returns the current insert view.
     */
    public View getCurrentInsertView() {
        initializeUI();
        return getInsertView() != null ? getInsertView().getCurrent() : null;
    }   
   
    /**
     * Retrieve the property module for the given index used by this module.
     * @param modIdx
     */
    public DcPropertyModule getPropertyModule(int modIdx) {
        return (DcPropertyModule) DcModules.get(getIndex() + modIdx);
    }

    /**
     * Returns the template module.
     * @return Template module or null.
     */
    public TemplateModule getTemplateModule() {
        if ((isTopModule() || isChildModule()) && !isAbstract())
            return (TemplateModule) DcModules.get(getIndex() + DcModules._TEMPLATE);
        else
            return null;
    }
   
    /**
     * Indicates if the module can be selected from the module bar.
     */
    public boolean isSelectableInUI() {
        return getIndex() == DcModules._CONTACTPERSON ||
               getIndex() == DcModules._MEDIA ||
              (isTopModule() && isEnabled() && !hasDependingModules());
    }

    /**
     * Adds a field to this module.
     * @param field
     */
    public void addField(DcField field) {
        fields.put(field.getIndex(), field);
    }
   
    /**
     * Returns all views.
     */
    public MasterView[] getViews() {
        if (getSearchView() != null && getInsertView() != null)
            return new MasterView[] {getSearchView(), getInsertView()};
        else if (getSearchView() != null)
            return new MasterView[] {getSearchView()};
        else if (getInsertView() != null)
            return new MasterView[] {getInsertView()};
        else
          return new MasterView[0];
    }

    /**
     * Retrieves the field definition for the given index.
     * @param index The field index.
     */
    public DcField getField(int index) {
        DcField field = fields.get(index);
        return field == null ? getSystemField(index) : field;
    }
   
    /**
     * Retrieves the field definition for the given index.
     * @param columnName The database column name.
     */
    public DcField getField(String columnName) {
        for (DcField field : getFields()) {
            if (field.getDatabaseFieldName().equalsIgnoreCase(columnName))
                return field;
        }
        return null;
    }
   
    /**
     * Registers a value enhancer for a specific field.
     * @param enhancer
     * @param field
     */
    public void addValueEnhancer(IValueEnhancer enhancer, int field) {
        getField(field).addValueEnhancer(enhancer);
    }
   
    /**
     * Removes all enhancers.
     */
    public void removeEnhancers() {
        for (DcField field : fields.values())
            field.removeEnhancers();
    }      
   
    /**
     * Retrieves the system field for the given index.
     * @param index The field index.
     */
    public DcField getSystemField(int index) {
        return systemFields.get(index);
    }

    /**
     * Register a child module.
     * @param module
     */
    public void setChild(int module) {
      this.childIdx = module;
    }
   
    /**
     * Creates the menu bar for this module.
     * @return The menu bar or null if not supported.
     */
    public MainFrameMenuBar getMenuBar() {
        return isTopModule() ? new MainFrameMenuBar(this) : null;
    }

    /**
     * Retrieves the parent module instance.
     * @return The parent module or null if not applicable.
     */
    public DcModule getParent() {
        return parentIdx > 0 ? DcModules.get(parentIdx) : null;
    }
   
    /**
     * Retrieves the child module instance.
     * @return The child module or null if not applicable.
     */
    public DcModule getChild() {
      return childIdx > 0 ? DcModules.get(childIdx) : null;
    }
   
    /**
     * Retrieves the index for the field holding the reference to the parent item.
     * @return The field index or -1 if not found.
     */
    public int getParentReferenceFieldIndex() {
        for (DcField field : getFields()) {
            if (field.getValueType() == DcRepository.ValueTypes._DCPARENTREFERENCE)
                return field.getIndex();
        }
       
        return -1;
    }

    /**
     * Creates the filter form (if not created already).
     * @param create Indicates if the form should be created when it does not yet exist.
     * @return The form or null if not available.
     */
    public FilterDialog getFilterForm(boolean create) {
        if (create)
            filterForm = filterForm == null && isTopModule() ? new FilterDialog(this, getSearchView()) : filterForm;
           
        return filterForm;
    }
   
    /**
     * Creates the file renamer dialog (if not created already).
     * @param create Indicates if the dialog should be created when it does not yet exist.
     * @return The dialog or null if not available.
     */
    public FileRenamerDialog getFileRenamerDialog(boolean create) {
        if (create)
            fileRenamerDialog = fileRenamerDialog == null ? new FileRenamerDialog(getIndex()) : fileRenamerDialog;

        return fileRenamerDialog;
    }   

    /**
     * Creates the chart panel (if not created already).
     * @param create Indicates if the panel should be created when it does not yet exist.
     * @return The panel or null if not available.
     */
    public ChartPanel getChartPanel(boolean create) {
        if (create)
            chartPanel = chartPanel == null && isTopModule() ? new ChartPanel(getIndex()) : chartPanel;
           
        return chartPanel;
    }
   
    /**
     * Indicates if this module is used by multiple modules.
     */
    public boolean isServingMultipleModules() {
        return isServingMultipleModules;
    }

    /**
     * Indicates if this module is used by multiple modules.
     * @param isServingMultipleModules
     */
    public void setServingMultipleModules(boolean isServingMultipleModules) {
        this.isServingMultipleModules = isServingMultipleModules;
    }   
   
    /**
     * Indicates if this module is a top module. Top modules are allowed
     * to be displayed in the module bar and can be enabled or disabled.
     */
    public boolean isTopModule() {
        return topModule;
    }

    /**
     * The number of fields belonging to this module.
     */
    public int getFieldCount() {
        return fields.size();
    }

    /**
     * Indicates if items belonging to this module can be lend.
     */
    public boolean canBeLend() {
        return canBeLended && 
               DcModules.get(DcModules._CONTACTPERSON) != null &&
               DcModules.get(DcModules._CONTACTPERSON).isEnabled();
    }

    /**
     * Indicates if other modules depend on this module.
     */
    public boolean hasDependingModules() {
        return hasDependingModules;   
    }

    /**
     * Retrieves the module setting value.
     * @param key The setting key {@link DcRepository.ModuleSettings}.
     */
    public Object getSetting(String key) {
        return settings.get(key);
    }
   
    /**
     * Sets the module setting value.
     * @param key The setting key {@link DcRepository.ModuleSettings}.
     * @param value The value to set.
     */
    public void setSetting(String key, Object value) {
        settings.set(key, value);
    }

    /**
     * Creates a new quick view panel.
     * @return New quick view panel or null.
     */
    public QuickViewPanel getQuickView() {
        return new QuickViewPanel(true);
    }

    /**
     * Tells if the module holds a reference to the given module.
     * This check is based on the original module index.
     * @param module The module index.
     */
    public boolean hasReferenceTo(int module) {
        for (DcField field : getFields()) {
            if (field.getSourceModuleIdx() == module)
                return true;
        }
        return false;
    }
   
    /**
     * Tells if the module holds a reference to the given module.
     * This check is based on the calculated module index.
     * @param module The module index.
     */
    public boolean hasActualReferenceTo(int module) {
        int parentRefIdx = getParentReferenceFieldIndex();
        boolean isMapping = DcModules.get(module).getType() == DcModule._TYPE_MAPPING_MODULE;
        for (DcField field : getFields()) {
            if (field != null && (isMapping || parentRefIdx != field.getIndex()) && field.getReferenceIdx() == module)
                return true;
        }
        return false;
    }

    /**
     * Retrieves all fields.
     */
    public Collection<DcField> getFields() {
        if (sortedFields == null || sortedFields.size() < fields.size()) {
            sortedFields = new ArrayList<DcField>();
            sortedFields.addAll(fields.values());
            Collections.sort((List<DcField>) sortedFields, new Comparator<DcField>() {
                @Override
                public int compare(DcField fld1, DcField fld2) {
                    return fld1.getOriginalLabel().compareTo(fld2.getOriginalLabel());
                }
            });
        }
        return sortedFields;
    }

    /**
     * Gets the field definitions. The field definitions contain the user settings such as the
     * modified label and the enabled setting.
     * @see DcFieldDefinition
     */
    public DcFieldDefinitions getFieldDefinitions() {
        return (DcFieldDefinitions) getSetting(DcRepository.ModuleSettings.stFieldDefinitions);
    }

    /**
     * Retrieves the web field definitions / settings
     * @see WebFieldDefinition
     */
    public WebFieldDefinitions getWebFieldDefinitions() {
        return (WebFieldDefinitions) getSetting(DcRepository.ModuleSettings.stWebFieldDefinitions);
    }
   
    /**
     * Retrieves the quick view field definitions / settings
     * @see QuickViewFieldDefinition
     */   
    public QuickViewFieldDefinitions getQuickViewFieldDefinitions() {
        return (QuickViewFieldDefinitions) getSetting(DcRepository.ModuleSettings.stQuickViewFieldDefinitions);
    }
   
    /**
     * Retrieves all field indices.
     */
    public int[] getFieldIndices() {
        Set<Integer> keys = fields.keySet();
        int[] indices = new int[keys.size()];
        int counter = 0;
        for (Integer key : keys)
            indices[counter++] = key.intValue();

        return indices;
    }
   
    /**
     * The import class.
     */
    public Class getImporterClass() {
        return importerClass;
    }
   
    /**
     * Creates a new instance of the file importer.
     */
    public FileImporter getImporter() {
        if (importerClass != null) {
            try {
                return (FileImporter) importerClass.newInstance();
            } catch (Exception e) {
                logger.error("Could not instantiate " + importerClass, e);
            }
        }
        return null;
    }

    /**
     * Indicates if this module is allowed to be customized.
     */
    public boolean isCustomFieldsAllowed() {
        return true;
    }
   
    /**
     * The module settings.
     * @see DcRepository.ModuleSettings
     */
    public net.datacrow.settings.Settings getSettings() {
        return settings;
    }
   
    /**
     * Applies the field settings on this module.
     */
    public void applySettings() {
        try {
            for (DcFieldDefinition definition : getFieldDefinitions().getDefinitions()) {
               DcField field = getField(definition.getIndex());
   
               field.setRequired(definition.isRequired());
               field.setEnabled(definition.isEnabled());
           }
        } catch (Exception e) {
            logger.error("Error while applying settings on module " + getName(), e);
        }
    }   
   
    /**
     * Indicates if the module is managed by (can belong to) a container.
     * @see ContainerModule
     * @see Container
     */
    public boolean isContainerManaged() {
        return isContainerManaged;
    }
   
    public DcField getPersistentField(int fieldIdx) {
        return getField(fieldIdx + 100000000);
    }
   
    /**
     * Creates a simple reference field for each multiple references field for ordering purposes.
     * It does need to have all modules registered before this method can be called.
     */
    public void initializeMultiReferenceFields() {
       
        if (    getType() == DcModule._TYPE_TEMPLATE_MODULE ||
                getType() == DcModule._TYPE_MAPPING_MODULE ||
                getType() == DcModule._TYPE_EXTERNALREFERENCE_MODULE)
            return;
       
        for (DcField field : getFields()) {
           
            if (field.getValueType() != DcRepository.ValueTypes._DCOBJECTCOLLECTION)
                continue;
           
            DcField fld = new DcField(
                    field.getIndex() + 100000000,
                    field.getModule(),
                    field.getSystemName() + "_persist",
                    false,
                    false,
                    true,
                    false, 256,
                    ComponentFactory._SHORTTEXTFIELD,
                    field.getModule(),
                    DcRepository.ValueTypes._STRING,
                    StringUtils.normalize(field.getSystemName()).replaceAll(" ", "").replaceAll("[\\-]", "") + "_persist");
           
            addField(fld);
        }
    }
   
    /**
     * Initializes the default fields.
     */
    protected void initializeFields() {
        try {
            addField(new DcField(DcObject._ID, getIndex(), "ID",
                                 false, true, true, false,
                                 36, ComponentFactory._SHORTTEXTFIELD, getIndex(), DcRepository.ValueTypes._STRING,
                                 "ID"));
            addField(new DcField(DcObject._SYS_CREATED, getIndex(), "Created",
                                 false, true, true, true,
                                 10, ComponentFactory._DATEFIELD, getIndex(), DcRepository.ValueTypes._DATE,
                                 "Created"));
            addField(new DcField(DcObject._SYS_MODIFIED, getIndex(), "Modified",
                                 false, true, true, true,
                                 10, ComponentFactory._DATEFIELD, getIndex(), DcRepository.ValueTypes._DATE,
                                 "Modified"));
           
            if ((isTopModule() || isChildModule()) && isCustomFieldsAllowed()) {
                addField(new DcField(DcMediaObject._U1_USER_LONGTEXT, getIndex(), "User Long Text Field",
                        false, false, false, true, 
                        4000, ComponentFactory._LONGTEXTFIELD, getIndex(), DcRepository.ValueTypes._STRING,
                        "UserLongText1"));        
                addField(new DcField(DcMediaObject._U2_USER_SHORTTEXT1, getIndex(), "User Short Text Field 1"
                        false, false, false, true, 
                        255, ComponentFactory._SHORTTEXTFIELD, getIndex(), DcRepository.ValueTypes._STRING,
                        "UserShortText1"));
                addField(new DcField(DcMediaObject._U3_USER_SHORTTEXT2, getIndex(), "User Short Text Field 2"
                        false, false, false, true, 
                        255, ComponentFactory._SHORTTEXTFIELD, getIndex(), DcRepository.ValueTypes._STRING,
                        "UserShortText2"));
                addField(new DcField(DcMediaObject._U4_USER_NUMERIC1, getIndex(), "User Numeric Field 1"
                        false, false, false, true, 
                        255, ComponentFactory._NUMBERFIELD, getIndex(), DcRepository.ValueTypes._LONG,
                        "UserInteger1"));
                addField(new DcField(DcMediaObject._U5_USER_NUMERIC2, getIndex(), "User Numeric Field 2"
                        false, false, false, true, 
                        255, ComponentFactory._NUMBERFIELD, getIndex(), DcRepository.ValueTypes._LONG,
                        "UserInteger2"));           
            }
           
            if (isTopModule() && !hasDependingModules()) {
                addField(new DcField(DcMediaObject._VALUE, getIndex(), "Item Value"
                        false, true, false, true, 
                        255, ComponentFactory._DECIMALFIELD, getIndex(), DcRepository.ValueTypes._DOUBLE,
                        "CurrencyValue"));           
            }
           
            if (    isTopModule() && !isAbstract() &&
                    getIndex() != DcModules._CONTAINER && getIndex() != DcModules._USER &&
                    getIndex() != DcModules._EXTERNALREFERENCE && getIndex() != DcModules._LOAN &&
                    getIndex() != DcModules._MAPPING && getIndex() != DcModules._PERMISSION &&
                    getIndex() != DcModules._TAB && getIndex() != DcModules._CONTACTPERSON) {
               
                addField(new DcField(DcObject._SYS_EXTERNAL_REFERENCES, getIndex(), "External References"
                        true, true, false, true, 
                        4, ComponentFactory._SIMPLEREFERENCESFIELD, DcModules._EXTERNALREFERENCE, DcRepository.ValueTypes._DCOBJECTCOLLECTION,
                        "externalreferences"));      
            }
   
            if (isContainerManaged())
                addField(getField(DcObject._SYS_CONTAINER));
           
            if (isTopModule() && deliversOnlineService()) {
                addField(getField(DcObject._SYS_SERVICE));
                addField(getField(DcObject._SYS_SERVICEURL));
            }
           
            addField(getField(DcObject._SYS_DISPLAYVALUE));
           
            if (isFileBacked) {
                addField(getField(DcObject._SYS_FILENAME));
                addField(getField(DcObject._SYS_FILESIZE));
                addField(getField(DcObject._SYS_FILEHASH));
                addField(getField(DcObject._SYS_FILEHASHTYPE));
            }
           
            // do not check whether the contact person module is enabled.
            // just add the fields if the settings allow for this
            if (canBeLended) {
                addField(getField(DcObject._SYS_AVAILABLE));
                addField(getField(DcObject._SYS_LENDBY));
                addField(getField(DcObject._SYS_LOANDURATION));
                addField(getField(DcObject._SYS_LOANDUEDATE));
                addField(getField(DcObject._SYS_LOANDAYSTILLOVERDUE));
            }
   
            addField(getField(DcObject._SYS_MODULE));
        } catch (Exception e) {
            logger.error(e, e);
        }
    }   

    /**
     * Initializes and corrects the module settings (if necessary)
     */
    public void initializeSettings() {
        settings = new DcModuleSettings(this);
   
        // check whether the definitions are still correct;
        // - there can be more definitions for a field; the actual field can be removed by a user
        QuickViewFieldDefinitions qvDefinitions =
            (QuickViewFieldDefinitions) settings.get(DcRepository.ModuleSettings.stQuickViewFieldDefinitions);
       
        QuickViewFieldDefinitions newQvDefinitions = new QuickViewFieldDefinitions();
        for (QuickViewFieldDefinition definition : qvDefinitions.getDefinitions()) {
            if (getField(definition.getField()) != null)
                newQvDefinitions.add(definition);
       
       
       
        WebFieldDefinitions webDefinitions =
            (WebFieldDefinitions) settings.get(DcRepository.ModuleSettings.stWebFieldDefinitions);
       
        WebFieldDefinitions newWebDefinitions = new WebFieldDefinitions();
        for (WebFieldDefinition definition : webDefinitions.getDefinitions()) {
            if (getField(definition.getField()) != null)
                newWebDefinitions.add(definition);
        }
       
        DcFieldDefinitions definitions =
            (DcFieldDefinitions) settings.get(DcRepository.ModuleSettings.stFieldDefinitions);
       
        DcFieldDefinitions newDefinitions = new DcFieldDefinitions();
        for (DcFieldDefinition definition : definitions.getDefinitions()) {
            if (getField(definition.getIndex()) != null)
                newDefinitions.add(definition);
        }
       
        settings.set(DcRepository.ModuleSettings.stQuickViewFieldDefinitions, newQvDefinitions);
        settings.set(DcRepository.ModuleSettings.stFieldDefinitions, newDefinitions);
        settings.set(DcRepository.ModuleSettings.stWebFieldDefinitions, newWebDefinitions);
    }
   
    /**
     * Initializes the system fields.
     */
    protected void initializeSystemFields() {
        systemFields.put(DcObject._SYS_MODULE,
                new DcField(DcObject._SYS_MODULE, getIndex(), "Item",
                            true, true, true, true,
                            255, ComponentFactory._SHORTTEXTFIELD, getIndex(), DcRepository.ValueTypes._STRING,
                            "Item"));
        systemFields.put(DcObject._SYS_AVAILABLE,
                new DcField(DcObject._SYS_AVAILABLE, getIndex(), "Available",
                            true, true, true, true,
                            4, ComponentFactory._AVAILABILITYCOMBO, getIndex(), DcRepository.ValueTypes._BOOLEAN,
                            "Available"));
        systemFields.put(DcObject._SYS_LENDBY,
                new DcField(DcObject._SYS_LENDBY, getIndex(), "Lend By",
                            true, true, true, true,
                            255, ComponentFactory._REFERENCEFIELD, DcModules._CONTACTPERSON, DcRepository.ValueTypes._DCOBJECTREFERENCE,
                            "LendBy"));
        systemFields.put(DcObject._SYS_LOANDURATION,
                new DcField(DcObject._SYS_LOANDURATION, getIndex(), "Days Loaned",
                            true, true, true, true,
                            10, ComponentFactory._NUMBERFIELD, getIndex(), DcRepository.ValueTypes._LONG,
                            "DaysLoaned"));
        systemFields.put(DcObject._SYS_LOANDUEDATE,
                new DcField(DcObject._SYS_LOANDUEDATE, getIndex(), "Due Date",
                            true, true, true, true,
                            10, ComponentFactory._DATEFIELD, getIndex(), DcRepository.ValueTypes._DATE,
                            "DueDate"));
        systemFields.put(DcObject._SYS_LOANDAYSTILLOVERDUE,
                new DcField(DcObject._SYS_LOANDAYSTILLOVERDUE, getIndex(), "Days till overdue",
                            true, true, true, true,
                            10, ComponentFactory._NUMBERFIELD, getIndex(), DcRepository.ValueTypes._LONG,
                            "DaysTillOverDue"));               
       
        if (isTopModule() && deliversOnlineService()) {
            systemFields.put(Integer.valueOf(DcObject._SYS_SERVICE),
                             new DcField(DcObject._SYS_SERVICE, getIndex(), "Service",
                                         false, true, true, false,
                                         255, ComponentFactory._SHORTTEXTFIELD, getIndex(), DcRepository.ValueTypes._STRING,
                                         "service"));
            systemFields.put(Integer.valueOf(DcObject._SYS_SERVICEURL),
                             new DcField(DcObject._SYS_SERVICEURL, getIndex(), "Service URL",
                                         false, true, true, false,
                                         255, ComponentFactory._URLFIELD, getIndex(), DcRepository.ValueTypes._STRING,
                                         "serviceurl"));       
        }
       
        if (isContainerManaged()) {
            systemFields.put(Integer.valueOf(DcObject._SYS_CONTAINER),
                    new DcField(DcObject._SYS_CONTAINER, getIndex(), "Container",
                                true, true, false, true, 
                                10, ComponentFactory._REFERENCESFIELD, DcModules._CONTAINER, DcRepository.ValueTypes._DCOBJECTCOLLECTION,
                                "Container"));
        }
       
        systemFields.put(Integer.valueOf(DcObject._SYS_DISPLAYVALUE),
                new DcField(Item._SYS_DISPLAYVALUE, getIndex(), "Label",
                            true, true, true, false,
                            255, ComponentFactory._SHORTTEXTFIELD, getIndex(), DcRepository.ValueTypes._STRING,
                            "Label"));
       
        if (isFileBacked) {
            systemFields.put(Integer.valueOf(DcObject._SYS_FILENAME),
                    new DcField(DcObject._SYS_FILENAME, getIndex(), "Filename",
                                false, true, false, true,
                                500, ComponentFactory._FILELAUNCHFIELD, getIndex(), DcRepository.ValueTypes._STRING,
                                "Filename"));
            systemFields.put(Integer.valueOf(DcObject._SYS_FILEHASH),
                    new DcField(DcObject._SYS_FILEHASH, getIndex(), "Filehash",
                                false, false, true, false,
                                32, ComponentFactory._SHORTTEXTFIELD, getIndex(), DcRepository.ValueTypes._STRING,
                                "Filehash"));
            systemFields.put(Integer.valueOf(DcObject._SYS_FILESIZE),
                    new DcField(DcObject._SYS_FILESIZE, getIndex(), "Filesize",
                                false, true, true, true,
                                10, ComponentFactory._FILESIZEFIELD, getIndex(), DcRepository.ValueTypes._LONG,
                                "Filesize"));
            systemFields.put(Integer.valueOf(DcObject._SYS_FILEHASHTYPE),
                    new DcField(DcObject._SYS_FILEHASHTYPE, getIndex(), "Filehash Type",
                                false, false, true, false,
                                10, ComponentFactory._SHORTTEXTFIELD, getIndex(), DcRepository.ValueTypes._STRING,
                                "FilehashType"));
        }
    }   
   
    /**
     * Indicates if this module has an insert view available.
     */
    public boolean hasInsertView() {
        return hasInsertView;
    }

    /**
     * Indicates if this module has a search view available.
     */
    public boolean hasSearchView() {
        return hasSearchView;
    }
   
    /**
     * Creates the various views.
     */
    protected void initializeUI()  {
        if (insertView == null && hasInsertView()) {
            insertView = new MasterView(getIndex());

            // table view
            if (!isAbstract()) {
              DcTable table = new DcTable(this, false, true);
              table.setDynamicLoading(false);
              View tableView = new View(insertView, View._TYPE_INSERT, table,
                      DcResources.getText("lblNewItem", getObjectNamePlural()),
                      IconLibrary._icoItemsNew, MasterView._TABLE_VIEW);
              table.setView(tableView);
              insertView.addView(MasterView._TABLE_VIEW, tableView);
            }
           
            // list view
            DcObjectList list = new DcObjectList(this, DcObjectList._CARDS, true, true);
            View listView = new View(insertView, View._TYPE_INSERT, list,
                    DcResources.getText("lblNewItem", getObjectNamePlural()),
                    IconLibrary._icoItemsNew, MasterView._LIST_VIEW);
            list.setView(listView);
           
            insertView.addView(MasterView._LIST_VIEW, listView);
        }
       
        if (searchView == null && hasSearchView() ) {
            searchView = new MasterView(getIndex());
            searchView.setTreePanel(this);
           
            // table view
            if (!isAbstract()) {
              DcTable table = new DcTable(this, false, true);
              View tableView = new View(searchView, View._TYPE_SEARCH, table, getObjectNamePlural(), getIcon16(), MasterView._TABLE_VIEW);
              table.setView(tableView);
             
              searchView.addView(MasterView._TABLE_VIEW, tableView);
            }
           
            // list view
            DcObjectList list = new DcObjectList(this, DcObjectList._CARDS, true, true);
            View listView = new View(searchView, View._TYPE_SEARCH, list, getObjectNamePlural(), getIcon16(), MasterView._LIST_VIEW);
            list.setView(listView);
           
            searchView.addView(MasterView._LIST_VIEW, listView);           
        }
    }

    /**
     * Indicates if the module holds items with a reference to a file.
     */
    public boolean isFileBacked() {
        return isFileBacked;
    }

    /**
     * Retrieves the index of the field on which is sorted by default.
     * Return 1 if this field exists or else the defined default index.
     */
    public int getDefaultSortFieldIdx() {
        return getField(1) != null ? 1 : defaultSortFieldIdx;
    }

    /**
     * The location of the module in the module bar.
     */
    public int getDisplayIndex() {
        return displayIndex;
    }

    /**
     * The field index holding the title of the item.
     */
    public int getNameFieldIdx() {
        return nameFieldIdx;
    }

    public String getIcon16Filename() {
        return icon16filename;
    }

    public String getIcon32Filename() {
        return icon32filename;
    }

    @Override
    public int hashCode() {
        return index;
    }
   
    @Override
    public boolean equals(Object o) {
        return (o instanceof DcModule ? ((DcModule) o).getIndex() == getIndex() : false);
    }

    /**
     * Retrieves the XML definition of this module.
     * @return The XML definition or null.
     */
    public XmlModule getXmlModule() {
        return xmlModule;
    }

    /**
     * Sets the XML definition for this module.
     */
    public void setXmlModule(XmlModule xmlModule) {
        this.xmlModule = xmlModule;
    }   
   
    public String getLabel() {
        if (DcResources.getText(moduleResourceKey) != null) {
            return DcResources.getText(moduleResourceKey);
        } else {
            return label;
        }
    }
   
    /**
     * Compares the supplied module with the current module. The check is performed
     * by comparing the labels.
     */
    @Override
    public int compareTo(DcModule module) {
        return getLabel().toLowerCase().compareTo(module.getLabel().toLowerCase());
    }

    @Override
    public String toString() {
        return getName();
    }
   
    /**
     * Deletes this module. Cannot be undone.
     */
    public void delete() throws Exception {
        if (getXmlModule() != null && !new ModuleJar(getXmlModule()).delete())
            throw new Exception("Module file could not be deleted. " +
                                "Please check the access rights for file: " + getXmlModule().getJarFilename());

       
        if (this instanceof DcPropertyModule && getXmlModule() != null && !getXmlModule().isServingMultipleModules()) {
            // We are (or might be) working on a property base module with a calculated tablename
            DcModule module = DcModules.get(getName());
           
            try {
                DatabaseManager.executeSQL("DROP TABLE " + module.getTableName());
            } catch (Exception e) {
                // happens for property base modules
                logger.debug("Table does not exist, no need to drop " + module.getTableName(), e);
            }
        } else {
            try {
                DatabaseManager.executeSQL("DROP TABLE " + getTableName());
            } catch (Exception e) {
                // happens for property base modules
                logger.debug("Table does not exist, no need to drop " + getTableName(), e);
            }
               
            if (getTemplateModule() != null)
                getTemplateModule().delete();
        }
    }
   
    /**
     * Retrieves the default data for this module.
     * The default data is inserted on new installations. Default data is located
     * in the data folder of the modules folder.
     * @return The default data or null.
     * @throws Exception
     */
    public Collection<DcObject> getDefaultData() throws Exception {

        File csvFile = new File(DataCrow.moduleDir + "data", getTableName() + ".data");
        File xmlFile = new File(DataCrow.moduleDir + "data", getTableName() + ".xml");
       
        Collection<DcObject> items = null;
        ItemImporterHelper reader = null;
        if (csvFile.exists()) {
            reader = new ItemImporterHelper("CSV", getIndex(), csvFile);
            reader.setSetting(CsvImporter._SEPERATOR, "\t");
        } else if (xmlFile.exists()) {
            reader = new ItemImporterHelper("XML", getIndex(), xmlFile);
        }
       
        if (reader != null) {
            reader.start();
            items = reader.getItems();
            reader.clear();
        }
       
        return items;
    }
}
TOP

Related Classes of net.datacrow.core.modules.DcModule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.