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.entityexc.ejb;
023:
024: import java.util.Collection;
025:
026: import java.rmi.RemoteException;
027:
028: import javax.ejb.EntityBean;
029: import javax.ejb.EntityContext;
030: import javax.ejb.CreateException;
031: import javax.ejb.DuplicateKeyException;
032: import javax.ejb.FinderException;
033: import javax.ejb.ObjectNotFoundException;
034: import javax.ejb.NoSuchEntityException;
035: import javax.ejb.EJBException;
036:
037: import javax.naming.InitialContext;
038: import javax.naming.Context;
039: import javax.naming.NamingException;
040:
041: import java.sql.Connection;
042: import java.sql.PreparedStatement;
043: import java.sql.ResultSet;
044: import java.sql.SQLException;
045:
046: import javax.sql.DataSource;
047:
048: import org.jboss.test.entityexc.interfaces.*;
049:
050: /**
051: * Implementation of the ExtityExc EJB.
052: *
053: * @author <a href="mailto:osh@sparre.dk">Ole Husgaard</a>
054: * @version $Revision: 57211 $
055: */
056: public class EntityExcBean implements EntityBean {
057: static org.apache.log4j.Category log = org.apache.log4j.Category
058: .getInstance(EntityExcBean.class);
059:
060: static final private boolean debug = true;
061:
062: /**
063: * The entity context of this instance.
064: */
065: private EntityContext ctx;
066:
067: /**
068: * Flags that this instance should have been discarded
069: * by the container.
070: */
071: private boolean wasDiscarded = false;
072:
073: /**
074: * The primary key of this instance.
075: * The second instance property <code>value</code> is not
076: * stored here, but read and written on demand.
077: */
078: private int id;
079:
080: /**
081: * Check if we are called when we should have been discarded.
082: */
083: private void checkDiscarded() {
084: if (wasDiscarded) {
085: log
086: .debug("**************************************************");
087: log.debug("Attempt to invoke method on an instance "
088: + "that should have been discarded.");
089: log
090: .debug("**************************************************");
091: throw new RuntimeException(
092: "Invokation on discarded instance");
093: }
094: }
095:
096: private void doFailure(boolean isAfter, int flags)
097: throws MyAppException, CreateException {
098: if (isAfter && (flags & EntityExc.F_SETROLLBACKONLY) != 0) {
099: if (debug)
100: log.debug("Marking transaction for rollback only.");
101: ctx.setRollbackOnly();
102: }
103:
104: if ((flags & EntityExc.F_EXC_MASK) != 0) {
105: if (isAfter && (flags & EntityExc.F_THROW_BEFORE) != 0)
106: return;
107: if (!isAfter && (flags & EntityExc.F_THROW_BEFORE) == 0)
108: return;
109:
110: switch (flags & EntityExc.F_EXC_MASK) {
111: case EntityExc.EXC_MYAPPEXCEPTION:
112: if (debug)
113: log.debug("Throwing MyAppException");
114: throw new MyAppException(EntityExc.EXCEPTION_TEXT);
115: case EntityExc.EXC_CREATEEXCEPTION:
116: if (debug)
117: log.debug("Throwing CreateException");
118: throw new CreateException(EntityExc.EXCEPTION_TEXT);
119: case EntityExc.EXC_EJBEXCEPTION:
120: if (debug)
121: log.debug("Throwing EJBException");
122: wasDiscarded = true;
123: throw new EJBException(EntityExc.EXCEPTION_TEXT);
124: default:
125: wasDiscarded = true;
126: throw new EJBException("Unknown exception code.");
127: }
128: }
129: }
130:
131: private void doFailureOnlyAppExc(boolean isAfter, int flags)
132: throws MyAppException {
133: try {
134: doFailure(isAfter, flags);
135: } catch (CreateException ex) {
136: // should not happen
137: wasDiscarded = true;
138: throw new EJBException("Unexpected CreateException");
139: }
140: }
141:
142: public void setEntityContext(EntityContext ctx) {
143: if (debug)
144: log.debug("EntityExcBean.setEntityContext() entered.");
145:
146: checkDiscarded();
147: this .ctx = ctx;
148: }
149:
150: public void unsetEntityContext() {
151: if (debug)
152: log.debug("EntityExcBean.unsetEntityContext() entered.");
153:
154: checkDiscarded();
155: ctx = null;
156: }
157:
158: public void ejbActivate() {
159: if (debug)
160: log.debug("EntityExcBean.ejbActivate() entered.");
161:
162: checkDiscarded();
163: }
164:
165: public void ejbPassivate() {
166: if (debug)
167: log.debug("EntityExcBean.ejbPassivate() entered.");
168:
169: checkDiscarded();
170: }
171:
172: /**
173: * Get a reference to the environment of this enterprise bean.
174: */
175: protected Context getEnvironment() {
176: try {
177: Context ic = new InitialContext();
178: return (Context) ic.lookup("java:comp/env");
179: } catch (NamingException ex) {
180: wasDiscarded = true;
181: throw new EJBException(ex);
182: }
183: }
184:
185: /**
186: * Return the data source of this enterprise bean.
187: */
188: protected DataSource getDataSource() {
189: try {
190: return (DataSource) getEnvironment().lookup(
191: "jdbc/entityexc");
192: } catch (NamingException ex) {
193: wasDiscarded = true;
194: throw new EJBException(ex);
195: }
196: }
197:
198: private Integer ejbCreate(Integer pk) throws CreateException {
199: if (debug)
200: log.debug("EntityExcBean.ejbCreate(Integer pk="
201: + pk.intValue() + ") entered.");
202:
203: this .id = pk.intValue();
204:
205: try {
206: Connection conn = getDataSource().getConnection();
207: try {
208: PreparedStatement stmt;
209:
210: // Check for duplicate key
211: stmt = conn.prepareStatement("select id "
212: + "from entityexc " + "where id=?");
213: try {
214: stmt.setInt(1, id);
215: ResultSet rs = stmt.executeQuery();
216: try {
217: if (rs.next())
218: throw new DuplicateKeyException(
219: "EntityExc id " + pk.intValue()
220: + " already in database.");
221: } finally {
222: rs.close();
223: }
224: } finally {
225: stmt.close();
226: }
227:
228: stmt = conn
229: .prepareStatement("insert into entityexc (id, val) "
230: + "values (?, ?)");
231: try {
232: stmt.setInt(1, id);
233: stmt.setInt(2, 0);
234: stmt.executeUpdate();
235: } finally {
236: stmt.close();
237: }
238:
239: } finally {
240: conn.close();
241: }
242: } catch (SQLException ex) {
243: wasDiscarded = true;
244: throw new EJBException(ex);
245: }
246:
247: return pk;
248: }
249:
250: private void ejbPostCreate(Integer pk) {
251: if (debug)
252: log.debug("EntityExcBean.ejbPostCreate(Integer pk="
253: + pk.intValue() + ") entered.");
254: }
255:
256: public Integer ejbCreate(Integer pk, int flags)
257: throws MyAppException, CreateException {
258: if (debug)
259: log.debug("EntityExcBean.ejbCreate(Integer pk="
260: + pk.intValue() + ", int flags=0x"
261: + Integer.toHexString(flags) + ") entered.");
262:
263: checkDiscarded();
264:
265: if ((flags & EntityExc.F_FAIL_POSTCREATE) == 0)
266: doFailure(false, flags);
267:
268: Integer pk2 = ejbCreate(pk);
269:
270: if ((flags & EntityExc.F_FAIL_POSTCREATE) == 0)
271: doFailure(true, flags);
272:
273: return pk2;
274: }
275:
276: public void ejbPostCreate(Integer pk, int flags)
277: throws MyAppException, CreateException {
278: if (debug)
279: log.debug("EntityExcBean.ejbPostCreate(Integer pk="
280: + pk.intValue() + ", int flags="
281: + Integer.toHexString(flags) + ") entered.");
282:
283: checkDiscarded();
284:
285: log.debug("#1");
286: if ((flags & EntityExc.F_FAIL_POSTCREATE) != 0)
287: doFailure(false, flags);
288:
289: log.debug("#2");
290: if ((flags & EntityExc.F_FAIL_POSTCREATE) != 0)
291: doFailure(true, flags);
292: log.debug("#3");
293: }
294:
295: public void ejbRemove() {
296: if (debug)
297: log.debug("EntityExcBean.ejbRemove() entered.");
298:
299: try {
300: Connection conn = getDataSource().getConnection();
301: try {
302: PreparedStatement stmt;
303:
304: stmt = conn.prepareStatement("delete from entityexc "
305: + "where id=?");
306: try {
307: stmt.setInt(1, id);
308: stmt.executeUpdate();
309: } finally {
310: stmt.close();
311: }
312: } finally {
313: conn.close();
314: }
315: } catch (SQLException ex) {
316: wasDiscarded = true;
317: throw new EJBException(ex);
318: }
319: }
320:
321: private Integer ejbFindByPrimaryKey(Integer pk)
322: throws FinderException {
323: if (debug)
324: log.debug("EntityExcBean.ejbFindByPrimaryKey(Integer pk="
325: + pk.intValue() + ") entered.");
326:
327: try {
328: Connection conn = getDataSource().getConnection();
329: try {
330: PreparedStatement stmt;
331:
332: stmt = conn
333: .prepareStatement("select id from entityexc where id=?");
334: try {
335: stmt.setInt(1, pk.intValue());
336: ResultSet rs = stmt.executeQuery();
337: try {
338: if (!rs.next())
339: throw new ObjectNotFoundException(
340: "EntityExc id " + pk.intValue()
341: + " not found in database.");
342: } finally {
343: rs.close();
344: }
345: } finally {
346: stmt.close();
347: }
348: } finally {
349: conn.close();
350: }
351: } catch (SQLException e) {
352: throw new FinderException("Failed to execute query " + e);
353: }
354:
355: return pk;
356: }
357:
358: public Integer ejbFindByPrimaryKey(Integer pk, int flags)
359: throws MyAppException, FinderException {
360: if (debug)
361: log.debug("EntityExcBean.ejbFindByPrimaryKey(Integer pk="
362: + pk.intValue() + ", int flags=0x"
363: + Integer.toHexString(flags) + ") entered.");
364:
365: checkDiscarded();
366:
367: doFailureOnlyAppExc(false, flags);
368:
369: Integer pk2 = ejbFindByPrimaryKey(pk);
370:
371: doFailureOnlyAppExc(true, flags);
372:
373: return pk2;
374: }
375:
376: private Collection ejbFindAll() throws FinderException {
377: if (debug)
378: log.debug("EntityExcBean.ejbFindAll() entered.");
379:
380: Collection c = new java.util.LinkedList();
381: try {
382: Connection conn = getDataSource().getConnection();
383: try {
384: PreparedStatement stmt;
385:
386: stmt = conn
387: .prepareStatement("select id from entityexc");
388: try {
389: ResultSet rs = stmt.executeQuery();
390: try {
391: while (rs.next())
392: c.add(new Integer(rs.getInt(1)));
393: } finally {
394: rs.close();
395: }
396: } finally {
397: stmt.close();
398: }
399: } finally {
400: conn.close();
401: }
402: } catch (SQLException ex) {
403: throw new FinderException("Failed to execute query " + ex);
404: }
405:
406: return c;
407: }
408:
409: public Collection ejbFindAll(int flags) throws MyAppException,
410: FinderException {
411: if (debug)
412: log.debug("EntityExcBean.ejbFindAll(int flags=0x"
413: + Integer.toHexString(flags) + ") entered.");
414:
415: checkDiscarded();
416:
417: doFailureOnlyAppExc(false, flags);
418:
419: Collection c = ejbFindAll();
420:
421: doFailureOnlyAppExc(true, flags);
422:
423: return c;
424: }
425:
426: public void ejbLoad() {
427: if (debug)
428: log.debug("EntityExcBean.ejbLoad() entered.");
429:
430: checkDiscarded();
431:
432: Object key = ctx.getPrimaryKey();
433: if (key == null)
434: log.debug("EntityExcBean.ejbLoad(): "
435: + "ctx.getPrimaryKey() returned null.");
436: else
437: log.debug("EntityExcBean.ejbLoad(): "
438: + "ctx.getPrimaryKey() returned class "
439: + key.getClass().getName());
440:
441: id = ((Integer) ctx.getPrimaryKey()).intValue();
442: }
443:
444: public void ejbStore() {
445: if (debug)
446: log.debug("EntityExcBean.ejbStore() entered.");
447:
448: checkDiscarded();
449: }
450:
451: public void ejbHomeResetDatabase() {
452: try {
453: Connection conn = getDataSource().getConnection();
454: try {
455: log.debug("Creating database table entityexc.");
456:
457: PreparedStatement stmt;
458:
459: stmt = conn.prepareStatement("drop table entityexc");
460: try {
461: stmt.executeUpdate();
462: } finally {
463: stmt.close();
464: }
465: log.debug("Database table entityexc dropped.");
466: } finally {
467: conn.close();
468: }
469: } catch (SQLException ex) {
470: log.debug("Ignoring error dropping database table: " + ex);
471: }
472: try {
473: Connection conn = getDataSource().getConnection();
474: try {
475: log.debug("Creating database table entityexc.");
476:
477: PreparedStatement stmt;
478:
479: stmt = conn.prepareStatement("create table entityexc"
480: + " (id integer, val integer)");
481: try {
482: stmt.executeUpdate();
483: } finally {
484: stmt.close();
485: }
486: log.debug("Database table entityexc created.");
487: } finally {
488: conn.close();
489: }
490: } catch (SQLException ex) {
491: log.debug("Error creating database table: " + ex);
492: wasDiscarded = true;
493: throw new EJBException("Error creating database table: "
494: + ex);
495: }
496: }
497:
498: //
499: // Business method helpers.
500: //
501:
502: /**
503: * Read the <code>val</code> property from the database,
504: * using the given connection.
505: */
506: private int get_val(Connection conn) throws SQLException {
507: if (debug)
508: log.debug("EntityExcBean.get_val() entered.");
509:
510: PreparedStatement stmt = conn.prepareStatement("select val "
511: + "from entityexc " + "where id=?");
512: try {
513: stmt.setInt(1, id);
514: ResultSet rs = stmt.executeQuery();
515: try {
516: if (rs.next() == false)
517: throw new NoSuchEntityException("EntityExc id "
518: + id + " not found in database.");
519: int ret = rs.getInt(1);
520:
521: if (debug)
522: log.debug("EntityExcBean.get_val() returning "
523: + ret);
524:
525: return ret;
526: } finally {
527: rs.close();
528: }
529: } finally {
530: stmt.close();
531: }
532: }
533:
534: /**
535: * Write the <code>val</code> property to the database,
536: * using the given connection.
537: */
538: private void set_val(int val, Connection conn) throws SQLException {
539: if (debug)
540: log.debug("EntityExcBean.set_val(" + val + ") entered.");
541:
542: PreparedStatement stmt = conn
543: .prepareStatement("update entityexc " + "set val=? "
544: + "where id=?");
545: try {
546: stmt.setInt(1, val);
547: stmt.setInt(2, id);
548: stmt.executeUpdate();
549: } finally {
550: stmt.close();
551: }
552: }
553:
554: //
555: // Business methods.
556: //
557:
558: public int getId() {
559: if (debug)
560: log.debug("EntityExcBean.getId() entered.");
561:
562: checkDiscarded();
563:
564: return id;
565: }
566:
567: public int getVal() {
568: if (debug)
569: log.debug("EntityExcBean.getVal() entered.");
570:
571: checkDiscarded();
572:
573: try {
574: Connection conn = getDataSource().getConnection();
575:
576: try {
577: return get_val(conn);
578: } finally {
579: conn.close();
580: }
581: } catch (SQLException ex) {
582: wasDiscarded = true;
583: throw new EJBException(ex);
584: }
585: }
586:
587: public void incrementVal() {
588: if (debug)
589: log.debug("EntityExcBean.incrementVal(void) entered.");
590:
591: checkDiscarded();
592:
593: try {
594: Connection conn = getDataSource().getConnection();
595:
596: try {
597: set_val(get_val(conn) + 1, conn);
598: } finally {
599: conn.close();
600: }
601: } catch (SQLException ex) {
602: wasDiscarded = true;
603: throw new EJBException(ex);
604: }
605: }
606:
607: public void incrementVal(int flags) throws MyAppException {
608: if (debug)
609: log.debug("EntityExcBean.incrementVal(flags=0x"
610: + Integer.toHexString(flags) + ") entered.");
611:
612: checkDiscarded();
613:
614: doFailureOnlyAppExc(false, flags);
615:
616: incrementVal();
617:
618: doFailureOnlyAppExc(true, flags);
619: }
620:
621: }
|