/*
 * Copyright (c) 2005, 2008, 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 6221321 6295867
 * @summary Test that annotations in Standard MBean interfaces
 * correctly produce Descriptor entries
 * @author Eamonn McManus
 * @run clean AnnotationTest
 * @run build AnnotationTest
 * @run main AnnotationTest
 */

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.management.Descriptor;
import javax.management.DescriptorRead;
import javax.management.DescriptorKey;
import javax.management.ImmutableDescriptor;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.ObjectName;

/*
  This test checks that annotations produce Descriptor entries as
  specified in javax.management.DescriptorKey.  It does two things:

  - An annotation consisting of an int and a String, each with an
    appropriate @DescriptorKey annotation, is placed on every program
    element where it can map to a Descriptor, namely:

    . on an MBean interface
    . on a getter for a read-only attribute
    . on a setter for a write-only attribute
    . on the getter but not the setter for a read/write attribute
    . on the setter but not the getter for a read/write attribute
    . on both the getter and the setter for a read/write attribute
    . on an operation
    . on each parameter of an operation
    . on a public constructor with no parameters
    . on a public constructor with a parameter
    . on the parameter of that public constructor
    . on all of the above for an MXBean instead of an MBean

    The test checks that in each case the corresponding Descriptor
    appears in the appropriate place inside the MBean's MBeanInfo.

  - An annotation consisting of enough other types to ensure coverage
    is placed on a getter.  The test checks that the generated
    MBeanAttributeInfo contains the corresponding Descriptor.  The tested
    types are the following:

    . Class
    . an enumeration type (java.lang.annotation.RetentionPolicy)
    . boolean
    . String[]
    . Class[]
    . int[]
    . an array of enumeration type (RetentionPolicy[])
    . boolean[]
 */
public class AnnotationTest {
    private static String failed = null;

    @Retention(RetentionPolicy.RUNTIME)
    public static @interface Pair {
        @DescriptorKey("x")
        int x();
        @DescriptorKey("y")
        String y();
    }

    @Retention(RetentionPolicy.RUNTIME)
    public static @interface Full {
        @DescriptorKey("class")
        Class classValue();
        @DescriptorKey("enum")
        RetentionPolicy enumValue();
        @DescriptorKey("boolean")
        boolean booleanValue();
        @DescriptorKey("stringArray")
        String[] stringArrayValue();
        @DescriptorKey("classArray")
        Class[] classArrayValue();
        @DescriptorKey("intArray")
        int[] intArrayValue();
        @DescriptorKey("enumArray")
        RetentionPolicy[] enumArrayValue();
        @DescriptorKey("booleanArray")
        boolean[] booleanArrayValue();
    }

    /* We use the annotation @Pair(x = 3, y = "foo") everywhere, and this is
       the Descriptor that it should produce: */
    private static Descriptor expectedDescriptor =
        new ImmutableDescriptor(new String[] {"x", "y"},
                                new Object[] {3, "foo"});

    private static Descriptor expectedFullDescriptor =
        new ImmutableDescriptor(new String[] {
                                    "class", "enum", "boolean", "stringArray",
                                    "classArray", "intArray", "enumArray",
                                    "booleanArray",
                                },
                                new Object[] {
                                    Full.class.getName(),
                                    RetentionPolicy.RUNTIME.name(),
                                    false,
                                    new String[] {"foo", "bar"},
                                    new String[] {Full.class.getName()},
                                    new int[] {1, 2},
                                    new String[] {RetentionPolicy.RUNTIME.name()},
                                    new boolean[] {false, true},
                                });

    @Pair(x = 3, y = "foo")
    public static interface ThingMBean {
        @Pair(x = 3, y = "foo")
        @Full(classValue=Full.class,
              enumValue=RetentionPolicy.RUNTIME,
              booleanValue=false,
              stringArrayValue={"foo", "bar"},
              classArrayValue={Full.class},
              intArrayValue={1, 2},
              enumArrayValue={RetentionPolicy.RUNTIME},
              booleanArrayValue={false, true})
        int getReadOnly();

        @Pair(x = 3, y = "foo")
        void setWriteOnly(int x);

        @Pair(x = 3, y = "foo")
        int getReadWrite1();
        void setReadWrite1(int x);

        @Pair(x = 3, y = "foo")
        int getReadWrite2();
        @Pair(x = 3, y = "foo")
        void setReadWrite2(int x);

        int getReadWrite3();
        @Pair(x = 3, y = "foo")
        void setReadWrite3(int x);

        @Pair(x = 3, y = "foo")
        int operation(@Pair(x = 3, y = "foo") int p1,
                      @Pair(x = 3, y = "foo") int p2);
    }

    public static class Thing implements ThingMBean {
        @Pair(x = 3, y = "foo")
        public Thing() {}

        @Pair(x = 3, y = "foo")
        public Thing(@Pair(x = 3, y = "foo") int p1) {}

        public int getReadOnly() {return 0;}

        public void setWriteOnly(int x) {}

        public int getReadWrite1() {return 0;}
        public void setReadWrite1(int x) {}

        public int getReadWrite2() {return 0;}
        public void setReadWrite2(int x) {}

        public int getReadWrite3() {return 0;}
        public void setReadWrite3(int x) {}

        public int operation(int p1, int p2) {return 0;}
    }

    @Pair(x = 3, y = "foo")
    public static interface ThingMXBean extends ThingMBean {}

    public static class ThingImpl implements ThingMXBean {
        @Pair(x = 3, y = "foo")
        public ThingImpl() {}

        @Pair(x = 3, y = "foo")
        public ThingImpl(@Pair(x = 3, y = "foo") int p1) {}

        public int getReadOnly() {return 0;}

        public void setWriteOnly(int x) {}

        public int getReadWrite1() {return 0;}
        public void setReadWrite1(int x) {}

        public int getReadWrite2() {return 0;}
        public void setReadWrite2(int x) {}

        public int getReadWrite3() {return 0;}
        public void setReadWrite3(int x) {}

        public int operation(int p1, int p2) {return 0;}
    }

    public static void main(String[] args) throws Exception {
        System.out.println("Testing that annotations are correctly " +
                           "reflected in Descriptor entries");

        MBeanServer mbs =
            java.lang.management.ManagementFactory.getPlatformMBeanServer();
        ObjectName on = new ObjectName("a:b=c");

        Thing thing = new Thing();
        mbs.registerMBean(thing, on);
        check(mbs, on);
        mbs.unregisterMBean(on);

        ThingImpl thingImpl = new ThingImpl();
        mbs.registerMBean(thingImpl, on);
        Descriptor d = mbs.getMBeanInfo(on).getDescriptor();
        if (!d.getFieldValue("mxbean").equals("true")) {
            System.out.println("NOT OK: expected MXBean");
            failed = "Expected MXBean";
        }
        check(mbs, on);

        if (failed == null)
            System.out.println("Test passed");
        else
            throw new Exception("TEST FAILED: " + failed);
    }

    private static void check(MBeanServer mbs, ObjectName on) throws Exception {
        MBeanInfo mbi = mbs.getMBeanInfo(on);

        // check the MBean itself
        check(mbi);

        // check attributes
        MBeanAttributeInfo[] attrs = mbi.getAttributes();
        for (MBeanAttributeInfo attr : attrs) {
            check(attr);
            if (attr.getName().equals("ReadOnly"))
                check("@Full", attr.getDescriptor(), expectedFullDescriptor);
        }

        // check operations
        MBeanOperationInfo[] ops = mbi.getOperations();
        for (MBeanOperationInfo op : ops) {
            check(op);
            check(op.getSignature());
        }

        MBeanConstructorInfo[] constrs = mbi.getConstructors();
        for (MBeanConstructorInfo constr : constrs) {
            check(constr);
            check(constr.getSignature());
        }
    }

    private static void check(DescriptorRead x) {
        check(x, x.getDescriptor(), expectedDescriptor);
    }

    private static void check(Object x, Descriptor d, Descriptor expect) {
        String fail = null;
        try {
            Descriptor u = ImmutableDescriptor.union(d, expect);
            if (!u.equals(d))
                fail = "should contain " + expect + "; is " + d;
        } catch (IllegalArgumentException e) {
            fail = e.getMessage();
        }
        if (fail == null) {
            System.out.println("OK: " + x);
        } else {
            failed = "NOT OK: Incorrect descriptor for: " + x;
            System.out.println(failed);
            System.out.println("..." + fail);
        }
    }

    private static void check(DescriptorRead[] xx) {
        for (DescriptorRead x : xx)
            check(x);
    }
}
