1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.codehaus.gmavenplus.util;
18
19 import org.apache.maven.plugin.logging.Log;
20 import org.codehaus.gmavenplus.model.internal.Version;
21
22 import java.io.File;
23 import java.lang.reflect.InvocationTargetException;
24 import java.net.MalformedURLException;
25 import java.net.URL;
26 import java.net.URLClassLoader;
27 import java.security.CodeSource;
28 import java.util.ArrayList;
29 import java.util.List;
30
31 import static org.codehaus.gmavenplus.util.ReflectionUtils.findMethod;
32 import static org.codehaus.gmavenplus.util.ReflectionUtils.invokeStaticMethod;
33
34
35
36
37
38
39
40
41 public class ClassWrangler {
42
43
44
45
46 private String groovyVersion = null;
47
48
49
50
51 private Boolean isIndy = null;
52
53
54
55
56 private final ClassLoader classLoader;
57
58
59
60
61 private final Log log;
62
63
64
65
66
67
68
69
70
71 public ClassWrangler(final List<?> classpath, final ClassLoader parentClassLoader, final Log pluginLog) throws MalformedURLException {
72 log = pluginLog;
73 classLoader = createNewClassLoader(classpath, parentClassLoader);
74 Thread.currentThread().setContextClassLoader(classLoader);
75 }
76
77
78
79
80
81
82 public String getGroovyVersionString() {
83 if (groovyVersion == null) {
84
85 try {
86 Class<?> groovySystemClass = getClass("groovy.lang.GroovySystem");
87 String ver = (String) invokeStaticMethod(findMethod(groovySystemClass, "getVersion"));
88 if (ver != null && !ver.isEmpty()) {
89 groovyVersion = ver;
90 }
91 } catch (ClassNotFoundException | IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
92
93 }
94
95
96 if (groovyVersion == null) {
97 log.info("Unable to get Groovy version from GroovySystem, trying InvokerHelper.");
98 try {
99 Class<?> invokerHelperClass = getClass("org.codehaus.groovy.runtime.InvokerHelper");
100 String ver = (String) invokeStaticMethod(findMethod(invokerHelperClass, "getVersion"));
101 if (ver != null && !ver.isEmpty()) {
102 groovyVersion = ver;
103 }
104 } catch (ClassNotFoundException | IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
105
106 }
107 }
108
109
110
111
112
113
114
115
116 if (groovyVersion == null) {
117 log.warn("Unable to get Groovy version from InvokerHelper or GroovySystem, trying jar name.");
118 String jar = getGroovyJar();
119 int idx = Integer.MAX_VALUE;
120 for (int i = 0; i < 9; i++) {
121 int newIdx = jar.indexOf("-" + i);
122 if (newIdx >= 0 && newIdx < idx) {
123 idx = newIdx;
124 }
125 }
126 if (idx < Integer.MAX_VALUE) {
127 groovyVersion = jar.substring(idx + 1, jar.length() - 4).replace("-indy", "").replace("-grooid", "");
128 }
129 }
130 }
131
132 return groovyVersion;
133 }
134
135
136
137
138
139
140 public Version getGroovyVersion() {
141 try {
142 return Version.parseFromString(getGroovyVersionString());
143 } catch (Exception e) {
144 throw new RuntimeException("Unable to determine Groovy version. Is Groovy declared as a dependency?");
145 }
146 }
147
148
149
150
151
152
153
154
155 public static boolean groovyAtLeast(Version detectedVersion, Version compareToVersion) {
156 return detectedVersion.compareTo(compareToVersion) >= 0;
157 }
158
159
160
161
162
163
164
165
166 public static boolean groovyIs(Version detectedVersion, Version compareToVersion) {
167 return detectedVersion.compareTo(compareToVersion) == 0;
168 }
169
170
171
172
173
174
175
176
177 public static boolean groovyNewerThan(Version detectedVersion, Version compareToVersion) {
178 return detectedVersion.compareTo(compareToVersion) > 0;
179 }
180
181
182
183
184
185
186
187
188 public static boolean groovyOlderThan(Version detectedVersion, Version compareToVersion) {
189 return detectedVersion.compareTo(compareToVersion) < 0;
190 }
191
192
193
194
195
196
197
198 public boolean isGroovyIndy() {
199 if (isIndy == null) {
200 try {
201 getClass("org.codehaus.groovy.vmplugin.v8.IndyInterface");
202 isIndy = true;
203 } catch (ClassNotFoundException e1) {
204 try {
205 getClass("org.codehaus.groovy.vmplugin.v7.IndyInterface");
206 isIndy = true;
207 } catch (ClassNotFoundException e2) {
208 isIndy = false;
209 }
210 }
211 }
212
213 return isIndy;
214 }
215
216
217
218
219
220
221 public void logGroovyVersion(final String goal) {
222 log.info("Using Groovy " + getGroovyVersionString() + " to perform " + goal + ".");
223 }
224
225
226
227
228
229
230
231
232 public Class<?> getClass(final String className) throws ClassNotFoundException {
233 return Class.forName(className, true, classLoader);
234 }
235
236
237
238
239
240
241 public ClassLoader getClassLoader() {
242 return classLoader;
243 }
244
245
246
247
248
249
250
251
252
253 protected ClassLoader createNewClassLoader(final List<?> classpath, final ClassLoader classLoader) throws MalformedURLException {
254 List<URL> urlsList = new ArrayList<>();
255 for (Object classPathObject : classpath) {
256 String path = (String) classPathObject;
257 urlsList.add(new File(path).toURI().toURL());
258 }
259 URL[] urlsArray = urlsList.toArray(new URL[0]);
260 return new URLClassLoader(urlsArray, classLoader);
261 }
262
263
264
265
266
267
268 protected String getGroovyJar() {
269 try {
270 String groovyObjectClassPath = getJarPath();
271 String groovyJar = null;
272 if (groovyObjectClassPath != null) {
273 groovyJar = groovyObjectClassPath.replaceAll("!.+", "");
274 groovyJar = groovyJar.substring(groovyJar.lastIndexOf("/") + 1);
275 }
276
277 return groovyJar;
278 } catch (ClassNotFoundException e) {
279 throw new RuntimeException("Unable to determine Groovy version. Is Groovy declared as a dependency?");
280 }
281 }
282
283
284
285
286
287
288
289 protected String getJarPath() throws ClassNotFoundException {
290 Class<?> groovyObjectClass = getClass("groovy.lang.GroovyObject");
291 String groovyObjectClassPath = String.valueOf(groovyObjectClass.getResource("/" + groovyObjectClass.getName().replace('.', '/') + ".class"));
292 if (groovyObjectClassPath == null) {
293 CodeSource codeSource = groovyObjectClass.getProtectionDomain().getCodeSource();
294 if (codeSource != null) {
295 groovyObjectClassPath = String.valueOf(codeSource.getLocation());
296 }
297 }
298 return groovyObjectClassPath;
299 }
300 }