001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb.plugins.cmp.jdbc;
023:
024: import org.jboss.deployment.DeploymentException;
025:
026: import org.jboss.ejb.plugins.cmp.ejbql.Catalog;
027: import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge;
028: import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMPFieldBridge;
029: import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCQueryMetaData;
030: import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCDeclaredQueryMetaData;
031: import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCReadAheadMetaData;
032:
033: /**
034: * This class generates a query based on the delcared-sql xml specification.
035: *
036: * @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
037: * @author <a href="mailto:rickard.oberg@telkel.com">Rickard Öberg</a>
038: * @author <a href="mailto:marc.fleury@telkel.com">Marc Fleury</a>
039: * @author <a href="mailto:shevlandj@kpi.com.au">Joe Shevland</a>
040: * @author <a href="mailto:justin@j-m-f.demon.co.uk">Justin Forder</a>
041: * @author <a href="mailto:michel.anke@wolmail.nl">Michel de Groot</a>
042: * @author <a href="danch@nvisia.com">danch (Dan Christopherson</a>
043: * @author <a href="alex@jboss.org">Alex Loubyansky</a>
044: * @version $Revision: 57209 $
045: */
046: public final class JDBCDeclaredSQLQuery extends
047: JDBCAbstractQueryCommand {
048: private final JDBCDeclaredQueryMetaData metadata;
049:
050: /**
051: * Creted a defined finder command based on the information
052: * in a declared-sql declaration.
053: */
054: public JDBCDeclaredSQLQuery(JDBCStoreManager manager,
055: JDBCQueryMetaData q) throws DeploymentException {
056: super (manager, q);
057:
058: metadata = (JDBCDeclaredQueryMetaData) q;
059:
060: // set the select object (either selectEntity or selectField)
061: initSelectObject(manager);
062:
063: // set the preload fields
064: JDBCReadAheadMetaData readAhead = metadata.getReadAhead();
065: JDBCEntityBridge selectEntity = getSelectEntity();
066: if (selectEntity != null && readAhead.isOnFind()) {
067: setEagerLoadGroup(readAhead.getEagerLoadGroup());
068: }
069:
070: // set the sql and parameters
071: String sql = buildSQL();
072: setSQL(parseParameters(sql));
073: }
074:
075: /**
076: * Initializes the entity or field to be selected.
077: * @throws DeploymentException if the specified object is invalid or
078: * non-existant
079: */
080: private void initSelectObject(JDBCStoreManager manager)
081: throws DeploymentException {
082: String entityName = metadata.getEJBName();
083:
084: // if no name is specified we are done
085: if (entityName == null) {
086: return;
087: }
088:
089: Catalog catalog = manager.getCatalog();
090:
091: JDBCEntityBridge entity = (JDBCEntityBridge) catalog
092: .getEntityByEJBName(entityName);
093: if (entity == null) {
094: throw new DeploymentException("Unknown entity: "
095: + entityName);
096: }
097:
098: String fieldName = metadata.getFieldName();
099: if (fieldName == null) {
100: setSelectEntity(entity);
101: } else {
102: JDBCCMPFieldBridge field = entity
103: .getCMPFieldByName(fieldName);
104: if (field == null) {
105: throw new DeploymentException("Unknown cmp field: "
106: + fieldName);
107: }
108: setSelectField(field);
109: }
110: }
111:
112: /**
113: * Builds the sql statement based on the delcared-sql metadata specification.
114: * @return the sql statement for this query
115: */
116: private String buildSQL() {
117: StringBuffer sql = new StringBuffer(300);
118:
119: sql.append(SQLUtil.SELECT);
120: if (metadata.isSelectDistinct()) {
121: sql.append(SQLUtil.DISTINCT);
122: }
123:
124: String alias = metadata.getAlias();
125: String from = metadata.getFrom();
126: String table;
127: String selectList;
128: if (getSelectField() == null) {
129: // we are selecting a full entity
130: table = getSelectEntity().getQualifiedTableName();
131:
132: // get a list of all fields to be loaded
133: // put pk fields in front
134: String tableAlias = getTableAlias(alias, from,
135: getSelectEntity().getTableName());
136: selectList = SQLUtil.getColumnNamesClause(
137: getSelectEntity().getPrimaryKeyFields(),
138: tableAlias, new StringBuffer(35)).toString();
139:
140: if (getEagerLoadGroup() != null) {
141: selectList += SQLUtil.appendColumnNamesClause(
142: getSelectEntity(), getEagerLoadGroup(),
143: tableAlias, new StringBuffer(35));
144: }
145: } else {
146: // we are just selecting one field
147: JDBCCMPFieldBridge selectField = getSelectField();
148: JDBCStoreManager manager = (JDBCStoreManager) getSelectField()
149: .getManager();
150: table = manager.getEntityBridge().getQualifiedTableName();
151: selectList = SQLUtil.getColumnNamesClause(
152: selectField,
153: getTableAlias(alias, from, manager
154: .getEntityBridge().getTableName()),
155: new StringBuffer()).toString();
156: }
157: sql.append(selectList);
158: String additionalColumns = metadata.getAdditionalColumns();
159: if (additionalColumns != null) {
160: sql.append(additionalColumns);
161: }
162: sql.append(SQLUtil.FROM).append(table);
163: if (alias != null) {
164: sql.append(' ').append(alias);
165: }
166: if (from != null) {
167: sql.append(' ').append(from);
168: }
169:
170: String where = metadata.getWhere();
171: if (where != null && where.trim().length() > 0) {
172: sql.append(SQLUtil.WHERE).append(where);
173: }
174:
175: String order = metadata.getOrder();
176: if (order != null && order.trim().length() > 0) {
177: sql.append(SQLUtil.ORDERBY).append(order);
178: }
179:
180: String other = metadata.getOther();
181: if (other != null && other.trim().length() > 0) {
182: sql.append(' ').append(other);
183: }
184: return sql.toString();
185: }
186:
187: private static String getTableAlias(String alias, String from,
188: String table) {
189: String tableAlias;
190: if (alias != null) {
191: tableAlias = alias;
192: } else if (from != null) {
193: tableAlias = table;
194: } else {
195: tableAlias = SQLUtil.EMPTY_STRING;
196: }
197: return tableAlias;
198: }
199: }
|