/*
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 5043030
 * @summary Verify that the method java.lang.reflect.Field.get(Object) makes
 *          use of the same caching mechanism as used for autoboxing
 *          when wrapping values of the primitive types.
 * @author Andrej Golovnin
 */

import java.lang.reflect.Field;

public class TestFieldReflectValueOf {

    @SuppressWarnings("unused")
    private static boolean booleanStaticField;
    @SuppressWarnings("unused")
    private static byte byteStaticField;
    @SuppressWarnings("unused")
    private static char charStaticField;
    @SuppressWarnings("unused")
    private static int intStaticField;
    @SuppressWarnings("unused")
    private static long longStaticField;
    @SuppressWarnings("unused")
    private static short shortStaticField;

    @SuppressWarnings("unused")
    private static volatile boolean booleanStaticVolatileField;
    @SuppressWarnings("unused")
    private static volatile byte byteStaticVolatileField;
    @SuppressWarnings("unused")
    private static volatile char charStaticVolatileField;
    @SuppressWarnings("unused")
    private static volatile int intStaticVolatileField;
    @SuppressWarnings("unused")
    private static volatile long longStaticVolatileField;
    @SuppressWarnings("unused")
    private static volatile short shortStaticVolatileField;

    @SuppressWarnings("unused")
    private boolean booleanField;
    @SuppressWarnings("unused")
    private byte byteField;
    @SuppressWarnings("unused")
    private char charField;
    @SuppressWarnings("unused")
    private int intField;
    @SuppressWarnings("unused")
    private long longField;
    @SuppressWarnings("unused")
    private short shortField;

    @SuppressWarnings("unused")
    private volatile boolean booleanVolatileField;
    @SuppressWarnings("unused")
    private volatile byte byteVolatileField;
    @SuppressWarnings("unused")
    private volatile char charVolatileField;
    @SuppressWarnings("unused")
    private volatile int intVolatileField;
    @SuppressWarnings("unused")
    private volatile long longVolatileField;
    @SuppressWarnings("unused")
    private volatile short shortVolatileField;

    public static void main(String[] args) {
        testStaticFieldAccessors();
        testStaticVolatileFieldAccessors();
        testFieldAccessors();
        testVolatileFieldAccessors();
    }

    private static void testStaticFieldAccessors() {
        testFieldAccessors(true, false);
    }

    private static void testStaticVolatileFieldAccessors() {
        testFieldAccessors(true, true);
    }

    private static void testFieldAccessors() {
        testFieldAccessors(false, false);
    }

    private static void testVolatileFieldAccessors() {
        testFieldAccessors(false, true);
    }

    private static void testFieldAccessors(boolean checkStatic,
        boolean checkVolatile)
    {
        // Boolean#valueOf test
        testField(Boolean.TYPE, Boolean.FALSE, checkStatic, checkVolatile);
        testField(Boolean.TYPE, Boolean.TRUE, checkStatic, checkVolatile);

        // Byte#valueOf test
        for (int b = Byte.MIN_VALUE; b < (Byte.MAX_VALUE + 1); b++) {
            testField(Byte.TYPE, Byte.valueOf((byte) b), checkStatic, checkVolatile);
        }

        // Character#valueOf test
        for (char c = '\u0000'; c <= '\u007F'; c++) {
            testField(Character.TYPE, Character.valueOf(c), checkStatic, checkVolatile);
        }

        // Integer#valueOf test
        for (int i = -128; i <= 127; i++) {
            testField(Integer.TYPE, Integer.valueOf(i), checkStatic, checkVolatile);
        }

        // Long#valueOf test
        for (long l = -128L; l <= 127L; l++) {
            testField(Long.TYPE, Long.valueOf(l), checkStatic, checkVolatile);
        }

        // Short#valueOf test
        for (short s = -128; s <= 127; s++) {
            testField(Short.TYPE, Short.valueOf(s), checkStatic, checkVolatile);
        }
    }

    private static void testField(Class<?> primType, Object wrappedValue,
        boolean checkStatic, boolean checkVolatile)
    {
        String fieldName = primType.getName();
        if (checkStatic) {
            fieldName += "Static";
        }
        if (checkVolatile) {
            fieldName += "Volatile";
        }
        fieldName += "Field";
        try {
            Field field = TestFieldReflectValueOf.class.getDeclaredField(fieldName);
            field.setAccessible(true);
            TestFieldReflectValueOf obj = new TestFieldReflectValueOf();
            field.set(obj, wrappedValue);
            Object result = field.get(obj);
            if (result != wrappedValue) {
                throw new RuntimeException("The value " + wrappedValue
                    + " is not cached for the type " + primType);
            }
        } catch (  NoSuchFieldException | SecurityException
                 | IllegalAccessException | IllegalArgumentException e)
        {
            throw new RuntimeException(e);
        }
    }

}
