219 lines · 8.8 KB · Java
RawDownload
/* * Copyright (c) 2011, 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.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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. */ package sun.management; import com.sun.management.GarbageCollectionNotificationInfo;import com.sun.management.GcInfo;import java.lang.reflect.Method;import javax.management.openmbean.CompositeData;import javax.management.openmbean.CompositeType;import javax.management.openmbean.CompositeDataSupport;import javax.management.openmbean.OpenDataException;import javax.management.openmbean.OpenType;import javax.management.openmbean.SimpleType;import java.security.AccessController;import java.security.PrivilegedAction;import java.lang.reflect.Field;import java.util.HashMap; /** * A CompositeData for GarbageCollectionNotificationInfo for the local management support. * This class avoids the performance penalty paid to the * construction of a CompositeData use in the local case. */public class GarbageCollectionNotifInfoCompositeData extends LazyCompositeData {    private final GarbageCollectionNotificationInfo gcNotifInfo;     public GarbageCollectionNotifInfoCompositeData(GarbageCollectionNotificationInfo info) {        this.gcNotifInfo = info;    }     public GarbageCollectionNotificationInfo getGarbageCollectionNotifInfo() {        return gcNotifInfo;    }     public static CompositeData toCompositeData(GarbageCollectionNotificationInfo info) {        GarbageCollectionNotifInfoCompositeData gcnicd =            new GarbageCollectionNotifInfoCompositeData(info);        return gcnicd.getCompositeData();    }     private CompositeType getCompositeTypeByBuilder() {        final GcInfoBuilder builder = AccessController.doPrivileged (new PrivilegedAction<GcInfoBuilder>() {                public GcInfoBuilder run() {                    try {                        Class cl = Class.forName("com.sun.management.GcInfo");                        Field f = cl.getDeclaredField("builder");                        f.setAccessible(true);                        return (GcInfoBuilder)f.get(gcNotifInfo.getGcInfo());                    } catch(ClassNotFoundException e) {                        return null;                    } catch(NoSuchFieldException e) {                        return null;                    } catch(IllegalAccessException e) {                        return null;                    }                }            });        CompositeType gict = null;        synchronized(compositeTypeByBuilder) {            gict = compositeTypeByBuilder.get(builder);            if(gict == null) {                OpenType[] gcNotifInfoItemTypes = new OpenType[] {                    SimpleType.STRING,                    SimpleType.STRING,                    SimpleType.STRING,                    builder.getGcInfoCompositeType(),                };                try {                    final String typeName =                        "sun.management.GarbageCollectionNotifInfoCompositeType";                    gict = new CompositeType(typeName,                                             "CompositeType for GC notification info",                                             gcNotifInfoItemNames,                                             gcNotifInfoItemNames,                                             gcNotifInfoItemTypes);                    compositeTypeByBuilder.put(builder,gict);                } catch (OpenDataException e) {                    // shouldn't reach here                    throw Util.newException(e);                }            }        }        return gict;    }     protected CompositeData getCompositeData() {        // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH        // gcNotifInfoItemNames!        final Object[] gcNotifInfoItemValues;        gcNotifInfoItemValues = new Object[] {            gcNotifInfo.getGcName(),            gcNotifInfo.getGcAction(),            gcNotifInfo.getGcCause(),            GcInfoCompositeData.toCompositeData(gcNotifInfo.getGcInfo())        };         CompositeType gict = getCompositeTypeByBuilder();         try {            return new CompositeDataSupport(gict,                                            gcNotifInfoItemNames,                                            gcNotifInfoItemValues);        } catch (OpenDataException e) {            // Should never reach here            throw new AssertionError(e);        }    }     //    private static MappedMXBeanType gcInfoMapType;    private static final String GC_NAME = "gcName";    private static final String GC_ACTION = "gcAction";    private static final String GC_CAUSE = "gcCause";    private static final String GC_INFO     = "gcInfo";    private static final String[] gcNotifInfoItemNames = {        GC_NAME,        GC_ACTION,        GC_CAUSE,        GC_INFO    };    private static HashMap<GcInfoBuilder,CompositeType> compositeTypeByBuilder =        new HashMap<GcInfoBuilder,CompositeType>();     public static String getGcName(CompositeData cd) {        String gcname = getString(cd, GC_NAME);        if (gcname == null) {            throw new IllegalArgumentException("Invalid composite data: " +                "Attribute " + GC_NAME + " has null value");        }        return gcname;    }     public static String getGcAction(CompositeData cd) {        String gcaction = getString(cd, GC_ACTION);        if (gcaction == null) {            throw new IllegalArgumentException("Invalid composite data: " +                "Attribute " + GC_ACTION + " has null value");        }        return gcaction;    }     public static String getGcCause(CompositeData cd) {        String gccause = getString(cd, GC_CAUSE);        if (gccause == null) {            throw new IllegalArgumentException("Invalid composite data: " +                "Attribute " + GC_CAUSE + " has null value");        }        return gccause;    }     public static GcInfo getGcInfo(CompositeData cd) {        CompositeData gcInfoData = (CompositeData) cd.get(GC_INFO);        return GcInfo.from(gcInfoData);    }     /** Validate if the input CompositeData has the expected     * CompositeType (i.e. contain all attributes with expected     * names and types).     */    public static void validateCompositeData(CompositeData cd) {        if (cd == null) {            throw new NullPointerException("Null CompositeData");        }         if (!isTypeMatched( getBaseGcNotifInfoCompositeType(), cd.getCompositeType())) {            throw new IllegalArgumentException(                "Unexpected composite type for GarbageCollectionNotificationInfo");        }    }     // This is only used for validation.    private static CompositeType baseGcNotifInfoCompositeType = null;    private static synchronized CompositeType getBaseGcNotifInfoCompositeType() {        if (baseGcNotifInfoCompositeType == null) {            try {                OpenType[] baseGcNotifInfoItemTypes = new OpenType[] {                    SimpleType.STRING,                    SimpleType.STRING,                    SimpleType.STRING,                    GcInfoCompositeData.getBaseGcInfoCompositeType()                };                baseGcNotifInfoCompositeType =                    new CompositeType("sun.management.BaseGarbageCollectionNotifInfoCompositeType",                                      "CompositeType for Base GarbageCollectionNotificationInfo",                                      gcNotifInfoItemNames,                                      gcNotifInfoItemNames,                                      baseGcNotifInfoItemTypes);            } catch (OpenDataException e) {                // shouldn't reach here                throw Util.newException(e);            }        }        return baseGcNotifInfoCompositeType;    }     private static final long serialVersionUID = -1805123446483771292L;}