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    @Override
284    public boolean equals(Object obj) {
285        if (!(obj instanceof Field)) {
286            return false;
287        }
288
289        if (this.getClass() != obj.getClass()) {
290            return false;
291        }
292
293        Field field = (Field) obj;
294        return this.id == field.id && this.classID == field.classID
295                && this.name.equals(field.name)
296                && this.signature.equals(field.signature)
297                && this.modBits == field.modBits;
298    }
299
300    /**
301     * Converts Field object to String.
302     *
303     * @see java.lang.Object#toString()
304     * @return String
305     */
306    @Override
307    public String toString() {
308        String str = "Field: id=" + id + ", classID=" + classID + ", name='"
309                + name + "', signature='" + signature + "', modBits=";
310        String access = "";
311        if ((this.modBits & JDWPConstants.FieldAccess.ACC_PRIVATE) == JDWPConstants.FieldAccess.ACC_PRIVATE) {
312            access += JDWPConstants.FieldAccess
313                    .getName(JDWPConstants.FieldAccess.ACC_PRIVATE)
314                    + " ";
315        } else if ((this.modBits & JDWPConstants.FieldAccess.ACC_PROTECTED) == JDWPConstants.FieldAccess.ACC_PROTECTED) {
316            access += JDWPConstants.FieldAccess
317                    .getName(JDWPConstants.FieldAccess.ACC_PROTECTED)
318                    + " ";
319        } else if ((this.modBits & JDWPConstants.FieldAccess.ACC_PUBLIC) == JDWPConstants.FieldAccess.ACC_PUBLIC) {
320            access += JDWPConstants.FieldAccess
321                    .getName(JDWPConstants.FieldAccess.ACC_PUBLIC)
322                    + " ";
323        }
324        if ((this.modBits & JDWPConstants.FieldAccess.ACC_FINAL) == JDWPConstants.FieldAccess.ACC_FINAL) {
325            access += JDWPConstants.FieldAccess
326                    .getName(JDWPConstants.FieldAccess.ACC_FINAL)
327                    + " ";
328        }
329        if ((this.modBits & JDWPConstants.FieldAccess.ACC_STATIC) == JDWPConstants.FieldAccess.ACC_STATIC) {
330            access += JDWPConstants.FieldAccess
331                    .getName(JDWPConstants.FieldAccess.ACC_STATIC)
332                    + " ";
333        }
334        if ((this.modBits & JDWPConstants.FieldAccess.ACC_TRANSIENT) == JDWPConstants.FieldAccess.ACC_TRANSIENT) {
335            access += JDWPConstants.FieldAccess
336                    .getName(JDWPConstants.FieldAccess.ACC_TRANSIENT)
337                    + " ";
338        }
339        if ((this.modBits & JDWPConstants.FieldAccess.ACC_VOLATILE) == JDWPConstants.FieldAccess.ACC_VOLATILE) {
340            access += JDWPConstants.FieldAccess
341                    .getName(JDWPConstants.FieldAccess.ACC_VOLATILE)
342                    + " ";
343        }
344
345        return str + access;
346    }
347
348    /**
349     * Tells whether this field is private.
350     *
351     * @return boolean
352     */
353    public boolean isPrivate() {
354        return (modBits & JDWPConstants.FieldAccess.ACC_PRIVATE) == JDWPConstants.FieldAccess.ACC_PRIVATE;
355    }
356
357    /**
358     * Tells whether this field is protected.
359     *
360     * @return boolean
361     */
362    public boolean isProtected() {
363        return (modBits & JDWPConstants.FieldAccess.ACC_PROTECTED) == JDWPConstants.FieldAccess.ACC_PROTECTED;
364    }
365
366    /**
367     * Tells whether this field is public.
368     *
369     * @return boolean
370     */
371    public boolean isPublic() {
372        return (modBits & JDWPConstants.FieldAccess.ACC_PUBLIC) == JDWPConstants.FieldAccess.ACC_PUBLIC;
373    }
374
375    /**
376     * Tells whether this field is final.
377     *
378     * @return boolean
379     */
380    public boolean isFinal() {
381        return (modBits & JDWPConstants.FieldAccess.ACC_FINAL) == JDWPConstants.FieldAccess.ACC_FINAL;
382    }
383
384    /**
385     * Tells whether this field is static.
386     *
387     * @return boolean
388     */
389    public boolean isStatic() {
390        return (modBits & JDWPConstants.FieldAccess.ACC_STATIC) == JDWPConstants.FieldAccess.ACC_STATIC;
391    }
392}
393