001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 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.jdi.internal;
011:
012: import java.io.DataInputStream;
013: import java.io.IOException;
014: import java.util.ArrayList;
015: import java.util.Iterator;
016: import java.util.List;
017:
018: import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket;
019: import org.eclipse.jdi.internal.jdwp.JdwpID;
020: import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
021: import org.eclipse.jdi.internal.jdwp.JdwpThreadGroupID;
022:
023: import com.sun.jdi.ThreadGroupReference;
024:
025: /**
026: * this class implements the corresponding interfaces
027: * declared by the JDI specification. See the com.sun.jdi package
028: * for more information.
029: *
030: */
031: public class ThreadGroupReferenceImpl extends ObjectReferenceImpl
032: implements ThreadGroupReference {
033: /** JDWP Tag. */
034: public static final byte tag = JdwpID.THREAD_GROUP_TAG;
035: /**
036: * The cached name of this thread group. This value is safe to cache because
037: * there is no API for changing the name of a ThreadGroup.
038: */
039: private String fName;
040: /**
041: * The cached parent of this thread group. Once set, this value cannot be changed
042: */
043: private ThreadGroupReference fParent = fgUnsetParent;
044: private static ThreadGroupReferenceImpl fgUnsetParent = new ThreadGroupReferenceImpl(
045: null, null);
046:
047: /**
048: * Creates new ThreadGroupReferenceImpl.
049: */
050: public ThreadGroupReferenceImpl(VirtualMachineImpl vmImpl,
051: JdwpThreadGroupID threadGroupID) {
052: super ("ThreadGroupReference", vmImpl, threadGroupID); //$NON-NLS-1$
053: }
054:
055: /**
056: * @returns Value tag.
057: */
058: public byte getTag() {
059: return tag;
060: }
061:
062: /**
063: * @return Returns the name of this thread group.
064: */
065: public String name() {
066: if (fName != null) {
067: return fName;
068: }
069: initJdwpRequest();
070: try {
071: JdwpReplyPacket replyPacket = requestVM(
072: JdwpCommandPacket.TGR_NAME, this );
073: defaultReplyErrorHandler(replyPacket.errorCode());
074: DataInputStream replyData = replyPacket.dataInStream();
075: fName = readString("name", replyData); //$NON-NLS-1$
076: return fName;
077: } catch (IOException e) {
078: defaultIOExceptionHandler(e);
079: return null;
080: } finally {
081: handledJdwpRequest();
082: }
083: }
084:
085: /**
086: * @return Returns the parent of this thread group., or null if there isn't.
087: */
088: public ThreadGroupReference parent() {
089: if (fParent != fgUnsetParent) {
090: return fParent;
091: }
092: initJdwpRequest();
093: try {
094: JdwpReplyPacket replyPacket = requestVM(
095: JdwpCommandPacket.TGR_PARENT, this );
096: defaultReplyErrorHandler(replyPacket.errorCode());
097: DataInputStream replyData = replyPacket.dataInStream();
098: fParent = ThreadGroupReferenceImpl.read(this , replyData);
099: return fParent;
100: } catch (IOException e) {
101: defaultIOExceptionHandler(e);
102: return null;
103: } finally {
104: handledJdwpRequest();
105: }
106: }
107:
108: /**
109: * Resumes all threads in this thread group (including subgroups).
110: */
111: public void resume() {
112: Iterator iter = allThreads().iterator();
113: while (iter.hasNext()) {
114: ThreadReferenceImpl thr = (ThreadReferenceImpl) iter.next();
115: thr.resume();
116: }
117: }
118:
119: /**
120: * Suspends all threads in this thread group (including subgroups).
121: */
122: public void suspend() {
123: Iterator iter = allThreads().iterator();
124: while (iter.hasNext()) {
125: ThreadReferenceImpl thr = (ThreadReferenceImpl) iter.next();
126: thr.suspend();
127: }
128: }
129:
130: /**
131: * Inner class used to return children info.
132: */
133: private class ChildrenInfo {
134: List childThreads;
135: List childThreadGroups;
136: }
137:
138: /**
139: * @return Returns a List containing each ThreadReference in this thread group.
140: */
141: public ChildrenInfo childrenInfo() {
142: // Note that this information should not be cached.
143: initJdwpRequest();
144: try {
145: JdwpReplyPacket replyPacket = requestVM(
146: JdwpCommandPacket.TGR_CHILDREN, this );
147: defaultReplyErrorHandler(replyPacket.errorCode());
148: DataInputStream replyData = replyPacket.dataInStream();
149: ChildrenInfo result = new ChildrenInfo();
150: int nrThreads = readInt("nr threads", replyData); //$NON-NLS-1$
151: result.childThreads = new ArrayList(nrThreads);
152: for (int i = 0; i < nrThreads; i++)
153: result.childThreads.add(ThreadReferenceImpl.read(this ,
154: replyData));
155: int nrThreadGroups = readInt("nr thread groups", replyData); //$NON-NLS-1$
156: result.childThreadGroups = new ArrayList(nrThreadGroups);
157: for (int i = 0; i < nrThreadGroups; i++)
158: result.childThreadGroups.add(ThreadGroupReferenceImpl
159: .read(this , replyData));
160: return result;
161: } catch (IOException e) {
162: defaultIOExceptionHandler(e);
163: return null;
164: } finally {
165: handledJdwpRequest();
166: }
167: }
168:
169: /**
170: * @return Returns a List containing each ThreadGroupReference in this thread group.
171: */
172: public List threadGroups() {
173: return childrenInfo().childThreadGroups;
174: }
175:
176: /**
177: * @return Returns a List containing each ThreadReference in this thread group.
178: */
179: public List threads() {
180: return childrenInfo().childThreads;
181: }
182:
183: /**
184: * @return Returns a List containing each ThreadGroupReference in this thread group and all of
185: * its subgroups.
186: */
187: private List allThreads() {
188: ChildrenInfo info = childrenInfo();
189: List result = info.childThreads;
190: Iterator iter = info.childThreadGroups.iterator();
191: while (iter.hasNext()) {
192: ThreadGroupReferenceImpl tg = (ThreadGroupReferenceImpl) iter
193: .next();
194: result.addAll(tg.allThreads());
195: }
196: return result;
197: }
198:
199: /**
200: * @return Returns description of Mirror object.
201: */
202: public String toString() {
203: try {
204: return name();
205: } catch (Exception e) {
206: return fDescription;
207: }
208: }
209:
210: /**
211: * @return Reads JDWP representation and returns new instance.
212: */
213: public static ThreadGroupReferenceImpl read(MirrorImpl target,
214: DataInputStream in) throws IOException {
215: VirtualMachineImpl vmImpl = target.virtualMachineImpl();
216: JdwpThreadGroupID ID = new JdwpThreadGroupID(vmImpl);
217: ID.read(in);
218: if (target.fVerboseWriter != null)
219: target.fVerboseWriter.println(
220: "threadGroupReference", ID.value()); //$NON-NLS-1$
221:
222: if (ID.isNull())
223: return null;
224:
225: ThreadGroupReferenceImpl mirror = (ThreadGroupReferenceImpl) vmImpl
226: .getCachedMirror(ID);
227: if (mirror == null) {
228: mirror = new ThreadGroupReferenceImpl(vmImpl, ID);
229: vmImpl.addCachedMirror(mirror);
230: }
231: return mirror;
232: }
233: }
|