Skip to content

Method: beginTask()

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.ast.type.Type;
15: import de.fhdw.wtf.common.exception.walker.SymmetricCheckException;
16: import de.fhdw.wtf.common.exception.walker.TaskException;
17: import de.fhdw.wtf.common.task.TaskExecutor;
18: import de.fhdw.wtf.common.task.TaskExecutorFixed;
19: import de.fhdw.wtf.walker.walker.SimpleWalkerTask;
20:
21: /**
22: * @author hfw413hy
23: *
24: */
25: public class SymmetricCheck extends SimpleWalkerTask {
26:         
27:         private final HashMap<Group, ArrayList<SymmetricCheckPart>> parts = new HashMap<>();
28:         private Group currentGroup;
29:         
30:         private final void addPart(final Attribute a, final ClassType owner) {
31:                 if (!this.parts.containsKey(this.currentGroup)) {
32:                         this.parts.put(this.currentGroup, new ArrayList<SymmetricCheckPart>());
33:                 }
34:                 this.parts.get(this.currentGroup).add(new SymmetricCheckPart(owner, a));
35:         }
36:         
37:         /**
38:          * Erzeugt ein Check-Objekt zum Prüfen, ob symmetrische Beziehungen auf beiden Seiten der Klasse angegeben wurden.
39:          *
40:          * @param model
41:          * Das zugrunde liegende Modell, welches geprüft werden soll.
42:          * @param taskmanager
43:          * Der Manager.
44:          * @return Das Check-Objekt.
45:          */
46:         public static SymmetricCheck create(final Model model, final TaskExecutorFixed taskmanager) {
47:                 return new SymmetricCheck(model, taskmanager);
48:         }
49:         
50:         private SymmetricCheck(final Model m, final TaskExecutor taskmanager) {
51:                 super(m, taskmanager);
52:         }
53:         
54:         @Override
55:         public void handleClass(final ClassType c) throws TaskException {
56:                 // Nichts
57:         }
58:         
59:         @Override
60:         public void handleGroup(final Group g) throws TaskException {
61:                 this.currentGroup = g;
62:         }
63:         
64:         @Override
65:         public void handleAttribute(final Attribute a, final ClassType owner) throws TaskException {
66:                 if (a.isSymmetric()) {
67:                         this.addPart(a, owner);
68:                 }
69:         }
70:         
71:         @Override
72:         public void handleConstructorOrOperation(final ConstructorOrOperation coo, final ClassType owner)
73:                         throws TaskException {
74:                 // Nichts...
75:         }
76:         
77:         /**
78:          *
79:          * @param g
80:          * Die Gruppe in der wir symmetrische Beziehungen testen.
81:          * @param current
82:          * Das Ausgangs-Attribut.
83:          * @throws SymmetricCheckException
84:          */
85:         private void findCorrespondingAttribute(final Group g, final SymmetricCheckPart current)
86:                         throws SymmetricCheckException {
87:                 final boolean debug = true;
88:                 final Iterator<SymmetricCheckPart> itemIt = this.parts.get(g).iterator();
89:                 while (itemIt.hasNext()) {
90:                         final SymmetricCheckPart cur = itemIt.next();
91:                         
92:                         // Überspringe Vergleich mit sich selbst
93:                         if (current.equals(cur)) {
94:                                 continue;
95:                         }
96:                         
97:                         // Klasse A: idA : B symmetric(idB);
98:                         // Klasse B: idB : A symmetric(idA);
99:                         
100:                         // Überprüfen der Attributnamen-Referenzierung
101:                         // Prüft ob "idA" (in A) so als Identifier in B (in symmetric(idA)) hinterlegt ist...
102:                         if (!cur.getAttributeName().equals(current.getSymmetricIdentifier())) {
103:                                 if (debug) {
104:                                         System.out.println("1 : " + cur.getAttributeName() + " vs " + current.getSymmetricIdentifier());
105:                                 }
106:                                 continue;
107:                         }
108:                         // ...und umgekehrt
109:                         if (!current.getAttributeName().equals(cur.getSymmetricIdentifier())) {
110:                                 if (debug) {
111:                                         System.out.println("2 : " + current.getAttributeName() + " vs " + cur.getSymmetricIdentifier());
112:                                 }
113:                                 continue;
114:                         }
115:                         
116:                         // Prüft ob die Typen übereinstimmen
117:                         if (!cur.getAttributeTypeString().equals(current.getClassTypeString())) {
118:                                 if (debug) {
119:                                         System.out.println("3 : " + cur.getAttributeTypeString() + " vs " + current.getClassTypeString());
120:                                 }
121:                                 continue;
122:                         }
123:                         if (!current.getAttributeTypeString().equals(cur.getClassTypeString())) {
124:                                 if (debug) {
125:                                         System.out.println("4 : " + current.getAttributeTypeString() + " vs " + cur.getClassTypeString());
126:                                 }
127:                                 continue;
128:                         }
129:                         
130:                         // Wir haben den passenden Typ gefunden der zu "current" passt
131:                         return;
132:                 }
133:                 
134:                 throw SymmetricCheckException.create("Kein passendes Attribut in der Klasse "
135:                                 + current.getAttributeType().getTypeString() + " gefunden!", current.getAttribute());
136:         }
137:         
138:         /**
139:          * Durchläuft und prüft alle Symmetric-Einträge einer Gruppe.
140:          *
141:          * @param g
142:          * Die zu prüfende Gruppe
143:          * @throws SymmetricCheckException
144:          */
145:         private void finalizeTaskHandleGroup(final Group g) throws SymmetricCheckException {
146:                 final Iterator<SymmetricCheckPart> itemIt = this.parts.get(g).iterator();
147:                 while (itemIt.hasNext()) {
148:                         final SymmetricCheckPart current = itemIt.next();
149:                         this.findCorrespondingAttribute(g, current);
150:                 }
151:         }
152:         
153:         @Override
154:         public void finalizeTask() throws TaskException {
155:                 final Iterator<Group> groupIt = this.parts.keySet().iterator();
156:                 while (groupIt.hasNext()) {
157:                         this.finalizeTaskHandleGroup(groupIt.next());
158:                 }
159:         }
160:         
161:         @Override
162:         public void beginTask() throws TaskException {
163:                 // Nichts...
164:         }
165:         
166: }
167:
168: /**
169: *
170: * @author hfw413hy
171: *
172: */
173: class SymmetricCheckPart {
174:         private final ClassType Owner;
175:         private final Attribute OwnerAttribute;
176:         
177:         public SymmetricCheckPart(final ClassType owner, final Attribute a) {
178:                 this.Owner = owner;
179:                 this.OwnerAttribute = a;
180:         }
181:         
182:         public Type getClassType() {
183:                 return this.Owner;
184:         }
185:         
186:         public Type getAttributeType() {
187:                 return this.OwnerAttribute.getAttrType();
188:         }
189:         
190:         public String getAttributeTypeString() {
191:                 String tmp = this.OwnerAttribute.getAttrType().getTypeString();
192:                 final int idx = tmp.indexOf("*");
193:                 if (idx > -1) {
194:                         tmp = tmp.substring(0, idx) + tmp.substring(idx + 1);
195:                 }
196:                 return tmp;
197:         }
198:         
199:         public Attribute getAttribute() {
200:                 return this.OwnerAttribute;
201:         }
202:         
203:         /**
204:          * Liefert den Identifier eines Symmetrischen Attributes zurück, Bsp.: "a : A symmetric(myA)" -> "myA".
205:          *
206:          * @return Der Identifier eines Symmetrischen Attributes, Bsp.: "a : A symmetric(myA)" -> "myA".
207:          */
208:         public String getSymmetricIdentifier() {
209:                 final Iterator<AttributeModifier> i = this.OwnerAttribute.getModifiers().iterator();
210:                 while (i.hasNext()) {
211:                         final AttributeModifier m = i.next();
212:                         if (m instanceof AttributeModifierSymmetric) {
213:                                 final AttributeModifierSymmetric cur = (AttributeModifierSymmetric) m;
214:                                 return cur.getIdentifierToken().getIdentifier();
215:                         }
216:                 }
217:                 return "";
218:         }
219:         
220:         public String getAttributeName() {
221:                 return this.OwnerAttribute.getName();
222:         }
223:         
224:         /**
225:          * Liefert bei einem qualifizierten Namen (Bsp.: "de>fhdw>test>a") den Klassennamen "a".
226:          *
227:          * @return Liefert bei einem qualifizierten Namen (Bsp.: "de>fhdw>test>a") den Klassennamen "a".
228:          */
229:         public String getClassTypeString() {
230:                 final String[] arr = this.getClassType().getTypeString().split(">");
231:                 return arr[arr.length - 1];
232:         }
233: }