Skip to content

Method: handle(GenInterfaceClass)

1: package de.fhdw.wtf.generator.transformer.transformers.classTransformer;
2:
3: import java.math.BigInteger;
4: import java.util.ArrayList;
5: import java.util.Arrays;
6: import java.util.Collection;
7: import java.util.Iterator;
8: import java.util.List;
9: import java.util.Vector;
10:
11: import de.fhdw.wtf.common.ast.Attribute;
12: import de.fhdw.wtf.common.ast.AttributeModifier;
13: import de.fhdw.wtf.common.ast.AttributeModifierFindable;
14: import de.fhdw.wtf.common.ast.AttributeModifierMutable;
15: import de.fhdw.wtf.common.ast.AttributeModifierPrior;
16: import de.fhdw.wtf.common.ast.AttributeModifierSymmetric;
17: import de.fhdw.wtf.common.ast.AttributeModifierTransient;
18: import de.fhdw.wtf.common.ast.Model;
19: import de.fhdw.wtf.common.ast.Operation;
20: import de.fhdw.wtf.common.ast.type.AtomicType;
21: import de.fhdw.wtf.common.ast.type.BaseType;
22: import de.fhdw.wtf.common.ast.type.ClassType;
23: import de.fhdw.wtf.common.ast.type.CompositeType;
24: import de.fhdw.wtf.common.ast.type.ListType;
25: import de.fhdw.wtf.common.ast.type.MapType;
26: import de.fhdw.wtf.common.ast.type.ProductElementType;
27: import de.fhdw.wtf.common.ast.type.ProductType;
28: import de.fhdw.wtf.common.ast.type.SumType;
29: import de.fhdw.wtf.common.ast.type.ThrownType;
30: import de.fhdw.wtf.common.ast.type.Type;
31: import de.fhdw.wtf.common.ast.type.TypeProxy;
32: import de.fhdw.wtf.common.ast.visitor.AtomicTypeVisitorException;
33: import de.fhdw.wtf.common.ast.visitor.AttributModifierVisitor;
34: import de.fhdw.wtf.common.ast.visitor.CompositeTypeVisitorException;
35: import de.fhdw.wtf.common.ast.visitor.OperationModifierVisitor;
36: import de.fhdw.wtf.common.ast.visitor.TypeVisitorException;
37: import de.fhdw.wtf.common.exception.walker.CyclicDependencyException;
38: import de.fhdw.wtf.common.exception.walker.TaskException;
39: import de.fhdw.wtf.common.task.TaskExecutor;
40: import de.fhdw.wtf.generator.java.generatorModel.GenAttributeModifier;
41: import de.fhdw.wtf.generator.java.generatorModel.GenClass;
42: import de.fhdw.wtf.generator.java.generatorModel.GenClassClass;
43: import de.fhdw.wtf.generator.java.generatorModel.GenClassModifier;
44: import de.fhdw.wtf.generator.java.generatorModel.GenComment;
45: import de.fhdw.wtf.generator.java.generatorModel.GenException;
46: import de.fhdw.wtf.generator.java.generatorModel.GenExternalClassClass;
47: import de.fhdw.wtf.generator.java.generatorModel.GenExternalInterfaceClass;
48: import de.fhdw.wtf.generator.java.generatorModel.GenInterfaceClass;
49: import de.fhdw.wtf.generator.java.generatorModel.GenInterfaceWithClassImplClass;
50: import de.fhdw.wtf.generator.java.generatorModel.GenJavaAttribute;
51: import de.fhdw.wtf.generator.java.generatorModel.GenJavaOperation;
52: import de.fhdw.wtf.generator.java.generatorModel.GenJavaUtilCollection;
53: import de.fhdw.wtf.generator.java.generatorModel.GenOperationModifier;
54: import de.fhdw.wtf.generator.java.generatorModel.GenPackage;
55: import de.fhdw.wtf.generator.java.generatorModel.GenParameter;
56: import de.fhdw.wtf.generator.java.generatorModel.GenPrimitiveClass;
57: import de.fhdw.wtf.generator.java.generatorModel.GenSimpleInterfaceClass;
58: import de.fhdw.wtf.generator.java.generatorModel.GenType;
59: import de.fhdw.wtf.generator.java.generatorModel.GenUnqualifiedPackage;
60: import de.fhdw.wtf.generator.java.generatorModel.GenUserClass;
61: import de.fhdw.wtf.generator.java.generatorModel.GenVisibility;
62: import de.fhdw.wtf.generator.java.generatorModel.GenVoidType;
63: import de.fhdw.wtf.generator.java.generatorModel.GeneratorModel;
64: import de.fhdw.wtf.generator.java.visitor.GenClassVisitor;
65: import de.fhdw.wtf.generator.java.visitor.GenClassVisitorException;
66: import de.fhdw.wtf.generator.java.visitor.GenInterfaceClassVisitor;
67: import de.fhdw.wtf.generator.java.visitor.GenInterfaceClassVisitorException;
68: import de.fhdw.wtf.generator.transformer.exception.GenTypeNotReferencedException;
69: import de.fhdw.wtf.generator.transformer.exception.NoAttributeAllowedInInterface;
70: import de.fhdw.wtf.walker.walker.SimpleWalkerTaskForTypes;
71:
72: public final class OperationAttributeTransformer extends SimpleWalkerTaskForTypes {
73:         
74:         private final GeneratorModel generatorModel;
75:         
76:         /**
77:          * String that represents the default method implementation.
78:          */
79:         private static final String DEFAULT_METHOD = "//TODO implement";
80:         
81:         /**
82:          * String that represents the name of the parameter of a load constructor.
83:          */
84:         public static final String LOAD_CONSTRUCTOR_PARAM_NAME = "userObject";
85:         
86:         /**
87:          * String that represents the type of the parameter of a load constructor.
88:          */
89:         public static final String LOAD_CONSTRUCTOR_PARAM_TYPE = "de.fhdw.wtf.persistence.meta.UserObject";
90:         
91:         /**
92:          * String that represents the default load constructor implementation.
93:          */
94:         private static final String DEFAULT_LOAD_CONSTRUCTOR = "super(" + LOAD_CONSTRUCTOR_PARAM_NAME + ");";
95:         
96:         /**
97:          * String that represents the default comment for an operation.
98:          */
99:         private static final String DEFAULT_OPERATION_COMMENT = "/** \n \t * TODO Comment Op \n\t */";
100:         
101:         /**
102:          * The default comment for constructor loading object from database.
103:          */
104:         private static final String DEFAULT_LOAD_CONSTRUCTOR_COMMENT =
105:                         "/** \n \t * Loads object from database.\n \t * @param userObject The underlying user object.\n\t */";
106:         
107:         /**
108:          * String that represents a java code line end.
109:          */
110:         private static final char JAVA_LINE_END = ';';
111:         
112:         /**
113:          * String that represents the default commit for a constructor of a product.
114:          */
115:         private static final String DEFAULT_PRODUCT_CONSTRUCTOR_COMMENT = "Create a anonym product.";
116:         
117:         /**
118:          * String that represents an equal Symbol.
119:          */
120:         private static final String EQUAL_SYMBOL = "=";
121:         
122:         /**
123:          * String that represents a this.
124:          */
125:         private static final String THIS_POINT = "this.";
126:         
127:         /**
128:          * String that represents a tab.
129:          */
130:         private static final String TAB = "\t";
131:         
132:         /**
133:          * String that represents a new line.
134:          */
135:         private static final String NEW_LINE = "\n";
136:         
137:         private OperationAttributeTransformer(final Model m,
138:                         final TaskExecutor taskmanager,
139:                         final GeneratorModel generatorModel,
140:                         final TypeTransformer typeTransformer) {
141:                 super(m, taskmanager, true);
142:                 this.generatorModel = generatorModel;
143:                 
144:                 try {
145:                         this.addDependency(typeTransformer);
146:                 } catch (final CyclicDependencyException e) {
147:                         // should not happen
148:                         e.printStackTrace();
149:                         throw new Error("Dependency tasks are cyclic in OperationAttributeTransformer.");
150:                 }
151:         }
152:         
153:         public static OperationAttributeTransformer create(final Model m,
154:                         final TaskExecutor taskmanager,
155:                         final GeneratorModel generatorModel,
156:                         final TypeTransformer typeTransformer) {
157:                 return new OperationAttributeTransformer(m, taskmanager, generatorModel, typeTransformer);
158:         }
159:         
160:         public GeneratorModel getGeneratorModel() {
161:                 return this.generatorModel;
162:         }
163:         
164:         @Override
165:         public void handleType(final Type c) throws TaskException {
166:                 c.accept(new TypeVisitorException<TaskException>() {
167:                         
168:                         @Override
169:                         public void handle(final AtomicType atomicType) throws TaskException {
170:                                 atomicType.accept(new AtomicTypeVisitorException<TaskException>() {
171:                                         
172:                                         @Override
173:                                         public void handle(final BaseType baseType) {
174:                                                 // BaseTypes are not generated
175:                                         }
176:                                         
177:                                         @Override
178:                                         public void handle(final ClassType clazz) throws TaskException {
179:                                                 final Iterator<Attribute> attributeIt = clazz.getAttributes().iterator();
180:                                                 while (attributeIt.hasNext()) {
181:                                                         final Attribute current = attributeIt.next();
182:                                                         OperationAttributeTransformer.this.handleAttribute(current, clazz);
183:                                                 }
184:                                                 
185:                                                 final Iterator<Operation> operationIt = clazz.getOperations().iterator();
186:                                                 while (operationIt.hasNext()) {
187:                                                         final Operation current = operationIt.next();
188:                                                         OperationAttributeTransformer.this.handleOperation(current, clazz);
189:                                                 }
190:                                                 final GenClass genOwner =
191:                                                                 OperationAttributeTransformer.this.getGeneratorModel().getClassMapping().get(clazz);
192:                                                 genOwner.accept(new GenClassVisitorException<TaskException>() {
193:                                                         
194:                                                         @Override
195:                                                         public void handle(final GenClassClass classClass) throws TaskException {
196:                                                                 OperationAttributeTransformer.this.createLoadConstructor(classClass);
197:                                                         }
198:                                                         
199:                                                         @Override
200:                                                         public void handle(final GenInterfaceClass interfaceClass) throws TaskException {
201:                                                                 interfaceClass.accept(new GenInterfaceClassVisitorException<TaskException>() {
202:                                                                         
203:                                                                         @Override
204:                                                                         public void handle(final GenSimpleInterfaceClass simpleInterface)
205:                                                                                         throws TaskException {
206:                                                                                 // Nothing to do.
207:                                                                                 // TODO Really nothing to do?
208:                                                                         }
209:                                                                         
210:                                                                         @Override
211:                                                                         public void handle(final GenInterfaceWithClassImplClass interfaceWithImplClass)
212:                                                                                         throws TaskException {
213:                                                                                 OperationAttributeTransformer.this.createLoadConstructor(interfaceWithImplClass
214:                                                                                                 .getImplementor());
215:                                                                         }
216:                                                                         
217:                                                                         @Override
218:                                                                         public void handle(final GenExternalInterfaceClass iface) throws TaskException {
219:                                                                                 // Nothing to do.
220:                                                                         }
221:                                                                         
222:                                                                 });
223:                                                         }
224:                                                         
225:                                                         @Override
226:                                                         public void handle(final GenPrimitiveClass primitiveClass) throws TaskException {
227:                                                                 OperationAttributeTransformer.this.createLoadConstructor(primitiveClass
228:                                                                                 .getImplementor());
229:                                                         }
230:                                                 });
231:                                         }
232:                                 });
233:                         }
234:                         
235:                         @Override
236:                         public void handle(final CompositeType compositeType) throws TaskException {
237:                                 compositeType.accept(new CompositeTypeVisitorException<TaskException>() {
238:                                         
239:                                         @Override
240:                                         public void handle(final SumType sum) {
241:                                                 // Sums do not have operations other than accept-Methods that are generated in
242:                                                 // VisitorTypeTransformer
243:                                         }
244:                                         
245:                                         @Override
246:                                         public void handle(final ProductType product) throws TaskException {
247:                                                 final GenClassClass prod =
248:                                                                 (GenClassClass) OperationAttributeTransformer.this.getGeneratorModel()
249:                                                                                 .getGenTypeForType(product);
250:                                                 if (product.equals(product.getAbstractPrototype())) {
251:                                                         // only add attributes to Products if they are the AbstractProductPrototype
252:                                                         OperationAttributeTransformer.this.handleProductAttributes(product, prod);
253:                                                 } else {
254:                                                         // only add getters and setters to Products if they are not the AbstractProductPrototype
255:                                                         OperationAttributeTransformer.this.generateProductsGettersAndSetters(product, prod);
256:                                                 }
257:                                                 // always create load constructor, regardless whether product type is or is not an abstract
258:                                                 // prototype or not
259:                                                 OperationAttributeTransformer.this.createLoadConstructor(prod);
260:                                         }
261:                                         
262:                                         @Override
263:                                         public void handle(final MapType map) {
264:                                                 // Maps are not generated
265:                                         }
266:                                         
267:                                         @Override
268:                                         public void handle(final ListType list) {
269:                                                 // Lists are not generated
270:                                         }
271:                                         
272:                                         @Override
273:                                         public void handle(final ThrownType thrownType) {
274:                                                 // ThrownTypes are not generated
275:                                         }
276:                                 });
277:                         }
278:                         
279:                         @Override
280:                         public void handle(final TypeProxy typeProxy) throws TaskException {
281:                                 // No need to handle TypeProxy
282:                                 
283:                         }
284:                 });
285:         }
286:         
287:         /**
288:          * Creates a special load constructor and adds it to a non-interface class.
289:          *
290:          * @param classClass
291:          * The GenClassClass object to add the constructor to.
292:          */
293:         private void createLoadConstructor(final GenClassClass classClass) {
294:                 // generate special constructor for loading object from database
295:                 final GenComment comment = GenComment.create(DEFAULT_LOAD_CONSTRUCTOR_COMMENT);
296:                 final GenType returnTyp = classClass;
297:                 final String method = DEFAULT_LOAD_CONSTRUCTOR;
298:                 final List<GenParameter> parameters = new Vector<>();
299:                 parameters.add(GenParameter.create(
300:                                 LOAD_CONSTRUCTOR_PARAM_NAME,
301:                                 GenExternalClassClass.getInstance(LOAD_CONSTRUCTOR_PARAM_TYPE)));
302:                 classClass.addConstructor(GenJavaOperation.create(
303:                                 "",
304:                                 GenVisibility.PUBLIC,
305:                                 parameters,
306:                                 new Vector<GenException>(),
307:                                 method,
308:                                 returnTyp,
309:                                 new Vector<GenOperationModifier>(),
310:                                 comment));
311:         }
312:         
313:         public void handleAttribute(final Attribute a, final ClassType owner) throws TaskException {
314:                 final String name = a.getName();
315:                 final GenType attrType = this.getGeneratorModel().getGenTypeForType(a.getAttrType());
316:                 final Collection<GenAttributeModifier> modifiers = this.handleAttributModifier(a, owner);
317:                 final GenJavaAttribute result = GenJavaAttribute.create(name, GenVisibility.PRIVATE, attrType, modifiers);
318:                 this.getGeneratorModel().getClassMapping().get(owner)
319:                                 .accept(new HandleAttributeGetOwnerGenClassVisitorException(result, a));
320:         }
321:         
322:         private final class HandleAttributeGetOwnerGenClassVisitorException implements
323:                         GenClassVisitorException<TaskException> {
324:                 private final GenJavaAttribute result;
325:                 private final Attribute a;
326:                 
327:                 private HandleAttributeGetOwnerGenClassVisitorException(final GenJavaAttribute result, final Attribute a) {
328:                         this.result = result;
329:                         this.a = a;
330:                 }
331:                 
332:                 @Override
333:                 public void handle(final GenClassClass classClass) throws TaskException {
334:                         classClass.getAttributes().add(this.result);
335:                         
336:                 }
337:                 
338:                 @Override
339:                 public void handle(final GenInterfaceClass interfaceClass) throws TaskException {
340:                         interfaceClass.accept(new GenInterfaceClassVisitorException<TaskException>() {
341:                                 
342:                                 @Override
343:                                 public void handle(final GenSimpleInterfaceClass simpleInterface) throws TaskException {
344:                                         throw NoAttributeAllowedInInterface.create();
345:                                 }
346:                                 
347:                                 @Override
348:                                 public void handle(final GenInterfaceWithClassImplClass interfaceWithImplClass) throws TaskException {
349:                                         HandleAttributeGetOwnerGenClassVisitorException.this.handle(interfaceWithImplClass
350:                                                         .getClassRepresentation());
351:                                 }
352:                                 
353:                                 @Override
354:                                 public void handle(final GenExternalInterfaceClass iface) throws TaskException {
355:                                         throw NoAttributeAllowedInInterface.create();
356:                                 }
357:                         });
358:                 }
359:                 
360:                 @Override
361:                 public void handle(final GenPrimitiveClass primitiveClass) throws NoAttributeAllowedInInterface {
362:                         // nothing to do
363:                 }
364:         }
365:         
366:         /**
367:          * Handles the occourence of {@link AttributeModifier}.
368:          *
369:          * @param a
370:          * @param owner
371:          * @return List of {@link AttributeModifier}
372:          */
373:         private Vector<GenAttributeModifier> handleAttributModifier(final Attribute a, final ClassType owner) {
374:                 final Vector<GenAttributeModifier> modifier = new Vector<>();
375:                 final GenAttributeModifier finalAttr = GenAttributeModifier.FINAL;
376:                 modifier.add(finalAttr);
377:                 final Iterator<AttributeModifier> i = a.getModifiers().iterator();
378:                 while (i.hasNext()) {
379:                         final AttributeModifier current = i.next();
380:                         current.accept(new AttributModifierVisitor() {
381:                                 @Override
382:                                 public boolean handle(final AttributeModifierMutable mutable) {
383:                                         return modifier.remove(finalAttr);
384:                                 }
385:                                 
386:                                 @Override
387:                                 public boolean handle(final AttributeModifierFindable findable) {
388:                                         return true;
389:                                 }
390:                                 
391:                                 @Override
392:                                 public boolean handle(final AttributeModifierTransient tranzient) {
393:                                         return modifier.add(GenAttributeModifier.TRANSIENT);
394:                                 }
395:                                 
396:                                 @Override
397:                                 public boolean handle(final AttributeModifierPrior prior) {
398:                                         // Final Attribute already in the list
399:                                         return true;
400:                                 }
401:                                 
402:                                 @Override
403:                                 public boolean handle(final AttributeModifierSymmetric symmetric) {
404:                                         return OperationAttributeTransformer.this.handleSymmetricAttributeModifier(a, symmetric, owner);
405:                                 }
406:                         });
407:                 }
408:                 modifier.remove(finalAttr);
409:                 return modifier;
410:         }
411:         
412:         private boolean handleSymmetricAttributeModifier(final Attribute a,
413:                         final AttributeModifierSymmetric modifier,
414:                         final ClassType owner) {
415:                 try {
416:                         final Vector<ClassType> targetClasses = this.getTargetClasses(a.getAttrType());
417:                         for (final ClassType targetClass : targetClasses) {
418:                                 this.addInverseGetterTo(a, targetClass, modifier, owner);
419:                         }
420:                 } catch (final GenTypeNotReferencedException e) {
421:                         e.printStackTrace();
422:                 }
423:                 return false;
424:         }
425:         
426:         private void addInverseGetterTo(final Attribute attribute,
427:                         final ClassType targetClass,
428:                         final AttributeModifierSymmetric modifier,
429:                         final ClassType owner) {
430:                 final GenClass symmetricRelationAccessClass = this.getSymmetricRelationAccessClassOfClass(owner, targetClass);
431:                 final String targetClassName = targetClass.getName().getLastAddedName().toString().toLowerCase();
432:                 final String inverseGetterIdentifier = modifier.getIdentifierToken().getIdentifier();
433:                 
434:                 GenType returnType;
435:                 String superMethodName;
436:                 Boolean isStarAssociation;
437:                 
438:                 // Entscheidung ob 0..1 oder * Assoziation
439:                 if (attribute.getAttrType() instanceof CompositeType) { // *
440:                         returnType = GenJavaUtilCollection.create(this.getGeneratorModel().getJavaClassForWTFClass(owner));
441:                         superMethodName = "inverseGetCollection";
442:                         isStarAssociation = true;
443:                 } else {
444:                         returnType = this.getGeneratorModel().getJavaClassForWTFClass(owner).getImplementor();
445:                         superMethodName = "<" + returnType.getFullyQualifiedTypeNameWithGenericArguments() + ">inverseGet";
446:                         isStarAssociation = false;
447:                 }
448:                 final Vector<GenParameter> registerSetterParameters = new Vector<>();
449:                 // TODO final GenParameter ownerParameter0 = GenParameter.create("setter", target.getSetter());
450:                 final GenParameter targetParameter0 =
451:                                 GenParameter.create("target", this.getGeneratorModel().getJavaClassForWTFClass(targetClass));
452:                 // registerSetterParameters.add(ownerParameter0);
453:                 registerSetterParameters.add(targetParameter0);
454:                 final GenJavaOperation registerSetterMethod =
455:                                 GenJavaOperation.create(
456:                                                 "registerSetter" + attribute.getName(),
457:                                                 GenVisibility.PUBLIC,
458:                                                 registerSetterParameters,
459:                                                 new Vector<GenException>(),
460:                                                 "",
461:                                                 GenVoidType.getInstance(),
462:                                                 new Vector<GenOperationModifier>(),
463:                                                 GenComment.create(""));
464:                 symmetricRelationAccessClass.addOperation(registerSetterMethod);
465:                 
466:                 // Bei 1 Assoziation set erstellen
467:                 if (!isStarAssociation) {
468:                         final Vector<GenParameter> parameters = new Vector<>();
469:                         final GenParameter ownerParameter =
470:                                         GenParameter.create("owner", this.getGeneratorModel().getJavaClassForWTFClass(owner));
471:                         final GenParameter targetParameter =
472:                                         GenParameter.create("target", this.getGeneratorModel().getJavaClassForWTFClass(targetClass));
473:                         parameters.add(ownerParameter);
474:                         parameters.add(targetParameter);
475:                         final String methodContent = "//TODO methodContent wird noch implementiert";
476:                         // TODO method
477:                         final GenJavaOperation setMethod =
478:                                         GenJavaOperation.create(
479:                                                         "set" + attribute.getName(),
480:                                                         GenVisibility.PUBLIC,
481:                                                         parameters,
482:                                                         new Vector<GenException>(),
483:                                                         methodContent,
484:                                                         GenVoidType.getInstance(),
485:                                                         new Vector<GenOperationModifier>(),
486:                                                         GenComment.create(""));
487:                         symmetricRelationAccessClass.addOperation(setMethod);
488:                         
489:                         // final Collection<GenAttributeModifier> genAttrModifier = null;
490:                         // final GenJavaAttribute hashMap =
491:                         // GenJavaAttribute.create(
492:                         // "mapHALLO" + attribute.getName(),
493:                         // GenVisibility.PRIVATE,
494:                         // GenVoidType.getInstance(),
495:                         // genAttrModifier);
496:                         //
497:                         // ((GenClassClass) symmetricRelationAccessClass).getAttributes().add(hashMap);
498:                         
499:                 } else {
500:                         // TODO hier muss noch add und remove für * Assoziation implementiert werden
501:                         final Vector<GenParameter> parameters1 = new Vector<>();
502:                         final GenParameter ownerParameter1 =
503:                                         GenParameter.create("owner", this.getGeneratorModel().getJavaClassForWTFClass(owner));
504:                         final GenParameter targetParameter1 =
505:                                         GenParameter.create("target", this.getGeneratorModel().getJavaClassForWTFClass(targetClass));
506:                         parameters1.add(ownerParameter1);
507:                         parameters1.add(targetParameter1);
508:                         final String methodContentAdd = "//TODO methodContent wird noch implementiert.";
509:                         // TODO method
510:                         final GenJavaOperation addMethod =
511:                                         GenJavaOperation.create(
512:                                                         "add" + attribute.getName(),
513:                                                         GenVisibility.PUBLIC,
514:                                                         parameters1,
515:                                                         new Vector<GenException>(),
516:                                                         methodContentAdd,
517:                                                         GenVoidType.getInstance(),
518:                                                         new Vector<GenOperationModifier>(),
519:                                                         GenComment.create(""));
520:                         
521:                         final Vector<GenParameter> parameters2 = new Vector<>();
522:                         final GenParameter ownerParameter2 =
523:                                         GenParameter.create("owner", this.getGeneratorModel().getJavaClassForWTFClass(owner));
524:                         final GenParameter targetParameter2 =
525:                                         GenParameter.create("target", this.getGeneratorModel().getJavaClassForWTFClass(targetClass));
526:                         parameters2.add(ownerParameter2);
527:                         parameters2.add(targetParameter2);
528:                         final String methodContentRemove = "//methodContent wird noch implementiert.";
529:                         // TODO method.
530:                         final GenJavaOperation removeMethod =
531:                                         GenJavaOperation.create(
532:                                                         "remove" + attribute.getName(),
533:                                                         GenVisibility.PUBLIC,
534:                                                         parameters2,
535:                                                         new Vector<GenException>(),
536:                                                         methodContentRemove,
537:                                                         GenVoidType.getInstance(),
538:                                                         new Vector<GenOperationModifier>(),
539:                                                         GenComment.create(""));
540:                         symmetricRelationAccessClass.addOperation(removeMethod);
541:                         symmetricRelationAccessClass.addOperation(addMethod);
542:                 }
543:                 
544:                 // TODO: Use constants/config-file instead of literals
545:                 final String associationName =
546:                                 "generated.model" + "." + owner.getName().toString().replace('>', '.') + "." + attribute.getName();
547:                 final String methodContent =
548:                                 "return this." + superMethodName + "(" + targetClassName + ", \"" + associationName + "\");";
549:                 
550:                 final GenJavaOperation inverseGetter =
551:                                 GenJavaOperation.create(
552:                                                 inverseGetterIdentifier,
553:                                                 GenVisibility.PUBLIC,
554:                                                 new Vector<GenParameter>(),
555:                                                 new Vector<GenException>(),
556:                                                 methodContent,
557:                                                 returnType,
558:                                                 new Vector<GenOperationModifier>(),
559:                                                 GenComment.create(""));
560:                 
561:                 // final GenJavaOperation
562:                 
563:                 final GenClass genClass = this.getGeneratorModel().getJavaClassForWTFClass(targetClass);
564:                 final GenClassClass genClassClass = genClass.getImplementor();
565:                 final GenParameter newParam = GenParameter.create(targetClassName, genClassClass);
566:                 inverseGetter.getParameters().add(newParam);
567:                 
568:                 symmetricRelationAccessClass.addOperation(inverseGetter);
569:         }
570:         
571:         private Vector<ClassType> getTargetClasses(final Type attrTypeOccurance) throws GenTypeNotReferencedException {
572:                 final Vector<ClassType> targetTypes = new Vector<>();
573:                 final Type attributeType = UtilTransformer.getTypeProxyFreePrototype(attrTypeOccurance);
574:                 attributeType.accept(new TypeVisitorException<GenTypeNotReferencedException>() {
575:                         
576:                         @Override
577:                         public void handle(final AtomicType s) throws GenTypeNotReferencedException {
578:                                 s.accept(new AtomicTypeVisitorException<GenTypeNotReferencedException>() {
579:                                         
580:                                         @Override
581:                                         public void handle(final BaseType baseType) throws GenTypeNotReferencedException {
582:                                                 // NOthing
583:                                         }
584:                                         
585:                                         @Override
586:                                         public void handle(final ClassType clazz) throws GenTypeNotReferencedException {
587:                                                 targetTypes.add(clazz);
588:                                         }
589:                                 });
590:                         }
591:                         
592:                         @Override
593:                         public void handle(final CompositeType c) throws GenTypeNotReferencedException {
594:                                 
595:                                 c.accept(new CompositeTypeVisitorException<GenTypeNotReferencedException>() {
596:                                         
597:                                         @Override
598:                                         public void handle(final MapType map) throws GenTypeNotReferencedException {
599:                                                 targetTypes.addAll(OperationAttributeTransformer.this.getTargetClasses(map.getOf()));
600:                                                 
601:                                         }
602:                                         
603:                                         @Override
604:                                         public void handle(final ListType list) throws GenTypeNotReferencedException {
605:                                                 targetTypes.addAll(OperationAttributeTransformer.this.getTargetClasses(list.getOf()));
606:                                                 
607:                                         }
608:                                         
609:                                         @Override
610:                                         public void handle(final ProductType product) throws GenTypeNotReferencedException {
611:                                                 for (final ProductElementType factorTypeOccurance : product.getElements()) {
612:                                                         targetTypes.addAll(OperationAttributeTransformer.this.getTargetClasses(factorTypeOccurance
613:                                                                         .getType()));
614:                                                 }
615:                                         }
616:                                         
617:                                         @Override
618:                                         public void handle(final SumType sum) throws GenTypeNotReferencedException {
619:                                                 for (final Type summandTypeOccurance : sum.getElements()) {
620:                                                         targetTypes.addAll(OperationAttributeTransformer.this
621:                                                                         .getTargetClasses(summandTypeOccurance));
622:                                                 }
623:                                         }
624:                                         
625:                                         @Override
626:                                         public void handle(final ThrownType thrownType) throws GenTypeNotReferencedException {
627:                                                 // nothing to do
628:                                         }
629:                                 });
630:                         }
631:                         
632:                         @Override
633:                         public void handle(final TypeProxy s) throws GenTypeNotReferencedException {
634:                                 // nothing to do
635:                         }
636:                 });
637:                 return targetTypes;
638:         }
639:         
640:         private GenClass getSymmetricRelationAccessClassOfClass(final ClassType ownerClass, final ClassType targetClass) {
641:                 // Bsp.: A
642:                 final String ownerClassName = ownerClass.getName().getLastAddedName() + "";
643:                 
644:                 // Bsp.: B
645:                 final String targetClassName = targetClass.getName().getLastAddedName() + "";
646:                 
647:                 // Sortiere Klassen Lexikographisch
648:                 final String[] strings = { ownerClassName, targetClassName };
649:                 Arrays.sort(strings);
650:                 
651:                 // Name des Singletons der für die Relation verantwortlich ist, Bsp.: A_BSymmetricRelationAccess
652:                 final String symmetricRelationAccessName = strings[0] + "_" + strings[1] + "SymmetricRelationAccess";
653:                 
654:                 for (final GenClass knownClass : this.getGeneratorModel().getClasses()) {
655:                         if (knownClass.getName().equals(symmetricRelationAccessName)) {
656:                                 return knownClass;
657:                         }
658:                 }
659:                 
660:                 GenPackage superClassPackage = GenUnqualifiedPackage.create("de");
661:                 superClassPackage = superClassPackage.addName("fhdw");
662:                 superClassPackage = superClassPackage.addName("wtf");
663:                 superClassPackage = superClassPackage.addName("context");
664:                 superClassPackage = superClassPackage.addName("model");
665:                 
666:                 final GenUserClass symmetricRelationAccessSuperClass =
667:                                 GenUserClass.create(
668:                                                 "SymmetricRelationAccess",
669:                                                 new Vector<GenJavaOperation>(),
670:                                                 new Vector<GenInterfaceClass>(),
671:                                                 new Vector<GenJavaAttribute>(),
672:                                                 new Vector<GenClassModifier>(),
673:                                                 new Vector<GenJavaOperation>(),
674:                                                 null,
675:                                                 superClassPackage,
676:                                                 GenComment.createFromPlainText("", false),
677:                                                 "");
678:                 
679:                 GenPackage classPackage = GenUnqualifiedPackage.create("generated");
680:                 classPackage = classPackage.addName("symmetry");
681:                 
682:                 final GenUserClass symmetricRelationAccessClass =
683:                                 GenUserClass.create(
684:                                                 symmetricRelationAccessName,
685:                                                 new Vector<GenJavaOperation>(),
686:                                                 new Vector<GenInterfaceClass>(),
687:                                                 new Vector<GenJavaAttribute>(),
688:                                                 new Vector<GenClassModifier>(),
689:                                                 new Vector<GenJavaOperation>(),
690:                                                 symmetricRelationAccessSuperClass,
691:                                                 classPackage,
692:                                                 GenComment.createFromPlainText("", false),
693:                                                 "");
694:                 
695:                 final Vector<GenAttributeModifier> instanceAttributeModifiers = new Vector<>();
696:                 instanceAttributeModifiers.add(GenAttributeModifier.STATIC);
697:                 final GenJavaAttribute instanceAttribute =
698:                                 GenJavaAttribute.create(
699:                                                 "instance",
700:                                                 GenVisibility.PRIVATE,
701:                                                 symmetricRelationAccessClass,
702:                                                 instanceAttributeModifiers);
703:                 
704:                 final Vector<GenOperationModifier> getInstanceModifiers = new Vector<>();
705:                 getInstanceModifiers.add(GenOperationModifier.STATIC);
706:                 final GenJavaOperation getInstanceOperation =
707:                                 GenJavaOperation.create(
708:                                                 "getInstance",
709:                                                 GenVisibility.PUBLIC,
710:                                                 new Vector<GenParameter>(),
711:                                                 new Vector<GenException>(),
712:                                                 "if(instance == null) instance = new " + symmetricRelationAccessName + "(); return instance;",
713:                                                 symmetricRelationAccessClass,
714:                                                 getInstanceModifiers,
715:                                                 GenComment.create(""));
716:                 
717:                 final GenJavaOperation constructor =
718:                                 GenJavaOperation.createConstructor(
719:                                                 symmetricRelationAccessClass,
720:                                                 GenVisibility.PRIVATE,
721:                                                 new Vector<GenParameter>(),
722:                                                 new Vector<GenException>(),
723:                                                 "",
724:                                                 GenComment.create(""));
725:                 
726:                 symmetricRelationAccessClass.getAttributes().add(instanceAttribute);
727:                 symmetricRelationAccessClass.addOperation(getInstanceOperation);
728:                 symmetricRelationAccessClass.getConstructors().add(constructor);
729:                 
730:                 this.getGeneratorModel().addNonAstClass(symmetricRelationAccessClass);
731:                 this.getGeneratorModel().addSymmetricManager(symmetricRelationAccessClass, ownerClass);
732:                 this.getGeneratorModel().addSymmetricManager(symmetricRelationAccessClass, targetClass);
733:                 return symmetricRelationAccessClass;
734:         }
735:         
736:         public void handleOperation(final Operation o, final ClassType owner) throws TaskException {
737:                 final GenComment comment = GenComment.create(DEFAULT_OPERATION_COMMENT);
738:                 final String name = o.getName();
739:                 final Vector<GenOperationModifier> modifiers = this.getOperationModifiers(o);
740:                 final Collection<GenException> exceptions = this.getGeneratorModel().getGenExceptionsForType(o.getReturnType());
741:                 final GenType returnTyp = this.getGeneratorModel().getGenTypeForType(o.getReturnType());
742:                 final String method =
743:                                 DEFAULT_METHOD + (returnTyp.getFullyQualifiedTypeName().equals("void") ? "" : "\n\t\treturn null;");
744:                 final List<GenParameter> parameters = this.handleParameter(o.getParameters());
745:                 final GenJavaOperation result =
746:                                 GenJavaOperation.create(
747:                                                 name,
748:                                                 GenVisibility.PUBLIC,
749:                                                 parameters,
750:                                                 exceptions,
751:                                                 method,
752:                                                 returnTyp,
753:                                                 modifiers,
754:                                                 comment);
755:                 
756:                 final GenClass genOwner = this.getGeneratorModel().getClassMapping().get(owner);
757:                 genOwner.accept(new GenClassVisitor() {
758:                         
759:                         @Override
760:                         public void handle(final GenPrimitiveClass primitiveClass) {
761:                                 // primitiveClass will not be generated, adding operation is useless
762:                         }
763:                         
764:                         @Override
765:                         public void handle(final GenInterfaceClass interfaceClass) {
766:                                 
767:                                 interfaceClass.accept(new GenInterfaceClassVisitor() {
768:                                         
769:                                         @Override
770:                                         public void handle(final GenInterfaceWithClassImplClass interfaceWithImplClass) {
771:                                                 interfaceWithImplClass.addOperation(result);
772:                                                 interfaceWithImplClass.getClassRepresentation().addOperation(result);
773:                                         }
774:                                         
775:                                         @Override
776:                                         public void handle(final GenSimpleInterfaceClass simpleInterface) {
777:                                                 simpleInterface.addOperation(result);
778:                                         }
779:                                         
780:                                         @Override
781:                                         public void handle(final GenExternalInterfaceClass iface) {
782:                                                 throw new Error("Operation " + o.getName() + " cannot be added to external interface "
783:                                                                 + iface.getFullyQualifiedTypeName());
784:                                         }
785:                                 });
786:                         }
787:                         
788:                         @Override
789:                         public void handle(final GenClassClass classClass) {
790:                                 classClass.addOperation(result);
791:                         }
792:                 });
793:         }
794:         
795:         /**
796:          * Returns a {@link Vector} with {@link GenOperationModifier} for the {@link Operation} <code>o</code>.
797:          *
798:          * @param o
799:          * o
800:          * @return Vector<GenOperationModifier>
801:          */
802:         private Vector<GenOperationModifier> getOperationModifiers(final Operation o) {
803:                 final Vector<GenOperationModifier> result = new Vector<>();
804:                 final Iterator<de.fhdw.wtf.common.ast.OperationModifier> i = o.getModifiers().iterator();
805:                 while (i.hasNext()) {
806:                         final de.fhdw.wtf.common.ast.OperationModifier current = i.next();
807:                         current.accept(new OperationModifierVisitor() {
808:                                 @Override
809:                                 public boolean handle(final de.fhdw.wtf.common.ast.OperationModifier abstract1) {
810:                                         result.add(GenOperationModifier.ABSTRACT);
811:                                         return false;
812:                                 }
813:                         });
814:                 }
815:                 return result;
816:         }
817:         
818:         /**
819:          * TODO Janik / Tilmann soll das wirklich so?!
820:          *
821:          * @param o
822:          * @return
823:          * @throws TaskException
824:          */
825:         protected List<GenParameter> handleParameter(final ProductType o) throws TaskException {
826:                 final List<ProductElementType> elements = o.getElements();
827:                 final Vector<GenParameter> result = new Vector<>();
828:                 for (final ProductElementType productElement : elements) {
829:                         final GenType paramType = this.getGeneratorModel().getGenTypeForType(productElement.getType());
830:                         result.add(GenParameter.create(productElement.getName(), paramType));
831:                 }
832:                 return result;
833:         }
834:         
835:         // BEGIN PRODUCTS
836:         
837:         /**
838:          * For each element of <code>product</code> this methods adds an <code>protected</code> attribute to the
839:          * {@link GenClassClass} that represents the {@link ProductType}.
840:          *
841:          * @param product
842:          * given {@link ProductType} to add attributes for.
843:          * @param prod
844:          * The underlying {@link GenClassClass} for the product passed.
845:          * @throws TaskException
846:          * Thrown when the product or an element-Type is not referenced in the {@link GeneratorModel}.
847:          */
848:         private void handleProductAttributes(final ProductType product, final GenClassClass prod) throws TaskException {
849:                 final StringBuilder methodString = new StringBuilder();
850:                 final List<GenParameter> parameters = new Vector<>();
851:                 final Iterator<ProductElementType> i = product.getElements().iterator();
852:                 while (i.hasNext()) {
853:                         final ProductElementType element = i.next();
854:                         final Collection<GenAttributeModifier> modifiers = new Vector<>();
855:                         final GenType type = this.getGeneratorModel().getGenTypeForType(element.getType());
856:                         final GenJavaAttribute currentAttr =
857:                                         GenJavaAttribute.create(element.getName(), GenVisibility.PROTECTED, type, modifiers);
858:                         prod.getAttributes().add(currentAttr);
859:                         
860:                         final String methodStringInitialize =
861:                                         THIS_POINT + currentAttr.getName() + EQUAL_SYMBOL + currentAttr.getName() + JAVA_LINE_END;
862:                         if (methodString.toString().equals("")) {
863:                                 methodString.append(methodStringInitialize);
864:                         } else {
865:                                 methodString.append(NEW_LINE + TAB + TAB + methodStringInitialize);
866:                         }
867:                         final GenParameter parameter = GenParameter.create(currentAttr.getName(), currentAttr.getTyp());
868:                         parameters.add(parameter);
869:                 }
870:                 // constructor
871:                 final GenComment comment = GenComment.createFromPlainText(DEFAULT_PRODUCT_CONSTRUCTOR_COMMENT, true);
872:                 final GenJavaOperation constructor =
873:                                 GenJavaOperation.createConstructor(
874:                                                 prod,
875:                                                 GenVisibility.PUBLIC,
876:                                                 parameters,
877:                                                 new Vector<GenException>(),
878:                                                 methodString.toString(),
879:                                                 comment);
880:                 prod.getConstructors().add(constructor);
881:         }
882:         
883:         /**
884:          * For each element of <code>product</code> this operation adds an getter and an setter to the {@link GenClassClass}
885:          * that represents the {@link ProductType}. Furthermore this operation adds a constructor based on all attributes to
886:          * the {@link GenClassClass}.
887:          *
888:          * @param product
889:          * given {@link ProductType} to generate getters, setters and a constructor for.
890:          * @param prod
891:          * The underlying {@link GenClassClass} for the product passed.
892:          * @throws TaskException
893:          * Thrown when the product or an element-Type is not referenced in the {@link GeneratorModel}.
894:          */
895:         private void generateProductsGettersAndSetters(final ProductType product, final GenClassClass prod)
896:                         throws TaskException {
897:                 final Iterator<ProductElementType> i = product.getElements().iterator();
898:                 BigInteger currentElementCount = BigInteger.ZERO;
899:                 while (i.hasNext()) {
900:                         currentElementCount = currentElementCount.add(BigInteger.ONE);
901:                         final ProductElementType current = i.next();
902:                         final String name = current.getName();
903:                         final String capitalName = name.substring(0, 1).toUpperCase() + name.substring(1);
904:                         final Collection<GenException> exceptions = new Vector<>();
905:                         final GenType prodElementType = this.getGeneratorModel().getGenTypeForType(current.getType());
906:                         final Collection<GenOperationModifier> operationModifier = new Vector<>();
907:                         // getter
908:                         final List<GenParameter> paramsGetter = new ArrayList<>();
909:                         final String implementationGetter = "return this.p$" + currentElementCount.toString() + ";";
910:                         prod.addOperation(GenJavaOperation.create(
911:                                         "get" + capitalName,
912:                                         GenVisibility.PUBLIC,
913:                                         paramsGetter,
914:                                         exceptions,
915:                                         implementationGetter,
916:                                         prodElementType,
917:                                         operationModifier,
918:                                         GenComment.createFromPlainText("", true)));
919:                         // setter
920:                         final List<GenParameter> paramsSetter = new ArrayList<>();
921:                         final GenParameter setParam = GenParameter.create(name, prodElementType);
922:                         paramsSetter.add(setParam);
923:                         final String implementationSetter = "this.p$" + currentElementCount.toString() + " = " + name + ";";
924:                         prod.addOperation(GenJavaOperation.create(
925:                                         "set" + capitalName,
926:                                         GenVisibility.PUBLIC,
927:                                         paramsSetter,
928:                                         exceptions,
929:                                         implementationSetter,
930:                                         GenVoidType.getInstance(),
931:                                         operationModifier,
932:                                         GenComment.createFromPlainText("", false)));
933:                 }
934:         }
935:         
936:         // END PRODUCTS
937:         
938:         @Override
939:         public String toString() {
940:                 return "Operation and Attribute generation";
941:         }
942:         
943:         @Override
944:         public void beginTask() throws TaskException {
945:                 // Nothing
946:         }
947:         
948:         @Override
949:         public void finalizeTask() throws TaskException {
950:                 // Nothing
951:         }
952: }