package crate.elasticsearch.action.searchinto.parser; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.collect.ImmutableMap; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.search.SearchParseElement; import org.elasticsearch.search.SearchParseException; import crate.elasticsearch.action.searchinto.SearchIntoContext; public abstract class AbstractSearchIntoParser implements ISearchIntoParser { /** * Main method of this class to parse given payload of _search_into action * * @param context * @param source * @throws org.elasticsearch.search.SearchParseException * */ public void parseSource(SearchIntoContext context, BytesReference source) throws SearchParseException { XContentParser parser = null; try { if (source != null) { parser = XContentFactory.xContent(source).createParser(source); XContentParser.Token token; while ((token = parser.nextToken()) != XContentParser.Token .END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { String fieldName = parser.currentName(); parser.nextToken(); SearchParseElement element = getElementParsers().get( fieldName); if (element == null) { throw new SearchParseException(context, "No parser for element [" + fieldName + "]"); } element.parse(parser, context); } else if (token == null) { break; } } } validate(context); } catch (Exception e) { String sSource = "_na_"; try { sSource = XContentHelper.convertToJson(source, false); } catch (Throwable e1) { // ignore } throw new SearchParseException(context, "Failed to parse source [" + sSource + "]", e); } finally { if (parser != null) { parser.close(); } } } /** * Get the element parser map * @return */ protected abstract ImmutableMap<String, SearchParseElement> getElementParsers(); /** * Validate the pay load of the search-into context. * @param context */ protected void validate(SearchIntoContext context) { if (context.hasFieldNames() && context.fieldNames().contains("_source")) { String index = context.mapperService().index().getName(); for (String type : context.mapperService().types()) { if (!context.mapperService().documentMapper(type).sourceMapper().enabled()) { throw new SearchParseException(context, "The _source field of index " + index + " and type " + type + " is not stored."); } } } } }