org.elasticsearch.script.AbstractScriptParser Maven / Gradle / Ivy
The newest version!
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.script;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.script.Script.ScriptField;
import org.elasticsearch.script.Script.ScriptParseException;
import org.elasticsearch.script.ScriptService.ScriptType;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public abstract class AbstractScriptParser {
protected abstract String parseInlineScript(XContentParser parser) throws IOException;
protected abstract S createScript(String script, ScriptType type, String lang, Map params);
protected abstract S createSimpleScript(XContentParser parser) throws IOException;
@Deprecated
protected Map getAdditionalScriptParameters() {
return Collections.emptyMap();
}
public S parse(XContentParser parser, ParseFieldMatcher parseFieldMatcher) throws IOException {
XContentParser.Token token = parser.currentToken();
// If the parser hasn't yet been pushed to the first token, do it now
if (token == null) {
token = parser.nextToken();
}
if (token == XContentParser.Token.VALUE_STRING) {
return createSimpleScript(parser);
}
if (token != XContentParser.Token.START_OBJECT) {
throw new ScriptParseException("expected a string value or an object, but found [{}] instead", token);
}
String script = null;
ScriptType type = null;
String lang = getDefaultScriptLang();
Map params = null;
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (parseFieldMatcher.match(currentFieldName, ScriptType.INLINE.getParseField()) || parseFieldMatcher.match(currentFieldName, ScriptService.SCRIPT_INLINE)) {
type = ScriptType.INLINE;
script = parseInlineScript(parser);
} else if (parseFieldMatcher.match(currentFieldName, ScriptType.FILE.getParseField()) || parseFieldMatcher.match(currentFieldName, ScriptService.SCRIPT_FILE)) {
type = ScriptType.FILE;
if (token == XContentParser.Token.VALUE_STRING) {
script = parser.text();
} else {
throw new ScriptParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
}
} else if (parseFieldMatcher.match(currentFieldName, ScriptType.INDEXED.getParseField()) || parseFieldMatcher.match(currentFieldName, ScriptService.SCRIPT_ID)) {
type = ScriptType.INDEXED;
if (token == XContentParser.Token.VALUE_STRING) {
script = parser.text();
} else {
throw new ScriptParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
}
} else if (parseFieldMatcher.match(currentFieldName, ScriptField.LANG) || parseFieldMatcher.match(currentFieldName, ScriptService.SCRIPT_LANG)) {
if (token == XContentParser.Token.VALUE_STRING) {
lang = parser.text();
} else {
throw new ScriptParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
}
} else if (parseFieldMatcher.match(currentFieldName, ScriptField.PARAMS)) {
if (token == XContentParser.Token.START_OBJECT) {
params = parser.map();
} else {
throw new ScriptParseException("expected an object for field [{}], but found [{}]", currentFieldName, token);
}
} else {
// TODO remove this in 3.0
ScriptType paramScriptType = getAdditionalScriptParameters().get(currentFieldName);
if (paramScriptType != null) {
script = parseInlineScript(parser);
type = paramScriptType;
} else {
throw new ScriptParseException("unexpected field [{}]", currentFieldName);
}
}
}
if (script == null) {
throw new ScriptParseException("expected one of [{}], [{}] or [{}] fields, but found none", ScriptType.INLINE.getParseField()
.getPreferredName(), ScriptType.FILE.getParseField().getPreferredName(), ScriptType.INDEXED.getParseField()
.getPreferredName());
}
assert type != null : "if script is not null, type should definitely not be null";
return createScript(script, type, lang, params);
}
/**
* @return the default script language for this parser or null
* to use the default set in the ScriptService
*/
protected String getDefaultScriptLang() {
return null;
}
public S parse(Map config, boolean removeMatchedEntries, ParseFieldMatcher parseFieldMatcher) {
String script = null;
ScriptType type = null;
String lang = null;
Map params = null;
for (Iterator> itr = config.entrySet().iterator(); itr.hasNext();) {
Entry entry = itr.next();
String parameterName = entry.getKey();
Object parameterValue = entry.getValue();
if (parseFieldMatcher.match(parameterName, ScriptField.LANG) || parseFieldMatcher.match(parameterName, ScriptService.SCRIPT_LANG)) {
if (parameterValue instanceof String || parameterValue == null) {
lang = (String) parameterValue;
if (removeMatchedEntries) {
itr.remove();
}
} else {
throw new ScriptParseException("Value must be of type String: [" + parameterName + "]");
}
} else if (parseFieldMatcher.match(parameterName, ScriptField.PARAMS)) {
if (parameterValue instanceof Map || parameterValue == null) {
params = (Map) parameterValue;
if (removeMatchedEntries) {
itr.remove();
}
} else {
throw new ScriptParseException("Value must be of type String: [" + parameterName + "]");
}
} else if (parseFieldMatcher.match(parameterName, ScriptType.INLINE.getParseField()) || parseFieldMatcher.match(parameterName, ScriptService.SCRIPT_INLINE)) {
if (parameterValue instanceof String || parameterValue == null) {
script = (String) parameterValue;
type = ScriptType.INLINE;
if (removeMatchedEntries) {
itr.remove();
}
} else {
throw new ScriptParseException("Value must be of type String: [" + parameterName + "]");
}
} else if (parseFieldMatcher.match(parameterName, ScriptType.FILE.getParseField()) || parseFieldMatcher.match(parameterName, ScriptService.SCRIPT_FILE)) {
if (parameterValue instanceof String || parameterValue == null) {
script = (String) parameterValue;
type = ScriptType.FILE;
if (removeMatchedEntries) {
itr.remove();
}
} else {
throw new ScriptParseException("Value must be of type String: [" + parameterName + "]");
}
} else if (parseFieldMatcher.match(parameterName, ScriptType.INDEXED.getParseField()) || parseFieldMatcher.match(parameterName, ScriptService.SCRIPT_ID)) {
if (parameterValue instanceof String || parameterValue == null) {
script = (String) parameterValue;
type = ScriptType.INDEXED;
if (removeMatchedEntries) {
itr.remove();
}
} else {
throw new ScriptParseException("Value must be of type String: [" + parameterName + "]");
}
}
}
if (script == null) {
throw new ScriptParseException("expected one of [{}], [{}] or [{}] fields, but found none", ScriptType.INLINE.getParseField()
.getPreferredName(), ScriptType.FILE.getParseField().getPreferredName(), ScriptType.INDEXED.getParseField()
.getPreferredName());
}
assert type != null : "if script is not null, type should definitely not be null";
return createScript(script, type, lang, params);
}
}