Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/clra/member/remote/MemberBean.java


1   /*
2    * Copyright (c) Carnegie Lake Rowing Association 2002. All rights reserved.
3    * Distributed under the GPL license. See doc/COPYING.
4    * $RCSfile: MemberBean.java,v $
5    * $Date: 2003/02/26 03:38:45 $
6    * $Revision: 1.11 $
7    */
8   
9   package com.clra.member.remote;
10  
11  import com.clra.member.Configuration;
12  import com.clra.util.DBConfiguration;
13  import com.clra.util.ISerializableComparator;
14  import com.clra.util.ErrorUtils;
15  import com.clra.member.AccountType;
16  import com.clra.member.Address;
17  import com.clra.member.Email;
18  import com.clra.member.MemberDBRead;
19  import com.clra.member.MemberException;
20  import com.clra.member.MemberName;
21  import com.clra.member.MemberRole;
22  import com.clra.member.MemberSnapshot;
23  import com.clra.member.Telephone;
24  import java.rmi.RemoteException;
25  import java.sql.Connection;
26  import java.sql.PreparedStatement;
27  import java.sql.ResultSet;
28  import java.sql.SQLException;
29  import java.sql.Types;
30  import java.util.ArrayList;
31  import java.util.Calendar;
32  import java.util.Collection;
33  import java.util.Date;
34  import java.util.HashMap;
35  import java.util.HashSet;
36  import java.util.Iterator;
37  import java.util.Map;
38  import java.util.Set;
39  import java.text.SimpleDateFormat;
40  import javax.ejb.CreateException;
41  import javax.ejb.EJBException;
42  import javax.ejb.EntityBean;
43  import javax.ejb.EntityContext;
44  import javax.ejb.FinderException;
45  import javax.ejb.NoSuchEntityException;
46  import javax.ejb.ObjectNotFoundException;
47  import javax.ejb.RemoveException;
48  import org.apache.log4j.Category;
49  
50  /**
51   * @author <a href="mailto:donaldzhu@sympatico.ca">Angela Yue</a>
52   * @author <a href="mailto:rphall@pluto.njcc.com">Rick Hall</a>
53   * @version $Revision: 1.11 $ $Date: 2003/02/26 03:38:45 $
54   */
55  
56  public class MemberBean implements EntityBean {
57  
58    private final static String base = MemberBean.class.getName();
59    private final static Category theLog = Category.getInstance( base );
60  
61    private transient boolean isDirty = false;
62  
63    private EntityContext context = null;
64  
65    private Integer m_memberId = null;
66    private String m_accountName = null;
67    private String m_accountPassword = null;
68    private AccountType m_accountType = null;
69    private MemberName m_memberName = null;
70    private Email m_email = null;
71    private Telephone m_eveningPhone = null;
72    private Telephone m_dayPhone = null;
73    private Telephone m_otherPhone = null;
74    private Address m_address = null;
75    private Date m_accountYear = null;
76    private Date m_birthDate = null;
77    private Set m_roles = null;
78  
79    public final static SimpleDateFormat dateFormat =
80            new SimpleDateFormat( Configuration.SQL_DATE_FORMAT );
81  
82    /** Set the context (and primary key) of this instance */
83    public void setEntityContext(EntityContext ctx) {
84  
85      this.context = ctx;
86      if ( theLog.isDebugEnabled() ) {
87        theLog.debug( "setEntityContext: context set" );
88        theLog.debug( "setEntityContext: id == " + this.m_memberId ); 
89      }
90  
91      return;
92    } // setEntityContext(EntityContext)
93  
94    /** Unset the context (and primary key) of this instance */
95    public void unsetEntityContext() {
96  
97      this.context = null;
98      if ( theLog.isDebugEnabled() ) {
99        theLog.debug( "unsetEntityContext: id nulled" );
100       theLog.debug( "unsetEntityContext: context nulled" );
101     }
102 
103     return;
104   } // unsetEntityContext()
105 
106   /**
107    * Sets all properties of a member except the member id. The member id
108    * of the specified snapshot must match the member id of this bean.
109    */
110   public void setData(MemberSnapshot data) {
111     _setData(data);
112   }
113 
114   /**
115    * A private method outside the watchful eye of the EJB container. Used
116    * to implement both <code>setData</code> and <code>loadRows()</code>.
117    */
118   private void _setData( MemberSnapshot data ) {
119 
120     if ( !m_memberId.equals(data.getId()) ) {
121       String msg = "memberId == '" +m_memberId+ "' != '" +data.getId()+ "'";
122       throw new IllegalArgumentException( msg );
123     }
124 
125     setAccountName( data.getAccountName() );
126     setAccountPassword( data.getAccountPassword() );
127     setAccountType( data.getAccountType() );
128     setMemberName( data.getMemberName() );
129     setEmail( data.getEmail() );
130 
131     Map phones = data.getTelephoneNumbers();
132     Telephone evening = (Telephone) phones.get( Telephone.EVENING );
133     setEveningTelephone( evening );
134 
135     Telephone day = (Telephone) phones.get( Telephone.DAY );
136     setDayTelephone( day );
137 
138     Telephone other = (Telephone) phones.get( Telephone.OTHER );
139     setOtherTelephone( other );
140 
141     setAddress( data.getAddress() );
142     setAccountYear( data.getAccountDate() );
143     setBirthDate( data.getBirthDate() );
144     setMemberRoles( data.getMemberRoles() );
145 
146     return;
147   } // setData( MemberSnapshot )
148 
149   public void setAccountName(String accountName) {
150     if ( accountName == null || accountName.trim().length() == 0 ) {
151       String msg = "invalid account name == '" +accountName+ "'";
152       throw new IllegalArgumentException( msg );
153     }
154     if ( m_accountName == null || !m_accountName.equals(accountName) ) {
155       this.isDirty = true;
156       m_accountName = accountName;
157     }
158     return;
159   } // setAccountName(String)
160 
161   public void setAccountPassword(String password) {
162     if ( password == null || password.trim().length() == 0 ) {
163       String msg = "invalid password == '" +password+ "'";
164       throw new IllegalArgumentException( msg );
165     }
166     if ( m_accountPassword == null || !m_accountPassword.equals(password) ) {
167       this.isDirty = true;
168       m_accountPassword = password;
169     }
170     return;
171   } // setAccountPassword(String)
172 
173   public void setAccountType(AccountType type ) {
174     if ( type == null ) {
175       throw new IllegalArgumentException( "null account type" );
176     }
177     if ( m_accountType == null || !m_accountType.equals(type) ) {
178       this.isDirty = true;
179       m_accountType = type;
180     }
181     return;
182   } // setAccountType(AccountType)
183 
184   public void setMemberName(MemberName name) {
185     if ( name == null ) {
186       throw new IllegalArgumentException( "null member name" );
187     }
188     if ( m_memberName == null || !m_memberName.equals(name) ) {
189       this.isDirty = true;
190       m_memberName = name;
191     }
192     return;
193   } // setMemberName(MemberName)
194 
195   public void setEmail(Email email) {
196     if ( m_email != null && !m_email.equals(email) ) {
197       this.isDirty = true;
198       m_email = email;
199     }
200     else if ( m_email == null && email != null ) {
201       this.isDirty = true;
202       m_email = email;
203     }
204     return;
205   } // setEmail(Email)
206 
207   public void setTelephones( Map telephones ) {
208 
209     if ( telephones == null ) {
210       throw new IllegalArgumentException( "null telephone map" );
211     }
212 
213     Telephone phone = (Telephone) telephones.get( Telephone.EVENING );
214     if ( phone == null ) {
215       String msg = "null evening phone";
216       theLog.error( msg );
217       throw new IllegalArgumentException( msg );
218     }
219     if ( m_eveningPhone == null || !m_eveningPhone.equals(phone) ) {
220       this.isDirty = true;
221       m_eveningPhone = phone;
222     }
223 
224     phone = (Telephone) telephones.get( Telephone.DAY );
225     if ( m_dayPhone != null && !m_dayPhone.equals(phone) ) {
226       this.isDirty = true;
227       m_dayPhone = phone;
228     }
229     else if ( m_dayPhone == null && phone != null ) {
230       this.isDirty = true;
231       m_dayPhone = phone;
232     }
233 
234     phone = (Telephone) telephones.get( Telephone.OTHER );
235     if ( m_otherPhone != null && !m_otherPhone.equals(phone) ) {
236       this.isDirty = true;
237       m_otherPhone = phone;
238     }
239     else if ( m_otherPhone == null && phone != null ) {
240       this.isDirty = true;
241       m_otherPhone = phone;
242     }
243 
244     return;
245   } // setTelephones(Map)
246 
247   public void setEveningTelephone(Telephone phone) {
248     if ( phone == null ) {
249       throw new IllegalArgumentException( "null evening phone" );
250     }
251     if ( m_eveningPhone == null || !m_eveningPhone.equals(phone) ) {
252       this.isDirty = true;
253       m_eveningPhone = phone;
254     }
255     return;
256   } // setEveningTelephone(Telephone)
257 
258   public void setDayTelephone(Telephone phone) {
259     if ( m_dayPhone != null && !m_dayPhone.equals(phone) ) {
260       this.isDirty = true;
261       m_dayPhone = phone;
262     }
263     else if ( m_dayPhone == null && phone != null ) {
264       this.isDirty = true;
265       m_dayPhone = phone;
266     }
267     return;
268   } // setDayTelephone(Telephone)
269 
270   public void setOtherTelephone(Telephone phone) {
271     if ( m_otherPhone != null && !m_otherPhone.equals(phone) ) {
272       this.isDirty = true;
273       m_otherPhone = phone;
274     }
275     else if ( m_otherPhone == null && phone != null ) {
276       this.isDirty = true;
277       m_otherPhone = phone;
278     }
279     return;
280   } // setOtherTelephone(Telephone)
281 
282   public void setAddress(Address address) {
283     if ( address == null ) {
284       throw new IllegalArgumentException( "null mailing address" );
285     }
286     if ( m_address == null || !m_address.equals( address ) ) {
287       this.isDirty = true;
288       m_address = address;
289     }
290     return;
291   } // setAddress(Address)
292 
293   public void setAccountYear(Date year) {
294     if ( year == null ) {
295       throw new IllegalArgumentException( "null year" );
296     }
297     if ( m_accountYear == null || !m_accountYear.equals( year ) ) {
298       this.isDirty = true;
299       m_accountYear = year;
300     }
301     return;
302   } // setAccountYear(Date)
303 
304   public void setBirthDate(Date date) {
305     if ( m_birthDate != null && !m_birthDate.equals(date) ) {
306       this.isDirty = true;
307       m_birthDate = date;
308     }
309     else if ( date != null ) {
310       this.isDirty = true;
311       m_birthDate = date;
312     }
313     return;
314   } // setBirthDate(Date)
315 
316   public void setMemberRoles( MemberRole[] roles ) {
317     if ( roles == null ) {
318       throw new IllegalArgumentException( "null roles" );
319     }
320     boolean isOutOfDate = false;
321     if ( m_roles == null ) {
322       isOutOfDate = true;
323     }
324     else if ( m_roles.size() != roles.length ) {
325       isOutOfDate = true;
326     }
327     else {
328       for ( int i=0; i<roles.length; i++ ) {
329         if ( roles[i] != null && !m_roles.contains(roles[i]) ) {
330           isOutOfDate = true;
331           break;
332         }
333         else if ( roles[i] == null ) {
334           isOutOfDate = true;
335           break;
336         }
337       } // for
338     }
339 
340     if ( isOutOfDate ) {
341       this.isDirty = true;
342       m_roles = new HashSet( roles.length );
343       for ( int i=0; i<roles.length; i++ ) {
344         if ( roles[i] != null ) {
345           m_roles.add( roles[i] );
346         }
347       } // for
348     }
349 
350     return;
351   } // setMemberRoles(MemberRole[])
352 
353   public Integer getId() {
354     return m_memberId;
355   }
356 
357   public MemberSnapshot getData() {
358 
359     Map phones = new HashMap();
360     phones.put( Telephone.EVENING, m_eveningPhone );
361     if ( m_dayPhone != null ) {
362       phones.put( Telephone.DAY, m_dayPhone );
363     }
364     if ( m_otherPhone != null ) {
365       phones.put( Telephone.OTHER, m_otherPhone );
366     }
367 
368     MemberRole[] roles = (MemberRole[]) m_roles.toArray( new MemberRole[0] );
369 
370     MemberSnapshot retVal = new MemberSnapshot( m_memberId,
371       m_accountName, m_accountPassword, m_accountType, m_memberName,
372       m_email, phones, m_address, m_accountYear, m_birthDate, roles );
373 
374     return retVal;
375   } // getData()
376 
377   public String getAccountName() {
378     return m_accountName;
379   }
380 
381   public String getAccountPassword() {
382     return m_accountPassword;
383   }
384 
385   public AccountType getAccountType() {
386     return m_accountType;
387   }
388 
389   public MemberName getMemberName() {
390     return m_memberName;
391   }
392 
393   public Email getEmail() {
394     return m_email;
395   }
396 
397   public Map getTelephones() {
398 
399     if ( m_eveningPhone == null ) {
400       throw new IllegalStateException( "null evening phone" );
401     }
402 
403     Map retVal = new HashMap();
404     retVal.put( Telephone.EVENING, m_eveningPhone );
405     if ( m_dayPhone != null ) {
406       retVal.put( Telephone.DAY, m_dayPhone );
407     }
408     if ( m_otherPhone != null ) {
409       retVal.put( Telephone.OTHER, m_otherPhone );
410     }
411 
412     return retVal;
413   } // getTelephones()
414 
415   public Telephone getEveningTelephone() {
416     return m_eveningPhone;
417   }
418 
419   public Telephone getDayTelephone() {
420     return m_dayPhone;
421   }
422 
423   public Telephone getOtherTelephone() {
424     return m_otherPhone;
425   }
426 
427   public Address getAddress() {
428     return m_address;
429   }
430 
431   public Date getAccountYear() {
432     return m_accountYear;
433   }
434 
435   public Date getBirthDate() {
436     return m_birthDate;
437   }
438 
439   public MemberRole[] getMemberRoles() {
440     MemberRole[] retVal = (MemberRole[]) m_roles.toArray( new MemberRole[0] );
441     return retVal;
442   }
443 
444   public Integer ejbCreate(
445                   String accountName,
446                   String accountPassword,
447                   AccountType accountType,
448                   MemberName memberName,
449                   Email email,
450                   Telephone evening,
451                   Telephone day,
452                   Telephone other,
453                   Address address,
454                   Date accountYear,
455                   Date birthDate,
456                   MemberRole[] roles
457                 ) throws CreateException {
458 
459     try {
460 
461       m_memberId = nextId();
462 
463       setAccountName( accountName );
464       setAccountPassword( accountPassword );
465       setAccountType( accountType );
466       setMemberName( memberName );
467       setEmail( email );
468       setEveningTelephone( evening );
469       setDayTelephone( day );
470       setOtherTelephone( other );
471       setAddress( address );
472       setAccountYear( accountYear );
473       setBirthDate( birthDate );
474       setMemberRoles( roles );
475 
476       insertRows();
477 
478       // FIXME shouldn't isDirty be set false here?
479       //this.isDirty = false;
480       // ENDFIXME
481 
482       if ( theLog.isDebugEnabled() ) {
483         String msg = "ejbCreate: " + m_memberId + ", '" + accountName
484           + "', '" + memberName.getLastName()
485           + "', '" + memberName.getFirstName() + "'";
486         theLog.debug( msg );
487       }
488 
489     }
490     catch (Exception ex) {
491       theLog.error( "ejbCreate", ex );
492       throw new EJBException( "ejbCreate: " + ex.getMessage() );
493     }
494 
495     return m_memberId;
496   } // ejbCreate
497 
498   public void ejbPostCreate( String accountName, String accountPassword,
499       AccountType accountType, MemberName memberName, Email email,
500       Telephone evening, Telephone day, Telephone other, Address address,
501       Date accountYear, Date birthDate, MemberRole[] roles ) {
502   }
503 
504   public Integer ejbFindByPrimaryKey(final Integer primaryKey)
505     throws FinderException {
506 
507     // Precondition
508     if ( primaryKey == null ) {
509       throw new FinderException( "null primaryKey" );
510     }
511 
512     Connection conn = null;
513     PreparedStatement stmt = null;
514     ResultSet rs = null;
515     boolean hasRow = false;
516     try {
517       conn = DBConfiguration.getConnection();
518       stmt = conn.prepareStatement(Configuration.SQL_08,
519                                    ResultSet.TYPE_FORWARD_ONLY,
520                                    ResultSet.CONCUR_READ_ONLY);
521 
522       stmt.setInt( 1, primaryKey.intValue() );
523 
524       rs = stmt.executeQuery();
525       hasRow = rs.next();
526       if ( theLog.isDebugEnabled() ) {
527         theLog.debug( "selectByPrimaryKey: hasRow == " + hasRow );
528       }
529 
530     } catch (Exception ex) {
531         theLog.debug("Exception in ejbFindByPrimaryKey: " + ex.getMessage());
532     }
533     finally {
534       DBConfiguration.closeSQLResultSet( rs );
535       DBConfiguration.closeSQLStatement( stmt );
536       DBConfiguration.closeSQLConnection( conn );
537       rs = null;
538       stmt = null;
539       conn = null;
540     }
541 
542     if (!hasRow) {
543       String msg = "Row for primaryKey '" + primaryKey + "' not found.";
544       throw new ObjectNotFoundException( msg );
545     }
546 
547     return primaryKey;
548   } // ejbFindByPrimaryKey(Integer)
549 
550   public Integer ejbFindByAccountName(String name)
551     throws FinderException {
552 
553     Connection conn = null;
554     PreparedStatement stmt = null;
555     ResultSet rs = null;
556     boolean retVal = false;
557     Integer primaryKey = null;
558 
559     try {
560       conn = DBConfiguration.getConnection();
561       stmt = conn.prepareStatement(Configuration.SQL_081,
562                                    ResultSet.TYPE_FORWARD_ONLY,
563                                    ResultSet.CONCUR_READ_ONLY);
564 
565       stmt.setString( 1, name );
566 
567       rs = stmt.executeQuery();
568       retVal = rs.next();
569       primaryKey = new Integer(rs.getInt(1));
570 
571       if ( theLog.isDebugEnabled() ) {
572         theLog.debug( "selectByPrimaryKey: retVal == " + retVal );
573       }
574 
575     } catch (Exception ex) {
576         theLog.debug("Exception in ejbFindByPrimaryKey: " + ex);
577     }
578     finally {
579       DBConfiguration.closeSQLResultSet( rs );
580       DBConfiguration.closeSQLStatement( stmt );
581       DBConfiguration.closeSQLConnection( conn );
582       rs = null;
583       stmt = null;
584       conn = null;
585     }
586 
587     if (!retVal) {
588       String msg = "Row for primary '" + primaryKey + "' not found.";
589       throw new ObjectNotFoundException( msg );
590     }
591 
592     m_memberId = primaryKey;
593     theLog.info("findByAccountName m_memberId = " + m_memberId );
594 
595     return primaryKey;
596   } // ejbFindByAccountName(String)
597 
598   public Collection ejbFindAll()
599     throws FinderException {
600 
601     Connection conn = null;
602     PreparedStatement stmt = null;
603     ResultSet rs = null;
604     Collection retVal = new ArrayList();
605     try {
606       conn = DBConfiguration.getConnection();
607       stmt = conn.prepareStatement(Configuration.SQL_09,
608                                    ResultSet.TYPE_FORWARD_ONLY,
609                                    ResultSet.CONCUR_READ_ONLY);
610 
611       rs = stmt.executeQuery();
612 
613       int rowCount = 0;
614       while ( rs.next() ) {
615         Integer m_memberId = new Integer( rs.getInt(1) );
616         retVal.add(m_memberId);
617         ++rowCount;
618       }
619 
620       if ( theLog.isDebugEnabled() ) {
621         String msg = "selectAll: rowCount == " + rowCount;
622         theLog.debug( msg );
623       }
624 
625     } catch (Exception ex) {
626         theLog.debug("Exception in ejbFindAll: " + ex);
627     }
628 
629     finally {
630       DBConfiguration.closeSQLResultSet( rs );
631       DBConfiguration.closeSQLStatement( stmt );
632       DBConfiguration.closeSQLConnection( conn );
633       rs = null;
634       stmt = null;
635       conn = null;
636     }
637 
638     return retVal;
639   } // ejbFindAll()
640 
641   /** @see delete() */
642   public void ejbRemove() {
643 
644     Connection conn = null;
645     PreparedStatement stmt = null;
646     ResultSet rs = null;
647 
648     try {
649       conn = DBConfiguration.getConnection();
650       stmt = conn.prepareStatement(Configuration.SQL_10,
651                                    ResultSet.TYPE_FORWARD_ONLY,
652                                    ResultSet.CONCUR_READ_ONLY);
653 
654       stmt.setInt( 1, m_memberId.intValue());
655 
656       rs = stmt.executeQuery();
657 
658       deleteRoles(); // delete old roles
659 
660       if ( theLog.isDebugEnabled() ) {
661         theLog.debug( "deleteRow: row " + m_memberId );
662       }
663 
664     } catch (Exception ex) {
665         theLog.debug("Exception in ejbRemove: " + ex);
666     }
667 
668     finally {
669       DBConfiguration.closeSQLResultSet( rs );
670       DBConfiguration.closeSQLStatement( stmt );
671       DBConfiguration.closeSQLConnection( conn );
672       rs = null;
673       stmt = null;
674       conn = null;
675     }
676 
677     return;
678   } // ejbRemove()
679 
680   public void ejbActivate() {
681     this.m_memberId = (Integer) this.context.getPrimaryKey();
682     if ( theLog.isDebugEnabled() ) {
683       theLog.debug( "ejbActivate: m_memberId == " + m_memberId );
684     }
685   }
686 
687   public void ejbPassivate() {
688     this.m_memberId = null;
689     if ( theLog.isDebugEnabled() ) {
690       theLog.debug( "MemberBean.ejbPassivate: m_memberId == " + m_memberId );
691     }
692   }
693 
694   public void ejbLoad() {
695 
696     this.m_memberId = (Integer) this.context.getPrimaryKey();
697     if ( theLog.isDebugEnabled() ) {
698       theLog.debug( "ejbLoad: m_memberId == " + m_memberId );
699     }
700 
701     try {
702       loadRows();
703       if ( theLog.isDebugEnabled() ) {
704         theLog.debug( "ejbLoad: row loaded" );
705       }
706       isDirty = false;
707     }
708     catch (Exception ex) {
709       theLog.error( "ejbLoad", ex );
710       throw new EJBException("ejbLoad: " + ex.getMessage());
711     }
712 
713   } // ejbLoad()
714 
715   public void ejbStore() {
716 
717     try {
718       if ( isDirty ) {
719         storeRows();
720         if ( theLog.isDebugEnabled() ) {
721             theLog.debug( "ejbStore: row stored for #"  + m_memberId );
722         }
723         isDirty = false;
724       }
725       else {
726         if ( theLog.isDebugEnabled() ) {
727           theLog.debug( "ejbStore: row skipped" );
728         }
729       }
730     }
731     catch (Exception ex) {
732       String msg = ErrorUtils.createDbgMsg( "ejbStore", ex );
733       theLog.error( msg, ex );
734       throw new EJBException(msg);
735     }
736 
737   } // ejbStore()
738 
739   /** Inserts a single Member row, and possibly multiple MemberRole rows */
740   private void insertRows() throws SQLException, CreateException {
741 
742     Connection conn = null;
743     PreparedStatement stmt = null;
744     int rowCount = 0;
745     try {
746 
747       conn = DBConfiguration.getConnection();
748       stmt = conn.prepareStatement(Configuration.SQL_12);
749 
750       stmt.setInt(1, m_memberId.intValue() );
751       stmt.setString(2, m_accountName );
752       stmt.setString(3, m_accountPassword );
753       stmt.setString(4, m_accountType.toString() );
754       stmt.setString(5, m_memberName.getLastName() );
755       stmt.setString(6, m_memberName.getFirstName() );
756 
757       int paramInd = 7;
758       final String nmiddle = m_memberName.getMiddleName();
759       if ( nmiddle != null && nmiddle.length() > 0 ) {
760           stmt.setString(paramInd, nmiddle);
761       } else {
762           stmt.setNull(paramInd, Types.VARCHAR);
763       }
764       paramInd++;
765 
766       final String nsuffix = m_memberName.getSuffix();
767       if ( nsuffix != null && nsuffix .length() > 0 ) {
768           stmt.setString(paramInd, nsuffix );
769       } else {
770           stmt.setNull(paramInd, Types.VARCHAR);
771       }
772       paramInd++;
773 
774       final String email = m_email == null ? null : m_email.toString();
775       if ( email != null && email .length() > 0 ) {
776           stmt.setString(paramInd, email );
777       } else {
778           stmt.setNull(paramInd, Types.VARCHAR);
779       }
780       paramInd++;
781 
782       final String tel_evening = toDataString(m_eveningPhone);
783       stmt.setString(paramInd, tel_evening );
784       paramInd++;
785 
786       final String tel_day =
787           m_dayPhone == null ? null : toDataString(m_dayPhone);
788       if ( tel_day != null ) {
789           stmt.setString(paramInd, tel_day );
790       } else {
791           stmt.setNull(paramInd, Types.VARCHAR);
792       }
793       paramInd++;
794 
795       final String tel_other =
796             m_otherPhone == null ? null : toDataString(m_otherPhone);
797       if ( tel_other != null ) {
798           stmt.setString(paramInd, tel_other );
799       } else {
800           stmt.setNull(paramInd, Types.VARCHAR);
801       }
802       paramInd++;
803 
804       final String addr_str1 = m_address.getStreet1();
805       stmt.setString(paramInd, addr_str1 );
806       paramInd++;
807 
808       final String addr_str2 = m_address.getStreet2();
809       if ( addr_str2 != null && addr_str2 .length() > 0 ) {
810           stmt.setString(paramInd, addr_str2 );
811       } else {
812           stmt.setNull(paramInd, Types.VARCHAR);
813       }
814       paramInd++;
815 
816       final String addr_city = m_address.getCity();
817       stmt.setString(paramInd, addr_city );
818       paramInd++;
819 
820       final String addr_state = m_address.getState();
821       stmt.setString(paramInd, addr_state );
822       paramInd++;
823 
824       final String addr_zip = m_address.getZip();
825       stmt.setString(paramInd, addr_zip );
826       paramInd++;
827 
828       final int year = m_accountYear.getYear() + 1900;
829       stmt.setInt(paramInd, year);
830       paramInd++;
831 
832       if ( m_birthDate != null ) {
833           String s = dateFormat.format( m_birthDate );
834           stmt.setString(paramInd, s );
835       } else {
836           stmt.setNull(paramInd, Types.VARCHAR);
837       }
838 
839       rowCount = stmt.executeUpdate();
840 
841       if ( theLog.isDebugEnabled() ) {
842         theLog.debug("insertRow count: " + rowCount);
843         theLog.debug("insertRow memberId: " + m_memberId);
844         theLog.debug("insertRow accountName: " + m_accountName);
845         theLog.debug("insertRow accountPassword: " + m_accountPassword);
846         theLog.debug("insertRow status: " + m_accountType.toString());
847         theLog.debug("insertRow lname: '" +m_memberName.getLastName()+ "'");
848         theLog.debug("insertRow fname: '" +m_memberName.getFirstName()+ "'");
849         theLog.debug("insertRow tel_evening: " + tel_evening);
850         theLog.debug("insertRow addr_str1: " + addr_str1);
851         theLog.debug("insertRow addr_city: " + addr_city);
852         theLog.debug("insertRow addr_state: " + addr_state);
853         theLog.debug("insertRow addr_zip: " + addr_zip);
854         theLog.debug("insertRow year: " + year);
855       }
856 
857       deleteRoles(); // delete old roles
858       insertRoles(); // insert current roles
859 
860     }
861     finally {
862       DBConfiguration.closeSQLStatement( stmt );
863       stmt = null;
864       DBConfiguration.closeSQLConnection( conn );
865       conn = null;
866     }
867 
868     if ( rowCount != 1 ) {
869       String msg = "failed to insert member ==  " + m_memberId;
870       theLog.error( msg );
871       throw new CreateException( msg );
872     }
873 
874     return;
875   } // insertRows
876 
877   /** Load a single Member row, and possibly multiple MemberRole rows */
878   private void loadRows() throws MemberException, SQLException {
879 
880     /*
881      * Implementation note: the translation from DB row to snapshot
882      * to bean looks inefficient, but it is not the bottleneck in
883      * loading bean. The bottleneck is the EJB algorithm for finding
884      * an id, then loading a row, then storing the result back to
885      * the DB. That means at least two DB calls (assuming the storage
886      * step is skipped by checking an isDirty flag). The DB calls
887      * completely dominate performance.
888      *
889      * On the other hand, returning a row as a snapshot allows the
890      * MemberDBRead code to be reused directly elsewhere. Where
891      * speed is critical, and where it is unlikely that a MemberBean
892      * is already in memory, it is best to use the MemberDBRead code to
893      * directly load a (read-only) snapshot from the database.
894      */
895 
896     MemberSnapshot data = MemberDBRead.loadMember( m_memberId );
897     _setData( data );
898 
899     return;
900   } // loadRows()
901 
902   /** Stores a single Member row, and possibly multiple MemberRole rows */
903   private void storeRows() throws SQLException {
904 
905     Connection conn = null;
906     PreparedStatement stmt = null;
907     int rowCount = 0;
908     try {
909 
910       conn = DBConfiguration.getConnection();
911       stmt = conn.prepareStatement(Configuration.SQL_11);
912 
913       stmt.setInt(    19, m_memberId.intValue() );
914       stmt.setString( 17, m_accountName );
915       stmt.setString(  1, m_accountPassword );
916       stmt.setString( 18, m_accountType.toString() );
917       stmt.setString(  2, m_memberName.getLastName() );
918       stmt.setString(  3, m_memberName.getFirstName() );
919 
920       final String nmiddle = m_memberName.getMiddleName();
921       if (nmiddle != null && nmiddle.length() > 0 ) {
922           stmt.setString( 4, nmiddle);
923       } else {
924           stmt.setNull( 4, Types.VARCHAR);
925       }
926 
927       final String nsuffix = m_memberName.getSuffix();
928       if ( nsuffix != null && nsuffix .length() > 0 ) {
929           stmt.setString( 5, nsuffix );
930       } else {
931           stmt.setNull( 5, Types.VARCHAR);
932       }
933 
934       final String email = m_email == null ? null : m_email.toString();
935       if ( email != null && email .length() > 0 ) {
936           stmt.setString( 6, email );
937       } else {
938           stmt.setNull( 6, Types.VARCHAR);
939       }
940 
941       stmt.setString( 7, toDataString(m_eveningPhone) );
942 
943       if ( m_dayPhone != null ) {
944         stmt.setString( 8, toDataString(m_dayPhone) );
945       }
946       else {
947         stmt.setNull( 8, Types.VARCHAR );
948       }
949 
950       if ( m_otherPhone != null ) {
951         stmt.setString( 9, toDataString(m_otherPhone) );
952       }
953       else {
954         stmt.setNull( 9, Types.VARCHAR );
955       }
956 
957       stmt.setString(10, m_address.getStreet1() );
958 
959       String addrstr2 = m_address.getStreet2();
960       if ( addrstr2 != null && addrstr2.trim().length() > 0) {
961         stmt.setString( 11, addrstr2 );
962       }
963       else {
964         stmt.setNull( 11, Types.VARCHAR );
965       }
966 
967       stmt.setString( 12, m_address.getCity() );
968       stmt.setString( 13, m_address.getState() );
969       stmt.setString( 14, m_address.getZip() );
970       stmt.setInt( 15, 1900 + m_accountYear.getYear() );
971 
972       if ( m_birthDate != null ) {
973         String s = dateFormat.format( m_birthDate );
974         stmt.setString( 16, s );
975       }
976       else {
977         stmt.setNull( 16, Types.VARCHAR );
978       }
979 
980       rowCount = stmt.executeUpdate();
981 
982       if ( theLog.isDebugEnabled() ) {
983         theLog.debug( "storeRows: rowCount == " + m_memberId );
984         theLog.debug( "storeRows: memberId: " + m_memberId);
985         theLog.debug( "storeRows: accountName: " + m_accountName);
986         theLog.debug( "storeRows: accountPassword: " + m_accountPassword);
987         theLog.debug( "storeRows: status: " + m_accountType.toString());
988         theLog.debug( "storeRows: lname: '" +m_memberName.getLastName()+ "'");
989         theLog.debug( "storeRows: fname: '" +m_memberName.getFirstName()+ "'");
990         theLog.debug( "storeRows: tel_evening: " + m_eveningPhone.toString());
991         theLog.debug( "storeRows: addr_str1: '" + m_address.getStreet1() + "'");
992         theLog.debug( "storeRows: addr_city: '" + m_address.getCity() + "'");
993         theLog.debug( "storeRows: addr_state: '" + m_address.getState() + "'");
994         theLog.debug( "storeRows: addr_zip: '" + m_address.getZip() + "'");
995         theLog.debug( "storeRows: year: " + (1900 + m_accountYear.getYear()) );
996       }
997 
998       deleteRoles(); // delete old roles
999       insertRoles(); // insert current roles
1000
1001    }
1002    finally {
1003      DBConfiguration.closeSQLStatement( stmt );
1004      stmt = null;
1005      DBConfiguration.closeSQLConnection( conn );
1006      conn = null;
1007    }
1008
1009    if ( rowCount != 1 ) {
1010      String msg = "failed to store member ==  " + m_memberId;
1011      theLog.error( msg );
1012      throw new EJBException( msg );
1013    }
1014
1015    return;
1016  } // storeRows()
1017
1018  /** Inserts (possibly multiple) MemberRole rows */
1019  private void insertRoles() throws SQLException {
1020
1021    Connection conn = null;
1022    PreparedStatement stmt = null;
1023    ResultSet rs = null;
1024
1025    try {
1026      conn = DBConfiguration.getConnection();
1027      stmt = conn.prepareStatement(Configuration.SQL_16);
1028
1029      MemberRole[] roles = this.getMemberRoles();
1030      for ( int i=0; i<roles.length; i++ ) {
1031
1032        stmt.setInt( 1, m_memberId.intValue() );
1033        stmt.setString( 2, roles[i].getRole() );
1034        stmt.setString( 3, roles[i].getRoleGroup() );
1035
1036        int count = stmt.executeUpdate();
1037
1038        if ( theLog.isDebugEnabled() ) {
1039          theLog.debug("insertRole count: " + count);
1040          theLog.debug("insertRole member_id: " + m_memberId);
1041          theLog.debug("insertRole role: " + roles[i].getRole() );
1042          theLog.debug("insertRole roleGroup: " + roles[i].getRoleGroup() );
1043        }
1044
1045      } // for
1046
1047    }
1048    finally {
1049      DBConfiguration.closeSQLResultSet( rs );
1050      rs = null;
1051      DBConfiguration.closeSQLStatement( stmt );
1052      stmt = null;
1053      DBConfiguration.closeSQLConnection( conn );
1054      conn = null;
1055    }
1056
1057    return;
1058  } // insertRoles()
1059
1060  /** Deletes (possibly multiple) MemberRole rows */
1061  private void deleteRoles() throws SQLException {
1062
1063    Connection conn = null;
1064    PreparedStatement stmt = null;
1065    ResultSet rs = null;
1066
1067    try {
1068      conn = DBConfiguration.getConnection();
1069      stmt = conn.prepareStatement(Configuration.SQL_17);
1070
1071      stmt.setInt( 1, m_memberId.intValue() );
1072
1073      rs = stmt.executeQuery();
1074
1075      if ( theLog.isDebugEnabled() ) {
1076        theLog.debug("deleteRole member_id: " + m_memberId);
1077      }
1078
1079    }
1080    finally {
1081      DBConfiguration.closeSQLResultSet( rs );
1082      rs = null;
1083      DBConfiguration.closeSQLStatement( stmt );
1084      stmt = null;
1085      DBConfiguration.closeSQLConnection( conn );
1086      conn = null;
1087    }
1088
1089    return;
1090  } // deleteRoles()
1091
1092  /** A utility that gets (and reserves) the next id for a member */
1093  public static Integer nextId() throws SQLException, CreateException {
1094
1095    Connection conn = null;
1096    PreparedStatement stmt = null;
1097    ResultSet rs = null;
1098    Integer retVal = null;
1099    try {
1100      conn = DBConfiguration.getConnection();
1101      stmt = conn.prepareStatement(
1102          Configuration.SQL_15,
1103          ResultSet.TYPE_FORWARD_ONLY,
1104          ResultSet.CONCUR_READ_ONLY);
1105
1106      if ( theLog.isDebugEnabled() ) {
1107        String msg =
1108          "nextId update: SQL == " + Configuration.SQL_15;
1109        theLog.debug( msg );
1110      }
1111
1112      if ( !DBConfiguration.isOracle() ) {
1113
1114        /*
1115         * There is a problem in this block of code because it is not
1116         * locked in a transaction. If two different threads execute
1117         * this block simultaneously, the MySQL sequence value will
1118         * have been incremented twice, and both threads will use the
1119         * same value in the code section that follows this block.
1120         *
1121         * As a practical matter, during normal operation, rowing
1122         * sessions are created infrequently, and this block of code
1123         * is executed by one thread at a time. This code works because
1124         * this is a low-load application.
1125         */
1126
1127        boolean moreResults = stmt.execute();
1128
1129        stmt = conn.prepareStatement(
1130            Configuration.SQL_15A,
1131            ResultSet.TYPE_FORWARD_ONLY,
1132            ResultSet.CONCUR_READ_ONLY);
1133
1134        if ( theLog.isDebugEnabled() ) {
1135          String msg =
1136            "nextId select: SQL == " + Configuration.SQL_15A;
1137          theLog.debug( msg );
1138        }
1139
1140      } // if !isOracle
1141
1142      rs = stmt.executeQuery();
1143
1144      int rowCount = 0;
1145      while ( rs.next() ) {
1146        retVal = new Integer( rs.getInt(1) );
1147        ++rowCount;
1148      }
1149      if ( rowCount != 1 ) {
1150        String msg =  "unable to get next id: rowCount == " + rowCount;
1151        throw new CreateException( msg );
1152      }
1153
1154      if ( theLog.isDebugEnabled() ) {
1155        String msg = "nextId: retVal == " + retVal.intValue();
1156        theLog.debug( msg );
1157      }
1158
1159    }
1160    finally {
1161      DBConfiguration.closeSQLResultSet( rs );
1162      DBConfiguration.closeSQLStatement( stmt );
1163      DBConfiguration.closeSQLConnection( conn );
1164      rs = null;
1165      stmt = null;
1166      conn = null;
1167    }
1168
1169    return retVal;
1170  } // nextId()
1171
1172  private static String toDataString( Telephone phone ) {
1173
1174    if ( phone == null ) {
1175      throw new IllegalArgumentException( "null phone" );
1176    }
1177
1178    StringBuffer sb = new StringBuffer();
1179    sb.append( phone.getAreaCode() ); 
1180    sb.append( " " );
1181    sb.append( phone.getExchange() );
1182    sb.append( "-" );
1183    sb.append( phone.getLocal() );
1184    String ext = phone.getExtension();
1185    if ( ext != null && ext.trim().length() > 0 ) {
1186      sb.append( " ext. " );
1187      sb.append( ext.trim() );
1188    }
1189    String retVal = new String(sb);
1190
1191    return retVal;
1192  } // toDataString(Telephone)
1193
1194} // MemberBean
1195
1196/*
1197 * $Log: MemberBean.java,v $
1198 * Revision 1.11  2003/02/26 03:38:45  rphall
1199 * Added copyright and GPL license
1200 *
1201 * Revision 1.10  2003/02/21 14:30:55  rphall
1202 * Fixed bug with blank extensions
1203 *
1204 * Revision 1.9  2003/02/21 05:02:33  rphall
1205 * Fixed bug where accountType, accountName weren't stored
1206 *
1207 * Revision 1.8  2003/02/20 04:58:03  rphall
1208 * Added insert/deleteRoles
1209 *
1210 */
1211