All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.cq.commerce.common.AbstractJcrCommerceService Maven / Gradle / Ivy

There is a newer version: 6.5.21
Show newest version
/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2012 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.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;

import aQute.bnd.annotation.ConsumerType;
import com.adobe.cq.commerce.api.CommerceException;
import com.adobe.cq.commerce.api.CommerceQuery;
import com.adobe.cq.commerce.api.CommerceResult;
import com.adobe.cq.commerce.api.CommerceService;
import com.adobe.cq.commerce.api.CommerceSession;
import com.adobe.cq.commerce.api.PaymentMethod;
import com.adobe.cq.commerce.api.Product;
import com.adobe.cq.commerce.api.ShippingMethod;
import com.adobe.cq.commerce.api.collection.ProductCollection;
import com.adobe.cq.commerce.api.conf.CommerceBasePathsService;
import com.adobe.cq.commerce.api.promotion.Promotion;
import com.adobe.cq.commerce.api.promotion.PromotionManager;
import com.adobe.cq.commerce.api.promotion.Voucher;
import com.day.cq.wcm.api.Page;

/**
 * An abstract base class for implementing {@link CommerceService}s on top of the JCR repository.
 * See GeoCommerceServiceImpl for an example.
 */
@ConsumerType
public abstract class AbstractJcrCommerceService implements CommerceService {

    private final ServiceContext serviceContext;

    protected Map context;

    protected CommerceSearchProvider searchProvider;

    protected ResourceResolver resolver;

    protected AbstractJcrCommerceService(ServiceContext serviceContext, Resource resource) {
        this.context = new HashMap();
        this.serviceContext = serviceContext;
        this.resolver = resource.getResourceResolver();
    }

    /**
     * Returns the {@link ServiceContext} of this service.
     */
    public ServiceContext serviceContext() {
        return serviceContext;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setContext(Map context) {
        this.context = context;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Map getContext() {
        return context;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getServer() {
        return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isActivated(Product product) throws CommerceException {
        // always return true, since we're not dealing with a remote system
        return true;
    }

    /**
     * Default implementation assumes a JCR-based promotion (in which the path parameter is
     * truly a path).
     */
    @Override
    public Promotion getPromotion(String path) throws CommerceException {
        Resource resource = resolver.getResource(path);
        return resource != null ? resource.adaptTo(Promotion.class) : null;
    }

    /**
     * Default implementation assumes a JCR-based voucher (in which the path parameter is
     * truly a path).
     */
    @Override
    public Voucher getVoucher(String path) throws CommerceException {
        Resource resource = resolver.getResource(path);
        return resource != null ? resource.adaptTo(Voucher.class) : null;
    }

    /**
     * Default implementation assumes a JCR-based product collection (in which the path parameter is
     * truly a path).
     */
    @Override
    public ProductCollection getProductCollection(String path) throws CommerceException {
        Resource resource = resolver.getResource(path);
        return resource != null ? resource.adaptTo(ProductCollection.class) : null;
    }

    /**
     * Return a vendor record of a placed order for order administration.  The given locale
     * will be used to format prices.
     */
    public VendorJcrPlacedOrder getPlacedOrder(String orderId, Locale locale) {
        return new VendorJcrPlacedOrder(this, orderId, locale);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void catalogRolloutHook(Page blueprint, Page catalog) throws CommerceException {
        // NOP
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void sectionRolloutHook(Page blueprint, Page section) {
        // NOP
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void productRolloutHook(Product productData, Page productPage, Product productReference) throws CommerceException {
        // NOP
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public CommerceResult search(CommerceQuery query) throws CommerceException {
        if (searchProvider == null) {
            this.searchProvider = getSearchProvider();
        }

        if (searchProvider != null) {
            return searchProvider.search(query, this);
        }

        return null;
    }

    /**
     * Gets the search provider used in the current e-commerce implementation.  Subclasses may override
     * this method to plug-in a custom search provider implementation into the e-commerce system which
     * is not available via {@code CommerceSearchProviderManger}.
     */
    protected CommerceSearchProvider getSearchProvider() throws CommerceException {
        String providerName = getSearchProviderName();
        if (providerName != null) {
            return serviceContext.searchProviderManager.getSearchProvider(providerName);
        }

        return null;
    }

    /**
     * Gets the identifier of the search provider used in the current e-commerce implementation.
     * Subclasses should override this method to return the name of the custom search provider service
     * available in {@code CommerceSearchProviderManger}.
     */
    protected String getSearchProviderName() {
        return null;
    }

    /**
     * Returns a list of JCR-based promotions (ie, those known to the {@link PromotionManager}).
     */
    @Override
    public List getAvailablePromotions(ResourceResolver resourceResolver) throws CommerceException {
        PromotionManager promotionManager = resourceResolver.adaptTo(PromotionManager.class);
        return promotionManager.getAvailablePromotions(resourceResolver);
    }

    /**
     * Returns a list of available shipping methods.
     *
     * 

NB: not in the public interface. All public access should be through * {@link CommerceSession#getAvailableShippingMethods()}.

* *

Implementations which support session- or order-specific shipping methods should implement * {@link AbstractJcrCommerceSession#getAvailableShippingMethods()} instead.

* *

This implementation picks up the shipping methods from the JCR repository. Override to * specify a more-specific path or a particular ShippingMethod implementation.

*/ public List getAvailableShippingMethods() throws CommerceException { CommerceBasePathsService cbps = resolver.adaptTo(CommerceBasePathsService.class); return enumerateMethods(cbps.getShippingMethodsBasePath(), ShippingMethod.class); } /** * Returns a list of available payment methods. * *

NB: not in the public interface. All public access should be through * {@link CommerceSession#getAvailablePaymentMethods()}.

* *

Implementations which support session- or order-specific shipping methods should implement * {@link AbstractJcrCommerceSession#getAvailablePaymentMethods()} instead.

* *

This implementation picks up the payment methods from the JCR repository. Override to * specify a more-specific path or a particular PaymentMethod implementation.

*/ public List getAvailablePaymentMethods() throws CommerceException { CommerceBasePathsService cbps = resolver.adaptTo(CommerceBasePathsService.class); return enumerateMethods(cbps.getPaymentMethodsBasePath(), PaymentMethod.class); } /** * A helper class used to pick up {@link ShippingMethod}s, {@link PaymentMethod}s, etc. from * the repository. * @param path Folder from which to grab methods. * @param type An adaptTo type for the children of the folder. * @return A List of folder children which successfully adapted to the given type. */ protected List enumerateMethods(String path, Class type) { List methods = new ArrayList(); Resource dir = resolver.getResource(path); if (dir != null) { for (Resource resource : dir.getChildren()) { if (resource.getName().equals("jcr:content")) { continue; } T method = resource.adaptTo(type); if (method != null) { methods.add(method); } } } return methods; } /** * Instantiates a new cart entry. Override this method to supply custom extensions of {@link DefaultJcrCartEntry}. * @param index The index of the entry with the current cart or PlacedOrder. * @param product The product the new entry represents. * @param quantity The quantity. */ public DefaultJcrCartEntry newCartEntryImpl(int index, Product product, int quantity) { return new DefaultJcrCartEntry(index, product, quantity); } /** * * Converts the cart entry data to a String of the form "productPath;quantity;property1_name=property1_value\fproperty2_name=property2_value\f...". * * @param productPath the path of the product of the cart entry * @param quantity the number of products in the cart entry * @param properties other cart entry properties * * @return the String representation of cart entry data */ public String serializeCartEntryData(String productPath, int quantity, ValueMap properties) { StringBuilder sb = new StringBuilder(); sb.append(productPath).append(';').append(quantity); if (properties == null || properties.isEmpty()) { return sb.toString(); } else { sb.append(';'); for (ValueMap.Entry entry : properties.entrySet()) { String key = entry.getKey(); String value = String.valueOf(entry.getValue()); sb.append(key).append('=').append(value).append('\f'); } return sb.toString(); } } /** * Creates cart entry data from a String created with {@link #serializeCartEntryData(String, int, org.apache.sling.api.resource.ValueMap)}. * * @param str the serialized cart entry data * @return the an Object[] of length 3 which contains the Product object at index 0, * the quantity Integer object at index 1 and null or a {@code Map<String, Object>} holding the * other properties of the cart entry at index 2. * @throws CommerceException */ public Object[] deserializeCartEntryData(String str) throws CommerceException { Object[] entryData = new Object[3]; String[] entryFields = str.split(";", 3); Product product = getProduct(entryFields[0]); entryData[0] = product; int quantity = Integer.parseInt(entryFields[1]); entryData[1] = quantity; if (entryFields.length == 2) { return entryData; } Map properties = new HashMap(); String[] propertyFields = entryFields[2].split("\f"); for (String field : propertyFields) { if (StringUtils.isNotBlank(field)) { String[] property = field.split("=", 2); properties.put(property[0], property[1]); } } entryData[2] = properties; return entryData; } /* * ================================================================================================== * Deprecated methods. For backwards-compatibility only. * ================================================================================================== */ /** * @deprecated use the {@link #serviceContext} field instead. */ @Deprecated public AbstractJcrCommerceServiceFactory.Services services; /** * @deprecated since 5.6.1; use {@link #AbstractJcrCommerceService(ServiceContext)} instead. */ @Deprecated public AbstractJcrCommerceService(AbstractJcrCommerceServiceFactory.Services services) { this((ServiceContext) null); this.services = services; } /** * @deprecated since 5.6.200; use {@link #AbstractJcrCommerceService(ServiceContext, Resource)} * instead. */ @Deprecated protected AbstractJcrCommerceService(ServiceContext serviceContext) { this.context = new HashMap(); this.serviceContext = serviceContext; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy