1 package org.andromda.scriptwrappers;
2
3 import groovy.lang.GroovyClassLoader;
4 import groovy.lang.GroovyObject;
5 import java.io.BufferedReader;
6 import java.io.File;
7 import java.io.FileNotFoundException;
8 import java.io.FileReader;
9 import java.io.IOException;
10 import java.io.Reader;
11 import java.lang.reflect.Method;
12 import java.util.Arrays;
13 import java.util.Iterator;
14 import java.util.LinkedHashSet;
15 import java.util.Set;
16
17
18
19
20
21
22
23
24 public class GroovyScriptWrapper
25 {
26 private String scriptPath;
27 private Object stub;
28
29
30
31
32
33
34
35
36 public GroovyScriptWrapper(
37 Object stub,
38 String scriptPath)
39 throws InstantiationError
40 {
41 this.stub = stub;
42 this.scriptPath = scriptPath;
43 }
44
45
46
47
48
49
50
51
52 public Object invoke(
53 String methodName,
54 Object[] args)
55 {
56 try
57 {
58 final GroovyClassLoader grooveyClassLoader = new GroovyClassLoader(this.getClassLoader());
59 final Class groovyClass =
60 grooveyClassLoader.parseClass(
61 this.getContents(new File(this.scriptPath)),
62 scriptPath);
63 final GroovyObject groovyObject = (GroovyObject)groovyClass.newInstance();
64
65 this.copyProperties(
66 this.stub,
67 groovyObject);
68 Object rtn = groovyObject.invokeMethod(
69 methodName,
70 args);
71 grooveyClassLoader.close();
72 return rtn;
73 }
74 catch (final Throwable throwable)
75 {
76 throw new RuntimeException(throwable);
77 }
78 }
79
80
81
82
83
84
85 private ClassLoader getClassLoader()
86 {
87 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
88 if (classLoader == null)
89 {
90 classLoader = this.getClass().getClassLoader();
91 }
92 return classLoader;
93 }
94
95
96
97
98 private static final char LINE_SEPARATOR = '\n';
99
100
101
102
103
104
105
106
107 @SuppressWarnings("static-method")
108 private String getContents(final File file)
109 throws FileNotFoundException
110 {
111 Reader resource = new FileReader(file);
112 final StringBuilder contents = new StringBuilder();
113 try
114 {
115 BufferedReader resourceInput = new BufferedReader(resource);
116 for (String line = resourceInput.readLine(); line != null; line = resourceInput.readLine())
117 {
118 contents.append(line).append(LINE_SEPARATOR);
119 }
120 resourceInput.close();
121 resourceInput = null;
122 }
123 catch (final Throwable throwable)
124 {
125 throw new RuntimeException(throwable);
126 }
127 finally
128 {
129 try
130 {
131 resource.close();
132 }
133 catch (IOException ex)
134 {
135
136 }
137 }
138
139
140 return contents.toString().trim().replaceAll(
141 "\\s+throws\\s+.+\\s+",
142 " ");
143 }
144
145
146
147
148
149
150
151
152
153 @SuppressWarnings("static-method")
154 private void copyProperties(
155 final Object from,
156 final GroovyObject to)
157 throws Exception
158 {
159 final Set methods = new LinkedHashSet();
160 loadSuperMethods(
161 from.getClass(),
162 methods);
163 for (final Iterator iterator = methods.iterator(); iterator.hasNext();)
164 {
165 final Method method = (Method)iterator.next();
166
167 final String methodName = method.getName();
168 final String getPrefix = "get";
169 if (methodName.startsWith(getPrefix) && method.getParameterTypes().length == 0)
170 {
171 String propertyName = methodName.replaceAll(
172 getPrefix,
173 "");
174
175 Method setterMethod = null;
176 try
177 {
178 setterMethod =
179 from.getClass().getMethod(
180 "set" + propertyName,
181 new Class[] {method.getReturnType()});
182 }
183 catch (final Exception exception)
184 {
185
186 }
187 if (setterMethod != null)
188 {
189 method.setAccessible(true);
190 final Object value = method.invoke(
191 from);
192 to.invokeMethod(
193 setterMethod.getName(),
194 new Object[] {value});
195 }
196 }
197 }
198 }
199
200
201
202
203
204
205
206
207 private static Set loadSuperMethods(
208 final Class clazz,
209 final Set methods)
210 {
211 if (clazz.getSuperclass() != null)
212 {
213 methods.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredMethods()));
214 methods.addAll(loadSuperMethods(
215 clazz.getSuperclass(),
216 methods));
217 }
218 return methods;
219 }
220 }