/* Copyright (c) 2014 Boundless and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/edl-v10.html
*
* Contributors:
* Gabriel Roldan (Boundless) - initial implementation
*/
package org.locationtech.geogig.di;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
public class DecoratorProvider {
private Set<Decorator> decorators;
private Map<Class<?>, Object> singletonDecorators = Maps.newConcurrentMap();
@Inject
public DecoratorProvider(Set<Decorator> decorators) {
this.decorators = decorators;
}
@SuppressWarnings("unchecked")
public <T> T get(final T undecorated) {
T decorated = undecorated;
Class<? extends Object> undecoratedClass = decorated.getClass();
{
Object singletonDecorator = singletonDecorators.get(undecoratedClass);
if (singletonDecorator != null) {
return (T) singletonDecorator;
}
}
for (Decorator decorator : decorators) {
if (decorator.canDecorate(decorated)) {
decorated = (T) decorator.decorate(decorated);
}
}
if (isSingleton(undecoratedClass)) {
singletonDecorators.put(undecoratedClass, decorated);
}
return decorated;
}
private boolean isSingleton(Class<? extends Object> c) {
if (c.isAnnotationPresent(Singleton.class)) {
return true;
}
Class<?> s = c.getSuperclass();
if (s != null && isSingleton(s)) {
return true;
}
Class<?>[] interfaces = c.getInterfaces();
for (Class<?> i : interfaces) {
return isSingleton(i);
}
return false;
}
}