001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.reef.tang;
020
021import org.apache.reef.tang.types.ClassNode;
022import org.apache.reef.tang.types.ConstructorDef;
023import org.apache.reef.tang.types.NamedParameterNode;
024
025import java.util.List;
026import java.util.Set;
027
028/**
029 * Immutable, type-checked configuration data.
030 * <p>
031 * Tang Configuration objects are constructed via
032 * ConfigurationBuilders, and most applications interact with the
033 * Configuration API much more than the one described here.  See
034 * the ConfigurationBuilder documentation for a discussion of the
035 * semantics of configuration options.  The documentation provided
036 * here is primarily for people that wish to extend Tang or implement
037 * formats that export data from Configuration objects to other systems.
038 * <p>
039 * Conceptually, a configuration contains a set of key
040 * value pairs.  Each pair either maps from an interface to an
041 * implementation (a class) or from a configuration option to a
042 * value (e.g., an integer or string).
043 * <p>
044 * Under the hood, Configuration objects carry much richer type
045 * information than this, and also refer to the ClassHierarchy
046 * object they were checked against.  Configurations can be
047 * merged into each other by creating a new ConfigurationBuilder
048 * object, and passing in multiple configurations.  In such situations,
049 * Tang automatically merges the reflection data from the underlying
050 * ClassHierarchy objects, and re-validates the merged configuration
051 * data against the merged classpath.
052 * <p>
053 * Note that the left hand side of each configuration object (the
054 * "key" in the key value pair) is unique.  Although there are many
055 * APIs that take NamedParameterNode objects in this API, a given
056 * NamedParameterNode represents a unique type of binding, and is only
057 * applicable to one of the getters below.  These APIs use Java generic
058 * types to make it easier to map from NamedParameterNode to the appropriate
059 * getter.
060 */
061public interface Configuration {
062
063  /**
064   * Create a new ConfigurationBuilder object based on the same classpath
065   * as this Configuration, and populate it with the configuration options
066   * of this object.
067   * <p>
068   * This API is unstable and should be considered private.  Use the methods
069   * in org.apache.reef.Tang instead.
070   *
071   * @return a new configuration builder
072   */
073  ConfigurationBuilder newBuilder();
074
075  /**
076   * Return the value of the given named parameter as an unparsed string.
077   * <p>
078   * If nothing was explicitly bound, this method returns null (it does not
079   * return default values).
080   *
081   * @param np A NamedParameter object from this Configuration's class hierarchy.
082   * @return The validated string that this parameter is bound to, or null.
083   * @see #getClassHierarchy()
084   */
085  String getNamedParameter(NamedParameterNode<?> np);
086
087  /**
088   * Obtain the set of class hierarchy nodes or strings that were bound to a given NamedParameterNode.
089   * If nothing was explicitly bound, the set will be empty (it will not reflect any default values).
090   *
091   * @param np A NamedParameterNode from this Configuration's class hierarchy.
092   * @return A set of ClassHierarchy Node objects or a set of strings, depending on
093   * whether the NamedParameterNode refers to an interface or configuration options, respectively.
094   * @see #getClassHierarchy()
095   */
096  Set<Object> getBoundSet(NamedParameterNode<Set<?>> np);
097
098  /**
099   * Get the list bound to a given NamedParameterNode. The list will be empty if nothing was bound.
100   *
101   * @param np Target NamedParameter
102   * @return A list bound to np
103   */
104  List<Object> getBoundList(NamedParameterNode<List<?>> np);
105
106  /**
107   * Return the bound constructor.
108   *
109   * @param <T> a type
110   * @param cn a class node
111   * @return the external constructor that cn has been explicitly bound to, or null.  Defaults are not returned.
112   */
113  <T> ClassNode<ExternalConstructor<T>> getBoundConstructor(ClassNode<T> cn);
114
115  /**
116   * Returns the bound implementation.
117   *
118   * @param <T> a type
119   * @param cn a class node
120   * @return the implementation that cn has been explicitly bound to, or null.  Defaults are not returned.
121   */
122  <T> ClassNode<T> getBoundImplementation(ClassNode<T> cn);
123
124  /**
125   * Return the LegacyConstructor that has been bound to this Class.
126   * Such constructors are defined in the class, but missing their @Inject annotation.
127   * <p>
128   * For now, only one legacy constructor can be bound per class.
129   * <p>
130   * TODO: Should this return {@code Set<ConstructorDef<T>>} instead?
131   *
132   * @param <T> a type
133   * @param cn a class node
134   * @return the legacy constructor
135   */
136  <T> ConstructorDef<T> getLegacyConstructor(ClassNode<T> cn);
137
138  /**
139   * @return the set of all interfaces (or super-classes) that have been explicitly
140   * bound to an implementation sub-class.
141   */
142  Set<ClassNode<?>> getBoundImplementations();
143
144  /**
145   * @return the set of all the interfaces that have had an external constructor bound to them.
146   */
147  Set<ClassNode<?>> getBoundConstructors();
148
149  /**
150   * @return the set of all the named parameters that have been explicitly bound to something.
151   */
152  Set<NamedParameterNode<?>> getNamedParameters();
153
154  /**
155   * @return the set of all interfaces that have a legacy constructor binding.
156   */
157  Set<ClassNode<?>> getLegacyConstructors();
158
159  /**
160   * Configuration objects are associated with the ClassHierarchy objects that were used during validation.
161   *
162   * @return the ClassHierarchy that backs this Configuration.
163   */
164  ClassHierarchy getClassHierarchy();
165
166  /**
167   * @return the set of all NamedParameterNodes explicitly bound to sets.
168   */
169  Set<NamedParameterNode<Set<?>>> getBoundSets();
170
171  /**
172   * @return the set of all NamedParameterNodes explicitly bound to lists.
173   */
174  Set<NamedParameterNode<List<?>>> getBoundLists();
175
176}