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 03.05.2005
25 */
26
27package org.apache.harmony.jpda.tests.framework.jdwp;
28
29/**
30 * This class provides description of class field.
31 *
32 */
33public final class Field {
34
35    private long id;
36
37    private long classID;
38
39    private String name;
40
41    private String signature;
42
43    private int modBits;
44
45    private byte tag;
46
47    /**
48     * Default constructor.
49     */
50    public Field() {
51        id = -1;
52        classID = -1;
53        name = "unknown";
54        signature = "unknown";
55        modBits = -1;
56    }
57
58    /**
59     * Constructor initializing all members of the Field instance.
60     *
61     * @param id
62     *            field id
63     * @param classID
64     *            class id
65     * @param name
66     *            field name
67     * @param signature
68     *            signature signature of the field class
69     * @param modBits
70     *            field modifiers
71     */
72    public Field(long id, long classID, String name, String signature,
73            int modBits) {
74        this.id = id;
75        this.classID = classID;
76        this.name = name;
77        this.modBits = modBits;
78        setSignature(signature);
79    }
80
81    /**
82     * Sets signature and detects type tag from it.
83     *
84     * @param signature
85     *            signature of the field class
86     */
87    private void setSignature(String signature) {
88        switch (signature.charAt(0)) {
89        case '[':
90            tag = JDWPConstants.Tag.ARRAY_TAG;
91            break;
92        case 'B':
93            tag = JDWPConstants.Tag.BYTE_TAG;
94            break;
95        case 'C':
96            tag = JDWPConstants.Tag.CHAR_TAG;
97            break;
98        case 'L':
99            tag = JDWPConstants.Tag.OBJECT_TAG;
100            break;
101        case 'F':
102            tag = JDWPConstants.Tag.FLOAT_TAG;
103            break;
104        case 'D':
105            tag = JDWPConstants.Tag.DOUBLE_TAG;
106            break;
107        case 'I':
108            tag = JDWPConstants.Tag.INT_TAG;
109            break;
110        case 'J':
111            tag = JDWPConstants.Tag.LONG_TAG;
112            break;
113        case 'S':
114            tag = JDWPConstants.Tag.SHORT_TAG;
115            break;
116        case 'V':
117            tag = JDWPConstants.Tag.VOID_TAG;
118            break;
119        case 'Z':
120            tag = JDWPConstants.Tag.BOOLEAN_TAG;
121            break;
122        case 's':
123            tag = JDWPConstants.Tag.STRING_TAG;
124            break;
125        case 't':
126            tag = JDWPConstants.Tag.THREAD_TAG;
127            break;
128        case 'g':
129            tag = JDWPConstants.Tag.THREAD_GROUP_TAG;
130            break;
131        case 'l':
132            tag = JDWPConstants.Tag.CLASS_LOADER_TAG;
133            break;
134        case 'c':
135            tag = JDWPConstants.Tag.CLASS_OBJECT_TAG;
136            break;
137        }
138
139        this.signature = signature;
140    }
141
142    /**
143     * Gets field id.
144     *
145     * @return long
146     */
147    public long getID() {
148        return this.id;
149    }
150
151    /**
152     * Gets id of the field reference type.
153     *
154     * @return long
155     */
156    public long getClassID() {
157        return classID;
158    }
159
160    /**
161     * Gets field name.
162     *
163     * @return String
164     */
165    public String getName() {
166        return name;
167    }
168
169    /**
170     * Gets signature of field type.
171     *
172     * @return String
173     */
174    public String getSignature() {
175        return signature;
176    }
177
178    /**
179     * Gets field modifiers.
180     *
181     * @return int
182     */
183    public int getModBits() {
184        return modBits;
185    }
186
187    /**
188     * Gets field java type.
189     *
190     * @return String
191     */
192    public String getType() {
193        String type = "unknown type";
194        switch (tag) {
195        case JDWPConstants.Tag.ARRAY_TAG:
196            switch (signature.charAt(1)) {
197            case 'B':
198                type = "byte[]";
199                break;
200            case 'C':
201                type = "char[]";
202                break;
203            case 'J':
204                type = "long[]";
205                break;
206            case 'F':
207                type = "float[]";
208                break;
209            case 'D':
210                type = "double[]";
211                break;
212            case 'I':
213                type = "int[]";
214                break;
215            case 'S':
216                type = "short[]";
217                break;
218            case 'V':
219                type = "void[]";
220                break;
221            case 'Z':
222                type = "boolean[]";
223                break;
224            case 's':
225                type = "java.Lang.String[]";
226                break;
227            case 'L':
228                type = signature
229                        .substring(2, signature.length() - 1 /*
230                                                                 * skip ending
231                                                                 * ';'
232                                                                 */)
233                        .replaceAll("/", ".")
234                        + "[]"; // skip ending ';'
235                break;
236            }
237            break;
238        case JDWPConstants.Tag.OBJECT_TAG:
239            type = signature
240                    .substring(1, signature.length() - 1 /* skip ending ';' */)
241                    .replaceAll("/", "."); // skip ending ';'
242            break;
243        case JDWPConstants.Tag.BOOLEAN_TAG:
244            type = "boolean";
245            break;
246        case JDWPConstants.Tag.BYTE_TAG:
247            type = "byte";
248            break;
249        case JDWPConstants.Tag.CHAR_TAG:
250            type = "char";
251            break;
252        case JDWPConstants.Tag.DOUBLE_TAG:
253            type = "double";
254            break;
255        case JDWPConstants.Tag.FLOAT_TAG:
256            type = "float";
257            break;
258        case JDWPConstants.Tag.INT_TAG:
259            type = "int";
260            break;
261        case JDWPConstants.Tag.LONG_TAG:
262            type = "long";
263            break;
264        case JDWPConstants.Tag.SHORT_TAG:
265            type = "short";
266            break;
267        case JDWPConstants.Tag.STRING_TAG:
268            type = "string";
269            break;
270        default:
271            break;
272        }
273
274        return type;
275    }
276
277    /**
278     * Compares two Field objects.
279     *
280     * @see java.lang.Object#equals(java.lang.Object)
281     * @return boolean
282     */
283    public boolean equals(Object obj) {
284        if (!(obj instanceof Field)) {
285            return false;
286        }
287
288        if (this.getClass() != obj.getClass()) {
289            return false;
290        }
291
292        Field field = (Field) obj;
293        return this.id == field.id && this.classID == field.classID
294                && this.name.equals(field.name)
295                && this.signature.equals(field.signature)
296                && this.modBits == field.modBits;
297    }
298
299    /**
300     * Converts Field object to String.
301     *
302     * @see java.lang.Object#toString()
303     * @return String
304     */
305    public String toString() {
306        String str = "Field: id=" + id + ", classID=" + classID + ", name='"
307                + name + "', signature='" + signature + "', modBits=";
308        String access = "";
309        if ((this.modBits & JDWPConstants.FieldAccess.ACC_PRIVATE) == JDWPConstants.FieldAccess.ACC_PRIVATE) {
310            access += JDWPConstants.FieldAccess
311                    .getName(JDWPConstants.FieldAccess.ACC_PRIVATE)
312                    + " ";
313        } else if ((this.modBits & JDWPConstants.FieldAccess.ACC_PROTECTED) == JDWPConstants.FieldAccess.ACC_PROTECTED) {
314            access += JDWPConstants.FieldAccess
315                    .getName(JDWPConstants.FieldAccess.ACC_PROTECTED)
316                    + " ";
317        } else if ((this.modBits & JDWPConstants.FieldAccess.ACC_PUBLIC) == JDWPConstants.FieldAccess.ACC_PUBLIC) {
318            access += JDWPConstants.FieldAccess
319                    .getName(JDWPConstants.FieldAccess.ACC_PUBLIC)
320                    + " ";
321        }
322        if ((this.modBits & JDWPConstants.FieldAccess.ACC_FINAL) == JDWPConstants.FieldAccess.ACC_FINAL) {
323            access += JDWPConstants.FieldAccess
324                    .getName(JDWPConstants.FieldAccess.ACC_FINAL)
325                    + " ";
326        }
327        if ((this.modBits & JDWPConstants.FieldAccess.ACC_STATIC) == JDWPConstants.FieldAccess.ACC_STATIC) {
328            access += JDWPConstants.FieldAccess
329                    .getName(JDWPConstants.FieldAccess.ACC_STATIC)
330                    + " ";
331        }
332        if ((this.modBits & JDWPConstants.FieldAccess.ACC_TRANSIENT) == JDWPConstants.FieldAccess.ACC_TRANSIENT) {
333            access += JDWPConstants.FieldAccess
334                    .getName(JDWPConstants.FieldAccess.ACC_TRANSIENT)
335                    + " ";
336        }
337        if ((this.modBits & JDWPConstants.FieldAccess.ACC_VOLATILE) == JDWPConstants.FieldAccess.ACC_VOLATILE) {
338            access += JDWPConstants.FieldAccess
339                    .getName(JDWPConstants.FieldAccess.ACC_VOLATILE)
340                    + " ";
341        }
342
343        return str + access;
344    }
345
346    /**
347     * Tells whether this field is private.
348     *
349     * @return boolean
350     */
351    public boolean isPrivate() {
352        return (modBits & JDWPConstants.FieldAccess.ACC_PRIVATE) == JDWPConstants.FieldAccess.ACC_PRIVATE;
353    }
354
355    /**
356     * Tells whether this field is protected.
357     *
358     * @return boolean
359     */
360    public boolean isProtected() {
361        return (modBits & JDWPConstants.FieldAccess.ACC_PROTECTED) == JDWPConstants.FieldAccess.ACC_PROTECTED;
362    }
363
364    /**
365     * Tells whether this field is public.
366     *
367     * @return boolean
368     */
369    public boolean isPublic() {
370        return (modBits & JDWPConstants.FieldAccess.ACC_PUBLIC) == JDWPConstants.FieldAccess.ACC_PUBLIC;
371    }
372
373    /**
374     * Tells whether this field is final.
375     *
376     * @return boolean
377     */
378    public boolean isFinal() {
379        return (modBits & JDWPConstants.FieldAccess.ACC_FINAL) == JDWPConstants.FieldAccess.ACC_FINAL;
380    }
381
382    /**
383     * Tells whether this field is static.
384     *
385     * @return boolean
386     */
387    public boolean isStatic() {
388        return (modBits & JDWPConstants.FieldAccess.ACC_STATIC) == JDWPConstants.FieldAccess.ACC_STATIC;
389    }
390}
391