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.modules.profiler.heapwalk.model;
042:
043: import org.netbeans.lib.profiler.heap.*;
044: import org.openide.util.NbBundle;
045: import java.text.MessageFormat;
046: import java.util.List;
047: import javax.swing.Icon;
048:
049: /**
050: *
051: * @author Jiri Sedlacek
052: */
053: public class HeapWalkerNodeFactory {
054: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
055:
056: // -----
057: // I18N String constants
058: private static final String NONE_STRING = NbBundle.getMessage(
059: HeapWalkerNodeFactory.class,
060: "HeapWalkerNodeFactory_NoneString"); // NOI18N
061: private static final String NO_FIELDS_STRING = NbBundle.getMessage(
062: HeapWalkerNodeFactory.class,
063: "HeapWalkerNodeFactory_NoFieldsString"); // NOI18N
064: private static final String NO_REFERENCES_STRING = NbBundle
065: .getMessage(HeapWalkerNodeFactory.class,
066: "HeapWalkerNodeFactory_NoReferencesString"); // NOI18N
067: private static final String NO_ITEMS_STRING = NbBundle.getMessage(
068: HeapWalkerNodeFactory.class,
069: "HeapWalkerNodeFactory_NoItemsString"); // NOI18N
070: private static final String SEARCHING_STRING = NbBundle.getMessage(
071: HeapWalkerNodeFactory.class,
072: "HeapWalkerNodeFactory_SearchingString"); // NOI18N
073: private static final String OUT_OF_MEMORY_STRING = NbBundle
074: .getMessage(HeapWalkerNodeFactory.class,
075: "HeapWalkerNodeFactory_OutOfMemoryString"); // NOI18N
076: private static final String ARRAY_CONTAINER_NAME_STRING = NbBundle
077: .getMessage(HeapWalkerNodeFactory.class,
078: "HeapWalkerNodeFactory_ArrayContainerNameString"); // NOI18N
079: private static final String ARRAY_CONTAINER_VALUE_STRING = NbBundle
080: .getMessage(HeapWalkerNodeFactory.class,
081: "HeapWalkerNodeFactory_ArrayContainerValueString"); // NOI18N
082: // -----
083: public static int ITEMS_COLLAPSE_UNIT_SIZE = 500;
084: public static int ITEMS_COLLAPSE_THRESHOLD = 2000;
085: public static int ITEMS_COLLAPSE_UNIT_THRESHOLD = 5000;
086:
087: //~ Methods ------------------------------------------------------------------------------------------------------------------
088:
089: public static HeapWalkerNode createArrayItemContainerNode(
090: final ArrayNode array, final int startIndex,
091: final int endIndex) {
092: return new AbstractHeapWalkerNode(array) {
093: protected String computeName() {
094: return MessageFormat.format(
095: ARRAY_CONTAINER_NAME_STRING, new Object[] {
096: startIndex, endIndex });
097: }
098:
099: protected String computeType() {
100: return BrowserUtils.getArrayItemType(array.getType());
101: }
102:
103: protected String computeValue() {
104: return MessageFormat.format(
105: ARRAY_CONTAINER_VALUE_STRING,
106: new Object[] { (endIndex - startIndex + 1) });
107: }
108:
109: protected Icon computeIcon() {
110: return null;
111: }
112:
113: public boolean isLeaf() {
114: return false;
115: }
116:
117: protected HeapWalkerNode[] computeChildren() {
118: return BrowserUtils.lazilyCreateChildren(this ,
119: getChildrenComputer());
120: }
121:
122: protected ChildrenComputer getChildrenComputer() {
123: return new ChildrenComputer() {
124: public HeapWalkerNode[] computeChildren() {
125: int itemsCount = endIndex - startIndex + 1;
126: HeapWalkerNode[] children = new HeapWalkerNode[itemsCount];
127:
128: boolean primitiveArray = array instanceof PrimitiveArrayNode;
129: List values = primitiveArray ? ((PrimitiveArrayInstance) (array
130: .getInstance())).getValues()
131: : ((ObjectArrayInstance) (array
132: .getInstance())).getValues();
133:
134: for (int i = 0; i < itemsCount; i++) {
135: if (primitiveArray) {
136: children[i] = createPrimitiveArrayItemNode(
137: (PrimitiveArrayNode) array,
138: startIndex + i, (String) values
139: .get(startIndex + i));
140: } else {
141: children[i] = createObjectArrayItemNode(
142: (ObjectArrayNode) array,
143: startIndex + i,
144: (Instance) values
145: .get(startIndex + i));
146: }
147: }
148:
149: return children;
150: }
151: };
152: }
153: };
154: }
155:
156: public static ClassNode createClassNode(JavaClass javaClass,
157: String name, HeapWalkerNode parent) {
158: return new ClassNode(javaClass, name, parent,
159: (parent == null) ? HeapWalkerNode.MODE_FIELDS : parent
160: .getMode());
161: }
162:
163: public static HeapWalkerFieldNode createFieldNode(
164: FieldValue fieldValue, HeapWalkerNode parent) {
165: if (fieldValue instanceof ObjectFieldValue) {
166: Instance instance = ((ObjectFieldValue) fieldValue)
167: .getInstance();
168:
169: if (instance instanceof PrimitiveArrayInstance) {
170: return new PrimitiveArrayFieldNode(
171: (ObjectFieldValue) fieldValue, parent);
172: } else if (instance instanceof ObjectArrayInstance) {
173: return new ObjectArrayFieldNode(
174: (ObjectFieldValue) fieldValue, parent);
175: } else {
176: return new ObjectFieldNode(
177: (ObjectFieldValue) fieldValue, parent);
178: }
179: } else {
180: return new PrimitiveFieldNode(fieldValue, parent);
181: }
182: }
183:
184: public static HeapWalkerInstanceNode createInstanceNode(
185: Instance instance, String name, HeapWalkerNode parent) {
186: int mode = (parent == null) ? HeapWalkerNode.MODE_FIELDS
187: : parent.getMode();
188:
189: if (instance instanceof PrimitiveArrayInstance) {
190: return new PrimitiveArrayNode(
191: (PrimitiveArrayInstance) instance, name, parent,
192: mode);
193: } else if (instance instanceof ObjectArrayInstance) {
194: return new ObjectArrayNode((ObjectArrayInstance) instance,
195: name, parent, mode);
196: } else {
197: return new ObjectNode(instance, name, parent, mode);
198: }
199: }
200:
201: public static HeapWalkerNode createNoFieldsNode(
202: HeapWalkerNode parent) {
203: return new AbstractHeapWalkerNode(parent) {
204: protected String computeName() {
205: return NO_FIELDS_STRING;
206: }
207:
208: protected String computeType() {
209: return NONE_STRING;
210: }
211:
212: protected String computeValue() {
213: return NONE_STRING;
214: }
215:
216: protected Icon computeIcon() {
217: return null;
218: }
219: };
220: }
221:
222: public static HeapWalkerNode createNoItemsNode(HeapWalkerNode parent) {
223: return new AbstractHeapWalkerNode(parent) {
224: protected String computeName() {
225: return NO_ITEMS_STRING;
226: }
227:
228: protected String computeType() {
229: return NONE_STRING;
230: }
231:
232: protected String computeValue() {
233: return NONE_STRING;
234: }
235:
236: protected Icon computeIcon() {
237: return null;
238: }
239: };
240: }
241:
242: public static HeapWalkerNode createNoReferencesNode(
243: HeapWalkerNode parent) {
244: return new AbstractHeapWalkerNode(parent) {
245: protected String computeName() {
246: return NO_REFERENCES_STRING;
247: }
248:
249: protected String computeType() {
250: return NONE_STRING;
251: }
252:
253: protected String computeValue() {
254: return NONE_STRING;
255: }
256:
257: protected Icon computeIcon() {
258: return null;
259: }
260: };
261: }
262:
263: public static HeapWalkerNode createOOMNode(HeapWalkerNode parent) {
264: return new AbstractHeapWalkerNode(parent) {
265: protected String computeName() {
266: return OUT_OF_MEMORY_STRING;
267: }
268:
269: protected String computeType() {
270: return "";
271: } // NOI18N
272:
273: protected String computeValue() {
274: return "";
275: } // NOI18N
276:
277: protected Icon computeIcon() {
278: return org.netbeans.modules.profiler.ui.Utils.ERROR_ICON;
279: }
280: };
281: }
282:
283: public static HeapWalkerNode createObjectArrayItemNode(
284: ObjectArrayNode array, int itemIndex, Instance instance) {
285: if (instance instanceof PrimitiveArrayInstance) {
286: return new PrimitiveArrayNode.ArrayItem(itemIndex,
287: (PrimitiveArrayInstance) instance, array);
288: } else if (instance instanceof ObjectArrayInstance) {
289: return new ObjectArrayNode.ArrayItem(itemIndex,
290: (ObjectArrayInstance) instance, array);
291: } else {
292: return new ObjectNode.ArrayItem(itemIndex, instance, array);
293: }
294: }
295:
296: public static HeapWalkerNode createPrimitiveArrayItemNode(
297: PrimitiveArrayNode array, int itemIndex, String value) {
298: return new PrimitiveFieldNode.ArrayItem(itemIndex, BrowserUtils
299: .getArrayItemType(array.getType()), value, array);
300: }
301:
302: public static HeapWalkerNode createProgressNode(
303: HeapWalkerNode parent) {
304: return new AbstractHeapWalkerNode(parent) {
305: protected String computeName() {
306: return SEARCHING_STRING;
307: }
308:
309: protected String computeType() {
310: return "";
311: } // NOI18N
312:
313: protected String computeValue() {
314: return "";
315: } // NOI18N
316:
317: protected Icon computeIcon() {
318: return BrowserUtils.ICON_PROGRESS;
319: }
320: };
321: }
322:
323: public static HeapWalkerNode createReferenceNode(Value value,
324: HeapWalkerNode parent) {
325: if (value instanceof ObjectFieldValue) {
326: return new ObjectFieldNode((ObjectFieldValue) value, parent);
327: } else if (value instanceof ArrayItemValue) {
328: ArrayItemValue arrayValue = (ArrayItemValue) value;
329:
330: return new ObjectArrayNode.ArrayItem(arrayValue.getIndex(),
331: (ObjectArrayInstance) arrayValue
332: .getDefiningInstance(), parent);
333: } else {
334: return null;
335: }
336: }
337:
338: public static ClassNode createRootClassNode(JavaClass javaClass,
339: String name, final Runnable refresher, int mode,
340: final Heap heap) {
341: return new ClassNode.RootNode(javaClass, name, null, mode) {
342: public void refreshView() {
343: refresher.run();
344: }
345:
346: public GCRoot getGCRoot(Instance inst) {
347: return heap.getGCRoot(inst);
348: };
349:
350: public JavaClass getJavaClassByID(long javaclassId) {
351: return heap.getJavaClassByID(javaclassId);
352: };
353: };
354: }
355:
356: public static HeapWalkerInstanceNode createRootInstanceNode(
357: Instance instance, String name, final Runnable refresher,
358: int mode, final Heap heap) {
359: if (instance instanceof PrimitiveArrayInstance) {
360: return new PrimitiveArrayNode.RootNode(
361: (PrimitiveArrayInstance) instance, name, null, mode) {
362: public void refreshView() {
363: refresher.run();
364: }
365:
366: public GCRoot getGCRoot(Instance inst) {
367: return heap.getGCRoot(inst);
368: };
369:
370: public JavaClass getJavaClassByID(long javaclassId) {
371: return heap.getJavaClassByID(javaclassId);
372: };
373: };
374: } else if (instance instanceof ObjectArrayInstance) {
375: return new ObjectArrayNode.RootNode(
376: (ObjectArrayInstance) instance, name, null, mode) {
377: public void refreshView() {
378: refresher.run();
379: }
380:
381: public GCRoot getGCRoot(Instance inst) {
382: return heap.getGCRoot(inst);
383: };
384:
385: public JavaClass getJavaClassByID(long javaclassId) {
386: return heap.getJavaClassByID(javaclassId);
387: };
388: };
389: } else {
390: return new ObjectNode.RootNode(instance, name, null, mode) {
391: public void refreshView() {
392: refresher.run();
393: }
394:
395: public GCRoot getGCRoot(Instance inst) {
396: return heap.getGCRoot(inst);
397: };
398:
399: public JavaClass getJavaClassByID(long javaclassId) {
400: return heap.getJavaClassByID(javaclassId);
401: };
402: };
403: }
404: }
405: }
|