1 package org.andromda.translation.ocl.query;
2
3 import org.andromda.core.translation.TranslationUtils;
4 import org.apache.commons.lang.StringUtils;
5
6 import java.util.HashMap;
7 import java.util.Map;
8
9 /***
10 * Performs translation to the following: <ul> <li>EJB-QL</li> </ul>
11 *
12 * @author Chad Brandon
13 */
14 public class EjbQLTranslator
15 extends QueryTranslator
16 {
17 /***
18 * Used to replace the 'counter' reference in the EJB-QL template
19 */
20 private static final String ARG_COUNTER = "counter";
21
22 /***
23 * Keeps track of an incrementing argument number.
24 */
25 private short argCounter;
26
27 /***
28 * Holds the arguments which have previously been used during translation. The key is the argument name BEFORE
29 * translation, and the value is the argument name AFTER translation.
30 */
31 private Map usedArguments = new HashMap();
32
33 /***
34 * Called by super class to reset any objects.
35 */
36 public void preProcess()
37 {
38 super.preProcess();
39 this.usedArguments.clear();
40 this.resetArgCounter();
41 }
42
43 /***
44 * Resets the argCounter variable to its beginning value.
45 */
46 private void resetArgCounter()
47 {
48 this.argCounter = 1;
49 }
50
51 /***
52 * Returns a String representing an incrementing number. It increments and returns the next value each time this
53 * method is called.
54 *
55 * @return String the counter represented by a String.
56 */
57 protected String getCounter()
58 {
59 return String.valueOf(argCounter++);
60 }
61
62 /***
63 * Checks to see if the replacement is an argument and if so replaces the {index} in the fragment with the
64 * 'argument' fragment from the template. Otherwise replaces the {index} with the passed in replacement value.
65 *
66 * @param fragment
67 * @param replacement
68 * @param index
69 * @return String the fragment with any replacements.
70 */
71 protected String replaceFragment(String fragment, String replacement, int index)
72 {
73 if (this.isOperationArgument(replacement))
74 {
75
76
77 String usedArgument = (String)this.usedArguments.get(replacement);
78 if (StringUtils.isEmpty(usedArgument))
79 {
80 String argument = this.getTranslationFragment("argument");
81 argument = this.replaceCounterPattern(argument);
82 this.usedArguments.put(replacement, argument);
83 replacement = argument;
84 }
85 else
86 {
87 replacement = usedArgument;
88 }
89 }
90 return super.replaceFragment(fragment, replacement, index);
91 }
92
93 /***
94 * Handles the replacemenht of the references to 'counter' with the incrementing counter (currently just used for
95 * EJB-QL translation) --> may want to find a cleaner way to do this.
96 */
97 protected String replaceCounterPattern(String fragment)
98 {
99 if (TranslationUtils.containsPattern(fragment, EjbQLTranslator.ARG_COUNTER))
100 {
101 fragment = TranslationUtils.replacePattern(fragment, EjbQLTranslator.ARG_COUNTER, this.getCounter());
102 }
103 return fragment;
104 }
105 }