diff options
Diffstat (limited to 'Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io')
3 files changed, 264 insertions, 0 deletions
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/CsvFileWriter.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/CsvFileWriter.xtend new file mode 100644 index 00000000..00b38d90 --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/CsvFileWriter.xtend | |||
@@ -0,0 +1,52 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io; | ||
2 | |||
3 | import java.io.File | ||
4 | import java.io.FileNotFoundException | ||
5 | import java.io.FileOutputStream | ||
6 | import java.io.PrintWriter | ||
7 | import java.util.ArrayList | ||
8 | import java.util.List | ||
9 | |||
10 | class CsvFileWriter { | ||
11 | |||
12 | def static void write(ArrayList<ArrayList<String>> datas, String uri) { | ||
13 | if(datas.size() <= 0) { | ||
14 | return; | ||
15 | } | ||
16 | val PrintWriter writer = new PrintWriter(new File(uri)); | ||
17 | output(writer, datas, uri); | ||
18 | } | ||
19 | |||
20 | def static void append(ArrayList<ArrayList<String>> datas, String uri) { | ||
21 | if(datas.size() <= 0) { | ||
22 | return; | ||
23 | } | ||
24 | val PrintWriter writer = new PrintWriter(new FileOutputStream(new File(uri), true)); | ||
25 | output(writer, datas, uri); | ||
26 | } | ||
27 | |||
28 | |||
29 | def private static void output(PrintWriter writer, ArrayList<ArrayList<String>> datas, String uri) { | ||
30 | //println("Output csv for " + uri); | ||
31 | try { | ||
32 | |||
33 | val output = new StringBuilder; | ||
34 | for(List<String> datarow : datas){ | ||
35 | for(var i = 0; i < datarow.size() - 1; i++){ | ||
36 | output.append(datarow.get(i) + ','); | ||
37 | } | ||
38 | |||
39 | if(datarow.size >= 1){ | ||
40 | output.append(datarow.get(datarow.size() - 1)); | ||
41 | output.append('\n'); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | writer.write(output.toString()); | ||
46 | writer.close(); | ||
47 | //println("Output csv finished"); | ||
48 | }catch(FileNotFoundException e) { | ||
49 | e.printStackTrace(); | ||
50 | } | ||
51 | } | ||
52 | } | ||
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend new file mode 100644 index 00000000..053e0da3 --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend | |||
@@ -0,0 +1,112 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io; | ||
2 | |||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.EMFGraph | ||
4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.EdgeTypeMetric | ||
5 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric | ||
6 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric | ||
7 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric | ||
8 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeTypeMetric | ||
9 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric | ||
10 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.TypedOutDegree | ||
11 | import java.io.File | ||
12 | import java.io.FileNotFoundException | ||
13 | import java.util.ArrayList | ||
14 | import java.util.List | ||
15 | import org.eclipse.emf.common.util.URI | ||
16 | import org.eclipse.emf.ecore.EObject | ||
17 | import org.eclipse.emf.ecore.EPackage | ||
18 | import org.eclipse.emf.ecore.EReference | ||
19 | import org.eclipse.emf.ecore.resource.Resource | ||
20 | import org.eclipse.emf.ecore.resource.ResourceSet | ||
21 | import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl | ||
22 | import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl | ||
23 | import org.eclipse.emf.ecore.EGenericType | ||
24 | import org.eclipse.emf.ecore.EStructuralFeature | ||
25 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.TypedClusteringCoefficientMetric | ||
26 | |||
27 | class GraphReader{ | ||
28 | val ResourceSet resSet = new ResourceSetImpl(); | ||
29 | val referenceTypes = new ArrayList<EReference>(); | ||
30 | var String suffix; | ||
31 | |||
32 | new(EPackage metaModel, String suffix) { | ||
33 | Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put("*",new XMIResourceFactoryImpl) | ||
34 | this.suffix = suffix; | ||
35 | |||
36 | //find all reference types in the meta model | ||
37 | metaModel.eAllContents.forEach[ | ||
38 | if(it instanceof EReference){ | ||
39 | referenceTypes.add(it); | ||
40 | } | ||
41 | ] | ||
42 | } | ||
43 | |||
44 | def List<EMFGraph> readModels(String path){ | ||
45 | val dir = new File(path); | ||
46 | if(!dir.isDirectory){ | ||
47 | throw new Exception("expecting a directory"); | ||
48 | } | ||
49 | |||
50 | val graphs = new ArrayList<EMFGraph>(); | ||
51 | |||
52 | val metrics = new ArrayList<Metric>(); | ||
53 | metrics.add(new OutDegreeMetric()); | ||
54 | metrics.add(new NodeActivityMetric()); | ||
55 | metrics.add(new MultiplexParticipationCoefficientMetric()); | ||
56 | metrics.add(new TypedOutDegree()); | ||
57 | metrics.add(new NodeTypeMetric()); | ||
58 | metrics.add(new EdgeTypeMetric()); | ||
59 | var count = 1 | ||
60 | //check all files in the directory with suffix | ||
61 | for(String name : dir.list.filter[it| it.endsWith(suffix)]){ | ||
62 | val file = new File(name); | ||
63 | val roots = readModel(EObject, path, file.name); | ||
64 | //add a list of metrics | ||
65 | val g = new EMFGraph(); | ||
66 | for(root : roots){ | ||
67 | g.init(root, metrics, name.replaceFirst(suffix, ""), referenceTypes); | ||
68 | } | ||
69 | |||
70 | count ++; | ||
71 | graphs.add(g); | ||
72 | } | ||
73 | |||
74 | return graphs; | ||
75 | } | ||
76 | |||
77 | def EMFGraph readModel(String path, String filename){ | ||
78 | val metrics = new ArrayList<Metric>(); | ||
79 | metrics.add(new OutDegreeMetric()); | ||
80 | metrics.add(new NodeActivityMetric()); | ||
81 | metrics.add(new MultiplexParticipationCoefficientMetric()); | ||
82 | metrics.add(new TypedOutDegree()); | ||
83 | metrics.add(new NodeTypeMetric()); | ||
84 | metrics.add(new EdgeTypeMetric()); | ||
85 | |||
86 | val file = new File(filename); | ||
87 | val roots = readModel(EObject, path, file.name); | ||
88 | //add a list of metrics | ||
89 | val g = new EMFGraph(); | ||
90 | for(root : roots){ | ||
91 | g.init(root, metrics, filename.replaceFirst(suffix, ""), referenceTypes); | ||
92 | } | ||
93 | return g | ||
94 | } | ||
95 | |||
96 | def <RootType extends EObject> List<RootType> readModel(Class<RootType> type, String path, String name) { | ||
97 | try { | ||
98 | val resource = resSet.getResource(getURI(path, name),true); | ||
99 | if(resource === null) throw new FileNotFoundException(getURI(path, name).toString) | ||
100 | else { | ||
101 | return resource.contents as List<RootType> | ||
102 | } | ||
103 | } catch(Exception e) { | ||
104 | e.printStackTrace(); | ||
105 | throw new Exception(getURI(path, name).toString()); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | def static getURI(String path, String name) { | ||
110 | URI.createFileURI(path + "/" + name) | ||
111 | } | ||
112 | } \ No newline at end of file | ||
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend new file mode 100644 index 00000000..2e7be586 --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend | |||
@@ -0,0 +1,100 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io | ||
2 | |||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain | ||
4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup | ||
5 | import github.impl.GithubPackageImpl | ||
6 | import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.impl.YakindummPackageImpl | ||
7 | import java.util.HashMap | ||
8 | import org.eclipse.emf.ecore.EReference | ||
9 | import org.eclipse.emf.ecore.impl.EcorePackageImpl | ||
10 | |||
11 | /** | ||
12 | * Read the sample of the distribution of a metric provided the csv file of the metric | ||
13 | */ | ||
14 | class RepMetricsReader { | ||
15 | static var Domain domain; | ||
16 | static def read(Domain d){ | ||
17 | var GraphReader reader; | ||
18 | if(d == Domain.Yakindumm){ | ||
19 | reader = new GraphReader(YakindummPackageImpl.eINSTANCE, '.xmi'); | ||
20 | }else if (d == Domain.Ecore){ | ||
21 | reader = new GraphReader(EcorePackageImpl.eINSTANCE, '.ecore'); | ||
22 | }else if (d == Domain.Github){ | ||
23 | reader = new GraphReader(GithubPackageImpl.eINSTANCE, '.githubmodel') | ||
24 | } | ||
25 | |||
26 | domain = d; | ||
27 | |||
28 | var domainRepPath = DataName.REP_PATH + d.name + '/'; | ||
29 | var rep = new MetricSampleGroup() | ||
30 | var out_d = readMetrics(reader, domainRepPath + DataName.OUT_D_REP); | ||
31 | var mpc = readMetrics(reader, domainRepPath + DataName.MPC_REP); | ||
32 | rep.mpcSamples = mpc.mpcSamples; | ||
33 | rep.outDegreeSamples = out_d.outDegreeSamples; | ||
34 | rep.naSamples = readMetrics(reader, domainRepPath + DataName.NA_REP).naSamples; | ||
35 | rep.typedOutDegreeSamples = out_d.typedOutDegreeSamples; | ||
36 | rep.edgeTypeSamples = mpc.edgeTypeSamples; | ||
37 | |||
38 | //TODO: Parameterize the prior node distribution | ||
39 | var nodeTypeSamples = new HashMap<String, Double>(); | ||
40 | if(d == Domain.Yakindumm){ | ||
41 | nodeTypeSamples.put('Entry', 0.04257802080554814); | ||
42 | nodeTypeSamples.put('Choice', 0.1267671379034409); | ||
43 | nodeTypeSamples.put('State', 0.1596092291277674); | ||
44 | nodeTypeSamples.put('Transition', 0.6138636969858629); | ||
45 | nodeTypeSamples.put('Statechart', 0.010136036276340358); | ||
46 | nodeTypeSamples.put('Region', 0.04467858095492131); | ||
47 | nodeTypeSamples.put('Exit', 0.0018338223526273673); | ||
48 | nodeTypeSamples.put('FinalState', 0.0005334755934915977); | ||
49 | }else if(d ==Domain.Ecore){ | ||
50 | nodeTypeSamples.put('EAttribute', 0.23539778449144008); | ||
51 | nodeTypeSamples.put('EClass', 0.33081570996978854); | ||
52 | nodeTypeSamples.put('EReference', 0.30996978851963747); | ||
53 | nodeTypeSamples.put('EPackage', 0.012789526686807653); | ||
54 | nodeTypeSamples.put('EAnnotation', 0.002517623363544813); | ||
55 | nodeTypeSamples.put('EEnumLiteral', 0.07275931520644502); | ||
56 | nodeTypeSamples.put('EEnum', 0.013645518630412891); | ||
57 | nodeTypeSamples.put('EDataType', 0.004028197381671702); | ||
58 | nodeTypeSamples.put('EParameter', 0.005941591137965764); | ||
59 | nodeTypeSamples.put('EGenericType', 0.002014098690835851); | ||
60 | nodeTypeSamples.put('EOperation', 0.009415911379657605); | ||
61 | nodeTypeSamples.put('ETypeParameter', 0.0007049345417925478); | ||
62 | }else if (d == Domain.Github){ | ||
63 | nodeTypeSamples.put('Project', 0.012636538873420432); | ||
64 | nodeTypeSamples.put('Commit', 0.5525808524309276); | ||
65 | nodeTypeSamples.put('User', 0.05847076461769116); | ||
66 | nodeTypeSamples.put('Issue', 0.12743628185907047); | ||
67 | nodeTypeSamples.put('PullRequest', 0.07560505461554937); | ||
68 | nodeTypeSamples.put('IssueEvent', 0.17327050760334123); | ||
69 | } | ||
70 | |||
71 | |||
72 | |||
73 | rep.nodeTypeSamples = nodeTypeSamples; | ||
74 | return rep; | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * Read representative model | ||
79 | */ | ||
80 | private static def readMetrics(GraphReader r, String path){ | ||
81 | val model = r.readModels(path).head; | ||
82 | if(domain == Domain.Ecore){ | ||
83 | var refsToRemove = EcorePackageImpl.eINSTANCE.eAllContents.filter(EReference).filter[ | ||
84 | it.name.equals('eGenericType') || it.name.equals('eGenericSuperTypes') || it.name.equals('eFactoryInstance') || | ||
85 | it.name.equals('eGenericExceptions') || it.name.equals('references') || it.name.equals('contents'); | ||
86 | ]; | ||
87 | refsToRemove.forEach[model.removeReference(it)]; | ||
88 | } | ||
89 | return model.evaluateAllMetricsToSamples(); | ||
90 | } | ||
91 | |||
92 | } | ||
93 | |||
94 | class DataName{ | ||
95 | public static val REP_PATH = 'data/'; | ||
96 | public static val MPC_REP = 'mpc_rep'; | ||
97 | public static val NA_REP = 'na_rep'; | ||
98 | public static val OUT_D_REP = 'out_d_rep'; | ||
99 | } | ||
100 | |||