protected ConfigNodeObject changeValueOnPath()

in scripts/src/main/java/com/gu/typesafe/config/impl/ConfigNodeObject.java [39:100]


    protected ConfigNodeObject changeValueOnPath(Path desiredPath, com.gu.typesafe.config.impl.AbstractConfigNodeValue value, com.gu.typesafe.config.ConfigSyntax flavor) {
        ArrayList<AbstractConfigNode> childrenCopy = new ArrayList<AbstractConfigNode>(super.children);
        boolean seenNonMatching = false;
        // Copy the value so we can change it to null but not modify the original parameter
        com.gu.typesafe.config.impl.AbstractConfigNodeValue valueCopy = value;
        for (int i = childrenCopy.size() - 1; i >= 0; i--) {
            if (childrenCopy.get(i) instanceof com.gu.typesafe.config.impl.ConfigNodeSingleToken) {
                Token t = ((com.gu.typesafe.config.impl.ConfigNodeSingleToken) childrenCopy.get(i)).token();
                // Ensure that, when we are removing settings in JSON, we don't end up with a trailing comma
                if (flavor == com.gu.typesafe.config.ConfigSyntax.JSON && !seenNonMatching && t == com.gu.typesafe.config.impl.Tokens.COMMA) {
                    childrenCopy.remove(i);
                }
                continue;
            } else if (!(childrenCopy.get(i) instanceof ConfigNodeField)) {
                continue;
            }
            ConfigNodeField node = (ConfigNodeField) childrenCopy.get(i);
            Path key = node.path().value();

            // Delete all multi-element paths that start with the desired path, since technically they are duplicates
            if ((valueCopy == null && key.equals(desiredPath))|| (key.startsWith(desiredPath) && !key.equals(desiredPath))) {
                childrenCopy.remove(i);
                // Remove any whitespace or commas after the deleted setting
                for (int j = i; j < childrenCopy.size(); j++) {
                    if (childrenCopy.get(j) instanceof com.gu.typesafe.config.impl.ConfigNodeSingleToken) {
                        Token t = ((com.gu.typesafe.config.impl.ConfigNodeSingleToken) childrenCopy.get(j)).token();
                        if (com.gu.typesafe.config.impl.Tokens.isIgnoredWhitespace(t) || t == com.gu.typesafe.config.impl.Tokens.COMMA) {
                            childrenCopy.remove(j);
                            j--;
                        } else {
                            break;
                        }
                    } else {
                        break;
                    }
                }
            } else if (key.equals(desiredPath)) {
                seenNonMatching = true;
                com.gu.typesafe.config.impl.AbstractConfigNodeValue indentedValue;
                AbstractConfigNode before = i - 1 > 0 ? childrenCopy.get(i - 1) : null;
                if (value instanceof com.gu.typesafe.config.impl.ConfigNodeComplexValue &&
                        before instanceof com.gu.typesafe.config.impl.ConfigNodeSingleToken &&
                        com.gu.typesafe.config.impl.Tokens.isIgnoredWhitespace(((com.gu.typesafe.config.impl.ConfigNodeSingleToken) before).token()))
                    indentedValue = ((com.gu.typesafe.config.impl.ConfigNodeComplexValue) value).indentText(before);
                else
                    indentedValue = value;
                childrenCopy.set(i, node.replaceValue(indentedValue));
                valueCopy = null;
            } else if (desiredPath.startsWith(key)) {
                seenNonMatching = true;
                if (node.value() instanceof ConfigNodeObject) {
                    Path remainingPath = desiredPath.subPath(key.length());
                    childrenCopy.set(i, node.replaceValue(((ConfigNodeObject) node.value()).changeValueOnPath(remainingPath, valueCopy, flavor)));
                    if (valueCopy != null && !node.equals(super.children.get(i)))
                        valueCopy = null;
                }
            } else {
                seenNonMatching = true;
            }
        }
        return new ConfigNodeObject(childrenCopy);
    }