All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.yin.cli.annotations.ClassScanner Maven / Gradle / Ivy

Go to download

Easy to use command-line parser, which enables you to define cmdline flags directly the class they are used in.

The newest version!
package com.github.yin.cli.annotations;

import com.github.yin.cli.ClassMetadata;
import com.github.yin.cli.ClassMetadataIndex;
import com.github.yin.cli.FlagIndex;
import com.github.yin.cli.FlagMetadata;
import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Set;

/**
 * @author yin
 */
public class ClassScanner {
    private static final Logger log  = LoggerFactory.getLogger(ClassScanner.class);

    // TODO yin: it would be also useful to return the metadata in a list
    public void scanClass(final String className, final FlagIndex index, ClassMetadataIndex classMetaIndex) throws ClassNotFoundException {
        Class clazz = Class.forName(className);
        scanClass(clazz, index, classMetaIndex);
    }

    public void scanClass(final Class clazz, final FlagIndex index, final ClassMetadataIndex classMetadataIndex) {
        collectClassMetadata(clazz, classMetadataIndex);
        collectFlagInfo(clazz, index);
    }

    private void collectClassMetadata(Class clazz, ClassMetadataIndex classMetadataIndex) {
        Usage[] flagDescs = clazz.getAnnotationsByType(Usage.class);
        if (flagDescs.length > 1) {
            log.error("Multiple @Usage occurrences on class: {}", clazz);
            return;
        }
        for (Usage desc : flagDescs) {
            ClassMetadata classInfo =  ClassMetadata.create(clazz.getCanonicalName(), desc.value());
            classMetadataIndex.classes().put(clazz.getCanonicalName(), classInfo);
        }
    }

    public void collectFlagInfo(final Class clazz, final FlagIndex index) {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            Usage[] flagDescs = field.getAnnotationsByType(Usage.class);
            if (flagDescs.length > 1) {
                log.error("Multiple @Usage occurrences on field: {}", field.toString());
                continue;
            }
            if ((field.getModifiers() & Modifier.STATIC) == 0) {
                log.error("@Usage on non-static field: {}", field.toString());
                continue;
            }
            if ((field.getModifiers() & Modifier.FINAL) == 0) {
                log.error("@Usage on non-final field: {}", field);
                continue;
            }
            if (field.isAccessible()) {
                log.error("@Usage on non-accessible filed: {}", field);
                continue;
            }
            for (Usage desc : flagDescs) {
                String name = desc.name() != null && !desc.name().isEmpty() ? desc.name() : field.getName();
                FlagMetadata meta =
                        FlagMetadata.create(clazz.getCanonicalName(), name, desc.value(), field.getType());
                index.add(meta.flagID(), meta);
            }
        }
    }

    public void scanPackage(String packagePrefix, FlagIndex index, ClassMetadataIndex classMetaIndex) {
        Reflections reflections = new Reflections(packagePrefix);
        Set> classDescs = reflections.getTypesAnnotatedWith(Usage.class);
        for (Class clazz : classDescs) {
            scanClass(clazz, index, classMetaIndex);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy