org.nuunframework.cli.NuunCliTypeListener.java Source code

Java tutorial

Introduction

Here is the source code for org.nuunframework.cli.NuunCliTypeListener.java

Source

/**
 * 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;
    }

}