All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.config.Configuration Maven / Gradle / Ivy

/*

Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.

Contact:
     SYSTAP, LLC DBA Blazegraph
     2501 Calvert ST NW #106
     Washington, DC 20008
     [email protected]

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*/
/*
 * Created on Nov 23, 2008
 */

package com.bigdata.config;

import java.io.IOException;
import java.util.Properties;
import java.util.UUID;

import org.apache.log4j.Logger;

import com.bigdata.btree.BTree;
import com.bigdata.btree.IndexMetadata;
import com.bigdata.journal.IIndexManager;
import com.bigdata.relation.RelationSchema;
import com.bigdata.service.DataService;
import com.bigdata.service.IBigdataFederation;
import com.bigdata.service.IDataService;
import com.bigdata.util.NV;

/**
 * Base class for managing the initial configuration metadata for indices and
 * locatable resources.
 * 
 * @todo There are some drawbacks with this approach. It remains to be seen
 *       whether this can be improved on readily.
 *       

* We can not report properties that DO NOT correspond to any known * property within the umbrella bigdata namespace (as log4j does) because * we do not make a closed world assumption for properties in that * namespace. *

* We can not interpret properties given in a Java code style (as jini * does with its Configuration object). *

* We are not using the Java beans model so you can not describe property * values or instantiate objects using reflection. Instead, the logic for * that stuff shows up in the code for the class that is being configured. *

* This presumes a fixed syntactic relation between a resource/index and * its container rather than the explicit relation defined by * {@link RelationSchema#CONTAINER}. * * @author Bryan Thompson * @version $Id$ */ public class Configuration { /** * Property values are logged at INFO. */ protected static final transient Logger log = Logger.getLogger(Configuration.class); /** * The prefix for namespace specific property value overrides. */ public static final transient String NAMESPACE = "com.bigdata.namespace"; /** * The namespace separator character. */ public static final transient char DOT = '.'; /** * Return the value for property, which may be the default value, a global * override, or a namespace override. Defaults are assigned by three * mechanisms. *

    * *
  1. Default values are generally described in the javadoc for * Options interfaces. The specific default is supplied by * the caller and will be used if the value is not overridden using any of * the other methods.
  2. * *
  3. The default value may be globally overridden using the property name. * For example, you can override the default branching factor for all * {@link BTree}s by specifying a value for * {@link IndexMetadata.Options#BTREE_BRANCHING_FACTOR}. In general, the * name of the property is declared by an interface along with its default * value.
  4. * *
  5. Any value may be overridden by a value that is specific to the * namespace (or to any prefix of that namespace which can * be formed by chopping off the namespace at a {@link #DOT}). For example, * you can override the branching factor property for an index named * foo.myIndex by specifying a value for the property name * com.bigdata.namespace.foo.myIndex.com.bigdata.btree.BTree.branchingFactor ({@value #NAMESPACE} * is the {@link #NAMESPACE} prefix for overrides, foo.myIndex * is the name of the index, and * {@value IndexMetadata.Options#BTREE_BRANCHING_FACTOR} is the name of the * property that will be overridden for that index). Alternatively you can * override the branching factor for all indices in the "foo" relation by * specifying a value for the property name * com.bigdata.namespace.foo.com.bigdata.btree.BTree.branchingFactor. * Note: You can use {@link #getOverrideProperty(String, String)} to form * these property names automatically, including from within a Jini * configuration file.
  6. * *
* * @param indexManagerIsIgnored * The value specified to the ctor (optional). * @param properties * The properties object against which the value of the property * will be resolved. * @param namespace * The namespace of the index, relation, etc (optional). * @param propertyName * The bare name of the property whose default value is requested * (without the namespace). * @param defaultValue * The value for that property that will be returned if the * default has not been overridden as described above (optional). * * @return The resolved value for the property. * * @todo test when namespace is empty (journal uses that) and possibly null. */ public static String getProperty(final IIndexManager indexManagerIsIgnored, final Properties properties, final String namespace, final String propertyName, final String defaultValue) { final NV nv = getProperty2(indexManagerIsIgnored, properties, namespace, propertyName, defaultValue); if(nv == null) return null; return nv.getValue(); } /** * Variant returns both the name under which the value was discovered and * the value. * * @param indexManagerIsIgnored * @param properties * @param namespace * @param globalName * @param defaultValue * @return */ public static NV getProperty2(final IIndexManager indexManagerIsIgnored, final Properties properties, final String namespace, final String globalName, final String defaultValue) { // indexManager MAY be null. if (properties == null) throw new IllegalArgumentException(); // if (namespace == null) // throw new IllegalArgumentException(); if (globalName == null) throw new IllegalArgumentException(); // defaultValue MAY be null. String key = null; String val = null; final String localName = globalName;//getLocalName(globalName); /* * Look for a namespace match, or a match on any prefix of the namespace * which can be formed by chopping off the last remaining component in * the namespace. */ if (namespace != null) { // right size the buffer. final StringBuilder sb = new StringBuilder(NAMESPACE.length() + 1 + namespace.length() + 1 + localName.length()); /* * Check the full namespace on the first pass then chop off the last * remaining component of each successive pass. */ String prefix = namespace; while (prefix.length() > 0) { sb.setLength(0); // reset each time. sb.append(NAMESPACE); sb.append(DOT); sb.append(prefix); sb.append(DOT); sb.append(localName); // namespace override. val = properties.getProperty(key = sb.toString()); if (val != null) { // Match - will be logged below. break; } if (log.isDebugEnabled()) log.debug("No match: " + key); final int lastIndexOf = prefix.lastIndexOf(DOT); if (lastIndexOf == -1) { // No match. break; } // chop off the last component and try again. prefix = prefix.substring(0, lastIndexOf); } } if (val == null) { // global override. val = properties.getProperty(key = globalName); if( val == null) { // no override. val = defaultValue; } } if (log.isInfoEnabled()) log.info(key + "=" + val); return new NV(key, val); } /** * Variant converts to the specified generic type and validates the value. * * @param * @param indexManager * @param properties * @param namespace * @param globalName * @param defaultValue * @param validator * * @return The validated value -or- null if there was no * default. */ public static E getProperty(final IIndexManager indexManager, final Properties properties, final String namespace, final String globalName, final String defaultValue, final IValidator validator) throws ConfigurationException { if (validator == null) throw new IllegalArgumentException(); final NV nv = getProperty2(indexManager, properties, namespace, globalName, defaultValue); if (nv == null) return null; final E e = validator.parse(nv.getName(), nv.getValue()); validator.accept(nv.getName(), nv.getValue(), e); return e; } // /** // * Return the last component of the globalName. // *

// * Note: If '.' does not appear, then lastIndexOf == -1 and beginIndex := // * lastIndexOf + 1 == 0, so the localName will be the same as the // * globalName. // * // * @param globalName // * The global name of some property. // */ // static protected String getLocalName(String globalName) { // // final int lastIndexOf = globalName.lastIndexOf(DOT); // // final String localName = globalName.substring(lastIndexOf + 1); // // return localName; // // } /** * Resolve the value to a {@link DataService} {@link UUID}. * * @param indexManager * The index manager (optional). * @param val * The value is either a {@link UUID} or a service name. * * @return The {@link UUID} of the identified service -or- null * if no service is identified for that value or if the * indexManager is either not given or not an * {@link IBigdataFederation}. * * @throws IllegalArgumentException * if the val is null. */ static protected UUID resolveDataService(final IIndexManager indexManager, final String val) { if (indexManager == null) return null; if (val == null) throw new IllegalArgumentException(); if (!(indexManager instanceof IBigdataFederation)) return null; final IBigdataFederation fed = ((IBigdataFederation) indexManager); /* * Value is a UUID? */ try { // valid UUID? return UUID.fromString(val); } catch (IllegalArgumentException ex) { // Ignore. } /* * Value is the name of a data service? */ { final IDataService dataService = fed.getDataServiceByName(val); if (dataService != null) { try { return dataService.getServiceUUID(); } catch (IOException ex) { throw new RuntimeException(ex); } } // fall through. } // can't interpret the value. log.warn("Could not resolve: "+val); return null; } /** * Return the name that can be used to override the specified property for * the given namespace. * * @param namespace * The namespace (of an index, relation, etc). * @param property * The global property name. * * @return The name that is used to override that property for that * namespace. */ public static String getOverrideProperty(final String namespace, final String property) { final String override = NAMESPACE + DOT + namespace + DOT + property; if(log.isInfoEnabled()) { log.info("namespace=" + namespace + ", property=" + property + ", override=" + override); } return override; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy