Wednesday, 18 May 2016

AEM Commerce Provider

If products are created within the /etc/commerce/products area they should be flagged with a cq:commerceProvider on the subfolder which holds them.

    /etc/commerce/products/andyProds
                                cq:commerceProvider = andyCommerceProvider
                                jcr:primaryType = sling:Folder

However, to see these products within the TouchUI commerce / products pages and to use the scaffolding to edit the values a commerceProvider is needed.

To create a simple commerceProvider is very straightforward and is documented below.

CommerceServiceFactory

This factory class just returns a CommerceService

package com.me.commerce;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;

import com.adobe.cq.commerce.api.CommerceService;
import com.adobe.cq.commerce.api.CommerceServiceFactory;
import com.adobe.cq.commerce.common.AbstractJcrCommerceServiceFactory;

/**
 * Specific implementation for the {@link CommerceServiceFactory} interface.
 */
@Component
@Service
@Properties(value = {
                @Property(name = "service.description", value = "Factory for implementation of the commerce service"),
                @Property(name = "commerceProvider", value = "meCommerceProvider", propertyPrivate = true)})
public class MeCommerceServiceFactory extends AbstractJcrCommerceServiceFactory implements CommerceServiceFactory
{

    /**
     * Create a new {@link MeCommerceService}.
     *
     * @param res The resource
     * @return The CommerceService found
     */
    @Override
    public CommerceService getCommerceService(final Resource res)
    {
        return new MeCommerceService(getServiceContext(), res);
    }
}

CommerceService

The CommerceService itself doesn't need to do much in our case apart from return a product.

package com.me.commerce;

import java.util.ArrayList;
import java.util.List;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;

import com.adobe.cq.commerce.api.CommerceConstants;
import com.adobe.cq.commerce.api.CommerceException;
import com.adobe.cq.commerce.api.CommerceService;
import com.adobe.cq.commerce.api.CommerceSession;
import com.adobe.cq.commerce.api.Product;
import com.adobe.cq.commerce.common.AbstractJcrCommerceService;
import com.adobe.cq.commerce.common.ServiceContext;

/**
 * This is the commerce service which is used by the Commerce API within AEM. The commerce-provider is a property that
 * is put on the base folder where the products are held.
 */
public class MeCommerceService extends AbstractJcrCommerceService implements CommerceService
{

    /**
     * Construct this MeCommerceService object.
     *
     * @param serviceContext The service context
     * @param resource The resource
     */
    public MeCommerceService(final ServiceContext serviceContext, final Resource resource)
    {
        super(serviceContext, resource);
    }

    /*
     * (non-Javadoc)
     * @see com.adobe.cq.commerce.api.CommerceService#getProduct(java.lang.String)
     */
    @Override
    public Product getProduct(final String path) throws CommerceException
    {
        final Resource resource = resolver.getResource(path);
        if (resource != null && MeCommerceProduct.isAProductOrVariant(resource))
        {
            return new MeCommerceProduct(resource);
        }
        return null;
    }

    /*
     * (non-Javadoc)
     * @see com.adobe.cq.commerce.api.CommerceService#isAvailable(java.lang.String)
     */
    @Override
    public boolean isAvailable(final String serviceType)
    {
        return CommerceConstants.SERVICE_COMMERCE.equals(serviceType);
    }

    /*
     * (non-Javadoc)
     * @see com.adobe.cq.commerce.api.CommerceService#login(org.apache.sling.api.SlingHttpServletRequest,
     * org.apache.sling.api.SlingHttpServletResponse)
     */
    @Override
    public CommerceSession login(final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws CommerceException
    {
        return null;
    }

    /*
     * (non-Javadoc)
     * @see com.adobe.cq.commerce.api.CommerceService#getCountries()
     */
    @Override
    public List<String> getCountries() throws CommerceException
    {
        final List<String> countries = new ArrayList<String>();
        countries.add("*");
        return countries;
    }

    /*
     * (non-Javadoc)
     * @see com.adobe.cq.commerce.api.CommerceService#getCreditCardTypes()
     */
    @Override
    public List<String> getCreditCardTypes() throws CommerceException
    {
        return new ArrayList<String>();
    }

    /*
     * (non-Javadoc)
     * @see com.adobe.cq.commerce.api.CommerceService#getOrderPredicates()
     */
    @Override
    public List<String> getOrderPredicates() throws CommerceException
    {
        return new ArrayList<String>();
    }
}

CommerceProduct

The commerce product doesn't need to do anything more than return the SKU which is a required field in the AEM commerce section.

package com.me.commerce;

import org.apache.sling.api.resource.Resource;

import com.adobe.cq.commerce.api.Product;
import com.adobe.cq.commerce.common.AbstractJcrProduct;

/**
 * The CommerceProduct needed for the products. This is part of the Commerce framework in AEM.
 */
public class MeCommerceProduct extends AbstractJcrProduct implements Product
{
    /**
     * The name of the identifier.
     */
    public static final String PN_IDENTIFIER = "identifier";

    /**
     * Construct this MeCommerceProduct object.
     *
     * @param resource The resource
     */
    public MeCommerceProduct(final Resource resource)
    {
        super(resource);
    }

    /*
     * (non-Javadoc)
     * @see com.adobe.cq.commerce.api.Product#getSKU()
     */
    @Override
    public String getSKU()
    {
        return getProperty(PN_IDENTIFIER, String.class);
    }
}





No comments:

Post a comment