View Javadoc

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              // get the used argument and if it exists, use that for the
76              // replacement, otherwise use a new one.
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 }