/** * 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.cli; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.Map; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Options; import org.nuunframework.kernel.commons.AssertUtils; import org.nuunframework.kernel.plugin.PluginException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.TypeLiteral; import com.google.inject.spi.TypeEncounter; import com.google.inject.spi.TypeListener; /** * @author ejemba * */ public class NuunCliTypeListener implements TypeListener { Logger logger = LoggerFactory.getLogger(NuunCliTypeListener.class); // private CommandLine commandLine; private Map<Class<?>, CommandLine> contextualCommandLineMap; /** * */ public NuunCliTypeListener(Map<Class<?>, CommandLine> contextualCommandLineMap) { this.contextualCommandLineMap = contextualCommandLineMap; } /* (non-Javadoc) * @see com.google.inject.spi.TypeListener#hear(com.google.inject.TypeLiteral, com.google.inject.spi.TypeEncounter) */ @Override public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) { for (Class<?> c = type.getRawType(); c != Object.class; c = c.getSuperclass()) { for (Field field : c.getDeclaredFields()) { AnnotationPointer annotationPointer = new AnnotationPointer(); if (annotationPresent(field, NuunOption.class, annotationPointer)) { if ( AssertUtils.isEquivalent(NuunOption.class, annotationPointer.annotation.annotationType()) ) { if (this.contextualCommandLineMap.get(c) != null ) encounter.register(new NuunOptionMembersInjector<I>(field, this.contextualCommandLineMap.get(c) , annotationPointer.annotation)); else logger.info("warning : no commandline for context " + c); } else { throw new PluginException("Annotation class %s is not compatible with %s. Please check it.", annotationPointer.annotation.annotationType().getCanonicalName() , NuunOption.class.getCanonicalName()); } } if (annotationPresent(field, NuunArgs.class, annotationPointer)) { if ( AssertUtils.isEquivalent(NuunArgs.class, annotationPointer.annotation.annotationType()) ) { if (this.contextualCommandLineMap.get(c) != null ) encounter.register(new NuunArgsMembersInjector<I>(field, this.contextualCommandLineMap.get(c) , annotationPointer.annotation)); else logger.info("warning no commandline for context " + c); } else { throw new PluginException("Annotation class %s is not compatible with %s. Please check it.", annotationPointer.annotation.annotationType().getCanonicalName() , NuunOption.class.getCanonicalName()); } } } } } static boolean annotationPresent(Field field , Class<? extends Annotation> annoClass, AnnotationPointer annotationPointer) { for (Annotation anno : field.getAnnotations() ) { if ( AssertUtils.hasAnnotationDeep(anno.annotationType(), annoClass) ) { annotationPointer.annotation = anno; return true; } } return false; } static class AnnotationPointer { public Annotation annotation; } }