001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.debug.core.logicalstructures;
011:
012: import org.eclipse.debug.core.DebugException;
013: import org.eclipse.debug.core.model.IVariable;
014: import org.eclipse.jdt.debug.core.IJavaArrayType;
015: import org.eclipse.jdt.debug.core.IJavaObject;
016: import org.eclipse.jdt.debug.core.IJavaType;
017: import org.eclipse.jdt.debug.core.IJavaValue;
018: import org.eclipse.jdt.internal.debug.core.HeapWalkingManager;
019: import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
020: import org.eclipse.jdt.internal.debug.core.model.JDIArrayValue;
021: import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
022: import org.eclipse.jdt.internal.debug.core.model.JDIPlaceholderValue;
023: import org.eclipse.jdt.internal.debug.core.model.JDIReferenceType;
024:
025: import com.ibm.icu.text.MessageFormat;
026:
027: /**
028: * Java value containing an array of java objects. This value is used to hold a list of
029: * all instances of a specific java type.
030: *
031: * @since 3.3
032: * @see org.eclipse.jdt.internal.debug.ui.heapwalking.AllInstancesActionDelegate
033: */
034: public class JDIAllInstancesValue extends JDIArrayValue {
035:
036: private IJavaObject[] fInstances;
037: private JDIReferenceType fRoot;
038: private IJavaArrayType fType;
039: private boolean fIsMoreThanPreference;
040:
041: /**
042: * Constructor, specifies whether there are more instances available than should be
043: * displayed according to the user's preference settings.
044: *
045: * @param target the target VM
046: * @param root the root object to get instances for
047: */
048: public JDIAllInstancesValue(JDIDebugTarget target,
049: JDIReferenceType root) {
050: super (target, null);
051: fRoot = root;
052: try {
053: IJavaType[] javaTypes = target
054: .getJavaTypes("java.lang.Object[]"); //$NON-NLS-1$
055: if (javaTypes.length > 0) {
056: fType = (IJavaArrayType) javaTypes[0];
057: }
058: } catch (DebugException e) {
059: }
060: }
061:
062: /**
063: * @return an array of java objects that are instances of the root type
064: */
065: protected IJavaObject[] getInstances() {
066: if (fInstances != null) {
067: return fInstances;
068: } else {
069: IJavaObject[] instances = new IJavaObject[0];
070: fIsMoreThanPreference = false;
071: if (fRoot != null) {
072: int max = HeapWalkingManager.getDefault()
073: .getAllInstancesMaxCount();
074: try {
075: if (max == 0) {
076: instances = fRoot.getInstances(max);
077: } else {
078: instances = fRoot.getInstances(max + 1);
079: if (instances.length > max) {
080: instances[max] = new JDIPlaceholderValue(
081: (JDIDebugTarget) fRoot
082: .getDebugTarget(),
083: MessageFormat
084: .format(
085: LogicalStructuresMessages.JDIAllInstancesValue_2,
086: new String[] { Integer
087: .toString(max) }));
088: fIsMoreThanPreference = true;
089: }
090: }
091: } catch (DebugException e) {
092: JDIDebugPlugin.log(e);
093: }
094: }
095: fInstances = instances;
096: return instances;
097: }
098: }
099:
100: /* (non-Javadoc)
101: * @see org.eclipse.jdt.internal.debug.core.model.JDIArrayValue#getLength()
102: */
103: public synchronized int getLength() throws DebugException {
104: return getInstances().length;
105: }
106:
107: /* (non-Javadoc)
108: * @see org.eclipse.jdt.internal.debug.core.model.JDIArrayValue#getSize()
109: */
110: public int getSize() throws DebugException {
111: return getInstances().length;
112: }
113:
114: /* (non-Javadoc)
115: * @see org.eclipse.jdt.internal.debug.core.model.JDIArrayValue#getValue(int)
116: */
117: public IJavaValue getValue(int index) throws DebugException {
118: if (index > getInstances().length - 1 || index < 0) {
119: internalError(LogicalStructuresMessages.JDIAllInstancesValue_0);
120: }
121: return getInstances()[index];
122: }
123:
124: /* (non-Javadoc)
125: * @see org.eclipse.jdt.internal.debug.core.model.JDIArrayValue#getValues()
126: */
127: public IJavaValue[] getValues() throws DebugException {
128: return getInstances();
129: }
130:
131: /* (non-Javadoc)
132: * @see org.eclipse.jdt.internal.debug.core.model.JDIArrayValue#getVariable(int)
133: */
134: public IVariable getVariable(int offset) throws DebugException {
135: if (offset > getInstances().length - 1 || offset < 0) {
136: internalError(LogicalStructuresMessages.JDIAllInstancesValue_1);
137: }
138: if (isMoreThanPreference()
139: && offset == getInstances().length - 1) {
140: return new JDIPlaceholderVariable(
141: LogicalStructuresMessages.JDIAllInstancesValue_4,
142: getInstances()[offset]);
143: } else {
144: return new JDIPlaceholderVariable(MessageFormat.format(
145: LogicalStructuresMessages.JDIAllInstancesValue_5,
146: new String[] { Integer.toString(offset) }),
147: getInstances()[offset]);
148: }
149: }
150:
151: /* (non-Javadoc)
152: * @see org.eclipse.jdt.internal.debug.core.model.JDIArrayValue#getVariables(int, int)
153: */
154: public IVariable[] getVariables(int offset, int length)
155: throws DebugException {
156: if (length == 0) {
157: return new IVariable[0];
158: }
159: if (offset > getInstances().length - 1 || offset < 0) {
160: internalError(LogicalStructuresMessages.JDIAllInstancesValue_1);
161: }
162: IVariable[] vars = new JDIPlaceholderVariable[length];
163: for (int i = 0; i < length; i++) {
164: vars[i] = getVariable(i + offset);
165: }
166: return vars;
167: }
168:
169: /* (non-Javadoc)
170: * @see org.eclipse.jdt.internal.debug.core.model.JDIValue#getVariables()
171: */
172: public IVariable[] getVariables() throws DebugException {
173: return getVariables(0, getInstances().length);
174: }
175:
176: /* (non-Javadoc)
177: * @see org.eclipse.jdt.internal.debug.core.model.JDIObjectValue#getReferringObjects(long)
178: */
179: public IJavaObject[] getReferringObjects(long max)
180: throws DebugException {
181: return new IJavaObject[0];
182: }
183:
184: /* (non-Javadoc)
185: * @see org.eclipse.jdt.internal.debug.core.model.JDIValue#isAllocated()
186: */
187: public boolean isAllocated() throws DebugException {
188: return getJavaDebugTarget().isAvailable();
189: }
190:
191: /* (non-Javadoc)
192: * @see org.eclipse.jdt.internal.debug.core.model.JDIArrayValue#getInitialOffset()
193: */
194: public int getInitialOffset() {
195: return 0;
196: }
197:
198: /* (non-Javadoc)
199: * @see org.eclipse.jdt.internal.debug.core.model.JDIArrayValue#hasVariables()
200: */
201: public boolean hasVariables() throws DebugException {
202: return getInstances().length > 0;
203: }
204:
205: /* (non-Javadoc)
206: * @see org.eclipse.jdt.internal.debug.core.model.JDIValue#getJavaType()
207: */
208: public IJavaType getJavaType() throws DebugException {
209: return fType;
210: }
211:
212: /* (non-Javadoc)
213: * @see org.eclipse.jdt.internal.debug.core.model.JDIValue#getSignature()
214: */
215: public String getSignature() throws DebugException {
216: return fType.getSignature();
217: }
218:
219: /* (non-Javadoc)
220: * @see org.eclipse.jdt.internal.debug.core.model.JDIObjectValue#getReferenceTypeName()
221: */
222: public String getReferenceTypeName() throws DebugException {
223: return fType.getName();
224: }
225:
226: /* (non-Javadoc)
227: * @see org.eclipse.jdt.internal.debug.core.model.JDIValue#getValueString()
228: */
229: public String getValueString() throws DebugException {
230: if (isMoreThanPreference()) {
231: return MessageFormat.format(
232: LogicalStructuresMessages.JDIAllInstancesValue_7,
233: new String[] { Integer
234: .toString(getInstances().length - 1) });
235: } else if (getInstances().length == 1) {
236: return MessageFormat.format(
237: LogicalStructuresMessages.JDIAllInstancesValue_8,
238: new String[] { Integer
239: .toString(getInstances().length) });
240: } else {
241: return MessageFormat.format(
242: LogicalStructuresMessages.JDIAllInstancesValue_9,
243: new String[] { Integer
244: .toString(getInstances().length) });
245: }
246: }
247:
248: /**
249: * Returns a string representation of this value intended to be displayed
250: * in the detail pane of views. Lists the references on separate lines.
251: *
252: * @return a string representation of this value to display in the detail pane
253: */
254: public String getDetailString() {
255: StringBuffer buf = new StringBuffer();
256: Object[] elements = getInstances();
257: if (elements.length == 0) {
258: buf
259: .append(LogicalStructuresMessages.JDIAllInstancesValue_10);
260: } else {
261: String length = null;
262: if (isMoreThanPreference()) {
263: length = MessageFormat
264: .format(
265: LogicalStructuresMessages.JDIAllInstancesValue_11,
266: new String[] { Integer
267: .toString(elements.length - 1) });
268: } else {
269: length = Integer.toString(elements.length);
270: }
271: if (elements.length == 1) {
272: buf
273: .append(MessageFormat
274: .format(
275: LogicalStructuresMessages.JDIAllInstancesValue_12,
276: new String[] { length }));
277: } else {
278: buf
279: .append(MessageFormat
280: .format(
281: LogicalStructuresMessages.JDIAllInstancesValue_13,
282: new String[] { length }));
283: }
284: for (int i = 0; i < elements.length; i++) {
285: buf.append(elements[i] + "\n"); //$NON-NLS-1$
286: }
287: }
288: return buf.toString();
289: }
290:
291: /**
292: * @return whether there are more instances available than should be displayed
293: */
294: protected boolean isMoreThanPreference() {
295: getInstances(); //The instances must be requested to know if there are more than the preference
296: return fIsMoreThanPreference;
297: }
298:
299: }
|