KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > access > trans > ProcedureTranslator


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20 package org.apache.cayenne.access.trans;
21
22 import java.sql.CallableStatement JavaDoc;
23 import java.sql.PreparedStatement JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import org.apache.cayenne.access.QueryLogger;
30 import org.apache.cayenne.access.QueryTranslator;
31 import org.apache.cayenne.map.Procedure;
32 import org.apache.cayenne.map.ProcedureParameter;
33 import org.apache.cayenne.query.ProcedureQuery;
34
35 /**
36  * Stored procedure query translator.
37  *
38  * @author Andrus Adamchik
39  */

40 public class ProcedureTranslator extends QueryTranslator {
41
42     /**
43      * Helper class to make OUT and VOID parameters logger-friendly.
44      */

45     static class NotInParam {
46
47         protected String JavaDoc type;
48
49         public NotInParam(String JavaDoc type) {
50             this.type = type;
51         }
52
53         public String JavaDoc toString() {
54             return type;
55         }
56     }
57
58     private static NotInParam OUT_PARAM = new NotInParam("[OUT]");
59
60     protected List JavaDoc callParams;
61     protected List JavaDoc values;
62
63     /**
64      * Creates an SQL String for the stored procedure call.
65      */

66     protected String JavaDoc createSqlString() {
67         Procedure procedure = getProcedure();
68
69         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
70
71         int totalParams = callParams.size();
72
73         // check if procedure returns values
74
if (procedure.isReturningValue()) {
75             totalParams--;
76             buf.append("{? = call ");
77         }
78         else {
79             buf.append("{call ");
80         }
81
82         buf.append(procedure.getFullyQualifiedName());
83
84         if (totalParams > 0) {
85             // unroll the loop
86
buf.append("(?");
87
88             for (int i = 1; i < totalParams; i++) {
89                 buf.append(", ?");
90             }
91
92             buf.append(")");
93         }
94
95         buf.append("}");
96         return buf.toString();
97     }
98
99     public PreparedStatement JavaDoc createStatement() throws Exception JavaDoc {
100         long t1 = System.currentTimeMillis();
101
102         this.callParams = getProcedure().getCallParameters();
103         this.values = new ArrayList JavaDoc(callParams.size());
104
105         initValues();
106         String JavaDoc sqlStr = createSqlString();
107
108         if (QueryLogger.isLoggable()) {
109             // need to convert OUT/VOID parameters to loggable strings
110
long time = System.currentTimeMillis() - t1;
111
112             List JavaDoc loggableParameters = new ArrayList JavaDoc(values.size());
113             Iterator JavaDoc it = values.iterator();
114             while (it.hasNext()) {
115                 Object JavaDoc val = it.next();
116                 if (val instanceof NotInParam) {
117                     val = val.toString();
118                 }
119                 loggableParameters.add(val);
120             }
121
122             QueryLogger.logQuery(sqlStr, loggableParameters, time);
123         }
124         CallableStatement JavaDoc stmt = connection.prepareCall(sqlStr);
125         initStatement(stmt);
126         return stmt;
127     }
128
129     public Procedure getProcedure() {
130         return getEntityResolver().lookupProcedure(query);
131     }
132
133     public ProcedureQuery getProcedureQuery() {
134         return (ProcedureQuery) query;
135     }
136
137     /**
138      * Set IN and OUT parameters.
139      */

140     protected void initStatement(CallableStatement JavaDoc stmt) throws Exception JavaDoc {
141         if (values != null && values.size() > 0) {
142             List JavaDoc params = getProcedure().getCallParameters();
143
144             int len = values.size();
145             for (int i = 0; i < len; i++) {
146                 ProcedureParameter param = (ProcedureParameter) params.get(i);
147
148                 // !Stored procedure parameter can be both in and out
149
// at the same time
150
if (param.isOutParam()) {
151                     setOutParam(stmt, param, i + 1);
152                 }
153
154                 if (param.isInParameter()) {
155                     setInParam(stmt, param, values.get(i), i + 1);
156                 }
157             }
158         }
159     }
160
161     protected void initValues() {
162         Map JavaDoc queryValues = getProcedureQuery().getParameters();
163
164         // match values with parameters in the correct order.
165
// make an assumption that a missing value is NULL
166
// Any reason why this is bad?
167

168         Iterator JavaDoc it = callParams.iterator();
169         while (it.hasNext()) {
170             ProcedureParameter param = (ProcedureParameter) it.next();
171
172             if (param.getDirection() == ProcedureParameter.OUT_PARAMETER) {
173                 values.add(OUT_PARAM);
174             }
175             else {
176                 values.add(queryValues.get(param.getName()));
177             }
178         }
179     }
180
181     /**
182      * Sets a single IN parameter of the CallableStatement.
183      */

184     protected void setInParam(
185             CallableStatement JavaDoc stmt,
186             ProcedureParameter param,
187             Object JavaDoc val,
188             int pos) throws Exception JavaDoc {
189
190         int type = param.getType();
191         adapter.bindParameter(stmt, val, pos, type, param.getPrecision());
192     }
193
194     /**
195      * Sets a single OUT parameter of the CallableStatement.
196      */

197     protected void setOutParam(CallableStatement JavaDoc stmt, ProcedureParameter param, int pos)
198             throws Exception JavaDoc {
199
200         int precision = param.getPrecision();
201         if (precision >= 0) {
202             stmt.registerOutParameter(pos, param.getType(), precision);
203         }
204         else {
205             stmt.registerOutParameter(pos, param.getType());
206         }
207     }
208 }
209
Popular Tags