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  * A {@link ProbeDescription} identifying a single probe combined with
36fb3fb4f3Stomee  * information about the identified probe.
37fb3fb4f3Stomee  * <p>
38fb3fb4f3Stomee  * Immutable.  Supports persistence using {@link java.beans.XMLEncoder}.
39fb3fb4f3Stomee  *
40fb3fb4f3Stomee  * @see Consumer#listProbes(ProbeDescription filter)
41fb3fb4f3Stomee  * @see Consumer#listProgramProbes(Program program)
42fb3fb4f3Stomee  *
43fb3fb4f3Stomee  * @author Tom Erickson
44fb3fb4f3Stomee  */
45fb3fb4f3Stomee public final class Probe implements Serializable {
46fb3fb4f3Stomee     static final long serialVersionUID = 8917481979541675727L;
47fb3fb4f3Stomee 
48fb3fb4f3Stomee     static {
49fb3fb4f3Stomee 	try {
50fb3fb4f3Stomee 	    BeanInfo info = Introspector.getBeanInfo(Probe.class);
51fb3fb4f3Stomee 	    PersistenceDelegate persistenceDelegate =
52fb3fb4f3Stomee 		    new DefaultPersistenceDelegate(
53fb3fb4f3Stomee 		    new String[] {"description", "info"})
54fb3fb4f3Stomee 	    {
55fb3fb4f3Stomee 		/*
56fb3fb4f3Stomee 		 * Need to prevent DefaultPersistenceDelegate from using
57fb3fb4f3Stomee 		 * overridden equals() method, resulting in a
58fb3fb4f3Stomee 		 * StackOverFlowError.  Revert to PersistenceDelegate
59fb3fb4f3Stomee 		 * implementation.  See
60fb3fb4f3Stomee 		 * http://forum.java.sun.com/thread.jspa?threadID=
61fb3fb4f3Stomee 		 * 477019&tstart=135
62fb3fb4f3Stomee 		 */
63fb3fb4f3Stomee 		protected boolean
64fb3fb4f3Stomee 		mutatesTo(Object oldInstance, Object newInstance)
65fb3fb4f3Stomee 		{
66fb3fb4f3Stomee 		    return (newInstance != null && oldInstance != null &&
67fb3fb4f3Stomee 			    oldInstance.getClass() == newInstance.getClass());
68fb3fb4f3Stomee 		}
69fb3fb4f3Stomee 	    };
70fb3fb4f3Stomee 	    BeanDescriptor d = info.getBeanDescriptor();
71fb3fb4f3Stomee 	    d.setValue("persistenceDelegate", persistenceDelegate);
72fb3fb4f3Stomee 	} catch (IntrospectionException e) {
73fb3fb4f3Stomee 	    System.out.println(e);
74fb3fb4f3Stomee 	}
75fb3fb4f3Stomee     }
76fb3fb4f3Stomee 
77fb3fb4f3Stomee     /** @serial */
78fb3fb4f3Stomee     private final ProbeDescription description;
79fb3fb4f3Stomee     /** @serial */
80fb3fb4f3Stomee     private final ProbeInfo info;
81fb3fb4f3Stomee 
82fb3fb4f3Stomee     /**
83fb3fb4f3Stomee      * Creates a {@code Probe} instance with the given identifying
84fb3fb4f3Stomee      * description and associated probe information.  Supports XML
85fb3fb4f3Stomee      * persistence.
86fb3fb4f3Stomee      *
87fb3fb4f3Stomee      * @param probeDescription probe description that identifies a
88fb3fb4f3Stomee      * single DTrace probe
89fb3fb4f3Stomee      * @param probeInfo information about the identified probe, {@code
90fb3fb4f3Stomee      * null} indicating that the information could not be obtained
91fb3fb4f3Stomee      * @throws NullPointerException if the given probe description is
92fb3fb4f3Stomee      * {@code null}
93fb3fb4f3Stomee      */
94fb3fb4f3Stomee     public
Probe(ProbeDescription probeDescription, ProbeInfo probeInfo)95fb3fb4f3Stomee     Probe(ProbeDescription probeDescription, ProbeInfo probeInfo)
96fb3fb4f3Stomee     {
97fb3fb4f3Stomee 	description = probeDescription;
98fb3fb4f3Stomee 	info = probeInfo;
99fb3fb4f3Stomee 	validate();
100fb3fb4f3Stomee     }
101fb3fb4f3Stomee 
10291cfa10aStomee     private final void
validate()103fb3fb4f3Stomee     validate()
104fb3fb4f3Stomee     {
105fb3fb4f3Stomee 	if (description == null) {
106fb3fb4f3Stomee 	    throw new NullPointerException("description is null");
107fb3fb4f3Stomee 	}
108fb3fb4f3Stomee     }
109fb3fb4f3Stomee 
110fb3fb4f3Stomee     /**
111fb3fb4f3Stomee      * Gets the probe description identifying a single probe described
112fb3fb4f3Stomee      * by this instance.
113fb3fb4f3Stomee      *
114fb3fb4f3Stomee      * @return non-null probe description matching a single probe on the
115fb3fb4f3Stomee      * system
116fb3fb4f3Stomee      */
117fb3fb4f3Stomee     public ProbeDescription
getDescription()118fb3fb4f3Stomee     getDescription()
119fb3fb4f3Stomee     {
120fb3fb4f3Stomee 	return description;
121fb3fb4f3Stomee     }
122fb3fb4f3Stomee 
123fb3fb4f3Stomee     /**
124fb3fb4f3Stomee      * Gets information including attributes and argument types of the
125fb3fb4f3Stomee      * probe identified by {@link #getDescription()}.
126fb3fb4f3Stomee      *
127fb3fb4f3Stomee      * @return information about the probe identified by {@link
128fb3fb4f3Stomee      * #getDescription()}, or {@code null} if that information could not
129fb3fb4f3Stomee      * be obtained for any reason
130fb3fb4f3Stomee      */
131fb3fb4f3Stomee     public ProbeInfo
getInfo()132fb3fb4f3Stomee     getInfo()
133fb3fb4f3Stomee     {
134fb3fb4f3Stomee 	return info;
135fb3fb4f3Stomee     }
136fb3fb4f3Stomee 
137fb3fb4f3Stomee     /**
138fb3fb4f3Stomee      * Compares the specified object with this {@code Probe} instance
139fb3fb4f3Stomee      * for equality.  Defines equality as having the same probe
140fb3fb4f3Stomee      * description.
141fb3fb4f3Stomee      *
142fb3fb4f3Stomee      * @return {@code true} if and only if the specified object is also
143fb3fb4f3Stomee      * a {@code Probe} and both instances return equal values from
144fb3fb4f3Stomee      * {@link #getDescription()}.
145fb3fb4f3Stomee      */
146fb3fb4f3Stomee     @Override
147fb3fb4f3Stomee     public boolean
equals(Object o)148fb3fb4f3Stomee     equals(Object o)
149fb3fb4f3Stomee     {
150fb3fb4f3Stomee 	if (o instanceof Probe) {
151fb3fb4f3Stomee 	    Probe p = (Probe)o;
152fb3fb4f3Stomee 	    return description.equals(p.description);
153fb3fb4f3Stomee 	}
154fb3fb4f3Stomee 	return false;
155fb3fb4f3Stomee     }
156fb3fb4f3Stomee 
157fb3fb4f3Stomee     /**
158fb3fb4f3Stomee      * Overridden to ensure that equal instances have equal hash codes.
159fb3fb4f3Stomee      */
160fb3fb4f3Stomee     @Override
161fb3fb4f3Stomee     public int
hashCode()162fb3fb4f3Stomee     hashCode()
163fb3fb4f3Stomee     {
164fb3fb4f3Stomee 	return description.hashCode();
165fb3fb4f3Stomee     }
166fb3fb4f3Stomee 
167fb3fb4f3Stomee     private void
readObject(ObjectInputStream s)168fb3fb4f3Stomee     readObject(ObjectInputStream s)
169fb3fb4f3Stomee             throws IOException, ClassNotFoundException
170fb3fb4f3Stomee     {
171fb3fb4f3Stomee 	s.defaultReadObject();
172fb3fb4f3Stomee 	// Check class invariants
173fb3fb4f3Stomee 	try {
174fb3fb4f3Stomee 	    validate();
175fb3fb4f3Stomee 	} catch (Exception e) {
176*4ae67516Stomee 	    InvalidObjectException x = new InvalidObjectException(
177*4ae67516Stomee 		    e.getMessage());
178*4ae67516Stomee 	    x.initCause(e);
179*4ae67516Stomee 	    throw x;
180fb3fb4f3Stomee 	}
181fb3fb4f3Stomee     }
182fb3fb4f3Stomee 
183fb3fb4f3Stomee     /**
184fb3fb4f3Stomee      * Returns a string representation of this {@code Probe} useful for
185fb3fb4f3Stomee      * logging and not intended for display.  The exact details of the
186fb3fb4f3Stomee      * representation are unspecified and subject to change, but the
187fb3fb4f3Stomee      * following format may be regarded as typical:
188fb3fb4f3Stomee      * <pre><code>
189fb3fb4f3Stomee      * class-name[property1 = value1, property2 = value2]
190fb3fb4f3Stomee      * </code></pre>
191fb3fb4f3Stomee      */
192fb3fb4f3Stomee     public String
toString()193fb3fb4f3Stomee     toString()
194fb3fb4f3Stomee     {
195*4ae67516Stomee 	StringBuilder buf = new StringBuilder();
196fb3fb4f3Stomee 	buf.append(Probe.class.getName());
197fb3fb4f3Stomee 	buf.append("[description = ");
198fb3fb4f3Stomee 	buf.append(description);
199fb3fb4f3Stomee 	buf.append(", info = ");
200fb3fb4f3Stomee 	buf.append(info);
201fb3fb4f3Stomee 	buf.append(']');
202fb3fb4f3Stomee 	return buf.toString();
203fb3fb4f3Stomee     }
204fb3fb4f3Stomee }
205