Subversion Repositories SmartDukaan

Rev

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

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

import in.shop2020.metamodel.core.Bullet;
import in.shop2020.metamodel.core.Entity;
import in.shop2020.metamodel.core.Feature;
import in.shop2020.metamodel.core.PrimitiveDataObject;
import in.shop2020.metamodel.core.Slide;
import in.shop2020.metamodel.definitions.Catalog;
import in.shop2020.metamodel.definitions.Category;
import in.shop2020.metamodel.definitions.DefinitionsContainer;
import in.shop2020.metamodel.definitions.EntityContainer;
import in.shop2020.metamodel.definitions.FeatureDefinition;
import in.shop2020.metamodel.definitions.SlideDefinition;
import in.shop2020.metamodel.util.ExpandedBullet;
import in.shop2020.metamodel.util.ExpandedCategoryFacetDefinition;
import in.shop2020.metamodel.util.ExpandedEntity;
import in.shop2020.metamodel.util.ExpandedFacetRuleDefinition;
import in.shop2020.metamodel.util.ExpandedFeature;
import in.shop2020.metamodel.util.ExpandedSlide;

import java.util.ArrayList;
import java.util.List;

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

/**
 * Command line utility to convert IR Definitions into IR Data and IR Meta-data
 * 
 * Usage: IR [irmetadata|irdata] {Category ID}
 * 
 * @author naveen
 *
 */
public class IR {
        
        /**
         * 
         */
        private long categoryID;
        
        /**
         * Level - 4, 8, 12, 16
         */
        private String[] xmlIndentation = {"", "    ", "        ", "            ", 
                        "                "};
        
        /**
         * @param args
         * @throws Exception 
         */
        public static void main(String[] args) throws Exception {
                String[] commands = new String[] {"irmetadata", "irdata"};
                
                String usage = "Usage: IR ["+ StringUtils.join(commands, "|") +
                        "] {Category ID}\n";
                
                if(args.length < 1) {
                        System.out.println(usage);
                        System.exit(-1);
                }
                
                String inputCommand = args[0];
                
                if(!ArrayUtils.contains(commands, inputCommand)) {
                        System.out.println(usage);
                        System.exit(-1);
                }

                long categoryID = 0L;
                if(args.length > 1) {
                        try {
                                categoryID = Long.parseLong(args[1]);
                        }
                        catch (NumberFormatException nfe) {
                                System.out.println(usage);
                                System.exit(-1);
                        }
                }
                
                IR ir = new IR(categoryID);
                
                if (inputCommand.equals("irdata")) {
                        ir.exportIRData();
                        
                        return;
                }
                
                if (inputCommand.equals("irmetadata")) {
                        ir.exportIRMetaData();
                        
                        return;
                }
                
        }
        
        /**
         * 
         * @param categoryID
         */
        public IR(long categoryID) {
                this.categoryID = categoryID;
        }
        
        /**
         * 
         * @throws Exception
         */
        public void exportIRMetaData() throws Exception {
                /*
                DefinitionsContainer defs = 
                        Catalog.getInstance().getDefinitionsContainer();
                
                EntityContainer ents = 
                        Catalog.getInstance().getEntityContainer();
                */
                
                // <IRMetaData>
                List<String> entityXMLSnippets = new ArrayList<String>();
                entityXMLSnippets.add("<IRMetaData>");
                
                // Hard coded Brand facet
                // REVISIT - May be moving it into Python is better idea
                //String brandIRMetaData = this.getBrandIRMetaData();
                //entityXMLSnippets.add(brandIRMetaData);
                
                // Iterate over all facet definitions
                // TODO
                
                // Iterate over all feature definitions
                // TODO
                
                // </IRMetaData>
                entityXMLSnippets.add("</IRMetaData>");
                
                String irMetaDataXML = StringUtils.join(entityXMLSnippets, "\n");
                Utils.info(irMetaDataXML);
                
                // Write it to file
                String irMetaDataFilename = Utils.EXPORT_IR_PATH + "irmetadata.xml";
                DBUtils.store(irMetaDataXML, irMetaDataFilename);
        }
        
        /**
         * 
         * @return
         * @throws Exception 
         */
        private String getBrandIRMetaData() throws Exception {
                EntityContainer ents = 
                        Catalog.getInstance().getEntityContainer();
                
                List<String> brandXMLSnippets = new ArrayList<String>();
                
                // <Facet>
                brandXMLSnippets.add("\t<Facet>");
                
                List<Bullet> brandBullets =  
                        ents.getLearnedBullets(Utils.BRAND_FEATURE_DEFINITION_ID);
                
                brandXMLSnippets.add("\t\t<FacetDefinitionID>" + 
                                Utils.BRAND_FACET_DEFINITION_ID + "</FacetDefinitionID>");

                brandXMLSnippets.add("\t\t<Label>Brand</Label>");
                brandXMLSnippets.add("\t\t<IsMultivalue>false</IsMultivalue>");
                brandXMLSnippets.add("\t\t<HierarchyType>Flat</HierarchyType>");
                brandXMLSnippets.add("\t\t<NullBehavior>Reject</NullBehavior>");
                brandXMLSnippets.add("\t\t<Datatype>string</Datatype>");
                
                brandXMLSnippets.add("\t\t<FacetValues>");
                for(Bullet bullet : brandBullets) {
                        PrimitiveDataObject pDO = 
                                (PrimitiveDataObject)bullet.getDataObject();

                        brandXMLSnippets.add("\t\t\t<FacetValue>");
                        brandXMLSnippets.add("\t\t\t\t<Value>" + pDO.getValue() + 
                                        "</Value>");
                        
                        brandXMLSnippets.add("\t\t\t</FacetValue>");
                }
                
                brandXMLSnippets.add("\t\t</FacetValues>");
                
                // </Facet>
                brandXMLSnippets.add("\t</Facet>");
                
                String brandIRMetaDataXML = StringUtils.join(brandXMLSnippets, "\n");
                Utils.info(brandIRMetaDataXML);
                
                return brandIRMetaDataXML;
        }

        
        /**
         * @throws Exception 
         * 
         */
        public void exportIRData() throws Exception {
                DefinitionsContainer defs = 
                        Catalog.getInstance().getDefinitionsContainer();
                
                EntityContainer ents = 
                        Catalog.getInstance().getEntityContainer();
                
                // <IRData>
                List<String> entityXMLSnippets = new ArrayList<String>();
                entityXMLSnippets.add("<IRData>");
                
                List<Category> categories = null;
                if(this.categoryID != 0L) {
                        categories = new ArrayList<Category>();
                        categories.add(defs.getCategory(this.categoryID));
                }
                else {
                        
                        // Get all categories
                        categories = defs.getChildrenCategories(10001);
                }
                
                for(Category cat : categories) {
                        long catID = cat.getID();
                        
                        // Get all facets for the category
                        ExpandedCategoryFacetDefinition expCategoryFacetDef = 
                                defs.getExpandedCategoryFacetDefinition(catID);
                        
                        List<ExpandedFacetRuleDefinition> expFacetRuleDefs = 
                                expCategoryFacetDef.getExpandedFacetRuleDefinitions();
                        
                        // Get all entities for the category
                        List<Entity> entities = ents.getEntities(catID);
                        
                        if(entities == null) {
                                continue;
                        }

                        // For each entity 
                        for(Entity entity : entities) {
                                ExpandedEntity expEntity = 
                                        ents.getExpandedEntity(entity.getID());
                                
                                List<String> facetXMLSnippets = new ArrayList<String>();
                                
                                // Collect FACETs
                                
                                List<Long> facetFeatureIDs = new ArrayList<Long>();
                                
                                // For each facet execute Rule
                                for(ExpandedFacetRuleDefinition expFacetRuleDef : 
                                                expFacetRuleDefs) {
                                        String facetXMLSnip = 
                                                this.processFacet(expEntity, expFacetRuleDef);
                                        
                                        if(!facetXMLSnip.isEmpty()) {
                                                facetXMLSnippets.add(facetXMLSnip);
                                                Utils.info("facetXMLSnip=" + facetXMLSnip);
                                        }
                                        
                                        // Collect features already covered as Facet
                                        if(expFacetRuleDef.getFeatureDefinition() != null) {
                                                facetFeatureIDs.add(
                                                                new Long(expFacetRuleDef.getFeatureDefinitionID()));
                                        }
                                }
                                
                                String facetXMLSnippetsStr = 
                                        StringUtils.join(facetXMLSnippets, "\n");
                                        
                                Utils.info("facetXMLSnippets=" + facetXMLSnippetsStr);
                                
                                // Collect PROPERTIES
                                String propertiesXMLSnippetsStr = 
                                        this.getPropertiesXMLSnippet(expEntity, facetFeatureIDs, 2);
                                
                                Utils.info(propertiesXMLSnippetsStr);
                                
                                String entityXMLSnip = this.getEntityXMLSnippet(expEntity, 
                                                facetXMLSnippetsStr, propertiesXMLSnippetsStr, 1);
                                
                                Utils.info(entityXMLSnip);
                                
                                entityXMLSnippets.add(entityXMLSnip);
                        }
                }
                
                // </IRData>
                entityXMLSnippets.add("</IRData>");
                
                String irDataXML = StringUtils.join(entityXMLSnippets, "\n");
                Utils.info(irDataXML);
                
                // Write it to file
                String irDataFilename = Utils.EXPORT_IR_PATH + "irdata.xml";
                DBUtils.store(irDataXML, irDataFilename);
        }
        
        /**
         * 
         * @param expEntity
         * @param expFacetDef
         * @return
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        private String processFacet(ExpandedEntity expEntity, 
                        ExpandedFacetRuleDefinition expFacetRuleDef) throws Exception {
                
                Utils.info("expFacetRuleDef=" + expFacetRuleDef);
                
                EntityContainer ents = 
                        Catalog.getInstance().getEntityContainer();
                
                IRDataJythonWrapper jw = new IRDataJythonWrapper();
                
                jw.setExpandedEntity(expEntity);
                jw.setExpandedFacetDefinition(expFacetRuleDef);
                
                // Set FeatureDefinition
                FeatureDefinition featureDef = 
                        expFacetRuleDef.getFeatureDefinition();
                
                if(featureDef != null) {
                        jw.setFeatureDefinition(featureDef);
                        
                        // Set Feature
                        Utils.info("featureDef.getID()=" + featureDef.getID());
                        
                        
                        Feature feature = 
                                ents.getFeature(expEntity.getID(), featureDef.getID());
                        
                        // Can happen with un-referred features like Brand
                        if(feature != null) {
                                ExpandedFeature expFeature = new ExpandedFeature(feature);
                                
                                jw.setExpandedFeature(expFeature);
                        }
                }
                
                // Set SlideDefinition
                SlideDefinition slideDef = expFacetRuleDef.getSlideDefinition();
                if(slideDef != null) {
                        jw.setSlideDefinition(slideDef);
                        
                        // Set Slide
                        Utils.info("slideDef.getID()=" + slideDef.getID());
                        
                        Slide slide = ents.getSlide(expEntity.getID(), slideDef.getID());
                        ExpandedSlide expSlide = new ExpandedSlide(slide);
                        
                        jw.setExpandedSlide(expSlide);
                }
                
                // Execute Python script
                jw.execIRDataRule();
                
                // Parse returned Python list
                List<Object> values = (List<Object>)jw.getValues();
                Utils.info("values=" + values);
                
                String facetXMLSnip = "";
                if(values != null) {
                        
                        // Get IR Data XML snippet for this entity and facet
                        facetXMLSnip = this.getFacetXMLSnippet(expFacetRuleDef, values, 2);
                }
                Utils.info(facetXMLSnip);
                
                return facetXMLSnip;
        }

        /**
         * 
         * @param expEntity
         * @param facetFeatureIDs
         * @param indent
         * @return
         */
        private String getPropertiesXMLSnippet(ExpandedEntity expEntity, 
                        List<Long> facetFeatureIDs, int indent) {
                
                List<String> xmlSnippet = new ArrayList<String>();
                
                // Collect all free-form content here
                List<String> ffc = new ArrayList<String>();
                
                // Features
                List<ExpandedSlide> expSlides = expEntity.getExpandedSlides();
                
                for(ExpandedSlide expSlide : expSlides) {
                        List<ExpandedFeature> expFeatures = expSlide.getExpandedFeatures();
                        
                        if(expSlide.getFreeformContent() != null) {
                                ffc.add(expSlide.getFreeformContent().getContent());
                        }
                        
                        if(expFeatures == null) {
                                continue;
                        }
                        
                        for(ExpandedFeature expFeature : expFeatures) {
                                Long featureDefID = 
                                        new Long(expFeature.getFeatureDefinitionID());
                                
                                // FFC at feature level
                                if(expFeature.getFreeformContent() != null) {
                                        ffc.add(expFeature.getFreeformContent().getContent());
                                }
                                
                                // Exclude those who are already covered as facets
                                if(facetFeatureIDs.contains(featureDefID)) {
                                        continue;
                                }
                
                                List<ExpandedBullet> expBullets = 
                                        expFeature.getExpandedBullets();
                                
                                if(expBullets == null) {
                                        continue;
                                }
                                
                                //<Property Label="">
                                xmlSnippet.add(this.xmlIndentation[indent] + 
                                                "<Property Label=\"" + StringEscapeUtils.escapeXml(
                                                                expFeature.getFeatureDefinition().getLabel()) + 
                                                "\">");

                                //<Value></Value>
                                for(ExpandedBullet bullet : expBullets) {
                                        
                                        // FFC at bullet level
                                        if(bullet.getFreeformContent() != null) {
                                                ffc.add(bullet.getFreeformContent().getContent());
                                        }
                                        
                                        xmlSnippet.add(this.xmlIndentation[indent + 1] + "<Value>" + 
                                                        StringEscapeUtils.escapeXml(bullet.getValue()) + 
                                                        "</Value>");
                                }
                                
                                //</Property>
                                xmlSnippet.add(this.xmlIndentation[indent] + "</Property>");
                        }
                }
                
                // FFC as Label="Free-form Content"
                if(!ffc.isEmpty()) {
                        xmlSnippet.add(this.xmlIndentation[indent] + 
                                        "<Property Label=\"Free-form Content\">");
                        
                        for(String f : ffc) {
                                if(f != null) {
                                        f = StringEscapeUtils.escapeXml(f);
                                        
                                        xmlSnippet.add(this.xmlIndentation[indent + 1] + "<Value>" + 
                                                f + "</Value>");
                                }
                        }
                        
                        xmlSnippet.add(this.xmlIndentation[indent] + "</Property>");
                }
                
                // Children slides
                // TODO
                
                return StringUtils.join(xmlSnippet, "\n");
        }
        
        /**
         * 
         * @param expEntity
         * @param facetXMLSnippets
         * @param indent
         * @return
         */
        private String getEntityXMLSnippet(ExpandedEntity expEntity, 
                        String facetXMLSnippets, String propertiesXMLSnippets, int indent) {

                //<Entity ID="40001">
                List<String> xmlSnippet = new ArrayList<String>();
                
                String entityID = new Long(expEntity.getID()).toString();
                xmlSnippet.add(this.xmlIndentation[indent] + "<Entity ID=\""+ entityID + 
                                "\">");

                //<Category>Business Phones</Category>
                String category = expEntity.getCategory().getLabel();
                xmlSnippet.add(this.xmlIndentation[indent + 1] + "<Category>" + 
                                StringEscapeUtils.escapeXml(category) + "</Category>");

                //<Title>Nokia E71</Title>
                String title = StringEscapeUtils.escapeXml(expEntity.getBrand()) + " " +
                StringEscapeUtils.escapeXml(expEntity.getModelName()) + 
                        ((expEntity.getModelNumber() != null) ? 
                                        (" " + 
                                                StringEscapeUtils.escapeXml(expEntity.getModelNumber()))
                                        : "");

                xmlSnippet.add(this.xmlIndentation[indent + 1] + 
                                "<Title>" + StringEscapeUtils.escapeXml(title) + "</Title>");
                
                xmlSnippet.add(facetXMLSnippets);

                xmlSnippet.add(propertiesXMLSnippets);
                
                //</Entity>
                xmlSnippet.add(this.xmlIndentation[indent] + "</Entity>");
                
                return StringUtils.join(xmlSnippet, "\n");
        }
        
        /**
         * 
         * @param expFacetDef
         * @param values
         * @param indent
         * @return String XML Snippet
         */
        private String getFacetXMLSnippet(
                        ExpandedFacetRuleDefinition expFacetRuleDef, 
                        List<Object> values, int indent) {
                
                // <Facet Label="Form Factor">
                List<String> xmlSnippet = new ArrayList<String>();
                String target = expFacetRuleDef.getFacetDefinition().getTarget();
                
                xmlSnippet.add(this.xmlIndentation[indent] + "<Facet Label=\"" + 
                                target + "\">");
                
                //<Value>Candybar</Value>
                for(Object value : values) {
                        xmlSnippet.add(this.xmlIndentation[indent + 1] + "<Value>" + 
                                        value.toString() + "</Value>");
                }
                
                //</Facet>
                xmlSnippet.add(this.xmlIndentation[indent] + "</Facet>");
                
                return StringUtils.join(xmlSnippet, "\n");
        }
}