Subversion Repositories SmartDukaan

Rev

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

package in.shop2020.ui.util;

import in.shop2020.metamodel.core.Bullet;
import in.shop2020.metamodel.core.Entity;
import in.shop2020.metamodel.core.Feature;
import in.shop2020.metamodel.core.FreeformContent;
import in.shop2020.metamodel.core.Media;
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.util.CreationUtils;
import in.shop2020.metamodel.util.ExpandedBullet;
import in.shop2020.metamodel.util.ExpandedEntity;
import in.shop2020.metamodel.util.ExpandedFeature;
import in.shop2020.metamodel.util.ExpandedSlide;
import in.shop2020.model.v1.catalog.CatalogService.Client;
import in.shop2020.model.v1.catalog.Item;
import in.shop2020.model.v1.catalog.status;
import in.shop2020.thrift.clients.CatalogClient;
import in.shop2020.util.EntityUtils;
import in.shop2020.util.Utils;
import in.shop2020.utils.Logger;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URLEncoder;
import java.nio.channels.FileChannel;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.json.JSONObject;

/**
 * Utility class to merge Java data objects with VTL scripts. Also generates
 * images and other required stuff for rendering content
 *
 * @author rajveer
 *
 */
public class NewVUI {
    private static final String ICON_JPG = "icon.jpg";
    private static final String THUMBNAIL_JPG = "thumbnail.jpg";
    private static final String DEFAULT_JPG = "default.jpg";
    private static final String SPACE = " ";
    private static final String DOT = ".";
    private static final String ESCAPED_DOT = "\\.";
    private static final String HYPHON = "-";
    private static Log log = LogFactory.getLog(NewVUI.class);
    private String     contentVersion;

    public NewVUI(Long contentVersion) throws Exception {
        this.contentVersion = contentVersion.toString();
    }
    
    static Client cl;
    
    static {
        try{
                cl = new CatalogClient().getClient();
        }catch (Exception e){
                e.printStackTrace();
        }
    }


    private void copyDocuments(ExpandedEntity expEntity, String documentPrefix) throws IOException {
        long catalogId = expEntity.getID();
        String destinationDirectory = Utils.EXPORT_PATH + "documents"
                + File.separator + catalogId;

        /*
         * Create the directory for this entity if it didn't exist.
         */
        File destFile = new File(destinationDirectory);
        if (!destFile.exists()) {
            destFile.mkdir();
        }

        ExpandedSlide expSlide = expEntity.getExpandedSlide(Utils.AFTER_SALES_SLIDE_DEFINITION_ID);

        if (expSlide == null || expSlide.getFreeformContent() == null) {
            return;
        }

        List<String> documentLabels = expSlide.getFreeformContent().getDocumentLabels();
        if ((documentLabels == null || documentLabels.isEmpty())) {
            return;
        } else {
            Map<String, Media> medias = expSlide.getFreeformContent().getMedias();
            for (String documentLabel : documentLabels) {
                Media document = medias.get(documentLabel);
                copyFile(new File(document.getLocation()), new File(destFile, computeNewFileName(documentPrefix, document.getFileName(),
                        String.valueOf(document.getCreationTime().getTime()))), false);
            }
        }
    }

    /**
     * It Actually copies the images from some given directory to export
     * directory. It also attaches the imagePrefix at the end of image name.
     *
     * @param catalogId
     * @param imagePrefix
     * @throws IOException
     */
    private void generateImages(ExpandedEntity entity, final String imagePrefix)
            throws IOException {
        long catalogId = entity.getID();
        String globalImageDirPath = Utils.CONTENT_DB_PATH + "media"
                + File.separator;
        String globalDefaultImagePath = globalImageDirPath + DEFAULT_JPG;

        String imageDirPath = globalImageDirPath + catalogId + File.separator;
        String defaultImagePath = imageDirPath + DEFAULT_JPG;

        /*
         * Create the directory for this entity if it didn't exist.
         */
        File f = new File(globalImageDirPath + catalogId);
        if (!f.exists()) {
            f.mkdir();
        }

        /*
         * If the default image is not present for this entity, copy the global
         * default image. TODO: This part will be moved to the Jython Script
         */
        File globalDefaultJPGFile = new File(globalDefaultImagePath);
        copyFile(globalDefaultJPGFile, new File(defaultImagePath), false);

        File staticMediaDirectory = new File(Utils.EXPORT_MEDIA_STATIC_PATH + catalogId);
        if (!staticMediaDirectory.exists()) {
            staticMediaDirectory.mkdir();
        }

        File websiteMediaDirectory = new File(Utils.EXPORT_MEDIA_WEBSITE_PATH + catalogId);
        if (!websiteMediaDirectory.exists()) {
            websiteMediaDirectory.mkdir();
        }

        /*
         * Creating default, thumbnails and icon files in case no 'default' labelled media is uploaded
         * in CMS for an entity in summary slide. It copes content form the global default location.
         * For incremental geenration, we check for global image file's last modified timestamp.
         */
        long defaultImageCreationTime = EntityUtils.getCreationTimeFromSummarySlide(entity, "default");
        File newVersionedDefaultJPGFile = new File(staticMediaDirectory,
                computeNewFileName(imagePrefix, DEFAULT_JPG, String.valueOf(defaultImageCreationTime)));

        // This flag basically determines whether 'default' labelled image has changed or not
        // If defaultImageCreationTime is zero, i.e. either the entity is old so its image/media 
        // object does not have creationTime field set; or, the default image itself does'not exist!
        // In either case, we shuld assume that default image does not exist
        boolean existsNewVersionedDefaultJPGFile = newVersionedDefaultJPGFile.exists();

        // If default images are not generated before, or default labelled images are absent, or the global
        // image itself got changed, we need to copy these images.
        if (defaultImageCreationTime == 0 && (!existsNewVersionedDefaultJPGFile ||
                globalDefaultJPGFile.lastModified() > Long.parseLong(contentVersion)))
        {
            copyFile(globalDefaultJPGFile,
                     new File(websiteMediaDirectory, DEFAULT_JPG), false);

            copyFile(globalDefaultJPGFile,
                     newVersionedDefaultJPGFile, false);

            copyFile(new File(imageDirPath + THUMBNAIL_JPG),
                     new File(websiteMediaDirectory, THUMBNAIL_JPG), true);

            copyFile(new File(imageDirPath + ICON_JPG),
                     new File(websiteMediaDirectory, ICON_JPG), true);

            copyFile(new File(imageDirPath + THUMBNAIL_JPG),
                     new File(staticMediaDirectory, computeNewFileName(imagePrefix, THUMBNAIL_JPG,
                             String.valueOf(defaultImageCreationTime))), false);

            copyFile(new File(imageDirPath + ICON_JPG),
                     new File(staticMediaDirectory, computeNewFileName(imagePrefix, ICON_JPG,
                             String.valueOf(defaultImageCreationTime))), false);

            // FIXME This should be removed once we are ready with changes in ProductListGenerator.
            copyFile(new File(imageDirPath + ICON_JPG),
                     new File(staticMediaDirectory, ICON_JPG), true);
        }

        /*
         * Copying the generated content from db/media to export/media. This
         * will also insert a creation timestamp tag in the file names.
         */
        for (ExpandedSlide expandedSlide : entity.getExpandedSlides()) {
            FreeformContent freeFormContent = expandedSlide
                    .getFreeformContent();
            if (freeFormContent != null) {
                for (String label : freeFormContent.getImageLabels()) {
                    final Media image = freeFormContent.getMedias().get(label);
                    if (isWebsiteImage(image)) {
                        // In case, default.jpg is changed, icon.jpg and
                        // thumbnail.jpg also need to be updated
                        if (isDefaultImage(image)) {
                                copyFile(new File(image.getLocation()),
                                         new File(websiteMediaDirectory, image.getFileName()),
                                        !existsNewVersionedDefaultJPGFile);

                                /*
                                 * Copy the thumbnail and the icon files. This is
                                 * required so that we can display the thumbnail on
                                 * the cart page and icon on the facebook.
                                 */
                                copyFile(new File(imageDirPath + THUMBNAIL_JPG),
                                         new File(websiteMediaDirectory, THUMBNAIL_JPG),
                                        !existsNewVersionedDefaultJPGFile);

                                copyFile(new File(imageDirPath + ICON_JPG),
                                         new File(websiteMediaDirectory, ICON_JPG),
                                        !existsNewVersionedDefaultJPGFile);
                        }
                        else {
                            copyFile(new File(image.getLocation()),
                                     new File(websiteMediaDirectory, image.getFileName()),
                                     false);
                        }
                    }

                    // Copying all files with timestamps in static directory
                    copyFile(new File(image.getLocation()),
                             new File(staticMediaDirectory, computeNewFileName(imagePrefix, image.getFileName(),
                                    String.valueOf(image.getCreationTime().getTime()))), false);

                    // If default image is changed icon and thumbnail images are
                    // re-copied in static directory
                    if (isDefaultImage(image)) {
                        copyFile(new File(imageDirPath + THUMBNAIL_JPG),
                                 new File(staticMediaDirectory,
                                         computeNewFileName(imagePrefix, THUMBNAIL_JPG, String.valueOf(image.getCreationTime().getTime()))), false);

                        copyFile(new File(imageDirPath + ICON_JPG),
                                 new File(staticMediaDirectory,
                                     computeNewFileName(imagePrefix, ICON_JPG, String.valueOf(image.getCreationTime().getTime()))), false);

                        // FIXME This should be removed once we are ready with
                        // changes in ProductListGenerator.
                        copyFile(new File(imageDirPath + ICON_JPG), new File(
                                staticMediaDirectory, ICON_JPG), !existsNewVersionedDefaultJPGFile);
                    }
                }
            }
        }
    }

    /**
     * This method computes new name of a given file. It adds necessary prefix 
     * and suffix to core file name separated by hyphons keeping extension intact.
     * e.g. computeNewFileName("pre", "file.txt", "post") would return "pre-file-post.txt"
     *
     * @param fileNamePrefix    the string to be prefixed
     * @param fileName          the complete name of file
     * @param fileNameSuffix    the string to be suffixed
     * @return the final file name
     */
    public static String computeNewFileName(String fileNamePrefix, String fileName, String fileNameSuffix) {
        String name = fileName.split(ESCAPED_DOT)[0];
        String fileExt = fileName.split(ESCAPED_DOT)[1];
        return fileNamePrefix + HYPHON + name + HYPHON + fileNameSuffix + DOT + fileExt;
    }

    /**
     * Images to be copied under export/media/website are identified here
     *
     * @param image
     * @return true in case image needs to be copied in website directory
     */
    private boolean isWebsiteImage(Media image) {
        if (isDefaultImage(image)) {
            return true;
        }

        return false;
    }

    /**
     * Retuens true in case a given image is the default one. False, otherwise.
     */
    private boolean isDefaultImage(Media image) {
        String label = image.getLabel();
        return label != null && "default".equals(label.trim());
    }

    /**
     * Copies the contents of the source file into the destination file. Creates
     * the destination file if it doesn't exist already.
     */
    private void copyFile(File sourceFile, File destFile, boolean overwrite) throws IOException {       
        if (!destFile.exists()) {
            log.info("Creating file: " + destFile.getAbsolutePath());
            destFile.createNewFile();
        }
        else {
            // Return in case file should not be overwritten
            if (!overwrite) {
                log.info("Not overwriting file: " + destFile.getAbsolutePath());
                return;
            }

            log.info("Overwriting file: " + destFile.getAbsolutePath());
        }

        FileChannel source = null;
        FileChannel destination = null;

        try {
            source = new FileInputStream(sourceFile).getChannel();
            destination = new FileOutputStream(destFile).getChannel();
            destination.transferFrom(source, 0, source.size());
        } finally {
            if (source != null) {
                source.close();
            }
            if (destination != null) {
                destination.close();
            }
        }
    }

    /**
     * Get the commonly used product properties and store them in a file.
     *
     * @param expEntity
     * @param exportPath
     */
    private void getProductPropertiesSnippet(ExpandedEntity expEntity,
            String exportPath) {
        long catalogId = expEntity.getID();

        try {
            expEntity = CreationUtils.getExpandedEntity(catalogId);
        } catch (Exception e) {
            log.error("Error fetching entity for id: " + catalogId, e);
        }

        String metaDescription = "";
        String metaKeywords = "";
        String entityUrl = EntityUtils.getEntityURL(expEntity);
        String title = "";

        List<Feature> features = expEntity.getSlide(130054).getFeatures();
        for (Feature feature : features) {
            if (feature.getFeatureDefinitionID() == 120132) {
                PrimitiveDataObject dataObject = (PrimitiveDataObject) feature
                        .getBullets().get(0).getDataObject();
                title = dataObject.getValue();
            }
            if (feature.getFeatureDefinitionID() == 120133) {
                PrimitiveDataObject dataObject = (PrimitiveDataObject) feature
                        .getBullets().get(0).getDataObject();
                metaDescription = dataObject.getValue();
            }
            if (feature.getFeatureDefinitionID() == 120134) {
                PrimitiveDataObject dataObject = (PrimitiveDataObject) feature
                        .getBullets().get(0).getDataObject();
                metaKeywords = dataObject.getValue();
            }
        }

        try {
            JSONObject props = new JSONObject();
            Category category = expEntity.getCategory();
            String categoryName = category.getLabel();
           
            props.put("metaDescription", metaDescription);
            props.put("metaKeywords", metaKeywords);
            props.put("entityUrl", entityUrl);
            props.put("title", title);
            props.put("name", EntityUtils.getProductName(expEntity));
            boolean displayAccessories;
            
            Category parentCategory = category.getParentCategory();
            props.put("parentCategory", parentCategory.getLabel());
            if(parentCategory.isHasAccessories()){
                props.put("displayAccessories", "TRUE");
                displayAccessories = true;
            }else{
                props.put("displayAccessories", "FALSE" );
                displayAccessories = false;
            }  
           
            props.put("categoryName", categoryName);
            props.put("compareCategory", parentCategory.isComparable() ? parentCategory.getLabel() : categoryName);
            props.put("categoryUrl", categoryName.replaceAll(SPACE, "-").toLowerCase() + "/" + category.getID());
            String categoryUrl = categoryName.replaceAll(SPACE, "-").toLowerCase() + "/" + category.getID();
           
            String brandUrl = expEntity.getBrand().toLowerCase().replace(' ', '-');
           
            String breadCrumb = "<a href='/'>Home</a>&nbsp;&gt;&nbsp;" +
                                "<a href='/" +  categoryUrl + "'>" + categoryName + "</a>&nbsp;&gt;&nbsp;";
            if(displayAccessories){
                breadCrumb = breadCrumb +  "<a href='/" + brandUrl + "'>" + expEntity.getBrand() + "</a>";
            }else{
                breadCrumb =  breadCrumb + "<a>" + expEntity.getBrand() + "</a>";  
            }
            breadCrumb = breadCrumb +  "&nbsp;<a>" + expEntity.getModelName().trim() + SPACE + expEntity.getModelNumber().trim() + "</a>";
            props.put("breadCrumb", breadCrumb);
         
           
            String exportFileName = exportPath + catalogId + File.separator
                    + "ProductPropertiesSnippet.vm";
            File exportFile = new File(exportFileName);
            if (!exportFile.exists()) {
                exportFile.createNewFile();
            }

            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(exportFile)));

            writer.write(props.toString());

            writer.flush();
            writer.close();
        } catch (Exception e) {
            log.error("Error generating JSON", e);
        }
    }

    /**
     * Get slide names and write them in a file. This file will be used in
     * comparison.
     *
     * @param expEntity
     * @param exportPath
     * @throws Exception
     */
    private void getSlidenamesSnippet(ExpandedEntity expEntity,
            String exportPath) throws Exception {
        long catalogId = expEntity.getID();

        StringBuilder slideNames = new StringBuilder();

        // TODO Investigate why brand + model number is used ?
        slideNames.append(expEntity.getBrand() + SPACE
                + expEntity.getModelName() + SPACE + expEntity.getModelNumber()
                + "\n");
        slideNames.append(expEntity.getBrand() + SPACE +
                        (StringUtils.isNotEmpty(expEntity.getModelName()) ?  expEntity.getModelName() : expEntity.getModelNumber())
                        + "\n");

        Map<Long, Double> slideScores = CreationUtils
                .getSlideComparisonScores(catalogId);

        DecimalFormat oneDForm = new DecimalFormat("#.#");
        for (ExpandedSlide expSlide : expEntity.getExpandedSlides()) {
            if (expSlide.getSlideDefinitionID() == Utils.SUMMARY_SLIDE_DEFINITION_ID
                    || expSlide.getSlideDefinitionID() == Utils.AFTER_SALES_SLIDE_DEFINITION_ID) {
                continue;
            }
            slideNames.append(expSlide.getSlideDefinition().getLabel() + "!!!");

            String bucketName = Catalog.getInstance().getDefinitionsContainer().getComparisonBucketName(expEntity.getCategoryID(), expSlide.getSlideDefinitionID());
            if ( bucketName == null) {
                bucketName = "None"; 
            }
            slideNames.append(bucketName + "!!!");

            double score = 0;
            if (slideScores != null && slideScores.get(expSlide.getSlideDefinitionID()) != null) {
                score = slideScores.get(expSlide.getSlideDefinitionID());
            }

            score = Double.valueOf(oneDForm.format(score));

            slideNames.append(score + "\n");
        }

        String exportFileName = exportPath + catalogId + File.separator
                + "SlideNamesSnippet.vm";
        File exportFile = new File(exportFileName);
        if (!exportFile.exists()) {
            exportFile.createNewFile();
        }

        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(exportFile)));

        writer.write(slideNames.toString());
        writer.flush();
        writer.close();

    }

    /**
     * Get related accessories
     *
     * @param expEntity
     * @param exportPath
     * @throws Exception
     */
    private void getRelatedAccessories(ExpandedEntity expEntity,
            String exportPath) throws Exception {
        long catalogId = expEntity.getID();

        Map<Long, List<Long>> relatedAccessories = CreationUtils
                .getRelatedAccessories().get(catalogId);
        List<Long> priorityList = new ArrayList<Long>();
        int individualLimit = 2;
        int totalLimit = 10;
        priorityList.add(Utils.CARRYING_CASE);
        priorityList.add(Utils.SCREEN_GUARD);
        priorityList.add(Utils.BATTERY);
        priorityList.add(Utils.MEMORY_CARD);
        priorityList.add(Utils.BLUETOOTH_HEADSET);
        priorityList.add(Utils.HEADSET);
        priorityList.add(Utils.CHARGER);

        StringBuffer sb = new StringBuffer();
        int totalCount = 0;
        if (relatedAccessories != null) {
            for (Long catID : priorityList) {
                int individualCount = 0;
                List<Long> ents = relatedAccessories.get(catID);
                if (ents != null && !ents.isEmpty()) {
                        Predicate activeOnly =new Predicate() {
                                                
                                                @Override
                                                public boolean evaluate(Object arg0) {
                                                        Long entityId = (Long)arg0;
                                                        boolean returnVal = false;
                                                        List<Item> items = null;
                                                        try {
                                                                try {
                                                                        items = cl.getItemsByCatalogId(entityId);
                                                                } catch (Exception e) {
                                                                        Logger.log("Error:", e);
                                                                        cl = new CatalogClient().getClient();
                                                                        items = cl.getItemsByCatalogId(entityId);
                                                                }
                                                                for(Item item: items){
                                                                        if(item.getItemStatus().equals(status.ACTIVE)){
                                                                                returnVal = true;
                                                                                break;
                                                                        }
                                                                }
                                                        } catch (Exception e) {
                                                                // TODO Auto-generated catch block
                                                                log.error("Error accessing thrift service", e);
                                                        }
                                                        return returnVal;
                                                }
                                        };
                                        CollectionUtils.filter(ents, activeOnly);
                    if (ents.size() > individualLimit) {
                        ents = ents.subList(0, individualLimit);
                    }
                    for (Long entID : ents) {
                        if (totalLimit > totalCount) {
                            sb.append(entID + "\n");
                            individualCount++;
                            totalCount++;
                        }
                    }
                }
            }
        }

        String exportFileName = exportPath + catalogId + File.separator
                + "RelatedAccessories.vm";
        File exportFile = new File(exportFileName);
        if (!exportFile.exists()) {
            exportFile.createNewFile();
        }

        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(exportFile)));

        writer.write(sb.toString());
        writer.flush();
        writer.close();

    }

    /**
     * Get most compared phones
     *
     * @param expEntity
     * @param exportPath
     * @throws Exception
     */
    private void getMostComparedProducts(ExpandedEntity expEntity,
            String exportPath) throws Exception {
        long catalogId = expEntity.getID();

        Map<Long, Long> comparedPhones = CreationUtils.getComparisonStats()
                .get(catalogId);

        StringBuffer sb = new StringBuffer();
        int maxCount = 10;
        int count = 0;
        if (comparedPhones != null) {
            for (Long entityID : comparedPhones.keySet()) {
                if (count > maxCount) {
                    break;
                }
                sb.append(entityID + "\n");
                count++;
            }
        }

        String exportFileName = exportPath + catalogId + File.separator
                + "MostComparedProducts.vm";
        File exportFile = new File(exportFileName);
        if (!exportFile.exists()) {
            exportFile.createNewFile();
        }

        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(exportFile)));

        writer.write(sb.toString());
        writer.flush();
        writer.close();
    }

    /**
     * Get the required parameters for generating velocity content.
     *
     * @param expEntity
     * @return
     * @throws Exception
     */
    private Map<String, String> getEntityParameters(ExpandedEntity expEntity)
            throws Exception {
        Map<String, String> params = new HashMap<String, String>();
        String title = EntityUtils.getProductName(expEntity);
        String brandName = expEntity.getBrand().trim();
        String productName = ((expEntity.getModelName() != null) ? expEntity
                .getModelName().trim() + SPACE : "")
                + ((expEntity.getModelNumber() != null) ? expEntity
                        .getModelNumber().trim() : "");

        String prodName = title;
        if (expEntity.getModelName() != null
                && !expEntity.getModelName().isEmpty()
                && (expEntity.getBrand().equals("Samsung") || expEntity
                        .getBrand().equals("Sony Ericsson"))) {
            prodName = expEntity.getBrand().trim()
                    + SPACE
                    + ((expEntity.getModelName() != null) ? expEntity
                            .getModelName().trim() : "");
        }
        Category cat = expEntity.getCategory();
        
        Category parentCategory = cat.getParentCategory();
        
        String categoryName = cat.getLabel();
        String tagline = "";
        String warranty = "";
        String tinySnippet = "";
        List<Feature> features = expEntity.getSlide(130054).getFeatures();
        for (Feature feature : features) {
            if (feature.getFeatureDefinitionID() == 120084) {
                PrimitiveDataObject dataObject = (PrimitiveDataObject) feature
                        .getBullets().get(0).getDataObject();
                tagline = dataObject.getValue();
            }
            if (feature.getFeatureDefinitionID() == 120089) {
                PrimitiveDataObject dataObject = (PrimitiveDataObject) feature
                        .getBullets().get(0).getDataObject();
                tinySnippet = dataObject.getValue();
            }
            if (feature.getFeatureDefinitionID() == 120081) {
                List<Bullet> bullets = feature.getBullets();
                int count = 1;
                for (Bullet bullet : bullets) {
                    PrimitiveDataObject dataObject = (PrimitiveDataObject) bullet
                            .getDataObject();
                    params.put("SNIPPET_" + count++, dataObject.getValue());
                }
            }
        }

        // Creating warranty string!
        for (Slide slide : expEntity.getSlide(130054).getChildrenSlides()) {
            if (slide.getSlideDefinitionID() == 130105) {
                ExpandedSlide expSlide = new ExpandedSlide(slide);
                Feature warrantyDurationFeature = expSlide.getExpandedFeature(120125);
                if (warrantyDurationFeature != null) {
                    ExpandedFeature expFeature = new ExpandedFeature(warrantyDurationFeature);
                    ExpandedBullet expBullet = expFeature.getExpandedBullets().get(0);
                    if (expBullet != null) {
                        String shortForm = expBullet.getUnit().getShortForm();

                        // Append 's' to month and year
                        if (!expBullet.getValue().trim().equals("1")) {
                            shortForm += "s";
                        }
                        warranty += expBullet.getValue() + SPACE + shortForm;
                    }
                }

                Feature warrantyTypeFeature = expSlide.getExpandedFeature(120219);
                if (warrantyTypeFeature != null) {
                    ExpandedFeature expFeature = new ExpandedFeature(warrantyTypeFeature);
                    ExpandedBullet expBullet = expFeature.getExpandedBullets().get(0);
                    if (expBullet != null) {
                        warranty += SPACE + expBullet.getExpandedEnumDataObject()
                                        .getEnumValue().getValue();
                    }
                }

                Feature warrantyCoverageFeature = expSlide.getExpandedFeature(120220);
                if (warrantyCoverageFeature != null) {
                    ExpandedFeature expFeature = new ExpandedFeature(warrantyCoverageFeature);
                    ExpandedBullet expBullet = expFeature.getExpandedBullets().get(0);
                    if (expBullet != null) {
                        warranty += SPACE + HYPHON + SPACE + expBullet.getExpandedEnumDataObject().getEnumValue().getValue();
                    }
                }
            }
        }
        long categoryId = cat.getID();
        params.put("PROD_NAME", prodName);
        params.put("URL", EntityUtils.getEntityURL(expEntity));
        params.put("TITLE", title);
        params.put("BRAND_NAME", brandName);
        params.put("PRODUCT_NAME", productName);
        params.put("CATEGORY_ID", ((int) categoryId) + "");
        params.put("CATEGORY_NAME", categoryName);
        params.put("PARENT_CATEGORY", parentCategory.getLabel());
        params.put("COMPARE_CATEGORY", parentCategory.isComparable() ? 
                                parentCategory.getLabel(): cat.getLabel());
        params.put("CATEGORY_URL", categoryName.replaceAll(SPACE, HYPHON)
                .toLowerCase() + "/" + categoryId);
        params.put(
                "PRODUCT_URL",
                URLEncoder.encode("http://www.", "UTF-8")
                        + "${domain}"
                        + URLEncoder.encode(
                                EntityUtils.getEntityURL(expEntity), "UTF-8"));
        
        if (cat.isComparable()) {
                params.put("IS_COMPARABLE", "TRUE");
        } else  {
                params.put("IS_COMPARABLE", "FALSE");
        }
        
        params.put("CATALOG_ID", expEntity.getID() + "");
        params.put("TAGLINE", tagline);
        params.put("WARRANTY", warranty);
        params.put("TINY_SNIPPET", tinySnippet);
        params.put("IMAGE_PREFIX", EntityUtils.getMediaPrefix(expEntity));
        params.put("contentVersion", contentVersion);
        params.put("skinImageCreationTime", String.valueOf(EntityUtils.getCreationTimeFromSummarySlide(expEntity, "skin")));
        params.put("DEFAULT_IMAGE_SUFFIX", String.valueOf(EntityUtils.getCreationTimeFromSummarySlide(expEntity, "default")));

        return params;
    }
   

    /**
     * Generates content for the specified entity embedding links to the
     * specified domain name.
     *
     * The method updates the member variable problems in any of the following
     * four cases:
     * <ol>
     * <li>The entity is not ready.
     * <li>The category has not been updated yet. (Set to -1).
     * <li>There are no items in the catalog corresponding to this entity.
     * <li>There are no active or content-complete items in the catalog
     * corresponding to this entity.
     * <li>Neither the items have been updated nor the content has been updated.
     * </ol>
     *
     * @param entity
     *            - Entity for which the content has to be generated.
     * @param domain
     *            - The domain name to be used to serve static content.
     * @param exportPath
     *            - Local file system path where content has to be generated.
     * @throws Exception
     */
    public void generateContentForOneEntity(Entity entity, String exportPath)
            throws Exception {
        ExpandedEntity expEntity = new ExpandedEntity(entity);
        long catalogId = expEntity.getID();

        // Create new directory
        File exportDir = new File(exportPath + catalogId);
        if (!exportDir.exists()) {
            exportDir.mkdir();
        }

        VelocityContext context = new VelocityContext();

        Category parentCategory = expEntity.getCategory().getParentCategory();
        Boolean isComparable = expEntity.getCategory().isComparable();
        String mediaPrefix = EntityUtils.getMediaPrefix(expEntity);
        context.put("mediaPrefix", mediaPrefix);
        context.put("expentity", expEntity);
        context.put("contentVersion", this.contentVersion);
        context.put("defs", Catalog.getInstance().getDefinitionsContainer());
        context.put("helpdocs", CreationUtils.getHelpdocs());
        context.put("params", getEntityParameters(expEntity));
        context.put("isComparable", isComparable);

        List<String> filenames = new ArrayList<String>();
        filenames.add("ProductDetail");
        filenames.add("WidgetSnippet");
        filenames.add("HomeSnippet");
        filenames.add("SearchSnippet");
        filenames.add("CategorySnippet");
        filenames.add("SlideGuide");
        filenames.add("AfterSales");
        filenames.add("CompareProductSnippet");
        filenames.add("ComparisonSnippet");
        getSlidenamesSnippet(expEntity, exportPath);
        filenames.add("MyResearchSnippet");
        if(isComparable){
                filenames.add("CompareProductSummarySnippet");
                filenames.add("MostComparedSnippet");
                getMostComparedProducts(expEntity, exportPath);
        }
        if(parentCategory.isHasAccessories()){
                getRelatedAccessories(expEntity, exportPath);
        }
        if(parentCategory.getID()==Utils.MOBILE_PHONES_CATAGORY){
                filenames.add("PhonesIOwnSnippet");
        }
//        if (expEntity.getCategory().getParentCategory().getID() != Utils.MOBILE_ACCESSORIES_CATEGORY) {
//
//              // For laptops we do not have related accessories and most comparable
//              if(expEntity.getCategory().getID() != Utils.LAPTOPS_CATEGORY)   {
//                filenames.add("PhonesIOwnSnippet");
//
//                getRelatedAccessories(expEntity, exportPath);
//                getMostComparedProducts(expEntity, exportPath);
//              }
//            filenames.add("CompareProductSnippet");
//            filenames.add("ComparisonSnippet");
//            filenames.add("CompareProductSummarySnippet");
//            // This method wont use any velocity file, So calling directly
//        }

        // This method wont use any velocity file, So calling directly
        getProductPropertiesSnippet(expEntity, exportPath);

        applyVelocityTemplate(filenames, exportPath, context, catalogId);

        generateImages(expEntity, mediaPrefix);

        copyDocuments(expEntity, mediaPrefix);
    }

    /**
     * Get list of files and apply velocity templates on them
     *
     * @param filenames
     * @param exportPath
     * @param context
     * @param catalogId
     */
    private void applyVelocityTemplate(List<String> filenames,
            String exportPath, VelocityContext context, long catalogId) {
        try {
            Properties p = new Properties();
            p.setProperty("resource.loader", "file");
            p.setProperty("file.resource.loader.class",
                    "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
            p.setProperty("file.resource.loader.path", Utils.VTL_SRC_PATH);
            Velocity.init(p);
            for (String filename : filenames) {
                Template template = Velocity.getTemplate(filename + ".vm");
                BufferedWriter writer = new BufferedWriter(
                        new OutputStreamWriter(
                                new FileOutputStream(exportPath + catalogId
                                        + File.separator + filename + ".vm")));
                template.merge(context, writer);
                writer.flush();
                writer.close();
            }
        } catch (ResourceNotFoundException e) {
            log.error("Error generating velocity templates", e);
        } catch (IOException e) {
            log.error("Error generating velocity templates", e);
        } catch (ParseErrorException e) {
            log.error("Error generating velocity templates", e);
        } catch (Exception e) {
            log.error("Error generating velocity templates", e);
        }
    }
}