OSDN Git Service

libjava/
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / classpath / jdwp / processor / ReferenceTypeCommandSet.java
1 /* ReferenceTypeCommandSet.java -- class to implement the ReferenceType
2    Command Set
3    Copyright (C) 2005, 2006, 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.JdwpString;
52 import gnu.classpath.jdwp.util.Signature;
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 ReferenceType Command Set.
63  * 
64  * @author Aaron Luchko <aluchko@redhat.com>
65  */
66 public class ReferenceTypeCommandSet
67   extends CommandSet
68 {
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.ReferenceType.SIGNATURE:
77             executeSignature(bb, os);
78             break;
79           case JdwpConstants.CommandSet.ReferenceType.CLASS_LOADER:
80             executeClassLoader(bb, os);
81             break;
82           case JdwpConstants.CommandSet.ReferenceType.MODIFIERS:
83             executeModifiers(bb, os);
84             break;
85           case JdwpConstants.CommandSet.ReferenceType.FIELDS:
86             executeFields(bb, os);
87             break;
88           case JdwpConstants.CommandSet.ReferenceType.METHODS:
89             executeMethods(bb, os);
90             break;
91           case JdwpConstants.CommandSet.ReferenceType.GET_VALUES:
92             executeGetValues(bb, os);
93             break;
94           case JdwpConstants.CommandSet.ReferenceType.SOURCE_FILE:
95             executeSourceFile(bb, os);
96             break;
97           case JdwpConstants.CommandSet.ReferenceType.NESTED_TYPES:
98             executeNestedTypes(bb, os);
99             break;
100           case JdwpConstants.CommandSet.ReferenceType.STATUS:
101             executeStatus(bb, os);
102             break;
103           case JdwpConstants.CommandSet.ReferenceType.INTERFACES:
104             executeInterfaces(bb, os);
105             break;
106           case JdwpConstants.CommandSet.ReferenceType.CLASS_OBJECT:
107             executeClassObject(bb, os);
108             break;
109           case JdwpConstants.CommandSet.ReferenceType.SOURCE_DEBUG_EXTENSION:
110             executeSourceDebugExtension(bb, os);
111             break;
112           case JdwpConstants.CommandSet.ReferenceType.SIGNATURE_WITH_GENERIC:
113             executeSignatureWithGeneric(bb, os);
114             break;
115           case JdwpConstants.CommandSet.ReferenceType.FIELDS_WITH_GENERIC:
116             executeFieldWithGeneric(bb, os);
117             break;
118           case JdwpConstants.CommandSet.ReferenceType.METHODS_WITH_GENERIC:
119             executeMethodsWithGeneric(bb, os);
120             break;
121           default:
122             throw new NotImplementedException("Command " + command +
123               " not found in ReferenceType Command Set.");
124           }
125       }
126     catch (IOException ex)
127       {
128         // The DataOutputStream we're using isn't talking to a socket at all
129         // So if we throw an IOException we're in serious trouble
130         throw new JdwpInternalErrorException(ex);
131       }
132
133     return false;
134   }
135
136   private void executeSignature(ByteBuffer bb, DataOutputStream os)
137     throws JdwpException, IOException
138   {
139     ReferenceTypeId refId = idMan.readReferenceTypeId(bb);
140     String sig = Signature.computeClassSignature(refId.getType());
141     JdwpString.writeString(os, sig);
142   }
143
144   private void executeClassLoader(ByteBuffer bb, DataOutputStream os)
145     throws JdwpException, IOException
146   {
147     ReferenceTypeId refId = idMan.readReferenceTypeId(bb);
148
149     Class clazz = refId.getType();
150     ClassLoader loader = clazz.getClassLoader();
151     ObjectId oid = idMan.getObjectId(loader);
152     oid.write(os);
153   }
154
155   private void executeModifiers(ByteBuffer bb, DataOutputStream os)
156     throws JdwpException, IOException
157   {
158     ReferenceTypeId refId = idMan.readReferenceTypeId(bb);
159
160     Class clazz = refId.getType();
161     os.writeInt(clazz.getModifiers());
162   }
163
164   private void executeFields(ByteBuffer bb, DataOutputStream os)
165     throws JdwpException, IOException
166   {
167     ReferenceTypeId refId = idMan.readReferenceTypeId(bb);
168     Class clazz = refId.getType();
169
170     Field[] fields = clazz.getFields();
171     os.writeInt(fields.length);
172     for (int i = 0; i < fields.length; i++)
173       {
174         Field field = fields[i];
175         idMan.getObjectId(field).write(os);
176         JdwpString.writeString(os, field.getName());
177         JdwpString.writeString(os, Signature.computeFieldSignature(field));
178         os.writeInt(field.getModifiers());
179       }
180   }
181
182   private void executeMethods(ByteBuffer bb, DataOutputStream os)
183     throws JdwpException, IOException
184   {
185     ReferenceTypeId refId = idMan.readReferenceTypeId(bb);
186     Class clazz = refId.getType();
187
188     VMMethod[] methods = VMVirtualMachine.getAllClassMethods(clazz);
189     os.writeInt (methods.length);
190     for (int i = 0; i < methods.length; i++)
191       {
192         VMMethod method = methods[i];
193         method.writeId(os);
194         JdwpString.writeString(os, method.getName());
195         JdwpString.writeString(os, method.getSignature());
196         os.writeInt(method.getModifiers());
197       }
198   }
199
200   private void executeGetValues(ByteBuffer bb, DataOutputStream os)
201     throws JdwpException, IOException
202   {
203     ReferenceTypeId refId = idMan.readReferenceTypeId(bb);
204     Class clazz = refId.getType();
205
206     int numFields = bb.getInt();
207     os.writeInt(numFields); // Looks pointless but this is the protocol
208     for (int i = 0; i < numFields; i++)
209       {
210         ObjectId fieldId = idMan.readObjectId(bb);
211         Field field = (Field) (fieldId.getObject());
212         Class fieldClazz = field.getDeclaringClass();
213
214         // We don't actually need the clazz to get the field but we might as
215         // well check that the debugger got it right
216         if (fieldClazz.isAssignableFrom(clazz))
217           {
218             try
219               {
220                 field.setAccessible(true); // Might be a private field
221                 Object value = field.get(null);
222                 Value val = ValueFactory.createFromObject(value, 
223                                                           field.getType());
224                 val.writeTagged(os);
225               }
226             catch (IllegalArgumentException ex)
227               {
228                 // I suppose this would best qualify as an invalid field then
229                 throw new InvalidFieldException(ex);
230               }
231             catch (IllegalAccessException ex)
232               {
233                 // Since we set it as accessible this really shouldn't happen
234                 throw new JdwpInternalErrorException(ex);
235               }
236           }
237         else
238           throw new InvalidFieldException(fieldId.getId());
239       }
240   }
241
242   private void executeSourceFile(ByteBuffer bb, DataOutputStream os)
243     throws JdwpException, IOException
244   {
245     ReferenceTypeId refId = idMan.readReferenceTypeId(bb);
246     Class clazz = refId.getType();
247
248     // We'll need to go into the jvm for this unless there's an easier way
249     String sourceFileName = VMVirtualMachine.getSourceFile(clazz);
250     JdwpString.writeString(os, sourceFileName);
251     // clazz.getProtectionDomain().getCodeSource().getLocation();
252   }
253
254   private void executeNestedTypes(ByteBuffer bb, DataOutputStream os)
255     throws JdwpException, IOException
256   {
257     ReferenceTypeId refId = idMan.readReferenceTypeId(bb);
258     Class clazz = refId.getType();
259     Class[] declaredClazzes = clazz.getDeclaredClasses();
260     os.writeInt(declaredClazzes.length);
261     for (int i = 0; i < declaredClazzes.length; i++)
262       {
263         Class decClazz = declaredClazzes[i];
264         ReferenceTypeId clazzId = idMan.getReferenceTypeId(decClazz);
265         clazzId.writeTagged(os);
266       }
267   }
268
269   private void executeStatus(ByteBuffer bb, DataOutputStream os)
270     throws JdwpException, IOException
271   {
272     ReferenceTypeId refId = idMan.readReferenceTypeId(bb);
273     Class clazz = refId.getType();
274
275     // I don't think there's any other way to get this
276     int status = VMVirtualMachine.getClassStatus(clazz);
277     os.writeInt(status);
278   }
279
280   private void executeInterfaces(ByteBuffer bb, DataOutputStream os)
281     throws JdwpException, IOException
282   {
283     ReferenceTypeId refId = idMan.readReferenceTypeId(bb);
284     Class clazz = refId.getType();
285     Class[] interfaces = clazz.getInterfaces();
286     os.writeInt(interfaces.length);
287     for (int i = 0; i < interfaces.length; i++)
288       {
289         Class interfaceClass = interfaces[i];
290         ReferenceTypeId intId = idMan.getReferenceTypeId(interfaceClass);
291         intId.write(os);
292       }
293   }
294
295   private void executeClassObject(ByteBuffer bb, DataOutputStream os)
296     throws JdwpException, IOException
297   {
298     ReferenceTypeId refId = idMan.readReferenceTypeId(bb);
299     Class clazz = refId.getType();
300     ObjectId clazzObjectId = idMan.getObjectId(clazz);
301     clazzObjectId.write(os);
302   }
303
304   private void executeSourceDebugExtension(ByteBuffer bb, DataOutputStream os)
305     throws JdwpException, IOException
306   {
307     if (!VMVirtualMachine.canGetSourceDebugExtension)
308       {
309         String msg = "source debug extension is not supported";
310         throw new NotImplementedException(msg);
311       }
312
313     ReferenceTypeId id = idMan.readReferenceTypeId(bb);
314     String ext = VMVirtualMachine.getSourceDebugExtension (id.getType());
315     JdwpString.writeString(os, ext);
316   }
317
318   private void executeSignatureWithGeneric(ByteBuffer bb, DataOutputStream os)
319     throws JdwpException, IOException
320   {
321     // We don't have generics yet
322     throw new NotImplementedException(
323       "Command SignatureWithGeneric not implemented.");
324   }
325
326   private void executeFieldWithGeneric(ByteBuffer bb, DataOutputStream os)
327     throws JdwpException, IOException
328   {
329     // We don't have generics yet
330     throw new NotImplementedException(
331       "Command executeFieldWithGeneric not implemented.");
332   }
333
334   private void executeMethodsWithGeneric(ByteBuffer bb, DataOutputStream os)
335     throws JdwpException, IOException
336   {
337     // We don't have generics yet
338     throw new NotImplementedException(
339       "Command executeMethodsWithGeneric not implemented.");
340   }
341 }