1 package org.andromda.core.translation.library;
2
3 import java.io.BufferedReader;
4 import java.io.Reader;
5 import java.io.StringReader;
6 import java.io.StringWriter;
7 import java.lang.reflect.Method;
8 import java.util.Arrays;
9 import java.util.LinkedHashMap;
10 import java.util.Map;
11 import org.andromda.core.common.ComponentContainer;
12 import org.andromda.core.common.ExceptionUtils;
13 import org.andromda.core.common.XmlObjectFactory;
14 import org.andromda.core.templateengine.TemplateEngine;
15 import org.andromda.core.translation.Translator;
16 import org.apache.commons.lang.StringUtils;
17 import org.apache.commons.lang.builder.ToStringBuilder;
18 import org.apache.log4j.Logger;
19
20
21
22
23
24
25
26
27 public class LibraryTranslation
28 {
29 private static final Logger logger = Logger.getLogger(LibraryTranslation.class);
30
31
32
33
34 private Library library;
35
36
37
38
39 private Translation translation;
40
41
42
43
44 private String name;
45
46
47
48
49
50
51 public String getName()
52 {
53 return name;
54 }
55
56
57
58
59
60
61 public void setName(final String name)
62 {
63 this.name = name;
64 }
65
66
67
68
69 private String template;
70
71
72
73
74
75
76 public String getTemplate()
77 {
78 return template;
79 }
80
81
82
83
84
85
86 public void setTemplate(final String template)
87 {
88 this.template = template;
89 }
90
91
92
93
94
95
96 public Library getLibrary()
97 {
98 return library;
99 }
100
101
102
103
104
105
106 public void setLibrary(final Library library)
107 {
108 this.library = library;
109 }
110
111
112
113
114 private String variable;
115
116
117
118
119
120
121 public String getVariable()
122 {
123 return this.variable;
124 }
125
126
127
128
129
130
131 public void setVariable(final String variable)
132 {
133 this.variable = variable;
134 }
135
136
137
138
139 private String translatorClass;
140
141
142
143
144
145
146 public void setTranslator(final String translatorClass)
147 {
148 this.translatorClass = translatorClass;
149 final ComponentContainer container = ComponentContainer.instance();
150 container.unregisterComponent(translatorClass);
151 container.registerComponentType(translatorClass);
152 }
153
154
155
156
157
158
159 public Translator getTranslator()
160 {
161 final String methodName = "LibraryTranslation.getTranslator";
162 final Translator translator =
163 (Translator)ComponentContainer.instance().findComponent(this.translatorClass, Translator.class);
164 if (translator == null)
165 {
166 throw new LibraryException(
167 methodName + " - a translator implementation must be defined, " +
168 " please check your translator library --> '" + this.library.getResource() + '\'');
169 }
170 return translator;
171 }
172
173
174
175
176
177
178
179
180
181
182 public void handleTranslationFragment(
183 final String name,
184 final String kind,
185 final Object node)
186 {
187 ExceptionUtils.checkNull("node", node);
188 if (this.translation != null && this.getTranslator() != null)
189 {
190 final String translation = this.getTranslationFragment(name, kind);
191 final Fragment fragment = this.translation.getFragment(name);
192 if (fragment != null)
193 {
194 String handlerMethod = fragment.getHandlerMethod();
195 if (StringUtils.isNotBlank(handlerMethod))
196 {
197 Class[] argTypes = {String.class, Object.class};
198 Method method = null;
199
200 Object[] args = {translation, node};
201
202 try
203 {
204 method = this.getTranslator().getClass().getMethod(handlerMethod, argTypes);
205
206 method.invoke(
207 this.getTranslator(),
208 args);
209 }
210 catch (final NoSuchMethodException exception)
211 {
212 String errMsg =
213 "the translator '" + this.getTranslator().getClass() + "' must implement the method '" +
214 handlerMethod + '\'' + StringUtils.join(argTypes, ",") + '\'' +
215 " in order to handle processing of the fragment --> '" + name + '\'';
216 logger.error(errMsg);
217 }
218 catch (Throwable throwable)
219 {
220 if (throwable.getCause()!=null)
221 {
222 throwable = throwable.getCause();
223 }
224
225 StackTraceElement[] trace = throwable.getStackTrace();
226 String location = " AT " + trace[0].getClassName() + '.' + trace[0].getMethodName() + ':' + trace[0].getLineNumber();
227 if (throwable.getMessage()!=null)
228 {
229 location += ' ' + throwable.getMessage();
230 }
231 logger.error(this.getTranslator().getClass() + " " + throwable + " invoking " + this.getTranslator() + " METHOD " + method + " WITH " + Arrays.toString(args) + location + " fragment " + name);
232 throw new LibraryException(throwable);
233 }
234 }
235 }
236 }
237 }
238
239
240
241
242
243
244
245
246
247 public String getTranslationFragment(
248 final String name,
249 final String kind)
250 {
251 String fragment = null;
252 if (this.translation != null)
253 {
254 fragment = this.translation.getTranslated(name, kind);
255 }
256 return fragment;
257 }
258
259
260
261
262
263
264 protected void setTranslation(final Reader translationInput)
265 {
266 ExceptionUtils.checkNull("translationInput", translationInput);
267 try
268 {
269 this.translation = (Translation)XmlObjectFactory.getInstance(Translation.class).getObject(translationInput);
270 this.translation.setLibraryTranslation(this);
271 }
272 catch (final Throwable throwable)
273 {
274 throw new LibraryException(throwable);
275 }
276 }
277
278
279
280
281
282
283
284
285
286
287 public Translation processTranslation(Map<String, Object> templateContext)
288 {
289 logger.debug(
290 "processing translation template --> '" + this.getTemplate() + '\'' + "' with templateContext --> '" +
291 templateContext + '\'');
292 if (this.getTemplate() != null)
293 {
294 if (templateContext == null)
295 {
296 templateContext = new LinkedHashMap<String, Object>();
297 }
298 this.getLibrary().populateTemplateContext(templateContext);
299
300 try
301 {
302 final TemplateEngine engine = this.getLibrary().getTemplateEngine();
303
304 final StringWriter output = new StringWriter();
305 engine.processTemplate(
306 this.getTemplate(),
307 templateContext,
308 output);
309 final String outputString = output.toString();
310 final BufferedReader input = new BufferedReader(new StringReader(outputString));
311 if (logger.isDebugEnabled())
312 {
313 logger.debug("processed output --> '" + outputString + '\'');
314 }
315
316
317 this.setTranslation(input);
318 }
319 catch (final Throwable throwable)
320 {
321 throw new LibraryException(throwable);
322 }
323 }
324 return this.translation;
325 }
326
327
328
329
330 public String toString()
331 {
332 return ToStringBuilder.reflectionToString(this);
333 }
334 }