/*
 * Copyright 2004 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.management;

import java.lang.management.MemoryNotificationInfo;
import java.lang.management.MemoryUsage;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.OpenDataException;

/**
 * A CompositeData for MemoryNotificationInfo 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 MemoryNotifInfoCompositeData extends LazyCompositeData {
    private final MemoryNotificationInfo memoryNotifInfo;

    private MemoryNotifInfoCompositeData(MemoryNotificationInfo info) {
        this.memoryNotifInfo = info;
    }

    public MemoryNotificationInfo getMemoryNotifInfo() {
        return memoryNotifInfo;
    }

    public static CompositeData toCompositeData(MemoryNotificationInfo info) {
        MemoryNotifInfoCompositeData mnicd =
            new MemoryNotifInfoCompositeData(info);
        return mnicd.getCompositeData();
    }

    protected CompositeData getCompositeData() {
        // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
        // memoryNotifInfoItemNames!
        final Object[] memoryNotifInfoItemValues = {
            memoryNotifInfo.getPoolName(),
            MemoryUsageCompositeData.toCompositeData(memoryNotifInfo.getUsage()),
            new Long(memoryNotifInfo.getCount()),
        };

        try {
            return new CompositeDataSupport(memoryNotifInfoCompositeType,
                                            memoryNotifInfoItemNames,
                                            memoryNotifInfoItemValues);
        } catch (OpenDataException e) {
            // Should never reach here
            throw Util.newInternalError(e);
        }
    }

    private static final CompositeType memoryNotifInfoCompositeType;
    static {
        try {
            memoryNotifInfoCompositeType = (CompositeType)
                MappedMXBeanType.toOpenType(MemoryNotificationInfo.class);
        } catch (OpenDataException e) {
            // Should never reach here
            throw Util.newInternalError(e);
        }
    }

    private static final String POOL_NAME = "poolName";
    private static final String USAGE     = "usage";
    private static final String COUNT     = "count";
    private static final String[] memoryNotifInfoItemNames = {
        POOL_NAME,
        USAGE,
        COUNT,
    };


    public static String getPoolName(CompositeData cd) {
        String poolname = getString(cd, POOL_NAME);
        if (poolname == null) {
            throw new IllegalArgumentException("Invalid composite data: " +
                "Attribute " + POOL_NAME + " has null value");
        }
        return poolname;
    }

    public static MemoryUsage getUsage(CompositeData cd) {
        CompositeData usageData = (CompositeData) cd.get(USAGE);
        return MemoryUsage.from(usageData);
    }

    public static long getCount(CompositeData cd) {
        return getLong(cd, COUNT);
    }

    /** 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(memoryNotifInfoCompositeType, cd.getCompositeType())) {
            throw new IllegalArgumentException(
                "Unexpected composite type for MemoryNotificationInfo");
        }
    }

}
