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

org.holoeverywhere.addon.IAddonBasicAttacher Maven / Gradle / Ivy

The newest version!

package org.holoeverywhere.addon;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.holoeverywhere.addon.IAddon.Addon;

public final class IAddonBasicAttacher, Z> implements IAddonAttacher {
    private final class AddonComparator implements Comparator {
        @Override
        public int compare(V lhs, V rhs) {
            final int i1 = getWeight(lhs.getParent());
            final int i2 = getWeight(rhs.getParent());
            return i1 > i2 ? 1 : i1 < i2 ? -1 : 0;
        }

        private int getWeight(IAddon addon) {
            if (addon.getClass().isAnnotationPresent(Addon.class)) {
                return addon.getClass().getAnnotation(Addon.class).weight();
            }
            return -1;
        }
    }

    private final Map, V> mAddons = new HashMap, V>();
    private List mAddonsList;
    private final Set mAddonsSet = new TreeSet(new AddonComparator());
    private boolean mLockAttaching = false;
    private Z mObject;

    public IAddonBasicAttacher(Z object) {
        mObject = object;
    }

    @Override
    public  T addon(Class clazz) {
        return addon(clazz, true);
    }

    @SuppressWarnings("unchecked")
    private  T addon(Class clazz, boolean checkConflicts) {
        T addon = (T) mAddons.get(clazz);
        if (addon == null) {
            if (mLockAttaching) {
                throw AttachException.afterInit(mObject, clazz);
            }
            addon = IAddon.obtain(clazz, mObject);
            if (addon == null) {
                return null;
            }
            mAddons.put(clazz, addon);
            mAddonsSet.add(addon);
            mAddonsList = null;
            if (checkConflicts) {
                checkConflicts();
            }
        }
        return addon;
    }

    @Override
    public void addon(Collection> classes) {
        if (classes == null || classes.size() == 0) {
            return;
        }
        for (Class clazz : classes) {
            addon(clazz, false);
        }
        checkConflicts();
    }

    @Override
    public  T addon(String classname) {
        return addon(IAddon.makeAddonClass(classname));
    }

    private void checkConflicts() {
        Set attachedAddons = new HashSet();
        Map conflictAddons = new HashMap();
        for (V addon : mAddonsSet) {
            Class clazz = addon.getParent().getClass();
            final String clazzName = clazz.getName();
            attachedAddons.add(clazzName);
            if (!clazz.isAnnotationPresent(Addon.class)) {
                continue;
            }
            Addon addonMeta = clazz.getAnnotation(Addon.class);
            for (String a : addonMeta.conflictStrings()) {
                conflictAddons.put(a, clazzName);
            }
            for (Class a : addonMeta.conflict()) {
                conflictAddons.put(a.getName(), clazzName);
            }
        }
        StringBuilder builder = null;
        for (String addon : conflictAddons.keySet()) {
            if (attachedAddons.contains(addon)) {
                if (builder == null) {
                    builder = new StringBuilder();
                } else {
                    builder.append('\n');
                }
                builder.append(String.format(
                        "Found addon conflict: %s is cannot be attached together with %s",
                        addon, conflictAddons.get(addon)));
            }
        }
        if (builder != null) {
            throw AttachException.conflict(builder.toString());
        }
    }

    public void inhert(Collection> sourceClasses) {
        if (sourceClasses == null || sourceClasses.size() == 0) {
            return;
        }
        List> classes = new ArrayList>();
        for (Class clazz : sourceClasses) {
            if (!clazz.isAnnotationPresent(Addon.class)) {
                continue;
            }
            Addon addon = clazz.getAnnotation(Addon.class);
            if (addon.inhert()) {
                classes.add(clazz);
            }
        }
        addon(classes);
    }

    public void inhert(IAddonAttacher attacher) {
        inhert(attacher == null ? null : attacher.obtainAddonsList());
    }

    @Override
    public boolean isAddonAttached(Class clazz) {
        return mAddons.containsKey(clazz);
    }

    @Override
    public void lockAttaching() {
        mLockAttaching = true;
    }

    @Override
    public Collection> obtainAddonsList() {
        return new ArrayList>(mAddons.keySet());
    }

    @Override
    public boolean performAddonAction(AddonCallback callback) {
        if (mAddonsSet.size() == 0) {
            return callback.post();
        }
        if (mAddonsList == null) {
            mAddonsList = new ArrayList(mAddonsSet);
        }
        final int addonCount = mAddonsList.size();
        for (int i = 0; i < addonCount; i++) {
            if (callback.action(mAddonsList.get(i))) {
                return true;
            }
        }
        return callback.post();
    }

    public void reset() {
        mAddons.clear();
        mAddonsSet.clear();
        mAddonsList = null;
        mLockAttaching = false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy