1 package org.andromda.translation.ocl.query;
2
3 import java.util.Iterator;
4 import java.util.List;
5 import org.andromda.core.translation.TranslationUtils;
6 import org.andromda.translation.ocl.BaseTranslator;
7 import org.andromda.translation.ocl.node.AFeatureCall;
8 import org.andromda.translation.ocl.node.ALogicalExpressionTail;
9 import org.andromda.translation.ocl.node.AParenthesesPrimaryExpression;
10 import org.andromda.translation.ocl.node.APropertyCallExpression;
11 import org.andromda.translation.ocl.node.ARelationalExpressionTail;
12 import org.andromda.translation.ocl.node.AStandardDeclarator;
13 import org.andromda.translation.ocl.node.PRelationalExpression;
14 import org.andromda.translation.ocl.syntax.ConcreteSyntaxUtils;
15 import org.apache.commons.lang.StringUtils;
16
17
18
19
20
21
22 public class QueryTranslator
23 extends BaseTranslator
24 {
25
26
27
28 private StringBuffer selectClause;
29
30
31
32
33 public void preProcess()
34 {
35 super.preProcess();
36 this.selectClause = new StringBuffer();
37 this.sortedByClause = new StringBuffer();
38 this.declaratorCtr = 0;
39 }
40
41
42
43
44 private short declaratorCtr;
45
46
47
48
49
50
51
52 protected boolean isInitialDeclarator()
53 {
54 boolean isInitialDeclarator = (this.declaratorCtr <= 0);
55 this.declaratorCtr++;
56 return isInitialDeclarator;
57 }
58
59
60
61
62
63
64 public void inAStandardDeclarator(AStandardDeclarator declarator)
65 {
66 final String methodName = "QueryTranslator.inAStandardDeclarator";
67 if (logger.isDebugEnabled())
68 logger.debug("performing " + methodName + " with declarator --> " + declarator);
69
70 String temp = this.selectClause.toString();
71
72 String declaratorName = ConcreteSyntaxUtils.getVariableDeclarations(declarator)[0].getName();
73
74
75 short replacement = 1;
76 if (this.isInitialDeclarator())
77 {
78
79
80 replacement = 0;
81 }
82
83
84 temp = TranslationUtils.replacePattern(temp, String.valueOf(replacement), declaratorName);
85 this.selectClause = new StringBuffer(temp);
86 }
87
88
89
90
91
92
93 public void inAPropertyCallExpression(APropertyCallExpression expression)
94 {
95 this.handleTranslationFragment(expression);
96 }
97
98
99
100
101
102
103 public void inAFeatureCall(AFeatureCall expression)
104 {
105
106
107 if (!TranslationUtils.trimToEmpty(expression).matches(OCLPatterns.ALL_INSTANCES))
108 {
109 this.handleTranslationFragment(expression);
110 }
111 }
112
113
114
115
116
117
118 public void inALogicalExpressionTail(ALogicalExpressionTail logicalExpressionTail)
119 {
120 this.handleTranslationFragment(logicalExpressionTail);
121 }
122
123
124
125
126
127
128 public void inARelationalExpressionTail(ARelationalExpressionTail relationalExpressionTail)
129 {
130 this.handleTranslationFragment(relationalExpressionTail);
131 }
132
133
134
135
136
137
138 public void inAParenthesesPrimaryExpression(AParenthesesPrimaryExpression expression)
139 {
140 this.getExpression().appendSpaceToTranslatedExpression();
141 this.getExpression().appendToTranslatedExpression("(");
142 }
143
144
145
146
147
148
149 public void outAParenthesesPrimaryExpression(AParenthesesPrimaryExpression expression)
150 {
151 this.getExpression().appendSpaceToTranslatedExpression();
152 this.getExpression().appendToTranslatedExpression(")");
153 }
154
155
156
157
158
159
160
161
162
163
164 protected String replaceFragment(String fragment, String replacement, int index)
165 {
166 fragment = StringUtils.trimToEmpty(fragment);
167 replacement = StringUtils.trimToEmpty(replacement);
168
169
170 if (this.isOperationArgument(replacement))
171 {
172 final String argument = replacement;
173 replacement = this.getTranslationFragment("argument");
174 replacement = TranslationUtils.replacePattern(replacement, String.valueOf(0), argument);
175 }
176 fragment = TranslationUtils.replacePattern(fragment, String.valueOf(index), replacement);
177 return fragment;
178 }
179
180
181
182
183 private static final String SELECT_CLAUSE_TAIL = "selectClauseTail";
184
185
186
187
188 private static final String SORTED_BY_CLAUSE_HEAD = "sortedByClauseHead";
189
190
191
192
193 @Override
194 public void postProcess()
195 {
196
197 String selectClauseTail = this.getTranslationFragment(SELECT_CLAUSE_TAIL);
198 String existingExpression = StringUtils.trimToEmpty(this.getExpression().getTranslatedExpression());
199
200 if (StringUtils.isNotBlank(selectClauseTail) && StringUtils.isNotBlank(existingExpression))
201 {
202 this.selectClause.append(' ');
203 this.selectClause.append(selectClauseTail);
204 this.selectClause.append(' ');
205 }
206
207 this.getExpression().insertInTranslatedExpression(0, selectClause.toString());
208
209 if (this.sortedByClause.length() > 0)
210 {
211 this.getExpression().appendSpaceToTranslatedExpression();
212 this.getExpression().appendToTranslatedExpression(this.getTranslationFragment(SORTED_BY_CLAUSE_HEAD));
213 this.getExpression().appendSpaceToTranslatedExpression();
214 this.getExpression().appendToTranslatedExpression(this.sortedByClause);
215 }
216
217
218 this.getExpression().replaceInTranslatedExpression("\\(\\s*", "(");
219 this.getExpression().replaceInTranslatedExpression("\\s*\\)", ")");
220 }
221
222
223
224
225
226
227
228
229
230 public void handleSubSelect(String translation, Object node)
231 {
232 APropertyCallExpression propertyCallExpression = (APropertyCallExpression) node;
233
234 String primaryExpression = ConcreteSyntaxUtils.getPrimaryExpression(propertyCallExpression);
235
236
237
238 translation = this.replaceFragment(translation, TranslationUtils.trimToEmpty(primaryExpression), 0);
239
240 this.selectClause.append(' ');
241 this.selectClause.append(translation);
242 }
243
244
245
246
247
248 public void handleIsLike(String translation, Object node)
249 {
250 APropertyCallExpression propertyCallExpression = (APropertyCallExpression) node;
251 List featureCalls = ConcreteSyntaxUtils.getFeatureCalls(propertyCallExpression);
252
253 List params = ConcreteSyntaxUtils.getParameters((AFeatureCall) featureCalls.get(0));
254
255 translation = this.replaceFragment(translation, TranslationUtils.deleteWhitespace(params.get(0)), 0);
256 translation = this.replaceFragment(translation, TranslationUtils.deleteWhitespace(params.get(1)), 1);
257
258 if (StringUtils.isNotBlank(this.getExpression().getTranslatedExpression()))
259 {
260 this.getExpression().appendSpaceToTranslatedExpression();
261 }
262 this.getExpression().appendToTranslatedExpression(translation);
263 }
264
265
266
267
268
269 public void handleSelect(String translation, Object node)
270 {
271 this.selectClause.append(translation);
272 }
273
274
275
276
277
278 public void handleIncludes(String translation, Object node)
279 {
280 APropertyCallExpression propertyCallExpression = (APropertyCallExpression) node;
281 List featureCalls = ConcreteSyntaxUtils.getFeatureCalls(propertyCallExpression);
282
283
284
285 String parameters = StringUtils.deleteWhitespace(ConcreteSyntaxUtils.getParametersAsString(
286 (AFeatureCall) featureCalls.get(0)));
287
288 String primaryExpression = ConcreteSyntaxUtils.getPrimaryExpression(propertyCallExpression);
289
290 translation = this.replaceFragment(translation, primaryExpression, 1);
291 translation = this.replaceFragment(translation, parameters, 0);
292
293 this.getExpression().appendSpaceToTranslatedExpression();
294 this.getExpression().appendToTranslatedExpression(translation);
295 }
296
297
298
299
300
301 public void handleDotOperation(String translation, Object node)
302 {
303 APropertyCallExpression propertyCallExpression = (APropertyCallExpression) node;
304 String firstArgument = ConcreteSyntaxUtils.getPrimaryExpression(propertyCallExpression);
305 translation = this.replaceFragment(translation, firstArgument, 0);
306 List featureCalls = ConcreteSyntaxUtils.getFeatureCalls(propertyCallExpression);
307 if (featureCalls != null && !featureCalls.isEmpty())
308 {
309
310
311
312 for (final Iterator callIterator = featureCalls.iterator(); callIterator.hasNext();)
313 {
314 AFeatureCall featureCall = (AFeatureCall) callIterator.next();
315
316 if (TranslationUtils.trimToEmpty(featureCall).matches(OCLPatterns.OPERATION_FEATURE_CALL))
317 {
318 List parameters = ConcreteSyntaxUtils.getParameters(featureCall);
319 if (parameters != null && !parameters.isEmpty())
320 {
321 Iterator parameterIterator = parameters.iterator();
322 for (int ctr = 1; parameterIterator.hasNext(); ctr++)
323 {
324 translation = this.replaceFragment(translation, (String) parameterIterator.next(), ctr);
325 }
326 }
327 break;
328 }
329 }
330 }
331 this.getExpression().appendSpaceToTranslatedExpression();
332 this.getExpression().appendToTranslatedExpression(translation);
333 }
334
335 private StringBuffer sortedByClause;
336
337
338
339
340
341 public void handleSortedBy(String translation, Object node)
342 {
343 if (this.sortedByClause.length() > 0)
344 {
345 this.sortedByClause.append(", ");
346 }
347 this.sortedByClause.append(TranslationUtils.deleteWhitespace(ConcreteSyntaxUtils.getParametersAsString(
348 (AFeatureCall) node)));
349 }
350
351
352
353
354
355
356
357 public void handleLogicalExpression(String translation, Object node)
358 {
359 this.getExpression().appendSpaceToTranslatedExpression();
360 this.getExpression().appendToTranslatedExpression(translation);
361 }
362
363
364
365
366
367
368
369 public void handleRelationalExpression(String translation, Object node)
370 {
371 ARelationalExpressionTail relationalExpressionTail = (ARelationalExpressionTail) node;
372
373 String[] leftAndRightExpressions = ConcreteSyntaxUtils.getLeftAndRightExpressions(
374 (PRelationalExpression) relationalExpressionTail.parent());
375 String leftExpression = StringUtils.deleteWhitespace(leftAndRightExpressions[0]);
376 String rightExpression = StringUtils.deleteWhitespace(leftAndRightExpressions[1]);
377 if (leftExpression.matches(OCLPatterns.OPERATION_FEATURE_CALL))
378 {
379 leftExpression = "";
380 }
381 translation = this.replaceFragment(translation, leftExpression, 0);
382 if (rightExpression.matches(OCLPatterns.OPERATION_FEATURE_CALL))
383 {
384 rightExpression = "";
385 }
386 translation = this.replaceFragment(translation, rightExpression, 1);
387
388 this.getExpression().appendSpaceToTranslatedExpression();
389 this.getExpression().appendToTranslatedExpression(translation);
390 }
391 }