001: /*
002: * Copyright 2004 Brian S O'Neill
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.cojen.classfile;
018:
019: import java.lang.reflect.Modifier;
020:
021: /**
022: * The Modifiers class is an immutable wrapper around a modifier bitmask. The
023: * methods provided to manipulate the bitmask ensure that it is always
024: * legal. i.e. setting it public automatically clears it from being private or
025: * protected.
026: *
027: * @author Brian S O'Neill
028: */
029: public class Modifiers {
030: public static final Modifiers NONE;
031: public static final Modifiers PUBLIC;
032: public static final Modifiers PUBLIC_ABSTRACT;
033: public static final Modifiers PUBLIC_STATIC;
034: public static final Modifiers PROTECTED;
035: public static final Modifiers PRIVATE;
036:
037: static {
038: NONE = new Modifiers(0);
039: PUBLIC = new Modifiers(Modifier.PUBLIC);
040: PUBLIC_ABSTRACT = new Modifiers(Modifier.PUBLIC
041: | Modifier.ABSTRACT);
042: PUBLIC_STATIC = new Modifiers(Modifier.PUBLIC | Modifier.STATIC);
043: PROTECTED = new Modifiers(Modifier.PROTECTED);
044: PRIVATE = new Modifiers(Modifier.PRIVATE);
045: }
046:
047: /**
048: * Returns a Modifiers object with the given bitmask.
049: */
050: public static Modifiers getInstance(int bitmask) {
051: switch (bitmask) {
052: case 0:
053: return NONE;
054: case Modifier.PUBLIC:
055: return PUBLIC;
056: case Modifier.PUBLIC | Modifier.ABSTRACT:
057: return PUBLIC_ABSTRACT;
058: case Modifier.PUBLIC | Modifier.STATIC:
059: return PUBLIC_STATIC;
060: case Modifier.PROTECTED:
061: return PROTECTED;
062: case Modifier.PRIVATE:
063: return PRIVATE;
064: }
065:
066: return new Modifiers(bitmask);
067: }
068:
069: private static int toPublic(int bitmask, boolean b) {
070: if (b) {
071: return (bitmask | Modifier.PUBLIC)
072: & (~Modifier.PROTECTED & ~Modifier.PRIVATE);
073: } else {
074: return bitmask & ~Modifier.PUBLIC;
075: }
076: }
077:
078: private static int toPrivate(int bitmask, boolean b) {
079: if (b) {
080: return (bitmask | Modifier.PRIVATE)
081: & (~Modifier.PUBLIC & ~Modifier.PROTECTED);
082: } else {
083: return bitmask & ~Modifier.PRIVATE;
084: }
085: }
086:
087: private static int toProtected(int bitmask, boolean b) {
088: if (b) {
089: return (bitmask | Modifier.PROTECTED)
090: & (~Modifier.PUBLIC & ~Modifier.PRIVATE);
091: } else {
092: return bitmask & ~Modifier.PROTECTED;
093: }
094: }
095:
096: private static int toStatic(int bitmask, boolean b) {
097: if (b) {
098: return bitmask | Modifier.STATIC;
099: } else {
100: return bitmask & ~Modifier.STATIC;
101: }
102: }
103:
104: private static int toFinal(int bitmask, boolean b) {
105: if (b) {
106: return (bitmask | Modifier.FINAL)
107: & (~Modifier.INTERFACE & ~Modifier.ABSTRACT);
108: } else {
109: return bitmask & ~Modifier.FINAL;
110: }
111: }
112:
113: private static int toSynchronized(int bitmask, boolean b) {
114: if (b) {
115: return (bitmask | Modifier.SYNCHRONIZED)
116: & (~Modifier.VOLATILE & ~Modifier.TRANSIENT & ~Modifier.INTERFACE);
117: } else {
118: return bitmask & ~Modifier.SYNCHRONIZED;
119: }
120: }
121:
122: private static int toVolatile(int bitmask, boolean b) {
123: if (b) {
124: return (bitmask | Modifier.VOLATILE)
125: & (~Modifier.SYNCHRONIZED & ~Modifier.NATIVE
126: & ~Modifier.INTERFACE & ~Modifier.ABSTRACT & ~Modifier.STRICT);
127: } else {
128: return bitmask & ~Modifier.VOLATILE;
129: }
130: }
131:
132: private static int toTransient(int bitmask, boolean b) {
133: if (b) {
134: return (bitmask | Modifier.TRANSIENT)
135: & (~Modifier.SYNCHRONIZED & ~Modifier.NATIVE
136: & ~Modifier.INTERFACE & ~Modifier.ABSTRACT & ~Modifier.STRICT);
137: } else {
138: return bitmask & ~Modifier.TRANSIENT;
139: }
140: }
141:
142: private static int toNative(int bitmask, boolean b) {
143: if (b) {
144: return (bitmask | Modifier.NATIVE)
145: & (~Modifier.VOLATILE & ~Modifier.TRANSIENT
146: & ~Modifier.INTERFACE & ~Modifier.ABSTRACT & ~Modifier.STRICT);
147: } else {
148: return bitmask & ~Modifier.NATIVE;
149: }
150: }
151:
152: private static int toInterface(int bitmask, boolean b) {
153: if (b) {
154: return (bitmask | (Modifier.INTERFACE | Modifier.ABSTRACT))
155: & (~Modifier.FINAL & ~Modifier.SYNCHRONIZED
156: & ~Modifier.VOLATILE & ~Modifier.TRANSIENT & ~Modifier.NATIVE);
157: } else {
158: return bitmask & ~Modifier.INTERFACE;
159: }
160: }
161:
162: private static int toAbstract(int bitmask, boolean b) {
163: if (b) {
164: return (bitmask | Modifier.ABSTRACT)
165: & (~Modifier.FINAL & ~Modifier.VOLATILE
166: & ~Modifier.TRANSIENT & ~Modifier.NATIVE
167: & ~Modifier.SYNCHRONIZED & ~Modifier.STRICT);
168: } else {
169: return bitmask & ~Modifier.ABSTRACT & ~Modifier.INTERFACE;
170: }
171: }
172:
173: private static int toStrict(int bitmask, boolean b) {
174: if (b) {
175: return bitmask | Modifier.STRICT;
176: } else {
177: return bitmask & ~Modifier.STRICT;
178: }
179: }
180:
181: private static int toBridge(int bitmask, boolean b) {
182: // Bridge re-uses the Modifier.VOLATILE modifier, which used to only
183: // apply to fields.
184: if (b) {
185: return (bitmask | Modifier.VOLATILE)
186: & (~Modifier.NATIVE & ~Modifier.INTERFACE & ~Modifier.ABSTRACT);
187: } else {
188: return bitmask & ~Modifier.VOLATILE;
189: }
190: }
191:
192: private static int toEnum(int bitmask, boolean b) {
193: // Enum re-uses the Modifier.NATIVE modifier, which used to only apply
194: // to methods.
195: if (b) {
196: return (bitmask | Modifier.NATIVE)
197: & (~Modifier.ABSTRACT & ~Modifier.INTERFACE
198: & ~Modifier.STRICT & ~Modifier.SYNCHRONIZED);
199: } else {
200: return bitmask & ~Modifier.NATIVE;
201: }
202: }
203:
204: private static int toVarArgs(int bitmask, boolean b) {
205: // Enum re-uses the Modifier.TRANSIENT modifier, which used to only
206: // apply to fields.
207: if (b) {
208: return (bitmask | Modifier.TRANSIENT)
209: & (~Modifier.INTERFACE & ~Modifier.VOLATILE);
210: } else {
211: return bitmask & ~Modifier.TRANSIENT;
212: }
213: }
214:
215: private final int mBitmask;
216:
217: private Modifiers(int bitmask) {
218: mBitmask = bitmask;
219: }
220:
221: /**
222: * Returns the bitmask.
223: */
224: public final int getBitmask() {
225: return mBitmask;
226: }
227:
228: public boolean isPublic() {
229: return Modifier.isPublic(mBitmask);
230: }
231:
232: public boolean isPrivate() {
233: return Modifier.isPrivate(mBitmask);
234: }
235:
236: public boolean isProtected() {
237: return Modifier.isProtected(mBitmask);
238: }
239:
240: public boolean isStatic() {
241: return Modifier.isStatic(mBitmask);
242: }
243:
244: public boolean isFinal() {
245: return Modifier.isFinal(mBitmask);
246: }
247:
248: public boolean isSynchronized() {
249: return Modifier.isSynchronized(mBitmask);
250: }
251:
252: public boolean isVolatile() {
253: return Modifier.isVolatile(mBitmask);
254: }
255:
256: public boolean isTransient() {
257: return Modifier.isTransient(mBitmask);
258: }
259:
260: public boolean isNative() {
261: return Modifier.isNative(mBitmask);
262: }
263:
264: public boolean isInterface() {
265: return Modifier.isInterface(mBitmask);
266: }
267:
268: public boolean isAbstract() {
269: return Modifier.isAbstract(mBitmask);
270: }
271:
272: public boolean isStrict() {
273: return Modifier.isStrict(mBitmask);
274: }
275:
276: public boolean isBridge() {
277: return Modifier.isVolatile(mBitmask);
278: }
279:
280: public boolean isEnum() {
281: return Modifier.isNative(mBitmask);
282: }
283:
284: public boolean isVarArgs() {
285: return Modifier.isTransient(mBitmask);
286: }
287:
288: /**
289: * When set public, the bitmask is cleared from being private or protected.
290: *
291: * @param b true to set public, false otherwise
292: */
293: public Modifiers toPublic(boolean b) {
294: return convert(toPublic(mBitmask, b));
295: }
296:
297: /**
298: * When set private, the bitmask is cleared from being public or protected.
299: *
300: * @param b true to set private, false otherwise
301: */
302: public Modifiers toPrivate(boolean b) {
303: return convert(toPrivate(mBitmask, b));
304: }
305:
306: /**
307: * When set protected, the bitmask is cleared from being public or private.
308: *
309: * @param b true to set protected, false otherwise
310: */
311: public Modifiers toProtected(boolean b) {
312: return convert(toProtected(mBitmask, b));
313: }
314:
315: /**
316: * @param b true to set static, false otherwise
317: */
318: public Modifiers toStatic(boolean b) {
319: return convert(toStatic(mBitmask, b));
320: }
321:
322: /**
323: * When set final, the bitmask is cleared from being an interface or
324: * abstract.
325: *
326: * @param b true to set final, false otherwise
327: */
328: public Modifiers toFinal(boolean b) {
329: return convert(toFinal(mBitmask, b));
330: }
331:
332: /**
333: * When set synchronized, non-method settings are cleared.
334: *
335: * @param b true to set synchronized, false otherwise
336: */
337: public Modifiers toSynchronized(boolean b) {
338: return convert(toSynchronized(mBitmask, b));
339: }
340:
341: /**
342: * When set volatile, non-field settings are cleared.
343: *
344: * @param b true to set volatile, false otherwise
345: */
346: public Modifiers toVolatile(boolean b) {
347: return convert(toVolatile(mBitmask, b));
348: }
349:
350: /**
351: * When set transient, non-field settings are cleared.
352: *
353: * @param b true to set transient, false otherwise
354: */
355: public Modifiers toTransient(boolean b) {
356: return convert(toTransient(mBitmask, b));
357: }
358:
359: /**
360: * When set native, non-native-method settings are cleared.
361: *
362: * @param b true to set native, false otherwise
363: */
364: public Modifiers toNative(boolean b) {
365: return convert(toNative(mBitmask, b));
366: }
367:
368: /**
369: * When set as an interface, non-interface settings are cleared and the
370: * bitmask is set abstract.
371: *
372: * @param b true to set interface, false otherwise
373: */
374: public Modifiers toInterface(boolean b) {
375: return convert(toInterface(mBitmask, b));
376: }
377:
378: /**
379: * When set abstract, the bitmask is cleared from being final, volatile,
380: * transient, native, synchronized, and strictfp. When cleared from being
381: * abstract, the bitmask is also cleared from being an interface.
382: *
383: * @param b true to set abstract, false otherwise
384: */
385: public Modifiers toAbstract(boolean b) {
386: return convert(toAbstract(mBitmask, b));
387: }
388:
389: /**
390: * @param b true to set strictfp, false otherwise
391: */
392: public Modifiers toStrict(boolean b) {
393: return convert(toStrict(mBitmask, b));
394: }
395:
396: /**
397: * Used to identify if a method is a bridge method.
398: *
399: * @param b true to set bridge, false otherwise
400: */
401: public Modifiers toBridge(boolean b) {
402: return convert(toBridge(mBitmask, b));
403: }
404:
405: /**
406: * Used to identify if a field is an enum constant.
407: *
408: * @param b true to set enum, false otherwise
409: */
410: public Modifiers toEnum(boolean b) {
411: return convert(toEnum(mBitmask, b));
412: }
413:
414: /**
415: * Used to identify if a method accepts a variable amount of
416: * arguments.
417: *
418: * @param b true to set varargs, false otherwise
419: */
420: public Modifiers toVarArgs(boolean b) {
421: return convert(toVarArgs(mBitmask, b));
422: }
423:
424: public int hashCode() {
425: return mBitmask;
426: }
427:
428: public boolean equals(Object obj) {
429: if (this == obj) {
430: return true;
431: }
432: if (obj instanceof Modifiers) {
433: Modifiers other = (Modifiers) obj;
434: return mBitmask == other.mBitmask;
435: }
436: return false;
437: }
438:
439: /**
440: * Returns the string value generated by the Modifier class.
441: *
442: * @see java.lang.reflect.Modifier#toString()
443: */
444: public String toString() {
445: return Modifier.toString(mBitmask);
446: }
447:
448: private Modifiers convert(int bitmask) {
449: return bitmask == mBitmask ? this : getInstance(bitmask);
450: }
451: }
|