Subversion Repositories SmartDukaan

Rev

Rev 26 | Blame | Last modification | View Log | RSS feed

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

import in.shop2020.metamodel.definitions.BulletDefinition;
import in.shop2020.metamodel.definitions.Category;
import in.shop2020.metamodel.definitions.CategorySlideDefinition;
import in.shop2020.metamodel.definitions.CompositeDefinition;
import in.shop2020.metamodel.definitions.CompositePartDefinition;
import in.shop2020.metamodel.definitions.DatatypeDefinition;
import in.shop2020.metamodel.definitions.EditorialImportance;
import in.shop2020.metamodel.definitions.EnumDefinition;
import in.shop2020.metamodel.definitions.EnumValue;
import in.shop2020.metamodel.definitions.FeatureDefinition;
import in.shop2020.metamodel.definitions.SlideDefinition;
import in.shop2020.metamodel.definitions.SlideFeatureDefinition;
import in.shop2020.metamodel.definitions.Unit;
import in.shop2020.metamodel.jaxb.BulletDefinitionType;
import in.shop2020.metamodel.jaxb.CategorySlideDefinitionType;
import in.shop2020.metamodel.jaxb.CategoryType;
import in.shop2020.metamodel.jaxb.CompositeDefinitionType;
import in.shop2020.metamodel.jaxb.CompositePartDefinitionType;
import in.shop2020.metamodel.jaxb.DatatypeDefinitionType;
import in.shop2020.metamodel.jaxb.DefinitionType;
import in.shop2020.metamodel.jaxb.EditorialImportanceType;
import in.shop2020.metamodel.jaxb.EnumDefinitionType;
import in.shop2020.metamodel.jaxb.EnumValueType;
import in.shop2020.metamodel.jaxb.FeatureDefinitionType;
import in.shop2020.metamodel.jaxb.SlideDefinitionType;
import in.shop2020.metamodel.jaxb.SlideFeatureDefinitionType;
import in.shop2020.metamodel.jaxb.UnitType;
import in.shop2020.util.Utils;

import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;

/**
 * MM - Meta-Model Tool
 * Imports and exports model definitions. Validates against meta model
 * 
 * @author naveen
 *
 */
public class MM {
        public static final String DEFINITIONS_SRC_PATH = 
                "/home/naveen/workspace/eclipse/webapp/src/xml/model/";
        public static final String DEFINITIONS_DB_PATH = 
                "/home/naveen/workspace/eclipse/db/definitions/";
        public static final String ENTITIES_DB_PATH = 
                "/home/naveen/workspace/eclipse/db/entities/";
        
        private String definitionSetName;
        private String srcFile;
        private String dbFile;
        
        /**
         * @param args
         */
        public static void main(String[] args) throws Exception {
                String[] definitionSetNames = new String[] {"units", 
                                "datatypedefinitions", "featuredefinitions", "slidedefinitions", 
                                "categories"};
                
                String[] commands = new String[] {"show", "import"};

                String usage = "Usage: MM ["+ StringUtils.join(commands, "|") +"] ["+ 
                        StringUtils.join(definitionSetNames, "|") +"]";
                
                if(args.length < 2) {
                        System.out.println(usage);
                        System.exit(-1);
                }
                Utils.logger.info("MM "+ args[0] + " " + args[1]);
                
                String inputCommand = args[0];
                String inputDefinitionSet = args[1];
                
                if(!ArrayUtils.contains(commands, inputCommand)) {
                        System.out.println(usage);
                        System.exit(-1);
                }
                
                if(!ArrayUtils.contains(definitionSetNames, inputDefinitionSet)) {
                        System.out.println(usage);
                        System.exit(-1);
                }
                
                MM mm = new MM(inputDefinitionSet);
                if(inputCommand.equals("import")) {
                        mm.importDefinitionSet();
                }
                else if(inputCommand.equals("show")) {
                        mm.showDefinitionSet();
                }
        }
        
        /**
         * 
         * @param definitionSet
         */
        public MM(String definitionSetName) {
                this.definitionSetName = definitionSetName;
                this.srcFile = DEFINITIONS_SRC_PATH + this.definitionSetName + ".xml";
                this.dbFile = DEFINITIONS_DB_PATH + this.definitionSetName + ".ser";
        }
        
        /**
         * 
         */
        @SuppressWarnings("unchecked")
        public void importDefinitionSet() throws Exception {
                DefinitionType defType = this.unmarshallSrcFile(this.srcFile);
                Object objectToStore = null;
                
                // Units
                if(this.definitionSetName.equals("units")) {
                        Map unitsMap = this.convertUnits(defType);
                        objectToStore = unitsMap;
                }
                
                // Categories
                else if(this.definitionSetName.equals("categories")) {
                        Map<Long, Category> categoriesMap = new HashMap<Long, Category>();
                        Category root = this.convertCategories(defType, categoriesMap);
                        //Utils.logger.info(categoriesMap);
                        //Utils.logger.info(root);
                        //System.exit(0);
                        
                        // Tree
                        String categoryTreeDBFile = DEFINITIONS_DB_PATH + "categorytree" + 
                                ".ser";
                        
                        if(root != null) {
                                DBUtils.store(root, categoryTreeDBFile);
                        }
                        
                        // Map
                        objectToStore = categoriesMap;
                }
                
                // Datatype Definitions
                else if(this.definitionSetName.equals("datatypedefinitions")) {
                        Map<Long, DatatypeDefinition> datatypeDefsMap = 
                                this.convertDatatypeDefinition(defType);
                        
                        // Store enum value id to value map separately
                        String enumValueDBFile = DEFINITIONS_DB_PATH + "enumvalues" + 
                                ".ser";
                        
                        // RE-VISIT - May not be optimal
                        Map<Long, EnumValue> enumValuesMap = new TreeMap<Long, EnumValue>();
                        for(Long datatypeDefID : datatypeDefsMap.keySet()) {
                                DatatypeDefinition datatypeDef = 
                                        datatypeDefsMap.get(datatypeDefID);
                                
                                if(datatypeDef instanceof EnumDefinition) {
                                        List<EnumValue> enumValues = 
                                                ((EnumDefinition) datatypeDef).getEnumValues();
                                        
                                        for(EnumValue enumValue : enumValues) {
                                                enumValuesMap.put(new Long(enumValue.getID()), 
                                                                enumValue);
                                        }
                                }
                        }
                        Utils.logger.info("enumValuesMap=" + enumValuesMap);
                        DBUtils.store(enumValuesMap, enumValueDBFile);
                        
                        objectToStore = datatypeDefsMap;
                }
                
                // Feature Definitions
                else if(this.definitionSetName.equals("featuredefinitions")) {
                        Map featureDefsMap = this.convertFeatureDefinitions(defType);

                        objectToStore = featureDefsMap;
                }
                
                // Slide Definitions
                else if(this.definitionSetName.equals("slidedefinitions")) {
                        Map slideDefsMap = this.convertSlideDefinitions(defType);

                        objectToStore = slideDefsMap;
                }
                
                if(objectToStore != null) {
                        DBUtils.store(objectToStore, this.dbFile);
                }
        }

        /**
         * 
         */
        public void showDefinitionSet() throws Exception {
                Object obj = DBUtils.read(this.dbFile);
                Utils.logger.info(obj.toString());
                
                if(this.definitionSetName.equals("categories")) {
                        String categoryTreeDBFile = DEFINITIONS_DB_PATH + "categorytree" + 
                                ".ser";
                        
                        Category root = (Category)DBUtils.read(categoryTreeDBFile);
                        Utils.logger.info(root.toString());
                        //Utils.logger.info("root.getChildrenCategory().size: " + 
                        //              root.getChildrenCategory().size());
                }
        }
        
        /**
         * 
         * @return Map
         */
        private Map<Long, SlideDefinition> convertSlideDefinitions(
                        DefinitionType defType) {
                
                Map<Long, SlideDefinition> defs = 
                        new HashMap<Long, SlideDefinition>();
                
                List<SlideDefinitionType> jaxbDefs = defType.getSlideDefinition();
                Iterator<SlideDefinitionType> itjaxbDefs = jaxbDefs.iterator();
                
                // Slide definitions
                while(itjaxbDefs.hasNext()) {
                        SlideDefinitionType jaxbDef = itjaxbDefs.next();
                        
                        Utils.logger.info("Slide label=" + jaxbDef.getLabel());
                        SlideDefinition def = new SlideDefinition(jaxbDef.getID(),
                                        jaxbDef.getLabel());
                        def.setDescription(jaxbDef.getDescription());
                        
                        // Slide Feature Definition
                        List<SlideFeatureDefinitionType> jaxbSlideFeatureDefs = 
                                jaxbDef.getSlideFeatureDefinition();
                        
                        if(jaxbSlideFeatureDefs != null) {
                                def.setSlideFeatureDefinitions((
                                                this.convertSlideFeatureDefinitions(
                                                                jaxbSlideFeatureDefs)));
                        }
                        Utils.logger.info("def=" + def);
                        
                        defs.put(new Long(jaxbDef.getID()), def);
                }
                        
                return defs;
        }
        
        /**
         * 
         * @param jaxbDefs
         * @return List<SlideFeatureDefinition>
         */
        private List<SlideFeatureDefinition> convertSlideFeatureDefinitions(
                        List<SlideFeatureDefinitionType> jaxbDefs) {
                
                List<SlideFeatureDefinition> defs = 
                        new ArrayList<SlideFeatureDefinition>();
                
                Iterator<SlideFeatureDefinitionType> itjaxbDefs = jaxbDefs.iterator();
                
                // Slide-feature definitions
                while(itjaxbDefs.hasNext()) {
                        SlideFeatureDefinitionType jaxbDef = itjaxbDefs.next();
                        SlideFeatureDefinition def = new SlideFeatureDefinition(
                                        jaxbDef.getFeatureDefinitionID());
                        
                        def.setEditorialImportance(this.convertEditorialImportance(
                                        jaxbDef.getEditorialImportance()));
                        
                        def.setDescription(jaxbDef.getDescription());
                        
                        defs.add(def);
                }
                
                return defs;
        }
        
        /**
         * 
         * @return Map
         */
        private Map<Long, FeatureDefinition> convertFeatureDefinitions(
                        DefinitionType defType) {
                
                Map<Long, FeatureDefinition> defs = 
                        new HashMap<Long, FeatureDefinition>();
                
                List<FeatureDefinitionType> jaxbDefs = defType.getFeatureDefinition();
                Iterator<FeatureDefinitionType> itjaxbDefs = jaxbDefs.iterator();
                
                // Feature definitions
                while(itjaxbDefs.hasNext()) {
                        FeatureDefinitionType jaxbDef = itjaxbDefs.next();
                        
                        //Utils.logger.info("Feature label=" + jaxbDef.getLabel());
                        FeatureDefinition def = new FeatureDefinition(jaxbDef.getID(),
                                        jaxbDef.getLabel());
                        def.setAllowsBlank(jaxbDef.isCanbeBlank());
                        def.setDescription(jaxbDef.getDescription());
                        
                        // Bullet Definition
                        BulletDefinitionType jaxbBulletDef = jaxbDef.getBulletDefinition();
                        if(jaxbBulletDef != null) {
                                def.setBulletDefinition(this.convertBulletDefinition(
                                                jaxbBulletDef));
                        }
                        Utils.logger.info("def=" + def);
                        
                        defs.put(new Long(jaxbDef.getID()), def);
                }
                        
                return defs;
        }

        /**
         * 
         * @param jaxbDef BulletDefinitionType
         * @return BulletDefinition
         */
        private BulletDefinition convertBulletDefinition(
                        BulletDefinitionType jaxbDef) {
                
                BulletDefinition def = new BulletDefinition(
                                jaxbDef.getDatatypeDefinitionID());
                
                Long unitID = jaxbDef.getUnitID();
                if(unitID != null) {
                        def.setUnitID(unitID.longValue());
                }
                def.setMultivalue(jaxbDef.isIsMultivalue());
                def.setLearned(jaxbDef.isIsLearned());
                def.setDescription(jaxbDef.getDescription());
                
                return def;
        }
        
        /**
         * 
         * @return Map
         */
        private Map<Long, DatatypeDefinition> convertDatatypeDefinition(
                        DefinitionType defType) {
                
                Map<Long, DatatypeDefinition> defs = 
                        new HashMap<Long, DatatypeDefinition>();
                
                List<DatatypeDefinitionType> jaxbDefs = defType.getDatatypeDefinition();
                Iterator<DatatypeDefinitionType> it = jaxbDefs.iterator();
                
                while(it.hasNext()) {
                        DatatypeDefinitionType jaxbDef = it.next();
                        
                        DatatypeDefinition def = null;
                        CompositeDefinitionType compositeDefType = 
                                jaxbDef.getCompositeDefinition();

                        EnumDefinitionType enumDefType = 
                                jaxbDef.getEnumDefinition();
                        
                        // Composite data type
                        if(compositeDefType != null) {
                                CompositeDefinition compDef = new CompositeDefinition(
                                                jaxbDef.getID(), jaxbDef.getName(), 
                                                compositeDefType.getSeparator());
                                
                                List<CompositePartDefinitionType> jaxbPartDefs = 
                                        compositeDefType.getCompositePartDefinition();
                                
                                Iterator<CompositePartDefinitionType> itPartDefs = 
                                        jaxbPartDefs.iterator();
                                
                                // Collect parts
                                while(itPartDefs.hasNext()) {
                                        CompositePartDefinitionType jaxbPartDef = itPartDefs.next();
                                        CompositePartDefinition partDef = 
                                                this.convertCompositePartDefinition(jaxbPartDef);
                                        
                                        compDef.addCompositePartDefinition(partDef);
                                }
                                
                                def = compDef;
                        }
                        
                        // Enumerated values
                        else if(enumDefType != null) {
                                EnumDefinition enumDef = new EnumDefinition(jaxbDef.getID(), 
                                                jaxbDef.getName());
                                
                                List<EnumValueType> jaxbEnumValues = 
                                        enumDefType.getEnumValue();
                                        
                                Iterator<EnumValueType> itEnumValues = 
                                        jaxbEnumValues.iterator();
                                
                                // Collect individual value
                                while(itEnumValues.hasNext()) {
                                        EnumValueType jaxbEnumValue = itEnumValues.next();
                                        EnumValue enumValue = 
                                                this.convertEnumValueDefinition(jaxbEnumValue);
                                        
                                        enumDef.addEnumValue(enumValue);
                                }
                                
                                def = enumDef;
                        }
                        
                        // Primitive
                        else {
                                def = new DatatypeDefinition(jaxbDef.getID(), 
                                                jaxbDef.getName());
                        }
                        
                        def.setDescription(jaxbDef.getDescription());
                        Utils.logger.info("def=" + def);
                        
                        defs.put(new Long(jaxbDef.getID()), def);
                }
                
                return defs;
        }

        /**
         * 
         * @param jaxbEnumValue
         * @return EnumValue
         */
        private EnumValue convertEnumValueDefinition(EnumValueType jaxbEnumValue) {
                
                EnumValue enumValue = new EnumValue(jaxbEnumValue.getID(), 
                                jaxbEnumValue.getValue());

                return enumValue;
        }
        /**
         * 
         * @param jaxbPartDef
         * @return CompositePartDefinition
         */
        private CompositePartDefinition convertCompositePartDefinition(
                        CompositePartDefinitionType jaxbPartDef) {
                
                CompositePartDefinition partDef = new CompositePartDefinition(
                                jaxbPartDef.getLabel(), jaxbPartDef.getDatatypeDefinitionID(), 
                                jaxbPartDef.getUnitID());
                
                partDef.setDescription(jaxbPartDef.getDescription());
                
                return partDef;
        }
        
        /**
         * 
         * @return Map
         */
        private Category convertCategories(DefinitionType defType, 
                        Map<Long, Category> catMap) {
                
                List<CategoryType> jaxbCats = defType.getCategory();
                Iterator<CategoryType> it = jaxbCats.iterator();
                
                // Get root category
                CategoryType jaxbCat = it.next();
                if(jaxbCat == null) {
                        Utils.logger.info("Invalid file: " + this.srcFile);
                        return null;
                }
                
                Category root = this.convertCategoryType(jaxbCat, null, catMap);
                Utils.logger.info("catMap.get(10002)=" + catMap.get(new Long(10002)));
                
                return root;
        }
        
        /**
         * 
         * @param jaxbCat
         * @return Category
         */
        @SuppressWarnings("unchecked")
        private Category convertCategoryType(CategoryType jaxbCat, 
                        Category parentCat, Map<Long, Category> catMap) {
                
                Category cat = new Category(jaxbCat.getID());
                cat.setLabel(jaxbCat.getName());
                cat.setDescription(jaxbCat.getDescription());
                if(parentCat != null) {
                        cat.setParentCategory(parentCat);
                        
                        // Copy parent's category-slide definitions
                        ArrayList<CategorySlideDefinition> parentCSDef = 
                                (ArrayList<CategorySlideDefinition>) 
                                parentCat.getCategorySlideDefintions();
                        
                        if(parentCSDef != null) {
                                cat.setCategorySlideDefintions(
                                        (List<CategorySlideDefinition>) parentCSDef.clone());
                        }
                }
                
                // Category Slide Definition
                List<CategorySlideDefinitionType> jaxbDefs = 
                        jaxbCat.getCategorySlideDefinition();
                
                Iterator<CategorySlideDefinitionType> it = jaxbDefs.iterator();
                while(it.hasNext()) {
                        CategorySlideDefinitionType jaxbDef = it.next();
                        CategorySlideDefinition catSlideDef 
                        = this.convertCategorySlideDefinitionType(jaxbCat.getID(), jaxbDef);
                        
                        cat.addCategorySlideDefintion(catSlideDef);
                }
                
                // Children
                List<CategoryType> jaxbChildren = jaxbCat.getChildCategory();
                //Utils.logger.info("jaxbChildren.size: " + jaxbChildren.size());
                
                Iterator<CategoryType> itChildren = jaxbChildren.iterator();
                while(itChildren.hasNext()) {
                        CategoryType jaxbChildCat = itChildren.next();
                        Category childCat = this.convertCategoryType(jaxbChildCat, cat, 
                                        catMap);
                        cat.addChild(childCat);
                }
                //Utils.logger.info("Parent cat: " + cat);
                // DEBUG ONLY
                Utils.logger.info("####### Cat ID: " + cat.getID());
                if(cat.getCategorySlideDefintions() != null) {
                        for(CategorySlideDefinition csd : cat.getCategorySlideDefintions()){
                                Utils.logger.info("####### SlideDefintionID=" + 
                                                csd.getSlideDefintionID());
                        }
                }
                
                catMap.put(new Long(jaxbCat.getID()), cat);
                return cat;
        }
        
        /**
         * 
         * @param jaxbDef
         * @return
         */
        private CategorySlideDefinition convertCategorySlideDefinitionType(
                        long categoryID, CategorySlideDefinitionType jaxbDef) {
                
                CategorySlideDefinition catSlideDef = new CategorySlideDefinition(
                                jaxbDef.getSlideDefinitionID());
                
                catSlideDef.setDescription(jaxbDef.getDescription());
                
                EditorialImportanceType jaxbEdImp = jaxbDef.getEditorialImportance();
                EditorialImportance edImp = this.convertEditorialImportance(jaxbEdImp);
                catSlideDef.setEditorialImportance(edImp);
                
                return catSlideDef;
        }
        
        /**
         * 
         * @return Map
         */
        private Map<Long, Unit> convertUnits(DefinitionType defType) {
                
                Map<Long, Unit> allUnits = new HashMap<Long, Unit>();
                List<UnitType> jaxbUnits = defType.getUnit();
                Iterator<UnitType> it = jaxbUnits.iterator();
                
                while(it.hasNext()) {
                        UnitType jaxbUnit = it.next();
                        
                        Unit unit = new Unit(jaxbUnit.getID());
                        unit.setDescription(jaxbUnit.getDescription());
                        unit.setFullForm(jaxbUnit.getFullform());
                        unit.setShortForm(jaxbUnit.getShortform());
                        Utils.logger.info("unit=" + unit);
                        
                        allUnits.put(new Long(jaxbUnit.getID()), unit);
                }
                
                return allUnits;
        }
        
        /**
         * 
         * @return DefinitionType
         */
        private DefinitionType unmarshallSrcFile(String srcFile) throws Exception {
                
        JAXBContext jc = JAXBContext.newInstance("in.shop2020.metamodel.jaxb");
        
        // create an Unmarshaller
        Unmarshaller u = jc.createUnmarshaller();
        
        JAXBElement<?> element = (JAXBElement<?>)u.unmarshal(
                        new FileInputStream(srcFile));
        
        return (DefinitionType)element.getValue();
        }
        
        /**
         * 
         * @param jaxbEdImp
         * @return EditorialImportance
         */
        private EditorialImportance convertEditorialImportance(
                        EditorialImportanceType jaxbEdImp) {
                
                String strEdImp = jaxbEdImp.value();
                EditorialImportance edImp = null;
                
                if(strEdImp.equals("Mandatory"))
                        edImp = EditorialImportance.MANDATORY;
                else if(strEdImp.equals("Optional"))
                        edImp = EditorialImportance.OPTIONAL;
                else 
                        edImp = EditorialImportance.RECOMMENDED;
                
                return edImp;
        }
}