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.io.*;
31fb3fb4f3Stomee import java.beans.*;
32fb3fb4f3Stomee 
33fb3fb4f3Stomee /**
34fb3fb4f3Stomee  * Information about a {@link Program} including stability and matching
35fb3fb4f3Stomee  * probe count.
36fb3fb4f3Stomee  * <p>
37fb3fb4f3Stomee  * Immutable.  Supports persistence using {@link java.beans.XMLEncoder}.
38fb3fb4f3Stomee  *
39fb3fb4f3Stomee  * @see Consumer#getProgramInfo(Program program)
40fb3fb4f3Stomee  * @see Consumer#enable(Program program)
41fb3fb4f3Stomee  *
42fb3fb4f3Stomee  * @author Tom Erickson
43fb3fb4f3Stomee  */
44fb3fb4f3Stomee public final class ProgramInfo implements Serializable {
45fb3fb4f3Stomee     static final long serialVersionUID = 663862981171935056L;
46fb3fb4f3Stomee 
47fb3fb4f3Stomee     static {
48fb3fb4f3Stomee 	try {
49fb3fb4f3Stomee 	    BeanInfo info = Introspector.getBeanInfo(ProgramInfo.class);
50fb3fb4f3Stomee 	    PersistenceDelegate persistenceDelegate =
51fb3fb4f3Stomee 		    new DefaultPersistenceDelegate(
52fb3fb4f3Stomee 		    new String[] { "minimumProbeAttributes",
53fb3fb4f3Stomee 		    "minimumStatementAttributes",
54fb3fb4f3Stomee 		    "matchingProbeCount" })
55fb3fb4f3Stomee 	    {
56fb3fb4f3Stomee 		/*
57fb3fb4f3Stomee 		 * Need to prevent DefaultPersistenceDelegate from using
58fb3fb4f3Stomee 		 * overridden equals() method, resulting in a
59fb3fb4f3Stomee 		 * StackOverFlowError.  Revert to PersistenceDelegate
60fb3fb4f3Stomee 		 * implementation.  See
61fb3fb4f3Stomee 		 * http://forum.java.sun.com/thread.jspa?threadID=
62fb3fb4f3Stomee 		 * 477019&tstart=135
63fb3fb4f3Stomee 		 */
64fb3fb4f3Stomee 		protected boolean
65fb3fb4f3Stomee 		mutatesTo(Object oldInstance, Object newInstance)
66fb3fb4f3Stomee 		{
67fb3fb4f3Stomee 		    return (newInstance != null && oldInstance != null &&
68fb3fb4f3Stomee 			    oldInstance.getClass() == newInstance.getClass());
69fb3fb4f3Stomee 		}
70fb3fb4f3Stomee 	    };
71fb3fb4f3Stomee 	    BeanDescriptor d = info.getBeanDescriptor();
72fb3fb4f3Stomee 	    d.setValue("persistenceDelegate", persistenceDelegate);
73fb3fb4f3Stomee 	} catch (IntrospectionException e) {
74fb3fb4f3Stomee 	    e.printStackTrace();
75fb3fb4f3Stomee 	}
76fb3fb4f3Stomee     }
77fb3fb4f3Stomee 
78fb3fb4f3Stomee     /** @serial */
79fb3fb4f3Stomee     private final InterfaceAttributes minimumProbeAttributes;
80fb3fb4f3Stomee     /** @serial */
81fb3fb4f3Stomee     private final InterfaceAttributes minimumStatementAttributes;
82fb3fb4f3Stomee     /** @serial */
83fb3fb4f3Stomee     private final int matchingProbeCount;
84fb3fb4f3Stomee 
85fb3fb4f3Stomee     /**
86fb3fb4f3Stomee      * Creates a {@code ProgamInfo} instance with the given properties.
87fb3fb4f3Stomee      * Supports XML persistence.
88fb3fb4f3Stomee      *
89fb3fb4f3Stomee      * @param minProbeAttr minimum stability levels of the
90fb3fb4f3Stomee      * program probe descriptions
91fb3fb4f3Stomee      * @param minStatementAttr minimum stability levels of the
92fb3fb4f3Stomee      * program action statements (including D variables)
93fb3fb4f3Stomee      * @param matchingProbes non-negative count of probes matching the
94fb3fb4f3Stomee      * program probe description
95fb3fb4f3Stomee      * @throws NullPointerException if {@code minProbeAttr} or {@code
96fb3fb4f3Stomee      * minStatementAttr} is {@code null}
97fb3fb4f3Stomee      * @throws IllegalArgumentException if {@code matchingProbes} is
98fb3fb4f3Stomee      * negative
99fb3fb4f3Stomee      */
100fb3fb4f3Stomee     public
ProgramInfo(InterfaceAttributes minProbeAttr, InterfaceAttributes minStatementAttr, int matchingProbes)101fb3fb4f3Stomee     ProgramInfo(InterfaceAttributes minProbeAttr,
102fb3fb4f3Stomee 	    InterfaceAttributes minStatementAttr,
103fb3fb4f3Stomee 	    int matchingProbes)
104fb3fb4f3Stomee     {
105fb3fb4f3Stomee 	// Called by native code.  Any change to this constructor requires a
106fb3fb4f3Stomee 	// similar change in the native invocation.
107fb3fb4f3Stomee 	minimumProbeAttributes = minProbeAttr;
108fb3fb4f3Stomee 	minimumStatementAttributes = minStatementAttr;
109fb3fb4f3Stomee 	matchingProbeCount = matchingProbes;
110fb3fb4f3Stomee 	validate();
111fb3fb4f3Stomee     }
112fb3fb4f3Stomee 
11391cfa10aStomee     private final void
validate()114fb3fb4f3Stomee     validate()
115fb3fb4f3Stomee     {
116fb3fb4f3Stomee 	if (minimumProbeAttributes == null) {
117fb3fb4f3Stomee 	    throw new NullPointerException("minimumProbeAttributes is null");
118fb3fb4f3Stomee 	}
119fb3fb4f3Stomee 	if (minimumStatementAttributes == null) {
120fb3fb4f3Stomee 	    throw new NullPointerException(
121fb3fb4f3Stomee 		    "minimumStatementAttributes is null");
122fb3fb4f3Stomee 	}
123fb3fb4f3Stomee 	if (matchingProbeCount < 0) {
124fb3fb4f3Stomee 	    throw new IllegalArgumentException(
125fb3fb4f3Stomee 		    "matchingProbeCount is negative");
126fb3fb4f3Stomee 	}
127fb3fb4f3Stomee     }
128fb3fb4f3Stomee 
129fb3fb4f3Stomee     /**
130fb3fb4f3Stomee      * Gets the minimum stability levels of the probe descriptions used
131fb3fb4f3Stomee      * in a compiled {@link Program}.
132fb3fb4f3Stomee      *
133fb3fb4f3Stomee      * @return non-null interface attributes describing the minimum
134fb3fb4f3Stomee      * stability of the probe descriptions in a D program
135fb3fb4f3Stomee      */
136fb3fb4f3Stomee     public InterfaceAttributes
getMinimumProbeAttributes()137fb3fb4f3Stomee     getMinimumProbeAttributes()
138fb3fb4f3Stomee     {
139fb3fb4f3Stomee 	return minimumProbeAttributes;
140fb3fb4f3Stomee     }
141fb3fb4f3Stomee 
142fb3fb4f3Stomee     /**
143fb3fb4f3Stomee      * Gets the minimum stability levels of the action statements
144fb3fb4f3Stomee      * including D variables used in a compiled {@link Program}.
145fb3fb4f3Stomee      *
146fb3fb4f3Stomee      * @return non-null interface attributes describing the minimum
147fb3fb4f3Stomee      * stability of the action statements (including D variables) in a D
148fb3fb4f3Stomee      * program
149fb3fb4f3Stomee      */
150fb3fb4f3Stomee     public InterfaceAttributes
getMinimumStatementAttributes()151fb3fb4f3Stomee     getMinimumStatementAttributes()
152fb3fb4f3Stomee     {
153fb3fb4f3Stomee 	return minimumStatementAttributes;
154fb3fb4f3Stomee     }
155fb3fb4f3Stomee 
156fb3fb4f3Stomee     /**
157fb3fb4f3Stomee      * Gets the number of DTrace probes that match the probe
158fb3fb4f3Stomee      * descriptions in a compiled {@link Program}.  This count may be
159fb3fb4f3Stomee      * very high for programs that use {@link ProbeDescription}
160fb3fb4f3Stomee      * wildcarding (field omission) and globbing (pattern matching
161fb3fb4f3Stomee      * syntax).
162fb3fb4f3Stomee      *
163fb3fb4f3Stomee      * @return non-negative count of probes on the system matching the
164fb3fb4f3Stomee      * program descriptions in a compiled D program
165fb3fb4f3Stomee      */
166fb3fb4f3Stomee     public int
getMatchingProbeCount()167fb3fb4f3Stomee     getMatchingProbeCount()
168fb3fb4f3Stomee     {
169fb3fb4f3Stomee 	return matchingProbeCount;
170fb3fb4f3Stomee     }
171fb3fb4f3Stomee 
172fb3fb4f3Stomee     /**
173fb3fb4f3Stomee      * Compares the specified object with this program information for
174fb3fb4f3Stomee      * equality.  Defines equality as having the same information,
175fb3fb4f3Stomee      * including stability attributes and matching probe counts.
176fb3fb4f3Stomee      * Different D programs may have equal program information.
177fb3fb4f3Stomee      *
178fb3fb4f3Stomee      * @return {@code true} if and only if the specified object is also
179fb3fb4f3Stomee      * a {@code ProgramInfo} instance and has all the same information
180fb3fb4f3Stomee      * as this instance
181fb3fb4f3Stomee      */
182fb3fb4f3Stomee     @Override
183fb3fb4f3Stomee     public boolean
equals(Object o)184fb3fb4f3Stomee     equals(Object o)
185fb3fb4f3Stomee     {
186fb3fb4f3Stomee 	if (o == this) {
187fb3fb4f3Stomee 	    return true;
188fb3fb4f3Stomee 	}
189fb3fb4f3Stomee 	if (o instanceof ProgramInfo) {
190fb3fb4f3Stomee 	    ProgramInfo i = (ProgramInfo)o;
191fb3fb4f3Stomee 	    return (minimumProbeAttributes.equals(
192fb3fb4f3Stomee 		    i.minimumProbeAttributes) &&
193fb3fb4f3Stomee 		    minimumStatementAttributes.equals(
194fb3fb4f3Stomee 		    i.minimumStatementAttributes) &&
195fb3fb4f3Stomee 		    (matchingProbeCount == i.matchingProbeCount));
196fb3fb4f3Stomee 	}
197fb3fb4f3Stomee 	return false;
198fb3fb4f3Stomee     }
199fb3fb4f3Stomee 
200fb3fb4f3Stomee     /**
201fb3fb4f3Stomee      * Overridden to ensure that equal {@code ProgramInfo} instances
202fb3fb4f3Stomee      * have equal hashcodes.
203fb3fb4f3Stomee      */
204fb3fb4f3Stomee     @Override
205fb3fb4f3Stomee     public int
hashCode()206fb3fb4f3Stomee     hashCode()
207fb3fb4f3Stomee     {
208fb3fb4f3Stomee         int hash = 17;
209fb3fb4f3Stomee 	hash = (37 * hash) + minimumProbeAttributes.hashCode();
210fb3fb4f3Stomee 	hash = (37 * hash) + minimumStatementAttributes.hashCode();
211fb3fb4f3Stomee 	hash = (37 * hash) + matchingProbeCount;
212fb3fb4f3Stomee 	return hash;
213fb3fb4f3Stomee     }
214fb3fb4f3Stomee 
215fb3fb4f3Stomee     private void
readObject(ObjectInputStream s)216fb3fb4f3Stomee     readObject(ObjectInputStream s)
217fb3fb4f3Stomee             throws IOException, ClassNotFoundException
218fb3fb4f3Stomee     {
219fb3fb4f3Stomee 	s.defaultReadObject();
220fb3fb4f3Stomee 	// Check constructor invariants
221fb3fb4f3Stomee 	try {
222fb3fb4f3Stomee 	    validate();
223fb3fb4f3Stomee 	} catch (Exception e) {
224*4ae67516Stomee 	    InvalidObjectException x = new InvalidObjectException(
225*4ae67516Stomee 		    e.getMessage());
226*4ae67516Stomee 	    x.initCause(e);
227*4ae67516Stomee 	    throw x;
228fb3fb4f3Stomee 	}
229fb3fb4f3Stomee     }
230fb3fb4f3Stomee 
231fb3fb4f3Stomee     /**
232fb3fb4f3Stomee      * Gets a string representation of this {@code ProgramInfo} useful
233fb3fb4f3Stomee      * for logging and not intended for display.  The exact details of
234fb3fb4f3Stomee      * the representation are unspecified and subject to change, but the
235fb3fb4f3Stomee      * following format may be regarded as typical:
236fb3fb4f3Stomee      * <pre><code>
237fb3fb4f3Stomee      * class-name[property1 = value1, property2 = value2]
238fb3fb4f3Stomee      * </code></pre>
239fb3fb4f3Stomee      */
240fb3fb4f3Stomee     @Override
241fb3fb4f3Stomee     public String
toString()242fb3fb4f3Stomee     toString()
243fb3fb4f3Stomee     {
244*4ae67516Stomee 	StringBuilder buf = new StringBuilder();
245fb3fb4f3Stomee 	buf.append(ProgramInfo.class.getName());
246fb3fb4f3Stomee 	buf.append("[minimumProbeAttributes = ");
247fb3fb4f3Stomee 	buf.append(minimumProbeAttributes);
248fb3fb4f3Stomee 	buf.append(", minimumStatementAttributes = ");
249fb3fb4f3Stomee 	buf.append(minimumStatementAttributes);
250fb3fb4f3Stomee 	buf.append(", matchingProbeCount = ");
251fb3fb4f3Stomee 	buf.append(matchingProbeCount);
252fb3fb4f3Stomee 	buf.append(']');
253fb3fb4f3Stomee 	return buf.toString();
254fb3fb4f3Stomee     }
255fb3fb4f3Stomee }
256