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.bridge;
023:
024: import java.lang.reflect.Method;
025: import java.util.Collection;
026: import java.util.HashSet;
027: import java.util.Set;
028: import javax.ejb.EJBException;
029: import javax.ejb.FinderException;
030: import javax.ejb.ObjectNotFoundException;
031: import javax.transaction.Transaction;
032: import javax.transaction.TransactionManager;
033:
034: import org.jboss.ejb.plugins.cmp.bridge.SelectorBridge;
035: import org.jboss.ejb.plugins.cmp.jdbc.JDBCQueryCommand;
036: import org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager;
037: import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCQueryMetaData;
038: import org.jboss.ejb.EntityEnterpriseContext;
039: import org.jboss.ejb.EntityContainer;
040: import org.jboss.ejb.GenericEntityObjectFactory;
041:
042: /**
043: * JDBCSelectorBridge represents one ejbSelect method.
044: * <p/>
045: * Life-cycle:
046: * Tied to the EntityBridge.
047: * <p/>
048: * Multiplicity:
049: * One for each entity bean ejbSelect method.
050: *
051: * @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
052: * @version $Revision: 57209 $
053: */
054: public class JDBCSelectorBridge implements SelectorBridge {
055: private final JDBCQueryMetaData queryMetaData;
056: private final JDBCStoreManager manager;
057: private TransactionManager tm;
058: private boolean syncBeforeSelect;
059:
060: public JDBCSelectorBridge(JDBCStoreManager manager,
061: JDBCQueryMetaData queryMetaData) {
062: this .queryMetaData = queryMetaData;
063: this .manager = manager;
064:
065: EntityContainer container = manager.getContainer();
066: tm = container.getTransactionManager();
067: syncBeforeSelect = !container.getBeanMetaData()
068: .getContainerConfiguration().getSyncOnCommitOnly();
069: }
070:
071: // BridgeInvoker implementation
072:
073: public Object invoke(EntityEnterpriseContext ctx, Method method,
074: Object[] args) throws Exception {
075: Transaction tx = (ctx != null ? ctx.getTransaction() : tm
076: .getTransaction());
077:
078: if (syncBeforeSelect) {
079: EntityContainer.synchronizeEntitiesWithinTransaction(tx);
080: }
081:
082: return execute(args);
083: }
084:
085: // SelectorBridge implementation
086:
087: public String getSelectorName() {
088: return queryMetaData.getMethod().getName();
089: }
090:
091: public Method getMethod() {
092: return queryMetaData.getMethod();
093: }
094:
095: private Class getReturnType() {
096: return queryMetaData.getMethod().getReturnType();
097: }
098:
099: public Object execute(Object[] args) throws FinderException {
100: Collection retVal;
101: Method method = getMethod();
102: try {
103: JDBCQueryCommand query = manager.getQueryManager()
104: .getQueryCommand(method);
105: GenericEntityObjectFactory factory = (queryMetaData
106: .isResultTypeMappingLocal() ? (GenericEntityObjectFactory) query
107: .getSelectManager().getContainer()
108: .getLocalProxyFactory()
109: : query.getSelectManager().getContainer()
110: .getProxyFactory());
111: retVal = query.execute(method, args, null, factory);
112: } catch (FinderException e) {
113: throw e;
114: } catch (EJBException e) {
115: throw e;
116: } catch (Exception e) {
117: throw new EJBException("Error in " + getSelectorName(), e);
118: }
119:
120: if (!Collection.class.isAssignableFrom(getReturnType())) {
121: // single object
122: if (retVal.size() == 0) {
123: throw new ObjectNotFoundException();
124: }
125: if (retVal.size() > 1) {
126: throw new FinderException(getSelectorName()
127: + " returned " + retVal.size() + " objects");
128: }
129:
130: Object o = retVal.iterator().next();
131: if (o == null && method.getReturnType().isPrimitive()) {
132: throw new FinderException(
133: "Cannot return null as a value of primitive type "
134: + method.getReturnType().getName());
135: }
136:
137: return o;
138: } else {
139: // collection or set
140: if (Set.class.isAssignableFrom(getReturnType())) {
141: return new HashSet(retVal);
142: } else {
143: return retVal;
144: }
145: }
146: }
147: }
|