Package: Uml2Vdm

Uml2Vdm

nameinstructionbranchcomplexitylinemethod
Uml2Vdm()
M: 25 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
convert(File)
M: 111 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 18 C: 0
0%
M: 1 C: 0
0%
createClass(Class)
M: 356 C: 0
0%
M: 34 C: 0
0%
M: 18 C: 0
0%
M: 70 C: 0
0%
M: 1 C: 0
0%
createFunction(AClassClassDefinition, Operation)
M: 112 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 16 C: 0
0%
M: 1 C: 0
0%
createInstanceVar(AClassClassDefinition, Property)
M: 101 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 25 C: 0
0%
M: 1 C: 0
0%
createOperation(AClassClassDefinition, Operation)
M: 99 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 14 C: 0
0%
M: 1 C: 0
0%
createValue(AClassClassDefinition, Property)
M: 105 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 25 C: 0
0%
M: 1 C: 0
0%
initialize(URI, String)
M: 38 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 16 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
writeClassFile(File, Map.Entry)
M: 55 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 11 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * #%~
3: * UML2 Translator
4: * %%
5: * Copyright (C) 2008 - 2014 Overture
6: * %%
7: * This program is free software: you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as
9: * published by the Free Software Foundation, either version 3 of the
10: * License, or (at your option) any later version.
11: *
12: * This program is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: * GNU General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public
18: * License along with this program. If not, see
19: * <http://www.gnu.org/licenses/gpl-3.0.html>.
20: * #~%
21: */
22: package org.overture.ide.plugins.uml2.uml2vdm;
23:
24: import java.io.File;
25: import java.io.FileWriter;
26: import java.io.IOException;
27: import java.io.PrintWriter;
28: import java.util.HashMap;
29: import java.util.List;
30: import java.util.Map;
31: import java.util.Map.Entry;
32: import java.util.Vector;
33:
34: import org.eclipse.emf.common.util.URI;
35: import org.eclipse.emf.ecore.EObject;
36: import org.eclipse.emf.ecore.resource.Resource;
37: import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
38: import org.eclipse.ui.PartInitException;
39: import org.eclipse.uml2.uml.Class;
40: import org.eclipse.uml2.uml.Element;
41: import org.eclipse.uml2.uml.Enumeration;
42: import org.eclipse.uml2.uml.Model;
43: import org.eclipse.uml2.uml.Operation;
44: import org.eclipse.uml2.uml.Parameter;
45: import org.eclipse.uml2.uml.Property;
46: import org.eclipse.uml2.uml.Stereotype;
47: import org.overture.ast.analysis.AnalysisException;
48: import org.overture.ast.definitions.AClassClassDefinition;
49: import org.overture.ast.definitions.AExplicitFunctionDefinition;
50: import org.overture.ast.definitions.AExplicitOperationDefinition;
51: import org.overture.ast.definitions.AInstanceVariableDefinition;
52: import org.overture.ast.definitions.ATypeDefinition;
53: import org.overture.ast.definitions.AValueDefinition;
54: import org.overture.ast.definitions.PDefinition;
55: import org.overture.ast.expressions.PExp;
56: import org.overture.ast.factory.AstFactory;
57: import org.overture.ast.lex.Dialect;
58: import org.overture.ast.lex.LexLocation;
59: import org.overture.ast.lex.LexNameToken;
60: import org.overture.ast.patterns.PPattern;
61: import org.overture.ast.types.AAccessSpecifierAccessSpecifier;
62: import org.overture.ast.types.AFunctionType;
63: import org.overture.ast.types.AOperationType;
64: import org.overture.ast.types.PType;
65: import org.overture.config.Settings;
66: import org.overture.ide.plugins.uml2.Activator;
67: import org.overture.ide.plugins.uml2.UmlConsole;
68: import org.overture.parser.lex.LexException;
69: import org.overture.parser.syntax.ParserException;
70: import org.overture.parser.util.ParserUtil;
71: import org.overture.parser.util.ParserUtil.ParserResult;
72: import org.overture.prettyprinter.PrettyPrinterEnv;
73: import org.overture.prettyprinter.PrettyPrinterVisitor;
74:
75: public class Uml2Vdm
76: {
77:         final static LexLocation location = new LexLocation(new File("generated"), "generating", 0, 0, 0, 0, 0, 0);
78:         Model model;
79:         private String extension = "vdmpp";
80:         private VdmTypeCreator tc = null;
81:         private UmlConsole console;
82:         private PExp NEW_A_UNDEFINED_EXP = AstFactory.newAUndefinedExp(location);
83:
84:         public Uml2Vdm()
85:         {
86:                 console = new UmlConsole();
87:                 tc = new VdmTypeCreator(console);
88:         }
89:
90:         public boolean initialize(URI uri, String extension)
91:         {
92:•                if (extension != null)
93:                 {
94:                         this.extension = extension;
95:                 }
96:                 Resource resource = new ResourceSetImpl().getResource(uri, true);
97:•                for (EObject c : resource.getContents())
98:                 {
99:•                        if (c instanceof Model)
100:                         {
101:                                 model = (Model) c;
102:                         }
103:                 }
104:
105:•                return model != null;
106:         }
107:
108:         public void convert(File outputDir)
109:         {
110:•                if (model != null)
111:                 {
112:                         try
113:                         {
114:                                 console.show();
115:                         } catch (PartInitException e2)
116:                         {
117:                         }
118:                         console.out.println("#\n# Starting translation of model: "
119:                                         + model.getName() + "\n#");
120:                         console.out.println("# Into: " + outputDir + "\n#");
121:                         console.out.println("-------------------------------------------------------------------------");
122:                         Map<String, AClassClassDefinition> classes = new HashMap<String, AClassClassDefinition>();
123:•                        for (Element e : model.getOwnedElements())
124:                         {
125:•                                if (e instanceof Class)
126:                                 {
127:                                         Class class_ = (Class) e;
128:                                         console.out.println("Converting: " + class_.getName());
129:                                         classes.put(class_.getName(), createClass(class_));
130:                                 }
131:                         }
132:
133:                         console.out.println("Writing source files");
134:•                        for (Entry<String, AClassClassDefinition> c : classes.entrySet())
135:                         {
136:                                 writeClassFile(outputDir, c);
137:                         }
138:                         console.out.println("Conversion completed.");
139:                 }
140:         }
141:
142:         private void writeClassFile(File outputDir,
143:                         Entry<String, AClassClassDefinition> c)
144:         {
145:                 try
146:                 {
147:                         outputDir.mkdirs();
148:                         FileWriter outFile = new FileWriter(new File(outputDir, c.getKey()
149:                                         + "." + extension));
150:                         PrintWriter out = new PrintWriter(outFile);
151:
152:                         out.println(c.getValue().apply(new PrettyPrinterVisitor(), new PrettyPrinterEnv()));
153:                         out.close();
154:                 } catch (IOException e)
155:                 {
156:                         Activator.log("Error in writeclassfile", e);
157:                 } catch (AnalysisException e)
158:                 {
159:                         Activator.log("Error in writeclassfile", e);
160:                 }
161:         }
162:
163:         private AClassClassDefinition createClass(Class class_)
164:         {
165:                 AClassClassDefinition c = AstFactory.newAClassClassDefinition();
166:                 c.setName(new LexNameToken(class_.getName(), class_.getName(), null));
167:
168:•                elementLoop: for (Element elem : class_.getOwnedElements())
169:                 {
170:•                        if (elem instanceof Class)
171:                         {
172:                                 Class innerType = (Class) elem;
173:                                 String innerTypeName = innerType.getName();
174:                                 AAccessSpecifierAccessSpecifier access = Uml2VdmUtil.createAccessSpecifier(innerType.getVisibility());
175:
176:•                                if (innerType.getNestedClassifier("record") != null
177:•                                                && innerType.getGeneralizations().isEmpty())
178:                                 {
179:                                         boolean createdType = false;
180:•                                        for (EObject innerElem : innerType.getOwnedElements())
181:                                         {
182:•                                                if (innerElem instanceof Stereotype)
183:                                                 {
184:                                                         Stereotype steriotype = (Stereotype) innerElem;
185:•                                                        if (steriotype.getName().equals("record"))
186:                                                         {
187:                                                                 console.out.println("\tConverting inner record type= "
188:                                                                                 + innerTypeName);
189:                                                                 ATypeDefinition innerTypeDef = AstFactory.newATypeDefinition(new LexNameToken(class_.getName(), innerTypeName, location), null, null, null);
190:                                                                 innerTypeDef.setType(tc.createRecord(innerType));
191:                                                                 innerTypeDef.setAccess(access);
192:                                                                 c.getDefinitions().add(innerTypeDef);
193:                                                                 createdType = true;
194:                                                                 break;
195:                                                         }
196:                                                 }
197:                                         }
198:
199:•                                        if (!createdType)
200:                                         {
201:                                                 console.err.println("\tFound type= " + innerTypeName
202:                                                                 + " : " + "unknown type");
203:                                         }
204:•                                } else if (innerTypeName.equalsIgnoreCase("string")// FIX Modelio 2.2.1
205:•                                                || innerType.getGeneralizations().isEmpty())
206:                                 {
207:
208:•                                        for (PDefinition def : c.getDefinitions())
209:                                         {
210:•                                                if (def.getName().getName().equals(innerTypeName))
211:                                                 {
212:                                                         continue elementLoop;
213:                                                 }
214:                                         }
215:                                         String innerTypeTypeName = "Seq<Char>";
216:                                         console.out.println("\tConverting inner type= "
217:                                                         + innerTypeName
218:                                                         + " : "
219:                                                         + innerTypeTypeName
220:                                                         + " Warning the actual type of \""
221:                                                         + innerTypeName
222:                                                         + "\" is undecidable - inserting \"seq of char\" instead");
223:                                         ATypeDefinition innerTypeDef = AstFactory.newATypeDefinition(new LexNameToken(class_.getName(), innerTypeName, location), null, null, null);
224:                                         innerTypeDef.setType(AstFactory.newASeqSeqType(location, AstFactory.newACharBasicType(location)));
225:                                         innerTypeDef.setAccess(access);
226:                                         c.getDefinitions().add(innerTypeDef);
227:
228:                                 } else
229:                                 {
230:                                         String innerTypeTypeName = innerType.getGeneralizations().get(0).getGeneral().getName();
231:                                         console.out.println("\tConverting inner type= "
232:                                                         + innerTypeName + " : " + innerTypeTypeName);
233:                                         ATypeDefinition innerTypeDef = AstFactory.newATypeDefinition(new LexNameToken(class_.getName(), innerTypeName, location), null, null, null);
234:                                         innerTypeDef.setType(tc.convert(innerTypeTypeName, null));
235:                                         innerTypeDef.setAccess(access);
236:                                         c.getDefinitions().add(innerTypeDef);
237:                                 }
238:•                        } else if (elem instanceof Enumeration)
239:                         {
240:                                 String innerTypeName = ((Enumeration) elem).getName();
241:                                 console.out.println("\tConverting inner enumeration type= "
242:                                                 + innerTypeName);
243:                                 ATypeDefinition innerTypeDef = AstFactory.newATypeDefinition(new LexNameToken(class_.getName(), innerTypeName, location), null, null, null);
244:                                 innerTypeDef.setType(tc.createEnumeration((Enumeration) elem));
245:                                 AAccessSpecifierAccessSpecifier access = Uml2VdmUtil.createAccessSpecifier(((Enumeration) elem).getVisibility());
246:                                 innerTypeDef.setAccess(access);
247:                                 c.getDefinitions().add(innerTypeDef);
248:                         }
249:                 }
250:
251:•                for (Property att : class_.getOwnedAttributes())
252:                 {
253:•                        if (att.isReadOnly())
254:                         {
255:                                 createValue(c, att);
256:                         } else
257:                         {
258:                                 createInstanceVar(c, att);
259:                         }
260:                 }
261:
262:•                for (Operation op : class_.getOwnedOperations())
263:                 {
264:•                        if (op.isQuery())
265:                         {
266:                                 createFunction(c, op);
267:                         } else
268:                         {
269:                                 createOperation(c, op);
270:                         }
271:                 }
272:
273:                 return c;
274:         }
275:
276:         private void createFunction(AClassClassDefinition c, Operation op)
277:         {
278:                 console.out.println("\tConverting function: " + op.getName());
279:                 LexNameToken name = new LexNameToken(c.getName().getName(), op.getName(), null);
280:
281:                 List<List<PPattern>> paramPatternList = new Vector<List<PPattern>>();
282:                 List<PPattern> paramPatterns = new Vector<PPattern>();
283:                 paramPatternList.add(paramPatterns);
284:                 List<PType> parameterTypes = new Vector<PType>();
285:
286:•                for (Parameter p : op.getOwnedParameters())
287:                 {
288:•                        if (p.getName() == null)
289:                         {
290:                                 continue;// this is the return type
291:                         }
292:                         parameterTypes.add(tc.convert(p.getType()));
293:                         paramPatterns.add(AstFactory.newAIdentifierPattern(new LexNameToken(c.getName().getName(), p.getName(), location)));
294:                 }
295:
296:                 AFunctionType type = AstFactory.newAFunctionType(null, true, parameterTypes, tc.convert(op.getType()));
297:
298:                 AExplicitFunctionDefinition operation = AstFactory.newAExplicitFunctionDefinition(name, null, null, type, paramPatternList, AstFactory.newAUndefinedExp(null), null, null, false, null);
299:                 operation.setAccess(Uml2VdmUtil.createAccessSpecifier(op.getVisibility(), op.isStatic(), false));
300:                 c.getDefinitions().add(operation);
301:         }
302:
303:         private void createOperation(AClassClassDefinition c, Operation op)
304:         {
305:                 console.out.println("\tConverting operation: " + op.getName());
306:                 LexNameToken name = new LexNameToken(c.getName().getName(), op.getName(), null);
307:                 List<PType> parameterTypes = new Vector<PType>();
308:                 List<PPattern> parameters = new Vector<PPattern>();
309:•                for (Parameter p : op.getOwnedParameters())
310:                 {
311:•                        if (p.getName() == null)
312:                         {
313:                                 continue;// this is the return type
314:                         }
315:                         parameterTypes.add(tc.convert(p.getType()));
316:                         parameters.add(AstFactory.newAIdentifierPattern(new LexNameToken(c.getName().getName(), p.getName(), location)));
317:                 }
318:                 AOperationType type = AstFactory.newAOperationType(null, parameterTypes, tc.convert(op.getType()));
319:
320:                 AExplicitOperationDefinition operation = AstFactory.newAExplicitOperationDefinition(name, type, parameters, null, null, AstFactory.newANotYetSpecifiedStm(null));
321:                 operation.setAccess(Uml2VdmUtil.createAccessSpecifier(op.getVisibility(), op.isStatic(), false));
322:                 c.getDefinitions().add(operation);
323:         }
324:
325:         private void createInstanceVar(AClassClassDefinition c, Property att)
326:         {
327:                 console.out.println("\tConverting instance variable: " + att.getName());
328:                 PType type = tc.convert(att);
329:                 PExp defaultExp = null;// NEW_A_INT_ZERRO_LITERAL_EXP.clone();
330:•                if (att.getDefault() != null && !att.getDefault().isEmpty())
331:                 {
332:                         Settings.dialect = Dialect.VDM_PP;
333:                         ParserResult<PExp> resExp = null;
334:                         boolean failed = false;
335:                         try
336:                         {
337:                                 resExp = ParserUtil.parseExpression(att.getDefault());
338:                         } catch (ParserException e)
339:                         {
340:                                 failed = true;
341:                                 e.printStackTrace();
342:                         } catch (LexException e)
343:                         {
344:                                 failed = true;
345:                                 e.printStackTrace();
346:                         }
347:•                        if (resExp.errors.isEmpty() && !failed)
348:                         {
349:                                 defaultExp = resExp.result;
350:                         } else
351:                         {
352:                                 console.err.println("\tFaild to parse expression for attribute: "
353:                                                 + att.getName()
354:                                                 + " in class "
355:                                                 + c.getName().getName()
356:                                                 + " default is: " + att.getDefault());
357:                         }
358:                 }
359:                 AInstanceVariableDefinition inst = AstFactory.newAInstanceVariableDefinition(new LexNameToken(c.getName().getName(), att.getName(), location), type, defaultExp);
360:                 c.getDefinitions().add(inst);
361:         }
362:
363:         private void createValue(AClassClassDefinition c, Property att)
364:         {
365:                 console.out.println("\tConverting value: " + att.getName());
366:                 PType type = tc.convert(att);
367:
368:                 PExp defaultExp = NEW_A_UNDEFINED_EXP.clone();
369:•                if (att.getDefault() != null && !att.getDefault().isEmpty())
370:                 {
371:                         Settings.dialect = Dialect.VDM_PP;
372:                         ParserResult<PExp> resExp = null;
373:                         boolean failed = false;
374:                         try
375:                         {
376:                                 resExp = ParserUtil.parseExpression(att.getDefault());
377:                         } catch (ParserException e)
378:                         {
379:                                 failed = true;
380:                                 e.printStackTrace();
381:                         } catch (LexException e)
382:                         {
383:                                 failed = true;
384:                                 e.printStackTrace();
385:                         }
386:•                        if (resExp.errors.isEmpty() && !failed)
387:                         {
388:                                 defaultExp = resExp.result;
389:                         } else
390:                         {
391:                                 console.err.println("\tFaild to parse expression for attribute: "
392:                                                 + att.getName()
393:                                                 + " in class "
394:                                                 + c.getName().getName()
395:                                                 + " default is: " + att.getDefault());
396:                         }
397:                 }
398:
399:                 AValueDefinition inst = AstFactory.newAValueDefinition(AstFactory.newAIdentifierPattern(new LexNameToken(c.getName().getName(), att.getName(), location)), null, type, defaultExp);
400:                 c.getDefinitions().add(inst);
401:         }
402: }