in libraries/bot-ai-luis-v3/src/main/java/com/microsoft/bot/ai/luis/LuisRecognizerOptionsV3.java [565:673]
private JsonNode mapEntitiesRecursive(JsonNode source, boolean inInstance) {
JsonNode result = source;
if (!source.isArray() && source.isObject()) {
ObjectNode nobj = JsonNodeFactory.instance.objectNode();
// Fix datetime by reverting to simple timex
JsonNode obj = source;
JsonNode type = source.get("type");
if (!inInstance && type != null && dateSubtypes.contains(type.asText())) {
JsonNode timexs = obj.get("values");
ArrayNode arr = JsonNodeFactory.instance.arrayNode();
if (timexs != null) {
Set<String> unique = new HashSet<>();
for (JsonNode elt : timexs) {
unique.add(elt.get("timex").textValue());
}
for (String timex : unique) {
arr.add(timex);
}
nobj.set("timex", arr);
}
nobj.set("type", type);
} else {
// Map or remove properties
Iterator<Map.Entry<String, JsonNode>> nodes = obj.fields();
while (nodes.hasNext()) {
Map.Entry<String, JsonNode> property = (Map.Entry<String, JsonNode>) nodes.next();
String name = normalizeEntity(property.getKey());
boolean isArray = property.getValue().isArray();
boolean isString = property.getValue().isTextual();
boolean isInt = property.getValue().isInt();
JsonNode val = mapEntitiesRecursive(property.getValue(), inInstance || name.equals(metadataKey));
if (name.equals("datetime") && isArray) {
nobj.set("datetimeV1", val);
} else if (name.equals("datetimeV2") && isArray) {
nobj.set("datetime", val);
} else if (inInstance) {
// Correct $instance issues
if (name.equals("length") && isInt) {
int value = property.getValue().intValue();
if (obj.get("startIndex") != null) {
value += obj.get("startIndex").intValue();
}
nobj.put("endIndex", value);
} else if (!((isInt && name.equals("modelTypeId")) || // NOPMD
(isString && name.equals("role"))) // NOPMD
) { // NOPMD
nobj.set(name, val);
}
} else {
// Correct non-$instance values
if (name.equals("unit") && isString) {
nobj.set("units", val);
} else {
nobj.set(name, val);
}
}
}
}
result = nobj;
} else if (source.isArray()) {
JsonNode arr = source;
ArrayNode narr = JsonNodeFactory.instance.arrayNode();
for (JsonNode elt : arr) {
// Check if element is geographyV2
String isGeographyV2 = "";
Iterator<Map.Entry<String, JsonNode>> nodes = elt.fields();
while (nodes.hasNext()) {
Map.Entry<String, JsonNode> props = (Map.Entry<String, JsonNode>) nodes.next();
if (props == null) {
break;
}
if (props.getKey().contains("type") && geographySubtypes.contains(props.getValue().textValue())) {
isGeographyV2 = props.getValue().textValue();
break;
}
}
if (!inInstance && !isGeographyV2.isEmpty()) {
ObjectNode geoEntity = JsonNodeFactory.instance.objectNode();
nodes = elt.fields();
while (nodes.hasNext()) {
Map.Entry<String, JsonNode> tokenProp = (Map.Entry<String, JsonNode>) nodes.next();
if (tokenProp.getKey().contains("value")) {
geoEntity.set("location", tokenProp.getValue());
}
}
geoEntity.put("type", isGeographyV2);
narr.add(geoEntity);
} else {
narr.add(mapEntitiesRecursive(elt, inInstance));
}
}
result = narr;
}
return result;
}