/** * Copyright (C) 2013 Kametic <epo.jemba@kametic.com> * * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3, 29 June 2007; * or any later version * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.gnu.org/licenses/lgpl-3.0.txt * * 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.nuunframework.kernel.context; import static com.google.common.collect.Collections2.filter; import static com.google.common.collect.Collections2.transform; import java.lang.annotation.Annotation; import java.util.Collection; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.inject.Injector; import com.google.inject.Key; /** * @author Epo Jemba * */ @Singleton public class ContextInternal implements Context { public final Injector mainInjector; /** * */ @Inject public ContextInternal(Injector mainInjector) { this.mainInjector = mainInjector; } // private void indexBindings() // { // for (Key key : mainInjector.getAllBindings().keySet()) // { // key.getAnnotationType() // } // } @Override public Collection<Class<?>> getClassAnnotatedWith(Class<? extends Annotation> clazz) { Collection<Key<?>> resultKeys = filter(mainInjector.getAllBindings().keySet(), withAnnotation(clazz)); return transform(resultKeys, fromKeyTClass()); } @Override public Collection<Class<?>> getClassAnnotatedWithRegex(String regex) { Collection<Key<?>> resultKeys = filter(mainInjector.getAllBindings().keySet(), withAnnotationName(regex)); return transform(resultKeys, fromKeyTClass()); } @Override public Collection<Class<?>> getClassWithParentType(Class<?> parentClass) { Collection<Key<?>> resultKeys = filter(mainInjector.getAllBindings().keySet(), withParentType(parentClass)); return transform(resultKeys, fromKeyTClass()); } @Override public Collection<Class<?>> getClassTypeByRegex(String typeNameRegex) { Collection<Key<?>> resultKeys = filter(mainInjector.getAllBindings().keySet(), withTypeName(typeNameRegex)); return transform(resultKeys, fromKeyTClass()); } /** where element is annotated with given {@code annotation} */ private Predicate<Key<?>> withTypeName(final String typeNameSuffix) { return new Predicate<Key<?>>() { public boolean apply(@Nullable Key<?> input) { return input != null && (input.getTypeLiteral().getRawType().getName().matches(typeNameSuffix)); } }; } /** where element is annotated with given {@code annotation} */ private Predicate<Key<?>> withParentType(final Class<?> parentType) { return new Predicate<Key<?>>() { public boolean apply(@Nullable Key<?> input) { boolean value1 = input != null; boolean value2 = false; if (value1) { // Collection<Class<?>> types = new HashSet<Class<?>>(); Class<?> süper = input.getTypeLiteral().getRawType().getSuperclass(); if (süper != null && süper != Object.class) { value2 = (süper == parentType); } if (!value2) { Class<?>[] interfaces = input.getTypeLiteral().getRawType().getInterfaces(); for (Class<?> class1 : interfaces) { value2 = (class1 == parentType); if (value2) break; } } } return value1 && value2; } }; } /** where element is annotated with given {@code annotation} */ private Predicate<Key<?>> withAnnotation(final Class<? extends Annotation> annotation) { return new Predicate<Key<?>>() { public boolean apply(@Nullable Key<?> input) { return input != null && input.getTypeLiteral().getRawType().isAnnotationPresent(annotation); } }; } /** where element is annotated with given {@code annotation} */ private Predicate<Key<?>> withAnnotationName(final String annotationNameRegex) { return new Predicate<Key<?>>() { public boolean apply(@Nullable Key<?> input) { boolean value1 = input != null; boolean value2 = false; if (value1) { for (Annotation annotation : input.getTypeLiteral().getRawType().getAnnotations()) { if (annotation.annotationType().getName().matches(annotationNameRegex)) { value2 = true; break; } } } // boolean value2 = .getName().endsWith(annotationName); return value1 && value2; } }; } private Function<Key<?>, Class<?>> fromKeyTClass() { return new Function<Key<?>, Class<?>>() { @Override public Class<?> apply(Key<?> input) { return input.getTypeLiteral().getRawType(); } }; } }