org.apache.nutch.searcher.response.json.JSONResponseWriter.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.nutch.searcher.response.json.JSONResponseWriter.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.nutch.searcher.response.json;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.nutch.searcher.Hit;
import org.apache.nutch.searcher.HitDetails;
import org.apache.nutch.searcher.Summary;
import org.apache.nutch.searcher.response.RequestUtils;
import org.apache.nutch.searcher.response.ResponseWriter;
import org.apache.nutch.searcher.response.SearchResults;

/**
 * A ResponseWriter implementation that returns search results in JSON format.
 */
public class JSONResponseWriter implements ResponseWriter {

    private String contentType = null;
    private Configuration conf;
    private int maxAgeInSeconds;
    private boolean prettyPrint = true;

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public Configuration getConf() {
        return conf;
    }

    public void setConf(Configuration conf) {
        this.conf = conf;
        this.maxAgeInSeconds = conf.getInt("searcher.response.maxage", 86400);
        this.prettyPrint = conf.getBoolean("searcher.response.prettyprint", true);
    }

    public void writeResponse(SearchResults results, HttpServletRequest request, HttpServletResponse response)
            throws IOException {

        // the function name, if any wrapping the JSON output
        String func = RequestUtils.getStringParameter(request, "func");

        // create the JSON object and add common values
        JSONObject jsonObj = new JSONObject();
        jsonObj.accumulate("query", results.getQuery());
        jsonObj.accumulate("lang", results.getLang());
        jsonObj.accumulate("sort", results.getSort());
        jsonObj.accumulate("reverse", results.isReverse());
        jsonObj.accumulate("start", results.getStart());
        jsonObj.accumulate("end", results.getEnd());
        jsonObj.accumulate("rows", results.getRows());
        jsonObj.accumulate("totalhits", results.getTotalHits());
        jsonObj.accumulate("withSummary", results.isWithSummary());

        String[] searchFields = results.getFields();
        Set<String> fieldSet = new HashSet<String>();
        if (searchFields != null && searchFields.length > 0) {
            jsonObj.accumulate("fields", StringUtils.join(searchFields, ","));
            for (int i = 0; i < searchFields.length; i++) {
                fieldSet.add(searchFields[i]);
            }
        }

        // add the documents from search hits
        JSONArray docsAr = new JSONArray();
        HitDetails[] details = results.getDetails();
        Hit[] hits = results.getHits();
        Summary[] summaries = results.getSummaries();
        for (int i = 0; i < details.length; i++) {

            // every document has an indexno and an indexdocno
            JSONObject result = new JSONObject();
            HitDetails detail = details[i];
            Hit hit = hits[i];
            result.accumulate("indexno", hit.getIndexNo());
            result.accumulate("indexkey", hit.getUniqueKey());

            // don't add summaries not including summaries
            if (summaries != null && results.isWithSummary()) {
                Summary summary = summaries[i];
                result.accumulate("summary", summary.toString());
            }

            // add the fields from hit details
            JSONObject fields = new JSONObject();
            for (int k = 0; k < detail.getLength(); k++) {
                String name = detail.getField(k);
                String[] values = detail.getValues(name);

                // if we specified fields to return, only return those fields
                if (fieldSet.size() == 0 || fieldSet.contains(name)) {
                    JSONArray valuesAr = new JSONArray();
                    for (int m = 0; m < values.length; m++) {
                        valuesAr.add(values[m]);
                    }
                    fields.accumulate(name, valuesAr);
                }
            }
            result.accumulate("fields", fields);
            docsAr.add(result);
        }

        jsonObj.accumulate("documents", docsAr);

        // pretty printing can be set through configuration, write out the wrapper
        // function if there is one
        StringBuilder builder = new StringBuilder();
        if (StringUtils.isNotBlank(func)) {
            builder.append(func + "(");
        }
        builder.append(prettyPrint ? jsonObj.toString(2) : jsonObj.toString());
        if (StringUtils.isNotBlank(func)) {
            builder.append(")");
        }

        // Cache control headers
        SimpleDateFormat sdf = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss 'GMT'");
        long relExpiresInMillis = System.currentTimeMillis() + (1000 * maxAgeInSeconds);
        response.setContentType(contentType);
        response.setHeader("Cache-Control", "max-age=" + maxAgeInSeconds);
        response.setHeader("Expires", sdf.format(relExpiresInMillis));

        // write out the content to the response
        response.getOutputStream().write(builder.toString().getBytes());
        response.flushBuffer();
    }

}