private JsonNode mapEntitiesRecursive()

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;
    }