QueryBuilderJsonServlet.java 6.95 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.servlet.Servlet
 *  javax.servlet.ServletException
 *  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.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.servlets.SlingAllMethodsServlet
 *  org.apache.sling.commons.json.JSONException
 *  org.apache.sling.commons.json.io.JSONWriter
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.search.impl.servlets;

import com.day.cq.search.Predicate;
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.Query;
import com.day.cq.search.QueryBuilder;
import com.day.cq.search.facets.Bucket;
import com.day.cq.search.facets.Facet;
import com.day.cq.search.impl.builder.QueryBuilderImpl;
import com.day.cq.search.result.Hit;
import com.day.cq.search.result.SearchResult;
import com.day.cq.search.writer.ResultHitWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Dictionary;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
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.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.io.JSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=0)
@Service(value={Servlet.class})
@Properties(value={@Property(name="sling.servlet.paths", value={"/bin/querybuilder.json"})})
public class QueryBuilderJsonServlet
extends SlingAllMethodsServlet {
    private static Logger log = LoggerFactory.getLogger(QueryBuilderJsonServlet.class);
    private static final String DEFAULT_HIT_WRITER = "simple";
    @Reference
    protected QueryBuilder queryBuilder;

    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        this.handleQuery(request, response);
    }

    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        this.handleQuery(request, response);
    }

    private void handleQuery(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException, ServletException {
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        Session session = (Session)request.getResourceResolver().adaptTo(Session.class);
        Query query = this.queryBuilder.createQuery(PredicateGroup.create(request.getParameterMap()), session);
        SearchResult result = query.getResult();
        try {
            PrintWriter out = response.getWriter();
            JSONWriter writer = new JSONWriter((Writer)out);
            writer.object();
            writer.key("success").value(true);
            writer.key("results").value((long)result.getHits().size());
            writer.key("total").value(result.getTotalMatches());
            writer.key("more").value(result.hasMore());
            writer.key("offset").value(result.getStartIndex());
            writer.key("hits").array();
            this.writeHits(result, writer, query);
            writer.endArray();
            if (query.getPredicates().getBool("facets")) {
                writer.key("facets").object();
                Map<String, Facet> facets = result.getFacets();
                for (String key : facets.keySet()) {
                    Facet facet = facets.get(key);
                    if (!facet.getContainsHit()) continue;
                    writer.key(key).array();
                    for (Bucket bucket : facet.getBuckets()) {
                        writer.object();
                        this.writeBucket(bucket, query, writer);
                        writer.endObject();
                    }
                    writer.endArray();
                }
                writer.endObject();
            }
            writer.endObject();
        }
        catch (JSONException e) {
            throw new ServletException("Error creating querybuilder json response", (Throwable)e);
        }
        catch (RepositoryException e) {
            throw new ServletException("Error reading result of querybuilder", (Throwable)e);
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    private void writeHits(SearchResult result, JSONWriter writer, Query query) throws JSONException, RepositoryException {
        QueryBuilderImpl qb = (QueryBuilderImpl)this.queryBuilder;
        PredicateGroup p = query.getPredicates();
        String name = p.get("hits", p.get("hitwriter", "simple"));
        ResultHitWriter hitWriter = qb.getComponent(ResultHitWriter.class, name, null);
        if (hitWriter == null) {
            log.warn("No ResultHitWriter found under '" + name + "', using default hit writer");
            hitWriter = qb.getComponent(ResultHitWriter.class, "simple", null);
            if (hitWriter == null) {
                log.error("Could not get default hit writer");
                return;
            }
        }
        try {
            for (Hit hit : result.getHits()) {
                writer.object();
                hitWriter.write(hit, writer, query);
                writer.endObject();
            }
        }
        finally {
            qb.releaseComponent(hitWriter);
        }
    }

    private void writeBucket(Bucket bucket, Query query, JSONWriter writer) throws JSONException {
        writer.key("value").value((Object)bucket.getValue());
        writer.key("count").value(bucket.getCount());
        writer.key("predicate").object();
        Map<String, String> map = bucket.getPredicate().getParameters();
        for (String k : map.keySet()) {
            writer.key(k).value((Object)map.get(k));
        }
        writer.endObject();
        Query newQuery = query.refine(bucket);
        writer.key("query").value((Object)newQuery.getPredicates().toURL());
    }

    protected void bindQueryBuilder(QueryBuilder queryBuilder) {
        this.queryBuilder = queryBuilder;
    }

    protected void unbindQueryBuilder(QueryBuilder queryBuilder) {
        if (this.queryBuilder == queryBuilder) {
            this.queryBuilder = null;
        }
    }
}