Android Open Source - Pedometer Reflective Property






From Project

Back to project page Pedometer.

License

The source code is released under:

Apache License

If you think the Android project Pedometer listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2011 The Android Open Source Project
 *//from ww  w  .j a  va  2s. co  m
 * 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
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */
package com.nineoldandroids.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Internal class to automatically generate a Property for a given class/name pair, given the
 * specification of {@link Property#of(java.lang.Class, java.lang.Class, java.lang.String)}
 */
class ReflectiveProperty<T, V> extends Property<T, V> {

    private static final String PREFIX_GET = "get";
    private static final String PREFIX_IS = "is";
    private static final String PREFIX_SET = "set";
    private Method mSetter;
    private Method mGetter;
    private Field mField;

    /**
     * For given property name 'name', look for getName/isName method or 'name' field.
     * Also look for setName method (optional - could be readonly). Failing method getters and
     * field results in throwing NoSuchPropertyException.
     *
     * @param propertyHolder The class on which the methods or field are found
     * @param name The name of the property, where this name is capitalized and appended to
     * "get" and "is to search for the appropriate methods. If the get/is methods are not found,
     * the constructor will search for a field with that exact name.
     */
    public ReflectiveProperty(Class<T> propertyHolder, Class<V> valueType, String name) {
         // TODO: cache reflection info for each new class/name pair
        super(valueType, name);
        char firstLetter = Character.toUpperCase(name.charAt(0));
        String theRest = name.substring(1);
        String capitalizedName = firstLetter + theRest;
        String getterName = PREFIX_GET + capitalizedName;
        try {
            mGetter = propertyHolder.getMethod(getterName, (Class<?>[]) null);
        } catch (NoSuchMethodException e) {
            try {
                /* The native implementation uses JNI to do reflection, which allows access to private methods.
                 * getDeclaredMethod(..) does not find superclass methods, so it's implemented as a fallback.
                 */
                mGetter = propertyHolder.getDeclaredMethod(getterName, (Class<?>[]) null);
                mGetter.setAccessible(true);
            } catch (NoSuchMethodException e2) {
                // getName() not available - try isName() instead
                getterName = PREFIX_IS + capitalizedName;
                try {
                    mGetter = propertyHolder.getMethod(getterName, (Class<?>[]) null);
                } catch (NoSuchMethodException e3) {
                    try {
                        /* The native implementation uses JNI to do reflection, which allows access to private methods.
                         * getDeclaredMethod(..) does not find superclass methods, so it's implemented as a fallback.
                         */
                        mGetter = propertyHolder.getDeclaredMethod(getterName, (Class<?>[]) null);
                        mGetter.setAccessible(true);
                    } catch (NoSuchMethodException e4) {
                        // Try public field instead
                        try {
                            mField = propertyHolder.getField(name);
                            Class fieldType = mField.getType();
                            if (!typesMatch(valueType, fieldType)) {
                                throw new NoSuchPropertyException("Underlying type (" + fieldType + ") " +
                                        "does not match Property type (" + valueType + ")");
                            }
                            return;
                        } catch (NoSuchFieldException e5) {
                            // no way to access property - throw appropriate exception
                            throw new NoSuchPropertyException("No accessor method or field found for"
                                    + " property with name " + name);
                        }
                    }
                }
            }
        }
        Class getterType = mGetter.getReturnType();
        // Check to make sure our getter type matches our valueType
        if (!typesMatch(valueType, getterType)) {
            throw new NoSuchPropertyException("Underlying type (" + getterType + ") " +
                    "does not match Property type (" + valueType + ")");
        }
        String setterName = PREFIX_SET + capitalizedName;
        try {
            // mSetter = propertyHolder.getMethod(setterName, getterType);
            // The native implementation uses JNI to do reflection, which allows access to private methods.
            mSetter = propertyHolder.getDeclaredMethod(setterName, getterType);
            mSetter.setAccessible(true);
        } catch (NoSuchMethodException ignored) {
            // Okay to not have a setter - just a readonly property
        }
    }

    /**
     * Utility method to check whether the type of the underlying field/method on the target
     * object matches the type of the Property. The extra checks for primitive types are because
     * generics will force the Property type to be a class, whereas the type of the underlying
     * method/field will probably be a primitive type instead. Accept float as matching Float,
     * etc.
     */
    private boolean typesMatch(Class<V> valueType, Class getterType) {
        if (getterType != valueType) {
            if (getterType.isPrimitive()) {
                return (getterType == float.class && valueType == Float.class) ||
                        (getterType == int.class && valueType == Integer.class) ||
                        (getterType == boolean.class && valueType == Boolean.class) ||
                        (getterType == long.class && valueType == Long.class) ||
                        (getterType == double.class && valueType == Double.class) ||
                        (getterType == short.class && valueType == Short.class) ||
                        (getterType == byte.class && valueType == Byte.class) ||
                        (getterType == char.class && valueType == Character.class);
            }
            return false;
        }
        return true;
    }

    @Override
    public void set(T object, V value) {
        if (mSetter != null) {
            try {
                mSetter.invoke(object, value);
            } catch (IllegalAccessException e) {
                throw new AssertionError();
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e.getCause());
            }
        } else if (mField != null) {
            try {
                mField.set(object, value);
            } catch (IllegalAccessException e) {
                throw new AssertionError();
            }
        } else {
            throw new UnsupportedOperationException("Property " + getName() +" is read-only");
        }
    }

    @Override
    public V get(T object) {
        if (mGetter != null) {
            try {
                return (V) mGetter.invoke(object, (Object[])null);
            } catch (IllegalAccessException e) {
                throw new AssertionError();
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e.getCause());
            }
        } else if (mField != null) {
            try {
                return (V) mField.get(object);
            } catch (IllegalAccessException e) {
                throw new AssertionError();
            }
        }
        // Should not get here: there should always be a non-null getter or field
        throw new AssertionError();
    }

    /**
     * Returns false if there is no setter or public field underlying this Property.
     */
    @Override
    public boolean isReadOnly() {
        return (mSetter == null && mField == null);
    }
}




Java Source Code List

com.google.example.games.basegameutils.ApplicationTest.java
com.google.example.games.basegameutils.BaseGameActivity.java
com.google.example.games.basegameutils.GameHelperUtils.java
com.google.example.games.basegameutils.GameHelper.java
com.nineoldandroids.ApplicationTest.java
com.nineoldandroids.animation.AnimatorInflater.java
com.nineoldandroids.animation.AnimatorListenerAdapter.java
com.nineoldandroids.animation.AnimatorSet.java
com.nineoldandroids.animation.Animator.java
com.nineoldandroids.animation.ArgbEvaluator.java
com.nineoldandroids.animation.FloatEvaluator.java
com.nineoldandroids.animation.FloatKeyframeSet.java
com.nineoldandroids.animation.IntEvaluator.java
com.nineoldandroids.animation.IntKeyframeSet.java
com.nineoldandroids.animation.KeyframeSet.java
com.nineoldandroids.animation.Keyframe.java
com.nineoldandroids.animation.ObjectAnimator.java
com.nineoldandroids.animation.PreHoneycombCompat.java
com.nineoldandroids.animation.PropertyValuesHolder.java
com.nineoldandroids.animation.TimeAnimator.java
com.nineoldandroids.animation.TypeEvaluator.java
com.nineoldandroids.animation.ValueAnimator.java
com.nineoldandroids.util.FloatProperty.java
com.nineoldandroids.util.IntProperty.java
com.nineoldandroids.util.NoSuchPropertyException.java
com.nineoldandroids.util.Property.java
com.nineoldandroids.util.ReflectiveProperty.java
com.nineoldandroids.view.ViewHelper.java
com.nineoldandroids.view.ViewPropertyAnimatorHC.java
com.nineoldandroids.view.ViewPropertyAnimatorICS.java
com.nineoldandroids.view.ViewPropertyAnimatorPreHC.java
com.nineoldandroids.view.ViewPropertyAnimator.java
com.nineoldandroids.view.animation.AnimatorProxy.java
de.j4velin.pedometer.Activity_Main.java
de.j4velin.pedometer.AppUpdatedReceiver.java
de.j4velin.pedometer.ApplicationTest.java
de.j4velin.pedometer.BootReceiver.java
de.j4velin.pedometer.Database.java
de.j4velin.pedometer.Dialog_Split.java
de.j4velin.pedometer.Dialog_Statistics.java
de.j4velin.pedometer.Fragment_Overview.java
de.j4velin.pedometer.Fragment_Settings.java
de.j4velin.pedometer.PlayServices.java
de.j4velin.pedometer.background.SensorListener.java
de.j4velin.pedometer.background.ShutdownRecevier.java
de.j4velin.pedometer.util.ColorPreview.java
de.j4velin.pedometer.util.Logger.java
de.j4velin.pedometer.util.TimeZoneListener.java
de.j4velin.pedometer.util.Util.java
de.j4velin.pedometer.widget.DashClock.java
de.j4velin.pedometer.widget.WidgetConfig.java
de.j4velin.pedometer.widget.WidgetUpdateService.java
de.j4velin.pedometer.widget.Widget.java
net.margaritov.preference.colorpicker.AlphaPatternDrawable.java
net.margaritov.preference.colorpicker.ApplicationTest.java
net.margaritov.preference.colorpicker.ColorPickerDialog.java
net.margaritov.preference.colorpicker.ColorPickerPanelView.java
net.margaritov.preference.colorpicker.ColorPickerPreference.java
net.margaritov.preference.colorpicker.ColorPickerView.java
net.margaritov.preference.colorpicker.Test.java
org.eazegraph.lib.ApplicationTest.java
org.eazegraph.lib.charts.BarChart.java
org.eazegraph.lib.charts.BaseBarChart.java
org.eazegraph.lib.charts.BaseChart.java
org.eazegraph.lib.charts.PieChart.java
org.eazegraph.lib.charts.StackedBarChart.java
org.eazegraph.lib.charts.ValueLineChart.java
org.eazegraph.lib.communication.IOnBarClickedListener.java
org.eazegraph.lib.communication.IOnItemFocusChangedListener.java
org.eazegraph.lib.communication.IOnPointFocusedListener.java
org.eazegraph.lib.models.BarModel.java
org.eazegraph.lib.models.BaseModel.java
org.eazegraph.lib.models.LegendModel.java
org.eazegraph.lib.models.PieModel.java
org.eazegraph.lib.models.Point2D.java
org.eazegraph.lib.models.StackedBarModel.java
org.eazegraph.lib.models.StandardValue.java
org.eazegraph.lib.models.ValueLinePoint.java
org.eazegraph.lib.models.ValueLineSeries.java
org.eazegraph.lib.utils.Utils.java