PromotionViewHandler.java 9.8 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.xss.XSSAPI
 *  com.day.cq.tagging.Tag
 *  com.day.cq.tagging.TagManager
 *  com.day.cq.wcm.api.Page
 *  com.day.cq.wcm.core.contentfinder.Hit
 *  com.day.cq.wcm.core.contentfinder.ViewHandler
 *  com.day.cq.wcm.core.contentfinder.ViewQuery
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Value
 *  javax.jcr.query.Row
 *  javax.jcr.query.RowIterator
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.jackrabbit.commons.query.GQL
 *  org.apache.jackrabbit.commons.query.GQL$Filter
 *  org.apache.jackrabbit.commons.query.GQL$ParserCallback
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.request.RequestPathInfo
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.commerce.impl.promotion;

import com.adobe.granite.xss.XSSAPI;
import com.day.cq.tagging.Tag;
import com.day.cq.tagging.TagManager;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.core.contentfinder.Hit;
import com.day.cq.wcm.core.contentfinder.ViewHandler;
import com.day.cq.wcm.core.contentfinder.ViewQuery;
import java.util.ArrayList;
import java.util.Collection;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;
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.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.commons.query.GQL;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
@Service
@Properties(value={@Property(name="service.description", value={"Handles the display of promotions in the content finders"}), @Property(name="sling.servlet.paths", value={"/bin/wcm/contentfinder/promotion/view"})})
public class PromotionViewHandler
extends ViewHandler {
    private static Logger log = LoggerFactory.getLogger(PromotionViewHandler.class);
    @Reference
    private XSSAPI xssAPI;
    private static final String NT_CQ_PAGE = "cq:Page";
    private static final String DEFAULT_START_PATH = "/content/campaigns";
    private static final String LAST_MOD_REL_PATH = "jcr:content/cq:lastModified";

    protected ViewQuery createQuery(SlingHttpServletRequest request, Session session, String queryString) throws RepositoryException {
        ParserCallback cb = new ParserCallback((TagManager)request.getResourceResolver().adaptTo(TagManager.class));
        GQL.parse((String)queryString, (Session)session, (GQL.ParserCallback)cb);
        StringBuilder gql = cb.getQuery();
        String path = cb.getStartPath();
        if (path == null) {
            RequestPathInfo pathInfo = request.getRequestPathInfo();
            String startPath = pathInfo.getSuffix() != null ? pathInfo.getSuffix() : "/content/campaigns";
            path = "path:\"" + startPath + "\"";
        }
        if (gql.length() > 0) {
            gql.append(" ");
        }
        gql.append(path).append(" ");
        String limit = cb.getLimit();
        if (limit == null) {
            limit = request.getParameter("limit");
            limit = limit != null && !limit.equals("") ? "limit:" + limit : "limit:20";
        }
        gql.append(limit).append(" ");
        String type = cb.getType();
        if (type == null) {
            type = request.getParameter("type");
            if (type == null) {
                type = "cq:Page";
            }
            type = "type:\"" + type + "\"";
        }
        gql.append(type).append(" ");
        String order = cb.getOrder();
        if (order == null) {
            order = "order:-jcr:content/cq:lastModified";
        }
        gql.append(order).append(" ");
        return new GQLViewQuery(request, gql.toString(), session, this.xssAPI.getRequestSpecificAPI(request));
    }

    private static Hit createHit(Page page, String excerpt, XSSAPI xssAPI) throws RepositoryException {
        Hit hit = new Hit();
        hit.set("name", (Object)xssAPI.encodeForHTML(page.getName()));
        hit.set("path", (Object)page.getPath());
        hit.set("excerpt", (Object)xssAPI.filterHTML(excerpt));
        if (page.getTitle() != null) {
            hit.set("title", (Object)xssAPI.encodeForHTML(page.getTitle()));
        } else {
            hit.set("title", (Object)xssAPI.encodeForHTML(page.getName()));
        }
        return hit;
    }

    protected void bindXssAPI(XSSAPI xSSAPI) {
        this.xssAPI = xSSAPI;
    }

    protected void unbindXssAPI(XSSAPI xSSAPI) {
        if (this.xssAPI == xSSAPI) {
            this.xssAPI = null;
        }
    }

    private static class GQLViewQuery
    implements ViewQuery {
        private final SlingHttpServletRequest request;
        private final String queryStr;
        private final Session session;
        private final XSSAPI xssAPI;

        public GQLViewQuery(SlingHttpServletRequest request, String queryStr, Session session, XSSAPI xssAPI) {
            this.request = request;
            this.queryStr = queryStr;
            this.session = session;
            this.xssAPI = xssAPI;
        }

        public Collection<Hit> execute() {
            ArrayList<Hit> hits = new ArrayList<Hit>();
            ResourceResolver resolver = this.request.getResourceResolver();
            log.debug("executing GQL query: " + this.queryStr);
            RowIterator rows = GQL.execute((String)this.queryStr, (Session)this.session, (String)null, (GQL.Filter)new PromotionFilter(resolver));
            while (rows.hasNext()) {
                Row row = rows.nextRow();
                try {
                    Page page = (Page)resolver.getResource(row.getPath()).adaptTo(Page.class);
                    String excerpt = "";
                    try {
                        excerpt = row.getValue("rep:excerpt()").getString();
                    }
                    catch (Exception e) {
                        excerpt = "";
                    }
                    hits.add(PromotionViewHandler.createHit(page, excerpt, this.xssAPI));
                }
                catch (RepositoryException re) {
                    log.error("A repository error occurred", (Throwable)re);
                }
            }
            return hits;
        }
    }

    private static class ParserCallback
    implements GQL.ParserCallback {
        private StringBuilder query = new StringBuilder();
        private String startPath = null;
        private String type = null;
        private String limit = null;
        private String order = null;
        private TagManager tagMgr;

        public ParserCallback(TagManager tagMgr) {
            this.tagMgr = tagMgr;
        }

        public void term(String property, String value, boolean optional) throws RepositoryException {
            if (property.equals("path")) {
                this.startPath = "path:\"" + value + "\"";
                return;
            }
            if (property.equals("type")) {
                this.type = "type:\"" + value + "\"";
                return;
            }
            if (property.equals("limit")) {
                this.limit = "limit:\"" + value + "\"";
                return;
            }
            if (property.equals("order")) {
                this.order = "order:\"" + value + "\"";
                return;
            }
            if (optional) {
                this.query.append("OR ");
            }
            if (property.equals("tag")) {
                if (this.tagMgr == null) {
                    this.query.append("\"cq:tags\":\"");
                    this.query.append(value).append("\" ");
                } else {
                    Tag tag = this.tagMgr.resolve(value);
                    if (tag != null) {
                        this.query.append(tag.getGQLSearchExpression("cq:tags"));
                        this.query.append(" ");
                    } else {
                        this.query.append("\"cq:tags\":\"______invalid______\" ");
                    }
                }
            } else if (property.length() == 0) {
                this.query.append("\"").append(value).append("\"");
            } else {
                this.query.append("\"").append(property).append("\":");
                this.query.append("\"").append(value).append("\" ");
            }
        }

        public StringBuilder getQuery() {
            return this.query;
        }

        public String getStartPath() {
            return this.startPath;
        }

        public String getType() {
            return this.type;
        }

        public String getLimit() {
            return this.limit;
        }

        public String getOrder() {
            return this.order;
        }
    }

    private static class PromotionFilter
    implements GQL.Filter {
        ResourceResolver resolver;

        PromotionFilter(ResourceResolver resolver) {
            this.resolver = resolver;
        }

        public boolean include(Row row) throws RepositoryException {
            String path = row.getPath();
            Resource resource = this.resolver.getResource(path);
            if (resource == null) {
                return false;
            }
            Resource pageContent = resource.getChild("jcr:content");
            return pageContent != null && pageContent.isResourceType("commerce/components/promotion");
        }
    }

}