/*
 * Copyright 2005-2006 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 com.sun.tools.attach;

import com.sun.tools.attach.spi.AttachProvider;

/**
 * Describes a Java virtual machine.
 *
 * <p> A <code>VirtualMachineDescriptor</code> is a container class used to
 * describe a Java virtual machine. It encapsulates an identifier that identifies
 * a target virtual machine, and a reference to the {@link
 * com.sun.tools.attach.spi.AttachProvider AttachProvider} that should be used
 * when attempting to attach to the virtual machine. The identifier is
 * implementation-dependent but is typically the process identifier (or pid)
 * environments where each Java virtual machine runs in its own operating system
 * process. </p>
 *
 * <p> A <code>VirtualMachineDescriptor</code> also has a {@link #displayName() displayName}.
 * The display name is typically a human readable string that a tool might
 * display to a user. For example, a tool that shows a list of Java
 * virtual machines running on a system might use the display name rather
 * than the identifier. A <code>VirtualMachineDescriptor</code> may be
 * created without a <i>display name</i>. In that case the identifier is
 * used as the <i>display name</i>.
 *
 * <p> <code>VirtualMachineDescriptor</code> instances are typically created by
 * invoking the {@link com.sun.tools.attach.VirtualMachine#list VirtualMachine.list()}
 * method. This returns the complete list of descriptors to describe the
 * Java virtual machines known to all installed {@link
 * com.sun.tools.attach.spi.AttachProvider attach providers}.
 *
 * @since 1.6
 */
public class VirtualMachineDescriptor {

    private AttachProvider provider;
    private String id;
    private String displayName;

    private volatile int hash;        // 0 => not computed

    /**
     * Creates a virtual machine descriptor from the given components.
     *
     * @param   provider      The AttachProvider to attach to the Java virtual machine.
     * @param   id            The virtual machine identifier.
     * @param   displayName   The display name.
     *
     * @throws  NullPointerException
     *          If any of the arguments are <code>null</code>
     */
    public VirtualMachineDescriptor(AttachProvider provider, String id, String displayName) {
        if (provider == null) {
            throw new NullPointerException("provider cannot be null");
        }
        if (id == null) {
            throw new NullPointerException("identifier cannot be null");
        }
        if (displayName == null) {
            throw new NullPointerException("display name cannot be null");
        }
        this.provider = provider;
        this.id = id;
        this.displayName = displayName;
    }

    /**
     * Creates a virtual machine descriptor from the given components.
     *
     * <p> This convenience constructor works as if by invoking the
     * three-argument constructor as follows:
     *
     * <blockquote><tt>
     * new&nbsp;{@link #VirtualMachineDescriptor(AttachProvider, String, String)
     * VirtualMachineDescriptor}(provider, &nbsp;id, &nbsp;id);
     * </tt></blockquote>
     *
     * <p> That is, it creates a virtual machine descriptor such that
     * the <i>display name</i> is the same as the virtual machine
     * identifier.
     *
     * @param   provider      The AttachProvider to attach to the Java virtual machine.
     * @param   id            The virtual machine identifier.
     *
     * @throws  NullPointerException
     *          If <tt>provider</tt> or <tt>id</tt> is <tt>null</tt>.
     */
    public VirtualMachineDescriptor(AttachProvider provider, String id) {
        this(provider, id, id);
    }

    /**
     * Return the <code>AttachProvider</code> that this descriptor references.
     *
     * @return The <code>AttachProvider</code> that this descriptor references.
     */
    public AttachProvider provider() {
        return provider;
    }

    /**
     * Return the identifier component of this descriptor.
     *
     * @return  The identifier component of this descriptor.
     */
    public String id() {
        return id;
    }

    /**
     * Return the <i>display name</i> component of this descriptor.
     *
     * @return  The display name component of this descriptor.
     */
    public String displayName() {
        return displayName;
    }

    /**
     * Returns a hash-code value for this VirtualMachineDescriptor. The hash
     * code is based upon the descriptor's components, and satifies
     * the general contract of the {@link java.lang.Object#hashCode()
     * Object.hashCode} method.
     *
     * @return  A hash-code value for this descriptor.
     */
    public int hashCode() {
        if (hash != 0) {
            return hash;
        }
        hash = provider.hashCode() * 127 + id.hashCode();
        return hash;
    }

    /**
     * Tests this VirtualMachineDescriptor for equality with another object.
     *
     * <p> If the given object is not a VirtualMachineDescriptor then this
     * method returns <tt>false</tt>. For two VirtualMachineDescriptors to
     * be considered equal requires that they both reference the same
     * provider, and their {@link #id() identifiers} are equal. </p>
     *
     * <p> This method satisfies the general contract of the {@link
     * java.lang.Object#equals(Object) Object.equals} method. </p>
     *
     * @param   ob   The object to which this object is to be compared
     *
     * @return  <tt>true</tt> if, and only if, the given object is
     *                a VirtualMachineDescriptor that is equal to this
     *                VirtualMachineDescriptor.
     */
    public boolean equals(Object ob) {
        if (ob == this)
            return true;
        if (!(ob instanceof VirtualMachineDescriptor))
            return false;
        VirtualMachineDescriptor other = (VirtualMachineDescriptor)ob;
        if (other.provider() != this.provider()) {
            return false;
        }
        if (!other.id().equals(this.id())) {
            return false;
        }
        return true;
    }

    /**
     * Returns the string representation of the <code>VirtualMachineDescriptor</code>.
     */
    public String toString() {
        String s = provider.toString() + ": " + id;
        if (displayName != id) {
            s += " " + displayName;
        }
        return s;
    }


}
