001    /*
002     * Copyright 2002-2004 The Apache Software Foundation
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    package org.apache.commons.clazz;
017    
018    import java.lang.reflect.Modifier;
019    
020    /**
021     * <code>ClazzModifiers</code> defines the modifiers in a manipulable way.
022     *
023     * @author <a href="mailto:scolebourne@apache.org">Stephen Colebourne</a>
024     * @version $Id: ClazzModifiers.java 155436 2005-02-26 13:17:48Z dirkv $
025     */
026    public class ClazzModifiers {
027        
028        /**
029         * The <code>int</code> value representing the <code>public</code> 
030         * modifier.
031         */    
032        public static final int PUBLIC           = Modifier.PUBLIC;
033    
034        /**
035         * The <code>int</code> value representing the <code>private</code> 
036         * modifier.
037         */    
038        public static final int PRIVATE          = Modifier.PRIVATE;
039    
040        /**
041         * The <code>int</code> value representing the <code>protected</code> 
042         * modifier.
043         */    
044        public static final int PROTECTED        = Modifier.PROTECTED;
045    
046        /**
047         * The <code>int</code> value representing the <code>static</code> 
048         * modifier.
049         */    
050        public static final int STATIC           = Modifier.STATIC;
051    
052        /**
053         * The <code>int</code> value representing the <code>final</code> 
054         * modifier.
055         */    
056        public static final int FINAL            = Modifier.FINAL;
057    
058        /**
059         * The <code>int</code> value representing the <code>synchronized</code> 
060         * modifier.
061         */    
062        public static final int SYNCHRONIZED     = Modifier.SYNCHRONIZED;
063    
064        /**
065         * The <code>int</code> value representing the <code>volatile</code> 
066         * modifier.
067         */    
068        public static final int VOLATILE         = Modifier.VOLATILE;
069    
070        /**
071         * The <code>int</code> value representing the <code>transient</code> 
072         * modifier.
073         */    
074        public static final int TRANSIENT        = Modifier.TRANSIENT;
075    
076        /**
077         * The <code>int</code> value representing the <code>native</code> 
078         * modifier.
079         */    
080        public static final int NATIVE           = Modifier.NATIVE;
081    
082        /**
083         * The <code>int</code> value representing the <code>interface</code> 
084         * modifier.
085         */    
086        public static final int INTERFACE        = Modifier.INTERFACE;
087    
088        /**
089         * The <code>int</code> value representing the <code>abstract</code> 
090         * modifier.
091         */    
092        public static final int ABSTRACT         = Modifier.ABSTRACT;
093    
094        /**
095         * The <code>int</code> value representing the <code>strictfp</code> 
096         * modifier.
097         */    
098        public static final int STRICT           = Modifier.STRICT;
099    
100        /** The modifiers */
101        private int modifiers = 0;
102        
103        /**
104         * Constructor.
105         *
106         * @param modifiers  the modifiers
107         */
108        public ClazzModifiers(int modifiers) {
109            super();
110            setFlags(modifiers);
111        }
112        
113        /**
114         * Copy constructor.
115         *
116         * @param modifiers  the modifiers object
117         * @throws IllegalArgumentException if the modifiers object is null
118         */
119        public ClazzModifiers(ClazzModifiers modifiers) {
120            super();
121            if (modifiers == null) {
122                throw new IllegalArgumentException(
123                        "The modifiers must not be null");
124            }
125            setFlags(modifiers.getFlags());
126        }
127        
128        //--------------------------------------------------------------------------
129        
130        /**
131         * Gets  the modifier flags, which can be accessed via java.lang.reflect.
132         * Modifier.
133         * 
134         * @return the modifier flags
135         */
136        public int getFlags() {
137            return modifiers;
138        }
139    
140        /**
141         * Sets the modifier flags.
142         * 
143         * @param modifiers  the modifier flags to update to
144         */
145        public void setFlags(int modifiers) {
146            this.modifiers = modifiers;
147        }
148    
149        //--------------------------------------------------------------------------
150        
151        /**
152         * Is the object public scope.
153         * 
154         * @return true if public scope
155         */
156        public boolean isPublicScope() {
157            return (getFlags() & PUBLIC) != 0;
158        }
159        
160        /**
161         * Set the object to be public scope.
162         */
163        public void setPublicScope() {
164            setFlags(
165                getFlags()
166                    & ~Modifier.PRIVATE
167                    & ~Modifier.PROTECTED
168                    & Modifier.PUBLIC);
169        }
170        
171        //--------------------------------------------------------------------------
172        
173        /**
174         * Is the object protected scope.
175         * 
176         * @return true if protected scope
177         */
178        public boolean isProtectedScope() {
179            return (getFlags() & PROTECTED) != 0;
180        }
181        
182        /**
183         * Set the object to be protected scope.
184         */
185        public void setProtectedScope() {
186            setFlags(
187                getFlags()
188                    & ~Modifier.PRIVATE
189                    & Modifier.PROTECTED
190                    & ~Modifier.PUBLIC);
191        }
192        
193        //--------------------------------------------------------------------------
194        
195        /**
196         * Is the object package scope.
197         * 
198         * @return true if package scope
199         */
200        public boolean isPackageScope() {
201            return (
202                (isPublicScope() == false)
203                    && (isProtectedScope() == false)
204                    && (isPrivateScope() == false));
205        }
206        
207        /**
208         * Set the object to be package scope.
209         */
210        public void setPackageScope() {
211            setFlags(
212                getFlags()
213                    & ~Modifier.PRIVATE
214                    & ~Modifier.PROTECTED
215                    & ~Modifier.PUBLIC);
216        }
217        
218        //--------------------------------------------------------------------------
219        
220        /**
221         * Is the object private scope.
222         * 
223         * @return true if private scope
224         */
225        public boolean isPrivateScope() {
226            return (getFlags() & PRIVATE) != 0;
227        }
228        
229        /**
230         * Set the object to be private scope.
231         */
232        public void setPrivateScope() {
233            setFlags(
234                getFlags()
235                    & Modifier.PRIVATE
236                    & ~Modifier.PROTECTED
237                    & ~Modifier.PUBLIC);
238        }
239        
240        //--------------------------------------------------------------------------
241        
242        /**
243         * Is the object static.
244         * 
245         * @return true if static
246         */
247        public boolean isStatic() {
248            return (getFlags() & STATIC) != 0;
249        }
250        
251        /**
252         * Set the object to be static.
253         * 
254         * @param state  true to make static
255         */
256        public void setStatic(boolean state) {
257            if (state) {
258                setFlags(getFlags() & Modifier.STATIC);
259            }
260            else {
261                setFlags(getFlags() & ~Modifier.STATIC);
262            }
263        }
264        
265        //--------------------------------------------------------------------------
266        
267        /**
268         * Is the object final.
269         * 
270         * @return true if final
271         */
272        public boolean isFinal() {
273            return (getFlags() & FINAL) != 0;
274        }
275        
276        /**
277         * Set the object to be final.
278         * 
279         * @param state  true to make final
280         */
281        public void setFinal(boolean state) {
282            if (state) {
283                setFlags(getFlags() & Modifier.FINAL);
284            }
285            else {
286                setFlags(getFlags() & ~Modifier.FINAL);
287            }
288        }
289        
290        //--------------------------------------------------------------------------
291        
292        /**
293         * Is the object synchronized.
294         * 
295         * @return true if synchronized
296         */
297        public boolean isSynchronized() {
298            return (getFlags() & SYNCHRONIZED) != 0;
299        }
300        
301        /**
302         * Set the object to be synchronized.
303         * 
304         * @param state  true to make synchronized
305         */
306        public void setSynchronized(boolean state) {
307            if (state) {
308                setFlags(getFlags() & Modifier.SYNCHRONIZED);
309            }
310            else {
311                setFlags(getFlags() & ~Modifier.SYNCHRONIZED);
312            }
313        }
314        
315        //--------------------------------------------------------------------------
316        
317        /**
318         * Is the object volatile.
319         * 
320         * @return true if volatile
321         */
322        public boolean isVolatile() {
323            return (getFlags() & VOLATILE) != 0;
324        }
325        
326        /**
327         * Set the object to be volatile.
328         * 
329         * @param state  true to make volatile
330         */
331        public void setVolatile(boolean state) {
332            if (state) {
333                setFlags(getFlags() & Modifier.VOLATILE);
334            }
335            else {
336                setFlags(getFlags() & ~Modifier.VOLATILE);
337            }
338        }
339        
340        //--------------------------------------------------------------------------
341        
342        /**
343         * Is the object transient.
344         * 
345         * @return true if transient
346         */
347        public boolean isTransient() {
348            return (getFlags() & TRANSIENT) != 0;
349        }
350        
351        /**
352         * Set the object to be transient.
353         * 
354         * @param state  true to make transient
355         */
356        public void setTransient(boolean state) {
357            if (state) {
358                setFlags(getFlags() & TRANSIENT);
359            }
360            else {
361                setFlags(getFlags() & ~TRANSIENT);
362            }
363        }
364        
365        //--------------------------------------------------------------------------
366        
367        /**
368         * Is the object native.
369         * 
370         * @return true if native
371         */
372        public boolean isNative() {
373            return (getFlags() & NATIVE) != 0;
374        }
375        
376        /**
377         * Set the object to be native.
378         * 
379         * @param state  true to make native
380         */
381        public void setNative(boolean state) {
382            if (state) {
383                setFlags(getFlags() & NATIVE);
384            }
385            else {
386                setFlags(getFlags() & ~NATIVE);
387            }
388        }
389        
390        //--------------------------------------------------------------------------
391        
392        /**
393         * Is the object abstract.
394         * 
395         * @return true if abstract
396         */
397        public boolean isAbstract() {
398            return (getFlags() & ABSTRACT) != 0;
399        }
400        
401        /**
402         * Set the object to be abstract.
403         * 
404         * @param state  true to make abstract
405         */
406        public void setAbstract(boolean state) {
407            if (state) {
408                setFlags(getFlags() & ABSTRACT);
409            }
410            else {
411                setFlags(getFlags() & ~ABSTRACT);
412            }
413        }
414        
415        //--------------------------------------------------------------------------
416        
417        /**
418         * Is the object strictfp.
419         * 
420         * @return true if strictfp
421         */
422        public boolean isStrictFP() {
423            return (getFlags() & STRICT) != 0;
424        }
425        
426        /**
427         * Set the object to be strictfp.
428         * 
429         * @param state  true to make strictfp
430         */
431        public void setStrictFP(boolean state) {
432            if (state) {
433                setFlags(getFlags() & STRICT);
434            }
435            else {
436                setFlags(getFlags() & ~STRICT);
437            }
438        }
439        
440        //--------------------------------------------------------------------------
441        
442        /**
443         * Geta string describing the access modifier flags in
444         * the specified modifier. For example:
445         * <blockquote><pre>
446         *    AModifiers[public final synchronized]
447         *    AModifiers[private transient volatile]
448         * </pre></blockquote>
449         * The modifier names are return in canonical order, as
450         * specified by <em>The Java Language Specification</em>.
451         * 
452         * @return a debug string
453         */
454        public String toString() {
455            StringBuffer sb = new StringBuffer("Modifiers[");
456    
457            if (isPublicScope()) {
458                sb.append("public ");
459            }
460            if (isPrivateScope()) {
461                sb.append("private ");
462            }
463            if (isProtectedScope()) {
464                sb.append("protected ");
465            }
466    
467            // Canonical order
468            if (isAbstract()) {
469                sb.append("abstract ");
470            }
471            if (isStatic()) {
472                sb.append("static ");
473            }
474            if (isFinal()) {
475                sb.append("final ");
476            }
477            if (isTransient()) {
478                sb.append("transient ");
479            }
480            if (isVolatile()) {
481                sb.append("volatile ");
482            }
483            if (isNative()) {
484                sb.append("native ");
485            }
486            if (isSynchronized()) {
487                sb.append("synchronized ");
488            }
489            //        if (isInterface()) {
490            //            sb.append("interface ");
491            //        }
492            if (isStrictFP()) {
493                sb.append("strictfp ");
494            }
495    
496            if (sb.charAt(sb.length() - 1) == ' ') {
497                sb.setCharAt(sb.length() - 1, ']');
498            }
499            else {
500                sb.append(']');
501            }
502            return sb.toString();
503        }
504    
505    }