This project has retired. For details please refer to its Attic page.
Source code
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.ConstructorDef;
022
023import java.lang.reflect.Constructor;
024import java.lang.reflect.InvocationTargetException;
025
026/**
027 * A simple interface that allows external code to interpose on Tang object
028 * injections.  This can be used to implement simplistic aspect oriented
029 * design patterns by interposing wrapper objects at injection time.  It
030 * can also be used for more mundane purposes, such as tracking the
031 * relationship between the objects that are instantiated at runtime.
032 * <p/>
033 * The Wake project contains a full-featured implementation of this API that
034 * may serve as a useful example.
035 */
036public interface Aspect {
037  /**
038   * Inject an object of type T.
039   * <p/>
040   * Note that it is never OK to return an instance of ExternalConstructor.
041   * Typical implementations check to see if they are about to return an
042   * instance of ExternalConstructor.  If so, they return ret.newInstance()
043   * instead.
044   *
045   * @param def         information about the constructor to be invoked.  This is
046   *                    mostly useful because it contains references to any relevant named
047   *                    parameters, and to the class to be injected.
048   * @param constructor The java constructor to be injected.  Tang automatically
049   *                    chooses the appropriate constructor and ensures that we have permission
050   *                    to invoke it.
051   * @param args        The parameters to be passed into constructor.newInstance(), in the correct order.
052   * @return A new instance of T.
053   * Note, it is inject()'s responsibility to call <tt>ret.getInstance() if ret instanceof ExternalConstructor</tt>.
054   * @throws A number of exceptions which are passed-through from the wrapped call to newInstance().
055   */
056  <T> T inject(ConstructorDef<T> def, Constructor<T> constructor, Object[] args) throws InvocationTargetException, IllegalAccessException, IllegalArgumentException, InstantiationException;
057
058  /**
059   * TANG calls this the first time get() is called on an injection future.  This informs the aspect of
060   * the relationship between InjectionFutures (that were already passed into inject()) and the instantiated
061   * object.
062   *
063   * @param f An InjectionFuture that was passed to the args[] array of inject at some point in the past.
064   * @param t An object instance that was returned by inject().
065   */
066  <T> void injectionFutureInstantiated(InjectionFuture<T> f, T t);
067
068  /**
069   * This method creates a child aspect, and returns it.  This allows aspects to track information about
070   * Tang injection scopes.  If such information is not needed, it is legal for Aspect implementations to
071   * return "this".
072   */
073  Aspect createChildAspect();
074}