001: /*
002: * Spoon - http://spoon.gforge.inria.fr/
003: * Copyright (C) 2006 INRIA Futurs <renaud.pawlak@inria.fr>
004: *
005: * This software is governed by the CeCILL-C License under French law and
006: * abiding by the rules of distribution of free software. You can use, modify
007: * and/or redistribute the software under the terms of the CeCILL-C license as
008: * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
009: *
010: * This program is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
013: *
014: * The fact that you are presently reading this means that you have had
015: * knowledge of the CeCILL-C license and that you accept its terms.
016: */
017:
018: package spoon.support.reflect.reference;
019:
020: import java.lang.annotation.Annotation;
021: import java.lang.reflect.Field;
022: import java.lang.reflect.Member;
023: import java.lang.reflect.Method;
024: import java.util.Set;
025: import java.util.TreeSet;
026:
027: import spoon.reflect.declaration.CtField;
028: import spoon.reflect.declaration.CtSimpleType;
029: import spoon.reflect.declaration.CtVariable;
030: import spoon.reflect.declaration.ModifierKind;
031: import spoon.reflect.reference.CtFieldReference;
032: import spoon.reflect.reference.CtTypeReference;
033: import spoon.reflect.visitor.CtVisitor;
034: import spoon.support.util.RtHelper;
035:
036: public class CtFieldReferenceImpl<T> extends CtVariableReferenceImpl<T>
037: implements CtFieldReference<T> {
038: private static final long serialVersionUID = 1L;
039:
040: CtTypeReference<?> declaringType;
041:
042: boolean fina = false;
043:
044: boolean stat = false;
045:
046: public CtFieldReferenceImpl() {
047: super ();
048: }
049:
050: public void accept(CtVisitor visitor) {
051: visitor.visitCtFieldReference(this );
052: }
053:
054: public Member getActualField() {
055: try {
056: if (getDeclaringType().getActualClass().isAnnotation()) {
057: return getDeclaringType().getActualClass()
058: .getDeclaredMethod(getSimpleName());
059: }
060: return getDeclaringType().getActualClass()
061: .getDeclaredField(getSimpleName());
062: } catch (Exception e) {
063: e.printStackTrace();
064: }
065: return null;
066: }
067:
068: @Override
069: public <A extends Annotation> A getAnnotation(
070: Class<A> annotationType) {
071: A annotation = super .getAnnotation(annotationType);
072: if (annotation != null) {
073: return annotation;
074: }
075: // use reflection
076: Class<?> c = getDeclaringType().getActualClass();
077: if (c.isAnnotation()) {
078: for (Method m : RtHelper.getAllMethods(c)) {
079: if (!getSimpleName().equals(m.getName())) {
080: continue;
081: }
082: m.setAccessible(true);
083: return m.getAnnotation(annotationType);
084: }
085: } else {
086: for (Field f : RtHelper.getAllFields(c)) {
087: if (!getSimpleName().equals(f.getName())) {
088: continue;
089: }
090: f.setAccessible(true);
091: return f.getAnnotation(annotationType);
092: }
093: }
094: return null;
095: }
096:
097: @Override
098: public Annotation[] getAnnotations() {
099: Annotation[] annotations = super .getAnnotations();
100: if (annotations != null) {
101: return annotations;
102: }
103: // use reflection
104: Class<?> c = getDeclaringType().getActualClass();
105: for (Field f : RtHelper.getAllFields(c)) {
106: if (!getSimpleName().equals(f.getName())) {
107: continue;
108: }
109: f.setAccessible(true);
110: return f.getAnnotations();
111: }
112: // If the fields belong to an annotation type, they are actually
113: // methods
114: for (Method m : RtHelper.getAllMethods(c)) {
115: if (!getSimpleName().equals(m.getName())) {
116: continue;
117: }
118: m.setAccessible(true);
119: return m.getAnnotations();
120: }
121: return null;
122: }
123:
124: @SuppressWarnings("unchecked")
125: public CtField<T> getDeclaration() {
126: CtSimpleType<?> type = declaringType.getDeclaration();
127: if ((declaringType != null) && (type != null)) {
128: return (CtField<T>) type.getField(getSimpleName());
129: }
130: return null;
131: }
132:
133: public CtTypeReference<?> getDeclaringType() {
134: return declaringType;
135: }
136:
137: public String getQualifiedName() {
138: return getDeclaringType().getQualifiedName() + "#"
139: + getSimpleName();
140: }
141:
142: public boolean isFinal() {
143: return fina;
144: }
145:
146: /**
147: * Tells if the referenced field is static.
148: */
149: public boolean isStatic() {
150: return stat;
151: }
152:
153: public void setDeclaringType(CtTypeReference<?> declaringType) {
154: this .declaringType = declaringType;
155: }
156:
157: public void setFinal(boolean b) {
158: fina = b;
159: }
160:
161: public void setStatic(boolean stat) {
162: this .stat = stat;
163: }
164:
165: @Override
166: public Set<ModifierKind> getModifiers() {
167: CtVariable<?> v = getDeclaration();
168: if (v != null) {
169: return v.getModifiers();
170: }
171: Member m = getActualField();
172: if (m != null) {
173: return RtHelper.getModifiers(m.getModifiers());
174: }
175: return new TreeSet<ModifierKind>();
176: }
177:
178: }
|