Subversion Repositories SmartDukaan

Rev

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

package in.shop2020.creation.controllers;

import in.shop2020.content.security.User;
import in.shop2020.content.security.UserManager;
import in.shop2020.metamodel.util.CreationUtils;
import in.shop2020.metamodel.core.Bullet;
import in.shop2020.metamodel.core.CompositeDataObject;
import in.shop2020.metamodel.core.Entity;
import in.shop2020.metamodel.core.EntityState;
import in.shop2020.metamodel.core.EnumDataObject;
import in.shop2020.metamodel.core.Feature;
import in.shop2020.metamodel.core.FreeformContent;
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.CompositeDefinition;
import in.shop2020.metamodel.definitions.CompositePartDefinition;
import in.shop2020.metamodel.definitions.DefinitionsContainer;
import in.shop2020.metamodel.definitions.EditorialImportance;
import in.shop2020.metamodel.definitions.EntityContainer;
import in.shop2020.metamodel.definitions.FeatureDefinition;
import in.shop2020.metamodel.definitions.SlideDefinition;
import in.shop2020.metamodel.definitions.SlideFeatureDefinition;
import in.shop2020.metamodel.util.ExpandedBullet;
import in.shop2020.metamodel.util.ExpandedBulletDefinition;
import in.shop2020.metamodel.util.ExpandedEntity;
import in.shop2020.metamodel.util.ExpandedFeature;
import in.shop2020.metamodel.util.ExpandedFeatureDefinition;
import in.shop2020.metamodel.util.ExpandedSlide;
import in.shop2020.metamodel.util.ExpandedSlideDefinition;
import in.shop2020.metamodel.util.SequenceGenerator;
import in.shop2020.model.v1.catalog.Item;
import in.shop2020.model.v1.catalog.status;
import in.shop2020.thrift.clients.CatalogServiceClient;
import in.shop2020.util.Utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import org.apache.commons.lang.StringUtils;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import org.apache.struts2.rest.DefaultHttpHeaders;
import org.apache.struts2.rest.HttpHeaders;


@InterceptorRefs({
    @InterceptorRef("myDefault"),
    @InterceptorRef("login")
})

@Results({
    @Result(name="success", type="redirectAction", 
                params = {"actionName" , "entity"}),
    @Result(name="redirect", location="${url}", type="redirect")
})

public class EntityController extends BaseController {
        
        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        /**
         * 
         */
        private static Log log = LogFactory.getLog(EntityController.class);
        
        /**
         * 
         */
        private String id;
        
        private ExpandedEntity expEntity;
        
        private Entity entity = null;
        
        private Collection<Entity> entities;

        private Map<Long, EntityState> entitiesState;
        
        private EntityContainer ents = Catalog.getInstance().getEntityContainer();
        
        private DefinitionsContainer defs = Catalog.getInstance().getDefinitionsContainer();
        
        private long firstSlideDefID;
        
        private ExpandedSlideDefinition expSlideDef;

        private ExpandedSlide expSlide;
        
        private String redirectURL;
        
        private Exception exception;
        
        private String errorString;
        
        private long newCurrentSlideDefinitionID;
        
        private long newNextSlideDefinitionID;
        
        private long newPrevSlideDefinitionID;

        private Map<Long, List<Long>> catSlides;
        
        private Map<Long, List<Entity>> catEntities;
        
                // GET /entity/1
    public String show() {
        log.info("EntityController.show");
        
        try {
                long entityID = Long.parseLong(this.getId());
                log.info("entityID:" + entityID);
                
                if(!UserManager.getUserManager().canView(getUsername(), entityID)){
                        return "fatel";
                }
                
                        this.expEntity = this.getExpandedEntity(entityID);
                        
                        return "show";
                } catch (Exception e) {
                        log.error(CreationUtils.getStackTrace(e));
                        this.setErrorString(CreationUtils.getStackTrace(e));
                        return "fatal";
                }
    }
        
    // GET /entity
    public HttpHeaders index() {
        log.info("EntityController.index");
        createEntitiesForItemsInProcess();
        try {
                        this.entities = CreationUtils.getEntities().values();
                        this.entitiesState = CreationUtils.getEntitiesState();
                        
                } catch (Exception e) {
                        log.error(CreationUtils.getStackTrace(e));
                        this.setErrorString(CreationUtils.getStackTrace(e));
                        return new DefaultHttpHeaders("fatal");
                }
        
        return new DefaultHttpHeaders("index").disableCaching();
    }

    // GET /entity
    public String create() {
        log.info("EntityController.create");
        
        if(!UserManager.getUserManager().canCreate(getUsername())){
                        return "success";
                }
        
                SequenceGenerator sg;
                try {
                        sg = SequenceGenerator.getInstance();
                        long entityID = sg.getNextSequence(SequenceGenerator.ENTITY);

                        String categoryID = this.reqparams.get("category")[0];
                        Entity entity = new Entity(entityID, Long.parseLong(categoryID));

                        entity.setBrand(this.reqparams.get("brand")[0]);
                        entity.setModelName(this.reqparams.get("modelname")[0]);
                        entity.setModelNumber(this.reqparams.get("modelnumber")[0]);
                        
                        EntityState entityState = new EntityState(entityID, getUsername());
                        
                        CreationUtils.createEntity(entity, entityState);
                        
                this.setId(new Long(entityID).toString());
                } catch (Exception e) {
                        log.error(CreationUtils.getStackTrace(e));
                        this.setErrorString(CreationUtils.getStackTrace(e));
                        return "fatal";
                }
                
                this.redirectURL = "entity/" + this.getId() + "/edit";
        
                return "redirect";
    }
    
    // GET /entity/1/edit
    public String edit() {
        log.info("EntityController.edit");
        
        long entityID = Long.parseLong(this.getId());
        log.info("entityID:" + entityID);
        if(!UserManager.getUserManager().canEdit(getUsername(), entityID)){
                addActionError("You can not edit as this entity is not assigned to you");
                        return "success";
                }
        
        try {
                        this.expEntity = this.getExpandedEntity(entityID);
                        //log.info("this.expEntity:" + this.expEntity);

                        String[] inputSlideDefIDs = this.reqparams.get("slideDefID");
                        long inputSlideDefID = 0L;
                        if(inputSlideDefIDs != null && inputSlideDefIDs.length > 0) {
                                try {
                                        inputSlideDefID = Long.parseLong(inputSlideDefIDs[0]);
                                } catch (NumberFormatException nfe) {}
                        }
                        long categoryID = CreationUtils.getEntity(entityID).getCategoryID();
                        
                        log.info("Entity ID:" + entityID + "   CategoryID " + categoryID );
                        
                        //Changed to make correct order of borrowed slides 
                        //List<Long> slideDefIDs = CreationUtils.getSlideSequence(entityID, categoryID);
                        
                        List<Long> slideDefIDs = expEntity.getSlideSequence();
                        log.info("slideDefIDs:" + slideDefIDs);
                        if(slideDefIDs == null){
                                slideDefIDs = Catalog.getInstance().getDefinitionsContainer().getCategorySlideSequence(categoryID);
                        }
                        
                        log.info("slideDefIDs:" + slideDefIDs);
                        
                        // Edit the entity from a specific slide
                        if(slideDefIDs != null && inputSlideDefID != 0L) {
                                
                                // -2 : Not set
                                // -1 : Not found
                                int currentIndex = slideDefIDs.indexOf(
                                                new Long(inputSlideDefID));
                                
                                int nextIndex = -2;
                                if(currentIndex+1 != slideDefIDs.size()) {
                                        nextIndex = currentIndex + 1;
                                }
;
                                int prevIndex = -2;
                                if(currentIndex != 0) {
                                        prevIndex = currentIndex - 1;
                                }

                                this.setNewCurrentSlideDefinitionID(
                                                slideDefIDs.get(currentIndex).longValue());
                                if(nextIndex != -2) {
                                        log.info("p7" + "---slidedefids:"+slideDefIDs+ "---nextIndex:"+nextIndex);
                                        log.info("p7" + "---currentslide:"+currentIndex+ "---prevslide:"+prevIndex);
                                        this.setNewNextSlideDefinitionID(
                                                        slideDefIDs.get(nextIndex).longValue());
                                }
                                
                                if(prevIndex != -2) {
                                        this.setNewPrevSlideDefinitionID(
                                                        slideDefIDs.get(prevIndex).longValue());
                                }

                                // Current Slide Definition
                                this.expSlideDef = defs.getExpandedSlideDefinition(
                                                inputSlideDefID);
                                // Current Slide Instance
                                this.expSlide = this.expEntity.getExpandedSlide(
                                                inputSlideDefID);
                                return "editSlide";
                        }
                } catch (Exception e) {
                        log.error(CreationUtils.getStackTrace(e));
                        this.setErrorString(CreationUtils.getStackTrace(e));
                        return "fatal";
                }
                
        return "edit";
    }
    
    /**
     * 
     * @return
     */
    public String getUrl() {
        return this.redirectURL;
    }
    
    /**
     * 
     * @return
     */
    // GET /entity/new
    public String editNew() {
        log.info("EntityController.editNew");

        if(!UserManager.getUserManager().canCreate(getUsername())){
                addActionError("You do not have rights to create an entity.");
                        return "success";
                }
        
        return "editNew";
    }
    
    /**
     * 
     * @return
     */
    // GET /entity/1
    public String update() {
        log.info("EntityController.update");

        long entityID = Long.parseLong(this.getId());
        log.info("entityID:" + entityID);
        
        if(!UserManager.getUserManager().canEdit(getUsername(), entityID)){
                        return "success";
                }
        
        try {
                        this.expEntity = this.getExpandedEntity(entityID);
                        //log.info("this.expEntity:" + this.expEntity);
                        log.info("p0");

                        // Save and Go to slides selection page
                        if (this.reqparams.containsKey("slides")) {
                                log.info("p1");
                                
                                Entity entity = this.expEntity.getEntity();
                                log.info("p2");
                                
                                String categoryID = this.reqparams.get("category")[0];
                                
                                entity.setCategoryID(Long.parseLong(categoryID));
                                entity.setBrand(this.reqparams.get("brand")[0]);
                                entity.setModelName(this.reqparams.get("modelname")[0]);
                                entity.setModelNumber(this.reqparams.get("modelnumber")[0]);
                                
                                log.info("p3");
                                CreationUtils.updateEntity(entity);
                                //this.updateEntity(entity);
                                
                                this.redirectURL = "/slides/" + this.getId() + "/edit";
                                return "redirect";
                        }
                        
                        long currentSlideDefID = 0L;
                        long nextSlideDefID = 0L;
                        long prevSlideDefID = 0L;
                        long gotoSlideDefID = 0L;
                        
                        String[] currentslideDefIDStrings = 
                                this.reqparams.get("currentslideDefID");
                        
                        String[] nextslideDefIDStrings = 
                                this.reqparams.get("nextslideDefID");
                        
                        String[] prevslideDefIDStrings = 
                                this.reqparams.get("prevslideDefID");
                        
                        String[] gotoslideDefIDStrings = 
                                this.reqparams.get("gotoslideDefID");
                        log.info("gotoslideDefIDStrings:" + 
                                        Arrays.toString(gotoslideDefIDStrings));
                        
                        // Current Slide ID
                        if(currentslideDefIDStrings != null && 
                                        currentslideDefIDStrings.length > 0) {
                                try {
                                        currentSlideDefID = Long.parseLong(
                                                        currentslideDefIDStrings[0]);
                                }
                                catch (NumberFormatException nfe) {}
                        }
                        
                        // Next Slide ID
                        if(nextslideDefIDStrings != null && 
                                        nextslideDefIDStrings.length > 0) {
                                try {
                                        nextSlideDefID = Long.parseLong(nextslideDefIDStrings[0]);
                                }
                                catch (NumberFormatException nfe) {}
                        }
                        
                        // Prev Slide ID
                        if(prevslideDefIDStrings != null && 
                                        prevslideDefIDStrings.length > 0) {
                                try {
                                        prevSlideDefID = Long.parseLong(prevslideDefIDStrings[0]);
                                }
                                catch (NumberFormatException nfe) {}
                        }
                        
                        // Go to Slide ID
                        if(gotoslideDefIDStrings != null && 
                                        gotoslideDefIDStrings.length > 0) {
                                try {
                                        gotoSlideDefID = Long.parseLong(gotoslideDefIDStrings[0]);
                                }
                                catch (NumberFormatException nfe) {}
                        }
                        
                        log.info("currentSlideDefID:" + currentSlideDefID);
                        log.info("nextSlideDefID:" + nextSlideDefID);
                        log.info("prevSlideDefID:" + prevSlideDefID);
                        log.info("gotoSlideDefID:" + gotoSlideDefID);
                        
                        
                        // Save on basic info page
                        if (this.reqparams.containsKey("save") && currentSlideDefID == 0L) {
                                log.info("Save");
                                
                                Entity entity = this.expEntity.getEntity();

                                String categoryID = this.reqparams.get("category")[0];
                                
                                entity.setCategoryID(Long.parseLong(categoryID));
                                entity.setBrand(this.reqparams.get("brand")[0]);
                                entity.setModelName(this.reqparams.get("modelname")[0]);
                                entity.setModelNumber(this.reqparams.get("modelnumber")[0]);
                                
                                CreationUtils.updateEntity(entity);
                                
                                return "success";
                        }
                        
                        List<Long> slideIDs = this.getSlideSequence(entityID);
                        log.info("slideIDs:"+slideIDs);
                        if(slideIDs == null) {
                                this.setErrorString("Slides need to be picked first!");
                                return "fatal";
                        }
                        
                        log.info("p4");
                        
                        boolean skip = false;
                        if(this.reqparams.containsKey("skipprev") || 
                                        this.reqparams.containsKey("skipnext")) {
                                skip = true;
                        }
                        
                        boolean next = this.reqparams.containsKey("skipnext") || 
                                this.reqparams.containsKey("next");

                        boolean prev = this.reqparams.containsKey("skipprev") || 
                                this.reqparams.containsKey("prev");

                        boolean go = this.reqparams.containsKey("goto");
                                
                        // Save or Next or Prev or Go - When editing a slide
                        int currentSlideIndex = 0;
                        currentSlideIndex = slideIDs.indexOf(new Long(currentSlideDefID));
                        log.info("currentSlideIndex:" + currentSlideIndex);

                        log.info("p5");
                        if(!skip && currentSlideDefID != 0L) {
                                Entity entity = this.expEntity.getEntity();
                                
                                log.info("p6");
                                // Create new instance and override existing
                                Slide currentSlide = this.createSlide(currentSlideDefID);
                                
                                entity.addSlide(currentSlide);
                                long categoryID = this.getEntity().getCategoryID();
                                //List<Long> orderedSlideIDs = CreationUtils.getSlideSequence(entityID, categoryID);
                                
                                List<Long> orderedSlideIDs = entity.getSlideSequence();
                                
                                if(orderedSlideIDs != null) {
                                        //entity.reorderSlides(orderedSlideIDs);
                                }
                                log.info("p7");
                                // Store
                                CreationUtils.updateEntity(entity);
                                //log.info("entity:" + entity);
                        }
                        
                        // Skip will delete current slide from entity
                        else if(skip && currentSlideDefID != 0L) {
                                Entity entity = this.expEntity.getEntity();
                                entity.removeSlide(currentSlideDefID);
                                long categoryID = this.getEntity().getCategoryID();
                                //List<Long> orderedSlideIDs = CreationUtils.getSlideSequence(entityID, categoryID);
                                
                                log.info("p8");
                                
                                List<Long> orderedSlideIDs = entity.getSlideSequence();
                                if(orderedSlideIDs != null) {
                                        //entity.reorderSlides(orderedSlideIDs);
                                }
                                
                                // Store
                                CreationUtils.updateEntity(entity);
                                //log.info("entity:" + entity);
                                
                                log.info("p9");
                        }
                        
                        boolean showAnotherSlide = false;
                        
                        // -2 : Not set
                        // -1 : Not found
                        int newCurrentIndex = -2;  
                        int newNextIndex = -2;
                        int newPrevIndex = -2;
                                
                        // Next
                        if(next && nextSlideDefID != 0L) {
                                log.info("Next");
                                log.info("p10");
                                // Decide on next slide ID
                                int nextSlideIndex = slideIDs.indexOf(new Long(nextSlideDefID));
                                log.info("nextSlideIndex:"+nextSlideIndex);
                                
                                // New Current
                                if (nextSlideIndex == -1) {
                                        this.setErrorString("Invalid Next slide ID " + 
                                                        nextSlideDefID);
                                        return "fatal";
                                }
                                
                                newCurrentIndex = nextSlideIndex;
                                
                                // New Next
                                if (newCurrentIndex != slideIDs.size()-1) {
                                        newNextIndex = newCurrentIndex + 1;
                                }
                                
                                // New Prev.
                                if(currentSlideDefID != 0L) {
                                        newPrevIndex = currentSlideIndex;
                                }
                                
                                showAnotherSlide = true;
                        }
                        
                        // Prev
                        if(prev && prevSlideDefID != 0L) {
                                log.info("Prev");
                                log.info("p11");
                                // Decide on prev slide ID
                                int prevSlideIndex = slideIDs.indexOf(new Long(prevSlideDefID));
                                log.info("prevSlideIndex:" + prevSlideIndex);
                                
                                if (prevSlideIndex == -1) {
                                        this.setErrorString("Invalid Prev slide ID " + 
                                                        prevSlideDefID);
                                        return "fatal";
                                }
                                
                                // New Next
                                if(currentSlideDefID != 0L) {
                                        newNextIndex = currentSlideIndex;
                                }

                                // New Current
                                newCurrentIndex = prevSlideIndex;
                                
                                // New Prev.
                                if (newCurrentIndex != 0) {
                                        newPrevIndex = newCurrentIndex - 1;
                                }
                                
                                showAnotherSlide = true;
                        }
                        
                        // Go to
                        if(go && gotoSlideDefID != 0) {
                                log.info("Goto");
                                log.info("p12");
                                int gotoSlideIndex = slideIDs.indexOf(new Long(gotoSlideDefID));
                                log.info("gotoSlideIndex:" + gotoSlideIndex);
                                
                                if (gotoSlideIndex == -1) {
                                        this.setErrorString("Invalid Go to slide ID " + 
                                                        gotoSlideDefID);
                                        return "fatal";
                                }
                                                                
                                // New Next
                                if(gotoSlideIndex != slideIDs.size()-1) {
                                        newNextIndex = gotoSlideIndex + 1;
                                }

                                // New Current
                                newCurrentIndex = gotoSlideIndex;
                                
                                // New Prev.
                                if (gotoSlideIndex != 0) {
                                        newPrevIndex = gotoSlideIndex - 1;
                                }
                                
                                showAnotherSlide = true;
                        }
                        
                        if(showAnotherSlide) {
                                log.info("newCurrentIndex:" + newCurrentIndex);
                                log.info("newNextIndex:" + newNextIndex);
                                log.info("newPrevIndex:" + newPrevIndex);

                                log.info("p13");
                                
                                if(newCurrentIndex != -2) {
                                        this.setNewCurrentSlideDefinitionID(
                                                        slideIDs.get(newCurrentIndex).longValue());
                                }
                                
                                if(newNextIndex != -2) {
                                        this.setNewNextSlideDefinitionID(
                                                        slideIDs.get(newNextIndex).longValue());
                                }
                                
                                if(newPrevIndex != -2) {
                                        this.setNewPrevSlideDefinitionID(
                                                        slideIDs.get(newPrevIndex).longValue());
                                }

                                long newCurrentSlideDefID = 
                                        this.getNewCurrentSlideDefinitionID();
                                log.info("newCurrentSlideDefID:" + newCurrentSlideDefID);
                                
                                // Current Slide Definition
                                this.expSlideDef = defs.getExpandedSlideDefinition(
                                                newCurrentSlideDefID);
                                
                                // Current Slide Instance
                                this.expSlide = this.expEntity.getExpandedSlide(
                                                newCurrentSlideDefID);
                                
                                log.info("this.expSlide is null: " + (this.expSlide == null));
                                
                                return "editSlide";
                        }
                }
        catch (Exception e) {
                        log.error(CreationUtils.getStackTrace(e));
                        this.setErrorString(CreationUtils.getStackTrace(e));
                        return "fatal";
        }
        
        return "success";
    }
        
    /**
     * 
     * @param entityID
     * @return
     * @throws Exception 
     */
    public long getBorrowedCategoryID(long slideDefID) throws Exception {
        long entityID = Long.parseLong(this.getId());
        entity = CreationUtils.getEntity(entityID);
        Long entityCatID = new Long(entity.getCategoryID());
        
        Map<Long, List<Long>> catSlides = this.getRawSlideSequence(entityID);
        
        Long lSlideDefID = new Long(slideDefID);
        if(catSlides != null) {
                for(Long catID : catSlides.keySet()) {
                        List<Long> slideDefIDs = catSlides.get(catID);
                        if(slideDefIDs.contains(lSlideDefID) && 
                                        !catID.equals(entityCatID)) {
                                return catID.longValue();
                        }
                }
        }
        
        return 0L;
    }

        /**
     * 
     * @param entityID
     * @return
     * @throws Exception 
     */
    private List<Long> getSlideSequence(long entityID) throws Exception {
        //this.catSlides = this.getRawSlideSequence(entityID);
        //return CreationUtils.getSlideSequence(this.catSlides);
        return entity.getSlideSequence();
        }
    
    /**
     * 
     * @param entityID
     * @return
     * @throws Exception
     */
        private Map<Long, List<Long>> getRawSlideSequence(long entityID) 
                throws Exception {
                if(this.catSlides == null) {
                        this.catSlides = defs.getCategorySlideSequence();
                }
                
                return this.catSlides;
        }


        /**
     * 
     * @param slideDefID
     * @return
     * @throws Exception
     */
    private Slide createSlide(long slideDefID) throws Exception {
                Slide slide = new Slide(slideDefID);
                
                long borrowedCategoryID = this.getBorrowedCategoryID(slideDefID);
                log.info("borrowedCategoryID:" + borrowedCategoryID);
                
                if(borrowedCategoryID != 0L) {
                        slide.setBorrowedCategoryID(borrowedCategoryID);
                }
                
                // Slide free-form content
                FreeformContent slideFFC = this.getFreeformContent(
                                "slide_" + slideDefID);
                
                log.info("slideFFC:" + slideFFC);
                
                slide.setFreeformContent(slideFFC);
                //log.info("currentSlide:" + currentSlide);
                
                // Collect Feature bullets
                List<Feature> features = this.createFeatures(slide);
                log.info("features:" + features);
                
                slide.setFeatures(features);
                
                // Collect children slides
                SlideDefinition slideDef = this.defs.getSlideDefinition(slideDefID);

                List<Long> childrenSlideIDs = slideDef.getChildrenSlideDefinitionIDs();
                if(childrenSlideIDs != null) {
                        List<Slide> childrenSlides = new ArrayList<Slide>();
                        for (Long childSlideID : childrenSlideIDs) {
                                Slide childSlide = this.createSlide(childSlideID.longValue());
                                if(childSlide != null) {
                                        childrenSlides.add(childSlide);
                                }
                        }
                        
                        slide.setChildrenSlides(childrenSlides);
                }
                
                return slide;
    }

    /**
     * 
     * @param slide
     * @return
     * @throws Exception
     */
    private List<Feature> createFeatures(Slide slide) throws Exception {
                
                long slideDefID = slide.getSlideDefinitionID();
                SlideDefinition slideDef = defs.getSlideDefinition(slideDefID);
                
                List<SlideFeatureDefinition> slideFeatureDefs = 
                        slideDef.getSlideFeatureDefinitions();
                
                List<Feature> features = new ArrayList<Feature>();      
                for(SlideFeatureDefinition slideFeatureDef : slideFeatureDefs) {
                        long featureDefinitionID = slideFeatureDef.getFeatureDefintionID();
                        log.info("featureDefinitionID:" + featureDefinitionID);
                        
                        // Ignore skipped featured
                        String[] skipvalue = 
                                this.reqparams.get(featureDefinitionID + "_skip");
                        log.info("skipvalue:" + Arrays.toString(skipvalue));
                        
                        if(skipvalue != null && skipvalue.length > 0 && 
                                        skipvalue[0].equals("on")) {
                                continue;
                        }
                        
                        String featureDefIDString = 
                                new Long(featureDefinitionID).toString();
                        
                        Feature feature = new Feature(featureDefinitionID);

                        FeatureDefinition featureDef = defs.getFeatureDefinition(
                                        featureDefinitionID);
                        log.info("featureDef:" + featureDef);
                        
                        ExpandedFeatureDefinition expFeatureDef = 
                                new ExpandedFeatureDefinition(featureDef);
                        
                        ExpandedBulletDefinition expBulletDef = 
                                expFeatureDef.getExpandedBulletDefinition();
                        
                        boolean isBlank = false;
                        
                        // Check if feature has no bullets
                        // Composite
                        if(expBulletDef.isComposite()) {
                                CompositeDefinition compositeDef = (CompositeDefinition)
                                        expBulletDef.getDatatypeDefinition(); 
                                
                                List<CompositePartDefinition> compositeParts = 
                                        compositeDef.getCompositePartDefinitions();
                                
                                boolean allPartsBlank = true;
                                for(int j=0;j<compositeParts.size();j++) {
                                        String[] partValues = this.reqparams.get(
                                                        featureDefIDString + "_" + (j + 1));

                                        if(partValues != null && partValues.length > 0) {
                                                allPartsBlank = false;
                                        }
                                }
                                
                                isBlank = allPartsBlank;
                        }
                        
                        // Enumerated and Primitive
                        else {
                                String[] bulletValues = this.reqparams.get(featureDefIDString);
                                if(bulletValues == null || bulletValues.length == 0) {
                                        isBlank = true;
                                }
                        }

                        // Has no bullets
                        if(isBlank) {
                                
                                // Mandatory
                                // or optional/recommended but allows blanck and not skipped
                                if(slideFeatureDef.getEditorialImportance() == 
                                        EditorialImportance.MANDATORY || expFeatureDef.allowsBlank()) {
                                        // FFC
                                        FreeformContent featureFFC = 
                                                this.getFreeformContent(featureDefIDString);
                                        
                                        feature.setFreeformContent(featureFFC);
                                        
                                        features.add(feature);
                                }
                                
                                continue;
                        }
                        
                        // Bullets
                        List<Bullet> bullets = new ArrayList<Bullet>();
                        
                        // Collect unit
                        String[] unitIDs = this.reqparams.get(featureDefIDString + "_unit");
                        long unitID = 0L;
                        if(unitIDs != null && unitIDs.length > 0) {
                                unitID = Long.parseLong(unitIDs[0]);
                        }
                        
                        // Composite
                        if(expBulletDef.isComposite()) {
                                log.info("Composite");
                                
                                CompositeDataObject compositeDataObject = 
                                        new CompositeDataObject();
                                
                                CompositeDefinition compositeDef = 
                                        (CompositeDefinition)expBulletDef.getDatatypeDefinition(); 
                                
                                List<CompositePartDefinition> compositeParts = 
                                        compositeDef.getCompositePartDefinitions();
                                
                                for(int j=0;j<compositeParts.size();j++) {
                                        String[] partValues = this.reqparams.get(
                                                        featureDefIDString + "_" + (j + 1));
                                        
                                        if(partValues != null && partValues.length > 0) {
                                                compositeDataObject.addPrimitiveDataObject(
                                                        new PrimitiveDataObject(partValues[0]));
                                        }
                                }
                                
                                Bullet bullet = new Bullet(compositeDataObject);
                                
                                if(unitID != 0L) {
                                        bullet.setUnitID(unitID);
                                }
                                
                                bullets.add(bullet);
                        }
                        
                        // Enumerated
                        else if(expBulletDef.isEnumerated()) {
                                log.info("Enumerated");
                                
                                String[] bulletValues = this.reqparams.get(featureDefIDString);
                                log.info("bulletValues:" + Arrays.toString(bulletValues));

                                
                                for(int i=0;i<bulletValues.length;i++) {
                                        EnumDataObject enumDataObject = 
                                                new EnumDataObject(Long.parseLong(bulletValues[i]));
                                        
                                        Bullet bullet = new Bullet(enumDataObject);
                                        
                                        if(unitID != 0L) {
                                                bullet.setUnitID(unitID);
                                        }
                                        
                                        bullets.add(bullet);
                                }
                        }
                        
                        // Primitive
                        else {
                                log.info("Primitive");
                                
                                String[] bulletValues = this.reqparams.get(featureDefIDString);
                                log.info("bulletValues:" + Arrays.toString(bulletValues));
                                
                                for(int i=0;i<bulletValues.length;i++) {
                                        Bullet bullet = new Bullet(
                                                        new PrimitiveDataObject(bulletValues[i]));
                                        
                                        if(unitID != 0L) {
                                                bullet.setUnitID(unitID);
                                        }
                                        
                                        bullets.add(bullet);
                                }
                        }
                        
                        feature.setBullets(bullets);
                        
                        // FFC
                        FreeformContent featureFFC = 
                                this.getFreeformContent(featureDefIDString);
                        
                        feature.setFreeformContent(featureFFC);
                        
                        features.add(feature);
                }
                
                return features;
        }

    // DELETE /entity/1000001
    /**
     * 
     */
    public String destroy() {
        log.info("#### EntityController.destroy ####");
        
        long entityID = Long.parseLong(this.getId());
        log.info("entityID:" + entityID);
        
        if(!UserManager.getUserManager().canDelete(getUsername(), entityID)){
                addActionError("You do not have rights to delete an entity");
                return "success";
                }
        
                // Store
                try {
                CreationUtils.deleteEntity(entityID);
                } catch (Exception e) {
                        log.error(CreationUtils.getStackTrace(e));
                        this.setErrorString(CreationUtils.getStackTrace(e));
                        return "fatal";
                }
        addActionMessage("Entity deleted successfully");
        return "success";
    }
        /**
     * 
     * @param ID
     * @return
     */
    private FreeformContent getFreeformContent(String ID) {

                
                FreeformContent ffc = new FreeformContent();
                String[] ffts = this.reqparams.get(ID + "_fft");
                if(ffts != null) {
                        ffc.setFreeformTexts(Arrays.asList(ffts));
                }
                
        System.out.println("String is " + ID);
        
        StringTokenizer tokenizer = new StringTokenizer(ID,"_");
        if(tokenizer.nextToken().compareTo("slide") == 0  ){
                long slideId = Long.parseLong(tokenizer.nextToken());
                FreeformContent old_ffc = null;
                if(this.entity.getSlide(slideId) != null){
                        old_ffc = this.entity.getSlide(slideId).getFreeformContent();
                        if(old_ffc != null){
                                ffc.setMedias(old_ffc.getMedias());                     
                        }
                }
        }
                
                
//              String[] imgRefs = this.reqparams.get(ID + "_image_references");
//              if(imgRefs != null) {
//                      ffc.setMedia("image", Arrays.asList(imgRefs));
//              }
//              
//              String[] youtubeRefs = 
//                      this.reqparams.get(ID + "_youtube_references");
//              if(youtubeRefs != null) {
//                      ffc.setMedia("youtube", Arrays.asList(youtubeRefs));
//              }
                
                log.info("ffc:" + ffc);
                return ffc;
        }
    
    
    /**
     * 
     * @param slideDefinitionID
     * @return
     */
        public ExpandedSlide getChildSlide(long slideDefinitionID) {
                if(this.expSlide == null) {
                        return null;
                }
                
                return this.getChildSlide(this.expSlide, slideDefinitionID);
        }
        
        
    /**
     * 
     * @param expSlide
     * @param slideDefinitionID
     * @return
     */
        public ExpandedSlide getChildSlide(ExpandedSlide expSlide, 
                        long slideDefinitionID) {
                
                List<ExpandedSlide> childrenSlides = 
                        expSlide.getExpandedChildrenSlides();
                
                ExpandedSlide resultSlide = null;
                
                if(childrenSlides != null) {
                        for(ExpandedSlide childSlide : childrenSlides) {
                                if(childSlide.getSlideDefinitionID() == slideDefinitionID) {
                                        return childSlide;
                                }
                                
                                resultSlide = this.getChildSlide(childSlide, slideDefinitionID);
                                if(resultSlide == null) {
                                        continue;
                                }
                                else {
                                        break;
                                }
                        }
                }
                
                return resultSlide;
        }

        /**
         * @return the entities
         */
        public Collection<Entity> getEntities() {
                return entities;
        }

        /**
         * @return the entities
         */
        public Map<Long, List<Entity>> getEntitiesByCategory() {
                return catEntities;
        }

                /**
         * Inquires about items in the IN_PROCESS state with the Catalog service and
         * creates those entities which do not exist in the CMS already.
         * 
         * @return A List of entities fetched from the catalog.
         */
        private void createEntitiesForItemsInProcess(){
                try {
                        CatalogServiceClient csc = new CatalogServiceClient();
                        in.shop2020.model.v1.catalog.InventoryService.Client iclient = csc.getClient();
                        List<Item> items = iclient.getAllItemsByStatus(status.IN_PROCESS);
                        for(Item item: items){
                                long entityID = item.getCatalogItemId();
                                if(CreationUtils.getEntity(entityID) == null){
                                        log.info("#### Going to add the entity with id: ####" + entityID);
                                        Entity entity = new Entity(entityID, -1);
                                        entity.setBrand(item.getBrand());
                                        entity.setModelNumber(item.getModelNumber() + " (" + item.getProductGroup() + ")");
                                        entity.setModelName((item.getModelName()==null) ? "" : item.getModelName());
                                        EntityState entityState = new EntityState(entityID, UserManager.getUserManager().getAdminName());
                                        CreationUtils.createEntity(entity, entityState);
                                }else
                                        log.info("###Everything went all right and we got an entity");
                        }
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }
        
    /**
         * @return the entities
         */
        public ExpandedEntity getEntity() {
                return expEntity;
        }

    /**
         * @return the current slide to edit
         */
        public ExpandedSlideDefinition getExpandedSlideDefinition() {
                return expSlideDef;
        }

        /**
         * 
         * @param slideDefID
         * @return
         */
        public ExpandedSlideDefinition getExpandedSlideDefinition(long slideDefID) {
                try {
                        return defs.getExpandedSlideDefinition(slideDefID);
                } catch (Exception e) {
                        return null;
                }
        }
        
        /**
     * 
     * @param id
     */
    public void setId(String id) {
        this.id = id;
    }
    
    /**
     * 
     */
    public String getId() {
        return this.id;
    }

        /**
         * @return the firstSlideID
         */
        public long getFirstSlideDefID() {
                return firstSlideDefID;
        }

        public String getCategoriesTree()  throws Exception {
                Map<String, String> cats = new HashMap<String, String>();
                
                List<Category> children = defs.getChildrenCategories(Catalog.getInstance().getRootCategory().getID());
                for(Category child : children) {
                        cats.put(new Long(child.getID()).toString(), child.getLabel());
                }
                return "";
        }
        
        public Map<String, String> getCategories() throws Exception {
                Map<String, String> cats = new HashMap<String, String>();

                List<Category> children = defs.getChildrenCategories(Catalog.getInstance().getRootCategory().getID());
                for(Category child : children) {
                        cats.put(new Long(child.getID()).toString(), child.getLabel());
                }
                
                return cats;
        }

        public Map<String, String> getSubcategories() throws Exception {
                Map<String, String> cats = new HashMap<String, String>();

                List<Category> children = defs.getChildrenCategories(Catalog.getInstance().getRootCategory().getID());
                for(Category child : children) {
                        List<Category> grandChildren = defs.getChildrenCategories(child.getID());
                        for(Category grandchild : grandChildren) {
                                cats.put(new Long(grandchild.getID()).toString(), grandchild.getLabel());
                        }
                }
                
                return cats;
        }
        public String getCategoriesString() throws Exception {
                StringBuilder categoryString = new StringBuilder();
                
                categoryString.append("<label for=\"basecategory\">Category: </label>");
                categoryString.append("\n");
                categoryString.append("<select id=\"basecategory\"  name=\"basecategory\" >"); 
                categoryString.append("\n");
                List<Category> children = defs.getChildrenCategories(Catalog.getInstance().getRootCategory().getID());
                for(Category child : children) {
                        categoryString.append("<option value=\"" + new Long(child.getID()).toString() + "\">" + child.getLabel() + "</option>");
                        categoryString.append("\n");
                }
                categoryString.append("</select>");
                categoryString.append("\n");
                categoryString.append("<br/>");
                categoryString.append("\n");
                
                categoryString.append("<label for=\"category\">Sub Category: </label>");
                categoryString.append("\n");
                categoryString.append("<select id=\"category\" name=\"category\" >");
                categoryString.append("\n");
                for(Category child : children) {
                        List<Category> grandChildren = defs.getChildrenCategories(child.getID());
                        for(Category grandchild : grandChildren) {
                                categoryString.append("<option value=\"" + new Long(grandchild.getID()).toString() + "\" selected=\"$selected\" class = \""+ child.getID()  + "\">" + grandchild.getLabel() + "</option>");
                                categoryString.append("\n");
                        }
                }
                categoryString.append("</select>");
                categoryString.append("\n");
                categoryString.append("<br/>");
                
                return categoryString.toString();
                
        }


        /**
         * 
         * @return
         * @throws Exception
         */
        public String getBrandString() throws Exception {
                List<String> brands = this.getBrands();
                return "\"" + StringUtils.join(brands, "\", \"") + "\"";
        }

        /**
         * 
         * @return
         * @throws Exception
         */
        public List<String> getBrands() throws Exception {
                
                List<String> brands = new ArrayList<String>();
                
                List<ExpandedBullet> expBullets;

                expBullets = CreationUtils.getLearnedBullets(Utils.BRAND_FEATURE_DEFINITION_ID);
                if(expBullets!=null){
                        for(ExpandedBullet expBullet : expBullets) {
                                brands.add(expBullet.getValue());
                        }
                }
                return brands;
        }


        /**
         * @param exception the exception to set
         */
        public void setException(Exception exception) {
                this.exception = exception;
        }

        /**
         * @return the exception
         */
        public Exception getException() {
                return exception;
        }

        /**
         * @param errorString the exceptionString to set
         */
        public void setErrorString(String errorString) {
                this.errorString = errorString;
        }

        /**
         * @return the exceptionString
         */
        public String getErrorString() {
                return errorString;
        }

        /**
         * @param newCurrentSlideID the newCurrentSlideID to set
         */
        public void setNewCurrentSlideDefinitionID(
                        long newCurrentSlideDefinitionID) {
                this.newCurrentSlideDefinitionID = newCurrentSlideDefinitionID;
        }

        /**
         * @return the newCurrentSlideID
         */
        public long getNewCurrentSlideDefinitionID() {
                return newCurrentSlideDefinitionID;
        }

        
        /**
         * @param newNextSlideID the newNextSlideID to set
         */
        public void setNewNextSlideDefinitionID(long newNextSlideDefinitionID) {
                this.newNextSlideDefinitionID = newNextSlideDefinitionID;
        }

        /**
         * @return the newNextSlideID
         */
        public long getNewNextSlideDefinitionID() {
                return newNextSlideDefinitionID;
        }

        /**
         * @param expSlide the expSlide to set
         */
        public void setExpandedSlide(ExpandedSlide expSlide) {
                this.expSlide = expSlide;
        }

        /**
         * @return the expSlide
         */
        public ExpandedSlide getExpandedSlide() {
                return expSlide;
        }

        /**
         * @param newPrevSlideDefinitionID the newPrevSlideDefinitionID to set
         */
        public void setNewPrevSlideDefinitionID(long newPrevSlideDefinitionID) {
                this.newPrevSlideDefinitionID = newPrevSlideDefinitionID;
        }

        /**
         * @return the newPrevSlideDefinitionID
         */
        public long getNewPrevSlideDefinitionID() {
                return newPrevSlideDefinitionID;
        }

        /**
         * 
         * @param featureDefinitionID
         * @return
         * @throws Exception
         */
        public String getLearnedValuesString(long featureDefinitionID) 
                        throws Exception {
                List<String> learnedValues = this.getLearnedValues(featureDefinitionID);
                if(learnedValues == null) {
                        return "";
                }
                
                return "\"" + StringUtils.join(learnedValues, "\", \"") + "\"";
        }

        /**
         * 
         * @param featureDefinitionID
         * @return
         * @throws Exception
         */
        public List<String> getLearnedValues(long featureDefinitionID) 
                        throws Exception {
                List<ExpandedBullet> learnedBullets = CreationUtils.getLearnedBullets(featureDefinitionID);
                
                if(learnedBullets == null) {
                        return null;
                }
                
                List<String> learnedValues = new ArrayList<String>();
                for(ExpandedBullet expBullet : learnedBullets) {
                        learnedValues.add(expBullet.getValue());
                }
                
                return learnedValues;
        }

        /**
         * 
         * @param featureDefinitionID
         * @return
         * @throws Exception
         */
        public ExpandedFeature getFeature(long featureDefinitionID) 
                throws Exception {
                if(this.expSlide != null) {
                        Feature feature = ents.getFeature(
                                        this.expSlide, featureDefinitionID);
                        
                        if(feature == null) {
                                return null;
                        }
                        return new ExpandedFeature(feature);
                }
                
                return null;
        }
        
        /**
         * 
         * @return
         */
        public String getEditorialImportance() {
                // Now that slides are selected upfront
                return "Mandatory";
                
                /*
                long catID = this.expEntity.getCategoryID();
                long slideDefID = this.getNewCurrentSlideDefinitionID();
                
                try {
                        List<CategorySlideDefinition> catSlideDefs =
                                defs.getCategorySlideDefinitions(catID);
                        for(CategorySlideDefinition catSlideDef : catSlideDefs) {
                                if(catSlideDef.getSlideDefintionID() == slideDefID) {
                                        return catSlideDef.getEditorialImportance().toString();
                                }
                        }
                } catch (Exception e) {
                        log.error(CreationUtils.getStackTrace(e));
        }
                
                return "";
                */
        }
        


        /**
         * 
         * @return
         */
        public String getCategoryName(long categoryID) {
                if(categoryID==-1)
                        return "Yet to be Asssigned";
                try {
                        return this.defs.getCategory(categoryID).getLabel();
                        
                } catch (Exception e) {
                        return null;
                }
        }
        
        /**
         * 
         * @return
         */
        public List<String[]> getSlides() {
                try {
                        long entityID = Long.parseLong(this.getId());
                        long categoryID = this.getEntity().getCategoryID();
                        //List<Long> slideDefIDs = CreationUtils.getSlideSequence(entityID, categoryID);
                        List<Long> slideDefIDs = CreationUtils.getEntity(entityID).getSlideSequence();
                        
                        List<String[]> slideData = new ArrayList<String[]>();
        
                        for(Long slideDefID : slideDefIDs) {
                                SlideDefinition slideDef = defs.getSlideDefinition(slideDefID);
                                String label = slideDef.getLabel();
                                
                                slideData.add(new String[] {slideDefID.toString(), label});
                        }
                        
                        return slideData;
                } catch (Exception e) {
                        log.error(CreationUtils.getStackTrace(e));
                        
                        return null;
                }
        } 
    
    /**
     * 
     * @param entityID
     * @return
     * @throws Exception 
     */
    private ExpandedEntity getExpandedEntity(long entityID) throws Exception {
        if(this.expEntity == null) {
                if(this.entity == null) {
                        this.entity = CreationUtils.getEntity(entityID);
                }
                this.expEntity = new ExpandedEntity(entity);
        }
        
        return this.expEntity;
    }

    public Map<Long, EntityState> getEntitiesState(){
        return this.entitiesState;
    }
    
    public Set<String> getAllUserNames(){
        return UserManager.getUserManager().getAllUserNames();
    }
    
    public Collection<User> getAllUsers(){
        return UserManager.getUserManager().getAllUsers();
    }
    
    
        
}