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;
019:
020: import java.io.Serializable;
021: import java.lang.annotation.Annotation;
022: import java.lang.reflect.Field;
023: import java.lang.reflect.Modifier;
024: import java.util.Collection;
025: import java.util.Map;
026: import java.util.Stack;
027: import java.util.Map.Entry;
028:
029: import spoon.reflect.CoreFactory;
030: import spoon.reflect.Factory;
031: import spoon.reflect.code.CtArrayAccess;
032: import spoon.reflect.code.CtAssert;
033: import spoon.reflect.code.CtAssignment;
034: import spoon.reflect.code.CtBinaryOperator;
035: import spoon.reflect.code.CtBlock;
036: import spoon.reflect.code.CtBreak;
037: import spoon.reflect.code.CtCase;
038: import spoon.reflect.code.CtCatch;
039: import spoon.reflect.code.CtCodeSnippetExpression;
040: import spoon.reflect.code.CtCodeSnippetStatement;
041: import spoon.reflect.code.CtConditional;
042: import spoon.reflect.code.CtContinue;
043: import spoon.reflect.code.CtDo;
044: import spoon.reflect.code.CtExpression;
045: import spoon.reflect.code.CtFieldAccess;
046: import spoon.reflect.code.CtFor;
047: import spoon.reflect.code.CtForEach;
048: import spoon.reflect.code.CtIf;
049: import spoon.reflect.code.CtInvocation;
050: import spoon.reflect.code.CtLiteral;
051: import spoon.reflect.code.CtLocalVariable;
052: import spoon.reflect.code.CtNewArray;
053: import spoon.reflect.code.CtNewClass;
054: import spoon.reflect.code.CtOperatorAssignment;
055: import spoon.reflect.code.CtReturn;
056: import spoon.reflect.code.CtStatementList;
057: import spoon.reflect.code.CtSwitch;
058: import spoon.reflect.code.CtSynchronized;
059: import spoon.reflect.code.CtThrow;
060: import spoon.reflect.code.CtTry;
061: import spoon.reflect.code.CtUnaryOperator;
062: import spoon.reflect.code.CtVariableAccess;
063: import spoon.reflect.code.CtWhile;
064: import spoon.reflect.cu.CompilationUnit;
065: import spoon.reflect.cu.SourcePosition;
066: import spoon.reflect.declaration.CtAnnotation;
067: import spoon.reflect.declaration.CtAnnotationType;
068: import spoon.reflect.declaration.CtAnonymousExecutable;
069: import spoon.reflect.declaration.CtClass;
070: import spoon.reflect.declaration.CtConstructor;
071: import spoon.reflect.declaration.CtElement;
072: import spoon.reflect.declaration.CtEnum;
073: import spoon.reflect.declaration.CtField;
074: import spoon.reflect.declaration.CtInterface;
075: import spoon.reflect.declaration.CtMethod;
076: import spoon.reflect.declaration.CtPackage;
077: import spoon.reflect.declaration.CtParameter;
078: import spoon.reflect.declaration.CtTypeParameter;
079: import spoon.reflect.reference.CtArrayTypeReference;
080: import spoon.reflect.reference.CtExecutableReference;
081: import spoon.reflect.reference.CtFieldReference;
082: import spoon.reflect.reference.CtLocalVariableReference;
083: import spoon.reflect.reference.CtPackageReference;
084: import spoon.reflect.reference.CtParameterReference;
085: import spoon.reflect.reference.CtReference;
086: import spoon.reflect.reference.CtTypeParameterReference;
087: import spoon.reflect.reference.CtTypeReference;
088: import spoon.support.reflect.code.CtArrayAccessImpl;
089: import spoon.support.reflect.code.CtAssertImpl;
090: import spoon.support.reflect.code.CtAssignmentImpl;
091: import spoon.support.reflect.code.CtBinaryOperatorImpl;
092: import spoon.support.reflect.code.CtBlockImpl;
093: import spoon.support.reflect.code.CtBreakImpl;
094: import spoon.support.reflect.code.CtCaseImpl;
095: import spoon.support.reflect.code.CtCatchImpl;
096: import spoon.support.reflect.code.CtCodeSnippetExpressionImpl;
097: import spoon.support.reflect.code.CtCodeSnippetStatementImpl;
098: import spoon.support.reflect.code.CtConditionalImpl;
099: import spoon.support.reflect.code.CtContinueImpl;
100: import spoon.support.reflect.code.CtDoImpl;
101: import spoon.support.reflect.code.CtFieldAccessImpl;
102: import spoon.support.reflect.code.CtForEachImpl;
103: import spoon.support.reflect.code.CtForImpl;
104: import spoon.support.reflect.code.CtIfImpl;
105: import spoon.support.reflect.code.CtInvocationImpl;
106: import spoon.support.reflect.code.CtLiteralImpl;
107: import spoon.support.reflect.code.CtLocalVariableImpl;
108: import spoon.support.reflect.code.CtNewArrayImpl;
109: import spoon.support.reflect.code.CtNewClassImpl;
110: import spoon.support.reflect.code.CtOperatorAssignmentImpl;
111: import spoon.support.reflect.code.CtReturnImpl;
112: import spoon.support.reflect.code.CtStatementListImpl;
113: import spoon.support.reflect.code.CtSwitchImpl;
114: import spoon.support.reflect.code.CtSynchronizedImpl;
115: import spoon.support.reflect.code.CtThrowImpl;
116: import spoon.support.reflect.code.CtTryImpl;
117: import spoon.support.reflect.code.CtUnaryOperatorImpl;
118: import spoon.support.reflect.code.CtVariableAccessImpl;
119: import spoon.support.reflect.code.CtWhileImpl;
120: import spoon.support.reflect.cu.CompilationUnitImpl;
121: import spoon.support.reflect.cu.SourcePositionImpl;
122: import spoon.support.reflect.declaration.CompilationUnitVirtualImpl;
123: import spoon.support.reflect.declaration.CtAnnotationImpl;
124: import spoon.support.reflect.declaration.CtAnnotationTypeImpl;
125: import spoon.support.reflect.declaration.CtAnonymousExecutableImpl;
126: import spoon.support.reflect.declaration.CtClassImpl;
127: import spoon.support.reflect.declaration.CtConstructorImpl;
128: import spoon.support.reflect.declaration.CtEnumImpl;
129: import spoon.support.reflect.declaration.CtFieldImpl;
130: import spoon.support.reflect.declaration.CtInterfaceImpl;
131: import spoon.support.reflect.declaration.CtMethodImpl;
132: import spoon.support.reflect.declaration.CtPackageImpl;
133: import spoon.support.reflect.declaration.CtParameterImpl;
134: import spoon.support.reflect.declaration.CtTypeParameterImpl;
135: import spoon.support.reflect.reference.CtArrayTypeReferenceImpl;
136: import spoon.support.reflect.reference.CtExecutableReferenceImpl;
137: import spoon.support.reflect.reference.CtFieldReferenceImpl;
138: import spoon.support.reflect.reference.CtLocalVariableReferenceImpl;
139: import spoon.support.reflect.reference.CtPackageReferenceImpl;
140: import spoon.support.reflect.reference.CtParameterReferenceImpl;
141: import spoon.support.reflect.reference.CtTypeParameterReferenceImpl;
142: import spoon.support.reflect.reference.CtTypeReferenceImpl;
143: import spoon.support.util.RtHelper;
144:
145: /**
146: * This class implements a default core factory for Spoon's meta-model. This
147: * implementation is done with regular Java classes (POJOs).
148: */
149: public class DefaultCoreFactory implements CoreFactory, Serializable {
150:
151: private static final long serialVersionUID = 1L;
152:
153: transient Stack<CtElement> cloningContext = new Stack<CtElement>();
154:
155: Factory mainFactory;
156:
157: /**
158: * Default constructor.
159: */
160: public DefaultCoreFactory() {
161: }
162:
163: @SuppressWarnings("unchecked")
164: public <T> T clone(T object) {
165: if (object == null)
166: return null;
167: T result = null;
168: try {
169: if (!(object instanceof CtElement || object instanceof CtReference)) {
170: return object;
171: }
172: if (object instanceof Cloneable) {
173: return (T) object.getClass().getMethod("clone").invoke(
174: object);
175: }
176: if (object.getClass().isEnum()) {
177: return object;
178: }
179: // System.err.println("cloning " + object + "["
180: // + object.getClass().getSimpleName() + "]");
181: result = (T) object.getClass().newInstance();
182: if (result instanceof CtElement) {
183: if (cloningContext.isEmpty()) {
184: cloningContext.push(((CtElement) result)
185: .getParent());
186: }
187: cloningContext.push((CtElement) result);
188: }
189: for (Field f : RtHelper.getAllFields(object.getClass())) {
190: // if (!clonedFields.contains(f)) {
191: // clonedFields.push(f);
192: f.setAccessible(true);
193: if (f.getName().equals("parent")) {
194: // if (!cloningContext.isEmpty()) {
195: ((CtElement) result).setParent(cloningContext
196: .get(cloningContext.size() - 2));
197: // }
198: } else {
199: Object fieldValue = f.get(object);
200: if (!Modifier.isFinal(f.getModifiers())
201: && !Modifier.isStatic(f.getModifiers())) {
202: if (fieldValue instanceof Collection) {
203: // System.err.println(" cloning collection " + f+" :
204: // "+cloningContext.peek().getClass().getSimpleName());
205: Collection c = (Collection) fieldValue
206: .getClass().getMethod("clone")
207: .invoke(fieldValue);
208: c.clear();
209: f.set(result, c);
210: for (Object o : (Collection) fieldValue) {
211: c.add(clone(o));
212: }
213: } else if (fieldValue instanceof Map) {
214: // System.err.println(" cloning collection " + f+" :
215: // "+cloningContext.peek().getClass().getSimpleName());
216: Map m = (Map) fieldValue.getClass()
217: .getMethod("clone").invoke(
218: fieldValue);
219: // m.clear();
220: f.set(result, m);
221: for (Entry e : ((Map<?, ?>) fieldValue)
222: .entrySet()) {
223: m.put(e.getKey(), clone(e.getValue()));
224: }
225: } else if ((object instanceof CtReference)
226: && (fieldValue instanceof CtElement)) {
227:
228: f.set(result, fieldValue);
229: } else {
230: // System.err.println(" cloning field " + f+" :
231: // "+cloningContext.peek().getClass().getSimpleName());
232: f.set(result, clone(f.get(object)));
233: }
234: }
235: }
236: // clonedFields.pop();
237: }
238: // }
239: if (result instanceof CtElement) {
240: cloningContext.pop();
241: }
242: } catch (Exception e) {
243: e.printStackTrace();
244: }
245: return result;
246:
247: }
248:
249: @SuppressWarnings("unchecked")
250: public <A extends Annotation> CtAnnotation<A> createAnnotation() {
251: CtAnnotation e = new CtAnnotationImpl<A>();
252: e.setFactory(getMainFactory());
253: return e;
254: }
255:
256: public <T extends Annotation> CtAnnotationType<T> createAnnotationType() {
257: CtAnnotationType<T> e = new CtAnnotationTypeImpl<T>();
258: e.setFactory(getMainFactory());
259: return e;
260: }
261:
262: public CtAnonymousExecutable createAnonymousExecutable() {
263: CtAnonymousExecutable e = new CtAnonymousExecutableImpl();
264: e.setFactory(getMainFactory());
265: return e;
266: }
267:
268: public <T, E extends CtExpression<?>> CtArrayAccess<T, E> createArrayAccess() {
269: CtArrayAccess<T, E> e = new CtArrayAccessImpl<T, E>();
270: e.setFactory(getMainFactory());
271: return e;
272: }
273:
274: public <T> CtArrayTypeReference<T> createArrayTypeReference() {
275: CtArrayTypeReference<T> e = new CtArrayTypeReferenceImpl<T>();
276: e.setFactory(getMainFactory());
277: return e;
278: }
279:
280: public <T> CtAssert<T> createAssert() {
281: CtAssert<T> e = new CtAssertImpl<T>();
282: e.setFactory(getMainFactory());
283: return e;
284: }
285:
286: public <T, A extends T> CtAssignment<T, A> createAssignment() {
287: CtAssignment<T, A> e = new CtAssignmentImpl<T, A>();
288: e.setFactory(getMainFactory());
289: return e;
290: }
291:
292: public <T> CtBinaryOperator<T> createBinaryOperator() {
293: CtBinaryOperator<T> e = new CtBinaryOperatorImpl<T>();
294: e.setFactory(getMainFactory());
295: return e;
296: }
297:
298: public <R> CtBlock<R> createBlock() {
299: CtBlock<R> e = new CtBlockImpl<R>();
300: e.setFactory(getMainFactory());
301: return e;
302: }
303:
304: public CtBreak createBreak() {
305: CtBreak e = new CtBreakImpl();
306: e.setFactory(getMainFactory());
307: return e;
308: }
309:
310: public <S> CtCase<S> createCase() {
311: CtCase<S> e = new CtCaseImpl<S>();
312: e.setFactory(getMainFactory());
313: return e;
314: }
315:
316: public CtCatch createCatch() {
317: CtCatch e = new CtCatchImpl();
318: e.setFactory(getMainFactory());
319: return e;
320: }
321:
322: public <T> CtClass<T> createClass() {
323: CtClass<T> e = new CtClassImpl<T>();
324: e.setFactory(getMainFactory());
325: return e;
326: }
327:
328: public <T> CtConditional<T> createConditional() {
329: CtConditional<T> e = new CtConditionalImpl<T>();
330: e.setFactory(getMainFactory());
331: return e;
332: }
333:
334: public <T> CtConstructor<T> createConstructor() {
335: CtConstructor<T> e = new CtConstructorImpl<T>();
336: e.setFactory(getMainFactory());
337: return e;
338: }
339:
340: public CtContinue createContinue() {
341: CtContinue e = new CtContinueImpl();
342: e.setFactory(getMainFactory());
343: return e;
344: }
345:
346: public CtDo createDo() {
347: CtDo e = new CtDoImpl();
348: e.setFactory(getMainFactory());
349: return e;
350: }
351:
352: public <T extends Enum<?>> CtEnum<T> createEnum() {
353: CtEnum<T> e = new CtEnumImpl<T>();
354: e.setFactory(getMainFactory());
355: return e;
356: }
357:
358: public <T> CtExecutableReference<T> createExecutableReference() {
359: CtExecutableReference<T> e = new CtExecutableReferenceImpl<T>();
360: e.setFactory(getMainFactory());
361: return e;
362: }
363:
364: public <T> CtField<T> createField() {
365: CtField<T> e = new CtFieldImpl<T>();
366: e.setFactory(getMainFactory());
367: return e;
368: }
369:
370: public <T> CtFieldAccess<T> createFieldAccess() {
371: CtFieldAccess<T> e = new CtFieldAccessImpl<T>();
372: e.setFactory(getMainFactory());
373: return e;
374: }
375:
376: public <T> CtFieldReference<T> createFieldReference() {
377: CtFieldReference<T> e = new CtFieldReferenceImpl<T>();
378: e.setFactory(getMainFactory());
379: return e;
380: }
381:
382: public CtFor createFor() {
383: CtFor e = new CtForImpl();
384: e.setFactory(getMainFactory());
385: return e;
386: }
387:
388: public CtForEach createForEach() {
389: CtForEach e = new CtForEachImpl();
390: e.setFactory(getMainFactory());
391: return e;
392: }
393:
394: public CtIf createIf() {
395: CtIf e = new CtIfImpl();
396: e.setFactory(getMainFactory());
397: return e;
398: }
399:
400: public <T> CtInterface<T> createInterface() {
401: CtInterface<T> e = new CtInterfaceImpl<T>();
402: e.setFactory(getMainFactory());
403: return e;
404: }
405:
406: public <T> CtInvocation<T> createInvocation() {
407: CtInvocation<T> e = new CtInvocationImpl<T>();
408: e.setFactory(getMainFactory());
409: return e;
410: }
411:
412: public <T> CtLiteral<T> createLiteral() {
413: CtLiteral<T> e = new CtLiteralImpl<T>();
414: e.setFactory(getMainFactory());
415: return e;
416: }
417:
418: public <T> CtLocalVariable<T> createLocalVariable() {
419: CtLocalVariable<T> e = new CtLocalVariableImpl<T>();
420: e.setFactory(getMainFactory());
421: return e;
422: }
423:
424: public <T> CtLocalVariableReference<T> createLocalVariableReference() {
425: CtLocalVariableReference<T> e = new CtLocalVariableReferenceImpl<T>();
426: e.setFactory(getMainFactory());
427: return e;
428: }
429:
430: public <T> CtMethod<T> createMethod() {
431: CtMethod<T> e = new CtMethodImpl<T>();
432: e.setFactory(getMainFactory());
433: return e;
434: }
435:
436: public <T> CtNewArray<T> createNewArray() {
437: CtNewArray<T> e = new CtNewArrayImpl<T>();
438: e.setFactory(getMainFactory());
439: return e;
440: }
441:
442: public <T> CtNewClass<T> createNewClass() {
443: CtNewClass<T> e = new CtNewClassImpl<T>();
444: e.setFactory(getMainFactory());
445: return e;
446: }
447:
448: public <T, A extends T> CtOperatorAssignment<T, A> createOperatorAssignment() {
449: CtOperatorAssignment<T, A> e = new CtOperatorAssignmentImpl<T, A>();
450: e.setFactory(getMainFactory());
451: return e;
452: }
453:
454: public CtPackage createPackage() {
455: CtPackage e = new CtPackageImpl();
456: e.setFactory(getMainFactory());
457: return e;
458: }
459:
460: public CtPackageReference createPackageReference() {
461: CtPackageReference e = new CtPackageReferenceImpl();
462: e.setFactory(getMainFactory());
463: return e;
464: }
465:
466: public <T> CtParameter<T> createParameter() {
467: CtParameter<T> e = new CtParameterImpl<T>();
468: e.setFactory(getMainFactory());
469: return e;
470: }
471:
472: public <T> CtParameterReference<T> createParameterReference() {
473: CtParameterReference<T> e = new CtParameterReferenceImpl<T>();
474: e.setFactory(getMainFactory());
475: return e;
476: }
477:
478: public <R> CtReturn<R> createReturn() {
479: CtReturn<R> e = new CtReturnImpl<R>();
480: e.setFactory(getMainFactory());
481: return e;
482: }
483:
484: public <R> CtStatementList<R> createStatementList() {
485: CtStatementList<R> e = new CtStatementListImpl<R>();
486: e.setFactory(getMainFactory());
487: return e;
488: }
489:
490: public <S> CtSwitch<S> createSwitch() {
491: CtSwitch<S> e = new CtSwitchImpl<S>();
492: e.setFactory(getMainFactory());
493: return e;
494: }
495:
496: public CtSynchronized createSynchronized() {
497: CtSynchronized e = new CtSynchronizedImpl();
498: e.setFactory(getMainFactory());
499: return e;
500: }
501:
502: public CtThrow createThrow() {
503: CtThrow e = new CtThrowImpl();
504: e.setFactory(getMainFactory());
505: return e;
506: }
507:
508: public CtTry createTry() {
509: CtTry e = new CtTryImpl();
510: e.setFactory(getMainFactory());
511: return e;
512: }
513:
514: public CtTypeParameter createTypeParameter() {
515: CtTypeParameter e = new CtTypeParameterImpl();
516: e.setFactory(getMainFactory());
517: return e;
518: }
519:
520: public CtTypeParameterReference createTypeParameterReference() {
521: CtTypeParameterReference e = new CtTypeParameterReferenceImpl();
522: e.setFactory(getMainFactory());
523: return e;
524: }
525:
526: public <T> CtTypeReference<T> createTypeReference() {
527: CtTypeReference<T> e = new CtTypeReferenceImpl<T>();
528: e.setFactory(getMainFactory());
529: return e;
530: }
531:
532: public <T> CtUnaryOperator<T> createUnaryOperator() {
533: CtUnaryOperator<T> e = new CtUnaryOperatorImpl<T>();
534: e.setFactory(getMainFactory());
535: return e;
536: }
537:
538: public <T> CtVariableAccess<T> createVariableAccess() {
539: CtVariableAccess<T> e = new CtVariableAccessImpl<T>();
540: e.setFactory(getMainFactory());
541: return e;
542: }
543:
544: public <T> CtCodeSnippetExpression<T> createCodeSnippetExpression() {
545: CtCodeSnippetExpression<T> e = new CtCodeSnippetExpressionImpl<T>();
546: e.setFactory(getMainFactory());
547: return e;
548: }
549:
550: public CtCodeSnippetStatement createCodeSnippetStatement() {
551: CtCodeSnippetStatement e = new CtCodeSnippetStatementImpl();
552: e.setFactory(getMainFactory());
553: return e;
554: }
555:
556: public CtWhile createWhile() {
557: CtWhile e = new CtWhileImpl();
558: e.setFactory(getMainFactory());
559: return e;
560: }
561:
562: public Factory getMainFactory() {
563: return mainFactory;
564: }
565:
566: public void setMainFactory(Factory mainFactory) {
567: this .mainFactory = mainFactory;
568: }
569:
570: public SourcePosition createSourcePosition(
571: CompilationUnit compilationUnit, int start, int end,
572: int[] lineSeparatorPositions) {
573: return new SourcePositionImpl(compilationUnit, start, end,
574: lineSeparatorPositions);
575: }
576:
577: public CompilationUnit createCompilationUnit() {
578: CompilationUnit cu = new CompilationUnitImpl();
579: cu.setFactory(getMainFactory());
580: return cu;
581: }
582:
583: public CompilationUnit createVirtualCompilationUnit() {
584: CompilationUnit cu = new CompilationUnitVirtualImpl();
585: cu.setFactory(getMainFactory());
586: return cu;
587: }
588:
589: }
|