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
27package org.apache.harmony.jpda.tests.framework.jdwp;
28
29import java.util.ArrayList;
30import java.util.Iterator;
31
32/**
33 * This class provides description of frame.
34 *
35 */
36public 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     */
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     */
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     */
80    public long getThreadID() {
81        return threadID;
82    }
83
84    /**
85     * Sets new thread id.
86     *
87     * @param threadID
88     *            new thread id
89     */
90    public void setThreadID(long threadID) {
91        this.threadID = threadID;
92    }
93
94    /**
95     * Gets frame id.
96     *
97     * @return long
98     */
99    public long getID() {
100        return id;
101    }
102
103    /**
104     * Sets new frame id.
105     *
106     * @param id
107     *            new frame id
108     */
109    public void setID(long id) {
110        this.id = id;
111    }
112
113    /**
114     * Gets frame location.
115     *
116     * @return Location
117     */
118    public Location getLocation() {
119        return loc;
120    }
121
122    /**
123     * Sets new frame location.
124     *
125     * @param location
126     *            new frame location
127     */
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     */
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     */
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     */
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     */
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         */
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         */
238        public long getCodeIndex() {
239            return codeIndex;
240        }
241
242        /**
243         * Sets new code index for variable.
244         *
245         * @param codeIndex
246         */
247        public void setCodeIndex(long codeIndex) {
248            this.codeIndex = codeIndex;
249        }
250
251        /**
252         * Gets variable name.
253         *
254         * @return String
255         */
256        public String getName() {
257            return name;
258        }
259
260        /**
261         * Sets new variable name.
262         *
263         * @param name
264         *            new variable name
265         */
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         */
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         */
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         */
344        public int getLength() {
345            return length;
346        }
347
348        /**
349         * Sets new variable length.
350         *
351         * @param length
352         *            new variable length
353         */
354        public void setLength(int length) {
355            this.length = length;
356        }
357
358        /**
359         * Returns variable slot value.
360         *
361         * @return int
362         */
363        public int getSlot() {
364            return slot;
365        }
366
367        /**
368         * Assigns new slot value.
369         *
370         * @param slot
371         *            new slot value
372         */
373        public void setSlot(int slot) {
374            this.slot = slot;
375        }
376
377        /**
378         * Gets variable type tag value.
379         *
380         * @return byte
381         */
382        public byte getTag() {
383            return tag;
384        }
385
386        /**
387         * Gets variable java type.
388         *
389         * @return String
390         */
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         */
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         */
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