Package org.apache.solr.response

Source Code of org.apache.solr.response.VelocityResponseWriter

/**
* 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.solr.response;

import org.apache.solr.client.solrj.SolrResponse;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.SolrResponseBase;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.tools.generic.*;

import java.io.*;
import java.util.Properties;

public class VelocityResponseWriter implements QueryResponseWriter {

  // TODO: maybe pass this Logger to the template for logging from there?
//  private static final Logger log = LoggerFactory.getLogger(VelocityResponseWriter.class);

  public void write(Writer writer, SolrQueryRequest request, SolrQueryResponse response) throws IOException {
    VelocityEngine engine = getEngine(request)// TODO: have HTTP headers available for configuring engine

    Template template = getTemplate(engine, request);

    VelocityContext context = new VelocityContext();

    context.put("request", request);

    // Turn the SolrQueryResponse into a SolrResponse.
    // QueryResponse has lots of conveniences suitable for a view
    // Problem is, which SolrResponse class to use?
    // One patch to SOLR-620 solved this by passing in a class name as
    // as a parameter and using reflection and Solr's class loader to
    // create a new instance.  But for now the implementation simply
    // uses QueryResponse, and if it chokes in a known way, fall back
    // to bare bones SolrResponseBase.
    // TODO: Can this writer know what the handler class is?  With echoHandler=true it can get its string name at least
    SolrResponse rsp = new QueryResponse();
    NamedList<Object> parsedResponse = BinaryResponseWriter.getParsedResponse(request, response);
    try {
      rsp.setResponse(parsedResponse);

      // page only injected if QueryResponse works
      context.put("page", new PageTool(request, response))// page tool only makes sense for a SearchHandler request... *sigh*
    } catch (ClassCastException e) {
      // known edge case where QueryResponse's extraction assumes "response" is a SolrDocumentList
      // (AnalysisRequestHandler emits a "response")
      e.printStackTrace();
      rsp = new SolrResponseBase();
      rsp.setResponse(parsedResponse);
    }
    context.put("response", rsp);

    // Velocity context tools - TODO: make these pluggable
    context.put("esc", new EscapeTool());
    context.put("date", new ComparisonDateTool());
    context.put("list", new ListTool());
    context.put("math", new MathTool());
    context.put("number", new NumberTool());
    context.put("sort", new SortTool());

    context.put("engine", engine)// for $engine.resourceExists(...)

    String layout_template = request.getParams().get("v.layout");
    String json_wrapper = request.getParams().get("v.json");
    boolean wrap_response = (layout_template != null) || (json_wrapper != null);

    // create output, optionally wrap it into a json object
    if (wrap_response) {
      StringWriter stringWriter = new StringWriter();
      template.merge(context, stringWriter);

      if (layout_template != null) {
        context.put("content", stringWriter.toString());
        stringWriter = new StringWriter();
        try {
          engine.getTemplate(layout_template + ".vm").merge(context, stringWriter);
        } catch (Exception e) {
          throw new IOException(e.getMessage());
        }
      }

      if (json_wrapper != null) {
        writer.write(request.getParams().get("v.json") + "(");
        writer.write(getJSONWrap(stringWriter.toString()));
        writer.write(')');
      } else // using a layout, but not JSON wrapping
        writer.write(stringWriter.toString());
      }
    } else {
      template.merge(context, writer);
    }
  }

  private VelocityEngine getEngine(SolrQueryRequest request) {
    VelocityEngine engine = new VelocityEngine();
    String template_root = request.getParams().get("v.base_dir");
    File baseDir = new File(request.getCore().getResourceLoader().getConfigDir(), "velocity");
    if (template_root != null) {
      baseDir = new File(template_root);
    }
    engine.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, baseDir.getAbsolutePath());
    engine.setProperty("params.resource.loader.instance", new SolrParamResourceLoader(request));
    SolrVelocityResourceLoader resourceLoader =
        new SolrVelocityResourceLoader(request.getCore().getSolrConfig().getResourceLoader());
    engine.setProperty("solr.resource.loader.instance", resourceLoader);

    // TODO: Externalize Velocity properties
    engine.setProperty(VelocityEngine.RESOURCE_LOADER, "params,file,solr");
    String propFile = request.getParams().get("v.properties");
    try {
      if (propFile == null)
        engine.init();
      else {
        InputStream is = null;
        try {
          is = resourceLoader.getResourceStream(propFile);
          Properties props = new Properties();
          props.load(is);
          engine.init(props);
        }
        finally {
          if (is != null) is.close();
        }
      }
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }

    return engine;
  }

  private Template getTemplate(VelocityEngine engine, SolrQueryRequest request) throws IOException {
    Template template;

    String template_name = request.getParams().get("v.template");
    String qt = request.getParams().get("qt");
    String path = (String) request.getContext().get("path");
    if (template_name == null && path != null) {
      template_name = path;
    // TODO: path is never null, so qt won't get picked up  maybe special case for '/select' to use qt, otherwise use path?
    if (template_name == null && qt != null) {
      template_name = qt;
    }
    if (template_name == null) template_name = "index";
    try {
      template = engine.getTemplate(template_name + ".vm");
    } catch (Exception e) {
      throw new IOException(e.getMessage());
    }

    return template;
  }

  public String getContentType(SolrQueryRequest request, SolrQueryResponse response) {
    return request.getParams().get("v.contentType", "text/html;charset=UTF-8");
  }

  private String getJSONWrap(String xmlResult) {  // TODO: maybe noggit or Solr's JSON utilities can make this cleaner?
    // escape the double quotes and backslashes
    String replace1 = xmlResult.replaceAll("\\\\", "\\\\\\\\");
    replace1 = replace1.replaceAll("\\n", "\\\\n");
    replace1 = replace1.replaceAll("\\r", "\\\\r");
    String replaced = replace1.replaceAll("\"", "\\\\\"");
    // wrap it in a JSON object
    return "{\"result\":\"" + replaced + "\"}";
  }

  public void init(NamedList args) {
  }
}
TOP

Related Classes of org.apache.solr.response.VelocityResponseWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.