org.janusgraph.diskstorage.configuration.ConfigElement.java Source code

Java tutorial

Introduction

Here is the source code for org.janusgraph.diskstorage.configuration.ConfigElement.java

Source

// Copyright 2017 JanusGraph Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.janusgraph.diskstorage.configuration;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import org.janusgraph.core.util.ReflectiveConfigOptionLoader;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.HashCodeBuilder;

import java.util.List;

/**
 * @author Matthias Broecheler (me@matthiasb.com)
 */
public abstract class ConfigElement {

    public static final char SEPARATOR = '.';

    public static final char[] ILLEGAL_CHARS = new char[] { SEPARATOR, ' ', '\t', '#', '@', '<', '>', '?', '/', ';',
            '"', '\'', ':', '+', '(', ')', '*', '^', '`', '~', '$', '%', '|', '\\', '{', '[', ']', '}' };

    private final ConfigNamespace namespace;
    private final String name;
    private final String description;

    public ConfigElement(ConfigNamespace namespace, String name, String description) {
        Preconditions.checkArgument(StringUtils.isNotBlank(name), "Name cannot be empty: %s", name);
        Preconditions.checkArgument(!StringUtils.containsAny(name, ILLEGAL_CHARS),
                "Name contains illegal character: %s (%s)", name, ILLEGAL_CHARS);
        Preconditions.checkArgument(namespace != null || this instanceof ConfigNamespace,
                "Need to specify namespace for ConfigOption");
        Preconditions.checkArgument(StringUtils.isNotBlank(description));
        this.namespace = namespace;
        this.name = name;
        this.description = description;
        if (namespace != null)
            namespace.registerChild(this);
    }

    public ConfigNamespace getNamespace() {
        Preconditions.checkArgument(namespace != null, "Cannot get namespace of root");
        return namespace;
    }

    public boolean isRoot() {
        return namespace == null;
    }

    public ConfigNamespace getRoot() {
        if (isRoot())
            return (ConfigNamespace) this;
        else
            return getNamespace().getRoot();
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    public abstract boolean isOption();

    public boolean isNamespace() {
        return !isOption();
    }

    @Override
    public String toString() {
        return (namespace != null ? namespace.toString() + SEPARATOR : "") + name;
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(name).append(namespace).toHashCode();
    }

    @Override
    public boolean equals(Object oth) {
        if (this == oth)
            return true;
        else if (oth == null || !getClass().isInstance(oth))
            return false;
        ConfigElement c = (ConfigElement) oth;
        return name.equals(c.name) && namespace == c.namespace;
    }

    public static String[] getComponents(final String path) {
        return StringUtils.split(path, SEPARATOR);
    }

    public static String toStringSingle(ConfigElement element) {
        return toStringSingle(element, "");
    }

    private static String toStringSingle(ConfigElement element, String indent) {
        String result = element.getName();
        if (element.isNamespace()) {
            result = "+ " + result;
            if (((ConfigNamespace) element).isUmbrella())
                result += " [*]";
        } else {
            result = "- " + result;
            ConfigOption option = (ConfigOption) element;
            result += " [";
            switch (option.getType()) {
            case FIXED:
                result += "f";
                break;
            case GLOBAL_OFFLINE:
                result += "g!";
                break;
            case GLOBAL:
                result += "g";
                break;
            case MASKABLE:
                result += "m";
                break;
            case LOCAL:
                result += "l";
                break;
            }
            result += "," + option.getDatatype().getSimpleName();
            result += "," + option.getDefaultValue();
            result += "]";
        }
        result = indent + result + "\n" + indent;
        String desc = element.getDescription();
        result += "\t" + '"' + desc.substring(0, Math.min(desc.length(), 50)) + '"';
        return result;
    }

    public static String toString(ConfigElement element) {
        //return toStringRecursive(element,"");
        return toStringSingle(element, "");
    }

    //    private static String toStringRecursive(ConfigElement element, String indent) {
    //        String result = toStringSingle(element, indent) + "\n";
    //        if (element.isNamespace()) {
    //            ConfigNamespace ns = (ConfigNamespace)element;
    //            indent += "\t";
    //            for (ConfigElement child : ns.getChildren()) {
    //                result += toStringRecursive(child,indent);
    //            }
    //        }
    //        return result;
    //    }

    public static String getPath(ConfigElement element, String... umbrellaElements) {
        return getPath(element, false, umbrellaElements);
    }

    public static String getPath(ConfigElement element, boolean includeRoot, String... umbrellaElements) {
        Preconditions.checkNotNull(element);
        if (umbrellaElements == null)
            umbrellaElements = new String[0];
        String path = element.getName();
        int umbrellaPos = umbrellaElements.length - 1;
        while (!element.isRoot() && !element.getNamespace().isRoot()) {
            ConfigNamespace parent = element.getNamespace();
            if (parent.isUmbrella()) {
                Preconditions.checkArgument(umbrellaPos >= 0, "Missing umbrella element path for element: %s",
                        element);
                String umbrellaName = umbrellaElements[umbrellaPos];
                Preconditions.checkArgument(!StringUtils.containsAny(umbrellaName, ILLEGAL_CHARS),
                        "Invalid umbrella name provided: %s. Contains illegal chars", umbrellaName);
                path = umbrellaName + SEPARATOR + path;
                umbrellaPos--;
            }
            path = parent.getName() + SEPARATOR + path;
            element = parent;
        }
        if (includeRoot) {
            // Assumes that roots are not umbrellas
            // If roots could be umbrellas, we might have to change the interpretation of umbrellaElements
            path = (element.isRoot() ? element.getName() : element.getNamespace().getName()) + SEPARATOR + path;
        }
        //Don't make this check so that we can still access more general config items
        Preconditions.checkArgument(umbrellaPos < 0, "Found unused umbrella element: %s",
                umbrellaPos < 0 ? null : umbrellaElements[umbrellaPos]);
        return path;
    }

    public static PathIdentifier parse(ConfigNamespace root, String path) {
        Preconditions.checkNotNull(root);
        if (StringUtils.isBlank(path))
            return new PathIdentifier(root, new String[] {}, false);
        String[] components = getComponents(path);
        Preconditions.checkArgument(components.length > 0, "Empty path provided: %s", path);
        List<String> umbrellaElements = Lists.newArrayList();
        ConfigNamespace parent = root;
        ConfigElement last = root;
        boolean lastIsUmbrella = false;
        for (int i = 0; i < components.length; i++) {
            if (parent.isUmbrella() && !lastIsUmbrella) {
                umbrellaElements.add(components[i]);
                lastIsUmbrella = true;
            } else {
                last = parent.getChild(components[i]);
                Preconditions.checkArgument(last != null, "Unknown configuration element in namespace [%s]: %s",
                        parent.toString(), components[i]);
                if (i + 1 < components.length) {
                    Preconditions.checkArgument(last instanceof ConfigNamespace,
                            "Expected namespace at position [%s] of [%s] but got: %s", i, path, last);
                    parent = (ConfigNamespace) last;
                }
                lastIsUmbrella = false;
            }
        }
        return new PathIdentifier(last, umbrellaElements.toArray(new String[umbrellaElements.size()]),
                lastIsUmbrella);
    }

    public static class PathIdentifier {

        public final ConfigElement element;
        public final String[] umbrellaElements;
        public final boolean lastIsUmbrella;

        private PathIdentifier(ConfigElement element, String[] umbrellaElements, boolean lastIsUmbrella) {
            this.lastIsUmbrella = lastIsUmbrella;
            Preconditions.checkNotNull(element);
            Preconditions.checkNotNull(umbrellaElements);
            this.element = element;
            this.umbrellaElements = umbrellaElements;
        }

        public boolean hasUmbrellaElements() {
            return umbrellaElements.length > 0;
        }

    }

}