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 existboolean 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 updatedif (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 directorycopyFile(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 directoryif (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 overwrittenif (!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> > " +"<a href='/" + categoryUrl + "'>" + categoryName + "</a> > ";if(displayAccessories){breadCrumb = breadCrumb + "<a href='/" + brandUrl + "'>" + expEntity.getBrand() + "</a>";}else{breadCrumb = breadCrumb + "<a>" + expEntity.getBrand() + "</a>";}breadCrumb = breadCrumb + " <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() {@Overridepublic 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 blocklog.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 yearif (!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 directoryFile 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 directlygetProductPropertiesSnippet(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);}}}