001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.lib.profiler.wireprotocol;
042:
043: import java.io.IOException;
044: import java.io.ObjectInputStream;
045: import java.io.ObjectOutputStream;
046:
047: /**
048: * This command is issued by the back end to signal that the root instrumentation class has been loaded.
049: * It contains the information about all classes loaded by the target JVM by that time.
050: *
051: * @author Misha Dmitriev
052: * @author Ian Formanek
053: */
054: public class RootClassLoadedCommand extends Command {
055: //~ Instance fields ----------------------------------------------------------------------------------------------------------
056:
057: private String eventBufferFileName;
058: private int[] allLoadedClassLoaderIds;
059: private String[] allLoadedClassNames;
060: private byte[][] cachedClassFileBytes;
061: private int[] parentLoaderIds; // An index into this table is a loader id, and the value at this index is this loader's parent loader id.
062: private int classCount;
063:
064: //~ Constructors -------------------------------------------------------------------------------------------------------------
065:
066: public RootClassLoadedCommand(String[] allLoadedClassNames,
067: int[] loaderIds, byte[][] cachedClassFileBytes,
068: int classCount, int[] parentLoaderIds,
069: String eventBufferFileName) {
070: super (ROOT_CLASS_LOADED);
071: this .allLoadedClassNames = allLoadedClassNames;
072: this .allLoadedClassLoaderIds = loaderIds;
073: this .cachedClassFileBytes = cachedClassFileBytes;
074: this .classCount = classCount;
075: this .parentLoaderIds = parentLoaderIds;
076: this .eventBufferFileName = eventBufferFileName;
077: }
078:
079: // Custom serialization support
080: RootClassLoadedCommand() {
081: super (ROOT_CLASS_LOADED);
082: }
083:
084: //~ Methods ------------------------------------------------------------------------------------------------------------------
085:
086: public int[] getAllLoadedClassLoaderIds() {
087: return allLoadedClassLoaderIds;
088: }
089:
090: public String[] getAllLoadedClassNames() {
091: return allLoadedClassNames;
092: }
093:
094: public byte[][] getCachedClassFileBytes() {
095: byte[][] res = cachedClassFileBytes;
096: cachedClassFileBytes = null; // Save memory
097:
098: return res;
099: }
100:
101: public String getEventBufferFileName() {
102: return eventBufferFileName;
103: }
104:
105: public int[] getParentLoaderIds() {
106: // Return a copy, just in case, since this instance of parentLoaderIds is reused when this command is received
107: int[] newParentLoaderIds = new int[parentLoaderIds.length];
108: System.arraycopy(parentLoaderIds, 0, newParentLoaderIds, 0,
109: parentLoaderIds.length);
110:
111: return newParentLoaderIds;
112: }
113:
114: // for debugging
115: public String toString() {
116: return super .toString() + ", eventBufferFileName: "
117: + eventBufferFileName; // NOI18N
118: }
119:
120: void readObject(ObjectInputStream in) throws IOException {
121: int len = in.readInt();
122: allLoadedClassNames = new String[len];
123:
124: for (int i = 0; i < len; i++) {
125: allLoadedClassNames[i] = in.readUTF();
126: }
127:
128: allLoadedClassLoaderIds = new int[len];
129:
130: for (int i = 0; i < len; i++) {
131: allLoadedClassLoaderIds[i] = in.readInt();
132: }
133:
134: len = in.readInt();
135:
136: if (len == 0) {
137: cachedClassFileBytes = null;
138: } else {
139: cachedClassFileBytes = new byte[len][];
140:
141: for (int i = 0; i < len; i++) {
142: int bytesLen = in.readInt();
143:
144: if (bytesLen == 0) {
145: continue;
146: } else {
147: cachedClassFileBytes[i] = new byte[bytesLen];
148: in.readFully(cachedClassFileBytes[i]);
149: }
150: }
151: }
152:
153: len = in.readInt();
154: parentLoaderIds = new int[len];
155:
156: for (int i = 0; i < len; i++) {
157: parentLoaderIds[i] = in.readInt();
158: }
159:
160: eventBufferFileName = in.readUTF();
161: }
162:
163: void writeObject(ObjectOutputStream out) throws IOException {
164: out.writeInt(classCount);
165:
166: for (int i = 0; i < classCount; i++) {
167: out.writeUTF(allLoadedClassNames[i]);
168: }
169:
170: for (int i = 0; i < classCount; i++) {
171: int loaderId = allLoadedClassLoaderIds[i];
172:
173: // At the client side we treat classes loaded by the bootstrap and by the system classloaders in the same way
174: if (loaderId == -1) {
175: loaderId = 0;
176: }
177:
178: out.writeInt(loaderId);
179: }
180:
181: if (cachedClassFileBytes == null) {
182: out.writeInt(0);
183: } else {
184: out.writeInt(classCount);
185:
186: for (int i = 0; i < classCount; i++) {
187: if (cachedClassFileBytes[i] == null) {
188: out.writeInt(0);
189: } else {
190: out.writeInt(cachedClassFileBytes[i].length);
191: out.write(cachedClassFileBytes[i]);
192: }
193: }
194: }
195:
196: out.writeInt(parentLoaderIds.length);
197:
198: for (int i = 0; i < parentLoaderIds.length; i++) {
199: out.writeInt(parentLoaderIds[i]);
200: }
201:
202: out.writeUTF(eventBufferFileName);
203: // Free memory
204: allLoadedClassNames = null;
205: allLoadedClassLoaderIds = null;
206: cachedClassFileBytes = null;
207: parentLoaderIds = null;
208: eventBufferFileName = null;
209: }
210: }
|