1 /* ObjectReferenceCommandSet.java -- class to implement the ObjectReference
3 Copyright (C) 2005 Free Software Foundation
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
40 package gnu.classpath.jdwp.processor;
42 import gnu.classpath.jdwp.JdwpConstants;
43 import gnu.classpath.jdwp.VMVirtualMachine;
44 import gnu.classpath.jdwp.exception.InvalidFieldException;
45 import gnu.classpath.jdwp.exception.JdwpException;
46 import gnu.classpath.jdwp.exception.JdwpInternalErrorException;
47 import gnu.classpath.jdwp.exception.NotImplementedException;
48 import gnu.classpath.jdwp.id.ObjectId;
49 import gnu.classpath.jdwp.id.ReferenceTypeId;
50 import gnu.classpath.jdwp.util.Value;
51 import gnu.classpath.jdwp.util.MethodResult;
53 import java.io.DataOutputStream;
54 import java.io.IOException;
55 import java.lang.reflect.Field;
56 import java.lang.reflect.Method;
57 import java.nio.ByteBuffer;
60 * A class representing the ObjectReference Command Set.
62 * @author Aaron Luchko <aluchko@redhat.com>
64 public class ObjectReferenceCommandSet
67 public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command)
74 case JdwpConstants.CommandSet.ObjectReference.REFERENCE_TYPE:
75 executeReferenceType(bb, os);
77 case JdwpConstants.CommandSet.ObjectReference.GET_VALUES:
78 executeGetValues(bb, os);
80 case JdwpConstants.CommandSet.ObjectReference.SET_VALUES:
81 executeSetValues(bb, os);
83 case JdwpConstants.CommandSet.ObjectReference.MONITOR_INFO:
84 executeMonitorInfo(bb, os);
86 case JdwpConstants.CommandSet.ObjectReference.INVOKE_METHOD:
87 executeInvokeMethod(bb, os);
89 case JdwpConstants.CommandSet.ObjectReference.DISABLE_COLLECTION:
90 executeDisableCollection(bb, os);
92 case JdwpConstants.CommandSet.ObjectReference.ENABLE_COLLECTION:
93 executeEnableCollection(bb, os);
95 case JdwpConstants.CommandSet.ObjectReference.IS_COLLECTED:
96 executeIsCollected(bb, os);
99 throw new NotImplementedException("Command " + command +
100 " not found in ObjectReference Command Set.");
103 catch (IOException ex)
105 // The DataOutputStream we're using isn't talking to a socket at all
106 // So if we throw an IOException we're in serious trouble
107 throw new JdwpInternalErrorException(ex);
112 private void executeReferenceType(ByteBuffer bb, DataOutputStream os)
113 throws JdwpException, IOException
115 ObjectId oid = idMan.readObjectId(bb);
116 Object obj = oid.getObject();
117 Class clazz = obj.getClass();
118 ReferenceTypeId refId = idMan.getReferenceTypeId(clazz);
119 refId.writeTagged(os);
122 private void executeGetValues(ByteBuffer bb, DataOutputStream os)
123 throws JdwpException, IOException
125 ObjectId oid = idMan.readObjectId(bb);
126 Object obj = oid.getObject();
128 int numFields = bb.getInt();
130 os.writeInt(numFields); // Looks pointless but this is the protocol
132 for (int i = 0; i < numFields; i++)
134 Field field = (Field) idMan.readObjectId(bb).getObject();
137 field.setAccessible(true); // Might be a private field
138 Object value = field.get(obj);
139 Value.writeTaggedValue(os, value);
141 catch (IllegalArgumentException ex)
143 // I suppose this would best qualify as an invalid field then
144 throw new InvalidFieldException(ex);
146 catch (IllegalAccessException ex)
148 // Since we set it as accessible this really shouldn't happen
149 throw new JdwpInternalErrorException(ex);
154 private void executeSetValues(ByteBuffer bb, DataOutputStream os)
155 throws JdwpException, IOException
157 ObjectId oid = idMan.readObjectId(bb);
158 Object obj = oid.getObject();
160 int numFields = bb.getInt();
162 for (int i = 0; i < numFields; i++)
164 Field field = (Field) idMan.readObjectId(bb).getObject();
165 Object value = Value.getUntaggedObj(bb, field.getType());
168 field.setAccessible(true); // Might be a private field
169 field.set(obj, value);
171 catch (IllegalArgumentException ex)
173 // I suppose this would best qualify as an invalid field then
174 throw new InvalidFieldException(ex);
176 catch (IllegalAccessException ex)
178 // Since we set it as accessible this really shouldn't happen
179 throw new JdwpInternalErrorException(ex);
184 private void executeMonitorInfo(ByteBuffer bb, DataOutputStream os)
187 // This command is optional, determined by VirtualMachines CapabilitiesNew
188 // so we'll leave it till later to implement
189 throw new NotImplementedException(
190 "Command ExecuteMonitorInfo not implemented.");
194 private void executeInvokeMethod(ByteBuffer bb, DataOutputStream os)
195 throws JdwpException, IOException
197 ObjectId oid = idMan.readObjectId(bb);
198 Object obj = oid.getObject();
200 ObjectId tid = idMan.readObjectId(bb);
201 Thread thread = (Thread) tid.getObject();
203 ReferenceTypeId rid = idMan.readReferenceTypeId(bb);
204 Class clazz = rid.getType();
206 ObjectId mid = idMan.readObjectId(bb);
207 Method method = (Method) mid.getObject();
209 int args = bb.getInt();
210 Object[] values = new Object[args];
212 for (int i = 0; i < args; i++)
214 values[i] = Value.getObj(bb);
217 int invokeOptions = bb.getInt();
218 boolean suspend = ((invokeOptions
219 & JdwpConstants.InvokeOptions.INVOKE_SINGLE_THREADED)
223 // We must suspend all other running threads first
224 VMVirtualMachine.suspendAllThreads ();
227 boolean nonVirtual = ((invokeOptions
228 & JdwpConstants.InvokeOptions.INVOKE_NONVIRTUAL)
231 MethodResult mr = VMVirtualMachine.executeMethod(obj, thread,
234 Object value = mr.getReturnedValue();
235 Exception exception = mr.getThrownException();
237 ObjectId eId = idMan.getObjectId(exception);
238 Value.writeTaggedValue(os, value);
242 private void executeDisableCollection(ByteBuffer bb, DataOutputStream os)
243 throws JdwpException, IOException
245 ObjectId oid = idMan.readObjectId(bb);
246 oid.disableCollection();
249 private void executeEnableCollection(ByteBuffer bb, DataOutputStream os)
250 throws JdwpException, IOException
252 ObjectId oid = idMan.readObjectId(bb);
253 oid.enableCollection();
256 private void executeIsCollected(ByteBuffer bb, DataOutputStream os)
257 throws JdwpException, IOException
259 ObjectId oid = idMan.readObjectId(bb);
260 boolean collected = (oid.getReference().get () == null);
261 os.writeBoolean(collected);