1 package org.andromda.translation.ocl.testsuite;
2
3 import java.util.Iterator;
4 import java.util.Map;
5 import junit.framework.TestCase;
6 import junit.framework.TestResult;
7 import junit.framework.TestSuite;
8 import org.andromda.core.AndroMDA;
9 import org.andromda.core.configuration.Configuration;
10 import org.andromda.core.configuration.Model;
11 import org.andromda.core.configuration.Namespaces;
12 import org.andromda.core.configuration.Repository;
13 import org.andromda.core.metafacade.MetafacadeFactory;
14 import org.andromda.core.metafacade.ModelAccessFacade;
15 import org.andromda.core.repository.Repositories;
16 import org.andromda.core.repository.RepositoryFacade;
17 import org.andromda.core.translation.Expression;
18 import org.andromda.core.translation.ExpressionTranslator;
19 import org.andromda.core.translation.TranslationUtils;
20 import org.apache.commons.lang.StringUtils;
21 import org.apache.log4j.Logger;
22
23
24
25
26
27
28 public final class TranslationTestProcessor
29 extends TestCase
30 {
31 private static final Logger logger = Logger.getLogger(TranslationTestProcessor.class);
32
33
34
35
36 private static TranslationTestProcessor instance;
37
38
39
40
41
42
43 public static final TranslationTestProcessor instance()
44 {
45 if (instance == null)
46 {
47 instance = new TranslationTestProcessor();
48 }
49 return instance;
50 }
51
52 private TranslationTestProcessor()
53 {
54 super();
55 }
56
57
58
59
60
61
62 public void setUseTraceTranslator(final boolean useTraceTranslator)
63 {
64 this.useTraceTranslator = useTraceTranslator;
65 }
66
67
68
69
70
71
72 private boolean useTraceTranslator;
73
74
75
76
77 private String translationName;
78
79
80
81
82
83
84 public void setTranslationName(final String translationName)
85 {
86 this.translationName = translationName;
87 }
88
89
90
91
92 private String testSourceDirectory;
93
94
95
96
97
98
99 public void setTestSourceDirectory(final String testSourceDirectory)
100 {
101 this.testSourceDirectory = testSourceDirectory;
102 }
103
104
105
106
107 private static final TranslationTestDiscoverer testDiscoverer = TranslationTestDiscoverer.instance();
108
109
110
111
112 private String testTranslation = null;
113
114
115
116
117 private TranslationTestProcessor(String testName)
118 {
119 super(testName);
120 }
121
122
123
124
125 private TestResult testResult;
126
127
128
129
130
131
132 public void setResult(final TestResult testResult)
133 {
134 this.testResult = testResult;
135 }
136
137
138
139
140
141
142 public void runSuite()
143 {
144 if (this.testResult == null)
145 {
146 throw new TranslationTestProcessorException(
147 "You must set the test result before attempting to run the suite");
148 }
149 final AndroMDA andromda = AndroMDA.newInstance();
150 MetafacadeFactory factory = MetafacadeFactory.getInstance();
151 andromda.initialize(this.configuration);
152 factory.setNamespace(Namespaces.DEFAULT);
153 if (this.model == null)
154 {
155 final Repositories repositoriesContainer = Repositories.instance();
156 final Repository[] repositories = this.configuration.getRepositories();
157 if (repositories != null && repositories.length > 0)
158 {
159 final int numberOfRepositories = repositories.length;
160 for (int ctr = 0; ctr < numberOfRepositories; ctr++)
161 {
162 final Repository repository = repositories[ctr];
163 final Model[] models = repository.getModels();
164 if (models != null)
165 {
166
167
168
169 final Model model = models[0];
170 repositoriesContainer.loadModel(model);
171 final RepositoryFacade repositoryImplementation =
172 repositoriesContainer.getImplementation(repository.getName());
173 this.model = repositoryImplementation.getModel();
174
175
176 factory.setModel(this.model, model.getType());
177 }
178 }
179 }
180 }
181 this.getSuite().run(this.testResult);
182 andromda.shutdown();
183 }
184
185
186
187
188
189
190 private TestSuite getSuite()
191 {
192 testDiscoverer.discoverTests(this.testSourceDirectory);
193 final Map tests = testDiscoverer.getTests();
194 final TestSuite suite = new TestSuite();
195 for (final Iterator iterator = tests.keySet().iterator(); iterator.hasNext();)
196 {
197 final TranslationTestProcessor unitTest = new TranslationTestProcessor("testTranslation");
198
199
200 unitTest.setConfiguration(this.configuration);
201 unitTest.setTestTranslation((String) iterator.next());
202 unitTest.model = this.model;
203 suite.addTest(unitTest);
204 }
205 return suite;
206 }
207
208 private Configuration configuration;
209
210
211
212
213
214
215 public void setConfiguration(final Configuration configuration)
216 {
217 this.configuration = configuration;
218 }
219
220
221
222
223
224
225
226 private void setTestTranslation(String testTranslation)
227 {
228 this.testTranslation = testTranslation;
229 }
230
231
232
233
234 private ModelAccessFacade model;
235
236
237
238
239
240
241
242
243
244 protected Object findModelElement(
245 String translation,
246 String expression)
247 {
248 final String methodName = "TranslationTestProcessor.findClassifier";
249 Object element = null;
250 if (StringUtils.isNotBlank(expression))
251 {
252 if (this.model == null)
253 {
254 throw new RuntimeException(methodName + " could not retrieve model from repository");
255 }
256
257 ContextElementFinder finder = new ContextElementFinder(model);
258 finder.translate(
259 translation,
260 expression,
261 null);
262 element = finder.getContextElement();
263
264 if (element == null)
265 {
266 final String message =
267 "No element found in model in expression --> '" + expression +
268 "' for translation ' " + translation + "', please check your model or your TranslationTest file";
269 logger.error("ERROR! " + message);
270 TestCase.fail(message);
271 }
272 }
273 return element;
274 }
275
276
277
278
279 public void testTranslation()
280 {
281 String translation = this.testTranslation;
282
283 if (this.shouldTest(translation))
284 {
285 if (logger.isInfoEnabled())
286 {
287 logger.info("testing translation --> '" + translation + '\'');
288 }
289
290 TranslationTest test = testDiscoverer.getTest(translation);
291
292 Map<String, ExpressionTest> expressions = test.getExpressionConfigs();
293
294 if (expressions != null)
295 {
296 for (String fromExpression : expressions.keySet())
297 {
298
299
300 if (StringUtils.isEmpty(fromExpression))
301 {
302 if (logger.isInfoEnabled())
303 {
304 logger.info(
305 "No body for the 'from' element was defined " + "within translation test --> '" +
306 test.getUri() + "', please define the body of this element with " +
307 "the expression you want to translate from");
308 }
309 continue;
310 }
311
312 Expression translated;
313 if (useTraceTranslator)
314 {
315 translated = TraceTranslator.getInstance().translate(
316 translation,
317 fromExpression,
318 null);
319 }
320 else
321 {
322 final ExpressionTest expressionConfig = expressions.get(fromExpression);
323 String toExpression = expressionConfig.getTo();
324
325 Object modelElement = null;
326
327
328
329 final Repository[] repositories = this.configuration.getRepositories();
330 if (repositories != null && repositories.length > 0)
331 {
332 modelElement = this.findModelElement(
333 translation,
334 fromExpression);
335 }
336 else
337 {
338 logger.info("No repositories defined in configuration, not finding for model elements");
339 }
340
341 translated =
342 ExpressionTranslator.instance().translate(
343 translation,
344 fromExpression,
345 modelElement);
346
347 if (translated != null)
348 {
349
350
351 toExpression = TranslationUtils.removeExtraWhitespace(toExpression);
352 if (logger.isInfoEnabled())
353 {
354 logger.info("translated: --> '" + translated.getTranslatedExpression() + '\'');
355 logger.info("expected: --> '" + toExpression + '\'');
356 }
357 TestCase.assertEquals(
358 toExpression,
359 translated.getTranslatedExpression());
360 }
361 }
362 }
363 }
364 } else
365 {
366 if (logger.isInfoEnabled())
367 {
368 logger.info("skipping translation --> '" + translation + '\'');
369 }
370 }
371 }
372
373
374
375
376
377
378
379
380
381 private boolean shouldTest(String translation)
382 {
383 translation = StringUtils.trimToEmpty(translation);
384 return StringUtils.isEmpty(this.translationName) ||
385 (StringUtils.isNotBlank(this.translationName) && this.translationName.equals(translation));
386 }
387
388
389
390
391 public void shutdown()
392 {
393 testDiscoverer.shutdown();
394 TranslationTestProcessor.instance = null;
395 }
396 }