1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  */
18 
19 /**
20  * @author Alexei S. Vaskin
21  */
22 
23 /**
24  * Created on 22.04.2005
25  */
26 
27 package org.apache.harmony.jpda.tests.framework.jdwp;
28 
29 import java.util.ArrayList;
30 import java.util.Iterator;
31 
32 /**
33  * This class provides description of frame.
34  *
35  */
36 public class Frame {
37 
38     protected long threadID;
39 
40     protected Location loc;
41 
42     protected long id;
43 
44     protected ArrayList vars;
45 
46     /**
47      * Default constructor.
48      */
Frame()49     public Frame() {
50         threadID = -1;
51         id = -1L;
52         loc = new Location();
53         vars = null;
54     }
55 
56     /**
57      * Constructor initializing all members of the Frame instance.
58      *
59      * @param threadID
60      *            thread id
61      * @param id
62      *            frame id
63      * @param location
64      *            frame location
65      * @param vars
66      *            list of variables
67      */
Frame(long threadID, long id, Location location, ArrayList vars)68     Frame(long threadID, long id, Location location, ArrayList vars) {
69         this.threadID = threadID;
70         this.id = id;
71         this.loc = location;
72         this.vars = vars;
73     }
74 
75     /**
76      * Gets thread id.
77      *
78      * @return long
79      */
getThreadID()80     public long getThreadID() {
81         return threadID;
82     }
83 
84     /**
85      * Sets new thread id.
86      *
87      * @param threadID
88      *            new thread id
89      */
setThreadID(long threadID)90     public void setThreadID(long threadID) {
91         this.threadID = threadID;
92     }
93 
94     /**
95      * Gets frame id.
96      *
97      * @return long
98      */
getID()99     public long getID() {
100         return id;
101     }
102 
103     /**
104      * Sets new frame id.
105      *
106      * @param id
107      *            new frame id
108      */
setID(long id)109     public void setID(long id) {
110         this.id = id;
111     }
112 
113     /**
114      * Gets frame location.
115      *
116      * @return Location
117      */
getLocation()118     public Location getLocation() {
119         return loc;
120     }
121 
122     /**
123      * Sets new frame location.
124      *
125      * @param location
126      *            new frame location
127      */
setLocation(Location location)128     public void setLocation(Location location) {
129         this.loc = location;
130     }
131 
132     /**
133      * Gets frame variables.
134      *
135      * @return list of frame variables
136      */
getVars()137     public ArrayList getVars() {
138         return vars;
139     }
140 
141     /**
142      * Sets new frame variables.
143      *
144      * @param vars
145      *            list of new frame variables
146      */
setVars(ArrayList vars)147     public void setVars(ArrayList vars) {
148         this.vars = vars;
149     }
150 
151     /**
152      * Converts Frame object to String.
153      *
154      * @see java.lang.Object#toString()
155      * @return String
156      */
toString()157     public String toString() {
158         String string = "Frame: id=" + id + ", threadID=" + threadID
159                 + ", location=" + loc.toString() + "\n";
160         string += "--- Variables ---";
161         Iterator it = vars.iterator();
162         while (it.hasNext()) {
163             string += ((Variable) it.next()).toString();
164         }
165         return string;
166     }
167 
168     /**
169      * Compares two Frame objects.
170      *
171      * @see java.lang.Object#equals(java.lang.Object)
172      * @return boolean
173      */
equals(Object obj)174     public boolean equals(Object obj) {
175         if (!(obj instanceof Frame)) {
176             return false;
177         }
178 
179         if (this.getClass() != obj.getClass()) {
180             return false;
181         }
182 
183         Frame frame = (Frame) obj;
184         if (this.threadID != frame.threadID || this.id != frame.id
185                 || !(this.loc.equals(frame.loc))) {
186             return false;
187         }
188 
189         if (vars.size() != frame.vars.size()) {
190             return false;
191         }
192 
193         if (!vars.equals(frame.vars)) {
194             return false;
195         }
196 
197         return true;
198     }
199 
200     /**
201      * This describing frame variable.
202      *
203      */
204     public final class Variable {
205         private long codeIndex;
206 
207         private String name;
208 
209         private String signature;
210 
211         private int length;
212 
213         private int slot;
214 
215         private byte tag;
216 
217         private String type;
218 
219         /**
220          * Constructor.
221          *
222          */
Variable()223         public Variable() {
224             codeIndex = -1;
225             name = "unknown";
226             signature = "unknown";
227             length = -1;
228             slot = -1;
229             tag = JDWPConstants.Tag.NO_TAG;
230             type = "unknown type";
231         }
232 
233         /**
234          * Gets code index of variable.
235          *
236          * @return long
237          */
getCodeIndex()238         public long getCodeIndex() {
239             return codeIndex;
240         }
241 
242         /**
243          * Sets new code index for variable.
244          *
245          * @param codeIndex
246          */
setCodeIndex(long codeIndex)247         public void setCodeIndex(long codeIndex) {
248             this.codeIndex = codeIndex;
249         }
250 
251         /**
252          * Gets variable name.
253          *
254          * @return String
255          */
getName()256         public String getName() {
257             return name;
258         }
259 
260         /**
261          * Sets new variable name.
262          *
263          * @param name
264          *            new variable name
265          */
setName(String name)266         public void setName(String name) {
267             this.name = name;
268         }
269 
270         /**
271          * Gets signature of the variable reference type.
272          *
273          * @return String
274          */
getSignature()275         public String getSignature() {
276             return signature;
277         }
278 
279         /**
280          * Sets new signature and detects value of a type tag.
281          *
282          * @param signature
283          */
setSignature(String signature)284         public void setSignature(String signature) {
285             switch (signature.charAt(0)) {
286             case '[':
287                 tag = JDWPConstants.Tag.ARRAY_TAG;
288                 break;
289             case 'B':
290                 tag = JDWPConstants.Tag.BYTE_TAG;
291                 break;
292             case 'C':
293                 tag = JDWPConstants.Tag.CHAR_TAG;
294                 break;
295             case 'L':
296                 tag = JDWPConstants.Tag.OBJECT_TAG;
297                 break;
298             case 'F':
299                 tag = JDWPConstants.Tag.FLOAT_TAG;
300                 break;
301             case 'D':
302                 tag = JDWPConstants.Tag.DOUBLE_TAG;
303                 break;
304             case 'I':
305                 tag = JDWPConstants.Tag.INT_TAG;
306                 break;
307             case 'J':
308                 tag = JDWPConstants.Tag.LONG_TAG;
309                 break;
310             case 'S':
311                 tag = JDWPConstants.Tag.SHORT_TAG;
312                 break;
313             case 'V':
314                 tag = JDWPConstants.Tag.VOID_TAG;
315                 break;
316             case 'Z':
317                 tag = JDWPConstants.Tag.BOOLEAN_TAG;
318                 break;
319             case 's':
320                 tag = JDWPConstants.Tag.STRING_TAG;
321                 break;
322             case 't':
323                 tag = JDWPConstants.Tag.THREAD_TAG;
324                 break;
325             case 'g':
326                 tag = JDWPConstants.Tag.THREAD_GROUP_TAG;
327                 break;
328             case 'l':
329                 tag = JDWPConstants.Tag.CLASS_LOADER_TAG;
330                 break;
331             case 'c':
332                 tag = JDWPConstants.Tag.CLASS_OBJECT_TAG;
333                 break;
334             }
335 
336             this.signature = signature;
337         }
338 
339         /**
340          * Gets variable length.
341          *
342          * @return int
343          */
getLength()344         public int getLength() {
345             return length;
346         }
347 
348         /**
349          * Sets new variable length.
350          *
351          * @param length
352          *            new variable length
353          */
setLength(int length)354         public void setLength(int length) {
355             this.length = length;
356         }
357 
358         /**
359          * Returns variable slot value.
360          *
361          * @return int
362          */
getSlot()363         public int getSlot() {
364             return slot;
365         }
366 
367         /**
368          * Assigns new slot value.
369          *
370          * @param slot
371          *            new slot value
372          */
setSlot(int slot)373         public void setSlot(int slot) {
374             this.slot = slot;
375         }
376 
377         /**
378          * Gets variable type tag value.
379          *
380          * @return byte
381          */
getTag()382         public byte getTag() {
383             return tag;
384         }
385 
386         /**
387          * Gets variable java type.
388          *
389          * @return String
390          */
getType()391         public String getType() {
392             switch (tag) {
393             case JDWPConstants.Tag.ARRAY_TAG:
394                 switch (signature.charAt(1)) {
395                 case 'B':
396                     type = "byte[]";
397                     break;
398                 case 'C':
399                     type = "char[]";
400                     break;
401                 case 'J':
402                     type = "long[]";
403                     break;
404                 case 'F':
405                     type = "float[]";
406                     break;
407                 case 'D':
408                     type = "double[]";
409                     break;
410                 case 'I':
411                     type = "int[]";
412                     break;
413                 case 'S':
414                     type = "short[]";
415                     break;
416                 case 'V':
417                     type = "void[]";
418                     break;
419                 case 'Z':
420                     type = "boolean[]";
421                     break;
422                 case 's':
423                     type = "java.Lang.String[]";
424                     break;
425                 case 'L':
426                     type = signature
427                             .substring(2, signature.length() - 1 /*
428                                                                      * skip
429                                                                      * ending
430                                                                      * ';'
431                                                                      */)
432                             .replaceAll("/", ".")
433                             + "[]"; // skip ending ';'
434                     break;
435                 }
436                 break;
437             case JDWPConstants.Tag.OBJECT_TAG:
438                 type = signature
439                         .substring(1, signature.length() - 1 /*
440                                                                  * skip ending
441                                                                  * ';'
442                                                                  */)
443                         .replaceAll("/", "."); // skip ending ';'
444                 break;
445             case JDWPConstants.Tag.BOOLEAN_TAG:
446                 type = "boolean";
447                 break;
448             case JDWPConstants.Tag.BYTE_TAG:
449                 type = "byte";
450                 break;
451             case JDWPConstants.Tag.CHAR_TAG:
452                 type = "char";
453                 break;
454             case JDWPConstants.Tag.DOUBLE_TAG:
455                 type = "double";
456                 break;
457             case JDWPConstants.Tag.FLOAT_TAG:
458                 type = "float";
459                 break;
460             case JDWPConstants.Tag.INT_TAG:
461                 type = "int";
462                 break;
463             case JDWPConstants.Tag.LONG_TAG:
464                 type = "long";
465                 break;
466             case JDWPConstants.Tag.SHORT_TAG:
467                 type = "short";
468                 break;
469             case JDWPConstants.Tag.STRING_TAG:
470                 type = "string";
471                 break;
472             default:
473                 break;
474             }
475 
476             return type;
477         }
478 
479         /**
480          * Converts Variable object to String.
481          *
482          * @see java.lang.Object#toString()
483          * @return String
484          */
toString()485         public String toString() {
486             return "Variable: codeIndex=" + codeIndex + ", name=" + name
487                     + ", signature=" + signature + ", length=" + length
488                     + ", slot=" + slot + ", tag="
489                     + JDWPConstants.Tag.getName(tag) + ", type=" + type;
490         }
491 
492         /**
493          * Compares two Variable objects.
494          *
495          * @see java.lang.Object#equals(java.lang.Object)
496          * @return boolean
497          */
equals(Object obj)498         public boolean equals(Object obj) {
499             if (!(obj instanceof Variable)) {
500                 return false;
501             }
502 
503             if (this.getClass() != obj.getClass()) {
504                 return false;
505             }
506 
507             Variable var = (Variable) obj;
508             return this.codeIndex == var.codeIndex
509                     && this.name.equals(var.name)
510                     && this.signature.equals(var.signature)
511                     && this.length == var.length && this.slot == var.slot
512                     && this.tag == var.tag && this.type.equals(var.type);
513 
514         }
515     }
516 }
517