Skip to content

Method: finalizeTask()

1: package de.fhdw.wtf.walker.tasks;
2:
3: import java.util.ArrayList;
4: import java.util.HashMap;
5: import java.util.Iterator;
6:
7: import de.fhdw.wtf.common.ast.Attribute;
8: import de.fhdw.wtf.common.ast.AttributeModifier;
9: import de.fhdw.wtf.common.ast.AttributeModifierSymmetric;
10: import de.fhdw.wtf.common.ast.ConstructorOrOperation;
11: import de.fhdw.wtf.common.ast.Group;
12: import de.fhdw.wtf.common.ast.Model;
13: import de.fhdw.wtf.common.ast.type.ClassType;
14: import de.fhdw.wtf.common.exception.walker.SymmetricCheckException;
15: import de.fhdw.wtf.common.exception.walker.TaskException;
16: import de.fhdw.wtf.common.task.TaskExecutor;
17: import de.fhdw.wtf.common.task.TaskExecutorFixed;
18: import de.fhdw.wtf.walker.walker.SimpleWalkerTask;
19:
20: /**
21: * @author hfw413hy
22: *
23: */
24: public class SymmetricCheck extends SimpleWalkerTask {
25:         
26:         private final HashMap<Group, ArrayList<SymmetricCheckPart>> parts = new HashMap<>();
27:         private Group currentGroup;
28:         
29:         private final void addPart(final Attribute a, final ClassType owner) {
30:                 if (!this.parts.containsKey(this.currentGroup)) {
31:                         this.parts.put(this.currentGroup, new ArrayList<SymmetricCheckPart>());
32:                 }
33:                 this.parts.get(this.currentGroup).add(new SymmetricCheckPart(owner, a));
34:         }
35:         
36:         /**
37:          * Erzeugt ein Check-Objekt zum Prüfen, ob symmetrische Beziehungen auf beiden Seiten der Klasse angegeben wurden.
38:          *
39:          * @param model
40:          * Das zugrunde liegende Modell, welches geprüft werden soll.
41:          * @param taskmanager
42:          * Der Manager.
43:          * @return Das Check-Objekt.
44:          */
45:         public static SymmetricCheck create(final Model model, final TaskExecutorFixed taskmanager) {
46:                 return new SymmetricCheck(model, taskmanager);
47:         }
48:         
49:         private SymmetricCheck(final Model m, final TaskExecutor taskmanager) {
50:                 super(m, taskmanager);
51:         }
52:         
53:         @Override
54:         public void handleClass(final ClassType c) throws TaskException {
55:                 // Nichts
56:         }
57:         
58:         @Override
59:         public void handleGroup(final Group g) throws TaskException {
60:                 this.currentGroup = g;
61:         }
62:         
63:         @Override
64:         public void handleAttribute(final Attribute a, final ClassType owner) throws TaskException {
65:                 if (a.isSymmetric()) {
66:                         this.addPart(a, owner);
67:                 }
68:         }
69:         
70:         @Override
71:         public void handleConstructorOrOperation(final ConstructorOrOperation coo, final ClassType owner)
72:                         throws TaskException {
73:                 // Nichts...
74:         }
75:         
76:         /**
77:          *
78:          * @param g
79:          * Die Gruppe in der wir symmetrische Beziehungen testen.
80:          * @param current
81:          * Das Ausgangs-Attribut.
82:          * @throws SymmetricCheckException
83:          */
84:         private void findCorrespondingAttribute(final Group g, final SymmetricCheckPart current)
85:                         throws SymmetricCheckException {
86:                 final Iterator<SymmetricCheckPart> itemIt = this.parts.get(g).iterator();
87:                 while (itemIt.hasNext()) {
88:                         final SymmetricCheckPart cur = itemIt.next();
89:                         
90:                         // Owner-Klassen müssen unterschiedlich sein... sonst zählt dies nicht als "gefunden"
91:                         if (current.getOwner().equals(cur.getOwner())) {
92:                                 continue;
93:                         }
94:                         
95:                         // Klasse A: idA : B symmetric(idB);
96:                         // Klasse B: idB : A symmetric(idA);
97:                         
98:                         // Überprüfen der Attributnamen-Referenzierung
99:                         // Prüft ob "idA" (in A) so als Identifier in B (in symmetric(idA)) hinterlegt ist...
100:                         if (!cur.getAttributeName().equals(current.getSymmetricIdentifier())) {
101:                                 continue;
102:                         }
103:                         // ...und umgekehrt
104:                         if (!current.getAttributeName().equals(cur.getSymmetricIdentifier())) {
105:                                 continue;
106:                         }
107:                         
108:                         // Prüft ob die Typen übereinstimmen
109:                         if (!cur.getAttributeType().equals(current.getOwnerClassName())) {
110:                                 continue;
111:                         }
112:                         if (!current.getAttributeType().equals(cur.getOwnerClassName())) {
113:                                 continue;
114:                         }
115:                         
116:                         // Wir haben den passenden Typ gefunden der zu "current" passt
117:                         return;
118:                 }
119:                 final String err =
120:                                 current.getSymmetricIdentifier() + " : " + current.getOwnerClassName() + " symmetric("
121:                                                 + current.getAttributeName() + ");";
122:                 throw SymmetricCheckException.create("Kein passendes Attribut in der Klasse " + current.getAttributeType()
123:                                 + " gefunden! Erwartet: '" + err + "'", current.getAttribute());
124:         }
125:         
126:         /**
127:          * Durchläuft und prüft alle Symmetric-Einträge einer Gruppe.
128:          *
129:          * @param g
130:          * Die zu prüfende Gruppe
131:          * @throws SymmetricCheckException
132:          */
133:         private void finalizeTaskHandleGroup(final Group g) throws SymmetricCheckException {
134:                 final Iterator<SymmetricCheckPart> itemIt = this.parts.get(g).iterator();
135:                 while (itemIt.hasNext()) {
136:                         final SymmetricCheckPart current = itemIt.next();
137:                         this.findCorrespondingAttribute(g, current);
138:                 }
139:         }
140:         
141:         @Override
142:         public void finalizeTask() throws TaskException {
143:                 final Iterator<Group> groupIt = this.parts.keySet().iterator();
144:•                while (groupIt.hasNext()) {
145:                         this.finalizeTaskHandleGroup(groupIt.next());
146:                 }
147:         }
148:         
149:         @Override
150:         public void beginTask() throws TaskException {
151:                 // Nichts...
152:         }
153:         
154: }
155:
156: /**
157: *
158: * @author hfw413hy
159: *
160: */
161: class SymmetricCheckPart {
162:         private final ClassType Owner;
163:         private final Attribute OwnerAttribute;
164:         
165:         public SymmetricCheckPart(final ClassType owner, final Attribute a) {
166:                 this.Owner = owner;
167:                 this.OwnerAttribute = a;
168:         }
169:         
170:         public ClassType getOwner() {
171:                 return this.Owner;
172:         }
173:         
174:         public Attribute getOwnerAttribute() {
175:                 return this.OwnerAttribute;
176:         }
177:         
178:         public String getSymmetricIdentifier() {
179:                 final Iterator<AttributeModifier> i = this.OwnerAttribute.getModifiers().iterator();
180:                 while (i.hasNext()) {
181:                         final AttributeModifier m = i.next();
182:                         if (m instanceof AttributeModifierSymmetric) {
183:                                 final AttributeModifierSymmetric cur = (AttributeModifierSymmetric) m;
184:                                 return cur.getIdentifierToken().getIdentifier();
185:                         }
186:                 }
187:                 return "";
188:         }
189:         
190:         public Attribute getAttribute() {
191:                 return this.OwnerAttribute;
192:         }
193:         
194:         public String getAttributeName() {
195:                 return this.OwnerAttribute.getName();
196:         }
197:         
198:         public String getAttributeType() {
199:                 return this.OwnerAttribute.getAttrType().getTypeString();
200:         }
201:         
202:         public String getOwnerClassName() {
203:                 return this.Owner.getName().getLastAddedName().toString();
204:         }
205: }