-
Notifications
You must be signed in to change notification settings - Fork 6
/
GMATransform.xtend
167 lines (132 loc) · 5.16 KB
/
GMATransform.xtend
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package com.opcoach.genmodeladdon.core.genmodel
import com.opcoach.genmodeladdon.core.GMAConstants
import com.opcoach.genmodeladdon.core.GenerateCommon
import java.text.MessageFormat
import java.util.Map
import java.util.TreeMap
import java.util.function.Consumer
import org.eclipse.emf.codegen.ecore.genmodel.GenBase
import org.eclipse.emf.codegen.ecore.genmodel.GenModel
import org.eclipse.emf.ecore.EClass
import org.eclipse.emf.ecore.EClassifier
import org.eclipse.emf.ecore.EPackage
import org.eclipse.emf.ecore.EcorePackage
/** This class computes the new names for generated classes according to pattern name matching */
class GMATransform implements GMAConstants {
// The map of devnames : key = implementation name, value = devName
protected Map<String, String> devNames = new TreeMap<String, String>()
String devInterfaceNamePattern = ADVISED_DEV_INTERFACE_PATTERN
String genInterfaceNamePattern = ADVISED_GEN_INTERFACE_PATTERN
String devClassNamePattern = ADVISED_DEV_CLASS_IMPL_PATTERN
String genClassNamePattern = ADVISED_GEN_CLASS_IMPL_PATTERN
GenModel gm
boolean isInit = false
new(GenModel gm) {
this(gm, true)
}
private new(GenModel gm, boolean mustInitNames) {
this.gm = gm
// Try to get the dev interface and class values set in properties
if (mustInitNames) {
initNames
}
}
new(GenModel gm, String devIntNamePattern, String genIntNamePattern, String devClassNamePattern,
String genClassNamePattern) {
this(gm, false)
this.devInterfaceNamePattern = devIntNamePattern
this.genInterfaceNamePattern = genIntNamePattern
this.devClassNamePattern = devClassNamePattern
this.genClassNamePattern = genClassNamePattern
}
// Set the value in the consumer if not null
private def initValue(String v, Consumer<String> consumer) {
if ((v !== null) && v.length > 0)
consumer.accept(v)
}
private def initNames() {
initValue(gm.classNamePattern, [v|this.genClassNamePattern = v])
initValue(gm.interfaceNamePattern, [v|this.genInterfaceNamePattern = v])
val f = GenerateCommon.getModelFile(gm)
if (f !== null) {
initValue(GenerateCommon.getProperty(f, PROP_CLASS_PATTERN), [v|devClassNamePattern = v])
initValue(GenerateCommon.getProperty(f, PROP_INTERFACE_PATTERN), [v|devInterfaceNamePattern = v])
}
}
def init() {
if (!isInit) {
for (gp : gm.getGenPackages())
computeNames(gp.getEcorePackage())
for (gp : gm.getUsedGenPackages())
computeNames(gp.getEcorePackage())
isInit = true
}
}
def clear() {
devNames.clear
isInit = false
}
def void computeNames(EPackage p) {
// Do not compute names for emf2002Ecore
if (!EcorePackage::eNS_URI.equals(p.nsURI)) {
for (c : p.getEClassifiers()) {
if ((c instanceof EClass) && !c.name.endsWith("Package") && !GenerateCommon.isMapType(c)) {
val devIntName = MessageFormat.format(devInterfaceNamePattern, c.name)
val genIntName = MessageFormat.format(genInterfaceNamePattern, c.name)
// println("Put : " + genIntName + "," + devIntName);
devNames.put(genIntName, devIntName)
val genClassName = MessageFormat.format(genClassNamePattern, c.name)
val devClassName = MessageFormat.format(devClassNamePattern, c.name)
// println("Put : " + genClassName + "," + devClassName);
devNames.put(genClassName, devClassName)
}
}
for (EPackage childPackage : p.getESubpackages())
computeNames(childPackage)
}
}
/**
* Replace the development name (a key in the map) as many times as necessary.
* But it must be replaced only if the key is found with not a letter before or after.
* Examples :
* <blockquote> public class MProject --> public class Project </blockquote>
* <blockquote> public class MyMProject extends MProject --> public class MyMProject extends Project </blockquote>
* <blockquote> public class MyMProject extends MProject implements YourMProject --> public class MyMProject extends Project implements YourMProject </blockquote>
*
*/
def replaceDevName(String stringToTranslate) {
var res = new StringBuffer(stringToTranslate) // Current copy recreated in the loop
for (entry : devNames.entrySet()) {
val key = entry.key
val value = entry.value
var s = 0
while (res.indexOf(key, s) != -1) {
s = res.indexOf(key, s)
val e = s + key.length
// Must change the string only if it is a real single word :
// of if it is at the beginning or at the end of the string.
val startIsOk = (s == 0) || !Character.isLetterOrDigit(res.charAt(s - 1))
val endIsOk = (e == res.length) || !Character.isLetterOrDigit(res.charAt(e))
if (startIsOk && endIsOk)
res = res.replace(s, e, value)
// Must continue so search after the end...
s = e
}
} // end for entry
return res.toString
}
/** Transform a String with default computed names with the new names */
static def replaceDevName(GenBase base, String stringToTranslate) {
// Check it base has a GenModelImpl with its own devtransform
val genModel = base.genModel
var GMATransform dt = null
if (genModel instanceof GMAGenModelImpl) {
val gm = genModel as GMAGenModelImpl
dt = gm.GMATransform
}
if (dt !== null)
dt.replaceDevName(stringToTranslate)
else
return stringToTranslate
}
}