KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > cmp > jdbc2 > DeclaredSQLQueryCommand


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb.plugins.cmp.jdbc2;
23
24 import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCEntityBridge2;
25 import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCCMPFieldBridge2;
26 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCDeclaredQueryMetaData;
27 import org.jboss.ejb.plugins.cmp.jdbc.SQLUtil;
28 import org.jboss.ejb.plugins.cmp.jdbc.QueryParameter;
29 import org.jboss.ejb.plugins.cmp.ejbql.Catalog;
30 import org.jboss.deployment.DeploymentException;
31 import org.jboss.logging.Logger;
32
33 import java.util.ArrayList JavaDoc;
34 import java.util.StringTokenizer JavaDoc;
35
36 /**
37  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
38  * @version <tt>$Revision: 58475 $</tt>
39  */

40 public class DeclaredSQLQueryCommand
41    extends AbstractQueryCommand
42 {
43    private JDBCCMPFieldBridge2 selectedField;
44
45    public DeclaredSQLQueryCommand(JDBCEntityBridge2 entity, JDBCDeclaredQueryMetaData metadata)
46       throws DeploymentException
47    {
48       initResultReader(entity, metadata);
49
50       this.sql = buildSQL(metadata);
51       this.sql = parseParameters(this.sql, metadata);
52
53       setResultType(metadata.getMethod().getReturnType());
54
55       log =
56          Logger.getLogger(getClass().getName() + "." + entity.getEntityName() + "#" + metadata.getMethod().getName());
57       log.debug("sql: " + sql);
58    }
59
60    private void initResultReader(JDBCEntityBridge2 entity, JDBCDeclaredQueryMetaData metadata)
61       throws DeploymentException
62    {
63       String JavaDoc entityName = metadata.getEJBName();
64       if(entityName != null)
65       {
66          Catalog catalog = entity.getManager().getCatalog();
67          JDBCEntityBridge2 otherEntity = (JDBCEntityBridge2) catalog.getEntityByEJBName(entityName);
68          if(otherEntity == null)
69          {
70             throw new DeploymentException("Unknown entity: " + entityName);
71          }
72          this.entity = otherEntity;
73       }
74       else
75       {
76          this.entity = entity;
77       }
78
79       String JavaDoc fieldName = metadata.getFieldName();
80       if(fieldName == null)
81       {
82          setEntityReader(this.entity, metadata.isSelectDistinct());
83       }
84       else
85       {
86          selectedField = (JDBCCMPFieldBridge2) entity.getFieldByName(fieldName);
87          if(selectedField == null)
88          {
89             throw new DeploymentException("Unknown cmp field: " + fieldName);
90          }
91
92          setFieldReader(selectedField);
93       }
94    }
95
96    private String JavaDoc buildSQL(JDBCDeclaredQueryMetaData metadata)
97    {
98       StringBuffer JavaDoc sql = new StringBuffer JavaDoc(300);
99
100       sql.append(SQLUtil.SELECT);
101       if(metadata.isSelectDistinct())
102       {
103          sql.append(SQLUtil.DISTINCT);
104       }
105
106       String JavaDoc alias = metadata.getAlias();
107       String JavaDoc from = metadata.getFrom();
108       String JavaDoc table;
109       String JavaDoc selectList;
110       if(metadata.getFieldName() == null)
111       {
112          // we are selecting a full entity
113
table = this.entity.getQualifiedTableName();
114
115          // get a list of all fields to be loaded
116
// put pk fields in front
117
String JavaDoc tableAlias = getTableAlias(alias, from, this.entity.getTableName());
118          selectList = SQLUtil.getColumnNamesClause(this.entity.getPrimaryKeyFields(),
119             tableAlias,
120             new StringBuffer JavaDoc(35)).toString();
121       }
122       else
123       {
124          // we are just selecting one field
125
JDBCStoreManager2 manager = (JDBCStoreManager2) selectedField.getManager();
126          table = manager.getEntityBridge().getQualifiedTableName();
127          selectList = SQLUtil.getColumnNamesClause(selectedField,
128             getTableAlias(alias, from, manager.getEntityBridge().getTableName()),
129             new StringBuffer JavaDoc()).toString();
130       }
131       sql.append(selectList);
132       String JavaDoc additionalColumns = metadata.getAdditionalColumns();
133       if(additionalColumns != null)
134       {
135          sql.append(additionalColumns);
136       }
137       sql.append(SQLUtil.FROM).append(table);
138       if(alias != null)
139       {
140          sql.append(' ').append(alias);
141       }
142       if(from != null)
143       {
144          sql.append(' ').append(from);
145       }
146
147       String JavaDoc where = metadata.getWhere();
148       if(where != null && where.trim().length() > 0)
149       {
150          sql.append(SQLUtil.WHERE).append(where);
151       }
152
153       String JavaDoc order = metadata.getOrder();
154       if(order != null && order.trim().length() > 0)
155       {
156          sql.append(SQLUtil.ORDERBY).append(order);
157       }
158
159       String JavaDoc other = metadata.getOther();
160       if(other != null && other.trim().length() > 0)
161       {
162          sql.append(' ').append(other);
163       }
164       return sql.toString();
165    }
166
167    private static String JavaDoc getTableAlias(String JavaDoc alias, String JavaDoc from, String JavaDoc table)
168    {
169       String JavaDoc tableAlias;
170       if(alias != null)
171       {
172          tableAlias = alias;
173       }
174       else if(from != null)
175       {
176          tableAlias = table;
177       }
178       else
179       {
180          tableAlias = SQLUtil.EMPTY_STRING;
181       }
182       return tableAlias;
183    }
184
185    /**
186     * Replaces the parameters in the specific sql with question marks, and
187     * initializes the parameter setting code. Parameters are encoded in curly
188     * brackets use a zero based index.
189     *
190     * @param sql the sql statement that is parsed for parameters
191     * @return the original sql statement with the parameters replaced with a
192     * question mark
193     * @throws DeploymentException if a error occures while parsing the sql
194     */

195    protected String JavaDoc parseParameters(String JavaDoc sql, JDBCDeclaredQueryMetaData metadata) throws DeploymentException
196    {
197       StringBuffer JavaDoc sqlBuf = new StringBuffer JavaDoc();
198       ArrayList JavaDoc params = new ArrayList JavaDoc();
199
200       // Replace placeholders {0} with ?
201
if(sql != null)
202       {
203          sql = sql.trim();
204
205          StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(sql, "{}", true);
206          while(tokens.hasMoreTokens())
207          {
208             String JavaDoc token = tokens.nextToken();
209             if(token.equals("{"))
210             {
211                token = tokens.nextToken();
212                if(Character.isDigit(token.charAt(0)))
213                {
214                   QueryParameter parameter = new QueryParameter(entity.getManager(), metadata.getMethod(), token);
215
216                   // of if we are here we can assume that we have
217
// a parameter and not a function
218
sqlBuf.append("?");
219                   params.add(parameter);
220
221                   if(!tokens.nextToken().equals("}"))
222                   {
223                      throw new DeploymentException("Invalid parameter - missing closing '}' : " + sql);
224                   }
225                }
226                else
227                {
228                   // ok we don't have a parameter, we have a function
229
// push the tokens on the buffer and continue
230
sqlBuf.append("{").append(token);
231                }
232             }
233             else
234             {
235                // not parameter... just append it
236
sqlBuf.append(token);
237             }
238          }
239       }
240
241       setParameters(params);
242
243       return sqlBuf.toString();
244    }
245 }
246
Popular Tags