msi.gama.common.util.JavaUtils.java Source code

Java tutorial

Introduction

Here is the source code for msi.gama.common.util.JavaUtils.java

Source

/*******************************************************************************************************
 *
 * msi.gama.common.util.JavaUtils.java, in plugin msi.gama.core,
 * is part of the source code of the GAMA modeling and simulation platform (v. 1.8)
 * 
 * (c) 2007-2018 UMI 209 UMMISCO IRD/SU & Partners
 *
 * Visit https://github.com/gama-platform/gama for license information and contacts.
 * 
 ********************************************************************************************************/
package msi.gama.common.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.collect.UnmodifiableIterator;

import gnu.trove.map.hash.TIntObjectHashMap;
import msi.gama.common.interfaces.ISkill;

/**
 * Written by drogoul Modified on 28 dc. 2010
 *
 * Provides some utilities for dealing with reflection.
 *
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public class JavaUtils {

    public final static TIntObjectHashMap<List<Class>> IMPLEMENTATION_CLASSES = new TIntObjectHashMap();
    private static Multimap<Class, Class> INTERFACES = HashMultimap.<Class, Class>create();
    private static Multimap<Class, Class> SUPERCLASSES = HashMultimap.<Class, Class>create();

    private static int keyOf(final Class base, final Iterable<Class<? extends ISkill>> others) {
        int result = base.hashCode();
        for (final Class other : others)
            result += other.hashCode();
        return result;
    }

    private static final Set<Class> allInterfacesOf(final Class c, final Set<Class> in) {
        if (c == null)
            return Collections.EMPTY_SET;
        if (!INTERFACES.containsKey(c)) {
            final Class[] interfaces = c.getInterfaces();
            for (final Class c1 : interfaces) {
                if (in.contains(c1)) {
                    INTERFACES.put(c, c1);
                    INTERFACES.putAll(c, allInterfacesOf(c1, in));
                }
            }
            INTERFACES.putAll(c, allInterfacesOf(c.getSuperclass(), in));
        }
        return (Set<Class>) INTERFACES.get(c);
    }

    private static final Set<Class> allSuperclassesOf(final Class c, final Set<Class> in) {
        if (c == null)
            return null;
        if (!SUPERCLASSES.containsKey(c)) {
            Class c2 = c.getSuperclass();
            while (c2 != null) {
                if (in.contains(c2)) {
                    SUPERCLASSES.put(c, c2);
                }
                c2 = c2.getSuperclass();
            }
        }
        return (Set<Class>) SUPERCLASSES.get(c);
    }

    public static List<Class> collectImplementationClasses(final Class baseClass,
            final Iterable<Class<? extends ISkill>> skillClasses, final Set<Class> in) {
        final int key = keyOf(baseClass, skillClasses);
        if (!IMPLEMENTATION_CLASSES.containsKey(key)) {
            final Iterable<Class> basis = Iterables.concat(Collections.singleton(baseClass), skillClasses,
                    allInterfacesOf(baseClass, in));
            final Iterable<Class> extensions = Iterables
                    .concat(Iterables.transform(basis, each -> allSuperclassesOf(each, in)));
            final Set<Class> classes = Sets.newHashSet(Iterables.concat(basis, extensions));
            final ArrayList<Class> classes2 = new ArrayList(classes);
            Collections.sort(classes2, (o1, o2) -> {
                if (o1 == o2) {
                    return 0;
                }
                if (o1.isAssignableFrom(o2)) {
                    return -1;
                }
                if (o2.isAssignableFrom(o1)) {
                    return 1;
                }
                if (o1.isInterface() && !o2.isInterface()) {
                    return -1;
                }
                if (o2.isInterface() && !o1.isInterface()) {
                    return 1;
                }
                return 1;
            });

            IMPLEMENTATION_CLASSES.put(key, classes2);
        }
        return IMPLEMENTATION_CLASSES.get(key);

    }

    public static <F> Iterator<F> iterator(final Object[] array) {
        if (array != null) {
            return (Iterator<F>) Iterators.forArray(array);
        }
        return new UnmodifiableIterator<F>() {

            @Override
            public boolean hasNext() {
                return false;
            }

            @Override
            public F next() {
                return null;
            }
        };
    }

}