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

org.holoeverywhere.Setting Maven / Gradle / Ivy

There is a newer version: 1.6.8
Show newest version

package org.holoeverywhere;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.util.Log;

public abstract class Setting> {
    public static class BooleanProperty extends Property {
        @Override
        protected void onSetDefaultValue(SettingProperty settingProperty) {
            setValue(settingProperty.defaultBoolean());
        }
    }

    public static class EnumProperty> extends Property {
        private String defaultValue;

        @SuppressWarnings("unchecked")
        @Override
        protected void onSetDefaultValue(SettingProperty settingProperty) {
            defaultValue = settingProperty.defaultEnum();
            Class t = settingProperty.enumClass();
            Class clazz = t == NullEnum.class ? null : (Class) t;
            if (clazz != null) {
                setEnumClass(clazz);
            }
        }

        @SuppressWarnings("unchecked")
        public void setEnumClass(Class clazz) {
            if (defaultValue != null) {
                try {
                    Method method = clazz.getMethod("valueOf", String.class);
                    method.setAccessible(true);
                    setValue((T) method.invoke(null, defaultValue));
                } catch (Exception e) {
                    Log.w(Setting.TAG, "Error on getting enum value", e);
                }
            }
        }
    }

    public static class IntegerProperty extends Property {
        @Override
        protected void onSetDefaultValue(SettingProperty settingProperty) {
            setValue(settingProperty.defaultInt());
        }
    }

    private static enum NullEnum {

    }

    public static class Property {
        private Setting setting;
        private Z value;
        private boolean wasAttach = false;

        public void attach(Setting setting) {
            if (setting != null) {
                setting.attach(this);
            }
        }

        public void detach() {
            if (setting != null) {
                setting.detach(this);
            }
        }

        public final Setting getSetting() {
            return setting;
        }

        public Z getValue() {
            return value;
        }

        public boolean isValid() {
            return true;
        }

        public final void notifyOnChange() {
            if (setting != null) {
                setting.onPropertyChange(this);
            }
        }

        protected void onAttach(Setting setting) {

        }

        protected void onDetach() {

        }

        protected void onSetDefaultValue(SettingProperty settingProperty) {

        }

        private final void setSetting(Setting setting) {
            this.setting = setting;
            if (setting != null) {
                if (wasAttach) {
                    onDetach();
                }
                onAttach(setting);
                wasAttach = true;
            } else if (wasAttach) {
                onDetach();
                wasAttach = false;
            }
        }

        public void setValue(Z value) {
            if (this.value != value) {
                this.value = value;
                notifyOnChange();
            }
        }
    }

    public static interface SettingListener> {
        public void onAttach(T setting);

        public void onDetach(T setting);

        public void onPropertyChange(T setting, Property property);
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public static @interface SettingProperty {
        public boolean create() default false;

        public boolean defaultBoolean() default false;

        public String defaultEnum() default "";

        public int defaultInt() default 0;

        public String defaultString() default "";

        public Class> enumClass() default NullEnum.class;
    }

    public static class StringProperty extends Property {
        @Override
        protected void onSetDefaultValue(SettingProperty settingProperty) {
            setValue(settingProperty.defaultString());
        }
    }

    private static final Map>, Setting> settingMap = new HashMap>, Setting>();

    private static final String TAG = Setting.class.getSimpleName();

    public static > void addListener(Class clazz,
            SettingListener settingListener) {
        Setting.get(clazz).addListener(settingListener);
    }

    @SuppressWarnings("unchecked")
    public static > T get(Class clazz) {
        if (!Setting.settingMap.containsKey(clazz)) {
            try {
                T t = clazz.newInstance();
                Setting.settingMap.put(clazz, t);
                t.init();
            } catch (Exception e) {
                Log.e(Setting.TAG, "Error init setting instance", e);
            }
        }
        return (T) Setting.settingMap.get(clazz);
    }

    public static > void removeListener(Class clazz,
            SettingListener settingListener) {
        if (Setting.settingMap.containsKey(clazz)) {
            Setting.get(clazz).removeListener(settingListener);
        }
    }

    private final List> listeners = new ArrayList>();

    private final List> propertyList = new ArrayList>();

    @SuppressWarnings("unchecked")
    public final T addListener(SettingListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("SettingListener can't be null");
        }
        if (!listeners.contains(listener)) {
            listeners.add(listener);
            listener.onAttach((T) this);
        } else {
            listeners.remove(listener);
            listeners.add(listener);
        }
        return (T) this;
    }

    @SuppressWarnings("unchecked")
    public final T attach(Property property) {
        if (property == null || !property.isValid()) {
            throw new RuntimeException("Property not valid");
        }
        if (property.getSetting() != null && property.getSetting() != this) {
            throw new RuntimeException("Property already attached to "
                    + property.getSetting().getClass().getName());
        }
        property.setSetting(this);
        propertyList.add(property);
        return (T) this;
    }

    @SuppressWarnings("unchecked")
    public final T detach(Property property) {
        if (property != null) {
            propertyList.remove(property);
            property.setSetting(null);
        }
        return (T) this;
    }

    private Field[] getFields() {
        try {
            return getClass().getDeclaredFields();
        } catch (Exception e) {
            return getClass().getFields();
        }
    }

    protected final void init() {
        for (Field field : getFields()) {
            try {
                field.setAccessible(true);
                if (field.isAnnotationPresent(SettingProperty.class)) {
                    SettingProperty settingProperty = field
                            .getAnnotation(SettingProperty.class);
                    if (settingProperty.create()) {
                        field.set(this, field.getType().newInstance());
                    }
                    Property property = (Property) field.get(this);
                    property.onSetDefaultValue(settingProperty);
                    attach(property);
                }
            } catch (Exception e) {
                Log.e(Setting.TAG, "Error on processing property", e);
            }
        }
        onInit();
    }

    protected void onInit() {

    }

    @SuppressWarnings("unchecked")
    protected void onPropertyChange(Property property) {
        for (SettingListener listener : listeners) {
            try {
                listener.onPropertyChange((T) this, property);
            } catch (RuntimeException e) {
                Log.w(Setting.TAG, "Listener error", e);
            }
        }
    }

    @SuppressWarnings("unchecked")
    public final T removeListener(SettingListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("SettingListener can't be null");
        }
        if (listeners.contains(listener)) {
            listener.onDetach((T) this);
            listeners.remove(listener);
        }
        return (T) this;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy