Source for gnu.classpath.jdwp.processor.ObjectReferenceCommandSet

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