Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2011 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.cq.commerce.common;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import com.adobe.cq.commerce.api.CommerceConstants;
import com.adobe.cq.commerce.api.CommerceException;
import com.adobe.cq.commerce.api.CommerceSession;
import com.adobe.cq.commerce.api.OrderHistoryTraitDataProvider;
import com.adobe.cq.commerce.api.PlacedOrderResult;
import com.adobe.cq.commerce.api.PriceInfo;
import com.adobe.cq.commerce.api.Product;
import com.adobe.cq.commerce.api.promotion.Promotion;
import com.adobe.cq.commerce.api.promotion.PromotionManager;
import com.adobe.cq.commerce.api.promotion.VoucherInfo;
import com.day.cq.commons.LanguageUtil;
import com.day.cq.commons.inherit.HierarchyNodeInheritanceValueMap;
import com.day.cq.commons.inherit.InheritanceValueMap;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.wcm.api.PageManager;
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.io.JSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.cq.commerce.api.promotion.PromotionInfo;
import com.day.cq.tagging.Tag;
import com.day.cq.tagging.TagManager;
import com.day.cq.wcm.api.Page;
public class CommerceHelper {
private static final Logger log = LoggerFactory.getLogger(CommerceHelper.class);
/**
* Maps a designer-supplied resource path (such as /content/geometrixx-outdoors/language-masters/en/user/cart)
* to the current language (ie: /content/geometrixx-outdoors/de/de/user/cart).
* @param currentPage The page being rendered (which controls the language selection)
* @param srcPath The resource path (usually given in the design language)
* @return The srcPath mapped to the currentPage's language
*/
public static String mapPathToCurrentLanguage(Page currentPage, String srcPath) {
// Example:
// currentPage: /content/geometrixx-outdoors/de/de/men/shorts/marka-sport
// srcPath: /content/geometrixx-outdoors/language-masters/en/user/cart
// return: /content/geometrixx-outdoors/de/de/user/cart
final String languageRoot = LanguageUtil.getLanguageRoot(currentPage.getPath());
if (StringUtils.isNotEmpty(languageRoot) && StringUtils.isNotBlank(srcPath)) {
final String srcSuffix = StringUtils.substringAfter(srcPath, LanguageUtil.getLanguageRoot(srcPath));
return(languageRoot+srcSuffix);
} else {
return srcPath;
}
}
/**
* Handles comparison of product "size" fields containing either numeric or letter sizes.
* Both operands must have the same type of size (ie: numeric or letter).
* @return a java.util.Comparator
*/
public static Comparator getProductSizeComparator() {
final String[] letterSizes = {"XXS", "2XS", "XS", "S", "M", "L", "XL", "XXL", "2XL", "XXXL", "3XL"};
final String[] units = {"IN", "FT", "MM", "CM", "M"};
return new Comparator() {
public int compare(Product o1, Product o2) {
String size1 = o1.getProperty("size", String.class).toUpperCase();
String size2 = o2.getProperty("size", String.class).toUpperCase();
if (indexOf(letterSizes, size1) >= 0 && indexOf(letterSizes, size2) >= 0) {
return NumberUtils.compare(indexOf(letterSizes, size1), indexOf(letterSizes, size2));
}
// remove units if both values share same unit
for (String unit : units) {
if (size1.contains(unit) && size2.contains(unit)) {
size1 = size1.replace(unit, "");
size2 = size2.replace(unit, "");
}
}
// convert feet and inches to monotonic function
if (size1.contains("\"")) {
size1 = size1.replace("\"", "");
}
if (size1.indexOf("'") >= 1) {
String parts[] = size1.split("'");
size1 = parts[0];
if (parts.length == 1) {
size1 += "00";
} else if (parts[1].length() == 1) {
size1 += "0" + parts[1];
} else {
size1 += parts[1];
}
}
if (size2.contains("\"")) {
size2 = size2.replace("\"", "");
}
if (size2.indexOf("'") >= 1) {
String parts[] = size2.split("'");
size2 = parts[0];
if (parts.length == 1) {
size2 += "00";
} else if (parts[1].length() == 1) {
size2 += "0" + parts[1];
} else {
size2 += parts[1];
}
}
double d1, d2;
if (NumberUtils.isNumber(size1) && NumberUtils.isNumber(size2)) {
d1 = Double.parseDouble(size1);
d2 = Double.parseDouble(size2);
} else {
throw new IllegalArgumentException(String.format("Size values not recognized: %s, %s",
o1.getProperty("size", String.class), o2.getProperty("size", String.class)));
}
return NumberUtils.compare(d1, d2);
}
};
}
private static int indexOf(String[] strings, String op) {
for (int i = 0; i < strings.length; i++) {
if (strings[i].equals(op)) {
return i;
}
}
return -1;
}
/**
* Finds the current {@link Product} for a product page. This will be the first {@link Product}
* node or reference within the page's content.
* @param currentPage The page to search in
* @return First Product for a product page
* @see #findProduct(Resource)
*/
public static Product findCurrentProduct(Page currentPage) {
try {
return findProduct(currentPage.getContentResource());
} catch (RepositoryException e) {
return null;
}
}
/**
* Finds a product at or below the provided resource's path.
* @param resource The resource to start from
* @return First Product that is found
* @throws RepositoryException
*/
protected static Product findProduct(Resource resource) throws RepositoryException {
final Resource productResource = findProductResource(resource);
if (productResource != null) {
return productResource.adaptTo(Product.class);
}
return null;
}
/**
* Finds the current product resource for a page. This will be the first node with a {@code cq:commerceType}
* property of {@code product}. As opposed to {@link #findCurrentProduct(com.day.cq.wcm.api.Page)}, this will not
* try to adapt the resource to a {@link Product}, so it will work even for yet-unfilled resources.
* @param page The page to search in
* @return The first {@code cq:commerceType='product'} resource, or {@code null} if it doesn't exist
* @see #findProductResource(org.apache.sling.api.resource.Resource)
*/
public static Resource findProductResource(final Page page) {
return findProductResource(page.getContentResource());
}
/**
* Finds a product resource at or below the provided resource's path. As opposed to
* {@link #findProduct(org.apache.sling.api.resource.Resource)}, this will not try to adapt the resource to a
* {@link Product}, so it will work even for yet-unfilled resources.
* @param resource The resource to start from
* @return The first {@code cq:commerceType='product'} resource, or {@code null} if it doesn't exist
* @see #findProductResource(com.day.cq.wcm.api.Page)
*/
public static Resource findProductResource(final Resource resource) {
if (AbstractJcrProduct.isABaseProduct(resource)) {
return resource;
} else {
for (Iterator iter = resource.listChildren(); iter.hasNext();) {
final Resource product = findProductResource(iter.next());
if (product != null) {
return product;
}
}
return null;
}
}
/**
* Collects up a map of product variations (including the base product) under a given subtree.
* The map is keyed by the PN_PRODUCT_DATA path.
* @param resource
* @param variations
*/
public static void collectVariants(final Resource resource, Mapvariations) {
if (AbstractJcrProduct.isAProductOrVariant(resource)) {
ValueMap properties = resource.adaptTo(ValueMap.class);
String key = properties.get(CommerceConstants.PN_PRODUCT_DATA, String.class);
if (key != null && !properties.get("cq:RolloutHookSyncAction", false)) {
variations.put(key, resource.adaptTo(Product.class));
}
}
for (final Iterator children = resource.listChildren(); children.hasNext();) {
collectVariants(children.next(), variations);
}
}
/**
* Copies a filtered list of tags from a Product to another Resource.
* @param source
* @param dest
* @param filter A {@link Predicate} which is passed each {@link com.day.cq.tagging.Tag}.
* @return true if any tags were copied
*/
public static boolean copyTags(Product source, Resource dest, Predicate filter) throws RepositoryException {
TagManager tagManager = dest.getResourceResolver().adaptTo(TagManager.class);
List resultTags = new ArrayList();
boolean changed = false;
String[] destTags = ResourceUtil.getValueMap(dest).get("cq:tags", String[].class);
if (destTags != null) {
resultTags.addAll(Arrays.asList(destTags));
}
String[] sourceTags = source.getProperty("cq:tags", String[].class);
if (sourceTags != null) {
for (String sourceTag : sourceTags) {
Tag tag = tagManager.resolve(sourceTag);
if (tag != null && filter.evaluate(tag) && !resultTags.contains(sourceTag)) {
resultTags.add(sourceTag);
changed = true;
}
}
}
if (changed) {
dest.adaptTo(Node.class).setProperty("cq:tags", resultTags.toArray(new String[resultTags.size()]));
}
return changed;
}
/**
* Writes a cart to JSON for the CartMgr ClientContextStore.
* Does not support server promotions or promotion maps.
*
* @param writer A JSONWriter instance
* @param commerceSession The commerce session
* @throws CommerceException
* @throws JSONException
*/
public static void writeCart(JSONWriter writer, CommerceSession commerceSession)
throws CommerceException, JSONException {
writeCart(writer, commerceSession, null);
}
/**
* Writes a cart to JSON for the CartMgr ClientContextStore.
* Supports server promotions, but not promotion maps.
*
* @param writer A JSONWriter instance
* @param commerceSession The commerce session
* @param resolver The resource resolver
* @throws CommerceException
* @throws JSONException
* @deprecated since 6.1
*/
@Deprecated
public static void writeCart(JSONWriter writer, CommerceSession commerceSession, ResourceResolver resolver)
throws CommerceException, JSONException {
writeCart(writer, commerceSession, resolver, null);
}
/**
* Writes a cart to JSON for the CartMgr ClientContextStore.
* Supports server promotions and promotionMaps.
*
* @param writer A JSONWriter instance
* @param commerceSession The commerce session
* @param resolver The resource resolver
* @param request The current request
* @throws CommerceException
* @throws JSONException
* @deprecated since 6.1 (moved to ClientContextCartServlet)
*/
@Deprecated
public static void writeCart(JSONWriter writer, CommerceSession commerceSession, ResourceResolver resolver,
SlingHttpServletRequest request) throws CommerceException, JSONException {
PromotionManager pm = resolver != null ? resolver.adaptTo(PromotionManager.class) : null;
//
// Fetch the server and client promotion:segments maps
//
Map serverPromotionsMap = new HashMap();
if (pm != null) {
for (Promotion promotion : pm.getAvailablePromotions(resolver)) {
if ("/libs/commerce/components/promotion/server".equals(promotion.getType())) {
ValueMap props = promotion.getConfig();
String code = props.get("code", "");
if (StringUtils.isNotBlank(code) && !props.get("disabled", Boolean.FALSE)) {
serverPromotionsMap.put(code, StringUtils.join(promotion.getSegments(), ","));
}
}
}
}
Map clientPromotionsMap = new HashMap();
if (pm != null && request != null) {
clientPromotionsMap = pm.getPromotionsMap(request);
}
writer.object();
{
writer.key("entries").array();
for (CommerceSession.CartEntry e : commerceSession.getCartEntries()) {
writer.object();
{
writer.key("title").value(e.getProduct().getTitle());
writer.key("quantity").value(e.getQuantity());
final List priceInfos = e.getPriceInfo(null);
if (priceInfos != null && priceInfos.size() > 0) {
writer.key("priceFormatted").value(priceInfos.get(0).getFormattedString());
writer.key("price").value(priceInfos.get(0).getAmount());
} else {
log.error("Empty PriceInfo list for product!", e.getProduct().getPath());
writer.key("priceFormatted").value("$0.00");
writer.key("price").value(0);
}
String thumbnail = e.getProduct().getThumbnailUrl(".64.transparent");
if (StringUtils.isNotEmpty(thumbnail)) {
writer.key("thumbnail").value(thumbnail);
}
writer.key("page").value(e.getProduct().getPagePath());
writer.key("path").value(e.getProduct().getPath());
Boolean readonly= e.getProperty(CommerceSession.PN_READONLY, Boolean.class);
if (readonly != null && readonly) {
writer.key("readonly").value(true);
}
if (e instanceof DefaultJcrCartEntry) {
DefaultJcrCartEntry entry = (DefaultJcrCartEntry) e;
ValueMap properties = entry.getProperties();
if (!properties.isEmpty()) {
writer.key("properties").object();
for (String key : properties.keySet()) {
writer.key(key).value(properties.get(key, String.class));
}
writer.endObject();
}
}
}
writer.endObject();
}
writer.endArray();
writer.key("promotions").array();
for (PromotionInfo p : commerceSession.getPromotions()) {
if (p.getStatus() == PromotionInfo.PromotionStatus.FIRED || p.getStatus() == PromotionInfo.PromotionStatus.POTENTIAL) {
writer.object();
{
writer.key("title").value(p.getTitle());
writer.key("description").value(p.getDescription());
writer.key("message").value(p.getMessage());
writer.key("path").value(p.getPath());
writer.key("status").value(p.getStatus().toString());
writer.key("cartEntryIndex").value(p.getCartEntryIndex());
if (p.getStatus().equals(PromotionInfo.PromotionStatus.FIRED) && serverPromotionsMap.containsKey(p.getPath())) {
writer.key("resolve").value("true");
}
}
writer.endObject();
}
}
writer.endArray();
writer.key("vouchers").array();
for (VoucherInfo c : commerceSession.getVoucherInfos()) {
writer.object();
{
writer.key("code").value(c.getCode());
writer.key("title").value(c.getTitle());
writer.key("description").value(c.getDescription());
writer.key("message").value(c.getMessage());
writer.key("path").value(c.getPath());
}
writer.endObject();
}
writer.endArray();
final List priceInfos = commerceSession.getCartPriceInfo(null);
if (priceInfos != null && priceInfos.size() > 0) {
writer.key("totalPrice").value(priceInfos.get(0).getFormattedString());
writer.key("totalPriceFloat").value(priceInfos.get(0).getAmount());
} else {
log.error("Empty PriceInfo list for cart!");
writer.key("totalPrice").value("$0.00");
writer.key("totalPriceFloat").value(0);
}
writer.key("promotionsMap").array();
Map map = commerceSession.supportsClientsidePromotionResolution() ? clientPromotionsMap : serverPromotionsMap;
for (Map.Entry entry : map.entrySet()) {
writer.object();
{
writer.key("segments").value(entry.getValue());
writer.key("path").value(entry.getKey());
}
writer.endObject();
}
writer.endArray();
}
writer.endObject();
}
/**
* Writes order history trait data to JSON for the OrderHistoryMgr ClientContextStore.
*
* @param writer A JSONWriter instance
* @param orderHistory the placed orders
* @param services the order history trait data provider services
* @throws CommerceException
* @throws JSONException
*/
public static void writeOrderHistory(JSONWriter writer, PlacedOrderResult orderHistory,
OrderHistoryTraitDataProvider[] services) throws CommerceException, JSONException {
if (services == null) {
services = new OrderHistoryTraitDataProvider[0];
}
writer.object();
writer.key("traits").object();
Arrays.sort(services, new Comparator() {
@Override
public int compare(OrderHistoryTraitDataProvider o1, OrderHistoryTraitDataProvider o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (OrderHistoryTraitDataProvider trait : services) {
writer.key(trait.getIdentifier()).object();
writer.key("name").value(trait.getName());
writer.key("data");
Object data = trait.getTraitData(orderHistory);
if (data instanceof Map) {
writer.object();
@SuppressWarnings("unchecked")
Map map = (Map) data;
for (Map.Entry entry : map.entrySet()) {
writer.key(entry.getKey());
writer.value(entry.getValue());
}
writer.endObject();
} else if (data instanceof Collection){
writer.array();
for (Object o : (Collection) data) {
writer.value(o);
}
writer.endArray();
} else {
writer.value(data);
}
writer.endObject();
}
writer.endObject();
writer.endObject();
}
/**
* Returns a thumbnail for a card in the catalogs console.
* @param contextPath the request's contextPath
*/
public static String getCatalogCardThumbnail(String contextPath, Resource resource, PageManager pageManager) {
ValueMap properties = resource.adaptTo(ValueMap.class);
Page templatePage = null;
if (ResourceUtil.isA(resource, "commerce/components/catalog")) {
InheritanceValueMap blueprintProps = new HierarchyNodeInheritanceValueMap(resource);
templatePage = pageManager.getPage(blueprintProps.getInherited("templates/catalog", ""));
} else if (ResourceUtil.isA(resource, "commerce/components/section")) {
InheritanceValueMap blueprintProps = new HierarchyNodeInheritanceValueMap(resource);
templatePage = pageManager.getPage(blueprintProps.getInherited("templates/section", ""));
}
if (templatePage != null) {
String url = contextPath + templatePage.getPath() + ".thumb.319.319.png";
Calendar lastMod = templatePage.getProperties().get("image/file/jcr:content/jcr:lastModified", Calendar.class);
if (lastMod != null) {
url += "?ck=" + (lastMod.getTimeInMillis() / 1000);
}
return url;
} else {
String coverUrl = properties.get("coverUrl", String.class);
if (coverUrl != null) {
return coverUrl + ".thumb.319.319.png";
} else {
return contextPath + resource.getParent().getPath() + ".thumb.319.319.png";
}
}
}
/**
* Return a title suitable for a card in the touch-optimized GUI.
* @param resource
* @param pageManager
* @return
*/
public static String getCardTitle(Resource resource, PageManager pageManager) {
String title;
if (AbstractJcrProduct.isAProductOrVariant(resource)) {
String jcrTitle = resource.getValueMap().get(JcrConstants.JCR_TITLE, String.class);
if (StringUtils.isNotBlank(jcrTitle)) {
return jcrTitle;
}
// No distinct title found. Walk up the product hierarchy, prepending intermediate
// nodeNames until we get a distinct title.
title = resource.getName();
resource = resource.getParent();
while (resource != null) {
jcrTitle = resource.getValueMap().get(JcrConstants.JCR_TITLE, String.class);
if (StringUtils.isNotBlank(jcrTitle)) {
// found a distinct title; prepend it and we're done:
title = jcrTitle + " / " + title;
return title;
}
title = resource.getName() + " / " + title;
resource = resource.getParent();
}
return title;
}
Page page = pageManager.getPage(resource.getPath());
if (page != null) {
return page.getTitle();
}
Resource jcr_content = resource.getChild("jcr:content");
if (jcr_content != null) {
String jcrTitle = jcr_content.getValueMap().get(JcrConstants.JCR_TITLE, String.class);
if (StringUtils.isNotBlank(jcrTitle)) {
return jcrTitle;
}
}
String jcrTitle = resource.getValueMap().get(JcrConstants.JCR_TITLE, String.class);
if (StringUtils.isNotBlank(jcrTitle)) {
return jcrTitle;
}
// No author-supplied title; go with the node name.
title = resource.getName();
// Check to see if we're in what looks like a date hierarchy (or other type
// of numeric bucketing), and if so, add a bit more context.
if (title.matches("\\d+")) {
resource = resource.getParent();
while (resource.getName().matches("\\d+")) {
title = resource.getName() + "." + title;
resource = resource.getParent();
}
}
return title;
}
/**
* Return an externalized URL to a product's thumbnail image.
* @param contextPath the request's contextPath
*/
public static String getProductCardThumbnail(String contextPath, Product product) {
String thumbnail = product.getThumbnailUrl(319);
if (StringUtils.isNotEmpty(thumbnail)) {
return contextPath + thumbnail;
}
return null;
}
}