1fb3fb4f3Stomee /*
2fb3fb4f3Stomee  * CDDL HEADER START
3fb3fb4f3Stomee  *
4fb3fb4f3Stomee  * The contents of this file are subject to the terms of the
5fb3fb4f3Stomee  * Common Development and Distribution License (the "License").
6fb3fb4f3Stomee  * You may not use this file except in compliance with the License.
7fb3fb4f3Stomee  *
8fb3fb4f3Stomee  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fb3fb4f3Stomee  * or http://www.opensolaris.org/os/licensing.
10fb3fb4f3Stomee  * See the License for the specific language governing permissions
11fb3fb4f3Stomee  * and limitations under the License.
12fb3fb4f3Stomee  *
13fb3fb4f3Stomee  * When distributing Covered Code, include this CDDL HEADER in each
14fb3fb4f3Stomee  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fb3fb4f3Stomee  * If applicable, add the following below this CDDL HEADER, with the
16fb3fb4f3Stomee  * fields enclosed by brackets "[]" replaced with your own identifying
17fb3fb4f3Stomee  * information: Portions Copyright [yyyy] [name of copyright owner]
18fb3fb4f3Stomee  *
19fb3fb4f3Stomee  * CDDL HEADER END
20fb3fb4f3Stomee  */
21fb3fb4f3Stomee 
22fb3fb4f3Stomee /*
2391cfa10aStomee  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24fb3fb4f3Stomee  * Use is subject to license terms.
25fb3fb4f3Stomee  *
26fb3fb4f3Stomee  * ident	"%Z%%M%	%I%	%E% SMI"
27fb3fb4f3Stomee  */
28fb3fb4f3Stomee package org.opensolaris.os.dtrace;
29fb3fb4f3Stomee 
30fb3fb4f3Stomee import java.util.*;
31fb3fb4f3Stomee import java.io.*;
32fb3fb4f3Stomee import java.beans.*;
33fb3fb4f3Stomee 
34fb3fb4f3Stomee /**
35fb3fb4f3Stomee  * Probe stability information.  Does not identify a probe, but gives
36fb3fb4f3Stomee  * information about a single probe identified by a {@link
37fb3fb4f3Stomee  * ProbeDescription}.  A {@code ProbeDescription} can match multiple
38fb3fb4f3Stomee  * probes using pattern syntax (globbing) and wildcarding (field
39fb3fb4f3Stomee  * omission), but it does not normally make sense to associate a {@code
40fb3fb4f3Stomee  * ProbeInfo} with a {@code ProbeDescription} unless that description
41fb3fb4f3Stomee  * matches exactly one probe on the system.  A {@link Probe} pairs a
42fb3fb4f3Stomee  * {@code ProbeDescription} with information about the DTrace probe it
43fb3fb4f3Stomee  * identifies.
44fb3fb4f3Stomee  * <p>
45fb3fb4f3Stomee  * Immutable.  Supports persistence using {@link java.beans.XMLEncoder}.
46fb3fb4f3Stomee  *
47fb3fb4f3Stomee  * @see Consumer#listProbeDetail(ProbeDescription filter)
48fb3fb4f3Stomee  * @see Consumer#listProgramProbeDetail(Program program)
49fb3fb4f3Stomee  *
50fb3fb4f3Stomee  * @author Tom Erickson
51fb3fb4f3Stomee  */
52fb3fb4f3Stomee public final class ProbeInfo implements Serializable {
53fb3fb4f3Stomee     static final long serialVersionUID = 1057402669978245904L;
54fb3fb4f3Stomee 
55fb3fb4f3Stomee     static {
56fb3fb4f3Stomee 	try {
57fb3fb4f3Stomee 	    BeanInfo info = Introspector.getBeanInfo(ProbeInfo.class);
58fb3fb4f3Stomee 	    PersistenceDelegate persistenceDelegate =
59fb3fb4f3Stomee 		    new DefaultPersistenceDelegate(
60fb3fb4f3Stomee 		    new String[] {"probeAttributes",
61fb3fb4f3Stomee 		    "argumentAttributes"})
62fb3fb4f3Stomee 	    {
63fb3fb4f3Stomee 		/*
64fb3fb4f3Stomee 		 * Need to prevent DefaultPersistenceDelegate from using
65fb3fb4f3Stomee 		 * overridden equals() method, resulting in a
66fb3fb4f3Stomee 		 * StackOverFlowError.  Revert to PersistenceDelegate
67fb3fb4f3Stomee 		 * implementation.  See
68fb3fb4f3Stomee 		 * http://forum.java.sun.com/thread.jspa?threadID=
69fb3fb4f3Stomee 		 * 477019&tstart=135
70fb3fb4f3Stomee 		 */
71fb3fb4f3Stomee 		protected boolean
72fb3fb4f3Stomee 		mutatesTo(Object oldInstance, Object newInstance)
73fb3fb4f3Stomee 		{
74fb3fb4f3Stomee 		    return (newInstance != null && oldInstance != null &&
75fb3fb4f3Stomee 			    oldInstance.getClass() == newInstance.getClass());
76fb3fb4f3Stomee 		}
77fb3fb4f3Stomee 	    };
78fb3fb4f3Stomee 	    BeanDescriptor d = info.getBeanDescriptor();
79fb3fb4f3Stomee 	    d.setValue("persistenceDelegate", persistenceDelegate);
80fb3fb4f3Stomee 	} catch (IntrospectionException e) {
81fb3fb4f3Stomee 	    System.out.println(e);
82fb3fb4f3Stomee 	}
83fb3fb4f3Stomee     }
84fb3fb4f3Stomee 
85fb3fb4f3Stomee     /** @serial */
86fb3fb4f3Stomee     private final InterfaceAttributes probeAttributes;
87fb3fb4f3Stomee     /** @serial */
88fb3fb4f3Stomee     private final InterfaceAttributes argumentAttributes;
89fb3fb4f3Stomee 
90fb3fb4f3Stomee     /**
91fb3fb4f3Stomee      * Creates a {@code ProbeInfo} instance from the given attributes.
92fb3fb4f3Stomee      * Supports XML persistence.
93fb3fb4f3Stomee      *
94fb3fb4f3Stomee      * @throws NullPointerException if any parameter is null
95fb3fb4f3Stomee      */
96fb3fb4f3Stomee     public
ProbeInfo(InterfaceAttributes singleProbeAttributes, InterfaceAttributes argAttributes)97fb3fb4f3Stomee     ProbeInfo(InterfaceAttributes singleProbeAttributes,
98fb3fb4f3Stomee 	    InterfaceAttributes argAttributes)
99fb3fb4f3Stomee     {
100fb3fb4f3Stomee 	probeAttributes = singleProbeAttributes;
101fb3fb4f3Stomee 	argumentAttributes = argAttributes;
102fb3fb4f3Stomee 	validate();
103fb3fb4f3Stomee     }
104fb3fb4f3Stomee 
10591cfa10aStomee     private final void
validate()106fb3fb4f3Stomee     validate()
107fb3fb4f3Stomee     {
108fb3fb4f3Stomee 	if (probeAttributes == null) {
109fb3fb4f3Stomee 	    throw new NullPointerException("probeAttributes is null");
110fb3fb4f3Stomee 	}
111fb3fb4f3Stomee 	if (argumentAttributes == null) {
112fb3fb4f3Stomee 	    throw new NullPointerException("argumentAttributes is null");
113fb3fb4f3Stomee 	}
114fb3fb4f3Stomee     }
115fb3fb4f3Stomee 
116fb3fb4f3Stomee     /**
117fb3fb4f3Stomee      * Gets the interface attributes of a probe.
118fb3fb4f3Stomee      *
119fb3fb4f3Stomee      * @return non-null attributes including stability levels and
120fb3fb4f3Stomee      * dependency class
121fb3fb4f3Stomee      */
122fb3fb4f3Stomee     public InterfaceAttributes
getProbeAttributes()123fb3fb4f3Stomee     getProbeAttributes()
124fb3fb4f3Stomee     {
125fb3fb4f3Stomee 	return probeAttributes;
126fb3fb4f3Stomee     }
127fb3fb4f3Stomee 
128fb3fb4f3Stomee     /**
129fb3fb4f3Stomee      * Gets the interface attributes of the arguments to a probe.
130fb3fb4f3Stomee      *
131fb3fb4f3Stomee      * @return non-null attributes including stability levels and
132fb3fb4f3Stomee      * dependency class of the arguments to a probe
133fb3fb4f3Stomee      */
134fb3fb4f3Stomee     public InterfaceAttributes
getArgumentAttributes()135fb3fb4f3Stomee     getArgumentAttributes()
136fb3fb4f3Stomee     {
137fb3fb4f3Stomee 	return argumentAttributes;
138fb3fb4f3Stomee     }
139fb3fb4f3Stomee 
140fb3fb4f3Stomee     /**
141fb3fb4f3Stomee      * Compares the specified object with this {@code ProbeInfo}
142fb3fb4f3Stomee      * instance for equality.  Defines equality as having equal probe
143fb3fb4f3Stomee      * attributes and equal argument attributes.
144fb3fb4f3Stomee      *
145fb3fb4f3Stomee      * @return {@code true} if and only if the specified object is also
146fb3fb4f3Stomee      * a {@code ProbeInfo} and both instances have the same attributes
147fb3fb4f3Stomee      */
148fb3fb4f3Stomee     @Override
149fb3fb4f3Stomee     public boolean
equals(Object o)150fb3fb4f3Stomee     equals(Object o)
151fb3fb4f3Stomee     {
152fb3fb4f3Stomee 	if (o instanceof ProbeInfo) {
153fb3fb4f3Stomee 	    ProbeInfo i = (ProbeInfo)o;
154fb3fb4f3Stomee 	    return (probeAttributes.equals(i.probeAttributes) &&
155fb3fb4f3Stomee 		    argumentAttributes.equals(i.argumentAttributes));
156fb3fb4f3Stomee 	}
157fb3fb4f3Stomee 	return false;
158fb3fb4f3Stomee     }
159fb3fb4f3Stomee 
160fb3fb4f3Stomee     /**
161fb3fb4f3Stomee      * Overridden to ensure that equal instances have equal hash codes.
162fb3fb4f3Stomee      */
163fb3fb4f3Stomee     @Override
164fb3fb4f3Stomee     public int
hashCode()165fb3fb4f3Stomee     hashCode()
166fb3fb4f3Stomee     {
167fb3fb4f3Stomee 	int hash = 17;
168fb3fb4f3Stomee 	hash = (37 * hash) + probeAttributes.hashCode();
169fb3fb4f3Stomee 	hash = (37 * hash) + argumentAttributes.hashCode();
170fb3fb4f3Stomee 	return hash;
171fb3fb4f3Stomee     }
172fb3fb4f3Stomee 
173fb3fb4f3Stomee     private void
readObject(ObjectInputStream s)174fb3fb4f3Stomee     readObject(ObjectInputStream s)
175fb3fb4f3Stomee             throws IOException, ClassNotFoundException
176fb3fb4f3Stomee     {
177fb3fb4f3Stomee 	s.defaultReadObject();
178fb3fb4f3Stomee 	// Must copy before checking class invariants
179fb3fb4f3Stomee 	try {
180fb3fb4f3Stomee 	    validate();
181fb3fb4f3Stomee 	} catch (Exception e) {
182*4ae67516Stomee 	    InvalidObjectException x = new InvalidObjectException(
183*4ae67516Stomee 		    e.getMessage());
184*4ae67516Stomee 	    x.initCause(e);
185*4ae67516Stomee 	    throw x;
186fb3fb4f3Stomee 	}
187fb3fb4f3Stomee     }
188fb3fb4f3Stomee 
189fb3fb4f3Stomee     /**
190fb3fb4f3Stomee      * Gets a string representation of this {@code ProbeInfo} useful for
191fb3fb4f3Stomee      * logging and not intended for display.  The exact details of the
192fb3fb4f3Stomee      * representation are unspecified and subject to change, but the
193fb3fb4f3Stomee      * following format may be regarded as typical:
194fb3fb4f3Stomee      * <pre><code>
195fb3fb4f3Stomee      * class-name[property1 = value1, property2 = value2]
196fb3fb4f3Stomee      * </code></pre>
197fb3fb4f3Stomee      */
198fb3fb4f3Stomee     public String
toString()199fb3fb4f3Stomee     toString()
200fb3fb4f3Stomee     {
201*4ae67516Stomee 	StringBuilder buf = new StringBuilder();
202fb3fb4f3Stomee 	buf.append(ProbeInfo.class.getName());
203fb3fb4f3Stomee 	buf.append("[probeAttributes = ");
204fb3fb4f3Stomee 	buf.append(probeAttributes);
205fb3fb4f3Stomee 	buf.append(", argumentAttributes = ");
206fb3fb4f3Stomee 	buf.append(argumentAttributes);
207fb3fb4f3Stomee 	buf.append(']');
208fb3fb4f3Stomee 	return buf.toString();
209fb3fb4f3Stomee     }
210fb3fb4f3Stomee }
211