Skip to content

Commit

Permalink
Support externalValue() in mappers
Browse files Browse the repository at this point in the history
Some mappers do not support externalValue() to be set. So plugin developers can't use it while building their own mappers.

Support added in this PR for:

* `BinaryFieldMapper`
* `BooleanFieldMapper`
* `GeoPointFieldMapper`
* `GeoShapeFieldMapper`

Closes elastic#4986.
Relative to elastic#4154.
  • Loading branch information
dadoonet committed Mar 14, 2014
1 parent 6f80b77 commit 84b5b45
Show file tree
Hide file tree
Showing 10 changed files with 489 additions and 58 deletions.
19 changes: 18 additions & 1 deletion src/main/java/org/elasticsearch/index/mapper/ParseContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.ElasticsearchIllegalStateException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.lucene.all.AllEntries;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
import org.elasticsearch.index.mapper.object.RootObjectMapper;

import java.util.*;
Expand Down Expand Up @@ -396,6 +396,23 @@ public Object externalValue() {
return externalValue;
}

/**
* Try to parse an externalValue if any
* @param clazz Expected class for external value
* @return null if no external value has been set or the value
*/
public <T> T parseExternalValue(Class<T> clazz) {
if (!externalValueSet() || externalValue() == null) {
return null;
}

if (!clazz.isInstance(externalValue())) {
throw new ElasticsearchIllegalArgumentException("illegal external value class ["
+ externalValue().getClass().getName() + "]. Should be " + clazz.getName());
}
return (T) externalValue();
}

public float docBoost() {
return this.docBoost;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,24 +174,26 @@ protected void parseCreateField(ParseContext context, List<Field> fields) throws
if (!fieldType().stored()) {
return;
}
byte[] value;
if (context.parser().currentToken() == XContentParser.Token.VALUE_NULL) {
return;
} else {
value = context.parser().binaryValue();
if (compress != null && compress && !CompressorFactory.isCompressed(value, 0, value.length)) {
if (compressThreshold == -1 || value.length > compressThreshold) {
BytesStreamOutput bStream = new BytesStreamOutput();
StreamOutput stream = CompressorFactory.defaultCompressor().streamOutput(bStream);
stream.writeBytes(value, 0, value.length);
stream.close();
value = bStream.bytes().toBytes();
}
byte[] value = context.parseExternalValue(byte[].class);
if (value == null) {
if (context.parser().currentToken() == XContentParser.Token.VALUE_NULL) {
return;
} else {
value = context.parser().binaryValue();
}
}
if (value == null) {
return;
}
if (compress != null && compress && !CompressorFactory.isCompressed(value, 0, value.length)) {
if (compressThreshold == -1 || value.length > compressThreshold) {
BytesStreamOutput bStream = new BytesStreamOutput();
StreamOutput stream = CompressorFactory.defaultCompressor().streamOutput(bStream);
stream.writeBytes(value, 0, value.length);
stream.close();
value = bStream.bytes().toBytes();
}
}
fields.add(new Field(names.indexName(), value, fieldType));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,19 +207,23 @@ protected void parseCreateField(ParseContext context, List<Field> fields) throws
if (!fieldType().indexed() && !fieldType().stored()) {
return;
}
XContentParser.Token token = context.parser().currentToken();
String value = null;
if (token == XContentParser.Token.VALUE_NULL) {
if (nullValue != null) {
value = nullValue ? "T" : "F";

Boolean value = context.parseExternalValue(Boolean.class);
if (value == null) {
XContentParser.Token token = context.parser().currentToken();
if (token == XContentParser.Token.VALUE_NULL) {
if (nullValue != null) {
value = nullValue;
}
} else {
value = context.parser().booleanValue();
}
} else {
value = context.parser().booleanValue() ? "T" : "F";
}

if (value == null) {
return;
}
fields.add(new Field(names.indexName(), value, fieldType));
fields.add(new Field(names.indexName(), value ? "T" : "F", fieldType));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -480,47 +480,52 @@ public void parse(ParseContext context) throws IOException {
context.path().pathType(pathType);
context.path().add(name());

XContentParser.Token token = context.parser().currentToken();
if (token == XContentParser.Token.START_ARRAY) {
token = context.parser().nextToken();
GeoPoint value = context.parseExternalValue(GeoPoint.class);
if (value != null) {
parseLatLon(context, value.lat(), value.lon());
} else {
XContentParser.Token token = context.parser().currentToken();
if (token == XContentParser.Token.START_ARRAY) {
// its an array of array of lon/lat [ [1.2, 1.3], [1.4, 1.5] ]
while (token != XContentParser.Token.END_ARRAY) {
token = context.parser().nextToken();
double lon = context.parser().doubleValue();
token = context.parser().nextToken();
double lat = context.parser().doubleValue();
while ((token = context.parser().nextToken()) != XContentParser.Token.END_ARRAY) {

}
parseLatLon(context, lat, lon);
token = context.parser().nextToken();
}
} else {
// its an array of other possible values
if (token == XContentParser.Token.VALUE_NUMBER) {
double lon = context.parser().doubleValue();
token = context.parser().nextToken();
double lat = context.parser().doubleValue();
while ((token = context.parser().nextToken()) != XContentParser.Token.END_ARRAY) {
token = context.parser().nextToken();
if (token == XContentParser.Token.START_ARRAY) {
// its an array of array of lon/lat [ [1.2, 1.3], [1.4, 1.5] ]
while (token != XContentParser.Token.END_ARRAY) {
token = context.parser().nextToken();
double lon = context.parser().doubleValue();
token = context.parser().nextToken();
double lat = context.parser().doubleValue();
while ((token = context.parser().nextToken()) != XContentParser.Token.END_ARRAY) {

}
parseLatLon(context, lat, lon);
token = context.parser().nextToken();
}
parseLatLon(context, lat, lon);
} else {
while (token != XContentParser.Token.END_ARRAY) {
if (token == XContentParser.Token.START_OBJECT) {
parseObjectLatLon(context);
} else if (token == XContentParser.Token.VALUE_STRING) {
parseStringLatLon(context);
}
// its an array of other possible values
if (token == XContentParser.Token.VALUE_NUMBER) {
double lon = context.parser().doubleValue();
token = context.parser().nextToken();
double lat = context.parser().doubleValue();
while ((token = context.parser().nextToken()) != XContentParser.Token.END_ARRAY) {

}
parseLatLon(context, lat, lon);
} else {
while (token != XContentParser.Token.END_ARRAY) {
if (token == XContentParser.Token.START_OBJECT) {
parseObjectLatLon(context);
} else if (token == XContentParser.Token.VALUE_STRING) {
parseStringLatLon(context);
}
token = context.parser().nextToken();
}
}
}
} else if (token == XContentParser.Token.START_OBJECT) {
parseObjectLatLon(context);
} else if (token == XContentParser.Token.VALUE_STRING) {
parseStringLatLon(context);
}
} else if (token == XContentParser.Token.START_OBJECT) {
parseObjectLatLon(context);
} else if (token == XContentParser.Token.VALUE_STRING) {
parseStringLatLon(context);
}

context.path().remove();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package org.elasticsearch.index.mapper.geo;

import com.spatial4j.core.shape.Shape;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.index.FieldInfo;
Expand Down Expand Up @@ -224,11 +225,15 @@ public boolean hasDocValues() {
@Override
public void parse(ParseContext context) throws IOException {
try {
ShapeBuilder shape = ShapeBuilder.parse(context.parser());
Shape shape = context.parseExternalValue(Shape.class);
if (shape == null) {
return;
ShapeBuilder shapeBuilder = ShapeBuilder.parse(context.parser());
if (shapeBuilder == null) {
return;
}
shape = shapeBuilder.build();
}
Field[] fields = defaultStrategy.createIndexableFields(shape.build());
Field[] fields = defaultStrategy.createIndexableFields(shape);
if (fields == null || fields.length == 0) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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.index.mapper.externalvalues;

import org.elasticsearch.common.inject.AbstractModule;

/**
*
*/
public class ExternalIndexModule extends AbstractModule {

@Override
protected void configure() {
bind(RegisterExternalTypes.class).asEagerSingleton();
}
}
Loading

0 comments on commit 84b5b45

Please sign in to comment.