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.jdbc2;
023:
024: import java.util.Collection;
025: import java.util.List;
026: import java.util.Set;
027: import javax.ejb.FinderException;
028: import org.jboss.ejb.GenericEntityObjectFactory;
029: import org.jboss.ejb.plugins.cmp.jdbc.EJBQLToSQL92Compiler;
030: import org.jboss.ejb.plugins.cmp.jdbc.QLCompiler;
031: import org.jboss.ejb.plugins.cmp.jdbc.QueryParameter;
032: import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCDynamicQLQueryMetaData;
033: import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCCMPFieldBridge2;
034: import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCEntityBridge2;
035: import org.jboss.ejb.plugins.cmp.jdbc2.schema.Schema;
036: import org.jboss.logging.Logger;
037:
038: /**
039: * @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
040: * @version <tt>$Revision: 63030 $</tt>
041: */
042: public class DynamicQueryCommand implements QueryCommand {
043: private Logger log;
044: private JDBCEntityBridge2 entity;
045: private JDBCDynamicQLQueryMetaData metadata;
046: private AbstractQueryCommand.CollectionFactory collectionFactory;
047:
048: public DynamicQueryCommand(JDBCEntityBridge2 entity,
049: JDBCDynamicQLQueryMetaData metadata) {
050: log = Logger.getLogger(getClass().getName() + "."
051: + entity.getEntityName() + "#"
052: + metadata.getMethod().getName());
053: this .entity = entity;
054: this .metadata = metadata;
055:
056: Class returnType = metadata.getMethod().getReturnType();
057: if (Collection.class.isAssignableFrom(returnType)) {
058: if (Set.class.isAssignableFrom(returnType)) {
059: collectionFactory = AbstractQueryCommand.SET_FACTORY;
060: } else {
061: collectionFactory = AbstractQueryCommand.COLLECTION_FACTORY;
062: }
063: }
064: }
065:
066: public JDBCStoreManager2 getStoreManager() {
067: return (JDBCStoreManager2) entity.getManager();
068: }
069:
070: public Collection fetchCollection(Schema schema,
071: GenericEntityObjectFactory factory, Object[] args)
072: throws FinderException {
073: if (log.isTraceEnabled()) {
074: log.trace("executing dynamic-ql: " + args[0]);
075: }
076:
077: JDBCStoreManager2 manager = (JDBCStoreManager2) entity
078: .getManager();
079: QLCompiler compiler = new EJBQLToSQL92Compiler(manager
080: .getCatalog());
081: try {
082: compiler.compileJBossQL((String) args[0], metadata
083: .getMethod().getReturnType(), getParamTypes(args),
084: metadata);
085: } catch (Throwable t) {
086: log.error("Error compiling JBossQL statement '" + args[0]
087: + "'", t);
088: throw new FinderException(
089: "Error compiling JBossQL statement '" + args[0]
090: + "'");
091: }
092:
093: String sql = compiler.getSQL();
094:
095: int offsetParam = compiler.getOffsetParam();
096: int offsetValue = compiler.getOffsetValue();
097: int limitParam = compiler.getLimitParam();
098: int limitValue = compiler.getLimitValue();
099:
100: AbstractQueryCommand.ResultReader resultReader;
101: if (!compiler.isSelectEntity()) {
102: if (compiler.isSelectField()) {
103: resultReader = new AbstractQueryCommand.FieldReader(
104: (JDBCCMPFieldBridge2) compiler.getSelectField());
105: } else {
106: resultReader = new AbstractQueryCommand.FunctionReader(
107: compiler.getSelectFunction());
108: }
109: } else {
110: resultReader = new AbstractQueryCommand.EntityReader(
111: (JDBCEntityBridge2) compiler.getSelectEntity(),
112: compiler.isSelectDistinct());
113: }
114:
115: return AbstractQueryCommand.fetchCollection(entity, sql,
116: toArray(compiler.getInputParameters()),
117: AbstractQueryCommand.toInt(args, offsetParam,
118: offsetValue), AbstractQueryCommand.toInt(args,
119: limitParam, limitValue),
120: new AbstractQueryCommand.EagerCollectionStrategy(
121: collectionFactory, resultReader, log), schema,
122: factory, (Object[]) args[1], log);
123: }
124:
125: public Object fetchOne(Schema schema,
126: GenericEntityObjectFactory factory, Object[] args)
127: throws FinderException {
128: if (log.isTraceEnabled()) {
129: log.trace("executing dynamic-ql: " + args[0]);
130: }
131:
132: JDBCStoreManager2 manager = (JDBCStoreManager2) entity
133: .getManager();
134: QLCompiler compiler = new EJBQLToSQL92Compiler(manager
135: .getCatalog());
136: try {
137: compiler.compileJBossQL((String) args[0], metadata
138: .getMethod().getReturnType(), getParamTypes(args),
139: metadata);
140: } catch (Throwable t) {
141: log.error("Error compiling JBossQL statement '" + args[0]
142: + "'", t);
143: throw new FinderException(
144: "Error compiling JBossQL statement '" + args[0]
145: + "'");
146: }
147:
148: String sql = compiler.getSQL();
149:
150: AbstractQueryCommand.ResultReader resultReader;
151: if (!compiler.isSelectEntity()) {
152: if (compiler.isSelectField()) {
153: resultReader = new AbstractQueryCommand.FieldReader(
154: (JDBCCMPFieldBridge2) compiler.getSelectField());
155: } else {
156: resultReader = new AbstractQueryCommand.FunctionReader(
157: compiler.getSelectFunction());
158: }
159: } else {
160: resultReader = new AbstractQueryCommand.EntityReader(
161: (JDBCEntityBridge2) compiler.getSelectEntity(),
162: compiler.isSelectDistinct());
163: }
164:
165: return AbstractQueryCommand.fetchOne(entity, sql,
166: toArray(compiler.getInputParameters()), resultReader,
167: (Object[]) args[1], factory, log);
168: }
169:
170: private static Class[] getParamTypes(Object[] args)
171: throws FinderException {
172: Class[] parameterTypes;
173: // get the parameters
174: Object[] parameters = (Object[]) args[1];
175: if (parameters == null) {
176: parameterTypes = new Class[0];
177: } else {
178: // get the parameter types
179: parameterTypes = new Class[parameters.length];
180: for (int i = 0; i < parameters.length; i++) {
181: if (parameters[i] == null) {
182: throw new FinderException("Parameter[" + i
183: + "] is null");
184: }
185: parameterTypes[i] = parameters[i].getClass();
186: }
187: }
188: return parameterTypes;
189: }
190:
191: static QueryParameter[] toArray(List p) {
192: QueryParameter[] params = null;
193: if (p.size() > 0) {
194: params = (QueryParameter[]) p.toArray(new QueryParameter[p
195: .size()]);
196: }
197: return params;
198: }
199: }
|