You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by eh...@apache.org on 2015/01/09 23:35:30 UTC
svn commit: r1650687 - in /lucene/dev/branches/branch_5x: ./ dev-tools/
dev-tools/idea/solr/contrib/velocity/ solr/ solr/contrib/
solr/contrib/velocity/src/java/org/apache/solr/response/
solr/contrib/velocity/src/resources/ solr/contrib/velocity/src/re...
Author: ehatcher
Date: Fri Jan 9 22:35:28 2015
New Revision: 1650687
URL: http://svn.apache.org/r1650687
Log:
SOLR-1723: VelocityResponseWriter improvements
SOLR-2035: Add a VelocityResponseWriter $resource tool for locale-specific string lookups.
Lots of VrW code cleanup, more and improved test cases.
(merged from r1650685 of trunk)
Added:
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/java/org/apache/solr/response/SolrVelocityLogger.java
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/java/org/apache/solr/response/SolrVelocityLogger.java
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/VM_global_library.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/resources/VM_global_library.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/_macros.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/resources/_macros.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/macros.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/resources/macros.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/macros.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/resources/velocity/macros.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/resources.properties
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/resources/velocity/resources.properties
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/file.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/test-files/velocity/file.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity-init.properties
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity-init.properties
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/VM_global_library.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/VM_global_library.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/foreach.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/foreach.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/layout.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/layout.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/locale.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/locale.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/macros.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/macros.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/test_macro_legacy_support.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/test_macro_legacy_support.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/test_macro_overridden.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/test_macro_overridden.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/test_macro_visible.vm
- copied unchanged from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/test_macro_visible.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test/velocity/
- copied from r1650685, lucene/dev/trunk/solr/contrib/velocity/src/test/velocity/
lucene/dev/branches/branch_5x/solr/server/solr/configsets/data_driven_schema_configs/conf/params.json
- copied unchanged from r1650685, lucene/dev/trunk/solr/server/solr/configsets/data_driven_schema_configs/conf/params.json
Removed:
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/VM_global_library.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/debug.vm
Modified:
lucene/dev/branches/branch_5x/ (props changed)
lucene/dev/branches/branch_5x/dev-tools/ (props changed)
lucene/dev/branches/branch_5x/dev-tools/idea/solr/contrib/velocity/velocity.iml
lucene/dev/branches/branch_5x/solr/ (props changed)
lucene/dev/branches/branch_5x/solr/CHANGES.txt (contents, props changed)
lucene/dev/branches/branch_5x/solr/contrib/ (props changed)
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/java/org/apache/solr/response/SolrParamResourceLoader.java
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/browse.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/error.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/footer.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/head.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/hit.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/layout.vm
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml
lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
lucene/dev/branches/branch_5x/solr/example/ (props changed)
lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/db/conf/solrconfig.xml
lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/mail/conf/solrconfig.xml
lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/rss/conf/solrconfig.xml
lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/solr/conf/solrconfig.xml
lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/tika/conf/solrconfig.xml
lucene/dev/branches/branch_5x/solr/server/ (props changed)
lucene/dev/branches/branch_5x/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml
lucene/dev/branches/branch_5x/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml
Modified: lucene/dev/branches/branch_5x/dev-tools/idea/solr/contrib/velocity/velocity.iml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/dev-tools/idea/solr/contrib/velocity/velocity.iml?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/dev-tools/idea/solr/contrib/velocity/velocity.iml (original)
+++ lucene/dev/branches/branch_5x/dev-tools/idea/solr/contrib/velocity/velocity.iml Fri Jan 9 22:35:28 2015
@@ -6,8 +6,10 @@
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/test" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/src/test/velocity" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test-files" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/resources" type="java-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
Modified: lucene/dev/branches/branch_5x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/CHANGES.txt?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_5x/solr/CHANGES.txt Fri Jan 9 22:35:28 2015
@@ -242,6 +242,9 @@ New Features
* SOLR-6766: Expose HdfsDirectoryFactory Block Cache statistics via JMX.
(Mike Drob, Mark Miller)
+
+* SOLR-2035: Add a VelocityResponseWriter $resource tool for locale-specific string lookups.
+ (Erik Hatcher)
Bug Fixes
@@ -602,6 +605,8 @@ Other Changes
* SOLR-6932: All HttpClient ConnectionManagers and SolrJ clients should always be shutdown
in tests and regular code. (Mark Miller)
+* SOLR-1723: VelocityResponseWriter improvements (Erik Hatcher)
+
================== 4.10.3 ==================
Bug Fixes
Modified: lucene/dev/branches/branch_5x/solr/contrib/velocity/src/java/org/apache/solr/response/SolrParamResourceLoader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/contrib/velocity/src/java/org/apache/solr/response/SolrParamResourceLoader.java?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/contrib/velocity/src/java/org/apache/solr/response/SolrParamResourceLoader.java (original)
+++ lucene/dev/branches/branch_5x/solr/contrib/velocity/src/java/org/apache/solr/response/SolrParamResourceLoader.java Fri Jan 9 22:35:28 2015
@@ -31,6 +31,8 @@ import java.util.Iterator;
import java.util.Map;
public class SolrParamResourceLoader extends ResourceLoader {
+ public static final String TEMPLATE_PARAM_PREFIX = VelocityResponseWriter.TEMPLATE + ".";
+
private Map<String,String> templates = new HashMap<>();
public SolrParamResourceLoader(SolrQueryRequest request) {
super();
@@ -44,8 +46,8 @@ public class SolrParamResourceLoader ext
while (names.hasNext()) {
String name = names.next();
- if (name.startsWith("v.template.")) {
- templates.put(name.substring(11) + ".vm",params.get(name));
+ if (name.startsWith(TEMPLATE_PARAM_PREFIX)) {
+ templates.put(name.substring(TEMPLATE_PARAM_PREFIX.length()) + VelocityResponseWriter.TEMPLATE_EXTENSION,params.get(name));
}
}
}
Modified: lucene/dev/branches/branch_5x/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java (original)
+++ lucene/dev/branches/branch_5x/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java Fri Jan 9 22:35:28 2015
@@ -17,46 +17,181 @@
package org.apache.solr.response;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Locale;
import java.util.Properties;
+import java.util.ResourceBundle;
+import org.apache.hadoop.util.StringUtils;
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.params.CommonParams;
import org.apache.solr.common.util.NamedList;
+import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.util.plugin.SolrCoreAware;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
+import org.apache.velocity.tools.ConversionUtils;
import org.apache.velocity.tools.generic.ComparisonDateTool;
import org.apache.velocity.tools.generic.DisplayTool;
import org.apache.velocity.tools.generic.EscapeTool;
import org.apache.velocity.tools.generic.ListTool;
import org.apache.velocity.tools.generic.MathTool;
import org.apache.velocity.tools.generic.NumberTool;
+import org.apache.velocity.tools.generic.ResourceTool;
import org.apache.velocity.tools.generic.SortTool;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-public class VelocityResponseWriter implements QueryResponseWriter {
+public class VelocityResponseWriter implements QueryResponseWriter, SolrCoreAware {
+ // init param names, these are _only_ loaded at init time (no per-request control of these)
+ // - multiple different named writers could be created with different init params
+ public static final String TEMPLATE_BASE_DIR = "template.base.dir";
+ public static final String PARAMS_RESOURCE_LOADER_ENABLED = "params.resource.loader.enabled";
+ public static final String SOLR_RESOURCE_LOADER_ENABLED = "solr.resource.loader.enabled";
+ public static final String PROPERTIES_FILE = "init.properties.file";
+
+ // request param names
+ public static final String TEMPLATE = "v.template";
+ public static final String LAYOUT = "v.layout";
+ public static final String LAYOUT_ENABLED = "v.layout.enabled";
+ public static final String CONTENT_TYPE = "v.contentType";
+ public static final String JSON = "v.json";
+ public static final String LOCALE = "v.locale";
+
+ public static final String TEMPLATE_EXTENSION = ".vm";
+ public static final String DEFAULT_CONTENT_TYPE = "text/html;charset=UTF-8";
+
+ private File fileResourceLoaderBaseDir;
+ private boolean paramsResourceLoaderEnabled;
+ private boolean solrResourceLoaderEnabled;
+ private String initPropertiesFileName; // used just to hold from init() to inform()
+
+ private static final Logger log = LoggerFactory.getLogger(VelocityResponseWriter.class);
+ private static final SolrVelocityLogger velocityLogger = new SolrVelocityLogger(log);
+ private Properties velocityInitProps = new Properties();
- // TODO: maybe pass this Logger to the template for logging from there?
-// private static final Logger log = LoggerFactory.getLogger(VelocityResponseWriter.class);
+ @Override
+ public void init(NamedList args) {
+ fileResourceLoaderBaseDir = null;
+ String templateBaseDir = (String) args.get(TEMPLATE_BASE_DIR);
+
+ if (templateBaseDir != null && !templateBaseDir.isEmpty()) {
+ fileResourceLoaderBaseDir = new File(templateBaseDir).getAbsoluteFile();
+ if (!fileResourceLoaderBaseDir.exists()) { // "*not* exists" condition!
+ log.warn(TEMPLATE_BASE_DIR + " specified does not exist: " + fileResourceLoaderBaseDir);
+ fileResourceLoaderBaseDir = null;
+ } else {
+ if (!fileResourceLoaderBaseDir.isDirectory()) { // "*not* a directory" condition
+ log.warn(TEMPLATE_BASE_DIR + " specified is not a directory: " + fileResourceLoaderBaseDir);
+ fileResourceLoaderBaseDir = null;
+ }
+ }
+ }
+
+ // params resource loader: off by default
+ Boolean prle = args.getBooleanArg(PARAMS_RESOURCE_LOADER_ENABLED);
+ paramsResourceLoaderEnabled = (null == prle ? false : prle);
+
+ // solr resource loader: on by default
+ Boolean srle = args.getBooleanArg(SOLR_RESOURCE_LOADER_ENABLED);
+ solrResourceLoaderEnabled = (null == srle ? true : srle);
+
+ initPropertiesFileName = (String) args.get(PROPERTIES_FILE);
+ }
+
+ @Override
+ public void inform(SolrCore core) {
+ // need to leverage SolrResourceLoader, so load init.properties.file here instead of init()
+ if (initPropertiesFileName != null) {
+ InputStream is = null;
+ try {
+ velocityInitProps.load(new InputStreamReader(core.getResourceLoader().openResource(initPropertiesFileName), StandardCharsets.UTF_8));
+ } catch (IOException e) {
+ log.warn("Error loading " + PROPERTIES_FILE + " specified property file: " + initPropertiesFileName, e);
+ }
+ }
+ }
+
+ @Override
+ public String getContentType(SolrQueryRequest request, SolrQueryResponse response) {
+ return request.getParams().get(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
+ }
@Override
public void write(Writer writer, SolrQueryRequest request, SolrQueryResponse response) throws IOException {
- VelocityEngine engine = getEngine(request); // TODO: have HTTP headers available for configuring engine
+ VelocityEngine engine = createEngine(request); // TODO: have HTTP headers available for configuring engine
Template template = getTemplate(engine, request);
+ VelocityContext context = createContext(request, response);
+ context.put("engine", engine); // for $engine.resourceExists(...)
+
+ String layoutTemplate = request.getParams().get(LAYOUT);
+ boolean layoutEnabled = request.getParams().getBool(LAYOUT_ENABLED, true) && layoutTemplate != null;
+
+ String jsonWrapper = request.getParams().get(JSON);
+ boolean wrapResponse = layoutEnabled || jsonWrapper != null;
+
+ // create output
+ if (!wrapResponse) {
+ // straight-forward template/context merge to output
+ template.merge(context, writer);
+ }
+ else {
+ // merge to a string buffer, then wrap with layout and finally as JSON
+ StringWriter stringWriter = new StringWriter();
+ template.merge(context, stringWriter);
+
+ if (layoutEnabled) {
+ context.put("content", stringWriter.toString());
+ stringWriter = new StringWriter();
+ try {
+ engine.getTemplate(layoutTemplate + TEMPLATE_EXTENSION).merge(context, stringWriter);
+ } catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ if (jsonWrapper != null) {
+ writer.write(jsonWrapper + "(");
+ writer.write(getJSONWrap(stringWriter.toString()));
+ writer.write(')');
+ } else { // using a layout, but not JSON wrapping
+ writer.write(stringWriter.toString());
+ }
+ }
+ }
+
+ private VelocityContext createContext(SolrQueryRequest request, SolrQueryResponse response) {
VelocityContext context = new VelocityContext();
context.put("request", request);
+ // Register useful Velocity "tools"
+ 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("display", new DisplayTool());
+ context.put("resource", new SolrVelocityResourceTool(
+ request.getCore().getSolrConfig().getResourceLoader().getClassLoader(),
+ request.getParams().get(LOCALE)));
+
// Turn the SolrQueryResponse into a SolrResponse.
// QueryResponse has lots of conveniences suitable for a view
// Problem is, which SolrResponse class to use?
@@ -65,14 +200,15 @@ public class VelocityResponseWriter impl
// 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
+ // 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*
+ context.put("page", new PageTool(request, response)); // page tool only makes sense for a SearchHandler request
+ context.put("debug",((QueryResponse)rsp).getDebugMap());
} catch (ClassCastException e) {
// known edge case where QueryResponse's extraction assumes "response" is a SolrDocumentList
// (AnalysisRequestHandler emits a "response")
@@ -81,81 +217,69 @@ public class VelocityResponseWriter impl
}
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("display", new DisplayTool());
-
- 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);
- }
+ return context;
}
- private VelocityEngine getEngine(SolrQueryRequest request) {
+ private VelocityEngine createEngine(SolrQueryRequest request) {
VelocityEngine engine = new VelocityEngine();
- engine.setProperty("params.resource.loader.instance", new SolrParamResourceLoader(request));
- SolrVelocityResourceLoader resourceLoader =
- new SolrVelocityResourceLoader(request.getCore().getSolrConfig().getResourceLoader());
- engine.setProperty("solr.resource.loader.instance", resourceLoader);
- engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "params,solr");
+ // route all Velocity logging through Solr's logging facility
+ engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, velocityLogger);
- // TODO: Externalize Velocity properties
- String propFile = request.getParams().get("v.properties");
- try {
- Properties props = new Properties();
- // Don't create a separate velocity log file by default.
- props.put(RuntimeConstants.RUNTIME_LOG, "");
-
- if (propFile == null) {
- engine.init(props);
- } else {
- InputStream is = null;
- try {
- is = resourceLoader.getResourceStream(propFile);
- props.load(new InputStreamReader(is, StandardCharsets.UTF_8));
- engine.init(props);
- }
- finally {
- if (is != null) is.close();
- }
- }
+ // Set some engine properties that improve the experience
+ // - these could be considered in the future for parameterization, but can also be overridden by using
+ // the init.properties.file setting. (TODO: add a test for this)
+
+ // load the built-in _macros.vm first, then load VM_global_library.vm for legacy (pre-5.0) support,
+ // and finally allow macros.vm to have the final say and override anything defined in the preceding files.
+ engine.setProperty(RuntimeConstants.VM_LIBRARY, "_macros.vm,VM_global_library.vm,macros.vm");
+
+ // Standard templates autoload, but not the macro one(s), by default, so let's just make life
+ // easier, and consistent, for macro development too.
+ engine.setProperty(RuntimeConstants.VM_LIBRARY_AUTORELOAD, "true");
+
+ /*
+ Set up Velocity resource loader(s)
+ terminology note: "resource loader" is overloaded here, there is Solr's resource loader facility for plugins,
+ and there are Velocity template resource loaders. It's confusing, they overlap: there is a Velocity resource
+ loader that loads templates from Solr's resource loader (SolrVelocityResourceLoader).
+
+ The Velocity resource loader order is [params,][file,][solr], intentionally ordered in this manner, and each
+ one optional and individually enable-able. By default, only "solr" (resource loader) is used, parsing templates
+ from a velocity/ sub-tree in either the classpath or under conf/.
+
+ A common usage would be to enable the file template loader, keeping the solr loader enabled; the Velocity resource
+ loader path would then be "file,solr" (params is disabled by default). The basic browse templates are built into
+ this plugin, but can be individually overridden by placing a same-named template in the template.base.dir specified
+ directory.
+ */
+ ArrayList<String> loaders = new ArrayList<String>();
+ if (paramsResourceLoaderEnabled) {
+ loaders.add("params");
+ engine.setProperty("params.resource.loader.instance", new SolrParamResourceLoader(request));
}
- catch (Exception e) {
- throw new RuntimeException(e);
+ if (fileResourceLoaderBaseDir != null) {
+ loaders.add("file");
+ engine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, fileResourceLoaderBaseDir.getAbsolutePath());
}
+ if (solrResourceLoaderEnabled) {
+ // The solr resource loader serves templates under a velocity/ subtree from <lib>, conf/,
+ // or SolrCloud's configuration tree. Or rather the other way around, other resource loaders are rooted
+ // from the top, whereas this is velocity/ sub-tree rooted.
+ loaders.add("solr");
+ engine.setProperty("solr.resource.loader.instance", new SolrVelocityResourceLoader(request.getCore().getSolrConfig().getResourceLoader()));
+ }
+
+ // Always have the built-in classpath loader. This is needed when using VM_LIBRARY macros, as they are required
+ // to be present if specified, and we want to have a nice macros facility built-in for users to use easily, and to
+ // extend in custom ways.
+ loaders.add("builtin");
+ engine.setProperty("builtin.resource.loader.instance", new ClasspathResourceLoader());
+
+ engine.setProperty(RuntimeConstants.RESOURCE_LOADER, StringUtils.join(",", loaders));
+
+ // bring in any custom properties too
+ engine.init(velocityInitProps);
return engine;
}
@@ -163,18 +287,19 @@ public class VelocityResponseWriter impl
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 templateName = request.getParams().get(TEMPLATE);
+
+ String qt = request.getParams().get(CommonParams.QT);
String path = (String) request.getContext().get("path");
- if (template_name == null && path != null) {
- template_name = path;
+ if (templateName == null && path != null) {
+ templateName = 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 (templateName == null && qt != null) {
+ templateName = qt;
}
- if (template_name == null) template_name = "index";
+ if (templateName == null) templateName = "index";
try {
- template = engine.getTemplate(template_name + ".vm");
+ template = engine.getTemplate(templateName + TEMPLATE_EXTENSION);
} catch (Exception e) {
throw new IOException(e.getMessage());
}
@@ -182,12 +307,7 @@ public class VelocityResponseWriter impl
return template;
}
- @Override
- 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?
+ private String getJSONWrap(String xmlResult) { // 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");
@@ -197,7 +317,34 @@ public class VelocityResponseWriter impl
return "{\"result\":\"" + replaced + "\"}";
}
- @Override
- public void init(NamedList args) {
+ // see: http://svn.apache.org/repos/asf/velocity/tools/branches/2.0.x/src/main/java/org/apache/velocity/tools/generic/ResourceTool.java
+ private class SolrVelocityResourceTool extends ResourceTool {
+
+ private final Locale locale;
+ private ClassLoader solrClassLoader;
+
+ public SolrVelocityResourceTool(ClassLoader cl, String localeString) {
+ this.solrClassLoader = cl;
+ Locale l = toLocale(localeString);
+ this.locale = (l == null ? Locale.ROOT : l);
+ }
+
+ @Override
+ protected ResourceBundle getBundle(String baseName, Object loc) {
+ // resource bundles for this tool must be in velocity "package"
+ return ResourceBundle.getBundle("velocity." + baseName, locale, solrClassLoader);
+ }
+
+ // Why did Velocity Tools make this private? Copied from ResourceTools.java
+ private Locale toLocale(Object obj) {
+ if (obj == null) {
+ return null;
+ }
+ if (obj instanceof Locale) {
+ return (Locale) obj;
+ }
+ String s = String.valueOf(obj);
+ return ConversionUtils.toLocale(s);
+ }
}
}
Modified: lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/browse.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/browse.vm?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/browse.vm (original)
+++ lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/browse.vm Fri Jan 9 22:35:28 2015
@@ -1,5 +1,3 @@
-#set($params = $request.params)
-
## Show Error Message, if any
<div class="error">
#parse("error.vm")
@@ -7,11 +5,11 @@
<div class="query-box">
<form id="query-form" action="#{url_for_home}" method="GET">
- Find:
- <input type="text" id="q" name="q" value="$!esc.html($params.get('q'))"/>
+ $resource.find:
+ <input type="text" id="q" name="q" value="$!esc.html($request.params.get('q'))"/>
<input type="submit"/>
- #if($request.params.get('debugQuery'))
+ #if($debug) ## TODO: this would automatically happen when arbitrary parameters are kept on URLs
<input type="hidden" name="debug" value="true"/>
#end
#foreach($fq in $request.params.getParams('fq'))
@@ -19,7 +17,7 @@
#end
<div class="constraints">
- #foreach($fq in $params.getParams('fq'))
+ #foreach($fq in $request.params.getParams('fq'))
#set($previous_fq_count=$velocityCount - 1)
#if($fq != '')
>
@@ -29,7 +27,7 @@
</div>
<div class="parsed_query_header">
- #if($request.params.get('debugQuery'))
+ #if($debug)
<a href="#" onclick='jQuery(this).siblings("div").toggle(); return false;'>toggle parsed query</a>
<div class="parsed_query" style="display:none">$response.response.debug.parsedquery</div>
#end
@@ -46,11 +44,10 @@
<span>
<span class="results-found">$page.results_found</span>
results found in
- ${response.responseHeader.QTime} ms
+ ${response.responseHeader.QTime}ms
</span>
- Page <span class="page-num">$page.current_page_number</span>
- of <span class="page-count">$page.page_count</span>
+ $resource.page_of.insert($page.current_page_number,$page.page_count)
</div>
## Render Results, actual matching docs
@@ -59,13 +56,12 @@
</div>
<div class="pagination">
- #link_to_previous_page("previous")
+ #link_to_previous_page
<span class="results-found">$page.results_found</span>
results found.
- Page <span class="page-num">$page.current_page_number</span>
- of <span class="page-count">$page.page_count</span>
+ $resource.page_of.insert($page.current_page_number,$page.page_count)
- #link_to_next_page("next")
+ #link_to_next_page
</div>
Modified: lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/error.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/error.vm?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/error.vm (original)
+++ lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/error.vm Fri Jan 9 22:35:28 2015
@@ -1,10 +1,3 @@
-#**
- * Show Error Message, if any
- *#
-
-## Show Error Message, if any
-## Usually rendered inside div class=error
-
#if( $response.response.error.code )
<h1>ERROR $response.response.error.code</h1>
$response.response.error.msg
Modified: lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/footer.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/footer.vm?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/footer.vm (original)
+++ lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/footer.vm Fri Jan 9 22:35:28 2015
@@ -2,14 +2,14 @@
<div>
<span>Options:</span>
- #if($request.params.get('debugQuery'))
+ #if($debug)
<a href="#url_for_home?#q#if($list.size($request.params.getParams('fq')) > 0)&#fqs($request.params.getParams('fq'))#end">
disable debug</a>
#else
<a href="#url_for_lens&debug=true&fl=*,score">enable debug</a>
#end
-
- <a href="#url_for_lens&wt=xml#if($request.params.get('debugQuery'))&debug=true#end">XML results</a>
+ <a href="#url_for_lens&wt=xml#if($debug)&debug=true#end">XML results</a> ## TODO: Add links for other formats, maybe dynamically?
</div>
Modified: lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/head.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/head.vm?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/head.vm (original)
+++ lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/head.vm Fri Jan 9 22:35:28 2015
@@ -3,9 +3,12 @@
*#
<title>Solr browse: #core_name</title>
+
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+
<link rel="icon" type="image/x-icon" href="#{url_root}/img/favicon.ico"/>
<link rel="shortcut icon" type="image/x-icon" href="#{url_root}/img/favicon.ico"/>
+
<script type="text/javascript" src="#{url_root}/js/lib/jquery-1.7.2.min.js"></script>
<style>
@@ -17,17 +20,6 @@
#head{
width: 100%;
}
- .array-field {
- border: 2px solid #474747;
- background: #FFE9D8;
- padding: 5px;
- margin: 5px;
- }
-
- .array-field-list li {
- list-style: circle;
- margin-left: 20px;
- }
.parsed_query_header {
font-family: Helvetica, Arial, sans-serif;
@@ -47,7 +39,11 @@
}
a {
- color: #43a4b1;
+ color: #305CB3;
+ }
+
+ em {
+ color: #FF833D;
}
.facets {
@@ -61,7 +57,7 @@
}
.facets h2 {
- background: #EA897E;
+ background: #D9411E;
padding: 2px 5px;
}
@@ -82,18 +78,9 @@
font-weight: bold;
}
- .highlight {
- color: white;
- background-color: gray;
- border: 1px black solid;
- }
-
- .highlight-box {
- margin-left: 15px;
- }
-
.field-name {
font-weight: bold;
+ // align="right" valign="top"
}
.highlighted-facet-field {
Modified: lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/hit.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/hit.vm?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/hit.vm (original)
+++ lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/hit.vm Fri Jan 9 22:35:28 2015
@@ -1,24 +1,27 @@
-#set($docId = $doc.getFieldValue('id'))
+#set($docId = $doc.getFirstValue($request.schema.uniqueKeyField.name))
+
<div class="result-document">
<table>
#foreach( $fieldName in $doc.fieldNames )
- #foreach( $value in $doc.getFieldValues($fieldName) )
<tr>
- <th align="right" valign="top">
- #if( $foreach.count == 1 )
- $fieldName:
- #end
+ <th align="right" valign="top" style="field-name">
+ $esc.html($fieldName):
</th>
<td align="left" valign="top">
- $esc.html($value) <br/>
+ #field($fieldName)
</td>
</tr>
- #end
#end
</table>
+ #if($debug)
+ <a href="#" onclick='jQuery(this).siblings("pre").toggle(); return false;'>toggle explain</a>
+ <pre style="display:none">
+ $response.getExplainMap().get($docId)
+ </pre>
+ #end
</div>
Modified: lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/layout.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/layout.vm?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/layout.vm (original)
+++ lucene/dev/branches/branch_5x/solr/contrib/velocity/src/resources/velocity/layout.vm Fri Jan 9 22:35:28 2015
@@ -5,7 +5,7 @@
<body>
<div id="admin"><a href="#url_root/#/#core_name">Solr Admin</a></div>
<div id="head">
- <a href="#url_for_home#if($request.params.get('debugQuery'))?debugQuery=true#end"><img src="#{url_root}/img/solr.svg" id="logo"/></a>
+ <a href="#url_for_home#if($debug)?debug=true#end"><img src="#{url_root}/img/solr.svg" id="logo"/></a>
</div>
<div id="content">
Modified: lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml (original)
+++ lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/solrconfig.xml Fri Jan 9 22:35:28 2015
@@ -16,65 +16,12 @@
limitations under the License.
-->
-<!--
- For more details about configurations options that may appear in
- this file, see http://wiki.apache.org/solr/SolrConfigXml.
--->
<config>
<luceneMatchVersion>${tests.luceneMatchVersion:LATEST}</luceneMatchVersion>
- <indexConfig>
- <useCompoundFile>${useCompoundFile:false}</useCompoundFile>
- </indexConfig>
-
- <lib dir="../../contrib/velocity/lib" />
- <lib dir="../../dist/" regex="solr-velocity-\d.*\.jar" />
- <dataDir>${solr.data.dir:}</dataDir>
-
-
- <directoryFactory name="DirectoryFactory"
- class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>
-
- <updateHandler class="solr.DirectUpdateHandler2">
- </updateHandler>
-
- <query>
- <maxBooleanClauses>1024</maxBooleanClauses>
- <filterCache class="solr.FastLRUCache"
- size="512"
- initialSize="512"
- autowarmCount="0"/>
- <queryResultCache class="solr.LRUCache"
- size="512"
- initialSize="512"
- autowarmCount="0"/>
- <documentCache class="solr.LRUCache"
- size="512"
- initialSize="512"
- autowarmCount="0"/>
- <enableLazyFieldLoading>true</enableLazyFieldLoading>
-
- <queryResultWindowSize>20</queryResultWindowSize>
- <queryResultMaxDocsCached>200</queryResultMaxDocsCached>
- <listener event="newSearcher" class="solr.QuerySenderListener">
- <arr name="queries">
- </arr>
- </listener>
- <listener event="firstSearcher" class="solr.QuerySenderListener">
- <arr name="queries">
- <lst>
- <str name="q">static firstSearcher warming in solrconfig.xml</str>
- </lst>
- </arr>
- </listener>
- <useColdSearcher>false</useColdSearcher>
- <maxWarmingSearchers>2</maxWarmingSearchers>
-
- </query>
- <requestDispatcher handleSelect="true" >
- <requestParsers enableRemoteStreaming="true"
- multipartUploadLimitInKB="2048000" />
- <httpCaching never304="true" />
- </requestDispatcher>
+
+ <!--<lib dir="../../contrib/velocity/lib" />-->
+ <!--<lib dir="../../dist/" regex="solr-velocity-\d.*\.jar" />-->
+
<requestHandler name="search" class="solr.SearchHandler" default="true">
<lst name="defaults">
@@ -83,13 +30,9 @@
</lst>
</requestHandler>
- <requestHandler name="/update" class="solr.UpdateRequestHandler" />
-
<queryResponseWriter name="velocity" class="solr.VelocityResponseWriter"/>
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
-
+ <queryResponseWriter name="velocityWithInitProps" class="solr.VelocityResponseWriter">
+ <str name="init.properties.file">velocity-init.properties</str>
+ </queryResponseWriter>
</config>
Modified: lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java (original)
+++ lucene/dev/branches/branch_5x/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java Fri Jan 9 22:35:28 2015
@@ -18,27 +18,39 @@
package org.apache.solr.velocity;
import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.util.NamedList;
import org.apache.solr.response.QueryResponseWriter;
+import org.apache.solr.response.SolrParamResourceLoader;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.response.VelocityResponseWriter;
import org.apache.solr.request.SolrQueryRequest;
import org.junit.BeforeClass;
import org.junit.Test;
+import java.io.IOException;
import java.io.StringWriter;
public class VelocityResponseWriterTest extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig.xml", "schema.xml", getFile("velocity/solr").getAbsolutePath());
+ System.out.println(getFile("velocity/solr").getAbsolutePath());
}
@Test
- public void testCustomParamTemplate() throws Exception {
- // This test doesn't use the Solr core, just the response writer directly
+ public void testVelocityResponseWriterRegistered() {
+ QueryResponseWriter writer = h.getCore().getQueryResponseWriter("velocity");
+ assertTrue("VrW registered check", writer instanceof VelocityResponseWriter);
+ }
+ @Test
+ public void testCustomParamTemplate() throws Exception {
org.apache.solr.response.VelocityResponseWriter vrw = new VelocityResponseWriter();
- SolrQueryRequest req = req("v.template","custom", "v.template.custom","$response.response.response_data");
+ NamedList<String> nl = new NamedList<String>();
+ nl.add(VelocityResponseWriter.PARAMS_RESOURCE_LOADER_ENABLED, "true");
+ vrw.init(nl);
+ SolrQueryRequest req = req(VelocityResponseWriter.TEMPLATE,"custom",
+ SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"custom","$response.response.response_data");
SolrQueryResponse rsp = new SolrQueryResponse();
StringWriter buf = new StringWriter();
rsp.add("response_data", "testing");
@@ -47,14 +59,92 @@ public class VelocityResponseWriterTest
}
@Test
- public void testVelocityResponseWriterRegistered() {
- QueryResponseWriter writer = h.getCore().getQueryResponseWriter("velocity");
+ public void testParamResourceLoaderDisabled() throws Exception {
+ org.apache.solr.response.VelocityResponseWriter vrw = new VelocityResponseWriter();
+ // by default param resource loader is disabled, no need to set it here
+ SolrQueryRequest req = req(VelocityResponseWriter.TEMPLATE,"custom",
+ SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"custom","$response.response.response_data");
+ SolrQueryResponse rsp = new SolrQueryResponse();
+ StringWriter buf = new StringWriter();
+ try {
+ vrw.write(buf, req, rsp);
+ fail("Should have thrown exception due to missing template");
+ } catch (IOException e) {
+ // expected exception
+ }
+ }
- assertTrue("VrW registered check", writer instanceof VelocityResponseWriter);
+ @Test
+ public void testFileResourceLoader() throws Exception {
+ org.apache.solr.response.VelocityResponseWriter vrw = new VelocityResponseWriter();
+ NamedList<String> nl = new NamedList<String>();
+ nl.add("template.base.dir", getFile("velocity").getAbsolutePath());
+ vrw.init(nl);
+ SolrQueryRequest req = req(VelocityResponseWriter.TEMPLATE,"file");
+ SolrQueryResponse rsp = new SolrQueryResponse();
+ StringWriter buf = new StringWriter();
+ vrw.write(buf, req, rsp);
+ assertEquals("testing", buf.toString());
}
@Test
public void testSolrResourceLoaderTemplate() throws Exception {
- assertEquals("0", h.query(req("q","*:*", "wt","velocity","v.template","numFound")));
+ assertEquals("0", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"numFound")));
+ }
+
+ @Test
+ public void testMacros() throws Exception {
+ // tests that a macro in a custom macros.vm is visible
+ assertEquals("test_macro_SUCCESS", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"test_macro_visible")));
+
+ // tests that a builtin (_macros.vm) macro, #url_root in this case, can be overridden in a custom macros.vm
+ // the macro is also defined in VM_global_library.vm, which should also be overridden by macros.vm
+ assertEquals("Loaded from: macros.vm", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"test_macro_overridden")));
+
+ // tests that macros defined in VM_global_library.vm are visible. This file was where macros in pre-5.0 versions were defined
+ assertEquals("legacy_macro_SUCCESS", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"test_macro_legacy_support")));
}
+
+ @Test
+ public void testInitProps() throws Exception {
+ // The test init properties file turns off being able to use $foreach.index (the implicit loop counter)
+ // The foreach.vm template uses $!foreach.index, with ! suppressing the literal "$foreach.index" output
+
+ assertEquals("01", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"foreach")));
+ assertEquals("", h.query(req("q","*:*", "wt","velocityWithInitProps",VelocityResponseWriter.TEMPLATE,"foreach")));
+ }
+
+ @Test
+ public void testLocaleFeature() throws Exception {
+ assertEquals("Color", h.query(req("q", "*:*", "wt", "velocity", VelocityResponseWriter.TEMPLATE, "locale",
+ VelocityResponseWriter.LOCALE,"en_US")));
+ assertEquals("Colour", h.query(req("q", "*:*", "wt", "velocity", VelocityResponseWriter.TEMPLATE, "locale",
+ VelocityResponseWriter.LOCALE,"en_UK")));
+ }
+
+ @Test
+ public void testLayoutFeature() throws Exception {
+ assertEquals("{{{0}}}", h.query(req("q","*:*", "wt","velocity",
+ VelocityResponseWriter.TEMPLATE,"numFound", VelocityResponseWriter.LAYOUT,"layout")));
+
+ // even with v.layout specified, layout can be disabled explicitly
+ assertEquals("0", h.query(req("q","*:*", "wt","velocity",
+ VelocityResponseWriter.TEMPLATE,"numFound",
+ VelocityResponseWriter.LAYOUT,"layout",
+ VelocityResponseWriter.LAYOUT_ENABLED,"false")));
+ }
+
+ @Test
+ public void testJSONWrapper() throws Exception {
+ assertEquals("foo({\"result\":\"0\"})", h.query(req("q", "*:*", "wt", "velocity",
+ VelocityResponseWriter.TEMPLATE, "numFound",
+ VelocityResponseWriter.JSON,"foo")));
+
+ // Now with layout, for good measure
+ assertEquals("foo({\"result\":\"{{{0}}}\"})", h.query(req("q", "*:*", "wt", "velocity",
+ VelocityResponseWriter.TEMPLATE, "numFound",
+ VelocityResponseWriter.JSON,"foo",
+ VelocityResponseWriter.LAYOUT,"layout")));
+ }
+
}
Modified: lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/db/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/db/conf/solrconfig.xml?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/db/conf/solrconfig.xml (original)
+++ lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/db/conf/solrconfig.xml Fri Jan 9 22:35:28 2015
@@ -1727,8 +1727,9 @@
<!--
Custom response writers can be declared as needed...
-->
- <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy"/>
-
+ <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy">
+ <str name="template.base.dir">${velocity.template.base.dir:}</str>
+ </queryResponseWriter>
<!-- XSLT response writer transforms the XML output by any xslt file found
in Solr's conf/xslt directory. Changes to xslt files are checked for
Modified: lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/mail/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/mail/conf/solrconfig.xml?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/mail/conf/solrconfig.xml (original)
+++ lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/mail/conf/solrconfig.xml Fri Jan 9 22:35:28 2015
@@ -1698,8 +1698,9 @@
<!--
Custom response writers can be declared as needed...
-->
- <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy"/>
-
+ <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy">
+ <str name="template.base.dir">${velocity.template.base.dir:}</str>
+ </queryResponseWriter>
<!-- XSLT response writer transforms the XML output by any xslt file found
in Solr's conf/xslt directory. Changes to xslt files are checked for
Modified: lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/rss/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/rss/conf/solrconfig.xml?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/rss/conf/solrconfig.xml (original)
+++ lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/rss/conf/solrconfig.xml Fri Jan 9 22:35:28 2015
@@ -1695,8 +1695,9 @@
<!--
Custom response writers can be declared as needed...
-->
- <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy"/>
-
+ <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy">
+ <str name="template.base.dir">${velocity.template.base.dir:}</str>
+ </queryResponseWriter>
<!-- XSLT response writer transforms the XML output by any xslt file found
in Solr's conf/xslt directory. Changes to xslt files are checked for
Modified: lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/solr/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/solr/conf/solrconfig.xml?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/solr/conf/solrconfig.xml (original)
+++ lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/solr/conf/solrconfig.xml Fri Jan 9 22:35:28 2015
@@ -1726,8 +1726,9 @@
<!--
Custom response writers can be declared as needed...
-->
- <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy"/>
-
+ <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy">
+ <str name="template.base.dir">${velocity.template.base.dir:}</str>
+ </queryResponseWriter>
<!-- XSLT response writer transforms the XML output by any xslt file found
in Solr's conf/xslt directory. Changes to xslt files are checked for
Modified: lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/tika/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/tika/conf/solrconfig.xml?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/tika/conf/solrconfig.xml (original)
+++ lucene/dev/branches/branch_5x/solr/example/example-DIH/solr/tika/conf/solrconfig.xml Fri Jan 9 22:35:28 2015
@@ -1704,8 +1704,9 @@
<!--
Custom response writers can be declared as needed...
-->
- <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy"/>
-
+ <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy">
+ <str name="template.base.dir">${velocity.template.base.dir:}</str>
+ </queryResponseWriter>
<!-- XSLT response writer transforms the XML output by any xslt file found
in Solr's conf/xslt directory. Changes to xslt files are checked for
Modified: lucene/dev/branches/branch_5x/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml (original)
+++ lucene/dev/branches/branch_5x/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml Fri Jan 9 22:35:28 2015
@@ -852,22 +852,9 @@
</requestHandler>
- <requestHandler name="/browse" class="solr.SearchHandler">
+ <requestHandler name="/browse" class="solr.SearchHandler" useParams="query,facets,velocity,browse">
<lst name="defaults">
<str name="echoParams">explicit</str>
-
- <!-- VelocityResponseWriter settings -->
- <str name="wt">velocity</str>
- <str name="v.template">browse</str>
- <str name="v.layout">layout</str>
-
- <!-- Query settings -->
- <str name="defType">edismax</str>
- <str name="q.alt">*:*</str>
-
- <!-- Facet settings -->
- <str name="facet">on</str>
-
</lst>
</requestHandler>
@@ -1485,8 +1472,9 @@
<!--
Custom response writers can be declared as needed...
-->
- <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy"/>
-
+ <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy">
+ <str name="template.base.dir">${velocity.template.base.dir:}</str>
+ </queryResponseWriter>
<!-- XSLT response writer transforms the XML output by any xslt file found
in Solr's conf/xslt directory. Changes to xslt files are checked for
Modified: lucene/dev/branches/branch_5x/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml?rev=1650687&r1=1650686&r2=1650687&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml (original)
+++ lucene/dev/branches/branch_5x/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml Fri Jan 9 22:35:28 2015
@@ -1762,7 +1762,9 @@
<!--
Custom response writers can be declared as needed...
-->
- <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy"/>
+ <queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy">
+ <str name="template.base.dir">${velocity.template.base.dir:}</str>
+ </queryResponseWriter>
<!-- XSLT response writer transforms the XML output by any xslt file found