1    package com.instantbank.component.job.util;
2    
3    import java.util.ArrayList;
4    import java.util.Hashtable;
5    import java.util.Enumeration;
6    import java.util.StringTokenizer;
7    import java.io.Serializable;
8    
9    import com.instantbank.component.job.util.Alias;
10   import com.instantbank.component.job.util.Field;
11   import com.instantbank.component.job.util.ParticipantTable;
12   import com.instantbank.component.job.util.JoinElement;
13   
14   import com.instantbank.common.utilcomponents.LetterTemplateGlobals;
15   import com.instantbank.common.utilcomponents.Debug;
16   
17   /**
18    *  Auxiliary Class that supports SQL sentence generation
19    *
20    * @author InstantBank (Consuelo Franky)
21    * @created October 2002
22    */
23   public class AuxGenerateSQLtext
24       implements Serializable {
25   
26     /**
27      * fixed rootType for systemAlias and systemFields attributes
28      */
29     private String rootType;
30   
31     /**
32      * memory representation of system alias
33      *key: tableAlias (String), value: Alias element
34      */
35     private Hashtable systemAlias;
36   
37     /**
38      * memory representation of system fields for current company
39      *key: fieldIdLong (Long), value: Field element
40      */
41     private Hashtable systemFields;
42   
43     // for debug:
44     private Debug debug = null;
45   
46   
47     /**
48      *  Constructor for the AuxGenerateSQLtext object
49      *
50      * @param systemFields values of system fields for current company
51      * @param systemAlias values of system alias
52      * @param rootType fixed rootType for systemAlias and systemFields
53      */
54     public AuxGenerateSQLtext(Hashtable systemFields, Hashtable systemAlias,
55                               String rootType) {
56       debug = new Debug();
57       debug.setDebugginOn(false);
58       debug.setPreMessage("** AuxGenerateSQLtext");
59   
60       this.systemFields = systemFields;
61       this.systemAlias = systemAlias;
62       this.rootType = rootType;
63     }
64   
65   
66     /**
67      *  Builds beginning of SELECT part according to rootType
68      *
69      * @return beginning string of SELECT
70      */
71     public String beginSELECT() {
72       String answer = null;
73       if(rootType.equals(LetterTemplateGlobals.ROOT_AGREEMENTS)) {
74         answer = " AGREEMENTS.AGRM_CODE AS AGRCODE ";
75       }
76       return answer;
77     }
78   
79   
80     /**
81      *  Finds tableAlias corresponding to a fieldId
82      *
83      * @param fieldId unique code of field
84      * @return name of table alias
85      */
86     public String alias(long fieldId) {
87       Field element = (Field)systemFields.get(new Long(fieldId));
88       return element.getTableAlias();
89     }
90   
91   
92     /**
93      *  Finds fieldColumn corresponding to a fieldId
94      *
95      * @param fieldId unique code of field
96      * @return column name corresponding to field
97      */
98     public String fieldColumn(long fieldId) {
99       Field element = (Field)systemFields.get(new Long(fieldId));
100      return element.getFieldColumn();
101    }
102  
103  
104    /**
105     *  Builds output name of a field in the SELECT
106     *
107     * @param fieldId unique code of field
108     * @return output name of the field
109     */
110    public String rename(long fieldId) {
111      String answer = "";
112  
113      String tableAlias = alias(fieldId);
114      Alias element = (Alias)systemAlias.get(tableAlias + "|" + rootType);
115  
116      String fieldCategory = element.getFieldCategory();
117      if(fieldCategory.equals(LetterTemplateGlobals.TEMPORAL_FIELDS)
118        || fieldCategory.equals(LetterTemplateGlobals.DERIVED_FIELDS)) {
119        answer = " AS " + tableAlias + "_" + fieldColumn(fieldId);
120      }
121      return answer;
122    }
123  
124  
125    /**
126     *  Finds tableAlias of root table according to rootType
127     *
128     * @return name of table alias corresponding to root table
129     */
130    public String rootParticipant() {
131      String answer = null;
132      if(rootType.equals(LetterTemplateGlobals.ROOT_AGREEMENTS)) {
133        answer = "AGREEMENTS";
134      }
135      return answer;
136    }
137  
138  
139    /**
140     *  Finds index of alias in the list of participant tables
141     *  of the job SQL sentence
142     *
143     * @param participantTables list of participant tables in the
144     *                           job SQL sentence;
145     *                           elements of type ParticipantTable
146     * @param alias table alias to search
147     * @return < 0 if not found
148     *                           index >=0 if found
149     */
150    public int findAlias(ArrayList participantTables, String alias) {
151      int sizeParticipants = participantTables.size();
152      boolean found = false;
153      ParticipantTable element;
154      int answer = -1;
155  
156      for(int i = 0; (i < sizeParticipants && !found); i++) {
157        element = (ParticipantTable)(participantTables.get(i));
158        String aliasParticipant = element.getAlias();
159        if(aliasParticipant.equals(alias)) {
160          found = true;
161          answer = i;
162        }
163      }
164      return answer;
165    }
166  
167  
168    /**
169     *  Builds a JoinElement corresponding to an alias
170     *
171     * @param alias name of table alias
172     * @return instance of type JoinElement
173     */
174    public JoinElement buildJoinElement(String alias) {
175      Alias element = (Alias)systemAlias.get(alias + "|" + rootType);
176  
177      String parentAlias = element.getParentTableAlias();
178      debug.println("parentAlias=" + parentAlias);
179      String parentColumn = element.getParentJoinColumn();
180      String sonAlias = alias;
181      String sonColumn = element.getSonJoinColumn();
182      String joinType = "";
183      if(element.getJoinType().equals(LetterTemplateGlobals.OUTER_JOIN)) {
184        joinType = "(+)";
185      }
186      return new JoinElement
187        (parentAlias, parentColumn, sonAlias, sonColumn, joinType);
188    }
189  
190  
191    /**
192     *  Finds index of parent of an alias in the join list of the job SQL sentence
193     *
194     * @param joinList join list of the job SQL sentence;
195     *                  elements of type JoinElement
196     * @param alias name of table alias
197     * @return < 0 if not found
198     *                  index >=0 if found
199     */
200    public int findParent(ArrayList joinList, String alias) {
201      boolean found = false;
202      JoinElement element;
203      int answer = -1;
204  
205      int sizeJoinList = joinList.size();
206      String parentAlias = parentTableAlias(alias);
207      for(int i = 0; (i < sizeJoinList && !found); i++) {
208        element = (JoinElement)(joinList.get(i));
209        String sonAliasJoin = element.getSonAlias();
210        if(sonAliasJoin.equals(parentAlias)) {
211          found = true;
212          answer = i;
213        }
214      }
215      return answer;
216    }
217  
218  
219    /**
220     *  Finds ParentTableAlias corresponding to an alias
221     *
222     * @param alias name of table alias
223     * @return alias of parent table for join
224     */
225    public String parentTableAlias(String alias) {
226      Alias element = (Alias)systemAlias.get(alias + "|" + rootType);
227      return (element.getParentTableAlias());
228    }
229  
230  
231    /**
232     *  Tranforms a value of DatabaseNames.LETT_JOB_WHERE
233     *  in a SQL value
234     *
235     * @param value value of a job where condition
236     * @param ruleOperator ruleOperator of the job where condition
237     * @param fieldId fieldId corresponding to value
238     * @return the corresponding SQL value
239     */
240    public String value(String value, String ruleOperator, long fieldId) {
241      ArrayList tokens = new ArrayList();
242      String token;
243      String answer = null;
244  
245      Field element = (Field)systemFields.get(new Long(fieldId));
246      String dataType = element.getDataType();
247      boolean valueHasSpecialDateVariables =
248        (value.indexOf(LetterTemplateGlobals.SYSDATE) >= 0)
249        || (value.indexOf(LetterTemplateGlobals.COMPANY_DATE) >= 0);
250  
251      if(!ruleOperator.equals("BETWEEN") && !ruleOperator.equals("IN")) {
252        // case of a single value
253        if(dataType.equals(LetterTemplateGlobals.FIELD_NUMERIC)) {
254          answer = value.trim();
255        }
256        else if(dataType.equals(LetterTemplateGlobals.FIELD_DATE)
257          && !valueHasSpecialDateVariables) {
258          answer = "TO_DATE('" + value.trim() + "','MM-DD-YYYY')";
259        }
260        else if(dataType.equals(LetterTemplateGlobals.FIELD_DATE)
261          && valueHasSpecialDateVariables) {
262          answer = value.trim();
263        }
264        else {  // dataType.equals(LetterTemplateGlobals.FIELD_STRING)
265          answer = "'" + value.trim() + "'";
266        }
267      }
268      else {  // operator is BETWEEN or IN:
269        StringTokenizer valueTokens = new StringTokenizer(value, ",");
270        while(valueTokens.hasMoreTokens()) {
271          token = valueTokens.nextToken();
272          boolean tokenHasSpecialDateVariables =
273            (token.indexOf(LetterTemplateGlobals.SYSDATE) >= 0)
274            || (token.indexOf(LetterTemplateGlobals.COMPANY_DATE) >= 0);
275          if(dataType.equals(LetterTemplateGlobals.FIELD_NUMERIC)) {
276            token = token.trim();
277          }
278          else if(dataType.equals(LetterTemplateGlobals.FIELD_DATE)
279            && !tokenHasSpecialDateVariables) {
280            token = "TO_DATE('" + token.trim() + "','MM-DD-YYYY')";
281          }
282          else if(dataType.equals(LetterTemplateGlobals.FIELD_DATE)
283            && tokenHasSpecialDateVariables) {
284            token = token.trim();
285          }
286          else {  // dataType.equals(LetterTemplateGlobals.FIELD_STRING)
287            token = "'" + token.trim() + "'";
288          }
289          tokens.add(token);
290        }
291  
292        if(ruleOperator.equals("BETWEEN")) {
293          answer = (String)tokens.get(0) + " AND " + (String)tokens.get(1);
294        }
295        else {  // ruleOperator.equals("IN")
296          answer = "(";
297          int sizeTokens = tokens.size();
298          for(int i = 0; i < sizeTokens; i++) {
299            token = (String)(tokens.get(i));
300            answer += token;
301            answer += (i != sizeTokens - 1) ? "," : "";
302          }
303          answer += ")";
304        }
305      }
306      return answer;
307    }
308  
309  
310    /**
311     *  Builds ending condition of WHERE part according to rootType
312     *
313     * @param companyId current company
314     * @return ending condition of WHERE (without "AND" )
315     */
316    public String endWHERE(String companyId) {
317      String answer = null;
318      if(rootType.equals(LetterTemplateGlobals.ROOT_AGREEMENTS)) {
319        answer = " (AGREEMENTS.AGRM_CMP_ID = " + companyId + ")";
320      }
321      return answer;
322    }
323  
324  
325    /**
326     *  Finds fieldCategory corresponding to an alias
327     *
328     * @param alias name of table alias
329     * @return category of fields corresponding to the alias
330     */
331    public String category(String alias) {
332      Alias element = (Alias)systemAlias.get(alias + "|" + rootType);
333      return (element.getFieldCategory());
334    }
335  
336  
337    /**
338     *  Finds realTable corresponding to an alias
339     *
340     * @param alias name of table alias
341     * @return name of real table corrsponding to the alias
342     */
343    public String realTable(String alias) {
344      Alias element = (Alias)systemAlias.get(alias + "|" + rootType);
345      return (element.getRealTable());
346    }
347  
348  
349    /**
350     *  Finds builtTable corresponding to an alias
351     *
352     * @param alias name of table alias of
353     *               fieldCategory == LetterTemplateGlobals.TEMPORAL_FIELDS
354     * @return SQL string for building the associated temporal table
355     */
356    public String builtTable(String alias) {
357      Alias element = (Alias)systemAlias.get(alias + "|" + rootType);
358      return (element.getBuiltTable());
359    }
360  
361  
362    /**
363     *  Tranforms a direction of DatabaseNames.LETT_JOB_ORDER
364     *  in a SQL direction
365     *
366     * @param direction direction of a job order element:
367     *                   "ascending" or "descending"
368     * @return the corresponding SQL direction: "" or "DESC"
369     */
370    public String direction(String direction) {
371      if(direction.equals(LetterTemplateGlobals.DESCENDING_DIRECTION)) {
372        return "DESC";
373      }
374      else {
375        return "";
376      }
377    }
378  }
379