com.almende.eve.capabilities.Config.java Source code

Java tutorial

Introduction

Here is the source code for com.almende.eve.capabilities.Config.java

Source

/*
 * Copyright: Almende B.V. (2014), Rotterdam, The Netherlands
 * License: The Apache Software License, Version 2.0
 */
package com.almende.eve.capabilities;

import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;

import com.almende.util.TypeUtil;
import com.almende.util.jackson.JOM;
import com.almende.util.uuid.UUID;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

/**
 * The Class Config.
 */
public class Config extends ObjectNode {
    private static Config global = new Config();

    private List<Config> pointers = new LinkedList<Config>();
    private boolean configured = false;

    /**
     * Instantiates a new config.
     */
    public Config() {
        super(JOM.getInstance().getNodeFactory(), new LinkedHashMap<String, JsonNode>(2));
    }

    private Config(final ObjectNode node) {
        super(JOM.getInstance().getNodeFactory(),
                new LinkedHashMap<String, JsonNode>(node != null ? node.size() : 2));
        if (node != null) {
            this.setAll(node);
        }
    }

    /**
     * Decorate.
     *
     * @param node
     *            the node
     * @return the config
     */
    public static Config decorate(final ObjectNode node) {
        Config res = null;
        if (node instanceof Config) {
            res = (Config) node;
        } else {
            res = new Config(node);
        }
        return res;
    }

    /**
     * Copy.
     *
     * @param node
     *            the node
     * @return the config
     */
    public Config copy(final ObjectNode node) {
        if (node != null) {
            if (node == this) {
                //Can't use equals!
                return this;
            }
            Config other = Config.decorate(node);
            this.pointers.addAll(other.pointers);
            this.pointers.add(other);
        }
        return this;
    }

    /**
     * Gets the global.
     *
     * @return the global
     */
    public static ObjectNode getGlobal() {
        return global;
    }

    /**
     * Gets the pointers.
     *
     * @return the pointers
     */
    public List<Config> getPointers() {
        return pointers;
    }

    /**
     * Sets the pointers.
     *
     * @param pointers
     *            the new pointers
     */
    public void setPointers(List<Config> pointers) {
        this.pointers = pointers;
    }

    /**
     * Load templates.
     *
     * @param fieldName
     *            the field name
     */
    public void loadTemplates(final String fieldName) {
        if (this.has(fieldName)) {
            global.set(fieldName, this.get(fieldName));
        }
    }

    /**
     * Extend this configuration with the other tree, overwriting existing
     * fields, adding new ones.
     * 
     * @param other
     *            the other
     * @return the config
     */
    public Config extend(final ObjectNode other) {
        this.setAll(other);
        return this;
    }

    /**
     * Sets the class path. (Required)
     * 
     * @param className
     *            the new class
     */
    public void setClassName(final String className) {
        this.put("class", className);
    }

    /**
     * Gets the class path.
     * 
     * @return the class path
     */
    public String getClassName() {
        if (this.has("class")) {
            return this.get("class").asText();
        }
        return null;
    }

    private JsonNode lget(final String... keys) {
        if (keys == null || keys.length == 0) {
            return null;
        }
        JsonNode node = this;
        for (final String key : keys) {
            node = node.get(key);
            if (node == null) {
                break;
            }
        }
        if (node == null) {
            return null;
        }
        return node;
    }

    @Override
    public JsonNode get(final String key) {
        JsonNode res = super.get(key);
        if ((res != null && !res.isObject()) || "extends".equals(key)) {
            return res;
        }
        if (!configured && this.has("extends")) {
            setupExtend();
        }
        JsonNode otherres = null;
        Config result = null;
        for (Config other : getPointers()) {
            JsonNode val = other.get(key);
            if (val == null) {
                continue;
            }
            if (val.isArray()) {
                final ArrayNode array = JOM.createArrayNode();
                for (JsonNode elem : val) {
                    final Config item = new Config();
                    item.pointers.add(Config.decorate((ObjectNode) elem));
                    array.add(item);
                }
                this.set(key, array);
                otherres = array;
            } else if (!val.isObject()) {
                otherres = val;
            } else {
                if (result == null) {
                    result = Config.decorate((ObjectNode) res);
                }
                result.getPointers().add(Config.decorate((ObjectNode) val));
            }
        }
        if (otherres != null) {
            return otherres;
        }
        if (result != null) {
            return result;
        }
        return res;
    }

    /**
     * Gets the.
     * 
     * @param <T>
     *            the generic type
     * @param keys
     *            the keys
     * @return the json node
     */
    public <T> T get(final String... keys) {
        JsonNode node = lget(keys);
        final TypeUtil<T> tu = new TypeUtil<T>() {
        };
        return tu.inject(node);
    }

    @Override
    public ObjectNode deepCopy() {
        final ObjectNode result = JOM.createObjectNode();
        for (Config other : pointers) {
            result.setAll(other.deepCopy());
        }
        result.setAll(super.deepCopy());
        return result;
    }

    /**
     * Setup extends.
     */
    public void setupExtend() {
        configured = true;
        final JsonNode extNode = this.get("extends");
        if (extNode == null || extNode.isNull()) {
            return;
        }
        ObjectNode reference = null;
        boolean found = false;
        final String path = extNode.textValue();
        if (path != null && !path.equals("")) {
            reference = (ObjectNode) this.lget(path.split("/"));
            if (reference == null || reference.isNull()) {
                reference = (ObjectNode) global.lget(path.split("/"));
                found = true;
            }
        }
        if (reference != null && !reference.isNull()) {
            Config refConf = null;
            if (reference instanceof Config) {
                refConf = (Config) reference;
            } else {
                refConf = new Config((ObjectNode) reference);
            }

            if (!found) {
                String ref = new UUID().toString();
                global.set(ref, refConf);
            }
            getPointers().add(refConf);
        }
    }
}