Subversion Repositories SmartDukaan

Rev

Rev 473 | Rev 1050 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/**
 * 
 */
package in.shop2020.metamodel.definitions;

import in.shop2020.metamodel.util.ExpandedCMPSlideRuleDefinition;
import in.shop2020.metamodel.util.ExpandedCategory;
import in.shop2020.metamodel.util.ExpandedCategoryFacetDefinition;
import in.shop2020.metamodel.util.ExpandedFacetDefinition;
import in.shop2020.metamodel.util.ExpandedSlideDefinition;
import in.shop2020.util.DBUtils;
import in.shop2020.util.Utils;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Single point of access to all definition objects
 * 
 * @author naveen
 *
 */
public class DefinitionsContainer implements Serializable {

        /** 
         * 
         */
        private static final long serialVersionUID = 1L;
        
        /**
         * Hashtable of Category ID to Category object
         */
        private Map<Long, Category> categories;
        
        /**
         * Hashtable of Slide ID to SlideDefinition object
         */
        private Map<Long, SlideDefinition> slideDefinitions;
        
        /**
         * Hashtable of Feature Definition ID to FeatureDefinition object
         */
        private Map<Long, FeatureDefinition> featureDefinitions;
        
        /**
         * Hashtable of Datatype Definition ID to DatatypeDefinition object
         */
        private Map<Long, DatatypeDefinition> datatypeDefinitions;
        
        /**
         * Hashtable of Enum value ID to EnumValue object
         */
        private Map<Long, EnumValue> enumValues;
        
        /**
         * Hashtable of Unit ID to Unit object
         */
        private Map<Long, Unit> units;
        
        /**
         * Hashtable of Facet Definition ID to FacetDefinition object
         */
        private Map<Long, FacetDefinition> facetDefinitions;
        
        /**
         * Hashtable of Category Facet Definition ID to CategoryFacetDefinition 
         * object
         */
        private Map<Long, CategoryFacetDefinition> categoryFacetDefinitions;
        
        /**
         * Hashtable of IR Data Rule ID to RuleDefinition object
         */
        private Map<Long, RuleDefinition> irDataRuleDefinitions;        
        
        /**
         * Hashtable of IR Meta Data Rule ID to RuleDefinition object
         */
        private Map<Long, RuleDefinition> irMetaDataRuleDefinitions;

        
        /**
         * Hashtable of Comparison Rule ID to CMPRuleDefinition object
         */
        private Map<Long, CMPRuleDefinition> cmpRuleDefinitions;        
        
        /**
         * Hashtable of SlideDefinition ID to CMPSlideRuleDefinition object
         */
        private Map<Long, CMPSlideRuleDefinition> cmpSlideRuleDefinitions;
        
        /**
         * Hashtable of Category ID to list of CMPBucketDefinition object
         */
        private Map<Long, List<CMPBucketDefinition>> cmpBucketDefinitions;

        /**
         * Hashtable of feature definition ID to normalization rule definition ID
         */
        private Map<Long, RuleDefinition> normalizationRuleDefinitions;

        /**
         * Hashtable of feature definition ID to normalization rule definition ID
         */
        private Map<Long, List<Long>> categorySlideSequence;
        
        /**
         * Database path. Just in case we want to override
         */
        private String dbPath =  Utils.CONTENT_DB_PATH;
        
        /**
         * Empty constructor. Data structures are initialised as needed
         */
        public DefinitionsContainer() {
                // Lazy initialization
        }
        
        /**
         * Empty constructor. Just dbPath is initialised
         */
        public DefinitionsContainer(String dbPath) {
                this.dbPath = dbPath;
                // Lazy initialization
        }
        
        /**
         * Returns Slide sequence for a category in the database
         * 
         * @return Map Null if Category-Slide definitions are not imported into 
         * definitions db 
         * (serialized java objects)
         * 
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, List<Long>> getCategorySlideSequence() throws Exception {              
                // De-serialize
                if(this.categorySlideSequence == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator + "categoryslidesequence"+
                                ".ser";
                        
                        this.categorySlideSequence = (Map<Long, List<Long>>) 
                                DBUtils.read(dbFile);
                }
                
                return this.categorySlideSequence;
        }

        /**
         * Given a category ID, returns all slide definition IDs in sequence 
         * provided by content editor
         * 
         * @param categoryID
         * @return List of Slide Definition IDs
         * @throws Exception
         */
        public List<Long> getCategorySlideSequence(long categoryID) 
                throws Exception {      
                this.getCategorySlideSequence();

                return this.categorySlideSequence.get(new Long(categoryID));
        }
        
        /**
         * Returns all Unit objects in the database
         * 
         * @return Map Null if units are not imported into definitions db 
         * (serialized java objects)
         * 
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, Unit> getUnits() throws Exception {            
                // De-serialize
                if(this.units == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator + "units" + ".ser";
                        
                        this.units = (Map<Long, Unit>) DBUtils.read(dbFile);
                }
                
                return this.units;
        }

        /**
         * Resolves Unit ID into Unit object
         * 
         * @param unitID Unit ID
         * @return Unit
         * @throws Exception 
         */
        public Unit getUnit(long unitID) throws Exception {             
                // Initialize 
                if(this.units == null) {
                        this.getUnits();
                }
                
                return this.units.get(new Long(unitID));
        }

        /**
         * Returns all DatatypeDefintion object in database
         * 
         * @return the datatypeDefinitions List of DatatypeDefinition objects
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, DatatypeDefinition> getDatatypeDefinitions() 
                throws Exception {
                
                // De-serialize
                if(this.datatypeDefinitions == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator + "datatypedefinitions" + 
                                ".ser";
                        
                        this.datatypeDefinitions = 
                                (Map<Long, DatatypeDefinition>) DBUtils.read(dbFile);
                }
                return this.datatypeDefinitions;
        }

        /**
         * Resolves Datatype Definition ID into DatetypeDefinition object
         * 
         * @param unitID Unit ID
         * @return Unit
         * @throws Exception 
         */
        public DatatypeDefinition getDatatypeDefinition(long id) throws Exception {
                
                // Initialize 
                if(this.datatypeDefinitions == null) {
                        this.getDatatypeDefinitions();
                }
                
                return this.datatypeDefinitions.get(new Long(id));
        }

        /**
         * Returns EnumValue ID for datatype definition ID and enum value string 
         * to match. Match is case insensitive
         * 
         * @param datatypeDefID DatatypeDefinition ID
         * @param value query enum value string
         * @return long enumValueID - "-1" if not found
         * @throws Exception 
         */
        public long getEnumValueID(long datatypeDefID, String value) 
                throws Exception {
                long enumValueID = -1L;
                
                // Let the callers catch ClassCastException
                EnumDefinition enumDef = 
                        (EnumDefinition)this.getDatatypeDefinition(datatypeDefID);
                
                List<EnumValue> enumValues = enumDef.getEnumValues();
                for(EnumValue enumValue : enumValues) {
                        if(value.equalsIgnoreCase(enumValue.getValue())) {
                                enumValueID = enumValue.getID();
                                break;
                        }
                }
                
                return enumValueID;
        }
        
        /**
         * Returns all category objects in the database
         * 
         * @return the categories
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, Category> getCategories() throws Exception {
                
                // De-serialize
                if(this.categories == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator + "categories" + ".ser";
                        
                        this.categories = (Map<Long, Category>) DBUtils.read(dbFile);
                }
                return this.categories;
        }
        
        /**
         * Resolves Category ID into Category object
         * 
         * @param categoryID Category ID
         * @return Category
         * @throws Exception 
         */
        public Category getCategory(long categoryID) throws Exception {
                
                // Initialize 
                if(this.categories == null) {
                        this.getCategories();
                }
                
                return this.categories.get(new Long(categoryID));
        }
        
        /**
         * Returns expanded Category object. All numeric identifiers are resolved 
         * into detailed objects
         * 
         * @param categoryID
         * @return ExpandedCategory
         * @throws Exception
         */
        public ExpandedCategory getExpandedCategory(long categoryID) 
                throws Exception {
                Category category = this.getCategory(categoryID);
                
                ExpandedCategory expCategory = new ExpandedCategory(category);
                
                return expCategory;
        }
        
        /**
         * Returns all children categories for a Category ID
         * 
         * @param categoryID
         * @return List<Category> Children Categories
         * @throws Exception
         */
        public List<Category> getChildrenCategories(long categoryID) 
                throws Exception {
                
                // Initialize 
                if(this.categories == null) {
                        this.getCategories();
                }
                
                return this.categories.get(new Long(categoryID)).getChildrenCategory();
        }
        
        /**
         * Returns all CategorySlideDefinition objects for a Category ID
         * 
         * @param categoryID Category ID
         * @return List<CategorySlideDefinition> 
         * @throws Exception 
         */
        public List<CategorySlideDefinition> getCategorySlideDefinitions(
                        long categoryID) throws Exception {
                Category category = this.getCategory(categoryID);
                
                return category.getCategorySlideDefintions();
        }
        
        /**
         * Returns All SlideDefinition objects in database
         * 
         * @return the slideDefinitions
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, SlideDefinition> getSlideDefinitions() throws Exception {
                
                // De-serialize
                if(this.slideDefinitions == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator + "slidedefinitions" + 
                                ".ser";
                        
                        this.slideDefinitions = 
                                (Map<Long, SlideDefinition>) DBUtils.read(dbFile);
                }
                return this.slideDefinitions;
        }
        
        /**
         * Resolves SlideDefinition ID into SlideDefinition object
         * 
         * @param id
         * @return SlideDefinition
         * @throws Exception
         */
        public SlideDefinition getSlideDefinition(long id) throws Exception {
                
                // Initialize 
                if(this.slideDefinitions == null) {
                        this.getSlideDefinitions();
                }
                
                return this.slideDefinitions.get(new Long(id));
        }
        
        /**
         * 
         * @param slideID
         * @return ExpandedSlideDefinition 
         * @throws Exception 
         */
        public ExpandedSlideDefinition getExpandedSlideDefinition(long slideID) 
                throws Exception {
                SlideDefinition slideDef = this.getSlideDefinition(slideID);
                
                return new ExpandedSlideDefinition(slideDef);
        }
        
        /**
         * Returns SlideDefinition objects for a category and matching slide label
         * 
         * @param label
         * @return List<SlideDefinition>
         * @throws Exception
         */
        public List<SlideDefinition> getSlideDefinitions(long categoryID, 
                        String label) throws Exception {

                // RE-VISIT
                // May be we need a new data structure, category id to slide definitions
                // for now
                List<SlideDefinition> matchingSlides = new ArrayList<SlideDefinition>();
                
                List<CategorySlideDefinition> csDefs = this.getCategorySlideDefinitions(
                                categoryID);
                
                for(CategorySlideDefinition csDef : csDefs) {
                        SlideDefinition sDef = this.getSlideDefinition(
                                        csDef.getSlideDefintionID());
                        
                        if(sDef.getLabel().equalsIgnoreCase(label)) {
                                matchingSlides.add(sDef);
                        }
                }
                
                return matchingSlides;
        }
        
        /**
         * Resolves Category ID into Category object
         * 
         * @param categoryID
         * @return List<SlideDefinition> 
         * @throws Exception
         */
        public List<SlideDefinition> getSlideDefinitions(long categoryID) 
                throws Exception {

                // RE-VISIT
                // May be we need a new data structure, category id to slide definitions
                // for now
                List<SlideDefinition> matchingSlides = new ArrayList<SlideDefinition>();
                
                List<CategorySlideDefinition> csDefs = this.getCategorySlideDefinitions(
                                categoryID);
                
                for(CategorySlideDefinition csDef : csDefs) {
                        SlideDefinition sDef = this.getSlideDefinition(
                                        csDef.getSlideDefintionID());
                        
                        matchingSlides.add(sDef);
                }
                
                return matchingSlides;
        }
        
        /**
         * Returns list of SlideDefinition objects for a category and editorial 
         * importance value
         * 
         * @param categoryID
         * @param EditorialImportance imp
         * @return List<SlideDefinition>
         * @throws Exception 
         */
        public List<SlideDefinition> getSlides(long categoryID, 
                        EditorialImportance imp) 
                throws Exception {
                
                List<CategorySlideDefinition> catSlideDefs = 
                        this.getCategorySlideDefinitions(categoryID);
                
                Iterator<CategorySlideDefinition> itCatSlideDefs = 
                        catSlideDefs.iterator();
                
                List<SlideDefinition> slideDefs = new ArrayList<SlideDefinition>();
                while(itCatSlideDefs.hasNext()) {
                        CategorySlideDefinition catSlideDef = itCatSlideDefs.next();
                        if(catSlideDef.getEditorialImportance() == imp) {
                                long slideDefID = catSlideDef.getSlideDefintionID();
                                slideDefs.add(this.getSlideDefinition(slideDefID));
                        }
                }
                return slideDefs;
        }
        
        /**
         * Returns all FeatureDefinition object in database
         * 
         * @return Map<Long, FeatureDefinition>
         * @throws Exception
         */
        @SuppressWarnings("unchecked")
        public Map<Long, FeatureDefinition> getFeatureDefinitions() 
                throws Exception {
                
                // De-serialize
                if(this.featureDefinitions == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator + "featuredefinitions" + 
                                ".ser";
                        
                        this.featureDefinitions = 
                                (Map<Long, FeatureDefinition>) DBUtils.read(dbFile);
                }
                return this.featureDefinitions;
        }
        
        /**
         * Returns all FeatureDefinition objects for a slide
         * 
         * @param slideID
         * @return List<FeatureDefinition> 
         * @throws Exception
         */
        public List<FeatureDefinition> getFeatureDefinitions(long slideID) 
                throws Exception {
                List<FeatureDefinition> featureDefs = 
                        new ArrayList<FeatureDefinition>();
                
                SlideDefinition slideDef = this.getSlideDefinition(slideID);
                List<SlideFeatureDefinition> slideFeatureDefs = 
                        slideDef.getSlideFeatureDefinitions();
                
                for(int i=0; i<slideFeatureDefs.size(); i++) {
                        featureDefs.add(this.getFeatureDefinition(
                                        slideFeatureDefs.get(i).getFeatureDefintionID()));
                }
                
                return featureDefs;
        }
        
        /**
         * Returns list of FeatureDefinition objects for a slide given editorial 
         * importance
         * 
         * @param slideID
         * @param imp Editorial Importance enum object
         * @return List<FeatureDefinition>
         * @throws Exception
         */
        public List<FeatureDefinition> getFeatureDefinitions(long slideID, 
                        EditorialImportance imp)  throws Exception {
                List<FeatureDefinition> featureDefs = 
                        new ArrayList<FeatureDefinition>();
                
                SlideDefinition slideDef = this.getSlideDefinition(slideID);
                List<SlideFeatureDefinition> slideFeatureDefs = 
                        slideDef.getSlideFeatureDefinitions();
                
                for(SlideFeatureDefinition slideFeatureDef : slideFeatureDefs) {
                        if(slideFeatureDef.getEditorialImportance() == imp) {
                                featureDefs.add(this.getFeatureDefinition(
                                                slideFeatureDef.getFeatureDefintionID()));
                        }
                }
                
                return featureDefs;
        }
        
        /**
         * Resolves Feature Definition ID into FeatureDefinition object
         * 
         * @param id Feature Definition ID 
         * @return FeatureDefinition
         * @throws Exception
         */
        public FeatureDefinition getFeatureDefinition(long id) throws Exception {
                
                // Initialize 
                if(this.featureDefinitions == null) {
                        this.getFeatureDefinitions();
                }
                
                return this.featureDefinitions.get(new Long(id));
        }       

        /**
         * Returns matching FeatureDefinition object for slide ID and feature label.
         * Label matching is case insensitive.
         * 
         * @param slideID Slide ID
         * @param featureLabel label to match, case is ignored
         * @return FeatureDefinition 
         * @throws Exception
         */
        public FeatureDefinition getFeatureDefinition(long slideID, 
                        String featureLabel) throws Exception {
                FeatureDefinition featureDef = null;
                
                SlideDefinition slideDef = this.getSlideDefinition(slideID);
                for(SlideFeatureDefinition slideFeatureDef : 
                        slideDef.getSlideFeatureDefinitions()) {
                        
                        long featureDefID = slideFeatureDef.getFeatureDefintionID();
                        
                        FeatureDefinition thisFeatureDef = this.getFeatureDefinition(
                                        featureDefID);
                        
                        if(featureLabel.equalsIgnoreCase(thisFeatureDef.getLabel())) {
                                featureDef = thisFeatureDef;
                        }
                }
                
                return featureDef;
        }

        /**
         * Returns all EnumValue objects in the database
         * 
         * @return the enumValues
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, EnumValue> getEnumValues() throws Exception {
                // De-serialise
                if(this.enumValues == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator + "enumvalues" + 
                                ".ser";
                        
                        this.enumValues = 
                                (Map<Long, EnumValue>) DBUtils.read(dbFile);
                }
                
                return this.enumValues;
        }
        
        /**
         * Resolves Enum value ID into EnumValue object
         * 
         * @param enumValueID
         * @return EnumValue
         * @throws Exception
         */
        public EnumValue getEnumValue(long enumValueID) throws Exception {
                // Initialise
                if(this.enumValues == null) {
                        this.getEnumValues();
                }
                
                return this.enumValues.get(new Long(enumValueID));
        }
        
        /**
         * Returns all FacetDefinition objects in the database
         * 
         * @return Map Null if facet definitions are not imported into definitions 
         * db (serialized java objects)
         * 
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, FacetDefinition> getFacetDefinitions() throws Exception {
                
                // De-serialize
                if(this.facetDefinitions == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator + "facetdefinitions" + 
                                ".ser";
                        
                        this.facetDefinitions = 
                                (Map<Long, FacetDefinition>) DBUtils.read(dbFile);
                }
                
                return this.facetDefinitions;
        }
        
        /**
         * Resolves Facet Definition ID into FacetDefinition object
         * 
         * @param facetDefinitionID
         * @return FacetDefinition
         * @throws Exception
         */
        public FacetDefinition getFacetDefinition(long facetDefinitionID) 
                throws Exception {
                
                if(this.facetDefinitions == null) {
                        this.getFacetDefinitions();
                }
                
                return this.facetDefinitions.get(new Long(facetDefinitionID));
        }
        
        /**
         * Utility method to get Expanded version of ExpandedFacetDefinition object 
         * 
         * @param facetDefinitionID
         * @return ExpandedFacetDefinition
         * @throws Exception
         */
        public ExpandedFacetDefinition getExpandedFacetDefinition(
                        long facetDefinitionID) throws Exception {
                
                FacetDefinition facetDefinition = 
                        this.getFacetDefinition(facetDefinitionID);
                
                ExpandedFacetDefinition expFacetDefinition = 
                        new ExpandedFacetDefinition(facetDefinition);
                
                return expFacetDefinition;
        }
        
        /**
         * Returns all CategoryFacetDefinition objects in the database
         * 
         * @return Map Null if category facet definitions are not imported into 
         * definitions db (serialized java objects)
         * 
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, CategoryFacetDefinition> getCategoryFacetDefinitions() 
                throws Exception {
                
                // De-serialize
                if(this.categoryFacetDefinitions == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator + 
                                "categoryfacetdefinitions.ser";
                        
                        this.categoryFacetDefinitions = 
                                (Map<Long, CategoryFacetDefinition>) DBUtils.read(dbFile);
                }
                
                return this.categoryFacetDefinitions;
        }
        
        /**
         * Resolves Category-Facet Definition ID into CategoryFacetDefinition object
         * 
         * @param categoryID
         * @return CategoryFacetDefinition
         * @throws Exception
         */
        public CategoryFacetDefinition getCategoryFacetDefinition(
                        long categoryID) throws Exception {
                
                if(this.categoryFacetDefinitions == null) {
                        this.getCategoryFacetDefinitions();
                }
                
                return this.categoryFacetDefinitions.get(
                                new Long(categoryID));
        }
        
        /**
         * Utility method to get Expanded version of CategoryFacetDefinition object 
         * 
         * @param categoryID
         * @return ExpandedCategoryFacetDefinition
         * @throws Exception
         */
        public ExpandedCategoryFacetDefinition getExpandedCategoryFacetDefinition(
                        long categoryID) throws Exception  {
                CategoryFacetDefinition categoryFacetDef = 
                        this.getCategoryFacetDefinition(categoryID);
                
                ExpandedCategoryFacetDefinition expCategoryFacetDef = 
                        new ExpandedCategoryFacetDefinition(categoryFacetDef);
                
                return expCategoryFacetDef;
        }
        
        /**
         * Returns all IR Data RuleDefintion objects in the database
         * 
         * @return Map Null if IR data rule definitions are not imported into 
         * definitions db (serialized java objects)
         * 
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, RuleDefinition> getIrDataRuleDefinitions() 
                throws Exception {
                
                // De-serialize
                if(this.irDataRuleDefinitions == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator + "irdatarules" + ".ser";
                        
                        this.irDataRuleDefinitions = 
                                (Map<Long, RuleDefinition>) DBUtils.read(dbFile);
                }
                
                return this.irDataRuleDefinitions;
        }
        
        /**
         * Resolves IR Data Rule Definition ID into RuleDefinition object
         * 
         * @param irDataRuleDefinitionID
         * @return RuleDefinition
         * @throws Exception
         */
        public RuleDefinition getIrDataRuleDefinition(
                        long irDataRuleDefinitionID) throws Exception {
                
                if(this.irDataRuleDefinitions == null) {
                        this.getIrDataRuleDefinitions();
                }
                
                return this.irDataRuleDefinitions.get(new Long(irDataRuleDefinitionID));
        }
        
        /**
         * Returns all IR Meta Data RuleDefintion objects in the database
         * 
         * @return Map Null if IR meta-data rule definitions are not imported into 
         * definitions db (serialized java objects)
         * 
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, RuleDefinition> getIrMetaDataRuleDefinitions() 
                throws Exception {
                
                // De-serialize
                if(this.irMetaDataRuleDefinitions == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator + "irmetadatarules" + 
                                ".ser";
                        
                        this.irMetaDataRuleDefinitions = 
                                (Map<Long, RuleDefinition>) DBUtils.read(dbFile);
                }
                
                return this.irMetaDataRuleDefinitions;
        }
        
        /**
         * Resolves IR Meta Data Rule Definition ID into RuleDefinition object
         * 
         * @param irMetaDataRuleDefinitionID
         * @return RuleDefinition
         * @throws Exception
         */
        public RuleDefinition getIrMetaDataRuleDefinition(
                        long irMetaDataRuleDefinitionID) throws Exception {
                
                if(this.irMetaDataRuleDefinitions == null) {
                        this.getIrMetaDataRuleDefinitions();
                }
                
                return this.irMetaDataRuleDefinitions.get(
                                new Long(irMetaDataRuleDefinitionID));
        }
        
        /**
         * Returns all Comparison RuleDefintion objects in the database
         * 
         * @return Map Null if Comparison rule definitions are not imported into 
         * definitions db (serialized java objects)
         * 
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, CMPRuleDefinition> getComparisonRuleDefinitions() 
                throws Exception {
                
                // De-serialize
                if(this.cmpRuleDefinitions == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator + "comparisonrules" + 
                                ".ser";
                        
                        this.cmpRuleDefinitions = 
                                (Map<Long, CMPRuleDefinition>) DBUtils.read(dbFile);
                }
                
                return this.cmpRuleDefinitions;
        }
        
        /**
         * Resolves IR Data Rule Definition ID into RuleDefinition object
         * 
         * @param cmpRuleDefinitionID
         * @return CMPRuleDefinition
         * @throws Exception
         */
        public CMPRuleDefinition getComparisonRuleDefinition(
                        long cmpRuleDefinitionID) throws Exception {
                
                if(this.cmpRuleDefinitions == null) {
                        this.getComparisonRuleDefinitions();
                }
                
                return this.cmpRuleDefinitions.get(new Long(cmpRuleDefinitionID));
        }

        
        /**
         * Returns all ComparisonSlideRuleDefintion objects in the database
         * 
         * @return Map Null if Comparison slide-rule definitions are not imported 
         * into definitions db (serialized java objects)
         * 
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, CMPSlideRuleDefinition> getComparisonSlideRuleDefinitions() 
                throws Exception {
                
                // De-serialize
                if(this.cmpSlideRuleDefinitions == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator +  
                                "comparisondefinitions.ser";
                        Utils.info("dbFile=" + dbFile);
                        
                        this.cmpSlideRuleDefinitions = 
                                (Map<Long, CMPSlideRuleDefinition>) DBUtils.read(dbFile);
                        
                        //Utils.info("this.cmpSlideRuleDefinitions=" +
                        //              this.cmpSlideRuleDefinitions);
                }
                
                return this.cmpSlideRuleDefinitions;
        }
        
        /**
         * Resolves Category ID into List of CMPSlideRuleDefinition object
         * 
         * @param categoryID
         * @return List<CMPSlideRuleDefinition> 
         * @throws Exception
         */
        public CMPSlideRuleDefinition getComparisonSlideRuleDefinition(
                        long slideDefinitionID) throws Exception {
                
                if(this.cmpSlideRuleDefinitions == null) {
                        this.getComparisonSlideRuleDefinitions();
                }
                
                return this.cmpSlideRuleDefinitions.get(new Long(slideDefinitionID));
        }

        
        /**
         * Resolves Slide Definition ID into ExpandedCMPSlideRuleDefinition object
         * 
         * @param categoryID
         * @return ExpandedCMPSlideRuleDefinition 
         * @throws Exception
         */
        public ExpandedCMPSlideRuleDefinition
                getExpandedComparisonSlideRuleDefinition(long slideDefinitionID) 
                throws Exception {
                Utils.info("slideDefinitionID=" + slideDefinitionID);
                
                CMPSlideRuleDefinition cmpSlideRuleDef = 
                        this.getComparisonSlideRuleDefinition(slideDefinitionID);
                
                if(cmpSlideRuleDef == null) {
                        return null;
                }
                
                ExpandedCMPSlideRuleDefinition expDef = 
                        new ExpandedCMPSlideRuleDefinition(cmpSlideRuleDef);
                
                return expDef;
        }

        
        /**
         * Returns all ComparisonSlideRuleDefintion objects in the database
         * 
         * @return Map Null if Comparison slide-rule definitions are not imported 
         * into definitions db (serialized java objects)
         * 
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, List<CMPBucketDefinition>> getComparisonBucketDefinitions() 
                throws Exception {
                
                // De-serialize
                if(this.cmpBucketDefinitions == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator +  "comparisonbuckets.ser";
                        Utils.info("dbFile=" + dbFile);
                        
                        this.cmpBucketDefinitions = 
                                (Map<Long, List<CMPBucketDefinition>>) DBUtils.read(dbFile);
                }
                
                return this.cmpBucketDefinitions;
        }
        
        /**
         * Resolves Category ID into List of CMPBucketDefinition object
         * 
         * @param categoryID
         * @return List<CMPBucketDefinition> 
         * @throws Exception
         */
        public List<CMPBucketDefinition> getComparisonBucketDefinitions(
                        long categoryID) throws Exception {
                
                if(this.cmpBucketDefinitions == null) {
                        this.getComparisonBucketDefinitions();
                }
                
                return this.cmpBucketDefinitions.get(new Long(categoryID));
        }
        
        /**
         * Resolve comparison bucket name for a slide in a particular category
         * 
         * @param categoryID
         * @param slideDefintionID
         * @return Bucket Name if found else Null
         * @throws Exception 
         */
        public String getComparisonBucketName(long categoryID, 
                        long slideDefinitionID) throws Exception {
                List<CMPBucketDefinition> cmpBuckets = 
                        this.getComparisonBucketDefinitions(categoryID);
                
                for (CMPBucketDefinition cmpBucket : cmpBuckets) {
                        List<Long> slideDefinitionIDs = cmpBucket.getSlideDefinitionIDs();
                        
                        if(slideDefinitionIDs.contains(new Long(slideDefinitionID))) {
                                return cmpBucket.getName();
                        }
                }
                
                return null;
        }
        
        /**
         * Returns list of facet definition IDs for given category ID
         * 
         * @param categoryID
         * @return list of facet definition IDs
         * @throws Exception 
         */
        public List<Long> getFacetDefinitionIDs(long categoryID) throws Exception {
                List<Long> facetDefIDs = new ArrayList<Long>();
                
                CategoryFacetDefinition categoryFacetDef = 
                        this.getCategoryFacetDefinition(categoryID);
                if(categoryFacetDef == null)
                        return null;
                List<FacetRuleDefinition> facetRuleDefs = 
                        categoryFacetDef.getFacetRuleDefinitions();
                
                for(FacetRuleDefinition facetRuleDef : facetRuleDefs) {
                        facetDefIDs.add(new Long(facetRuleDef.getFacetDefinitionID()));
                }
                
                return facetDefIDs;
        }
        
        /**
         * Returns list of feature definition IDs for given category ID
         * 
         * @param categoryID
         * @return list of feature definition IDs
         * @throws Exception 
         */
        public List<Long> getFeatureDefinitionIDs(long categoryID) 
                throws Exception {
                
                List<Long> featureDefIDs = new ArrayList<Long>();
                
                List<SlideDefinition> slideDefs = this.getSlideDefinitions(categoryID);
                
                for(SlideDefinition slideDef : slideDefs) {
                        List<Long> slideFeatureDefIDs = 
                                this.getFeatureDefintionIDs(slideDef);
                        
                        featureDefIDs.addAll(slideFeatureDefIDs);
                }
                
                return featureDefIDs;
        }
        
        /**
         * Returns list of feature definition IDs for given slide definition ID
         * 
         * @param slideDef
         * @return list of feature definition IDs
         */
        public List<Long> getFeatureDefintionIDs(SlideDefinition slideDef) {
                List<Long> featureDefIDs = new ArrayList<Long>();
                
                List<SlideFeatureDefinition> slideFeatureDefs = 
                        slideDef.getSlideFeatureDefinitions();
                
                for(SlideFeatureDefinition slideFeatureDef : slideFeatureDefs) {
                        featureDefIDs.add(
                                        new Long(slideFeatureDef.getFeatureDefintionID()));
                }
                
                return featureDefIDs;
        }
        
        /**
         * 
         * @param borrowedSlideDefID
         * @return
         * @throws Exception 
         */
        public boolean isValidSlideDefinitionID(long borrowedSlideDefID) 
                throws Exception {
                this.getSlideDefinitions();
                
                return this.slideDefinitions.containsKey(new Long(borrowedSlideDefID));
        }
        
        /**
         * Returns Facet-Rule definition object defined for a category and 
         * slide definition
         * 
         * @param borrowedCategoryID
         * @param slideDefID
         * @return FacetRuleDefinition 
         * @throws Exception 
         */
        public FacetRuleDefinition getFacetRuleDefinitionForSlide(long categoryID,
                        long slideDefinitionID) throws Exception {
                CategoryFacetDefinition categoryFacetDef = 
                        this.getCategoryFacetDefinition(categoryID);
                
                List<FacetRuleDefinition> facetRuleDefs = 
                        categoryFacetDef.getFacetRuleDefinitions();
                
                for(FacetRuleDefinition facetRuleDef : facetRuleDefs) {
                        if(facetRuleDef.getSlideDefinitionID() == slideDefinitionID) {
                                return facetRuleDef;
                        }
                }
                
                return null;
        }
        
        /**
         * Returns Facet-Rule definition object defined for a category and 
         * feature definition
         * 
         * @param categoryID
         * @param featureDefinitionID
         * @return FacetRuleDefinition
         * @throws Exception
         */
        public FacetRuleDefinition getFacetRuleDefinitionForFeature(long categoryID,
                        long featureDefinitionID) throws Exception {
                CategoryFacetDefinition categoryFacetDef = 
                        this.getCategoryFacetDefinition(categoryID);
                
                List<FacetRuleDefinition> facetRuleDefs = 
                        categoryFacetDef.getFacetRuleDefinitions();
                
                for(FacetRuleDefinition facetRuleDef : facetRuleDefs) {
                        if(facetRuleDef.getFeatureDefinitionID() == featureDefinitionID) {
                                return facetRuleDef;
                        }
                }
                
                return null;
        }

        /**
         * Returns all normalization rule defined
         * 
         * @return Map<Long, RuleDefinition> 
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        public Map<Long, RuleDefinition> getNormalizationRules() throws Exception {
                
                // De-serialize
                if(this.normalizationRuleDefinitions == null) {
                        String dbFile = this.dbPath + "definitions" + File.separator +  
                                "normalizationrules.ser";
                        
                        Utils.info("dbFile=" + dbFile);
                        
                        this.normalizationRuleDefinitions = 
                                (Map<Long, RuleDefinition>) DBUtils.read(dbFile);
                }
                
                return this.normalizationRuleDefinitions;
        }

        
        /**
         * True if feature has normalization rule defined
         * 
         * @param feature
         * @return boolean 
         * @throws Exception 
         */
        public boolean needsNormalization(long featureDefinitionID) 
                throws Exception {
                this.getFeatureDefinitions();
                
                FeatureDefinition featureDef = 
                        this.featureDefinitions.get(new Long(featureDefinitionID));
                
                if(featureDef.getNormalizationRuleDefinitionID() != 0L) {
                        return true;
                }
                
                return false;
        }
        
        /**
         * Returns normalization rule definition for rule definition ID
         * 
         * @param ruleID
         * @return RuleDefinition 
         * @throws Exception 
         */
        public RuleDefinition getNormalizationRuleDefinition(
                        long ruleDefinitionID) throws Exception {
                this.getNormalizationRules();
                
                return this.normalizationRuleDefinitions.get(
                                new Long(ruleDefinitionID));
        }
}