xref: /illumos-gate/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/Program.java (revision 004388ebfdfe2ed7dfd2d153a876dfcc22d2c006)
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 2006 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.io.*;
31 
32 /**
33  * Identifies a compiled D program.  This identifier is valid only on
34  * the {@link LocalConsumer} from which it was obtained.  Some {@code
35  * Consumer} methods attach additional {@link ProgramInfo} to this
36  * identifier.
37  * <p>
38  * Not intended for persistence, since it identifies nothing after its
39  * source {@code LocalConsumer} closes.
40  *
41  * @see Consumer#compile(String program, String[] macroArgs)
42  * @see Consumer#compile(java.io.File program, String[] macroArgs)
43  * @see Consumer#enable(Program program)
44  * @see Consumer#getProgramInfo(Program program)
45  * @see Consumer#listProgramProbes(Program program)
46  * @see Consumer#listProgramProbeDetail(Program program)
47  *
48  * @author Tom Erickson
49  */
50 public class Program implements Serializable {
51     static final long serialVersionUID = 364989786308628466L;
52 
53     /**
54      * Identifies this program among all of a consumer's programs.  Set
55      * by native code.
56      *
57      * @serial
58      */
59     private int id = -1;
60 
61     // Set by LocalConsumer.compile()
62     /** @serial */
63     LocalConsumer.Identifier consumerID;
64     /** @serial */
65     String contents;
66 
67     /** @serial */
68     private ProgramInfo info;
69 
70     /**
71      * Called by native code
72      */
73     private Program()
74     {
75     }
76 
77     // Called by LocalConsumer.compile() to ensure that only valid
78     // instances are made accessible to users.  Similarly called by
79     // readObject to ensure that only valid instances are deserialized.
80     void
81     validate()
82     {
83 	if (id < 0) {
84 	    throw new IllegalArgumentException("id is negative");
85 	}
86 	if (consumerID == null) {
87 	    throw new NullPointerException("consumer ID is null");
88 	}
89     }
90 
91     /**
92      * Gets the full pre-compiled text of the identified program.
93      *
94      * @return the {@code String} passed to {@link
95      * Consumer#compile(String program, String[] macroArgs)}, or the
96      * contents of the {@code File} passed to {@link
97      * Consumer#compile(java.io.File program, String[] macroArgs)}
98      */
99     public String
100     getContents()
101     {
102 	return contents;
103     }
104 
105     /**
106      * Gets information about this compiled program provided by {@link
107      * Consumer#getProgramInfo(Program program)} or {@link
108      * Consumer#enable(Program program)}.
109      *
110      * @return information about this compiled program, or {@code null}
111      * if this {@code Program} has not been passed to {@link
112      * Consumer#getProgramInfo(Program program)} or {@link
113      * Consumer#enable(Program program)}
114      */
115     public ProgramInfo
116     getInfo()
117     {
118 	return info;
119     }
120 
121     /**
122      * Sets additional information about this compiled program,
123      * including program stability and matching probe count.  Several
124      * {@code Consumer} methods attach such information to a given
125      * {@code Program} argument.  The method is {@code public} to
126      * support implementations of the {@code Consumer} interface other
127      * than {@link LocalConsumer}.  Although a {@code Program} can only
128      * be obtained from a {@code LocalConsumer}, other {@code Consumer}
129      * implemenations may provide a helpful layer of abstraction while
130      * using a {@code LocalConsumer} internally to compile DTrace
131      * programs.  Users of the API are not otherwise expected to call
132      * the {@code setInfo()} method directly.
133      *
134      * @param programInfo optional additional information about this
135      * compiled program
136      * @see #getInfo()
137      * @see Consumer#enable(Program program)
138      * @see Consumer#getProgramInfo(Program program)
139      */
140     public void
141     setInfo(ProgramInfo programInfo)
142     {
143 	info = programInfo;
144     }
145 
146     private void
147     readObject(ObjectInputStream s)
148 	    throws IOException, ClassNotFoundException
149     {
150 	s.defaultReadObject();
151 	// check class invariants
152 	try {
153 	    validate();
154 	} catch (Exception e) {
155 	    throw new InvalidObjectException(e.getMessage());
156 	}
157     }
158 
159     /**
160      * Gets the contents of the given file as a string.
161      *
162      * @return non-null contents of the given file as a string
163      * @throws IOException if the method fails to read the contents of
164      * the given file
165      */
166     static String
167     getProgramString(java.io.File programFile) throws IOException
168     {
169 	if (programFile == null) {
170 	    return null;
171 	}
172 
173 	StringBuffer buf = new StringBuffer();
174 	InputStream in;
175 	in = new BufferedInputStream(new FileInputStream(programFile));
176 	int i = in.read();
177 	while (i >= 0) {
178 	    buf.append((char)i);
179 	    i = in.read();
180 	}
181 
182 	String s = buf.toString();
183 	return s;
184     }
185 
186     /**
187      * Gets a string representation of this {@code Program} instance
188      * useful for logging and not intended for display.  The exact
189      * details of the representation are unspecified and subject to
190      * change, but the following format may be regarded as typical:
191      * <pre><code>
192      * class-name[property1 = value1, property2 = value2]
193      * </code></pre>
194      */
195     public String
196     toString()
197     {
198 	StringBuffer buf = new StringBuffer();
199 	buf.append(Program.class.getName());
200 	buf.append("[contents = ");
201 	buf.append(contents);
202 	buf.append(", info = ");
203 	buf.append(info);
204 	buf.append(']');
205 	return buf.toString();
206     }
207 
208     /**
209      * Identifies a compiled D program, specifically one that has been
210      * compiled from a file.
211      */
212     public static final class File extends Program {
213 	// Set by LocalConsumer.compile()
214 	/** @serial */
215 	java.io.File file;
216 
217 	private
218 	File()
219 	{
220 	}
221 
222 	// Called by LocalConsumer.compile() to ensure that only valid
223 	// instances are made accessible to users.  Similarly called by
224 	// readObject to ensure that only valid instances are deserialized.
225 	void
226 	validate()
227 	{
228 	    super.validate();
229 	    if (file == null) {
230 		throw new NullPointerException("file is null");
231 	    }
232 	}
233 
234 	/**
235 	 * Gets the program file.
236 	 *
237 	 * @return the {@code File} passed to {@link
238 	 * Consumer#compile(java.io.File program, String[] macroArgs)}
239 	 */
240 	public java.io.File
241 	getFile()
242 	{
243 	    return file;
244 	}
245 
246 	public String
247 	toString()
248 	{
249 	    StringBuffer buf = new StringBuffer();
250 	    buf.append(Program.File.class.getName());
251 	    buf.append("[super = ");
252 	    buf.append(super.toString());
253 	    buf.append(", file = ");
254 	    buf.append(file);
255 	    buf.append(']');
256 	    return buf.toString();
257 	}
258     }
259 }
260