SOLR-10537: Added SolrParams.toLocalParamsString() and moved QP.encodeLocalParamVal to ClientUtils

This commit is contained in:
David Smiley 2017-04-26 08:38:52 -04:00
parent db92a9efc2
commit f45017b2d4
6 changed files with 62 additions and 36 deletions

View File

@ -189,6 +189,8 @@ New Features
* SOLR-10505: Add multi-field support to TermsComponent when requesting terms' statistics. (Shai Erera)
* SOLR-10537: SolrJ: Added SolrParams.toLocalParamsString() and ClientUtils.encodeLocalParamVal. (David Smiley)
Optimizations
----------------------

View File

@ -34,6 +34,7 @@ import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.FixedBitSet;
import org.apache.solr.client.solrj.util.ClientUtils;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.params.CommonParams;
@ -374,7 +375,7 @@ public class FacetComponent extends SearchComponent {
// add terms into the original facet.field command
// do it via parameter reference to avoid another layer of encoding.
String termsKeyEncoded = QueryParsing.encodeLocalParamVal(termsKey);
String termsKeyEncoded = ClientUtils.encodeLocalParamVal(termsKey);
if (dff.localParams != null) {
facetCommand = commandPrefix + termsKeyEncoded + " "
+ dff.facetStr.substring(2);

View File

@ -32,16 +32,13 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.lucene.util.FixedBitSet;
import org.apache.solr.search.DocIterator;
import org.apache.solr.search.SolrIndexSearcher;
import org.locationtech.spatial4j.context.SpatialContext;
import org.locationtech.spatial4j.shape.Shape;
import org.apache.lucene.spatial.prefix.HeatmapFacetCounter;
import org.apache.lucene.spatial.prefix.PrefixTreeStrategy;
import org.apache.lucene.spatial.query.SpatialArgs;
import org.apache.lucene.spatial.query.SpatialOperation;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.FixedBitSet;
import org.apache.solr.client.solrj.util.ClientUtils;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.FacetParams;
@ -54,10 +51,13 @@ import org.apache.solr.schema.RptWithGeometrySpatialField;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.SpatialRecursivePrefixTreeFieldType;
import org.apache.solr.search.BitDocSet;
import org.apache.solr.search.DocIterator;
import org.apache.solr.search.DocSet;
import org.apache.solr.search.QueryParsing;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.util.DistanceUnits;
import org.apache.solr.util.SpatialUtils;
import org.locationtech.spatial4j.context.SpatialContext;
import org.locationtech.spatial4j.shape.Shape;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -305,7 +305,7 @@ public class SpatialHeatmapFacets {
//add heatmap field param
if (!key.equals(facet.facetOn)) {
sreq.params.add(FacetParams.FACET_HEATMAP,
"{!" + CommonParams.OUTPUT_KEY + "=" + QueryParsing.encodeLocalParamVal(key) + "}" + facet.facetOn);
"{!" + CommonParams.OUTPUT_KEY + "=" + ClientUtils.encodeLocalParamVal(key) + "}" + facet.facetOn);
} else {
sreq.params.add(FacetParams.FACET_HEATMAP, facet.facetOn);
}

View File

@ -171,33 +171,6 @@ public class QueryParsing {
}
public static String encodeLocalParamVal(String val) {
int len = val.length();
int i = 0;
if (len > 0 && val.charAt(0) != '$') {
for (;i<len; i++) {
char ch = val.charAt(i);
if (Character.isWhitespace(ch) || ch=='}') break;
}
}
if (i>=len) return val;
// We need to enclose in quotes... but now we need to escape
StringBuilder sb = new StringBuilder(val.length() + 4);
sb.append('\'');
for (i=0; i<len; i++) {
char ch = val.charAt(i);
if (ch=='\'') {
sb.append('\\');
}
sb.append(ch);
}
sb.append('\'');
return sb.toString();
}
/**
* "foo" returns null
* "{!prefix f=myfield}yes" returns type="prefix",f="myfield",v="yes"

View File

@ -159,6 +159,35 @@ public class ClientUtils
return sb.toString();
}
/**
* Returns the value encoded properly so it can be appended after a <pre>name=</pre> local-param.
*/
public static String encodeLocalParamVal(String val) {
int len = val.length();
int i = 0;
if (len > 0 && val.charAt(0) != '$') {
for (;i<len; i++) {
char ch = val.charAt(i);
if (Character.isWhitespace(ch) || ch=='}') break;
}
}
if (i>=len) return val;
// We need to enclose in quotes... but now we need to escape
StringBuilder sb = new StringBuilder(val.length() + 4);
sb.append('\'');
for (i=0; i<len; i++) {
char ch = val.charAt(i);
if (ch=='\'') {
sb.append('\\');
}
sb.append(ch);
}
sb.append('\'');
return sb.toString();
}
/** Constructs a slices map from a collection of slices and handles disambiguation if multiple collections are being queried simultaneously */
public static void addSlices(Map<String,Slice> target, String collectionName, Collection<Slice> slices, boolean multiCollection) {
for (Slice slice : slices) {

View File

@ -30,6 +30,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.solr.client.solrj.util.ClientUtils;
import org.apache.solr.common.MapSerializable;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.NamedList;
@ -497,7 +498,27 @@ public abstract class SolrParams implements Serializable, MapSerializable {
throw new AssertionError(e);
}
}
/**
* Generates a local-params string of the form <pre>{! name=value name2=value2}</pre>.
*/
public String toLocalParamsString() {
final StringBuilder sb = new StringBuilder(128);
sb.append("{!");
//TODO perhaps look for 'type' and add here? but it doesn't matter.
for (final Iterator<String> it = getParameterNamesIterator(); it.hasNext();) {
final String name = it.next();
for (String val : getParams(name)) {
sb.append(' '); // do so even the first time; why not.
sb.append(name); // no escaping for name; it must follow "Java Identifier" rules.
sb.append('=');
sb.append(ClientUtils.encodeLocalParamVal(val));
}
}
sb.append('}');
return sb.toString();
}
/** Like {@link #toQueryString()}, but only replacing enough chars so that
* the URL may be unambiguously pasted back into a browser.
* This method can be used to properly log query parameters without