com.chrynan.teleport.Teleport.java Source code

Java tutorial

Introduction

Here is the source code for com.chrynan.teleport.Teleport.java

Source

package com.chrynan.teleport;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/*
 * Copyright 2016 chRyNaN
 * <p/>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Created by chRyNaN on 4/20/2016. This class handles binding retrieved data to appropriate fields of a specified binding object.
 */
public class Teleport {
    private static final String TAG = Teleport.class.getSimpleName();

    /**
     * Retrieves and stores data into their corresponding fields within the specified binding object.
     *
     * @param bindObject The binding object that is searched for Data annotation named fields,
     *                   which these fields are then propagated with corresponding fetched data.
     * @param context    The Context used to store and retrieve data.
     */
    public static final void bind(@NonNull Object bindObject, @NonNull Context context) {
        if (bindObject == null) {
            throw new IllegalArgumentException("Object parameter in bind method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (context == null) {
            throw new IllegalArgumentException("Context parameter in bind method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        StorageMap map = StorageMap.with(context);
        for (Field f : getAnnotatedFields(bindObject)) {
            try {
                f.setAccessible(true);
                Data d = f.getAnnotation(Data.class);
                if (d.bind()) {
                    f.set(bindObject, map.get((d == null) ? "" : d.value(), f.getType()));
                }
            } catch (IllegalAccessException iae) {
                iae.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Retrieves and stores data into their corresponding fields within the specified binding object.
     *
     * @param bindObject The binding object that is searched for Data annotation named fields,
     *                   which these fields are then propagated with corresponding fetched data.
     * @param context    The underlying Context used for storing and retrieving data. This needed Context is
     *                   only used for certain scenarios (ex: saving files) but if the Intent parameter is
     *                   null, then it is used as the default storage mechanism (SharedPreferences created by Context).
     * @param intent     The Intent used to store and retrieve data.
     */
    public static final void bind(@NonNull Object bindObject, @NonNull Context context, Intent intent) {
        if (bindObject == null) {
            throw new IllegalArgumentException("Object parameter in bind method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (context == null) {
            throw new IllegalArgumentException("Context parameter in bind method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (intent == null) {
            bind(bindObject, context);
        } else {
            StorageMap map = StorageMap.with(context, intent);
            for (Field f : getAnnotatedFields(bindObject)) {
                try {
                    f.setAccessible(true);
                    Data d = f.getAnnotation(Data.class);
                    if (d.bind()) {
                        f.set(bindObject, map.get((d == null) ? "" : d.value(), f.getType()));
                    }
                } catch (IllegalAccessException iae) {
                    iae.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Retrieves and stores data into their corresponding fields within the specified binding object.
     *
     * @param bindObject The binding object that is searched for Data annotation named fields,
     *                   which these fields are then propagated with corresponding fetched data.
     * @param context    The underlying Context used for storing and retrieving data. This needed Context is
     *                   only used for certain scenarios (ex: saving files) but if the Intent parameter is
     *                   null, then it is used as the default storage mechanism (SharedPreferences created by Context).
     * @param bundle     The Bundle used to store and retrieve data.
     */
    public static final void bind(@NonNull Object bindObject, @NonNull Context context, Bundle bundle) {
        if (bindObject == null) {
            throw new IllegalArgumentException("Object parameter in bind method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (context == null) {
            throw new IllegalArgumentException("Context parameter in bind method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (bundle == null) {
            bind(bindObject, context);
        } else {
            StorageMap map = StorageMap.with(context, bundle);
            for (Field f : getAnnotatedFields(bindObject)) {
                try {
                    f.setAccessible(true);
                    Data d = f.getAnnotation(Data.class);
                    if (d.bind()) {
                        f.set(bindObject, map.get((d == null) ? "" : d.value(), f.getType()));
                    }
                } catch (IllegalAccessException iae) {
                    iae.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Retrieves and stores data into their corresponding fields within the specified binding object.
     * Uses the Activity as both the binding object and the Context. First checks the Activity for
     * an Intent (via the getIntent() method), if this Intent is not null it will attempt to use
     * it as the storage mechanism. Otherwise it will use the default storage mechanism using the Context.
     *
     * @param activity The Activity object that acts as both the binding object and the Context.
     */
    public static final void bind(@NonNull Activity activity) {
        if (activity == null) {
            throw new IllegalArgumentException("Activity parameter in bind method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (activity.getIntent() != null) {
            bind(activity, activity, activity.getIntent());
        } else {
            bind(activity, activity);
        }
    }

    /**
     * Retrieves and stores data into their corresponding fields within the specified binding object.
     * Uses the Activity as both the binding object and the Context. First attempts to use the provided
     * Intent object as the storage mechanism.
     *
     * @param activity The Activity object that acts as both the binding object and the Context.
     * @param intent   The Intent used to store and retieve data.
     */
    public static final void bind(@NonNull Activity activity, Intent intent) {
        if (activity == null) {
            throw new IllegalArgumentException("Activity parameter in bind method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (intent != null) {
            bind(activity, activity, intent);
        } else {
            bind(activity, activity);
        }
    }

    /**
     * Retrieves and stores data into their corresponding fields within the specified binding object.
     * Uses the Activity as both the binding object and the Context. First attempts to use the provided
     * Bundle object as the storage mechanism.
     *
     * @param activity The Activity object that acts as both the binding object and the Context.
     * @param bundle   The Intent used to store and retieve data.
     */
    public static final void bind(@NonNull Activity activity, Bundle bundle) {
        if (activity == null) {
            throw new IllegalArgumentException("Activity parameter in bind method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (bundle != null) {
            bind(activity, activity, bundle);
        } else {
            bind(activity, activity);
        }
    }

    /**
     * Retrieves and stores data into their corresponding fields within the specified binding object.
     * Uses the Fragment as both the binding object and to get the Context (via getActivity() method).
     * First checks the Fragment for a Bundle (via the getArguments() method), if this Bundle is not null
     * it will attempt to use it as the storage mechanism. Otherwise it will use the default storage
     * mechanism using the Context.
     *
     * @param fragment The Fragment object that acts both as the binding object and to get the Context.
     */
    public static final void bind(@NonNull Fragment fragment) {
        if (fragment == null) {
            throw new IllegalArgumentException("Fragment parameter in bind method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (fragment.getArguments() != null) {
            bind(fragment, fragment.getActivity(), fragment.getArguments());
        } else {
            bind(fragment, fragment.getActivity());
        }
    }

    /**
     * Stores all fields in the binding object annotated with Data (with beam set to true) using the specified
     * context. Context acts as both the binding object and the underlying storage context.
     *
     * @param context The binding object and the underlying storage object used with StorageMap.
     */
    public static final void beam(@NonNull Context context) {
        if (context == null) {
            throw new IllegalArgumentException("Context parameter in beam method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        beam(context, context);
    }

    /**
     * Stores all fields in the binding object annotated with Data (with beam set to true) using the specified
     * context.
     *
     * @param bindObject The binding object to check for Data annotated fields (objects to be stored).
     * @param context    The context used for the underlying storage mechanism; StorageMap.
     */
    public static final void beam(@NonNull Object bindObject, @NonNull Context context) {
        if (bindObject == null) {
            throw new IllegalArgumentException("Object parameter in beam method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (context == null) {
            throw new IllegalArgumentException("Context parameter in beam method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        StorageMap map = StorageMap.with(context);
        for (Field f : getAnnotatedFields(bindObject)) {
            try {
                f.setAccessible(true);
                Data d = f.getAnnotation(Data.class);
                if (d.beam()) {
                    map.put(d.value(), f.get(bindObject));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Stores all fields in the binding object annotated with Data (with beam set to true) using the specified
     * context.
     *
     * @param bindObject The binding object to check for Data annotated fields (objects to be stored).
     * @param context    The context used for the underlying storage mechanism; StorageMap.
     * @param intent     The intent used with context for the underlying storage mechanism; StorageMap.
     */
    public static final void beam(@NonNull Object bindObject, @NonNull Context context, Intent intent) {
        if (bindObject == null) {
            throw new IllegalArgumentException("Object parameter in beam method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (context == null) {
            throw new IllegalArgumentException("Context parameter in beam method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (intent == null) {
            beam(bindObject, context);
        } else {
            StorageMap map = StorageMap.with(context, intent);
            for (Field f : getAnnotatedFields(bindObject)) {
                try {
                    f.setAccessible(true);
                    Data d = f.getAnnotation(Data.class);
                    if (d.beam()) {
                        map.put(d.value(), f.get(bindObject));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Stores all fields in the binding object annotated with Data (with beam set to true) using the specified
     * context. Context acts as both the binding object and the underlying storage context.
     *
     * @param context Context acts as both the binding object and the underlying storage context.
     * @param intent  The intent used with context for the underlying storage mechanism; StorageMap.
     */
    public static final void beam(@NonNull Context context, Intent intent) {
        if (context == null) {
            throw new IllegalArgumentException("Context parameter in beam method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (intent == null) {
            beam(context, context);
        } else {
            beam(context, context, intent);
        }
    }

    /**
     * Stores all fields in the binding object annotated with Data (with beam set to true) using the specified
     * context.
     *
     * @param bindObject The binding object to check for Data annotated fields (objects to be stored).
     * @param context    The context used for the underlying storage mechanism; StorageMap.
     * @param bundle     The bundle used with context for the underlying storage mechanism; StorageMap.
     */
    public static final void beam(@NonNull Object bindObject, @NonNull Context context, Bundle bundle) {
        if (bindObject == null) {
            throw new IllegalArgumentException("Object parameter in beam method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (context == null) {
            throw new IllegalArgumentException("Context parameter in beam method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (bundle == null) {
            beam(bindObject, context);
        } else {
            StorageMap map = StorageMap.with(context, bundle);
            for (Field f : getAnnotatedFields(bindObject)) {
                try {
                    f.setAccessible(true);
                    Data d = f.getAnnotation(Data.class);
                    if (d.beam()) {
                        map.put(d.value(), f.get(bindObject));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Stores all fields in the binding object annotated with Data (with beam set to true) using the specified
     * context.
     *
     * @param context Context acts as both the binding object and the underlying storage context.
     * @param bundle  The bundle used with context for the underlying storage mechanism; StorageMap.
     */
    public static final void beam(@NonNull Context context, Bundle bundle) {
        if (context == null) {
            throw new IllegalArgumentException("Context parameter in beam method of "
                    + Teleport.class.getSimpleName() + " class must not be null.");
        }
        if (bundle == null) {
            beam(context, context);
        } else {
            beam(context, context, bundle);
        }
    }

    /**
     * Retrieves all the Field objects that have a Data annotation within the binding object class.
     *
     * @param bindingObject The object to search for Data annotated Fields.
     * @return List<Field> The list of annotated Fields; returns an empty list if there are no Fields.
     */
    private static final List<Field> getAnnotatedFields(Object bindingObject) {
        List<Field> fields = new ArrayList<>();
        for (Field f : bindingObject.getClass().getDeclaredFields()) {
            if (f.isAnnotationPresent(Data.class)) {
                f.setAccessible(true);
                fields.add(f);
            }
        }
        return fields;
    }

}