You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sa...@apache.org on 2016/12/13 20:06:48 UTC
lucene-solr:apiv2: SOLR-8029: Api spec parsing: Recursively handle
'#include' directives in all JSON objects;
replace repeated analyzer definitions in the addFieldType spec with a single
file included for each of the different types of analyzers; add mul
Repository: lucene-solr
Updated Branches:
refs/heads/apiv2 338b8d594 -> 6aa57e891
SOLR-8029: Api spec parsing: Recursively handle '#include' directives in all JSON objects; replace repeated analyzer definitions in the addFieldType spec with a single file included for each of the different types of analyzers; add multiTermAnalyzer key to addFieldType spec.
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/6aa57e89
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/6aa57e89
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/6aa57e89
Branch: refs/heads/apiv2
Commit: 6aa57e891aca031b598c085a10d26c1d82e99343
Parents: 338b8d5
Author: Steve Rowe <sa...@apache.org>
Authored: Tue Dec 13 15:06:39 2016 -0500
Committer: Steve Rowe <sa...@apache.org>
Committed: Tue Dec 13 15:06:39 2016 -0500
----------------------------------------------------------------------
.../src/java/org/apache/solr/api/ApiBag.java | 52 +------------
.../core.SchemaEdit.addFieldType.analyzers.json | 51 +++++++++++++
.../apispec/core.SchemaEdit.addFieldType.json | 78 ++------------------
.../solr/common/util/ValidatingJsonMap.java | 52 +++++++++++--
4 files changed, 107 insertions(+), 126 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/6aa57e89/solr/core/src/java/org/apache/solr/api/ApiBag.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/api/ApiBag.java b/solr/core/src/java/org/apache/solr/api/ApiBag.java
index 9a1da62..143792e 100644
--- a/solr/core/src/java/org/apache/solr/api/ApiBag.java
+++ b/solr/core/src/java/org/apache/solr/api/ApiBag.java
@@ -18,7 +18,6 @@
package org.apache.solr.api;
import java.io.IOException;
-import java.io.InputStream;
import java.io.Reader;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
@@ -59,27 +58,6 @@ public class ApiBag {
private final Map<String, PathTrie<Api>> apis = new ConcurrentHashMap<>();
- public static ValidatingJsonMap getResource(String name) {
- InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(name);
- if (is == null)
- throw new RuntimeException("invalid API spec :" + name );
- ValidatingJsonMap map1 = null;
- try {
- map1 = ValidatingJsonMap.fromJSON(is);
- } catch (Exception e) {
- log.error("Error in JSON : " + name, e);
- if (e instanceof RuntimeException) {
- throw (RuntimeException) e;
- }
- throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
- }
- if (map1 == null) throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Empty value for " + name);
-
- return ValidatingJsonMap.getDeepCopy(map1, 5, false);
- }
-
-
-
public synchronized void register(Api api, Map<String, String> nameSubstitutes) {
try {
validateAndRegister(api, nameSubstitutes);
@@ -208,36 +186,8 @@ public class ApiBag {
public static SpecProvider getSpec(final String name) {
return () -> {
- String jsonName = APISPEC_LOCATION + name + ".json";
- ValidatingJsonMap map = getResource(jsonName);
- ValidatingJsonMap result = map;
- ValidatingJsonMap cmds = result.getMap("commands", null);
- if (cmds != null) {
- Map commands2BReplaced = new ValidatingJsonMap();
- for (Object o : cmds.keySet()) {
- Object val = cmds.get(o);
- Map m = (Map) val;
- String include = (String) m.get("#include");
- if (include != null) {
- ValidatingJsonMap cmdSpec = getResource(APISPEC_LOCATION + include + ".json");
- m = ValidatingJsonMap.getDeepCopy(m, 4, true);
- m.remove("#include");
- m.putAll(cmdSpec);
- commands2BReplaced.put(o.toString(), m);
- }
- }
-
- if (!commands2BReplaced.isEmpty()) {
- ValidatingJsonMap mapCopy = ValidatingJsonMap.getDeepCopy(result, 4, true);
- mapCopy.getMap("commands", NOT_NULL).putAll(commands2BReplaced);
- result = ValidatingJsonMap.getDeepCopy(mapCopy, 4, false);
- }
- }
-
- return result;
+ return ValidatingJsonMap.parse(APISPEC_LOCATION + name + ".json", APISPEC_LOCATION);
};
-
-
}
public static class ReqHandlerToApi extends Api implements PermissionNameProvider {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/6aa57e89/solr/core/src/resources/apispec/core.SchemaEdit.addFieldType.analyzers.json
----------------------------------------------------------------------
diff --git a/solr/core/src/resources/apispec/core.SchemaEdit.addFieldType.analyzers.json b/solr/core/src/resources/apispec/core.SchemaEdit.addFieldType.analyzers.json
new file mode 100644
index 0000000..2974a60
--- /dev/null
+++ b/solr/core/src/resources/apispec/core.SchemaEdit.addFieldType.analyzers.json
@@ -0,0 +1,51 @@
+{
+ "type": "object",
+ "properties": {
+ "class": {
+ "type": "string"
+ },
+ "charFilters": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "class": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "class"
+ ],
+ "additionalProperties": true
+ }
+ },
+ "tokenizer": {
+ "type": "object",
+ "properties": {
+ "class": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "class"
+ ],
+ "additionalProperties": true
+ },
+ "filters": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "class": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "class"
+ ],
+ "additionalProperties": true
+ }
+ }
+ },
+ "additionalProperties": true
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/6aa57e89/solr/core/src/resources/apispec/core.SchemaEdit.addFieldType.json
----------------------------------------------------------------------
diff --git a/solr/core/src/resources/apispec/core.SchemaEdit.addFieldType.json b/solr/core/src/resources/apispec/core.SchemaEdit.addFieldType.json
index 3a44f6e..e24572e 100644
--- a/solr/core/src/resources/apispec/core.SchemaEdit.addFieldType.json
+++ b/solr/core/src/resources/apispec/core.SchemaEdit.addFieldType.json
@@ -28,83 +28,21 @@
"description": "Defines a custom PostingsFormat to use for fields of this type. A custom PostingsFormat requires that a schema-aware codec has also been configured in solrconfig.xml."
},
"queryAnalyzer": {
- "type": "object",
"description": "A query analyzer section defines how incoming queries to Solr will be analyzed for a field of this type.",
- "properties":{
- "tokenizer": {
- "type": "object",
- "properties": {
- "class": {
- "type": "string"
- }
- },
- "additionalProperties": true
- }
- },
- "additionalProperties": true
+ "#include": "core.SchemaEdit.addFieldType.analyzers"
},
"indexAnalyzer": {
- "type": "object",
"description": "An index analyzer section defines how incoming text in documents will be analyzed for a field of this type.",
- "properties": {
- "tokenizer": {
- "type": "object",
- "description": "",
- "properties": {
- "class": {
- "type": "string"
- }
- },
- "additionalProperties": true
- }
- },
- "additionalProperties": true
+ "#include": "core.SchemaEdit.addFieldType.analyzers"
+ },
+ "multiTermAnalyzer": {
+ "description": "A multiterm analyzer section defines how incoming queries that results in Multi-Term expansion will be analyzed for a field of this type.",
+ "documentation": "https://cwiki.apache.org/confluence/display/solr/Analyzers#Analyzers-AnalysisforMulti-TermExpansion",
+ "#include": "core.SchemaEdit.addFieldType.analyzers"
},
"analyzer": {
- "type": "object",
"description": "An analyzer defines how both incoming text in documents and queries are analyzed for a field of this type. If a query analyzer and an index analyzer have both been defined, a general analyzer does not need to be defined for this type.",
- "properties": {
- "class": {
- "type": "string"
- },
- "tokenizer":{
- "type":"object",
- "properties":{
- "class":{
- "type":"string"
- }
- },
- "required":["class"],
- "additionalProperties":true
- },
- "charFilters":{
- "type":"array",
- "items":{
- "type":"object",
- "properties":{
- "class":{
- "type":"string"
- }
- },
- "required":["class"],
- "additionalProperties":true
- }
- },
- "filters":{
- "type":"array",
- "items":{
- "type":"object",
- "properties":{
- "class":{
- "type":"string"
- }
- },
- "required":["class"],
- "additionalProperties":true
- }
- }
- },
- "additionalProperties": true
+ "#include": "core.SchemaEdit.addFieldType.analyzers"
}
},
"additionalProperties": true,
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/6aa57e89/solr/solrj/src/java/org/apache/solr/common/util/ValidatingJsonMap.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/common/util/ValidatingJsonMap.java b/solr/solrj/src/java/org/apache/solr/common/util/ValidatingJsonMap.java
index 3ea11bf..95318af 100644
--- a/solr/solrj/src/java/org/apache/solr/common/util/ValidatingJsonMap.java
+++ b/solr/solrj/src/java/org/apache/solr/common/util/ValidatingJsonMap.java
@@ -30,15 +30,20 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.apache.solr.common.SolrException;
import org.noggit.JSONParser;
import org.noggit.ObjectBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableSet;
public class ValidatingJsonMap implements Map<String, Object> {
-
+ private static final Logger log = LoggerFactory.getLogger(ValidatingJsonMap.class);
+ private static final String INCLUDE = "#include";
+ private static final String RESOURCE_EXTENSION = ".json";
public static final PredicateWithErrMsg<Object> NOT_NULL = o -> {
if (o == null) return " Must not be NULL";
return null;
@@ -237,18 +242,37 @@ public class ValidatingJsonMap implements Map<String, Object> {
}
- public static ValidatingJsonMap fromJSON(InputStream is) {
- return fromJSON(new InputStreamReader(is, UTF_8));
+ public static ValidatingJsonMap fromJSON(InputStream is, String includeLocation) {
+ return fromJSON(new InputStreamReader(is, UTF_8), includeLocation);
}
- public static ValidatingJsonMap fromJSON(Reader s) {
+ public static ValidatingJsonMap fromJSON(Reader s, String includeLocation) {
try {
- return (ValidatingJsonMap) (getObjectBuilder(new JSONParser(s)).getObject());
+ ValidatingJsonMap map = (ValidatingJsonMap)getObjectBuilder(new JSONParser(s)).getObject();
+ handleIncludes(map, includeLocation);
+ return map;
} catch (IOException e) {
throw new RuntimeException();
}
}
+ /**
+ * In the given map, recursively replace "#include":"resource-name" with the key/value pairs
+ * parsed from the resource at {location}/{resource-name}.json
+ */
+ private static void handleIncludes(ValidatingJsonMap map, String location) {
+ final String loc = location == null ? "" // trim trailing slash
+ : (location.endsWith("/") ? location.substring(0, location.length() - 1) : location);
+ String resourceToInclude = (String)map.get(INCLUDE);
+ if (resourceToInclude != null) {
+ ValidatingJsonMap includedMap = parse(loc + "/" + resourceToInclude + RESOURCE_EXTENSION, loc);
+ map.remove(INCLUDE);
+ map.putAll(includedMap);
+ }
+ map.entrySet().stream().filter(e->e.getValue() instanceof Map).map(Map.Entry::getValue)
+ .forEach(m->handleIncludes((ValidatingJsonMap)m, loc));
+ }
+
public static ValidatingJsonMap getDeepCopy(Map map, int maxDepth, boolean mutable) {
if (map == null) return null;
if (maxDepth < 1) return ValidatingJsonMap.wrap(map);
@@ -284,6 +308,24 @@ public class ValidatingJsonMap implements Map<String, Object> {
};
}
+ public static ValidatingJsonMap parse(String resourceName, String includeLocation) {
+ InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName);
+ if (is == null)
+ throw new RuntimeException("invalid API spec: " + resourceName);
+ ValidatingJsonMap map = null;
+ try {
+ map = fromJSON(is, includeLocation);
+ } catch (Exception e) {
+ log.error("Error in JSON : " + resourceName, e);
+ if (e instanceof RuntimeException) {
+ throw e;
+ }
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
+ }
+ if (map == null) throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Empty value for " + resourceName);
+
+ return getDeepCopy(map, 5, false);
+ }
@Override
public boolean equals(Object that) {