You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@reef.apache.org by we...@apache.org on 2015/01/23 00:46:49 UTC
[16/51] [partial] incubator-reef git commit: [REEF-93] Move java
sources to lang/java
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Configuration.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Configuration.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Configuration.java
new file mode 100644
index 0000000..af210d3
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Configuration.java
@@ -0,0 +1,167 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang;
+
+import org.apache.reef.tang.types.ClassNode;
+import org.apache.reef.tang.types.ConstructorDef;
+import org.apache.reef.tang.types.NamedParameterNode;
+
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * Immutable, type-checked configuration data.
+ * <p/>
+ * Tang Configuration objects are constructed via
+ * ConfigurationBuilders, and most applications interact with the
+ * Configuration API much more than the one described here. See
+ * the ConfigurationBuilder documentation for a discussion of the
+ * semantics of configuration options. The documentation provided
+ * here is primarily for people that wish to extend Tang or implement
+ * formats that export data from Configuration objects to other systems.
+ * <p/>
+ * Conceptually, a configuration contains a set of key
+ * value pairs. Each pair either maps from an interface to an
+ * implementation (a class) or from a configuration option to a
+ * value (e.g., an integer or string).
+ * <p/>
+ * Under the hood, Configuration objects carry much richer type
+ * information than this, and also refer to the ClassHierarchy
+ * object they were checked against. Configurations can be
+ * merged into each other by creating a new ConfigurationBuilder
+ * object, and passing in multiple configurations. In such situations,
+ * Tang automatically merges the reflection data from the underlying
+ * ClassHierarchy objects, and re-validates the merged configuration
+ * data against the merged classpath.
+ * <p/>
+ * Note that the left hand side of each configuration object (the
+ * "key" in the key value pair) is unique. Although there are many
+ * APIs that take NamedParameterNode objects in this API, a given
+ * NamedParameterNode represents a unique type of binding, and is only
+ * applicable to one of the getters below. These APIs use Java generic
+ * types to make it easier to map from NamedParameterNode to the appropriate
+ * getter.
+ */
+public interface Configuration {
+
+ /**
+ * Create a new ConfigurationBuilder object based on the same classpath
+ * as this Configuration, and populate it with the configuration options
+ * of this object.
+ * <p/>
+ * This API is unstable and should be considered private. Use the methods
+ * in org.apache.reef.Tang instead.
+ */
+ public ConfigurationBuilder newBuilder();
+
+ /**
+ * Return the value of the given named parameter as an unparsed string.
+ * <p/>
+ * If nothing was explicitly bound, this method returns null (it does not
+ * return default values).
+ *
+ * @param np A NamedParameter object from this Configuration's class hierarchy.
+ * @return The validated string that this parameter is bound to, or null.
+ * @see getClassHierarchy()
+ */
+ public String getNamedParameter(NamedParameterNode<?> np);
+
+ /**
+ * Obtain the set of class hierarchy nodes or strings that were bound to a given NamedParameterNode.
+ * If nothing was explicitly bound, the set will be empty (it will not reflect any default values).
+ *
+ * @param np A NamedParameterNode from this Configuration's class hierarchy.
+ * @return A set of ClassHierarchy Node objects or a set of strings, depending on whether the NamedParameterNode refers to an interface or configuration options, respectively.
+ * @see getClassHierarchy()
+ */
+ public Set<Object> getBoundSet(NamedParameterNode<Set<?>> np);
+
+ /**
+ * Get the list bound to a given NamedParameterNode. The list will be empty if nothing was bound.
+ *
+ * @param np Target NamedParameter
+ * @return A list bound to np
+ */
+ public List<Object> getBoundList(NamedParameterNode<List<?>> np);
+
+ /**
+ * @return the external constructor that cn has been explicitly bound to, or null. Defaults are not returned.
+ */
+ public <T> ClassNode<ExternalConstructor<T>> getBoundConstructor(ClassNode<T> cn);
+
+ /**
+ * @return the implementation that cn has been explicitly bound to, or null. Defaults are not returned.
+ */
+ public <T> ClassNode<T> getBoundImplementation(ClassNode<T> cn);
+
+ /**
+ * Return the LegacyConstructor that has been bound to this Class. Such constructors are defined in the class, but missing their @Inject annotation.
+ * <p/>
+ * For now, only one legacy constructor can be bound per class.
+ * <p/>
+ * TODO: Should this return Set<ConstructorDef<T>> instead?
+ */
+ public <T> ConstructorDef<T> getLegacyConstructor(ClassNode<T> cn);
+
+ /**
+ * @return the set of all interfaces (or super-classes) that have been explicitly
+ * bound to an implementation sub-class.
+ */
+ Set<ClassNode<?>> getBoundImplementations();
+
+ /**
+ * @return the set of all the interfaces that have had an external constructor bound to them.
+ */
+ Set<ClassNode<?>> getBoundConstructors();
+
+ /**
+ * @return the set of all the named parameters that have been explicitly bound to something.
+ */
+ Set<NamedParameterNode<?>> getNamedParameters();
+
+ /**
+ * @return the set of all interfaces that have a legacy constructor binding.
+ */
+ Set<ClassNode<?>> getLegacyConstructors();
+
+ /**
+ * Configuration objects are associated with the ClassHierarchy objects that were used during validation.
+ *
+ * @return the ClassHierarchy that backs this Configuration.
+ */
+ public ClassHierarchy getClassHierarchy();
+
+ /**
+ * Get the set bindings from set-valued NamedParameters to the values they were bound to.
+ * <p/>
+ * TODO: This API seems wonky. Why not return a Set<NamedParameterNode<Set<?>>> instead, and let the caller invoke getBoundSet() above?
+ *
+ * @return a flattened set with one entry for each binding (the same NamedParameterNode may be a key for multiple bindings.
+ * @deprecated
+ */
+ @Deprecated
+ Iterable<Entry<NamedParameterNode<Set<?>>, Object>> getBoundSets();
+
+ /**
+ * @return the set of all NamedParameterNodes explicitly bound to lists.
+ */
+ Set<NamedParameterNode<List<?>>> getBoundLists();
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/ConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/ConfigurationBuilder.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/ConfigurationBuilder.java
new file mode 100644
index 0000000..b4152dd
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/ConfigurationBuilder.java
@@ -0,0 +1,251 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang;
+
+import org.apache.reef.tang.exceptions.BindException;
+import org.apache.reef.tang.types.ClassNode;
+import org.apache.reef.tang.types.ConstructorArg;
+import org.apache.reef.tang.types.NamedParameterNode;
+import org.apache.reef.tang.types.Node;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class allows applications to register bindings with Tang. Tang
+ * configurations are simply sets of bindings of various types. The most
+ * common bindings are of interfaces (or superclasses) to implementation
+ * classes, and of configuration options ("NamedParameters") to values.
+ * <p/>
+ * Implementations of this class type check the bindings against an underlying
+ * ClassHierarchy implementation. Typically, the backing ClassHierarchy will
+ * be delegate to the default classloader (the one that loaded the code that is
+ * invoking Tang), though other scenarios are possible. For instance, the
+ * ClassHierarchy could incorporate additional Jars, or it might not delegate
+ * to the default classloader at all. In fact, Tang supports ClassHierarchy
+ * objects that are derived from reflection data from other languages, such as
+ * C#. This enables cross-language injection sessions, where Java code
+ * configures C# code, or vice versa.
+ * <p/>
+ * <p/>
+ * When possible, the methods in this interface eagerly check for these
+ * errors. Methods that check for configuration and other runtime or
+ * application-level errors are declared to throw BindException.
+ * <p/>
+ * Furthermore, all methods in Tang, may throw RuntimeException if they
+ * encounter inconsistencies in the underlying ClassHierarchy. Such errors
+ * reflect problems that existed when the application was compiled or
+ * packaged, and cannot be corrected at runtime. Examples include
+ * inconsistent type hierarchies (such as version mismatches between jars),
+ * and unparsable default values (such as an int that defaults to "false"
+ * or "five"). These exceptions are analogous to the runtime exceptions
+ * thrown by the Java classloader; other than logging them or reporting them
+ * to an end user, applications have little recourse when such problems are
+ * encountered.
+ *
+ * @see JavaConfigurationBuilder for convenience methods that assume the
+ * underlying ClassHierarchy object delegates to the default
+ * classloader, and enable many compile time static checks.
+ * @see ConfigurationModule which pushes additional type checks to class load
+ * time. This allows Tint, Tang's static analysis tool, to detect a wide
+ * range of runtime configuration errors at build time.
+ */
+public interface ConfigurationBuilder {
+
+ /**
+ * Add all configuration parameters from the given Configuration object.
+ *
+ * @param c
+ */
+ public void addConfiguration(final Configuration c) throws BindException;
+
+ /**
+ * Each ConfigurationBuilder instance is associated with a ClassHierarchy.
+ * It uses this ClassHierarchy to validate the configuration options that it
+ * processes.
+ *
+ * @return a reference to the ClassHierarchy instance backing this
+ * ConfigurationBuilder. No copy is made, since ClassHierarchy objects
+ * are effectively immutable.
+ */
+ public ClassHierarchy getClassHierarchy();
+
+ /**
+ * Force Tang to treat the specified constructor as though it had an @Inject
+ * annotation.
+ * <p/>
+ * This method takes ClassNode objects. Like all of the methods in this
+ * API, the ClassNode objects must come from the ClassHierarchy instance
+ * returned by getClassHierarchy().
+ *
+ * @param cn The class the constructor instantiates.
+ * @param args The types of the arguments taken by the constructor, in declaration order.
+ * @throws BindException if the constructor does not exist, or if it has already been bound as a legacy constructor.
+ */
+ void registerLegacyConstructor(ClassNode<?> cn, ClassNode<?>... args)
+ throws BindException;
+
+ /**
+ * Force Tang to treat the specified constructor as though it had an @Inject
+ * annotation.
+ *
+ * @param cn The full name of the class the constructor instantiates.
+ * @param args The full names of the types of the arguments taken by the constructor, in declaration order.
+ * @throws BindException if the constructor does not exist, or if it has already been bound as a legacy constructor.
+ */
+ void registerLegacyConstructor(String cn, String... args)
+ throws BindException;
+
+ /**
+ * Force Tang to treat the specified constructor as though it had an @Inject
+ * annotation.
+ * <p/>
+ * This method takes ClassNode and ConstructorArg objects. Like all of the
+ * methods in this API, these objects must come from the ClassHierarchy
+ * instance returned by getClassHierarchy().
+ *
+ * @param cn The class the constructor instantiates.
+ * @param args The parsed ConstructorArg objects correspdonding to the types of the arguments taken by the constructor, in declaration order.
+ * @throws BindException if the constructor does not exist, or if it has already been bound as a legacy constructor.
+ */
+ void registerLegacyConstructor(ClassNode<?> c, ConstructorArg... args)
+ throws BindException;
+
+ /**
+ * Bind classes to each other, based on their full class names; alternatively,
+ * bound a NamedParameter configuration option to a configuration value.
+ *
+ * @param iface The full name of the interface that should resolve to impl,
+ * or the NamedParameter to be set.
+ * @param impl The full name of the implementation that will be used in
+ * place of impl, or the value the NamedParameter should be set to.
+ * @throws BindException If (In the case of interfaces and implementations)
+ * the underlying ClassHierarchy does not recognice iface and
+ * impl as known, valid classes, or if impl is not a in
+ * implementation of iface, or (in the case of NamedParameters
+ * and values) if iface is not a NamedParameter, or if impl
+ * fails to parse as the type the iface expects.
+ */
+ public <T> void bind(String iface, String impl)
+ throws BindException;
+
+ /**
+ * Bind classes to each other, based on their full class names; alternatively,
+ * bound a NamedParameter configuration option to a configuration value.
+ * <p/>
+ * This method takes Node objects. Like all of the methods in this API,
+ * these objects must come from the ClassHierarchy instance returned by
+ * getClassHierarchy().
+ *
+ * @param key The interface / NamedParmaeter to be bound.
+ * @param value The implementation / value iface should be set to.
+ * @throws BindException if there is a type checking error
+ * @see bind(String, String) for a more complete description.
+ */
+ void bind(Node iface, Node impl) throws BindException;
+
+ /**
+ * Register an ExternalConstructor implementation with Tang.
+ * ExternalConstructors are proxy classes that instantiate some
+ * other class. They have two primary use cases: (1) adding new
+ * constructors to classes that you cannot modify and (2) implementing
+ * constructors that exmanine their arguments and return an instance of a
+ * subclass of the requested object.
+ * <p/>
+ * To see how the second use case could be useful, consider a implementing a
+ * URI interface with a distinct subclass for each valid URI prefix (e.g.,
+ * http://, ssh://, etc...). An ExternalConstructor could examine the prefix
+ * and delegate to a constructor of the correct implementation (e.g, HttpURL,
+ * SshURL, etc...) which would validate the remainder of the provided string.
+ * URI's external constructor would return the validated subclass of URI that
+ * corresponds to the provided string, allowing instanceof and downcasts to
+ * behave as expected in the code that invoked Tang.
+ * <p/>
+ * Both use cases should be avoided when possible, since they can
+ * unnecessarily complicate object injections and undermine Tang's ability
+ * to statically check a given configuration.
+ * <p/>
+ * This method takes ClassNode objects. Like all of the methods in this API,
+ * these objects must come from the ClassHierarchy instance returned by
+ * getClassHierarchy().
+ *
+ * @param iface The class or interface to be instantiated.
+ * @param impl The ExternalConstructor class that will be used to instantiate iface.
+ * @throws BindException If impl does not instantiate a subclass of iface.
+ */
+ public <T> void bindConstructor(ClassNode<T> iface,
+ ClassNode<? extends ExternalConstructor<? extends T>> impl)
+ throws BindException;
+
+ /**
+ * Pretty print the default implementation / value of the provided class / NamedParamter.
+ * This is used by Tang to produce human readable error messages.
+ */
+ public String classPrettyDefaultString(String longName) throws BindException;
+
+ /**
+ * Pretty print the human readable documentation of the provided class / NamedParamter.
+ * This is used by Tang to produce human readable error messages.
+ */
+ public String classPrettyDescriptionString(String longName)
+ throws BindException;
+
+ /**
+ * Produce an immutable Configuration object that contains the current
+ * bindings and ClassHierarchy of this ConfigurationBuilder. Future
+ * changes to this ConfigurationBuilder will not be reflected in the
+ * returned Configuration.
+ * <p/>
+ * Since Tang eagerly checks for configuration errors, this method does not
+ * perform any additional validation, and does not throw any checkable
+ * exceptions.
+ *
+ * @return
+ */
+ public Configuration build();
+
+ public <T> void bindSetEntry(NamedParameterNode<Set<T>> iface, Node impl)
+ throws BindException;
+
+ public <T> void bindSetEntry(NamedParameterNode<Set<T>> iface, String impl)
+ throws BindException;
+
+ public void bindSetEntry(String iface, String impl) throws BindException;
+
+ public void bindSetEntry(String iface, Node impl) throws BindException;
+
+ /**
+ * Bind an list of implementations(Class or String) to an given NamedParameter.
+ * Unlike bindSetEntry, bindListEntry will bind a whole list to the parameter,
+ * not an element of the list.
+ * <p/>
+ * Since ordering of the list is important, list binding cannot be repeated or
+ * merged unlike set binding. If the elements of the list are Classes, the objects
+ * created by the Classes will be injected. If the elements are Strings, the values
+ * will be injected directly to a given list parameter.
+ *
+ * @param iface The list named parameter to be instantiated
+ * @param implList The list of class or value will be used to instantiated the named parameter
+ * @throws BindException
+ */
+ public <T> void bindList(NamedParameterNode<List<T>> iface, List implList) throws BindException;
+
+ public void bindList(String iface, List implList) throws BindException;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Configurations.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Configurations.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Configurations.java
new file mode 100644
index 0000000..a7450bc
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Configurations.java
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang;
+
+/**
+ * Helper class for Configurations
+ */
+public final class Configurations {
+
+ /**
+ * This is a utility class that isn't meant to be instantiated.
+ */
+ private Configurations() {
+ }
+
+
+ /**
+ * Merge a set of Configurations.
+ *
+ * @param configurations
+ * @return the merged configuration.
+ * @throws org.apache.reef.tang.exceptions.BindException if the merge fails.
+ */
+ public static Configuration merge(final Configuration... configurations) {
+ return Tang.Factory.getTang().newConfigurationBuilder(configurations).build();
+ }
+
+ /**
+ * Merge a set of Configurations.
+ *
+ * @param configurations
+ * @return the merged configuration.
+ * @throws org.apache.reef.tang.exceptions.BindException if the merge fails.
+ */
+ public static Configuration merge(final Iterable<Configuration> configurations) {
+ final ConfigurationBuilder configurationBuilder = Tang.Factory.getTang().newConfigurationBuilder();
+ for (final Configuration configuration : configurations) {
+ configurationBuilder.addConfiguration(configuration);
+ }
+ return configurationBuilder.build();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/ExternalConstructor.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/ExternalConstructor.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/ExternalConstructor.java
new file mode 100644
index 0000000..7fb9fcc
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/ExternalConstructor.java
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang;
+
+/**
+ * This interface allows legacy classes to be injected by
+ * ConfigurationBuilderImpl. To be of any use, implementations of this class
+ * must have at least one constructor with an @Inject annotation. From
+ * ConfigurationBuilderImpl's perspective, an ExternalConstructor class is just
+ * a special instance of the class T, except that, after injection an
+ * ExternalConstructor, ConfigurationBuilderImpl will call newInstance, and
+ * store the resulting object. It will then discard the ExternalConstructor.
+ *
+ * @param <T> The type this ExternalConstructor will create.
+ * @author sears
+ */
+public interface ExternalConstructor<T> {
+ /**
+ * This method will only be called once.
+ *
+ * @return a new, distinct instance of T.
+ */
+ public T newInstance();
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/InjectionFuture.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/InjectionFuture.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/InjectionFuture.java
new file mode 100644
index 0000000..0cdc522
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/InjectionFuture.java
@@ -0,0 +1,136 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang;
+
+import org.apache.reef.tang.annotations.Name;
+import org.apache.reef.tang.exceptions.InjectionException;
+import org.apache.reef.tang.implementation.java.InjectorImpl;
+
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A future-based mechanism for cyclic object injections. Since Tang is a
+ * constructor-based dependency injector, there is no way to directly create
+ * cycles of objects.
+ * <p/>
+ * In situations where you need to have two objects that point at each other, you
+ * can use an InjectionFuture to break the cycle. Simply ask Tang to inject an
+ * InjectionFuture<T> into your constructor. Later (after your constructor
+ * returns) invoke the get() method of the injection future to get a reference
+ * to an injected object of type T.
+ * <p/>
+ * Note that InjectorFutures and singletons interact in subtle ways.
+ * <p/>
+ * Normally, Tang never reuses a reference to an injected object unless the
+ * object is a singleton or a volatile instance. If InjectionFutures followed
+ * this convention, then a cyclic injection of two non-singleton classes would
+ * result in an an infinite chain of objects of the two types. Tang addresses
+ * this issue as follows:
+ * <p/>
+ * 1) In the first pass, it injects a complete object tree, making note of
+ * InjectionFuture objects that will need to be populated later. The injection
+ * of this tree respects standard Tang singleton and volatile semantics.
+ * <p/>
+ * 2) In a second pass, Tang populates each of the InjectionFutures with the
+ * reference to the requested class that was instantiated in the first pass. If
+ * this reference does not exist (or is non-unique) then an InjectionException
+ * is thrown.
+ * <p/>
+ * Note: The semantics of complex cyclic injections may change over time.
+ * <p/>
+ * We haven't seen many complicated injections that involve cycles in practice.
+ * A second approach would be to establish some scoping rules, so that each
+ * InjectionFuture binds to the innermost matching parent in the InjectionPlan.
+ * This would allow plans to inject multiple cycles involving distinct objects
+ * of the same type.
+ *
+ * @param <T>
+ */
+
+public final class InjectionFuture<T> implements Future<T> {
+
+ protected final InjectorImpl injector;
+
+ private final Class<? extends T> iface;
+
+ private final T instance;
+
+ public InjectionFuture() {
+ injector = null;
+ iface = null;
+ instance = null;
+ }
+
+ public InjectionFuture(final Injector injector, Class<? extends T> iface) {
+ this.injector = (InjectorImpl) injector;
+ this.iface = iface;
+ this.instance = null;
+ }
+
+ public InjectionFuture(T instance) {
+ this.injector = null;
+ this.iface = null;
+ this.instance = instance;
+ }
+
+ @Override
+ public final boolean cancel(boolean mayInterruptIfRunning) {
+ return false;
+ }
+
+ @Override
+ public final boolean isCancelled() {
+ return false;
+ }
+
+ @Override
+ public final boolean isDone() {
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public T get() {
+ if (instance != null) return instance;
+ try {
+ synchronized (injector) {
+ final T t;
+ if (Name.class.isAssignableFrom(iface)) {
+ t = injector.getNamedInstance((Class<Name<T>>) iface);
+ } else {
+ t = injector.getInstance(iface);
+ }
+ Aspect a = injector.getAspect();
+ if (a != null) {
+ a.injectionFutureInstantiated(this, t);
+ }
+ return t;
+ }
+ } catch (InjectionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public T get(long timeout, TimeUnit unit) {
+ throw new UnsupportedOperationException();
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Injector.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Injector.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Injector.java
new file mode 100644
index 0000000..198f2f3
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Injector.java
@@ -0,0 +1,133 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang;
+
+import org.apache.reef.tang.annotations.Name;
+import org.apache.reef.tang.exceptions.BindException;
+import org.apache.reef.tang.exceptions.InjectionException;
+import org.apache.reef.tang.exceptions.NameResolutionException;
+import org.apache.reef.tang.implementation.InjectionPlan;
+
+public interface Injector {
+
+ /**
+ * Gets an instance of iface, or the implementation that has been bound to it.
+ * If an instance has alread been created in this (or a parent) scope, then
+ * the existing instance will be returned. Otherwise, a new instance will be
+ * returned, and registered in the current scope.
+ *
+ * @param iface
+ * @return
+ * @throws NameResolutionException
+ * @throws ReflectiveOperationException
+ */
+ public <U> U getInstance(Class<U> iface) throws InjectionException;
+
+ public <U> U getInstance(String iface) throws InjectionException,
+ NameResolutionException;
+
+ /**
+ * Gets the value stored for the given named parameter.
+ *
+ * @param <U>
+ * @param name
+ * @return an Instance of the class configured as the implementation for the
+ * given interface class.
+ * @throws InjectionException
+ */
+ public <U> U getNamedInstance(Class<? extends Name<U>> iface)
+ throws InjectionException;
+
+ /**
+ * Binds the given object to the class. Note that this only affects objects
+ * created by the returned Injector and its children. Also, like all
+ * Injectors, none of those objects can be serialized back to a configuration
+ * file).
+ *
+ * @param iface
+ * @param inst
+ * @return A copy of this injector that reflects the new binding.
+ * @throws BindException
+ */
+ public <T> void bindVolatileInstance(Class<T> iface, T inst)
+ throws BindException;
+
+ public <T> void bindVolatileParameter(Class<? extends Name<T>> iface, T inst)
+ throws BindException;
+
+ /**
+ * Binds a TANG Aspect to this injector. Tang Aspects interpose on each
+ * injection performed by an injector, and return an instance of their choosing.
+ * <p/>
+ * A given aspect will be invoked once for each object that Tang injects, and aspects
+ * will be copied in a way that mirrors the scoping that Tang creates at runtime.
+ *
+ * @param a
+ * @throws BindException
+ */
+ public <T> void bindAspect(Aspect a) throws BindException;
+
+ /**
+ * Allows InjectionFuture to tell the aspect when get() is invoked. Package private.
+ *
+ * @return
+ */
+ Aspect getAspect();
+
+ /**
+ * Create a copy of this Injector that inherits the instances that were already
+ * created by this Injector, but reflects additional Configuration objects.
+ * This can be used to create trees of Injectors that obey hierarchical
+ * scoping rules.
+ * <p/>
+ * <p/>
+ * Except for the fact that the child Injector will have references to this
+ * injector's instances, the returned Injector is equivalent to the one you
+ * would get by using ConfigurationBuilder to build a merged Configuration,
+ * and then using the merged Configuration to create an Injector. Injectors
+ * returned by ConfigurationBuilders are always independent, and never
+ * share references to the same instances of injected objects.
+ *
+ * @throws BindException If any of the configurations conflict with each other, or the
+ * existing Injector's Configuration.
+ */
+ public Injector forkInjector(Configuration... configurations) throws BindException;
+
+ /**
+ * Returns true if this Injector is able to instantiate the object named by
+ * name.
+ *
+ * @param name
+ * @return
+ * @throws BindException
+ */
+ boolean isInjectable(String name) throws BindException;
+
+ boolean isParameterSet(String name) throws BindException;
+
+ boolean isInjectable(Class<?> clazz) throws BindException;
+
+ boolean isParameterSet(Class<? extends Name<?>> name) throws BindException;
+
+ InjectionPlan<?> getInjectionPlan(String name) throws NameResolutionException;
+
+ <T> InjectionPlan<T> getInjectionPlan(Class<T> name);
+
+ Injector forkInjector();
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/JavaClassHierarchy.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/JavaClassHierarchy.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/JavaClassHierarchy.java
new file mode 100644
index 0000000..27aa6cb
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/JavaClassHierarchy.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang;
+
+import org.apache.reef.tang.exceptions.ClassHierarchyException;
+import org.apache.reef.tang.exceptions.ParseException;
+import org.apache.reef.tang.types.NamedParameterNode;
+import org.apache.reef.tang.types.Node;
+
+public interface JavaClassHierarchy extends ClassHierarchy {
+ /**
+ * Look up a class object in this ClassHierarchy. Unlike the version that
+ * takes a string in ClassHierarchy, this version does not throw
+ * NameResolutionException.
+ * <p/>
+ * The behavior of this method is undefined if the provided Class object is
+ * not from the ClassLoader (or an ancestor of the ClassLoader) associated
+ * with this JavaClassHierarchy. By default, Tang uses the default runtime
+ * ClassLoader as its root ClassLoader, so static references (expressions like
+ * getNode(Foo.class)) are safe.
+ *
+ * @param c The class to be looked up in the class hierarchy.
+ * @return The associated NamedParameterNode or ClassNode.
+ */
+ public Node getNode(Class<?> c);
+
+ public Class<?> classForName(String name) throws ClassNotFoundException;
+
+ /**
+ * Parse a string value that has been passed into a named parameter.
+ *
+ * @param name The named parameter that will receive the value.
+ * @param value A string value to be validated and parsed.
+ * @return An instance of T, or a ClassNode<? extends T>.
+ * @throws ParseException if the value failed to parse, or parsed to the
+ * wrong type (such as when it specifies a class that does not implement
+ * or extend T).
+ */
+ public <T> T parse(NamedParameterNode<T> name, String value) throws ParseException;
+
+ /**
+ * Obtain a parsed instance of the default value of a named parameter
+ *
+ * @param name The named parameter that should be checked for a default instance.
+ * @return The default instance or null, unless T is a set type. If T is a set,
+ * then this method returns a (potentially empty) set of default instances.
+ * @throws ClassHierarchyException if an instance failed to parse.
+ */
+ public <T> T parseDefaultValue(NamedParameterNode<T> name) throws ClassHierarchyException;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/JavaConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/JavaConfigurationBuilder.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/JavaConfigurationBuilder.java
new file mode 100644
index 0000000..ace0080
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/JavaConfigurationBuilder.java
@@ -0,0 +1,98 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang;
+
+
+import org.apache.reef.tang.annotations.Name;
+import org.apache.reef.tang.exceptions.BindException;
+import org.apache.reef.tang.exceptions.NameResolutionException;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Convenience methods that extend the ConfigurationBuilder but assume that
+ * the underlying ClassHierarchy delegates to the default Java classloader.
+ * <p/>
+ * In addition to being less verbose, this interface expresses many of Tang's
+ * type checks in Java's generic type system. This improves IDE
+ * auto-completion. It also allows the errors to be caught at compile time
+ * instead of later on in the build process, or at runtime.
+ *
+ * @see ConfigurationModule which pushes additional type checks to class load
+ * time. This allows Tint, Tang's static analysis tool, to detect a wide
+ * range of runtime configuration errors at build time.
+ */
+public interface JavaConfigurationBuilder extends ConfigurationBuilder {
+
+ /**
+ * Bind named parameters, implementations or external constructors, depending
+ * on the types of the classes passed in.
+ *
+ * @param iface
+ * @param impl
+ */
+ public <T> JavaConfigurationBuilder bind(Class<T> iface, Class<?> impl) throws BindException;
+
+ /**
+ * Binds the Class impl as the implementation of the interface iface
+ *
+ * @param <T>
+ * @param iface
+ * @param impl
+ */
+ public <T> JavaConfigurationBuilder bindImplementation(Class<T> iface, Class<? extends T> impl)
+ throws BindException;
+
+
+ /**
+ * Set the value of a named parameter.
+ *
+ * @param name The dummy class that serves as the name of this parameter.
+ * @param value A string representing the value of the parameter. Reef must know
+ * how to parse the parameter's type.
+ * @throws NameResolutionException
+ */
+ public JavaConfigurationBuilder bindNamedParameter(Class<? extends Name<?>> name, String value)
+ throws BindException;
+
+ public <T> JavaConfigurationBuilder bindNamedParameter(Class<? extends Name<T>> iface,
+ Class<? extends T> impl) throws BindException;
+
+ public <T> JavaConfigurationBuilder bindConstructor(Class<T> c,
+ Class<? extends ExternalConstructor<? extends T>> v) throws BindException;
+
+ public <T> JavaConfigurationBuilder bindSetEntry(Class<? extends Name<Set<T>>> iface, String value) throws BindException;
+
+ public <T> JavaConfigurationBuilder bindSetEntry(Class<? extends Name<Set<T>>> iface, Class<? extends T> impl) throws BindException;
+
+ /**
+ * Binds a specfic list to a named parameter. List's elements can be string values or class implementations.
+ * Their type would be checked in this method. If their types are not applicable to the named parameter,
+ * it will make an exception.
+ *
+ * @param iface The target named parameter to be injected into
+ * @param impl A concrete list
+ * @param <T>
+ * @return
+ * @throws BindException
+ */
+ public <T> JavaConfigurationBuilder bindList(Class<? extends Name<List<T>>> iface, List impl)
+ throws BindException;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Tang.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Tang.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Tang.java
new file mode 100644
index 0000000..3bba253
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Tang.java
@@ -0,0 +1,149 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang;
+
+import org.apache.reef.tang.exceptions.BindException;
+import org.apache.reef.tang.implementation.TangImpl;
+
+import java.net.URL;
+
+/**
+ * The root factory interface for Tang. This interface allows callers to
+ * instantiate Tang's core API, and is responsible for memoization and other
+ * runtime optimizations.
+ */
+public interface Tang {
+
+ /**
+ * Returns an Injector for the given Configurations.
+ *
+ * @throws BindException If the confs conflict, a BindException will be thrown.
+ */
+ public Injector newInjector(final Configuration... confs)
+ throws BindException;
+
+ /**
+ * Returns an Injector for the given Configuration.
+ */
+ public Injector newInjector(final Configuration confs);
+
+ /**
+ * Returns an Injector based on an empty Configuration.
+ */
+ public Injector newInjector();
+
+ /**
+ * Return a new ConfigurationBuilder that is backed by the provided
+ * ClassHierarchy object.
+ *
+ * @param ch Any valid Tang ClassHierarchy, including ones derived from non-Java application binaries.
+ * @return an instance of ConfigurationBuilder. In Tang's default implementation this returns an instance or JavaConfigurationBuilder if ch is backed by a Java classloader.
+ */
+ public ConfigurationBuilder newConfigurationBuilder(ClassHierarchy ch);
+
+ /**
+ * Create a new ConfigurationBuilder that is backed by the default
+ * classloader and the provided jars. Following standard Java's semantics,
+ * when looking up a class, Tang will consult the default classloader first,
+ * then the first classpath entry / jar passed to this method, then the
+ * second, and so on.
+ *
+ * @return a new JavaConfigurationBuilder
+ */
+ public JavaConfigurationBuilder newConfigurationBuilder(URL... jars);
+
+ /**
+ * Merge a set of configurations into a new JavaConfiurationBuilder. If
+ * the configurations conflict, this method will throw a bind exception.
+ * <p/>
+ * The underlying ClassHierarchies and parameter parsers of the
+ * configurations will be checked for consistency. The returned
+ * configuration builder will be backed by a ClassHierachy that incorporates
+ * the classpath and parsers from all of the provided Configurations.
+ *
+ * @return a new ConfigurationBuilder
+ * @throws BindException if any of the configurations contain duplicated or
+ * conflicting bindings, or if the backing ClassHierarchy objects conflict
+ * in some way.
+ */
+ public JavaConfigurationBuilder newConfigurationBuilder(Configuration... confs)
+ throws BindException;
+
+ /**
+ * Create an empty JavaConfigurationBuilder that is capable of parsing
+ * application-specific configuration values. The returned
+ * JavaConfigurationBuilder will be backed by the default classloader.
+ *
+ * @return a new ConfigurationBuilder
+ */
+ public JavaConfigurationBuilder newConfigurationBuilder(@SuppressWarnings("unchecked") Class<? extends ExternalConstructor<?>>... parameterParsers)
+ throws BindException;
+
+ /**
+ * Create a new JavaConfiguration builder that has additional jars,
+ * incorporates existing configuration data and / or can parse
+ * application-specific types.
+ *
+ * @see The documentation for the other newConfigurationBuilder methods in
+ * this class for detailed information about each of the parameters to
+ * this method.
+ */
+ public JavaConfigurationBuilder newConfigurationBuilder(URL[] jars,
+ Configuration[] confs, Class<? extends ExternalConstructor<?>>[] parameterParsers) throws BindException;
+
+ /**
+ * Create a new empty ConfigurationBuilder that is backed by the default
+ * classloader.
+ */
+ public JavaConfigurationBuilder newConfigurationBuilder();
+
+ /**
+ * @return an instance of JavaClassHierarchy that is backed by the default
+ * Java classloader. ClassHierarchy objects are immutable, so multiple
+ * invocations of this method may return the same instance.
+ */
+ public JavaClassHierarchy getDefaultClassHierarchy();
+
+ /**
+ * @return a custom instance of JavaClassHierarchy. ClassHierarchy objects
+ * are immutable, so multiple invocations of this method may return the
+ * same instance.
+ * @TODO Is the class hierarchy returned here backed by the default
+ * classloader or not? If not, then callers will need to merge it with
+ * getDefaultClassHierarchy(). If so, we should add a new method like
+ * getNonDefaultClassHiearchy() that takes the same options as this one.
+ */
+ public JavaClassHierarchy getDefaultClassHierarchy(URL[] jars, Class<? extends ExternalConstructor<?>>[] parsers);
+
+ /**
+ * A factory that returns the default implementation of the Tang interface.
+ */
+ public final class Factory {
+ /**
+ * Return an instance of the default implementation of Tang.
+ *
+ * @return
+ */
+ public static Tang getTang() {
+ return new TangImpl();
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/DefaultImplementation.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/DefaultImplementation.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/DefaultImplementation.java
new file mode 100644
index 0000000..cfeb13b
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/DefaultImplementation.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.annotations;
+
+import java.lang.annotation.*;
+
+/**
+ * Allows interfaces to specify a default implementation.
+ * <p/>
+ * Note that the default can be overridden after the fact
+ * by explicitly binding a different implementation to the
+ * interface.
+ * <p/>
+ * For "normal" injections of a given library, this reduces
+ * the amount of boilerplate configuration code needed,
+ * and also shrinks the Tang configuration objects that
+ * need to be passed around.
+ */
+@Target(ElementType.TYPE)
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DefaultImplementation {
+ Class<?> value() default Void.class;
+
+ String name() default "";
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/Name.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/Name.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/Name.java
new file mode 100644
index 0000000..f450e1f
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/Name.java
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.annotations;
+
+public interface Name<T> {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/NamedParameter.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/NamedParameter.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/NamedParameter.java
new file mode 100644
index 0000000..2b400f1
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/NamedParameter.java
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.annotations;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.TYPE)
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface NamedParameter {
+ //Class<?> type() default String.class;
+ String doc() default "";
+
+ String short_name() default "";
+
+ // One of the following should be set.
+ String default_value() default "";
+
+ Class<?> default_class() default Void.class;
+
+ String[] default_values() default {};
+
+ Class<?>[] default_classes() default {};
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/Parameter.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/Parameter.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/Parameter.java
new file mode 100644
index 0000000..543843e
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/Parameter.java
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Target(ElementType.PARAMETER)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Parameter {
+ Class<? extends Name<? extends Object>> value();
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/Unit.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/Unit.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/Unit.java
new file mode 100644
index 0000000..093069c
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/Unit.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * A TANG Unit consists of an outer class and some non-static inner classes.
+ * TANG injectors automatically treat all the classes in a unit as singletons.
+ * <p/>
+ * In order to inject the singleton instance of each inner class, TANG first
+ * instantiates the outer class and then uses the resulting instance to
+ * instantiate each inner class.
+ * <p/>
+ * Classes annotated in this way must have at least one non-static inner class
+ * and no static inner classes. The inner classes must not declare any
+ * constructors.
+ * <p/>
+ * Furthermore, classes annotated with Unit may not have injectable (or Unit)
+ * subclasses.
+ *
+ * @author sears
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Unit {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/package-info.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/package-info.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/package-info.java
new file mode 100644
index 0000000..b8d11f2
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/annotations/package-info.java
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+/**
+ Annotations that application developers can use to register configuration
+ metadata with Tang.
+ */
+package org.apache.reef.tang.annotations;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/PrintTypeHierarchy.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/PrintTypeHierarchy.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/PrintTypeHierarchy.java
new file mode 100644
index 0000000..1f60718
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/PrintTypeHierarchy.java
@@ -0,0 +1,105 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.examples;
+
+import org.apache.reef.tang.Configuration;
+import org.apache.reef.tang.ConfigurationBuilder;
+import org.apache.reef.tang.Injector;
+import org.apache.reef.tang.Tang;
+import org.apache.reef.tang.annotations.Name;
+import org.apache.reef.tang.annotations.NamedParameter;
+import org.apache.reef.tang.annotations.Parameter;
+import org.apache.reef.tang.exceptions.BindException;
+import org.apache.reef.tang.exceptions.InjectionException;
+import org.apache.reef.tang.formats.CommandLine;
+import org.apache.reef.tang.implementation.InjectionPlan;
+import org.apache.reef.tang.util.walk.graphviz.GraphvizConfigVisitor;
+import org.apache.reef.tang.util.walk.graphviz.GraphvizInjectionPlanVisitor;
+
+import javax.inject.Inject;
+import java.io.FileWriter;
+import java.io.IOException;
+
+/**
+ * Build a Graphviz representation of TANG configuration and injection plan.
+ */
+public final class PrintTypeHierarchy {
+
+ /**
+ * Parameter to test the injection.
+ */
+ private final transient int id;
+
+ /**
+ * Constructor to test the parameter injection.
+ *
+ * @param aId test parameter
+ */
+ @Inject
+ public PrintTypeHierarchy(@Parameter(PrintTypeHierarchy.Id.class) final int id) {
+ this.id = id;
+ }
+
+ /**
+ * @param args command line arguments.
+ * @throws BindException configuration error.
+ * @throws InjectionException configuration error.
+ * @throws IOException cannot process command line parameters.
+ */
+ public static void main(final String[] args)
+ throws BindException, InjectionException, IOException {
+
+ final Tang tang = Tang.Factory.getTang();
+ final ConfigurationBuilder confBuilder = tang.newConfigurationBuilder();
+
+ new CommandLine(confBuilder).processCommandLine(args);
+ final Configuration config = confBuilder.build();
+
+ final Injector injector = tang.newInjector(config);
+ final PrintTypeHierarchy myself = injector.getInstance(PrintTypeHierarchy.class);
+
+ try (final FileWriter out = new FileWriter("type-hierarchy.dot")) {
+ out.write(GraphvizConfigVisitor.getGraphvizString(config, true, true));
+ }
+
+ final InjectionPlan<PrintTypeHierarchy> plan =
+ injector.getInjectionPlan(PrintTypeHierarchy.class);
+
+ try (final FileWriter out = new FileWriter("injection-plan.dot")) {
+ out.write(GraphvizInjectionPlanVisitor.getGraphvizString(plan, true));
+ }
+
+ System.out.println(myself);
+ }
+
+ /**
+ * @return string representation of the object.
+ */
+ @Override
+ public String toString() {
+ return this.getClass().getName() + " :: " + this.id;
+ }
+
+ /**
+ * Parameter to test the injection.
+ */
+ @NamedParameter(default_value = "999", doc = "Test parameter", short_name = "id")
+ class Id implements Name<Integer> {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/Timer.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/Timer.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/Timer.java
new file mode 100644
index 0000000..5cc5e34
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/Timer.java
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.examples;
+
+import org.apache.reef.tang.Configuration;
+import org.apache.reef.tang.JavaConfigurationBuilder;
+import org.apache.reef.tang.Tang;
+import org.apache.reef.tang.annotations.Name;
+import org.apache.reef.tang.annotations.NamedParameter;
+import org.apache.reef.tang.annotations.Parameter;
+import org.apache.reef.tang.formats.CommandLine;
+import org.apache.reef.tang.formats.ConfigurationFile;
+import org.apache.reef.tang.implementation.InjectionPlan;
+import org.apache.reef.tang.implementation.java.InjectorImpl;
+
+import javax.inject.Inject;
+
+public class Timer {
+ private final int seconds;
+
+ @Inject
+ public Timer(@Parameter(Seconds.class) int seconds) {
+ if (seconds < 0) {
+ throw new IllegalArgumentException("Cannot sleep for negative time!");
+ }
+ this.seconds = seconds;
+ }
+
+ public static void main(String[] args) throws Exception {
+ Tang tang = Tang.Factory.getTang();
+ JavaConfigurationBuilder cb = tang.newConfigurationBuilder();
+ CommandLine cl = new CommandLine(cb);
+ cl.registerShortNameOfClass(Timer.Seconds.class);
+ cl.processCommandLine(args);
+ Configuration conf = cb.build();
+ System.out.println("start conf");
+ System.out.println(ConfigurationFile.toConfigurationString(conf));
+ System.out.println("end conf");
+ InjectorImpl injector = (InjectorImpl) tang.newInjector(conf);
+ InjectionPlan<Timer> ip = injector.getInjectionPlan(Timer.class);
+ System.out.println(ip.toPrettyString());
+ System.out.println("Number of plans:" + ip.getNumAlternatives());
+ Timer timer = injector.getInstance(Timer.class);
+ System.out.println("Tick...");
+ timer.sleep();
+ System.out.println("Tock.");
+ }
+
+ public void sleep() throws InterruptedException {
+ java.lang.Thread.sleep(seconds * 1000);
+ }
+
+ @NamedParameter(default_value = "10",
+ doc = "Number of seconds to sleep", short_name = "sec")
+ class Seconds implements Name<Integer> {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/TimerV1.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/TimerV1.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/TimerV1.java
new file mode 100644
index 0000000..fca0635
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/TimerV1.java
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.examples;
+
+import org.apache.reef.tang.Configuration;
+import org.apache.reef.tang.Injector;
+import org.apache.reef.tang.JavaConfigurationBuilder;
+import org.apache.reef.tang.Tang;
+import org.apache.reef.tang.annotations.Name;
+import org.apache.reef.tang.annotations.NamedParameter;
+import org.apache.reef.tang.annotations.Parameter;
+import org.apache.reef.tang.exceptions.BindException;
+import org.apache.reef.tang.exceptions.InjectionException;
+
+import javax.inject.Inject;
+
+public class TimerV1 {
+
+ private final int seconds;
+
+ @Inject
+ public TimerV1(@Parameter(Seconds.class) int seconds) {
+ this.seconds = seconds;
+ }
+
+ public static void main(String[] args) throws BindException, InjectionException {
+ Tang tang = Tang.Factory.getTang();
+ JavaConfigurationBuilder cb = (JavaConfigurationBuilder) tang.newConfigurationBuilder();
+ Configuration conf = cb.build();
+ Injector injector = tang.newInjector(conf);
+ TimerV1 timer = injector.getInstance(TimerV1.class);
+
+ try {
+ System.out.println("Tick...");
+ timer.sleep();
+ System.out.println("Tock.");
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void sleep() throws InterruptedException {
+ java.lang.Thread.sleep(seconds * 1000);
+ }
+
+ @NamedParameter(default_value = "10",
+ doc = "Number of seconds to sleep", short_name = "sec")
+ class Seconds implements Name<Integer> {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/package-info.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/package-info.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/package-info.java
new file mode 100644
index 0000000..d0b62aa
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/package-info.java
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+/**
+ * Example code from the tutorial on Tang's home page.
+ */
+package org.apache.reef.tang.examples;
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/Timer.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/Timer.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/Timer.java
new file mode 100644
index 0000000..b1bed6e
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/Timer.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.examples.timer;
+
+import org.apache.reef.tang.annotations.DefaultImplementation;
+import org.apache.reef.tang.annotations.Name;
+import org.apache.reef.tang.annotations.NamedParameter;
+
+@DefaultImplementation(TimerImpl.class)
+public interface Timer {
+ public void sleep() throws Exception;
+
+ @NamedParameter(default_value = "10",
+ doc = "Number of seconds to sleep", short_name = "sec")
+ public static class Seconds implements Name<Integer> {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/TimerImpl.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/TimerImpl.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/TimerImpl.java
new file mode 100644
index 0000000..09f990c
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/TimerImpl.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.examples.timer;
+
+import org.apache.reef.tang.annotations.Parameter;
+
+import javax.inject.Inject;
+
+public class TimerImpl implements Timer {
+
+ private final int seconds;
+
+ @Inject
+ public TimerImpl(@Parameter(Timer.Seconds.class) int seconds) {
+ if (seconds < 0) {
+ throw new IllegalArgumentException("Cannot sleep for negative time!");
+ }
+ this.seconds = seconds;
+ }
+
+ @Override
+ public void sleep() throws Exception {
+ java.lang.Thread.sleep(seconds);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/TimerMock.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/TimerMock.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/TimerMock.java
new file mode 100644
index 0000000..fe8b41c
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/TimerMock.java
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.examples.timer;
+
+import org.apache.reef.tang.Configuration;
+import org.apache.reef.tang.Tang;
+import org.apache.reef.tang.annotations.Parameter;
+import org.apache.reef.tang.exceptions.BindException;
+import org.apache.reef.tang.exceptions.InjectionException;
+import org.apache.reef.tang.formats.ConfigurationModule;
+import org.apache.reef.tang.formats.ConfigurationModuleBuilder;
+import org.apache.reef.tang.formats.OptionalParameter;
+
+import javax.inject.Inject;
+
+public class TimerMock implements Timer {
+
+ public static final ConfigurationModule CONF = new TimerMockConf()
+ .bindImplementation(Timer.class, TimerMock.class)
+ .bindNamedParameter(Timer.Seconds.class, TimerMockConf.MOCK_SLEEP_TIME)
+ .build();
+ private final int seconds;
+
+ @Inject
+ TimerMock(@Parameter(Timer.Seconds.class) int seconds) {
+ if (seconds < 0) {
+ throw new IllegalArgumentException("Cannot sleep for negative time!");
+ }
+ this.seconds = seconds;
+ }
+
+ public static void main(String[] args) throws BindException, InjectionException, Exception {
+ Configuration c = TimerMock.CONF
+ .set(TimerMockConf.MOCK_SLEEP_TIME, 1)
+ .build();
+ Timer t = Tang.Factory.getTang().newInjector(c).getInstance(Timer.class);
+ System.out.println("Tick...");
+ t.sleep();
+ System.out.println("...tock.");
+ }
+
+ @Override
+ public void sleep() {
+ System.out.println("Would have slept for " + seconds + "sec.");
+ }
+
+ public static class TimerMockConf extends ConfigurationModuleBuilder {
+ public static final OptionalParameter<Integer> MOCK_SLEEP_TIME = new OptionalParameter<>();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/package-info.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/package-info.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/package-info.java
new file mode 100644
index 0000000..765dab9
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/examples/timer/package-info.java
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+/**
+ * A more complicated version of the Timer example, including delegating
+ * interfaces to default implementations.
+ */
+package org.apache.reef.tang.examples.timer;
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/exceptions/BindException.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/exceptions/BindException.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/exceptions/BindException.java
new file mode 100644
index 0000000..996b344
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/exceptions/BindException.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.exceptions;
+
+/**
+ * Thrown when an illegal or contradictory configuration option is encountered.
+ * <p/>
+ * While binding configuration values and merging Configuration objects, Tang
+ * checks each configuration option to make sure that it is correctly typed,
+ * and that it does not override some other setting (even if the two settings
+ * bind the same configuration option to the same value). When a bad
+ * configuration option is encountered, a BindException is thrown.
+ *
+ * @see NameResolutionException which covers the special case where an unknown
+ * configuration option or class is encountered.
+ */
+public class BindException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public BindException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
+ public BindException(String msg) {
+ super(msg);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/exceptions/ClassHierarchyException.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/exceptions/ClassHierarchyException.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/exceptions/ClassHierarchyException.java
new file mode 100644
index 0000000..c16722a
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/exceptions/ClassHierarchyException.java
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.exceptions;
+
+/**
+ * This exception is thrown when Tang detects improper or inconsistent class
+ * annotations. This is a runtime exception because it denotes a problem that
+ * existed during compilation.
+ */
+public class ClassHierarchyException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public ClassHierarchyException(Throwable cause) {
+ super(cause);
+ }
+
+ public ClassHierarchyException(String msg) {
+ super(msg);
+ }
+
+ public ClassHierarchyException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/53ea32cc/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/exceptions/InjectionException.java
----------------------------------------------------------------------
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/exceptions/InjectionException.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/exceptions/InjectionException.java
new file mode 100644
index 0000000..6b93923
--- /dev/null
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/exceptions/InjectionException.java
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.reef.tang.exceptions;
+
+/**
+ * Thrown when an injection fails. Injections commonly fail for two reasons.
+ * The first is that the InjectionPlan that Tang produced is ambiguous or
+ * infeasible. The second is that a constructor invoked by Tang itself threw
+ * an exception.
+ * <p/>
+ * A third, less common issue arises when constructors obtain a handle to the
+ * Tang Injector that created them, and then attempt to modify its state.
+ * Doing so is illegal, and results in a runtime exception that Tang converts
+ * into an InjectionException. Code involved in such exceptions is typically
+ * attempting to perform cyclic object injections, and should use an
+ * InjectionFuture instead.
+ */
+public class InjectionException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public InjectionException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
+ public InjectionException(String msg) {
+ super(msg);
+ }
+}