ProductFeedServiceImpl.java 6.29 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.cq.commerce.api.Product
 *  com.adobe.cq.commerce.common.CommerceHelper
 *  com.day.cq.commons.Filter
 *  com.day.cq.wcm.api.Page
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Workspace
 *  javax.jcr.query.Query
 *  javax.jcr.query.QueryManager
 *  javax.jcr.query.QueryResult
 *  org.apache.commons.lang.StringUtils
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.PropertyOption
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.resource.LoginException
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.commerce.pim.impl.productfeed;

import com.adobe.cq.commerce.api.Product;
import com.adobe.cq.commerce.common.CommerceHelper;
import com.adobe.cq.commerce.pim.api.ProductFeedService;
import com.adobe.cq.commerce.pim.impl.productfeed.ProductPageFilter;
import com.day.cq.commons.Filter;
import com.day.cq.wcm.api.Page;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Dictionary;
import java.util.Iterator;
import java.util.List;
import java.util.TimeZone;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyOption;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Service
@Component(metatype=1, label="Adobe CQ Commerce Product Feed Service", description="Generates a list of products based on a list of pages that have been rolled-out", immediate=1)
public class ProductFeedServiceImpl
implements ProductFeedService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ProductFeedServiceImpl.class);
    @Property(name="Feed generator algorithm", description="The algorithm used to generated the product feed", options={@PropertyOption(name="traversal", value="Path traversal"), @PropertyOption(name="query", value="Query")})
    private static final String CONFIG_KEY_ALGORITHM = "cq.commerce.productfeed.algorithm";
    private FeedAlgorithm algorithm;
    private static SimpleDateFormat dateFormat = null;

    protected void activate(ComponentContext context) throws LoginException {
        String alg = (String)context.getProperties().get("cq.commerce.productfeed.algorithm");
        this.algorithm = StringUtils.isEmpty((String)alg) ? FeedAlgorithm.TRAVERSAL : FeedAlgorithm.valueOf(alg.toUpperCase());
        LOGGER.debug("Algorithm is {}", (Object)this.algorithm.toString());
    }

    @Override
    public List<Product> getFullProductsList(Page root) throws RepositoryException {
        List<Product> products = null;
        products = this.algorithm.equals((Object)FeedAlgorithm.TRAVERSAL) ? this.getByTraversal(root, 0) : this.getByQuery(root, 0);
        return products;
    }

    @Override
    public List<Product> getIncrementalProductsList(Page root, long timestamp) throws RepositoryException {
        List<Product> products = null;
        products = this.algorithm == FeedAlgorithm.TRAVERSAL ? this.getByTraversal(root, timestamp) : this.getByQuery(root, timestamp);
        return products;
    }

    private List<Product> getByTraversal(Page root, long timestamp) {
        ArrayList<Product> products = new ArrayList<Product>();
        Iterator pageIterator = root.listChildren((Filter)new ProductPageFilter(timestamp), true);
        while (pageIterator.hasNext()) {
            Product prod = CommerceHelper.findCurrentProduct((Page)((Page)pageIterator.next()));
            products.add(prod);
        }
        return products;
    }

    private List<Product> getByQuery(Page root, long timestamp) throws RepositoryException {
        ArrayList<Product> products = new ArrayList<Product>();
        String rootPath = root.getPath();
        ResourceResolver resolver = root.getContentResource().getResourceResolver();
        StringBuilder queryString = new StringBuilder("SELECT * ");
        queryString.append("FROM [nt:unstructured] AS N ");
        queryString.append("WHERE ISDESCENDANTNODE(N,'").append(rootPath).append("') ");
        queryString.append(" AND N.[cq:lastModified] > CAST('").append(dateFormat.format(new Date(timestamp))).append("' as DATE)");
        Session jcrSession = (Session)resolver.adaptTo(Session.class);
        QueryManager qm = jcrSession.getWorkspace().getQueryManager();
        Query q = qm.createQuery(queryString.toString(), "JCR-SQL2");
        LOGGER.debug("Executing " + queryString.toString());
        NodeIterator iterator = q.execute().getNodes();
        while (iterator.hasNext()) {
            Node node = iterator.nextNode();
            Resource productResource = CommerceHelper.findProductResource((Resource)resolver.resolve(node.getPath()));
            if (productResource != null) {
                products.add((Product)productResource.adaptTo(Product.class));
                continue;
            }
            LOGGER.debug("Skipping {}", (Object)node.getPath());
        }
        return products;
    }

    static {
        int offset = TimeZone.getDefault().getOffset(System.currentTimeMillis()) / 1000 / 3600;
        String offsetString = String.valueOf(Math.abs(offset)) + ":00";
        if (offset / 10 < 1) {
            offsetString = "0" + offsetString;
        }
        offsetString = offset < 0 ? "-" + offsetString : "+" + offsetString;
        dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS" + offsetString);
    }

    private static enum FeedAlgorithm {
        TRAVERSAL,
        QUERY;
        

        private FeedAlgorithm() {
        }
    }

}