/*******************************************************************************
* Copyright (c) 2008, 2014 Stuart McCulloch
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Stuart McCulloch - initial API and implementation
*******************************************************************************/
package org.eclipse.sisu.peaberry.util;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import org.aopalliance.intercept.MethodInterceptor;
import org.eclipse.sisu.peaberry.builders.ImportDecorator;
import org.eclipse.sisu.peaberry.util.decorators.DecoratorChain;
import org.eclipse.sisu.peaberry.util.decorators.InterceptingDecorator;
import org.eclipse.sisu.peaberry.util.decorators.StickyDecorator;
import com.google.inject.matcher.Matcher;
/**
* Methods for creating various general purpose {@link ImportDecorator}s.
*
* @author mcculls@gmail.com (Stuart McCulloch)
*/
public final class Decorators {
// instances not allowed
private Decorators() {}
/**
* An {@link ImportDecorator} that caches the first valid service instance and
* uses that until it becomes invalid. The decorator then calls the reset task
* to see if it should reset the cache and get a new service instance.
* <p>
* If no reset task is provided, the service instance cache is never reset.
* <p>
* Note: sticky decorators only really make sense for <i>single</i> services.
*
* @param resetTask called when cached service becomes invalid, may be null
* @return decorator that caches service instances
*/
public static <S> ImportDecorator<S> sticky(final Callable<Boolean> resetTask) {
return new StickyDecorator<S>(resetTask);
}
/**
* An {@link ImportDecorator} that applies decorators in a chain, right-left.
*
* @param decorators sequence of decorators
* @return decorator combining the given decorators
*/
@SuppressWarnings("unchecked")
public static <S> ImportDecorator<S> chain(final ImportDecorator... decorators) {
return new DecoratorChain<S>(decorators);
}
/**
* An {@link ImportDecorator} that supports {@link MethodInterceptor}s.
*
* @param classMatcher matches interfaces to be intercepted
* @param methodMatcher matches methods to be intercepted
* @param interceptors sequence of method interceptors
* @return decorator that intercepts imported services
*/
public static <S> ImportDecorator<S> intercept(final Matcher<? super Class<?>> classMatcher,
final Matcher<? super Method> methodMatcher, final MethodInterceptor... interceptors) {
return new InterceptingDecorator<S>(classMatcher, methodMatcher, interceptors);
}
}