aboutsummaryrefslogtreecommitdiffstats
path: root/Metrics/Metrics-Calculation/RealisticRunner/src/ca/mcgill/dslreasoner/runner/RandomEMFRunner.java
diff options
context:
space:
mode:
Diffstat (limited to 'Metrics/Metrics-Calculation/RealisticRunner/src/ca/mcgill/dslreasoner/runner/RandomEMFRunner.java')
-rw-r--r--Metrics/Metrics-Calculation/RealisticRunner/src/ca/mcgill/dslreasoner/runner/RandomEMFRunner.java402
1 files changed, 402 insertions, 0 deletions
diff --git a/Metrics/Metrics-Calculation/RealisticRunner/src/ca/mcgill/dslreasoner/runner/RandomEMFRunner.java b/Metrics/Metrics-Calculation/RealisticRunner/src/ca/mcgill/dslreasoner/runner/RandomEMFRunner.java
new file mode 100644
index 00000000..ddc5e26b
--- /dev/null
+++ b/Metrics/Metrics-Calculation/RealisticRunner/src/ca/mcgill/dslreasoner/runner/RandomEMFRunner.java
@@ -0,0 +1,402 @@
1package ca.mcgill.dslreasoner.runner;
2
3import java.io.IOException;
4import java.io.PrintWriter;
5import java.io.StringWriter;
6import java.text.MessageFormat;
7import java.util.ArrayList;
8import java.util.Collections;
9import java.util.Comparator;
10import java.util.List;
11import java.util.logging.Logger;
12
13import org.apache.commons.cli.CommandLine;
14import org.apache.commons.cli.CommandLineParser;
15import org.apache.commons.cli.GnuParser;
16import org.apache.commons.cli.HelpFormatter;
17import org.apache.commons.cli.Option;
18import org.apache.commons.cli.OptionBuilder;
19import org.apache.commons.cli.Options;
20import org.apache.commons.cli.ParseException;
21import org.apache.commons.lang3.Range;
22import org.eclipse.emf.common.util.BasicDiagnostic;
23import org.eclipse.emf.common.util.Diagnostic;
24import org.eclipse.emf.common.util.URI;
25import org.eclipse.emf.ecore.EObject;
26import org.eclipse.emf.ecore.EPackage;
27import org.eclipse.emf.ecore.EcorePackage;
28import org.eclipse.emf.ecore.resource.Resource;
29import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
30import org.eclipse.emf.ecore.util.Diagnostician;
31import org.eclipse.emf.ecore.util.EcoreUtil;
32import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl;
33import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
34import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
35
36import fr.inria.atlanmod.instantiator.GenerationException;
37import fr.inria.atlanmod.instantiator.GenericMetamodelConfig;
38import fr.obeo.emf.specimen.SpecimenGenerator;
39
40public class RandomEMFRunner implements IGeneratorRunner{
41 public final static Logger LOGGER = Logger.getLogger(RandomEMFRunner.class.getName());
42
43 protected GenericMetamodelConfig config;
44
45 protected SpecimenGenerator generator;
46 private int size;
47
48 private static final int DEFAULT_AVERAGE_MODEL_SIZE = 1000;
49 private static final float DEFAULT_DEVIATION = 0.1f;
50
51 private static final int ERROR = 1;
52
53 private static final String METAMODEL = "m";
54 private static final String METAMODEL_LONG = "metamodel";
55 private static final String ADDITIONAL_METAMODEL = "a";
56 private static final String ADDITIONAL_METAMODEL_LONG = "additional-metamodel";
57 private static final String OUTPUT_DIR = "o";
58 private static final String OUTPUT_DIR_LONG = "output-dir";
59 private static final String N_MODELS = "n";
60 private static final String N_MODELS_LONG = "number-models";
61 private static final String SIZE = "s";
62 private static final String SIZE_LONG = "size";
63 private static final String VARIATION = "p";
64 private static final String VARIATION_LONG = "variation";
65 private static final String PROP_VARIATION = "v";
66 private static final String PROP_VARIATION_LONG = "properties-variation";
67 private static final String DEGREE = "d";
68 private static final String DEGREE_LONG = "references-degree";
69 private static final String VALUES_SIZE = "z";
70 private static final String VALUES_SIZE_LONG = "values-size";
71 private static final String SEED = "e";
72 private static final String SEED_LONG = "seed";
73 private static final String FORCE = "f";
74 private static final String FORCE_LONG = "force";
75 private static final String DIAGNOSE = "g";
76 private static final String DIAGNOSE_LONG = "diagnose";
77 private static final String ROOT = "r";
78 private static final String ROOT_LONG = "root";
79
80 public RandomEMFRunner(String[] args) throws IllegalArgumentException, GenerationException, IOException {
81 super();
82 this.config = config(args);
83
84 generator = new SpecimenGenerator(config, config.getSeed());
85 }
86
87
88 private static class OptionComparator<T extends Option> implements Comparator<T> {
89 private static final String OPTS_ORDER = "maonspdzefg";
90
91 @Override
92 public int compare(T o1, T o2) {
93 return OPTS_ORDER.indexOf(o1.getOpt()) - OPTS_ORDER.indexOf(o2.getOpt());
94 }
95 }
96
97 public GenericMetamodelConfig config(String[] args) throws GenerationException, IOException {
98
99 {
100 // Initialize the global registry
101 Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
102 EcorePackage.eNS_PREFIX, new EcoreResourceFactoryImpl());
103 Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
104 Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());
105 }
106
107 Options options = new Options();
108
109 configureOptions(options);
110
111 CommandLineParser parser = new GnuParser();
112
113 try {
114 CommandLine commandLine = parser.parse(options, args);
115
116 String metamodel = commandLine.getOptionValue(METAMODEL);
117
118 Resource metamodelResource = new XMIResourceImpl(URI.createFileURI(metamodel));
119 metamodelResource.load(Collections.emptyMap());
120 EcoreUtil.resolveAll(metamodelResource);
121 {
122 BasicDiagnostic diagnosticChain = diagnoseResource(metamodelResource);
123 if (isFailed(diagnosticChain)) {
124 LOGGER.severe(MessageFormat.format(
125 "Found ''{0}'' unrecoverable issues(s) in the resource ''{1}''. Please fix them before attempting a generation or use option -{2}|--{3}.",
126 diagnosticChain.getChildren().size(), metamodelResource.getURI(), FORCE, FORCE_LONG));
127 for (Diagnostic diagnostic : diagnosticChain.getChildren()) {
128 LOGGER.severe(diagnostic.getMessage());
129 }
130 if (commandLine.hasOption(FORCE)) {
131 LOGGER.info(MessageFormat.format(
132 "An attempt to run the generation will be done anyway (-{0}|--{1} option selected)",
133 FORCE, FORCE_LONG));
134 } else {
135 System.exit(ERROR);
136 }
137 } else if (isWarning(diagnosticChain)) {
138 LOGGER.warning(MessageFormat.format(
139 "Found ''{0}'' issue(s) in the resource ''{1}''. An attempt to run the generation will be done anyway.",
140 diagnosticChain.getChildren().size(), metamodelResource.getURI()));
141 for (Diagnostic diagnostic : diagnosticChain.getChildren()) {
142 LOGGER.fine(diagnostic.getMessage());
143 }
144 }
145 }
146
147 registerPackages(metamodelResource);
148
149 size = DEFAULT_AVERAGE_MODEL_SIZE;
150 if (commandLine.hasOption(SIZE)) {
151 Number number = (Number) commandLine.getParsedOptionValue(SIZE);
152 size = (int) Math.min(Integer.MAX_VALUE, number.longValue());
153 }
154
155 float variation = DEFAULT_DEVIATION;
156 if (commandLine.hasOption(VARIATION)) {
157 Number number = (Number) commandLine.getParsedOptionValue(VARIATION);
158 if (number.floatValue() < 0.0f || number.floatValue() > 1.0f) {
159 throw new ParseException(MessageFormat.format("Invalid value for option -{0}: {1}", VARIATION, number.floatValue()));
160 }
161 variation = number.floatValue();
162 }
163
164 float propVariation = DEFAULT_DEVIATION;
165 if (commandLine.hasOption(PROP_VARIATION)) {
166 Number number = (Number) commandLine.getParsedOptionValue(PROP_VARIATION);
167 if (number.floatValue() < 0.0f || number.floatValue() > 1.0f) {
168 throw new ParseException(MessageFormat.format("Invalid value for option -{0}: {1}", PROP_VARIATION, number.floatValue()));
169 }
170 propVariation = number.floatValue();
171 }
172
173
174 long seed = System.currentTimeMillis();
175 if (commandLine.hasOption(SEED)) {
176 seed = ((Number) commandLine.getParsedOptionValue(SEED)).longValue();
177 }
178
179 String root = null;
180 if (commandLine.hasOption(ROOT)) {
181 root = (String) commandLine.getParsedOptionValue(ROOT);
182 }
183
184 Range<Integer> range = Range.between(
185 Math.round(size * (1 - variation)),
186 Math.round(size * (1 + variation)));
187
188 GenericMetamodelConfig config = new GenericMetamodelConfig(metamodelResource, range, seed, root);
189
190 int valuesSize = GenericMetamodelConfig.DEFAULT_AVERAGE_VALUES_LENGTH;
191 if (commandLine.hasOption(VALUES_SIZE)) {
192 Number number = (Number) commandLine.getParsedOptionValue(VALUES_SIZE);
193 valuesSize = (int) Math.min(Integer.MAX_VALUE, number.longValue());
194 }
195
196 int referencesSize = GenericMetamodelConfig.DEFAULT_AVERAGE_REFERENCES_SIZE;
197 if (commandLine.hasOption(VALUES_SIZE)) {
198 Number number = (Number) commandLine.getParsedOptionValue(DEGREE);
199 referencesSize = (int) Math.min(Integer.MAX_VALUE, number.longValue());
200 }
201
202
203 config.setValuesRange(
204 Math.round(valuesSize * (1 - propVariation)),
205 Math.round(valuesSize * (1 + propVariation)));
206
207 config.setReferencesRange(
208 Math.round(referencesSize * (1 - propVariation)),
209 Math.round(referencesSize * (1 + propVariation)));
210
211 config.setPropertiesRange(
212 Math.round(referencesSize * (1 - propVariation)),
213 Math.round(referencesSize * (1 + propVariation)));
214
215 return config;
216
217 } catch (ParseException e) {
218 System.err.println(e.getLocalizedMessage());
219 HelpFormatter formatter = new HelpFormatter();
220 formatter.setOptionComparator(new OptionComparator<Option>());
221 formatter.printHelp("java -jar <this-file.jar>", options, true);
222 System.exit(ERROR);
223 return null;
224 } catch (Throwable t) {
225 System.err.println("ERROR: " + t.getLocalizedMessage());
226 StringWriter stringWriter = new StringWriter();
227 t.printStackTrace(new PrintWriter(stringWriter));
228 t.printStackTrace();
229 LOGGER.fine(stringWriter.toString());
230 System.exit(ERROR);
231 return null;
232 }
233 }
234
235
236
237 private static BasicDiagnostic diagnoseResource(Resource resource) {
238 BasicDiagnostic diagnosticChain = new BasicDiagnostic();
239 for (EObject eObject : resource.getContents()) {
240 Diagnostician.INSTANCE.validate(eObject, diagnosticChain);
241 }
242 return diagnosticChain;
243 }
244
245 private static boolean isFailed(BasicDiagnostic diagnosticChain) {
246 return (diagnosticChain.getSeverity() & Diagnostic.ERROR) == Diagnostic.ERROR;
247 }
248
249 private static boolean isWarning(BasicDiagnostic diagnosticChain) {
250 return (diagnosticChain.getSeverity() & Diagnostic.WARNING) == Diagnostic.WARNING;
251 }
252
253
254 /**
255 * Configures the program options
256 *
257 * @param options
258 */
259 private static void configureOptions(Options options) {
260 Option metamodelOpt = OptionBuilder.create(METAMODEL);
261 metamodelOpt.setLongOpt(METAMODEL_LONG);
262 metamodelOpt.setArgName("path_to_metamodel.ecore");
263 metamodelOpt.setDescription("Ecore metamodel");
264 metamodelOpt.setArgs(1);
265 metamodelOpt.setRequired(true);
266
267 Option additionalMetamodelOpt = OptionBuilder.create(ADDITIONAL_METAMODEL);
268 additionalMetamodelOpt.setLongOpt(ADDITIONAL_METAMODEL_LONG);
269 additionalMetamodelOpt.setArgName("path_to_metamodel.ecore");
270 additionalMetamodelOpt.setDescription("Additional ecore metamodel(s) that need to be registered");
271 additionalMetamodelOpt.setArgs(Option.UNLIMITED_VALUES);
272
273 Option outDirOpt = OptionBuilder.create(OUTPUT_DIR);
274 outDirOpt.setLongOpt(OUTPUT_DIR_LONG);
275 outDirOpt.setArgName("path_to_output.dir");
276 outDirOpt.setDescription("Output directory (defaults to working dir)");
277 outDirOpt.setArgs(1);
278
279 Option nModelsOpt = OptionBuilder.create(N_MODELS);
280 nModelsOpt.setLongOpt(N_MODELS_LONG);
281 nModelsOpt.setArgName("models");
282 nModelsOpt.setDescription("Number of generated models (defaults to 1)");
283 nModelsOpt.setType(Number.class);
284 nModelsOpt.setArgs(1);
285
286 Option sizeOption = OptionBuilder.create(SIZE);
287 sizeOption.setLongOpt(SIZE_LONG);
288 sizeOption.setArgName("size");
289 sizeOption.setDescription(MessageFormat.format("Average models'' size (defaults to {0})", DEFAULT_AVERAGE_MODEL_SIZE));
290 sizeOption.setType(Number.class);
291 sizeOption.setArgs(1);
292
293 Option variationOption = OptionBuilder.create(VARIATION);
294 variationOption.setLongOpt(VARIATION_LONG);
295 variationOption.setArgName("proportion");
296 variationOption.setDescription(
297 MessageFormat.format("Variation ([0..1]) in the models'' size (defaults to {0})",
298 DEFAULT_DEVIATION));
299 variationOption.setType(Number.class);
300 variationOption.setArgs(1);
301
302 Option propVariationOption = OptionBuilder.create(PROP_VARIATION);
303 propVariationOption.setLongOpt(PROP_VARIATION_LONG);
304 propVariationOption.setArgName("properties deviation");
305 propVariationOption.setDescription(
306 MessageFormat.format("Variation ([0..1]) in the properties'' size (defaults to {0})",
307 DEFAULT_DEVIATION));
308 propVariationOption.setType(Number.class);
309 propVariationOption.setArgs(1);
310
311 Option seedOption = OptionBuilder.create(SEED);
312 seedOption.setLongOpt(SEED_LONG);
313 seedOption.setArgName("seed");
314 seedOption.setDescription("Seed number (random by default)");
315 seedOption.setType(Number.class);
316 seedOption.setArgs(1);
317
318 Option rootOption = OptionBuilder.create(ROOT);
319 rootOption.setLongOpt(ROOT_LONG);
320 rootOption.setArgName("root");
321 rootOption.setDescription("root class of the generated model (random by default)");
322 rootOption.setType(String.class);
323 rootOption.setArgs(1);
324
325 Option valuesSizeOption = OptionBuilder.create(VALUES_SIZE);
326 valuesSizeOption.setLongOpt(VALUES_SIZE_LONG);
327 valuesSizeOption.setArgName("size");
328 valuesSizeOption.setDescription(
329 MessageFormat.format("Average size for attributes with variable length (defaults to {0}). Actual sizes may vary +/- {1}%.",
330 GenericMetamodelConfig.DEFAULT_AVERAGE_VALUES_LENGTH, GenericMetamodelConfig.DEFAULT_VALUES_DEVIATION * 100));
331 valuesSizeOption.setType(Number.class);
332 valuesSizeOption.setArgs(1);
333
334 Option degreeOption = OptionBuilder.create(DEGREE);
335 degreeOption.setLongOpt(DEGREE_LONG);
336 degreeOption.setArgName("degree");
337 degreeOption.setDescription(
338 MessageFormat.format("Average number of references per EObject (defaults to {0}). Actual sizes may vary +/- {1}%.",
339 GenericMetamodelConfig.DEFAULT_AVERAGE_REFERENCES_SIZE, GenericMetamodelConfig.DEFAULT_REFERENCES_DEVIATION * 100));
340 degreeOption.setType(Number.class);
341 degreeOption.setArgs(1);
342
343 Option forceOption = OptionBuilder.create(FORCE);
344 forceOption.setLongOpt(FORCE_LONG);
345 forceOption.setDescription("Force the generation, even if input metamodels contain errors");
346
347 Option diagnoseOption = OptionBuilder.create(DIAGNOSE);
348 diagnoseOption.setLongOpt(DIAGNOSE_LONG);
349 diagnoseOption.setDescription("Run diagnosis on the result model");
350
351
352 options.addOption(metamodelOpt);
353 options.addOption(additionalMetamodelOpt);
354 options.addOption(outDirOpt);
355 options.addOption(nModelsOpt);
356 options.addOption(sizeOption);
357 options.addOption(variationOption);
358 options.addOption(propVariationOption);
359 options.addOption(valuesSizeOption);
360 options.addOption(degreeOption);
361 options.addOption(seedOption);
362 options.addOption(rootOption);
363 options.addOption(forceOption);
364 options.addOption(diagnoseOption);
365 }
366
367 /**
368 * Registers the packages
369 * @param resource
370 */
371 private static void registerPackages(Resource resource) {
372 EObject eObject = resource.getContents().get(0);
373 if (eObject instanceof EPackage) {
374 EPackage p = (EPackage) eObject;
375 EPackage.Registry.INSTANCE.put(p.getNsURI(), p);
376 }
377 }
378
379 @Override
380 public List<EObject> runGeneration(int run) throws GenerationException {
381
382 List<EObject> roots = new ArrayList<EObject>();
383
384 generator = new SpecimenGenerator(config, System.currentTimeMillis());
385
386 for (int i = 0; i < run; i++) {
387 ResourceImpl resource = new ResourceImpl();
388 generator.generate(resource);
389 roots.add(resource.getContents().get(0));
390 }
391
392 return roots;
393
394 }
395
396 protected String getMetaModelResourceName() {
397 URI metamodelURI = config.getMetamodelResource().getURI();
398 return metamodelURI.lastSegment().substring(0, metamodelURI.lastSegment().indexOf("."));
399 }
400
401
402}