001    // This file is part of the RECODER library and protected by the LGPL.
002    
003    package recoder.java.declaration;
004    
005    import java.util.ArrayList;
006    import java.util.List;
007    
008    import recoder.java.Declaration;
009    import recoder.java.JavaNonTerminalProgramElement;
010    import recoder.java.declaration.modifier.Abstract;
011    import recoder.java.declaration.modifier.Final;
012    import recoder.java.declaration.modifier.Native;
013    import recoder.java.declaration.modifier.Private;
014    import recoder.java.declaration.modifier.Protected;
015    import recoder.java.declaration.modifier.Public;
016    import recoder.java.declaration.modifier.Static;
017    import recoder.java.declaration.modifier.StrictFp;
018    import recoder.java.declaration.modifier.Synchronized;
019    import recoder.java.declaration.modifier.Transient;
020    import recoder.java.declaration.modifier.VisibilityModifier;
021    import recoder.java.declaration.modifier.Volatile;
022    import recoder.list.generic.ASTList;
023    
024    /**
025     * Java declaration.
026     * 
027     * @author <TT>AutoDoc</TT>
028     */
029    
030    public abstract class JavaDeclaration extends JavaNonTerminalProgramElement implements Declaration {
031        /**
032             * 
033             */
034            private static final long serialVersionUID = 1L;
035            
036            /**
037         * Modifiers.
038         */
039    
040            ASTList<DeclarationSpecifier> declarationSpecifiers;
041    
042        /**
043         * Java declaration.
044         */
045    
046        public JavaDeclaration() {
047            // nothing to do here
048        }
049    
050        /**
051         * Java declaration.
052         * 
053         * @param mods
054         *            a modifier mutable list.
055         */
056    
057        public JavaDeclaration(ASTList<DeclarationSpecifier> mods) {
058            setDeclarationSpecifiers(mods);
059            // makeParentRoleValid() called by subclasses' constructors
060        }
061    
062        /**
063         * Java declaration.
064         * 
065         * @param proto
066         *            a java declaration.
067         */
068    
069        protected JavaDeclaration(JavaDeclaration proto) {
070            super(proto);
071            if (proto.declarationSpecifiers != null) {
072                declarationSpecifiers = proto.declarationSpecifiers.deepClone();
073            }
074            // makeParentRoleValid() called by subclasses' constructors
075        }
076    
077        /**
078         * Get modifiers.
079         * 
080         * @return an list containing all modifiers but no annotations. Changes on the list do not reflect
081         * changes on the AST!
082         */
083        public List<Modifier> getModifiers() {
084            if (declarationSpecifiers == null) return new ArrayList<Modifier>(0);
085            List<Modifier> mml = new ArrayList<Modifier>();
086                    for (int i = 0, max = declarationSpecifiers.size(); i < max; i++) {
087                            DeclarationSpecifier ds = declarationSpecifiers.get(i);
088                            if (ds instanceof Modifier)
089                                    mml.add((Modifier)ds);
090                    }
091                    return mml;
092        }
093    
094        /**
095         * @return a list of annotations
096         */
097        public List<AnnotationUseSpecification> getAnnotations() {
098            if (declarationSpecifiers == null)
099                return new ArrayList<AnnotationUseSpecification>(0);
100            List<AnnotationUseSpecification> result = new ArrayList<AnnotationUseSpecification>(declarationSpecifiers.size());
101            int s = declarationSpecifiers.size();
102            for(int i = 0; i < s; i++) {
103                DeclarationSpecifier ds = declarationSpecifiers.get(i);
104                if (ds instanceof AnnotationUseSpecification)
105                    result.add((AnnotationUseSpecification)ds);
106            }
107            return result;
108        }
109           
110        public ASTList<DeclarationSpecifier> getDeclarationSpecifiers() {
111            return declarationSpecifiers;
112        }
113        
114        public void setDeclarationSpecifiers(ASTList<DeclarationSpecifier> m) {
115            declarationSpecifiers = m;
116        }
117    
118        /**
119         * Returns a Public, Protected, or Private Modifier, if there is one, null
120         * otherwise. A return value of null can usually be interpreted as package
121         * visibility.
122         */
123    
124        public VisibilityModifier getVisibilityModifier() {
125            if (declarationSpecifiers == null) {
126                return null;
127            }
128            for (int i = declarationSpecifiers.size() - 1; i >= 0; i -= 1) {
129                DeclarationSpecifier m = declarationSpecifiers.get(i);
130                if (m instanceof VisibilityModifier) {
131                    return (VisibilityModifier) m;
132                }
133            }
134            return null;
135        }
136    
137        final boolean containsModifier(Class<? extends Modifier> type) {
138            int s = (declarationSpecifiers == null) ? 0 : declarationSpecifiers.size();
139            for (int i = 0; i < s; i += 1) {
140                if (type.isInstance(declarationSpecifiers.get(i))) {
141                    return true;
142                }
143            }
144            return false;
145        }
146    
147        /**
148         * Test whether the declaration is abstract.
149         */
150    
151        protected boolean isAbstract() {
152            return containsModifier(Abstract.class);
153        }
154    
155        /**
156         * Test whether the declaration is private.
157         */
158    
159        protected boolean isPrivate() {
160            return containsModifier(Private.class);
161        }
162    
163        /**
164         * Test whether the declaration is protected.
165         */
166    
167        protected boolean isProtected() {
168            return containsModifier(Protected.class);
169        }
170    
171        /**
172         * Test whether the declaration is public.
173         */
174    
175        protected boolean isPublic() {
176            return containsModifier(Public.class);
177        }
178    
179        /**
180         * Test whether the declaration is static.
181         */
182    
183        protected boolean isStatic() {
184            return containsModifier(Static.class);
185        }
186    
187        /**
188         * Test whether the declaration is transient.
189         */
190    
191        protected boolean isTransient() {
192            return containsModifier(Transient.class);
193        }
194    
195        /**
196         * Test whether the declaration is volatile.
197         */
198    
199        protected boolean isVolatile() {
200            return containsModifier(Volatile.class);
201        }
202    
203        /**
204         * Test whether the declaration is strictfp.
205         */
206    
207        protected boolean isStrictFp() {
208            return containsModifier(StrictFp.class);
209        }
210    
211        /**
212         * Test whether the declaration is final.
213         */
214    
215        protected boolean isFinal() {
216            return containsModifier(Final.class);
217        }
218    
219        /**
220         * Test whether the declaration is native.
221         */
222    
223        protected boolean isNative() {
224            return containsModifier(Native.class);
225        }
226    
227        /**
228         * Test whether the declaration is synchronized.
229         */
230    
231        protected boolean isSynchronized() {
232            return containsModifier(Synchronized.class);
233        }
234    
235        /**
236         * Make parent role valid.
237         */
238    
239        public void makeParentRoleValid() {
240            super.makeParentRoleValid();
241            if (declarationSpecifiers != null) {
242                for (int i = declarationSpecifiers.size() - 1; i >= 0; i -= 1) {
243                    declarationSpecifiers.get(i).setParent(this);
244                }
245            }
246        }
247    }