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;
30
31/**
32 * This class provides description of frame.
33 *
34 */
35public class Frame {
36
37    protected long threadID;
38
39    protected Location loc;
40
41    protected long id;
42
43    protected ArrayList<Variable> vars;
44
45    /**
46     * Default constructor.
47     */
48    public Frame() {
49        threadID = -1;
50        id = -1L;
51        loc = new Location();
52        vars = null;
53    }
54
55    /**
56     * Constructor initializing all members of the Frame instance.
57     *
58     * @param threadID
59     *            thread id
60     * @param id
61     *            frame id
62     * @param location
63     *            frame location
64     * @param vars
65     *            list of variables
66     */
67    Frame(long threadID, long id, Location location, ArrayList<Variable> vars) {
68        this.threadID = threadID;
69        this.id = id;
70        this.loc = location;
71        this.vars = vars;
72    }
73
74    /**
75     * Gets thread id.
76     *
77     * @return long
78     */
79    public long getThreadID() {
80        return threadID;
81    }
82
83    /**
84     * Sets new thread id.
85     *
86     * @param threadID
87     *            new thread id
88     */
89    public void setThreadID(long threadID) {
90        this.threadID = threadID;
91    }
92
93    /**
94     * Gets frame id.
95     *
96     * @return long
97     */
98    public long getID() {
99        return id;
100    }
101
102    /**
103     * Sets new frame id.
104     *
105     * @param id
106     *            new frame id
107     */
108    public void setID(long id) {
109        this.id = id;
110    }
111
112    /**
113     * Gets frame location.
114     *
115     * @return Location
116     */
117    public Location getLocation() {
118        return loc;
119    }
120
121    /**
122     * Sets new frame location.
123     *
124     * @param location
125     *            new frame location
126     */
127    public void setLocation(Location location) {
128        this.loc = location;
129    }
130
131    /**
132     * Gets frame variables.
133     *
134     * @return list of frame variables
135     */
136    public ArrayList<Variable> getVars() {
137        return vars;
138    }
139
140    /**
141     * Sets new frame variables.
142     *
143     * @param vars
144     *            list of new frame variables
145     */
146    public void setVars(ArrayList<Variable> vars) {
147        this.vars = vars;
148    }
149
150    /**
151     * Converts Frame object to String.
152     *
153     * @see java.lang.Object#toString()
154     * @return String
155     */
156    @Override
157    public String toString() {
158        String string = "Frame: id=" + id + ", threadID=" + threadID
159                + ", location=" + loc.toString() + "\n";
160        string += "--- Variables ---";
161        for (Variable var : vars) {
162            string += var.toString();
163        }
164        return string;
165    }
166
167    /**
168     * Compares two Frame objects.
169     *
170     * @see java.lang.Object#equals(java.lang.Object)
171     * @return boolean
172     */
173    @Override
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 static final class Variable {
205        private long codeIndex;
206
207        private String name;
208
209        private String signature;
210
211        private String genericSignature;
212
213        private int length;
214
215        private int slot;
216
217        private byte tag;
218
219        private String type;
220
221        /**
222         * Constructor.
223         *
224         */
225        public Variable() {
226            codeIndex = -1;
227            name = "unknown";
228            signature = "unknown";
229            genericSignature = "unknown";
230            length = -1;
231            slot = -1;
232            tag = JDWPConstants.Tag.NO_TAG;
233            type = "unknown type";
234        }
235
236        /**
237         * Gets code index of variable.
238         *
239         * @return long
240         */
241        public long getCodeIndex() {
242            return codeIndex;
243        }
244
245        /**
246         * Sets new code index for variable.
247         *
248         * @param codeIndex
249         */
250        public void setCodeIndex(long codeIndex) {
251            this.codeIndex = codeIndex;
252        }
253
254        /**
255         * Gets variable name.
256         *
257         * @return String
258         */
259        public String getName() {
260            return name;
261        }
262
263        /**
264         * Sets new variable name.
265         *
266         * @param name
267         *            new variable name
268         */
269        public void setName(String name) {
270            this.name = name;
271        }
272
273        /**
274         * Gets signature of the variable reference type.
275         *
276         * @return String
277         */
278        public String getSignature() {
279            return signature;
280        }
281
282        /**
283         * Sets new signature and detects value of a type tag.
284         *
285         * @param signature
286         */
287        public void setSignature(String signature) {
288            switch (signature.charAt(0)) {
289            case '[':
290                tag = JDWPConstants.Tag.ARRAY_TAG;
291                break;
292            case 'B':
293                tag = JDWPConstants.Tag.BYTE_TAG;
294                break;
295            case 'C':
296                tag = JDWPConstants.Tag.CHAR_TAG;
297                break;
298            case 'L':
299                tag = JDWPConstants.Tag.OBJECT_TAG;
300                break;
301            case 'F':
302                tag = JDWPConstants.Tag.FLOAT_TAG;
303                break;
304            case 'D':
305                tag = JDWPConstants.Tag.DOUBLE_TAG;
306                break;
307            case 'I':
308                tag = JDWPConstants.Tag.INT_TAG;
309                break;
310            case 'J':
311                tag = JDWPConstants.Tag.LONG_TAG;
312                break;
313            case 'S':
314                tag = JDWPConstants.Tag.SHORT_TAG;
315                break;
316            case 'V':
317                tag = JDWPConstants.Tag.VOID_TAG;
318                break;
319            case 'Z':
320                tag = JDWPConstants.Tag.BOOLEAN_TAG;
321                break;
322            case 's':
323                tag = JDWPConstants.Tag.STRING_TAG;
324                break;
325            case 't':
326                tag = JDWPConstants.Tag.THREAD_TAG;
327                break;
328            case 'g':
329                tag = JDWPConstants.Tag.THREAD_GROUP_TAG;
330                break;
331            case 'l':
332                tag = JDWPConstants.Tag.CLASS_LOADER_TAG;
333                break;
334            case 'c':
335                tag = JDWPConstants.Tag.CLASS_OBJECT_TAG;
336                break;
337            }
338
339            this.signature = signature;
340        }
341
342        /**
343         * Gets variable generic signature.
344         *
345         * @return the generic signature
346         */
347        public String getGenericSignature() {
348            return genericSignature;
349        }
350
351        /**
352         * Sets new variable generic signature.
353         *
354         * @param genericSignature the generic signature to set
355         */
356        public void setGenericSignature(String genericSignature) {
357            this.genericSignature = genericSignature;
358        }
359
360        /**
361         * Gets variable length.
362         *
363         * @return int
364         */
365        public int getLength() {
366            return length;
367        }
368
369        /**
370         * Sets new variable length.
371         *
372         * @param length
373         *            new variable length
374         */
375        public void setLength(int length) {
376            this.length = length;
377        }
378
379        /**
380         * Returns variable slot value.
381         *
382         * @return int
383         */
384        public int getSlot() {
385            return slot;
386        }
387
388        /**
389         * Assigns new slot value.
390         *
391         * @param slot
392         *            new slot value
393         */
394        public void setSlot(int slot) {
395            this.slot = slot;
396        }
397
398        /**
399         * Gets variable type tag value.
400         *
401         * @return byte
402         */
403        public byte getTag() {
404            return tag;
405        }
406
407        /**
408         * Gets variable java type.
409         *
410         * @return String
411         */
412        public String getType() {
413            switch (tag) {
414            case JDWPConstants.Tag.ARRAY_TAG:
415                switch (signature.charAt(1)) {
416                case 'B':
417                    type = "byte[]";
418                    break;
419                case 'C':
420                    type = "char[]";
421                    break;
422                case 'J':
423                    type = "long[]";
424                    break;
425                case 'F':
426                    type = "float[]";
427                    break;
428                case 'D':
429                    type = "double[]";
430                    break;
431                case 'I':
432                    type = "int[]";
433                    break;
434                case 'S':
435                    type = "short[]";
436                    break;
437                case 'V':
438                    type = "void[]";
439                    break;
440                case 'Z':
441                    type = "boolean[]";
442                    break;
443                case 's':
444                    type = "java.Lang.String[]";
445                    break;
446                case 'L':
447                    type = signature
448                            .substring(2, signature.length() - 1 /*
449                                                                     * skip
450                                                                     * ending
451                                                                     * ';'
452                                                                     */)
453                            .replaceAll("/", ".")
454                            + "[]"; // skip ending ';'
455                    break;
456                }
457                break;
458            case JDWPConstants.Tag.OBJECT_TAG:
459                type = signature
460                        .substring(1, signature.length() - 1 /*
461                                                                 * skip ending
462                                                                 * ';'
463                                                                 */)
464                        .replaceAll("/", "."); // skip ending ';'
465                break;
466            case JDWPConstants.Tag.BOOLEAN_TAG:
467                type = "boolean";
468                break;
469            case JDWPConstants.Tag.BYTE_TAG:
470                type = "byte";
471                break;
472            case JDWPConstants.Tag.CHAR_TAG:
473                type = "char";
474                break;
475            case JDWPConstants.Tag.DOUBLE_TAG:
476                type = "double";
477                break;
478            case JDWPConstants.Tag.FLOAT_TAG:
479                type = "float";
480                break;
481            case JDWPConstants.Tag.INT_TAG:
482                type = "int";
483                break;
484            case JDWPConstants.Tag.LONG_TAG:
485                type = "long";
486                break;
487            case JDWPConstants.Tag.SHORT_TAG:
488                type = "short";
489                break;
490            case JDWPConstants.Tag.STRING_TAG:
491                type = "string";
492                break;
493            default:
494                break;
495            }
496
497            return type;
498        }
499
500        /**
501         * Converts Variable object to String.
502         *
503         * @see java.lang.Object#toString()
504         * @return String
505         */
506        @Override
507        public String toString() {
508            return "Variable: codeIndex=" + codeIndex + ", name=" + name
509                    + ", signature=" + signature + ", length=" + length
510                    + ", slot=" + slot + ", tag="
511                    + JDWPConstants.Tag.getName(tag) + ", type=" + type;
512        }
513
514        /**
515         * Compares two Variable objects.
516         *
517         * @see java.lang.Object#equals(java.lang.Object)
518         * @return boolean
519         */
520        @Override
521        public boolean equals(Object obj) {
522            if (!(obj instanceof Variable)) {
523                return false;
524            }
525
526            if (this.getClass() != obj.getClass()) {
527                return false;
528            }
529
530            Variable var = (Variable) obj;
531            return this.codeIndex == var.codeIndex
532                    && this.name.equals(var.name)
533                    && this.signature.equals(var.signature)
534                    && this.length == var.length && this.slot == var.slot
535                    && this.tag == var.tag && this.type.equals(var.type);
536
537        }
538    }
539}
540