// 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.Maps; import com.google.common.collect.Sets; import org.apache.commons.lang.StringUtils; import java.util.Map; import java.util.Set; /** * @author Matthias Broecheler (me@matthiasb.com) */ public abstract class AbstractConfiguration implements Configuration { private final ConfigNamespace root; protected AbstractConfiguration(ConfigNamespace root) { Preconditions.checkNotNull(root); Preconditions.checkArgument(!root.isUmbrella(),"Root cannot be an umbrella namespace"); this.root = root; } public ConfigNamespace getRootNamespace() { return root; } protected void verifyElement(ConfigElement element) { Preconditions.checkNotNull(element); Preconditions.checkArgument(element.getRoot().equals(root),"Configuration element is not associated with this configuration: %s",element); } protected String getPath(ConfigElement option, String... umbrellaElements) { verifyElement(option); return ConfigElement.getPath(option,umbrellaElements); } protected Set<String> getContainedNamespaces(ReadConfiguration config, ConfigNamespace umbrella, String... umbrellaElements) { verifyElement(umbrella); Preconditions.checkArgument(umbrella.isUmbrella()); String prefix = ConfigElement.getPath(umbrella,umbrellaElements); Set<String> result = Sets.newHashSet(); for (String key : config.getKeys(prefix)) { Preconditions.checkArgument(key.startsWith(prefix)); String sub = key.substring(prefix.length()+1).trim(); if (!sub.isEmpty()) { String ns = ConfigElement.getComponents(sub)[0]; Preconditions.checkArgument(StringUtils.isNotBlank(ns),"Invalid sub-namespace for key: %s",key); result.add(ns); } } return result; } protected Map<String,Object> getSubset(ReadConfiguration config, ConfigNamespace umbrella, String... umbrellaElements) { verifyElement(umbrella); String prefix = umbrella.isRoot() ? "" : ConfigElement.getPath(umbrella, umbrellaElements); Map<String,Object> result = Maps.newHashMap(); for (String key : config.getKeys(prefix)) { Preconditions.checkArgument(key.startsWith(prefix)); // A zero-length prefix is a root. A positive-length prefix // is not a root and we should tack on an additional character // to consume the dot between the prefix and the rest of the key. int startIndex = umbrella.isRoot() ? prefix.length() : prefix.length() + 1; String sub = key.substring(startIndex).trim(); if (!sub.isEmpty()) { result.put(sub,config.get(key,Object.class)); } } return result; } protected static Configuration restrictTo(final Configuration config, final String... fixedUmbrella) { Preconditions.checkArgument(fixedUmbrella!=null && fixedUmbrella.length>0); return new Configuration() { private String[] concat(String... others) { if (others==null || others.length==0) return fixedUmbrella; String[] join = new String[fixedUmbrella.length+others.length]; System.arraycopy(fixedUmbrella,0,join,0,fixedUmbrella.length); System.arraycopy(others,0,join,fixedUmbrella.length,others.length); return join; } @Override public boolean has(ConfigOption option, String... umbrellaElements) { if (option.getNamespace().hasUmbrella()) return config.has(option,concat(umbrellaElements)); else return config.has(option); } @Override public <O> O get(ConfigOption<O> option, String... umbrellaElements) { if (option.getNamespace().hasUmbrella()) return config.get(option,concat(umbrellaElements)); else return config.get(option); } @Override public Set<String> getContainedNamespaces(ConfigNamespace umbrella, String... umbrellaElements) { return config.getContainedNamespaces(umbrella,concat(umbrellaElements)); } @Override public Map<String, Object> getSubset(ConfigNamespace umbrella, String... umbrellaElements) { return config.getSubset(umbrella,concat(umbrellaElements)); } @Override public Configuration restrictTo(String... umbrellaElements) { return config.restrictTo(concat(umbrellaElements)); } }; } public abstract void close(); }