1 /* ObjectReferenceCommandSet.java -- class to implement the ObjectReference 2 Command Set 3 Copyright (C) 2005, 2007 Free Software Foundation 4 5 This file is part of GNU Classpath. 6 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) 10 any later version. 11 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. 16 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 20 02110-1301 USA. 21 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 25 combination. 26 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. */ 38 39 40 package gnu.classpath.jdwp.processor; 41 42 import gnu.classpath.jdwp.JdwpConstants; 43 import gnu.classpath.jdwp.VMMethod; 44 import gnu.classpath.jdwp.VMVirtualMachine; 45 import gnu.classpath.jdwp.exception.InvalidFieldException; 46 import gnu.classpath.jdwp.exception.JdwpException; 47 import gnu.classpath.jdwp.exception.JdwpInternalErrorException; 48 import gnu.classpath.jdwp.exception.NotImplementedException; 49 import gnu.classpath.jdwp.id.ObjectId; 50 import gnu.classpath.jdwp.id.ReferenceTypeId; 51 import gnu.classpath.jdwp.util.MethodResult; 52 import gnu.classpath.jdwp.util.MonitorInfo; 53 import gnu.classpath.jdwp.value.Value; 54 import gnu.classpath.jdwp.value.ValueFactory; 55 56 import java.io.DataOutputStream; 57 import java.io.IOException; 58 import java.lang.reflect.Field; 59 import java.nio.ByteBuffer; 60 61 /** 62 * A class representing the ObjectReference Command Set. 63 * 64 * @author Aaron Luchko <aluchko@redhat.com> 65 */ 66 public class ObjectReferenceCommandSet 67 extends CommandSet 68 { runCommand(ByteBuffer bb, DataOutputStream os, byte command)69 public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) 70 throws JdwpException 71 { 72 try 73 { 74 switch (command) 75 { 76 case JdwpConstants.CommandSet.ObjectReference.REFERENCE_TYPE: 77 executeReferenceType(bb, os); 78 break; 79 case JdwpConstants.CommandSet.ObjectReference.GET_VALUES: 80 executeGetValues(bb, os); 81 break; 82 case JdwpConstants.CommandSet.ObjectReference.SET_VALUES: 83 executeSetValues(bb, os); 84 break; 85 case JdwpConstants.CommandSet.ObjectReference.MONITOR_INFO: 86 executeMonitorInfo(bb, os); 87 break; 88 case JdwpConstants.CommandSet.ObjectReference.INVOKE_METHOD: 89 executeInvokeMethod(bb, os); 90 break; 91 case JdwpConstants.CommandSet.ObjectReference.DISABLE_COLLECTION: 92 executeDisableCollection(bb, os); 93 break; 94 case JdwpConstants.CommandSet.ObjectReference.ENABLE_COLLECTION: 95 executeEnableCollection(bb, os); 96 break; 97 case JdwpConstants.CommandSet.ObjectReference.IS_COLLECTED: 98 executeIsCollected(bb, os); 99 break; 100 default: 101 throw new NotImplementedException("Command " + command + 102 " not found in ObjectReference Command Set."); 103 } 104 } 105 catch (IOException ex) 106 { 107 // The DataOutputStream we're using isn't talking to a socket at all 108 // So if we throw an IOException we're in serious trouble 109 throw new JdwpInternalErrorException(ex); 110 } 111 112 return false; 113 } 114 executeReferenceType(ByteBuffer bb, DataOutputStream os)115 private void executeReferenceType(ByteBuffer bb, DataOutputStream os) 116 throws JdwpException, IOException 117 { 118 ObjectId oid = idMan.readObjectId(bb); 119 Object obj = oid.getObject(); 120 Class clazz = obj.getClass(); 121 ReferenceTypeId refId = idMan.getReferenceTypeId(clazz); 122 refId.writeTagged(os); 123 } 124 executeGetValues(ByteBuffer bb, DataOutputStream os)125 private void executeGetValues(ByteBuffer bb, DataOutputStream os) 126 throws JdwpException, IOException 127 { 128 ObjectId oid = idMan.readObjectId(bb); 129 Object obj = oid.getObject(); 130 131 int numFields = bb.getInt(); 132 133 os.writeInt(numFields); // Looks pointless but this is the protocol 134 135 for (int i = 0; i < numFields; i++) 136 { 137 Field field = (Field) idMan.readObjectId(bb).getObject(); 138 try 139 { 140 field.setAccessible(true); // Might be a private field 141 Object value = field.get(obj); 142 Value val = ValueFactory.createFromObject(value, 143 field.getType()); 144 val.writeTagged(os); 145 } 146 catch (IllegalArgumentException ex) 147 { 148 // I suppose this would best qualify as an invalid field then 149 throw new InvalidFieldException(ex); 150 } 151 catch (IllegalAccessException ex) 152 { 153 // Since we set it as accessible this really shouldn't happen 154 throw new JdwpInternalErrorException(ex); 155 } 156 } 157 } 158 executeSetValues(ByteBuffer bb, DataOutputStream os)159 private void executeSetValues(ByteBuffer bb, DataOutputStream os) 160 throws JdwpException, IOException 161 { 162 ObjectId oid = idMan.readObjectId(bb); 163 Object obj = oid.getObject(); 164 165 int numFields = bb.getInt(); 166 167 for (int i = 0; i < numFields; i++) 168 { 169 Field field = (Field) idMan.readObjectId(bb).getObject(); 170 Object value = Value.getUntaggedObject(bb, field.getType()); 171 try 172 { 173 field.setAccessible(true); // Might be a private field 174 field.set(obj, value); 175 } 176 catch (IllegalArgumentException ex) 177 { 178 // I suppose this would best qualify as an invalid field then 179 throw new InvalidFieldException(ex); 180 } 181 catch (IllegalAccessException ex) 182 { 183 // Since we set it as accessible this really shouldn't happen 184 throw new JdwpInternalErrorException(ex); 185 } 186 } 187 } 188 executeMonitorInfo(ByteBuffer bb, DataOutputStream os)189 private void executeMonitorInfo(ByteBuffer bb, DataOutputStream os) 190 throws JdwpException, IOException 191 { 192 if (!VMVirtualMachine.canGetMonitorInfo) 193 { 194 String msg = "getting monitor info not supported"; 195 throw new NotImplementedException(msg); 196 } 197 198 ObjectId oid = idMan.readObjectId(bb); 199 Object obj = oid.getObject(); 200 MonitorInfo info = VMVirtualMachine.getMonitorInfo(obj); 201 info.write(os); 202 } 203 executeInvokeMethod(ByteBuffer bb, DataOutputStream os)204 private void executeInvokeMethod(ByteBuffer bb, DataOutputStream os) 205 throws JdwpException, IOException 206 { 207 ObjectId oid = idMan.readObjectId(bb); 208 Object obj = oid.getObject(); 209 210 ObjectId tid = idMan.readObjectId(bb); 211 Thread thread = (Thread) tid.getObject(); 212 213 ReferenceTypeId rid = idMan.readReferenceTypeId(bb); 214 Class clazz = rid.getType(); 215 216 VMMethod method = VMMethod.readId(clazz, bb); 217 218 int args = bb.getInt(); 219 Value[] values = new Value[args]; 220 221 for (int i = 0; i < args; i++) 222 values[i] = ValueFactory.createFromTagged(bb); 223 224 int invokeOptions = bb.getInt(); 225 MethodResult mr = VMVirtualMachine.executeMethod(obj, thread, 226 clazz, method, 227 values, invokeOptions); 228 Throwable exception = mr.getThrownException(); 229 ObjectId eId = idMan.getObjectId(exception); 230 mr.getReturnedValue().writeTagged(os); 231 eId.writeTagged(os); 232 } 233 executeDisableCollection(ByteBuffer bb, DataOutputStream os)234 private void executeDisableCollection(ByteBuffer bb, DataOutputStream os) 235 throws JdwpException, IOException 236 { 237 ObjectId oid = idMan.readObjectId(bb); 238 oid.disableCollection(); 239 } 240 executeEnableCollection(ByteBuffer bb, DataOutputStream os)241 private void executeEnableCollection(ByteBuffer bb, DataOutputStream os) 242 throws JdwpException, IOException 243 { 244 ObjectId oid = idMan.readObjectId(bb); 245 oid.enableCollection(); 246 } 247 executeIsCollected(ByteBuffer bb, DataOutputStream os)248 private void executeIsCollected(ByteBuffer bb, DataOutputStream os) 249 throws JdwpException, IOException 250 { 251 ObjectId oid = idMan.readObjectId(bb); 252 boolean collected = (oid.getReference().get () == null); 253 os.writeBoolean(collected); 254 } 255 } 256