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