use of org.opensearch.OpenSearchParseException in project OpenSearch by opensearch-project.
the class GeoJsonParser method parseGeometries.
/**
* Parse the geometries array of a GeometryCollection
*
* @param parser Parser that will be read from
* @return Geometry[] geometries of the GeometryCollection
* @throws IOException Thrown if an error occurs while reading from the XContentParser
*/
static GeometryCollectionBuilder parseGeometries(XContentParser parser, AbstractShapeGeometryFieldMapper mapper) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_ARRAY) {
throw new OpenSearchParseException("geometries must be an array of geojson objects");
}
XContentParser.Token token = parser.nextToken();
GeometryCollectionBuilder geometryCollection = new GeometryCollectionBuilder();
while (token != XContentParser.Token.END_ARRAY) {
ShapeBuilder shapeBuilder = ShapeParser.parse(parser);
geometryCollection.shape(shapeBuilder);
token = parser.nextToken();
}
return geometryCollection;
}
use of org.opensearch.OpenSearchParseException in project OpenSearch by opensearch-project.
the class GeoJsonParser method parse.
protected static ShapeBuilder parse(XContentParser parser, AbstractShapeGeometryFieldMapper shapeMapper) throws IOException {
GeoShapeType shapeType = null;
DistanceUnit.Distance radius = null;
CoordinateNode coordinateNode = null;
GeometryCollectionBuilder geometryCollections = null;
Orientation orientation = (shapeMapper == null) ? AbstractShapeGeometryFieldMapper.Defaults.ORIENTATION.value() : shapeMapper.orientation();
Explicit<Boolean> coerce = (shapeMapper == null) ? AbstractShapeGeometryFieldMapper.Defaults.COERCE : shapeMapper.coerce();
Explicit<Boolean> ignoreZValue = (shapeMapper == null) ? AbstractShapeGeometryFieldMapper.Defaults.IGNORE_Z_VALUE : shapeMapper.ignoreZValue();
String malformedException = null;
XContentParser.Token token;
try (XContentParser subParser = new XContentSubParser(parser)) {
while ((token = subParser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
String fieldName = subParser.currentName();
if (ShapeParser.FIELD_TYPE.match(fieldName, subParser.getDeprecationHandler())) {
subParser.nextToken();
final GeoShapeType type = GeoShapeType.forName(subParser.text());
if (shapeType != null && shapeType.equals(type) == false) {
malformedException = ShapeParser.FIELD_TYPE + " already parsed as [" + shapeType + "] cannot redefine as [" + type + "]";
} else {
shapeType = type;
}
} else if (ShapeParser.FIELD_COORDINATES.match(fieldName, subParser.getDeprecationHandler())) {
subParser.nextToken();
CoordinateNode tempNode = parseCoordinates(subParser, ignoreZValue.value());
if (coordinateNode != null && tempNode.numDimensions() != coordinateNode.numDimensions()) {
throw new OpenSearchParseException("Exception parsing coordinates: " + "number of dimensions do not match");
}
coordinateNode = tempNode;
} else if (ShapeParser.FIELD_GEOMETRIES.match(fieldName, subParser.getDeprecationHandler())) {
if (shapeType == null) {
shapeType = GeoShapeType.GEOMETRYCOLLECTION;
} else if (shapeType.equals(GeoShapeType.GEOMETRYCOLLECTION) == false) {
malformedException = "cannot have [" + ShapeParser.FIELD_GEOMETRIES + "] with type set to [" + shapeType + "]";
}
subParser.nextToken();
geometryCollections = parseGeometries(subParser, shapeMapper);
} else if (CircleBuilder.FIELD_RADIUS.match(fieldName, subParser.getDeprecationHandler())) {
if (shapeType == null) {
shapeType = GeoShapeType.CIRCLE;
} else if (shapeType != null && shapeType.equals(GeoShapeType.CIRCLE) == false) {
malformedException = "cannot have [" + CircleBuilder.FIELD_RADIUS + "] with type set to [" + shapeType + "]";
}
subParser.nextToken();
radius = DistanceUnit.Distance.parseDistance(subParser.text());
} else if (ShapeParser.FIELD_ORIENTATION.match(fieldName, subParser.getDeprecationHandler())) {
if (shapeType != null && (shapeType.equals(GeoShapeType.POLYGON) || shapeType.equals(GeoShapeType.MULTIPOLYGON)) == false) {
malformedException = "cannot have [" + ShapeParser.FIELD_ORIENTATION + "] with type set to [" + shapeType + "]";
}
subParser.nextToken();
orientation = ShapeBuilder.Orientation.fromString(subParser.text());
} else {
subParser.nextToken();
subParser.skipChildren();
}
}
}
}
if (malformedException != null) {
throw new OpenSearchParseException(malformedException);
} else if (shapeType == null) {
throw new OpenSearchParseException("shape type not included");
} else if (coordinateNode == null && GeoShapeType.GEOMETRYCOLLECTION != shapeType) {
throw new OpenSearchParseException("coordinates not included");
} else if (geometryCollections == null && GeoShapeType.GEOMETRYCOLLECTION == shapeType) {
throw new OpenSearchParseException("geometries not included");
} else if (radius != null && GeoShapeType.CIRCLE != shapeType) {
throw new OpenSearchParseException("field [{}] is supported for [{}] only", CircleBuilder.FIELD_RADIUS, CircleBuilder.TYPE);
}
if (shapeType.equals(GeoShapeType.GEOMETRYCOLLECTION)) {
return geometryCollections;
}
return shapeType.getBuilder(coordinateNode, radius, orientation, coerce.value());
}
use of org.opensearch.OpenSearchParseException in project OpenSearch by opensearch-project.
the class GeometryParser method parseGeometry.
/**
* Parses the value as a {@link Geometry}. The following types of values are supported:
* <p>
* Object: has to contain either lat and lon or geohash fields
* <p>
* String: expected to be in "latitude, longitude" format, a geohash or WKT
* <p>
* Array: two or more elements, the first element is longitude, the second is latitude, the rest is ignored if ignoreZValue is true
* <p>
* Json structure: valid geojson definition
*/
public Geometry parseGeometry(Object value) throws OpenSearchParseException {
if (value instanceof List) {
List<?> values = (List<?>) value;
if (values.size() == 2 && values.get(0) instanceof Number) {
GeoPoint point = GeoUtils.parseGeoPoint(values, ignoreZValue);
return new Point(point.lon(), point.lat());
} else {
List<Geometry> geometries = new ArrayList<>(values.size());
for (Object object : values) {
geometries.add(parseGeometry(object));
}
return new GeometryCollection<>(geometries);
}
}
try (XContentParser parser = new MapXContentParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, Collections.singletonMap("null_value", value), null)) {
// start object
parser.nextToken();
// field name
parser.nextToken();
// field value
parser.nextToken();
if (isPoint(value)) {
GeoPoint point = GeoUtils.parseGeoPoint(parser, new GeoPoint(), ignoreZValue);
return new Point(point.lon(), point.lat());
} else {
return parse(parser);
}
} catch (IOException | ParseException ex) {
throw new OpenSearchParseException("error parsing geometry ", ex);
}
}
use of org.opensearch.OpenSearchParseException in project OpenSearch by opensearch-project.
the class XContentHelper method convertToMap.
/**
* Converts the given bytes into a map that is optionally ordered. The provided {@link XContentType} must be non-null.
*/
public static Tuple<XContentType, Map<String, Object>> convertToMap(BytesReference bytes, boolean ordered, XContentType xContentType) throws OpenSearchParseException {
try {
final XContentType contentType;
InputStream input;
Compressor compressor = CompressorFactory.compressor(bytes);
if (compressor != null) {
InputStream compressedStreamInput = compressor.threadLocalInputStream(bytes.streamInput());
if (compressedStreamInput.markSupported() == false) {
compressedStreamInput = new BufferedInputStream(compressedStreamInput);
}
input = compressedStreamInput;
} else if (bytes instanceof BytesArray) {
final BytesArray arr = (BytesArray) bytes;
final byte[] raw = arr.array();
final int offset = arr.offset();
final int length = arr.length();
contentType = xContentType != null ? xContentType : XContentFactory.xContentType(raw, offset, length);
return new Tuple<>(Objects.requireNonNull(contentType), convertToMap(XContentFactory.xContent(contentType), raw, offset, length, ordered));
} else {
input = bytes.streamInput();
}
try (InputStream stream = input) {
contentType = xContentType != null ? xContentType : XContentFactory.xContentType(stream);
return new Tuple<>(Objects.requireNonNull(contentType), convertToMap(XContentFactory.xContent(contentType), stream, ordered));
}
} catch (IOException e) {
throw new OpenSearchParseException("Failed to parse content to map", e);
}
}
use of org.opensearch.OpenSearchParseException in project OpenSearch by opensearch-project.
the class DocumentParser method createBuilderFromDynamicValue.
private static Mapper.Builder<?> createBuilderFromDynamicValue(final ParseContext context, XContentParser.Token token, String currentFieldName) throws IOException {
if (token == XContentParser.Token.VALUE_STRING) {
String text = context.parser().text();
boolean parseableAsLong = false;
try {
Long.parseLong(text);
parseableAsLong = true;
} catch (NumberFormatException e) {
// not a long number
}
boolean parseableAsDouble = false;
try {
Double.parseDouble(text);
parseableAsDouble = true;
} catch (NumberFormatException e) {
// not a double number
}
if (parseableAsLong && context.root().numericDetection()) {
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, XContentFieldType.LONG);
if (builder == null) {
builder = newLongBuilder(currentFieldName, context.indexSettings().getSettings());
}
return builder;
} else if (parseableAsDouble && context.root().numericDetection()) {
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, XContentFieldType.DOUBLE);
if (builder == null) {
builder = newFloatBuilder(currentFieldName, context.indexSettings().getSettings());
}
return builder;
} else if (parseableAsLong == false && parseableAsDouble == false && context.root().dateDetection()) {
// `epoch_millis` or `YYYY`
for (DateFormatter dateTimeFormatter : context.root().dynamicDateTimeFormatters()) {
try {
dateTimeFormatter.parse(text);
} catch (OpenSearchParseException | DateTimeParseException | IllegalArgumentException e) {
// failure to parse this, continue
continue;
}
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, dateTimeFormatter);
if (builder == null) {
boolean ignoreMalformed = IGNORE_MALFORMED_SETTING.get(context.indexSettings().getSettings());
builder = new DateFieldMapper.Builder(currentFieldName, DateFieldMapper.Resolution.MILLISECONDS, dateTimeFormatter, ignoreMalformed, Version.indexCreated(context.indexSettings().getSettings()));
}
return builder;
}
}
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, XContentFieldType.STRING);
if (builder == null) {
builder = new TextFieldMapper.Builder(currentFieldName, context.mapperService().getIndexAnalyzers()).addMultiField(new KeywordFieldMapper.Builder("keyword").ignoreAbove(256));
}
return builder;
} else if (token == XContentParser.Token.VALUE_NUMBER) {
XContentParser.NumberType numberType = context.parser().numberType();
if (numberType == XContentParser.NumberType.INT || numberType == XContentParser.NumberType.LONG || numberType == XContentParser.NumberType.BIG_INTEGER) {
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, XContentFieldType.LONG);
if (builder == null) {
builder = newLongBuilder(currentFieldName, context.indexSettings().getSettings());
}
return builder;
} else if (numberType == XContentParser.NumberType.FLOAT || numberType == XContentParser.NumberType.DOUBLE || numberType == XContentParser.NumberType.BIG_DECIMAL) {
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, XContentFieldType.DOUBLE);
if (builder == null) {
// no templates are defined, we use float by default instead of double
// since this is much more space-efficient and should be enough most of
// the time
builder = newFloatBuilder(currentFieldName, context.indexSettings().getSettings());
}
return builder;
}
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, XContentFieldType.BOOLEAN);
if (builder == null) {
builder = new BooleanFieldMapper.Builder(currentFieldName);
}
return builder;
} else if (token == XContentParser.Token.VALUE_EMBEDDED_OBJECT) {
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, XContentFieldType.BINARY);
if (builder == null) {
builder = new BinaryFieldMapper.Builder(currentFieldName);
}
return builder;
} else {
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, XContentFieldType.STRING);
if (builder != null) {
return builder;
}
}
// TODO how do we identify dynamically that its a binary value?
throw new IllegalStateException("Can't handle serializing a dynamic type with content token [" + token + "] and field name [" + currentFieldName + "]");
}
Aggregations