Skip to content

Package: DelegationTransformer$10

DelegationTransformer$10

nameinstructionbranchcomplexitylinemethod
handle(GenFullParsedOperationState)
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
handle(GenSimpleOperationState)
M: 2 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
{...}
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: package de.fhdw.wtf.generator.transformer.transformers.classTransformer;
2:
3: import java.util.Collection;
4: import java.util.Iterator;
5: import java.util.List;
6: import java.util.Vector;
7:
8: import de.fhdw.wtf.common.ast.Attribute;
9: import de.fhdw.wtf.common.ast.ConstructorOrOperation;
10: import de.fhdw.wtf.common.ast.Group;
11: import de.fhdw.wtf.common.ast.Model;
12: import de.fhdw.wtf.common.ast.type.ClassType;
13: import de.fhdw.wtf.common.exception.walker.TaskException;
14: import de.fhdw.wtf.common.task.TaskExecutor;
15: import de.fhdw.wtf.generator.java.generatorModel.GenClass;
16: import de.fhdw.wtf.generator.java.generatorModel.GenClassClass;
17: import de.fhdw.wtf.generator.java.generatorModel.GenComment;
18: import de.fhdw.wtf.generator.java.generatorModel.GenException;
19: import de.fhdw.wtf.generator.java.generatorModel.GenExternalInterfaceClass;
20: import de.fhdw.wtf.generator.java.generatorModel.GenFullParsedOperationState;
21: import de.fhdw.wtf.generator.java.generatorModel.GenInterfaceClass;
22: import de.fhdw.wtf.generator.java.generatorModel.GenInterfaceWithClassImplClass;
23: import de.fhdw.wtf.generator.java.generatorModel.GenJavaOperation;
24: import de.fhdw.wtf.generator.java.generatorModel.GenOperationModifier;
25: import de.fhdw.wtf.generator.java.generatorModel.GenParameter;
26: import de.fhdw.wtf.generator.java.generatorModel.GenPrimitiveClass;
27: import de.fhdw.wtf.generator.java.generatorModel.GenSimpleInterfaceClass;
28: import de.fhdw.wtf.generator.java.generatorModel.GenSimpleOperationState;
29: import de.fhdw.wtf.generator.java.generatorModel.GenTypeReference;
30: import de.fhdw.wtf.generator.java.generatorModel.GenVisibility;
31: import de.fhdw.wtf.generator.java.generatorModel.GeneratorModel;
32: import de.fhdw.wtf.generator.java.visitor.GenClassVisitorException;
33: import de.fhdw.wtf.generator.java.visitor.GenClassVisitorReturn;
34: import de.fhdw.wtf.generator.java.visitor.GenInterfaceClassVisitorException;
35: import de.fhdw.wtf.generator.java.visitor.GenInterfaceClassVisitorReturn;
36: import de.fhdw.wtf.generator.java.visitor.GenOperationStateVisitor;
37: import de.fhdw.wtf.generator.java.visitor.GenOperationStateVisitorReturn;
38: import de.fhdw.wtf.generator.transformer.exception.GenTypeNotReferencedException;
39: import de.fhdw.wtf.walker.walker.SimpleWalkerTask;
40:
41: /**
42: * Transformer who realizes the delegation pattern for the generated model.
43: *
44: * @author hfw413sc
45: *
46: */
47: public class DelegationTransformer extends SimpleWalkerTask {
48:         
49:         /**
50:          * The referenced generator model.
51:          */
52:         private final GeneratorModel generatorModel;
53:         
54:         /**
55:          * The list of root types of the model.
56:          */
57:         private final List<ClassType> rootTypeList = new Vector<>();
58:         
59:         /**
60:          * Creates a DelegationTransformer.
61:          *
62:          * @param m
63:          * the model
64:          * @param taskmanager
65:          * the taskmanager
66:          * @param generatorModel
67:          * the generator model
68:          */
69:         public DelegationTransformer(final Model m, final TaskExecutor taskmanager, final GeneratorModel generatorModel) {
70:                 super(m, taskmanager);
71:                 this.generatorModel = generatorModel;
72:         }
73:         
74:         @Override
75:         public void handleClass(final ClassType c) throws TaskException {
76:                 final GenClass clazz = this.generatorModel.getJavaClassForWTFClass(c);
77:                 clazz.accept(new GenClassVisitorException<GenTypeNotReferencedException>() {
78:                         
79:                         @Override
80:                         public void handle(final GenClassClass classClass) throws GenTypeNotReferencedException {
81:                                 // nothing to do
82:                                 
83:                         }
84:                         
85:                         @Override
86:                         public void handle(final GenInterfaceClass interfaceClass) throws GenTypeNotReferencedException {
87:                                 interfaceClass.accept(new GenInterfaceClassVisitorException<GenTypeNotReferencedException>() {
88:                                         
89:                                         @Override
90:                                         public void handle(final GenSimpleInterfaceClass simpleInterface)
91:                                                         throws GenTypeNotReferencedException {
92:                                                 // nothing to do
93:                                         }
94:                                         
95:                                         @Override
96:                                         public void handle(final GenInterfaceWithClassImplClass interfaceWithImplClass)
97:                                                         throws GenTypeNotReferencedException {
98:                                                 if (DelegationTransformer.this.isInterfaceInheritanceRoot(interfaceWithImplClass)) {
99:                                                         DelegationTransformer.this.addToRootTypeList(c);
100:                                                 }
101:                                                 
102:                                         }
103:                                         
104:                                         @Override
105:                                         public void handle(final GenExternalInterfaceClass iface) throws GenTypeNotReferencedException {
106:                                                 // nothing to do
107:                                         }
108:                                 });
109:                                 
110:                         }
111:                         
112:                         @Override
113:                         public void handle(final GenPrimitiveClass primitiveClass) throws GenTypeNotReferencedException {
114:                                 // nothing to do
115:                         }
116:                 });
117:         }
118:         
119:         /**
120:          * Adds the type rootType to rootTypeList.
121:          *
122:          * @param rootType
123:          * type to be added
124:          */
125:         private void addToRootTypeList(final ClassType rootType) {
126:                 this.rootTypeList.add(rootType);
127:         }
128:         
129:         /**
130:          * Returns true if checkInterface is directly extending Anything.
131:          *
132:          * @param checkInterface
133:          * Interface to be checked
134:          * @return true if checkInterface is a root of the inheritance
135:          * @throws GenTypeNotReferencedException
136:          * possible exception
137:          */
138:         private boolean isInterfaceInheritanceRoot(final GenInterfaceWithClassImplClass checkInterface)
139:                         throws GenTypeNotReferencedException {
140:                 return checkInterface.getImplement().contains(
141:                                 this.generatorModel.getGenTypeForType(this.getModel().getAnything()));
142:         }
143:         
144:         @Override
145:         public void handleGroup(final Group g) throws TaskException {
146:                 // nothing to do
147:                 
148:         }
149:         
150:         @Override
151:         public void handleAttribute(final Attribute a, final ClassType owner) throws TaskException {
152:                 // nothing to do
153:                 
154:         }
155:         
156:         @Override
157:         public void handleConstructorOrOperation(final ConstructorOrOperation coo, final ClassType owner)
158:                         throws TaskException {
159:                 // nothing to do
160:                 
161:         }
162:         
163:         @Override
164:         public void finalizeTask() throws TaskException {
165:                 this.generateDelegationPatternForInheritanceTree();
166:                 
167:         }
168:         
169:         /**
170:          * Generates the whole delegation code for the inheritance tree based on the private list rootTypeList.
171:          */
172:         private void generateDelegationPatternForInheritanceTree() {
173:                 for (final ClassType type : this.rootTypeList) {
174:                         this.delegateOperationsInImplementingClasses(type);
175:                 }
176:                 
177:         }
178:         
179:         /**
180:          * Generates the whole delegation code in all implementing classes of type.
181:          *
182:          * @param type
183:          * super type for delegation code generation
184:          */
185:         private void delegateOperationsInImplementingClasses(final ClassType type) {
186:                 final GenClassVisitorReturn<GenInterfaceWithClassImplClass> genInterfaceWithClassImplClassReturnVisitor =
187:                                 new GenClassVisitorReturn<GenInterfaceWithClassImplClass>() {
188:                                         
189:                                         @Override
190:                                         public GenInterfaceWithClassImplClass handle(final GenClassClass classClass) {
191:                                                 return null;
192:                                         }
193:                                         
194:                                         @Override
195:                                         public GenInterfaceWithClassImplClass handle(final GenInterfaceClass interfaceClass) {
196:                                                 return interfaceClass
197:                                                                 .accept(new GenInterfaceClassVisitorReturn<GenInterfaceWithClassImplClass>() {
198:                                                                         
199:                                                                         @Override
200:                                                                         public GenInterfaceWithClassImplClass handle(final GenSimpleInterfaceClass simpleInterface) {
201:                                                                                 return null;
202:                                                                         }
203:                                                                         
204:                                                                         @Override
205:                                                                         public GenInterfaceWithClassImplClass handle(final GenInterfaceWithClassImplClass interfaceWithImplClass) {
206:                                                                                 return interfaceWithImplClass;
207:                                                                         }
208:                                                                         
209:                                                                         @Override
210:                                                                         public GenInterfaceWithClassImplClass handle(final GenExternalInterfaceClass iface) {
211:                                                                                 return null;
212:                                                                         }
213:                                                                 });
214:                                         }
215:                                         
216:                                         @Override
217:                                         public GenInterfaceWithClassImplClass handle(final GenPrimitiveClass primitiveClass) {
218:                                                 return null;
219:                                         }
220:                                 };
221:                 final GenInterfaceWithClassImplClass superInterface =
222:                                 this.generatorModel.getJavaClassForWTFClass(type).accept(genInterfaceWithClassImplClassReturnVisitor);
223:                 for (final ClassType sub : type.getSubTypes()) {
224:                         final GenInterfaceWithClassImplClass subInterface =
225:                                         this.generatorModel.getJavaClassForWTFClass(sub)
226:                                                         .accept(genInterfaceWithClassImplClassReturnVisitor);
227:                         
228:                         DelegationTransformer.this.delegateFromSuperToSub(
229:                                         superInterface.getClassRepresentation(),
230:                                         subInterface.getClassRepresentation());
231:                         
232:                         DelegationTransformer.this.delegateOperationsInImplementingClasses(sub);
233:                 }
234:         }
235:         
236:         /**
237:          * Adds everything necessary for inheritance delegation to the classes and the model for the inheritance between
238:          * genSubClassClass and genSuperClassClass.
239:          *
240:          *
241:          * @param superClass
242:          * superClass
243:          * @param sub
244:          * subClass
245:          *
246:          */
247:         private void delegateFromSuperToSub(final GenClassClass superClass, final GenClassClass sub) {
248:                 
249:                 final Iterator<GenJavaOperation> i = superClass.getOperations().iterator();
250:                 while (i.hasNext()) {
251:                         final GenJavaOperation genJavaOperation = i.next();
252:                         
253:                         boolean sameNameFound = false;
254:                         
255:                         final Iterator<GenJavaOperation> i2 = sub.getOperations().iterator();
256:                         while (!sameNameFound && i2.hasNext()) {
257:                                 final GenJavaOperation genJavaOperation2 = i2.next();
258:                                 if (genJavaOperation.getName().equals("accept")) {
259:                                         sameNameFound = genJavaOperation2.toString().equals(genJavaOperation.toString());
260:                                 } else {
261:                                         sameNameFound = genJavaOperation2.getName().equals(genJavaOperation.getName());
262:                                 }
263:                                 
264:                         }
265:                         if (!sameNameFound) {
266:                                 
267:                                 genJavaOperation.getState().accept(new GenOperationStateVisitor() {
268:                                         
269:                                         @Override
270:                                         public void handle(final GenSimpleOperationState s) {
271:                                                 // nothing to do
272:                                         }
273:                                         
274:                                         @Override
275:                                         public void handle(final GenFullParsedOperationState s) {
276:                                                 if (s.getModifiers().contains(GenOperationModifier.ABSTRACT)) {
277:                                                         DelegationTransformer.this.handleAbstractOperation(genJavaOperation, sub, superClass);
278:                                                 } else {
279:                                                         final GenJavaOperation operationWithDelegationMethod =
280:                                                                         DelegationTransformer.this.cloneAndChangeToDelegation(genJavaOperation, superClass);
281:                                                         sub.addOperation(operationWithDelegationMethod);
282:                                                 }
283:                                         }
284:                                 });
285:                                 
286:                         }
287:                 }
288:                 
289:         }
290:         
291:         /**
292:          * Handles abstract operation in subclass and superclass.
293:          *
294:          * @param genJavaOperation
295:          * operation handled
296:          * @param sub
297:          * subclass
298:          * @param superClass
299:          * superclass
300:          */
301:         private void handleAbstractOperation(final GenJavaOperation genJavaOperation,
302:                         final GenClassClass sub,
303:                         final GenClassClass superClass) {
304:                 final String name = genJavaOperation.getName();
305:                 final List<GenParameter> parameters = genJavaOperation.getParameters();
306:                 final GenComment comment = genJavaOperation.getState().accept(new GenOperationStateVisitorReturn<GenComment>() {
307:                         
308:                         @Override
309:                         public GenComment handle(final GenSimpleOperationState s) {
310:                                 return null;
311:                         }
312:                         
313:                         @Override
314:                         public GenComment handle(final GenFullParsedOperationState s) {
315:                                 return s.getComment();
316:                         }
317:                 });
318:                 final Collection<GenException> exceptions =
319:                                 genJavaOperation.getState().accept(new GenOperationStateVisitorReturn<Collection<GenException>>() {
320:                                         
321:                                         @Override
322:                                         public Collection<GenException> handle(final GenSimpleOperationState s) {
323:                                                 return null;
324:                                         }
325:                                         
326:                                         @Override
327:                                         public Collection<GenException> handle(final GenFullParsedOperationState s) {
328:                                                 return s.getExceptions();
329:                                         }
330:                                 });
331:                 final GenTypeReference returntyp =
332:                                 genJavaOperation.getState().accept(new GenOperationStateVisitorReturn<GenTypeReference>() {
333:                                         
334:                                         @Override
335:                                         public GenTypeReference handle(final GenSimpleOperationState s) {
336:                                                 return null;
337:                                         }
338:                                         
339:                                         @Override
340:                                         public GenTypeReference handle(final GenFullParsedOperationState s) {
341:                                                 return s.getReturntyp();
342:                                         }
343:                                 });
344:                 final Collection<GenOperationModifier> modifiers =
345:                                 genJavaOperation.getState().accept(
346:                                                 new GenOperationStateVisitorReturn<Collection<GenOperationModifier>>() {
347:                                                         
348:                                                         @Override
349:                                                         public Collection<GenOperationModifier> handle(final GenSimpleOperationState s) {
350:                                                                 return null;
351:                                                         }
352:                                                         
353:                                                         @Override
354:                                                         public Collection<GenOperationModifier> handle(final GenFullParsedOperationState s) {
355:                                                                 return s.getModifiers();
356:                                                         }
357:                                                 });
358:                 final GenVisibility visibility =
359:                                 genJavaOperation.getState().accept(new GenOperationStateVisitorReturn<GenVisibility>() {
360:                                         
361:                                         @Override
362:                                         public GenVisibility handle(final GenSimpleOperationState s) {
363:                                                 return null;
364:                                         }
365:                                         
366:                                         @Override
367:                                         public GenVisibility handle(final GenFullParsedOperationState s) {
368:                                                 return s.getVisibility();
369:                                         }
370:                                 });
371:                 
372:                 final String methodbodyForSub =
373:                                 "//TODO implement operation " + name
374:                                                 + (returntyp.getFullyQualifiedName().equals("void") ? "" : "\n\t\treturn null;");
375:                 final GenFullParsedOperationState stateForSub =
376:                                 GenFullParsedOperationState.create(
377:                                                 comment,
378:                                                 exceptions,
379:                                                 returntyp,
380:                                                 modifiers,
381:                                                 visibility,
382:                                                 methodbodyForSub);
383:                 final GenJavaOperation operationForSub = GenJavaOperation.create(name, parameters, stateForSub);
384:                 sub.addOperation(operationForSub);
385:                 
386:                 final String methodbodyForSuper =
387:                                 "if(this.getThis()==this)throw new Error();" + "\n\t\t"
388:                                                 + (returntyp.getFullyQualifiedName().equals("void") ? "" : "return ") + "this.getThis()."
389:                                                 + name + "();";
390:                 final GenFullParsedOperationState stateForSuper =
391:                                 GenFullParsedOperationState.create(
392:                                                 comment,
393:                                                 exceptions,
394:                                                 returntyp,
395:                                                 modifiers,
396:                                                 visibility,
397:                                                 methodbodyForSuper);
398:                 final GenJavaOperation operationForSuper = GenJavaOperation.create(name, parameters, stateForSuper);
399:                 superClass.overrideExistingOperation(operationForSuper);
400:                 
401:         }
402:         
403:         /**
404:          * Copies the operation genJavaOperation and change method to delegation.
405:          *
406:          * @param genJavaOperation
407:          * operation from superClass
408:          * @param owner
409:          * needed for references
410:          * @return operation with delegation method
411:          */
412:         private GenJavaOperation cloneAndChangeToDelegation(final GenJavaOperation genJavaOperation,
413:                         final GenClassClass owner) {
414:                 final Collection<GenOperationModifier> modifiers = new Vector<>();
415:                 modifiers.addAll(genJavaOperation.getState().accept(
416:                                 new GenOperationStateVisitorReturn<Collection<GenOperationModifier>>() {
417:                                         
418:                                         @Override
419:                                         public Collection<GenOperationModifier> handle(final GenSimpleOperationState s) {
420:                                                 return null;
421:                                         }
422:                                         
423:                                         @Override
424:                                         public Collection<GenOperationModifier> handle(final GenFullParsedOperationState s) {
425:                                                 return s.getModifiers();
426:                                         }
427:                                 }));
428:                 final GenTypeReference returnType =
429:                                 genJavaOperation.getState().accept(new GenOperationStateVisitorReturn<GenTypeReference>() {
430:                                         
431:                                         @Override
432:                                         public GenTypeReference handle(final GenSimpleOperationState s) {
433:                                                 return null;
434:                                         }
435:                                         
436:                                         @Override
437:                                         public GenTypeReference handle(final GenFullParsedOperationState s) {
438:                                                 return s.getReturntyp();
439:                                         }
440:                                 });
441:                 String parameterNamesList = "";
442:                 for (final GenParameter p : genJavaOperation.getParameters()) {
443:                         parameterNamesList = parameterNamesList + ", " + p.getName();
444:                 }
445:                 if (parameterNamesList.length() > 0) {
446:                         parameterNamesList = parameterNamesList.replaceFirst("," + " ", "");
447:                 }
448:                 final String methodbody =
449:                                 (returnType.getFullyQualifiedName().equals("void") ? "" : "return ") + "(("
450:                                                 + owner.getFullyQualifiedTypeName()
451:                                                 + ") this.get$generatedObjects().get(new de.fhdw.wtf.context.model.Str(\""
452:                                                 + owner.getFullyQualifiedTypeName() + "\")))." + genJavaOperation.getName() + "("
453:                                                 + parameterNamesList + ");";
454:                 
455:                 final GenJavaOperation result =
456:                                 GenJavaOperation.create(
457:                                                 genJavaOperation.getName(),
458:                                                 genJavaOperation.getParameters(),
459:                                                 GenFullParsedOperationState.create(
460:                                                                 genJavaOperation.getState().accept(new GenOperationStateVisitorReturn<GenComment>() {
461:                                                                         
462:                                                                         @Override
463:                                                                         public GenComment handle(final GenSimpleOperationState s) {
464:                                                                                 return null;
465:                                                                         }
466:                                                                         
467:                                                                         @Override
468:                                                                         public GenComment handle(final GenFullParsedOperationState s) {
469:                                                                                 return s.getComment();
470:                                                                         }
471:                                                                 }),
472:                                                                 genJavaOperation.getState().accept(
473:                                                                                 new GenOperationStateVisitorReturn<Collection<GenException>>() {
474:                                                                                         
475:                                                                                         @Override
476:                                                                                         public Collection<GenException> handle(final GenSimpleOperationState s) {
477:                                                                                                 return new Vector<>();
478:                                                                                         }
479:                                                                                         
480:                                                                                         @Override
481:                                                                                         public Collection<GenException> handle(final GenFullParsedOperationState s) {
482:                                                                                                 return s.getExceptions();
483:                                                                                         }
484:                                                                                 }),
485:                                                                 returnType,
486:                                                                 modifiers,
487:                                                                 genJavaOperation.getState().accept(new GenOperationStateVisitorReturn<GenVisibility>() {
488:                                                                         
489:                                                                         @Override
490:                                                                         public GenVisibility handle(final GenSimpleOperationState s) {
491:                                                                                 return GenVisibility.DEFAULT;
492:                                                                         }
493:                                                                         
494:                                                                         @Override
495:                                                                         public GenVisibility handle(final GenFullParsedOperationState s) {
496:                                                                                 return s.getVisibility();
497:                                                                         }
498:                                                                 }),
499:                                                                 methodbody));
500:                 result.getGenerics().addAll(genJavaOperation.getGenerics());
501:                 return result;
502:         }
503:         
504:         @Override
505:         public void beginTask() throws TaskException {
506:                 // nothing to do
507:                 
508:         }
509:         
510: }