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