AccessFlags.java revision 00fc68adf2e39aeb9fed35293f2576bbe729ec4b
1/*
2 * [The "BSD licence"]
3 * Copyright (c) 2010 Ben Gruver (JesusFreke)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29package org.jf.dexlib.Util;
30
31import java.util.ArrayList;
32import java.util.HashMap;
33import java.util.List;
34
35public enum AccessFlags
36{
37    PUBLIC(0x1, "public", true, true, true),
38    PRIVATE(0x2, "private", true, true, true),
39    PROTECTED(0x4, "protected", true, true, true),
40    STATIC(0x8, "static", true, true, true),
41    FINAL(0x10, "final", true, true, true),
42    SYNCHRONIZED(0x20, "synchronized", false, true, false),
43    VOLATILE(0x40, "volatile", false, false, true),
44    BRIDGE(0x40, "bridge", false, true, false),
45    TRANSIENT(0x80, "transient", false, false, true),
46    VARARGS(0x80, "varargs", false, true, false),
47    NATIVE(0x100, "native", false, true, false),
48    INTERFACE(0x200, "interface", true, false, false),
49    ABSTRACT(0x400, "abstract", true, true, false),
50    STRICTFP(0x800, "strictfp", false, true, false),
51    SYNTHETIC(0x1000, "synthetic", true, true, true),
52    ANNOTATION(0x2000, "annotation", true, false, false),
53    ENUM(0x4000, "enum", true, false, true),
54    CONSTRUCTOR(0x10000, "constructor", false, true, false),
55    DECLARED_SYNCHRONIZED(0x20000, "declared-synchronized", false, true, false);
56
57    private int value;
58    private String accessFlagName;
59    private boolean validForClass;
60    private boolean validForMethod;
61    private boolean validForField;
62
63    private static HashMap<String, AccessFlags> accessFlagsByName;
64
65    static {
66        accessFlagsByName = new HashMap<String, AccessFlags>();
67        for (AccessFlags accessFlag: AccessFlags.values()) {
68            accessFlagsByName.put(accessFlag.accessFlagName, accessFlag);
69        }
70    }
71
72    private AccessFlags(int value, String accessFlagName, boolean validForClass, boolean validForMethod,
73                        boolean validForField) {
74        this.value = value;
75        this.accessFlagName = accessFlagName;
76        this.validForClass = validForClass;
77        this.validForMethod = validForMethod;
78        this.validForField = validForField;
79    }
80
81    public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) {
82        int size = 0;
83        for (AccessFlags accessFlag: AccessFlags.values()) {
84            if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
85                size++;
86            }
87        }
88
89        AccessFlags[] accessFlags = new AccessFlags[size];
90        int accessFlagsPosition = 0;
91        for (AccessFlags accessFlag: AccessFlags.values()) {
92            if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
93                accessFlags[accessFlagsPosition++] = accessFlag;
94            }
95        }
96        return accessFlags;
97    }
98
99    private static String formatAccessFlags(AccessFlags[] accessFlags) {
100        int size = 0;
101        for (AccessFlags accessFlag: accessFlags) {
102            size += accessFlag.toString().length() + 1;
103        }
104
105        StringBuilder sb = new StringBuilder(size);
106        for (AccessFlags accessFlag: accessFlags) {
107            sb.append(accessFlag.toString());
108            sb.append(" ");
109        }
110        if (accessFlags.length > 0) {
111            sb.delete(sb.length() - 1, sb.length());
112        }
113        return sb.toString();
114    }
115
116    public static String formatAccessFlagsForClass(int accessFlagValue) {
117        return formatAccessFlags(getAccessFlagsForClass(accessFlagValue));
118    }
119
120    public static AccessFlags[] getAccessFlagsForMethod(int accessFlagValue) {
121        int size = 0;
122        for (AccessFlags accessFlag: AccessFlags.values()) {
123            if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) {
124                size++;
125            }
126        }
127
128        AccessFlags[] accessFlags = new AccessFlags[size];
129        int accessFlagsPosition = 0;
130        for (AccessFlags accessFlag: AccessFlags.values()) {
131            if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) {
132                accessFlags[accessFlagsPosition++] = accessFlag;
133            }
134        }
135        return accessFlags;
136    }
137
138    public static String formatAccessFlagsForMethod(int accessFlagValue) {
139        return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue));
140    }
141
142    public static AccessFlags[] getAccessFlagsForField(int accessFlagValue) {
143        int size = 0;
144        for (AccessFlags accessFlag: AccessFlags.values()) {
145            if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) {
146                size++;
147            }
148        }
149
150        AccessFlags[] accessFlags = new AccessFlags[size];
151        int accessFlagsPosition = 0;
152        for (AccessFlags accessFlag: AccessFlags.values()) {
153            if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) {
154                accessFlags[accessFlagsPosition++] = accessFlag;
155            }
156        }
157        return accessFlags;
158    }
159
160    public static String formatAccessFlagsForField(int accessFlagValue) {
161        return formatAccessFlags(getAccessFlagsForField(accessFlagValue));
162    }
163
164    public static AccessFlags getAccessFlag(String accessFlag) {
165        return accessFlagsByName.get(accessFlag);
166    }
167
168    public int getValue() {
169        return value;
170    }
171
172    public String toString() {
173        return accessFlagName;
174    }
175}
176