001: /*--
002:
003: Copyright (C) 2002-2005 Adrian Price.
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009:
010: 1. Redistributions of source code must retain the above copyright
011: notice, this list of conditions, and the following disclaimer.
012:
013: 2. Redistributions in binary form must reproduce the above copyright
014: notice, this list of conditions, and the disclaimer that follows
015: these conditions in the documentation and/or other materials
016: provided with the distribution.
017:
018: 3. The names "OBE" and "Open Business Engine" must not be used to
019: endorse or promote products derived from this software without prior
020: written permission. For written permission, please contact
021: adrianprice@sourceforge.net.
022:
023: 4. Products derived from this software may not be called "OBE" or
024: "Open Business Engine", nor may "OBE" or "Open Business Engine"
025: appear in their name, without prior written permission from
026: Adrian Price (adrianprice@users.sourceforge.net).
027:
028: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
029: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
030: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
031: DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
032: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
033: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
034: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
035: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
036: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
037: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
038: POSSIBILITY OF SUCH DAMAGE.
039:
040: For more information on OBE, please see
041: <http://obe.sourceforge.net/>.
042:
043: */
044:
045: package org.obe.server.j2ee.ejb;
046:
047: import org.apache.commons.logging.Log;
048: import org.obe.OBERuntimeException;
049: import org.obe.client.api.model.OBEFilter;
050: import org.obe.client.api.repository.RepositoryException;
051: import org.obe.server.util.QueryBuilder;
052: import org.obe.xpdl.model.workflow.WorkflowProcess;
053: import org.wfmc.wapi.WMFilter;
054:
055: import javax.ejb.CreateException;
056: import java.beans.PropertyDescriptor;
057: import java.sql.*;
058: import java.util.ArrayList;
059: import java.util.List;
060:
061: /**
062: * Provides SQL access to persistent data.
063: *
064: * @author Adrian Price
065: */
066: public abstract class AbstractDAO {
067: private String _dbProductName;
068:
069: protected abstract Log getLogger();
070:
071: protected AbstractDAO() {
072: }
073:
074: protected long getNewId(Sequence sequence)
075: throws RepositoryException {
076: try {
077: synchronized (sequence) {
078: if (!sequence.hasNext())
079: EJBHelper.getSequenceHome().reallocate(sequence);
080: return sequence.getNext();
081: }
082: } catch (CreateException e) {
083: throw new RepositoryException(e);
084: }
085: }
086:
087: public final boolean isOracle() {
088: try {
089: return getDatabaseProductName().startsWith("Oracle");
090: } catch (SQLException e) {
091: throw new OBERuntimeException(e);
092: }
093: }
094:
095: protected int count(String table, WMFilter filter)
096: throws SQLException, RepositoryException {
097:
098: return count(table, filter == null ? null
099: : new WMFilter[] { filter });
100: }
101:
102: protected int count(String table, WMFilter[] filters)
103: throws SQLException, RepositoryException {
104:
105: Connection con = null;
106: PreparedStatement stmt = null;
107: ResultSet rs = null;
108: try {
109: con = EJBHelper.getConnection();
110: String sql = "SELECT COUNT(*) FROM " + table;
111: stmt = prepareStatement(con, sql, filters, -1, null, null,
112: null);
113: rs = stmt.executeQuery();
114: rs.next();
115: return rs.getInt(1);
116: } finally {
117: close(con, stmt, rs);
118: }
119: }
120:
121: public List findPkByFilter(String table, String pkField,
122: WMFilter filter) throws SQLException, RepositoryException {
123:
124: return findPkByFilter(table, pkField, filter == null ? null
125: : new WMFilter[] { filter });
126: }
127:
128: public List findPkByFilter(String table, String pkField,
129: WMFilter[] filters) throws SQLException,
130: RepositoryException {
131:
132: Connection con = null;
133: PreparedStatement stmt = null;
134: ResultSet rs = null;
135: try {
136: List pks = new ArrayList();
137: con = EJBHelper.getConnection();
138: String sql = "SELECT " + pkField + " FROM " + table;
139: stmt = prepareStatement(con, sql, filters, -1, null, null,
140: null);
141: rs = stmt.executeQuery();
142: while (rs.next()) {
143: pks.add(rs.getString(1));
144: }
145: return pks;
146: } finally {
147: close(con, stmt, rs);
148: }
149: }
150:
151: protected final Connection getConnection() throws SQLException {
152: return EJBHelper.getConnection();
153: }
154:
155: protected final String getDatabaseProductName() throws SQLException {
156: if (_dbProductName == null) {
157: Connection con = null;
158: try {
159: con = EJBHelper.getConnection();
160:
161: // meta-data cannot be used after closing the connection
162: _dbProductName = con.getMetaData()
163: .getDatabaseProductName();
164: } finally {
165: close(con, null, null);
166: }
167: }
168: return _dbProductName;
169: }
170:
171: protected final void close(Connection con, Statement stmt,
172: ResultSet rs) {
173: try {
174: if (rs != null)
175: rs.close();
176: } catch (SQLException e) {
177: getLogger().error(e);
178: }
179: try {
180: if (stmt != null)
181: stmt.close();
182: } catch (SQLException e) {
183: getLogger().error(e);
184: }
185: try {
186: if (con != null)
187: con.close();
188: } catch (SQLException e) {
189: getLogger().error(e);
190: }
191: }
192:
193: protected final PreparedStatement prepareStatement(Connection con,
194: String sql, WMFilter filter) throws RepositoryException,
195: SQLException {
196:
197: return prepareStatement(con, sql, filter == null ? null
198: : new WMFilter[] { filter }, -1, null, null, null);
199: }
200:
201: protected PreparedStatement prepareStatement(Connection con,
202: String sql, WMFilter[] filters) throws RepositoryException,
203: SQLException {
204:
205: return prepareStatement(con, sql, filters, -1, null, null, null);
206: }
207:
208: protected PreparedStatement prepareStatement(Connection con,
209: String sql, WMFilter[] filters, int ownerType,
210: String pkField, PropertyDescriptor[] sysAttrs,
211: WorkflowProcess workflow) throws RepositoryException,
212: SQLException {
213:
214: QueryBuilder builder = new QueryBuilder(sql, pkField,
215: ownerType, sysAttrs, workflow);
216:
217: if (filters != null) {
218: for (int i = 0, n = filters.length; i < n; i++) {
219: WMFilter filter = filters[i];
220: if (filter == null)
221: continue;
222: switch (filter.getFilterType()) {
223: case WMFilter.SIMPLE_TYPE:
224: String attributeName = filter.getAttributeName();
225: if (attributeName != null) {
226: builder.addQueryTerm(attributeName, filter
227: .getAttributeType(), filter
228: .getSQLComparison(), filter
229: .getFilterValue());
230: }
231: break;
232: case WMFilter.SQL_TYPE:
233: String filterString = filter.getFilterString();
234: if (filterString != null)
235: builder.addQueryTerm(filterString);
236: break;
237: default:
238: throw new RepositoryException(
239: "Filter type not supported: "
240: + filter.getFilterType());
241: }
242: if (filter instanceof OBEFilter) {
243: OBEFilter obeFilter = (OBEFilter) filter;
244: String orderBy = obeFilter.getOrderBy();
245: if (orderBy != null)
246: builder.addOrderBy(orderBy);
247: int maxRows = obeFilter.getMaxRows();
248: if (maxRows > 0)
249: builder.setMaxRows(maxRows);
250: }
251: }
252: }
253:
254: return builder.prepareStatement(con);
255: }
256: }
|