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.declaration;
019:
020: import java.io.Serializable;
021: import java.lang.annotation.Annotation;
022: import java.util.List;
023: import java.util.Set;
024: import java.util.TreeSet;
025:
026: import spoon.reflect.Factory;
027: import spoon.reflect.cu.SourcePosition;
028: import spoon.reflect.declaration.CtAnnotation;
029: import spoon.reflect.declaration.CtElement;
030: import spoon.reflect.reference.CtTypeReference;
031: import spoon.reflect.visitor.CtScanner;
032: import spoon.reflect.visitor.DefaultJavaPrettyPrinter;
033: import spoon.reflect.visitor.Filter;
034: import spoon.reflect.visitor.Query;
035: import spoon.reflect.visitor.filter.AnnotationFilter;
036: import spoon.support.visitor.ElementReplacer;
037: import spoon.support.visitor.SignaturePrinter;
038: import spoon.support.visitor.TypeReferenceScanner;
039:
040: /**
041: * The implementation for {@link spoon.test.spoon.reflect.Declaration}.
042: *
043: * @author Renaud Pawlak
044: * @see spoon.test.spoon.reflect.Declaration
045: */
046: public abstract class CtElementImpl implements CtElement, Serializable {
047:
048: transient Factory factory;
049:
050: public String getSignature() {
051: SignaturePrinter pr = new SignaturePrinter();
052: pr.scan(this );
053: return pr.getSignature();
054: }
055:
056: public Factory getFactory() {
057: return factory;
058: }
059:
060: public void setFactory(Factory factory) {
061: this .factory = factory;
062: }
063:
064: Set<CtAnnotation<? extends Annotation>> annotations = new TreeSet<CtAnnotation<? extends Annotation>>();
065:
066: String docComment;
067:
068: CtElement parent;
069:
070: SourcePosition position;
071:
072: public CtElementImpl() {
073: super ();
074: }
075:
076: public int compareTo(CtElement o) {
077: String current = getSignature();
078: String other = o.getSignature();
079: if (current.length() <= 0 || other.length() <= 0)
080: throw new ClassCastException("Unable to compare elements");
081: return current.compareTo(other);
082: }
083:
084: @SuppressWarnings("unchecked")
085: public <A extends Annotation> A getAnnotation(
086: Class<A> annotationType) {
087: for (CtAnnotation<? extends Annotation> a : getAnnotations()) {
088: if (a.getAnnotationType().toString().equals(
089: annotationType.getName())) {
090: return ((CtAnnotation<A>) a).getActualAnnotation();
091: }
092: }
093: return null;
094: }
095:
096: // TODO remove the warning
097: @SuppressWarnings("unchecked")
098: public <A extends Annotation> CtAnnotation<A> getAnnotation(
099: CtTypeReference<A> annotationType) {
100: for (CtAnnotation<? extends Annotation> a : getAnnotations()) {
101: if (a.getAnnotationType().equals(annotationType)) {
102: return (CtAnnotation<A>) a;
103: }
104: }
105: return null;
106: }
107:
108: public Set<CtAnnotation<? extends Annotation>> getAnnotations() {
109: return annotations;
110: }
111:
112: public String getDocComment() {
113: return docComment;
114: }
115:
116: public CtElement getParent() {
117: return parent;
118: }
119:
120: @SuppressWarnings("unchecked")
121: public <P extends CtElement> P getParent(Class<P> parentType) {
122: if (getParent() == null)
123: return null;
124: if (parentType.isAssignableFrom(getParent().getClass()))
125: return (P) getParent();
126: return getParent().getParent(parentType);
127: }
128:
129: public boolean hasParent(CtElement candidate) {
130: if (getParent() == null)
131: return false;
132: if (getParent() == candidate)
133: return true;
134: return getParent().hasParent(candidate);
135: }
136:
137: public SourcePosition getPosition() {
138: return position;
139: }
140:
141: @Override
142: public int hashCode() {
143: SignaturePrinter pr = new SignaturePrinter();
144: pr.scan(this );
145: return pr.getSignature().hashCode();
146: }
147:
148: public void replace(CtElement element) {
149: ElementReplacer<CtElement> translator = new ElementReplacer<CtElement>(
150: this , element);
151: getParent().accept(translator);
152: }
153:
154: public void replace(Filter<? extends CtElement> replacementPoints,
155: CtElement element) {
156: List<? extends CtElement> l = Query.getElements(this ,
157: replacementPoints);
158: for (CtElement e : l) {
159: e.replace(element);
160: }
161: }
162:
163: public void setAnnotations(
164: Set<CtAnnotation<? extends Annotation>> annotations) {
165: this .annotations = annotations;
166: }
167:
168: public void setDocComment(String docComment) {
169: this .docComment = docComment;
170: }
171:
172: public void setParent(CtElement parentElement) {
173: this .parent = parentElement;
174: }
175:
176: public void setPosition(SourcePosition position) {
177: this .position = position;
178: }
179:
180: public void setPositions(final SourcePosition position) {
181: accept(new CtScanner() {
182: public void enter(CtElement e) {
183: e.setPosition(position);
184: }
185: });
186: }
187:
188: @Override
189: public String toString() {
190: DefaultJavaPrettyPrinter printer = new DefaultJavaPrettyPrinter(
191: getFactory().getEnvironment());
192: printer.scan(this );
193: return printer.toString();
194: }
195:
196: @SuppressWarnings("unchecked")
197: public <E extends CtElement> List<E> getAnnotatedChildren(
198: Class<? extends Annotation> annotationType) {
199: return Query.getElements(this , new AnnotationFilter(
200: CtElement.class, annotationType));
201: }
202:
203: boolean implicit = false;
204:
205: public boolean isImplicit() {
206: return implicit;
207: }
208:
209: public void setImplicit(boolean implicit) {
210: this .implicit = implicit;
211: }
212:
213: public Set<CtTypeReference<?>> getReferencedTypes() {
214: TypeReferenceScanner s = new TypeReferenceScanner();
215: s.scan(this);
216: return s.getReferences();
217: }
218:
219: }
|