Skip to content

Method: SyntaxCheckAbstract()

1: package de.fhdw.wtf.tooling;
2:
3: import java.io.IOException;
4: import java.net.URI;
5: import java.nio.charset.Charset;
6: import java.nio.charset.StandardCharsets;
7: import java.nio.file.Files;
8: import java.nio.file.Paths;
9: import java.util.ArrayList;
10: import java.util.Collection;
11: import java.util.concurrent.ExecutionException;
12:
13: import de.fhdw.wtf.common.ast.Model;
14: import de.fhdw.wtf.common.exception.editor.CheckException;
15: import de.fhdw.wtf.common.exception.editor.EditorMarkable;
16: import de.fhdw.wtf.common.exception.editor.EditorMarker;
17: import de.fhdw.wtf.common.exception.editor.GeneralCheckException;
18: import de.fhdw.wtf.common.exception.editor.MarkableCheckException;
19: import de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions;
20: import de.fhdw.wtf.common.exception.parser.AbstractParserException;
21: import de.fhdw.wtf.common.exception.parser.NoValidTokenStreamException;
22: import de.fhdw.wtf.common.exception.referencer.ReferencerException;
23: import de.fhdw.wtf.common.exception.referencer.ReferencingNotSuccessfulException;
24: import de.fhdw.wtf.common.exception.walker.CyclicDependencyException;
25: import de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException;
26: import de.fhdw.wtf.common.exception.walker.TaskException;
27: import de.fhdw.wtf.common.stream.FilteredTokenStream;
28: import de.fhdw.wtf.common.stream.SimpleScannerInput;
29: import de.fhdw.wtf.common.task.DependencyTask;
30: import de.fhdw.wtf.common.task.GroupDependencyTask;
31: import de.fhdw.wtf.common.task.TaskExecutorFixed;
32: import de.fhdw.wtf.common.task.result.ExceptionalTaskResult;
33: import de.fhdw.wtf.common.task.result.OKTaskResult;
34: import de.fhdw.wtf.common.task.result.TaskResult;
35: import de.fhdw.wtf.common.task.result.visitor.TaskResultVisitor;
36: import de.fhdw.wtf.common.token.Position;
37: import de.fhdw.wtf.dsl.scanner.modelScanner.ModelDslScanner;
38: import de.fhdw.wtf.parser.Parser;
39: import de.fhdw.wtf.walker.tasks.AbstractOperationsCheck;
40: import de.fhdw.wtf.walker.tasks.AnalyzeInheritanceTreesTask;
41: import de.fhdw.wtf.walker.tasks.BaseTypeInheritanceCheck;
42: import de.fhdw.wtf.walker.tasks.ConstructorReferencer;
43: import de.fhdw.wtf.walker.tasks.CyclicInheritanceCheck;
44: import de.fhdw.wtf.walker.tasks.DoubleAttributenameCheck;
45: import de.fhdw.wtf.walker.tasks.DoubleGroupcomponentCheck;
46: import de.fhdw.wtf.walker.tasks.InvalidAttributeModifierCheck;
47: import de.fhdw.wtf.walker.tasks.OverloadingCheck;
48: import de.fhdw.wtf.walker.tasks.ProductCheck;
49: import de.fhdw.wtf.walker.tasks.PrototypesTask;
50: import de.fhdw.wtf.walker.tasks.ReferencedConstructorsCheck;
51: import de.fhdw.wtf.walker.tasks.SubtypesFillTask;
52: import de.fhdw.wtf.walker.tasks.SupertypesCleanInheritanceTask;
53: import de.fhdw.wtf.walker.tasks.SupertypesFillTask;
54: import de.fhdw.wtf.walker.tasks.SymmetricCheck;
55: import de.fhdw.wtf.walker.tasks.TypeReferencer;
56: import de.fhdw.wtf.walker.walker.SimpleWalkerTask;
57:
58: public abstract class SyntaxCheckAbstract {
59:         
60:         private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
61:         
62:         /**
63:          * Erzeugt ein Modell aus dem übergebenen Pfad zum WTF-Modell.
64:          *
65:          * @param uri
66:          * @return
67:          * @throws MultipleCheckExceptions
68:          * @throws CyclicDependencyException
69:          * @throws InterruptedException
70:          * @throws CyclicPartDefinitionException
71:          * @throws ExecutionException
72:          */
73:         public Model getModelFromFile(final URI uri) throws MultipleCheckExceptions, CyclicDependencyException,
74:                         InterruptedException, CyclicPartDefinitionException, ExecutionException {
75:                 try {
76:                         final String fileContent = readFile(uri, DEFAULT_CHARSET);
77:                         return this.getModelFromString(fileContent);
78:                 } catch (final IOException e) {
79:                         e.printStackTrace();
80:                         return null;
81:                 }
82:         }
83:         
84:         /**
85:          * Erzeugt ein Modell aus dem übergebenen Inhalt einer Datei die ein WTF-Modell enthält.
86:          *
87:          * @param wtfFileContent
88:          * @return
89:          * @throws MultipleCheckExceptions
90:          * @throws CyclicDependencyException
91:          * @throws InterruptedException
92:          * @throws CyclicPartDefinitionException
93:          * @throws ExecutionException
94:          */
95:         public Model getModelFromString(final String wtfFileContent) throws MultipleCheckExceptions,
96:                         CyclicDependencyException, InterruptedException, CyclicPartDefinitionException, ExecutionException {
97:                 final FilteredTokenStream output = this.scanString(wtfFileContent);
98:                 Model result;
99:                 result = this.parseStream(output);
100:                 this.checkModelGeneral(result);
101:                 return result;
102:         }
103:         
104:         /**
105:          * Internal Method. This Method check the model.
106:          *
107:          * @param model
108:          */
109:         public void checkModelGeneral(final Model model) throws MultipleCheckExceptions, CyclicDependencyException,
110:                         InterruptedException, ExecutionException, CyclicPartDefinitionException {
111:                 final MultipleCheckExceptions exceptions = new MultipleCheckExceptions();
112:                 final TaskExecutorFixed taskmanager = TaskExecutorFixed.create();
113:                 
114:                 final GroupDependencyTask firstCheckers = GroupDependencyTask.create(taskmanager);
115:                 final DependencyTask doubleGroupcomponent = DoubleGroupcomponentCheck.create(model, taskmanager);
116:                 final DependencyTask abstractOperationsCheck = AbstractOperationsCheck.create(model, taskmanager);
117:                 final DependencyTask productCheck = ProductCheck.create(model, taskmanager);
118:                 final DependencyTask symmetricCheck = SymmetricCheck.create(model, taskmanager);
119:                 firstCheckers.addMembers(doubleGroupcomponent, abstractOperationsCheck, productCheck, symmetricCheck);
120:                 
121:                 final TypeReferencer typeReferencer = TypeReferencer.create(model, taskmanager);
122:                 typeReferencer.addDependency(firstCheckers);
123:                 
124:                 final GroupDependencyTask inheritanceChecker = GroupDependencyTask.create(taskmanager);
125:                 final DependencyTask cyclicInheritance = CyclicInheritanceCheck.create(model, taskmanager);
126:                 final DependencyTask baseTypeInheritanceCheck = BaseTypeInheritanceCheck.create(model, taskmanager);
127:                 inheritanceChecker.addMembers(cyclicInheritance, baseTypeInheritanceCheck);
128:                 inheritanceChecker.addDependency(typeReferencer);
129:                 
130:                 final GroupDependencyTask checkersAfterReferencing = GroupDependencyTask.create(taskmanager);
131:                 final SimpleWalkerTask invalidAttributeModifierCheck = InvalidAttributeModifierCheck.create(model, taskmanager);
132:                 final DependencyTask doubleAttributenameCheck = DoubleAttributenameCheck.create(model, taskmanager);
133:                 checkersAfterReferencing.addMembers(invalidAttributeModifierCheck, doubleAttributenameCheck);
134:                 checkersAfterReferencing.addDependency(inheritanceChecker);
135:                 
136:                 final GroupDependencyTask completers = GroupDependencyTask.create(taskmanager);
137:                 final DependencyTask prototypesTask = PrototypesTask.create(model, taskmanager);
138:                 final DependencyTask subtypesFillTask = SubtypesFillTask.create(model, taskmanager);
139:                 final SupertypesFillTask supertypesFillTask = SupertypesFillTask.create(model, taskmanager);
140:                 final DependencyTask supertypesCleanInheritanceTask =
141:                                 SupertypesCleanInheritanceTask.create(model, taskmanager, supertypesFillTask);
142:                 prototypesTask.addDependency(subtypesFillTask);
143:                 supertypesFillTask.addDependency(prototypesTask);
144:                 supertypesCleanInheritanceTask.addDependency(supertypesFillTask);
145:                 completers.addMembers(subtypesFillTask, prototypesTask, supertypesFillTask, supertypesCleanInheritanceTask);
146:                 completers.addDependency(checkersAfterReferencing);
147:                 final SimpleWalkerTask overloadingCheck = OverloadingCheck.create(model, taskmanager);
148:                 overloadingCheck.addDependency(completers);
149:                 
150:                 final ConstructorReferencer constructorReferencer = ConstructorReferencer.create(model, taskmanager);
151:                 constructorReferencer.addDependency(overloadingCheck);
152:                 
153:                 final DependencyTask analyzeInheritanceTreesTask = AnalyzeInheritanceTreesTask.create(model, taskmanager);
154:                 analyzeInheritanceTreesTask.addDependency(constructorReferencer);
155:                 
156:                 final DependencyTask referencedConstructorsCheck = ReferencedConstructorsCheck.create(model, taskmanager);
157:                 referencedConstructorsCheck.addDependency(analyzeInheritanceTreesTask);
158:                 
159:                 taskmanager.startAllKnownTasks();
160:                 final Collection<TaskResult> results = taskmanager.getResultsAndShutdown();
161:                 
162:                 final Collection<Exception> occuredExceptions = new ArrayList<>();
163:                 for (final TaskResult current : results) {
164:                         current.accept(new TaskResultVisitor() {
165:                                 
166:                                 @Override
167:                                 public void handleOkTaskResult(final OKTaskResult result) {
168:                                         // Everything right
169:                                 }
170:                                 
171:                                 @Override
172:                                 public void handleExceptionalTaskResult(final ExceptionalTaskResult result) {
173:                                         occuredExceptions.add(result.getError());
174:                                 }
175:                         });
176:                 }
177:                 if (!occuredExceptions.isEmpty()) {
178:                         for (final Exception occuredException : occuredExceptions) {
179:                                 if (occuredException instanceof ReferencingNotSuccessfulException) {
180:                                         for (final TaskException e : typeReferencer.getExceptions()) {
181:                                                 if (e instanceof ReferencerException) {
182:                                                         exceptions.add(new MarkableCheckException(((ReferencerException) e).getPosStart(),
183:                                                                         ((ReferencerException) e).getPosEnd(), e, EditorMarker.REFERENCER_MARKER));
184:                                                 }
185:                                         }
186:                                 } else if (occuredException instanceof EditorMarkable) {
187:                                         final EditorMarkable e = (EditorMarkable) occuredException;
188:                                         exceptions.add(new MarkableCheckException(e.getStartPosition(), e.getEndPos(), occuredException, e
189:                                                         .getMarker()));
190:                                 } else {
191:                                         exceptions.add(new GeneralCheckException(occuredException));
192:                                 }
193:                         }
194:                         
195:                         throw exceptions;
196:                 }
197:         }
198:         
199:         private Model parseStream(final FilteredTokenStream output) throws MultipleCheckExceptions {
200:                 Model result;
201:                 final Parser parser = Parser.create(output);
202:                 try {
203:                         result = parser.parse();
204:                         return result;
205:                 } catch (final NoValidTokenStreamException e) {
206:                         
207:                         final Collection<CheckException> excList = new ArrayList<>();
208:                         for (final AbstractParserException parserException : parser.getExceptions()) {
209:                                 final int positionInLine =
210:                                                 parserException.getToken().getPosition().getPosition() + parserException.getToken().getLength();
211:                                 final int columnNumber =
212:                                                 parserException.getToken().getPosition().getPosition() + parserException.getToken().getLength();
213:                                 final int lineNumber = parserException.getToken().getPosition().getLineNumber();
214:                                 final Position startPos = parserException.getToken().getPosition();
215:                                 final Position endPos =
216:                                                 Position.create(
217:                                                                 parserException.getToken().getPosition().getFilePath(),
218:                                                                 lineNumber,
219:                                                                 columnNumber,
220:                                                                 positionInLine);
221:                                 final MarkableCheckException markableException =
222:                                                 new MarkableCheckException(startPos, endPos, parserException, EditorMarker.PARSER_MARKER);
223:                                 excList.add(markableException);
224:                         }
225:                         throw new MultipleCheckExceptions(excList); // NOPMD - "e" is not a cause here
226:                 }
227:         }
228:         
229:         private FilteredTokenStream scanString(final String fileContent) {
230:                 final FilteredTokenStream output = FilteredTokenStream.create();
231:                 final ModelDslScanner scanner = ModelDslScanner.create();
232:                 final SimpleScannerInput input = new SimpleScannerInput(fileContent);
233:                 scanner.scan(input, output);
234:                 return output;
235:         }
236:         
237:         private static String readFile(final URI uri, final Charset encoding) throws IOException {
238:                 final byte[] encoded = Files.readAllBytes(Paths.get(uri.getPath()));
239:                 return new String(encoded, encoding);
240:         }
241:         
242: }