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.test.cts.ejb;
023:
024: import java.util.Collection;
025:
026: import javax.sql.DataSource;
027: import java.sql.Connection;
028: import java.sql.Statement;
029: import java.sql.PreparedStatement;
030: import java.sql.ResultSet;
031: import java.sql.ResultSetMetaData;
032: import java.sql.Types;
033: import java.sql.SQLException;
034:
035: import javax.naming.InitialContext;
036: import javax.naming.Context;
037: import javax.naming.NamingException;
038:
039: import javax.jms.JMSException;
040: import javax.ejb.EntityBean;
041: import javax.ejb.EntityContext;
042: import javax.ejb.CreateException;
043: import javax.ejb.DuplicateKeyException;
044: import javax.ejb.FinderException;
045: import javax.ejb.ObjectNotFoundException;
046: import javax.ejb.NoSuchEntityException;
047: import javax.ejb.EJBException;
048:
049: import org.jboss.test.cts.keys.AccountPK;
050:
051: import org.jboss.test.cts.jms.ContainerMBox;
052: import org.jboss.test.cts.jms.MsgSender;
053:
054: /**
055: * Class CtsBmpBean is a simple BMP entity bean for testing.
056: * <p/>
057: * If the table used for persistence here does not exist, ejbFindAll()
058: * will create it.
059: *
060: * @author $Author: dimitris@jboss.org $
061: * @version $Revision: 57211 $
062: */
063:
064: public class CtsBmpBean implements EntityBean {
065: org.apache.log4j.Category log = org.apache.log4j.Category
066: .getInstance(getClass());
067:
068: private static final String TABLE_NAME = "BMP_BEAN_TBL";
069: EntityContext ctx = null;
070: DataSource ds = null;
071:
072: private MsgSender ms = null;
073:
074: // bmp fields
075: String accountNumber;
076: String personsName;
077:
078: /**
079: * Create a new instance.
080: *
081: * @param pk The primary key of the new instance.
082: * @param personsName Person name of the new instance.
083: * @throws CreateException In case of database row creation failure.
084: * @throws DuplicateKeyException If another instance with this primary key already exist.
085: */
086: public AccountPK ejbCreate(AccountPK pk, String personsName)
087: throws CreateException, DuplicateKeyException {
088: log.debug("entry ejbCreate(\"" + pk.getKey() + "\", " + "\""
089: + personsName + "\")");
090:
091: sendMsg(ContainerMBox.EJB_CREATE_MSG);
092:
093: try {
094: Connection con = ds.getConnection();
095: try {
096: PreparedStatement ps;
097:
098: // Check for duplicates.
099: ps = con.prepareStatement("SELECT accountNumber "
100: + "FROM " + TABLE_NAME + " "
101: + "WHERE accountNumber=?");
102: try {
103: ps.setString(1, pk.getKey());
104:
105: ResultSet rs = ps.executeQuery();
106:
107: if (rs.next())
108: throw new DuplicateKeyException(
109: "Bean with accountNumber="
110: + pk.getKey()
111: + " already exists.");
112: } finally {
113: ps.close();
114: }
115:
116: // Create in database.
117: ps = con.prepareStatement("INSERT INTO " + TABLE_NAME
118: + " VALUES (?,?)");
119: try {
120: ps.setString(1, pk.getKey());
121: ps.setString(2, personsName);
122:
123: ps.execute();
124: } finally {
125: ps.close();
126: }
127: } finally {
128: con.close();
129: }
130: } catch (SQLException e) {
131: log.debug("failed", e);
132:
133: throw new CreateException("Entity bean creation failure: "
134: + e.getMessage());
135: }
136:
137: this .accountNumber = pk.getKey();
138: this .personsName = personsName;
139:
140: log.debug("Created \"" + accountNumber + "\".");
141:
142: return pk;
143: }
144:
145: /**
146: * Method ejbPostCreate
147: */
148: public void ejbPostCreate(AccountPK pk, String personsName) {
149: log.debug("ejbPostCreate(AccountPK, String) called");
150:
151: sendMsg(ContainerMBox.EJB_POST_CREATE_MSG);
152: }
153:
154: /**
155: * Find a single instance by primary key.
156: *
157: * @param pk Primary key of the instance searched for.
158: * @throws ObjectNotFoundException If no instance with this primary key exists.
159: * @throws FinderException If the lookup failed.
160: */
161: public AccountPK ejbFindByPrimaryKey(AccountPK pk)
162: throws FinderException {
163: log.debug("entry ejbFindByPrimaryKey");
164:
165: try {
166: Connection con = ds.getConnection();
167: try {
168: PreparedStatement ps;
169:
170: ps = con.prepareStatement("SELECT accountNumber "
171: + "FROM " + TABLE_NAME + " "
172: + "WHERE accountNumber=?");
173: try {
174: ps.setString(1, pk.getKey());
175:
176: ResultSet rs = ps.executeQuery();
177:
178: if (!rs.next())
179: throw new ObjectNotFoundException(
180: "No bean with " + "accountNumber="
181: + pk.getKey() + " found.");
182:
183: return pk;
184: } finally {
185: ps.close();
186: }
187: } finally {
188: con.close();
189: }
190: } catch (SQLException e) {
191: log.debug("failed", e);
192:
193: throw new FinderException("Could not find: "
194: + e.getMessage());
195: }
196: }
197:
198: /**
199: * Find all instances.
200: *
201: * @throws FinderException If the lookup failed.
202: */
203: public Collection ejbFindAll() throws FinderException {
204: log.debug("entry ejbFindAll");
205:
206: ensureTableExists();
207:
208: Collection result = new java.util.LinkedList();
209: try {
210: Connection con = ds.getConnection();
211: try {
212: PreparedStatement ps;
213:
214: ps = con.prepareStatement("SELECT accountNumber "
215: + "FROM " + TABLE_NAME);
216: try {
217: ResultSet rs = ps.executeQuery();
218:
219: while (rs.next())
220: result.add(new AccountPK(rs.getString(1)));
221:
222: return result;
223: } finally {
224: ps.close();
225: }
226: } finally {
227: con.close();
228: }
229: } catch (SQLException e) {
230: log.debug("failed", e);
231:
232: throw new FinderException("Could not find: "
233: + e.getMessage());
234: }
235: }
236:
237: /**
238: * Find all instances where the personsName property is
239: * equal to the argument.
240: *
241: * @throws FinderException If the lookup failed.
242: */
243: public Collection ejbFindByPersonsName(String guysName)
244: throws FinderException {
245: log.debug("entry ejbFindByPersonsName(\"" + guysName + "\").");
246:
247: Collection result = new java.util.LinkedList();
248: try {
249: Connection con = ds.getConnection();
250: try {
251: PreparedStatement ps;
252:
253: ps = con.prepareStatement("SELECT accountNumber "
254: + "FROM " + TABLE_NAME + " " + "WHERE name=?");
255: try {
256: ps.setString(1, guysName);
257:
258: ResultSet rs = ps.executeQuery();
259:
260: while (rs.next())
261: result.add(new AccountPK(rs.getString(1)));
262:
263: return result;
264: } finally {
265: ps.close();
266: }
267: } finally {
268: con.close();
269: }
270: } catch (SQLException e) {
271: log.debug("failed", e);
272:
273: throw new FinderException("Could not find: "
274: + e.getMessage());
275: }
276: }
277:
278: /**
279: * Method ejbLoad
280: */
281: public void ejbLoad() {
282: log.debug("ejbLoad(\""
283: + ((AccountPK) ctx.getPrimaryKey()).getKey()
284: + "\") called");
285:
286: sendMsg(ContainerMBox.EJB_LOAD_MSG);
287:
288: try {
289: Connection con = ds.getConnection();
290: try {
291: PreparedStatement ps;
292:
293: ps = con.prepareStatement("SELECT accountNumber,name "
294: + "FROM " + TABLE_NAME + " "
295: + "WHERE accountNumber=?");
296: try {
297: AccountPK pk = (AccountPK) ctx.getPrimaryKey();
298:
299: ps.setString(1, pk.getKey());
300: ResultSet rs = ps.executeQuery();
301:
302: if (rs.next() == false)
303: throw new NoSuchEntityException("Instance "
304: + pk.getKey()
305: + " not found in database.");
306:
307: accountNumber = rs.getString(1);
308: personsName = rs.getString(2);
309: } finally {
310: ps.close();
311: }
312: } finally {
313: con.close();
314: }
315: } catch (SQLException e) {
316: log.debug("failed", e);
317:
318: throw new EJBException(e);
319: }
320:
321: log.debug("ejbLoad(\""
322: + ((AccountPK) ctx.getPrimaryKey()).getKey()
323: + "\") returning");
324:
325: }
326:
327: /**
328: * Method ejbStore
329: */
330: public void ejbStore() {
331: log.debug("ejbStore(\"" + accountNumber + "\") called");
332: //Thread.currentThread().dumpStack();
333:
334: sendMsg(ContainerMBox.EJB_STORE_MSG);
335:
336: try {
337: Connection con = ds.getConnection();
338: try {
339: PreparedStatement ps;
340:
341: ps = con.prepareStatement("UPDATE " + TABLE_NAME + " "
342: + "SET name=? " + "WHERE accountNumber=?");
343: try {
344: ps.setString(1, personsName);
345: ps.setString(2, accountNumber);
346:
347: ps.executeUpdate();
348: } finally {
349: ps.close();
350: }
351: } finally {
352: con.close();
353: }
354: } catch (SQLException e) {
355: log.debug("failed", e);
356:
357: throw new EJBException(e);
358: }
359:
360: log.debug("ejbStore(\"" + accountNumber + "\") returning");
361: }
362:
363: /**
364: * Method ejbRemove
365: */
366: public void ejbRemove() {
367: log.debug("ejbRemove(\"" + accountNumber + "\") called");
368:
369: sendMsg(ContainerMBox.EJB_REMOVE_MSG);
370:
371: try {
372: Connection con = ds.getConnection();
373: try {
374: PreparedStatement ps;
375:
376: ps = con.prepareStatement("DELETE FROM " + TABLE_NAME
377: + " " + "WHERE accountNumber=?");
378: try {
379: ps.setString(1, accountNumber);
380:
381: ps.executeUpdate();
382: } finally {
383: ps.close();
384: }
385: } finally {
386: con.close();
387: }
388: } catch (SQLException e) {
389: log.debug("failed", e);
390:
391: throw new EJBException(e);
392: }
393:
394: log.debug("Removed \"" + accountNumber + "\".");
395: }
396:
397: /**
398: * Method ejbActivate
399: */
400: public void ejbActivate() {
401: log.debug("ejbActivate() called");
402:
403: sendMsg(ContainerMBox.EJB_ACTIVATE_MSG);
404: }
405:
406: /**
407: * Method ejbPassivate
408: */
409: public void ejbPassivate() {
410: log.debug("ejbPassivate() called");
411:
412: sendMsg(ContainerMBox.EJB_PASSIVATE_MSG);
413:
414: // drop message sender
415: if (ms != null) {
416: try {
417: ms.close();
418: } catch (JMSException e) {
419: log.debug("failed", e);
420: // otherwise ignore
421: }
422: ms = null;
423: }
424: }
425:
426: /**
427: * Method setEntityContext
428: */
429: public void setEntityContext(EntityContext ctx) {
430: log.debug("setEntityContext() called");
431:
432: sendMsg(ContainerMBox.SET_ENTITY_CONTEXT_MSG);
433:
434: this .ctx = ctx;
435:
436: // lookup the datasource
437: try {
438: Context context = new InitialContext();
439:
440: ds = (DataSource) context
441: .lookup("java:comp/env/datasource");
442: } catch (NamingException nex) {
443: log.debug("failed", nex);
444:
445: throw new EJBException("Datasource not found: "
446: + nex.getMessage());
447: }
448: }
449:
450: /**
451: * Method unsetEntityContext
452: */
453: public void unsetEntityContext() {
454: log.debug("unsetEntityContext() called");
455:
456: sendMsg(ContainerMBox.UNSET_ENTITY_CONTEXT_MSG);
457:
458: ctx = null;
459: ds = null;
460: }
461:
462: //
463: // Private methods
464: //
465:
466: /**
467: * Check if a good table exists, and create it if needed.
468: */
469: private void ensureTableExists() {
470: boolean exists = true;
471:
472: try {
473: Connection con = ds.getConnection();
474: try {
475: Statement s = con.createStatement();
476: try {
477: ResultSet rs = s.executeQuery("SELECT * FROM "
478: + TABLE_NAME);
479: ResultSetMetaData md = rs.getMetaData();
480:
481: if (md.getColumnCount() != 2)
482: throw new SQLException("Not two columns");
483:
484: if (!"ACCOUNTNUMBER".equals(md.getColumnName(1)
485: .toUpperCase()))
486: throw new SQLException(
487: "First column name not \"accountNumber\"");
488: if (!"NAME".equals(md.getColumnName(2)
489: .toUpperCase()))
490: throw new SQLException(
491: "Second column name not \"name\"");
492:
493: if (md.getColumnType(1) != Types.VARCHAR)
494: throw new SQLException(
495: "First column type not VARCHAR");
496: if (md.getColumnType(2) != Types.VARCHAR)
497: throw new SQLException(
498: "Second column type not VARCHAR");
499: } finally {
500: s.close();
501: }
502: } finally {
503: con.close();
504: }
505: } catch (SQLException e) {
506: exists = false;
507: }
508:
509: if (!exists)
510: initializeDatabaseTable();
511: }
512:
513: /**
514: * Create the table, removing any old table first.
515: */
516: private void initializeDatabaseTable() {
517: log.debug("Initializing DATABASE tables for BMP test...");
518:
519: try {
520: Connection con = ds.getConnection();
521: try {
522: Statement s;
523:
524: s = con.createStatement();
525: try {
526: s.executeUpdate("DROP TABLE " + TABLE_NAME);
527: log.debug("Dropped old table.");
528: } catch (SQLException e) {
529: // Ignore: Presume the table didn't exist.
530: } finally {
531: s.close();
532: }
533:
534: s = con.createStatement();
535: try {
536: s.executeUpdate("CREATE TABLE " + TABLE_NAME + " "
537: + "(accountNumber VARCHAR(25),"
538: + " name VARCHAR(200))");
539: log.debug("Created new table.");
540: } finally {
541: s.close();
542: }
543: } finally {
544: con.close();
545: }
546: } catch (SQLException e) {
547: log.debug("failed", e);
548:
549: throw new EJBException(e);
550: }
551:
552: log.debug("Initialized DATABASE tables for BMP test.");
553: }
554:
555: /**
556: * Send a JMS message.
557: */
558: private void sendMsg(String msg) {
559: if (ms == null)
560: ms = new MsgSender();
561:
562: ms.sendMsg(msg);
563: }
564:
565: //
566: // Business methods
567: //
568:
569: /**
570: * Setter for property personsName.
571: */
572: public void setPersonsName(String personsName) {
573: this .personsName = personsName;
574: }
575:
576: /**
577: * Getter for property personsName.
578: */
579: public String getPersonsName() {
580: return this.personsName;
581: }
582: }
|