com.artemchep.horario.content.PreferenceStore.java Source code

Java tutorial

Introduction

Here is the source code for com.artemchep.horario.content.PreferenceStore.java

Source

/*
 * Copyright (C) 2017 XJSHQ@github.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 */
package com.artemchep.horario.content;

import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.Pair;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Artem Chepurnoy
 */
public abstract class PreferenceStore {

    private Map<String, Preference> mMap;

    @NonNull
    public abstract String getPreferenceName();

    public abstract void loadPreferencesMap(Map<String, Preference> map);

    public void load(@NonNull Context context) {
        mMap = new HashMap<>();
        loadPreferencesMap(mMap);
        String name = getPreferenceName();
        SharedPreferences sp = context.getSharedPreferences(name, Context.MODE_PRIVATE);
        for (Preference pref : mMap.values()) {
            Object value = pref.value;
            if (boolean.class.isAssignableFrom(pref.clazz)) {
                value = sp.getBoolean(pref.key, (Boolean) value);
            } else if (int.class.isAssignableFrom(pref.clazz)) {
                value = sp.getInt(pref.key, (Integer) value);
            } else if (float.class.isAssignableFrom(pref.clazz)) {
                value = sp.getFloat(pref.key, (Float) value);
            } else if (String.class.isAssignableFrom(pref.clazz)) {
                value = sp.getString(pref.key, (String) value);
            } else if (long.class.isAssignableFrom(pref.clazz)) {
                value = sp.getLong(pref.key, (Long) value);
            } else
                throw new IllegalArgumentException("Unknown option\'s type.");
            pref.value = value;
        }
    }

    @NonNull
    public Object getObject(@NonNull String key) {
        return mMap.get(key).value;
    }

    @NonNull
    public String getString(@NonNull String key) {
        return (String) getObject(key);
    }

    public int getInt(@NonNull String key) {
        return (Integer) getObject(key);
    }

    public boolean getBoolean(@NonNull String key) {
        return (Boolean) getObject(key);
    }

    @NonNull
    @CheckResult
    public Editor edit(@NonNull Context context) {
        return new Editor(this, context);
    }

    public void addListener(@NonNull OnPreferenceStoreChangeListener l, @NonNull String... keys) {
        for (String key : keys) {
            assert key != null;
            Preference pref = mMap.get(key);
            if (pref == null) {
                throw new IllegalArgumentException("No corresponding preference found for the " + "key=" + key);
            } else
                pref.listeners.add(l);
        }
    }

    public void removeListener(@NonNull OnPreferenceStoreChangeListener l, @NonNull String... keys) {
        for (String key : keys) {
            assert key != null;
            Preference pref = mMap.get(key);
            if (pref == null) {
                throw new IllegalArgumentException("No corresponding preference found for the " + "key=" + key);
            } else
                pref.listeners.remove(l);
        }
    }

    /**
     * @author Artem Chepurnoy
     */
    public interface OnPreferenceStoreChangeListener {

        void onPreferenceStoreChange(@NonNull Context context, @NonNull Preference pref, @NonNull Object old);
    }

    /**
     * @author Artem Chepurnoy
     */
    public static class Editor {

        private final PreferenceStore mStore;
        private final Context mContext;

        private final List<Pair<String, Object>> mList;

        public Editor(@NonNull PreferenceStore ps, @NonNull Context context) {
            mList = new ArrayList<>();
            mContext = context;
            mStore = ps;
        }

        @NonNull
        public Editor put(@NonNull String key, @NonNull Object value) {
            mList.add(new Pair<>(key, value));
            return this;
        }

        public void commit() {
            commit(null);
        }

        public void commit(@Nullable OnPreferenceStoreChangeListener listenerToIgnore) {
            SharedPreferences.Editor editor = mContext
                    .getSharedPreferences(mStore.getPreferenceName(), Context.MODE_PRIVATE).edit();
            for (Pair<String, Object> diff : mList) {
                Preference pref = mStore.mMap.get(diff.first);
                Object old = pref.value;
                if (diff.second.equals(old))
                    continue;
                pref.value = diff.second;

                for (OnPreferenceStoreChangeListener l : pref.listeners) {
                    if (listenerToIgnore != l) {
                        l.onPreferenceStoreChange(mContext, pref, old);
                    }
                }

                // Tell editor to put new value
                if (boolean.class.isAssignableFrom(pref.clazz)) {
                    editor.putBoolean(pref.key, (Boolean) pref.value);
                } else if (int.class.isAssignableFrom(pref.clazz)) {
                    editor.putInt(pref.key, (Integer) pref.value);
                } else if (float.class.isAssignableFrom(pref.clazz)) {
                    editor.putFloat(pref.key, (Float) pref.value);
                } else if (String.class.isAssignableFrom(pref.clazz)) {
                    editor.putString(pref.key, (String) pref.value);
                } else if (long.class.isAssignableFrom(pref.clazz)) {
                    editor.putLong(pref.key, (Long) pref.value);
                } else
                    throw new IllegalArgumentException("Unknown option\'s type.");
            }
            editor.apply();
        }

    }

    /**
     * @author Artem Chepurnoy
     */
    public static class Preference {

        public Class clazz;
        public String key;
        public Object value;

        final List<OnPreferenceStoreChangeListener> listeners = new ArrayList<>();

        /**
         * @author Artem Chepurnoy
         */
        public final static class Builder {

            private Class mClazz;
            private String mKey;
            private Object mValue;

            @NonNull
            public Builder setKey(@NonNull String key) {
                mKey = key;
                return this;
            }

            @NonNull
            public Builder setClass(@NonNull Class clazz) {
                mClazz = clazz;
                return this;
            }

            @NonNull
            public Builder setValue(@NonNull Object object) {
                mValue = object;
                return this;
            }

            @NonNull
            @CheckResult
            public Preference build() {
                Preference pref = new Preference();
                pref.key = mKey;
                pref.clazz = mClazz;
                pref.value = mValue;
                return pref;
            }

        }

    }

}