Source Code Cross Referenced for DefaultUserInfo.java in  » J2EE » Expresso » com » jcorporate » expresso » services » dbobj » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » Expresso » com.jcorporate.expresso.services.dbobj 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ====================================================================
0002:         * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
0003:         *
0004:         * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
0005:         *
0006:         * Redistribution and use in source and binary forms, with or without
0007:         * modification, are permitted provided that the following conditions
0008:         * are met:
0009:         *
0010:         * 1. Redistributions of source code must retain the above copyright
0011:         *    notice, this list of conditions and the following disclaimer.
0012:         *
0013:         * 2. Redistributions in binary form must reproduce the above copyright
0014:         *    notice, this list of conditions and the following disclaimer in
0015:         *    the documentation and/or other materials provided with the
0016:         *    distribution.
0017:         *
0018:         * 3. The end-user documentation included with the redistribution,
0019:         *    if any, must include the following acknowledgment:
0020:         *       "This product includes software developed by Jcorporate Ltd.
0021:         *        (http://www.jcorporate.com/)."
0022:         *    Alternately, this acknowledgment may appear in the software itself,
0023:         *    if and wherever such third-party acknowledgments normally appear.
0024:         *
0025:         * 4. "Jcorporate" and product names such as "Expresso" must
0026:         *    not be used to endorse or promote products derived from this
0027:         *    software without prior written permission. For written permission,
0028:         *    please contact info@jcorporate.com.
0029:         *
0030:         * 5. Products derived from this software may not be called "Expresso",
0031:         *    or other Jcorporate product names; nor may "Expresso" or other
0032:         *    Jcorporate product names appear in their name, without prior
0033:         *    written permission of Jcorporate Ltd.
0034:         *
0035:         * 6. No product derived from this software may compete in the same
0036:         *    market space, i.e. framework, without prior written permission
0037:         *    of Jcorporate Ltd. For written permission, please contact
0038:         *    partners@jcorporate.com.
0039:         *
0040:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0041:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0042:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0043:         * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
0044:         * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0045:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
0046:         * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0047:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0048:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0049:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0050:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0051:         * SUCH DAMAGE.
0052:         * ====================================================================
0053:         *
0054:         * This software consists of voluntary contributions made by many
0055:         * individuals on behalf of the Jcorporate Ltd. Contributions back
0056:         * to the project(s) are encouraged when you make modifications.
0057:         * Please send them to support@jcorporate.com. For more information
0058:         * on Jcorporate Ltd. and its products, please see
0059:         * <http://www.jcorporate.com/>.
0060:         *
0061:         * Portions of this software are based upon other open source
0062:         * products and are subject to their respective licenses.
0063:         */
0064:
0065:        package com.jcorporate.expresso.services.dbobj;
0066:
0067:        import com.jcorporate.expresso.core.cache.Cache;
0068:        import com.jcorporate.expresso.core.cache.CacheException;
0069:        import com.jcorporate.expresso.core.cache.CacheManager;
0070:        import com.jcorporate.expresso.core.cache.CacheSystem;
0071:        import com.jcorporate.expresso.core.cache.CachedObject;
0072:        import com.jcorporate.expresso.core.controller.ControllerRequest;
0073:        import com.jcorporate.expresso.core.db.DBConnection;
0074:        import com.jcorporate.expresso.core.db.DBException;
0075:        import com.jcorporate.expresso.core.dbobj.DBField;
0076:        import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
0077:        import com.jcorporate.expresso.core.dbobj.ValidValue;
0078:        import com.jcorporate.expresso.core.logging.LogException;
0079:        import com.jcorporate.expresso.core.misc.Base64;
0080:        import com.jcorporate.expresso.core.misc.ConfigManager;
0081:        import com.jcorporate.expresso.core.misc.ConfigurationException;
0082:        import com.jcorporate.expresso.core.misc.DateTime;
0083:        import com.jcorporate.expresso.core.misc.EMailSender;
0084:        import com.jcorporate.expresso.core.misc.EventHandler;
0085:        import com.jcorporate.expresso.core.misc.StringUtil;
0086:        import com.jcorporate.expresso.core.security.CryptoManager;
0087:        import com.jcorporate.expresso.core.security.User;
0088:        import com.jcorporate.expresso.core.security.UserInfo;
0089:        import com.jcorporate.expresso.kernel.exception.ChainedException;
0090:        import com.jcorporate.expresso.kernel.util.FastStringBuffer;
0091:        import org.apache.log4j.Logger;
0092:
0093:        import java.util.Date;
0094:        import java.util.Enumeration;
0095:        import java.util.Hashtable;
0096:        import java.util.Iterator;
0097:        import java.util.Vector;
0098:
0099:        /**
0100:         * Default implementation of the UserInfo object.  This is the class that comes
0101:         * for managing users and security with Expresso.
0102:         *
0103:         * @author Michael Nash, adapted Larry Hamel, CodeGuild
0104:         */
0105:        public class DefaultUserInfo extends SecurityDBObject implements 
0106:                UserInfo {
0107:
0108:            /**
0109:             * Debugging information value
0110:             */
0111:            public static final String THIS_CLASS = DefaultUserInfo.class
0112:                    .getName();
0113:
0114:            /**
0115:             *
0116:             */
0117:            public static final String NAME_2_ID_CACHE_NAME = THIS_CLASS
0118:                    + ".nameToId";
0119:
0120:            /**
0121:             * Field name for the user id
0122:             */
0123:            public static final String EXPUID = "ExpUid";
0124:
0125:            /**
0126:             * Field name for the login name
0127:             */
0128:            public static final String LOGIN = "LoginName";
0129:
0130:            /**
0131:             * Field name for the password
0132:             */
0133:            public static final String PASSWORD = "Passwd";
0134:
0135:            /**
0136:             * Field name for user's email
0137:             */
0138:            public static final String EMAIL_ADDRESS = "EMail";
0139:
0140:            /**
0141:             * Field name for the registration domain id.
0142:             */
0143:            public static final String REGISTRATION_DOMAIN = "RegDomId";
0144:
0145:            /**
0146:             * Field name for account status
0147:             */
0148:            public static final String ACCOUNT_STATUS = "AccountStatus";
0149:
0150:            /**
0151:             * Field name for registration complete flag
0152:             */
0153:            public static final String IS_REG_COMPLETE = "RegComplete";
0154:
0155:            /**
0156:             * Field name for created date
0157:             */
0158:            public static final String CREATED_DATE = "CreateDate";
0159:
0160:            /**
0161:             * Field name for updated date
0162:             */
0163:            public static final String UPDATED_DATE = "UpdateDate";
0164:
0165:            /**
0166:             * Field name for validation code
0167:             */
0168:            public static final String VALIDATION_CODE = "EmailValCode";
0169:
0170:            /**
0171:             * Field name for full name.
0172:             */
0173:            public static final String FULL_NAME = "UserName";
0174:
0175:            /**
0176:             * Full name field length
0177:             */
0178:            public static final int FULL_NAME_LENGTH = 80;
0179:
0180:            /**
0181:             * Email address length
0182:             */
0183:            public static final int EMAIL_ADDRESS_LENGTH = 80;
0184:
0185:            /**
0186:             * Login name length
0187:             */
0188:            public static final int LOGIN_LENGTH = 30;
0189:
0190:            /**
0191:             * Password name length
0192:             */
0193:            public static final int PASSWORD_LENGTH = 30;
0194:
0195:            /**
0196:             * Validation code length
0197:             */
0198:            public static final int VALIDATION_CODE_LENGTH = 30;
0199:
0200:            /**
0201:             * The log4j Logger
0202:             */
0203:            private static Logger log = Logger.getLogger(DefaultUserInfo.class);
0204:
0205:            /**
0206:             * constants used to indicate one of two cases: whether checking for unique email/login name during add() or update()
0207:             */
0208:            private static final boolean IS_UPDATE = true;
0209:            private static final boolean IS_ADD = false;
0210:
0211:            /**
0212:             * Sets the uid of the userinfo object
0213:             *
0214:             * @param uid the user id to set
0215:             * @throws DBException upon error
0216:             */
0217:            public void setUid(String uid) throws DBException {
0218:                StringUtil.assertNotBlank(uid, "Can't set a blank UID");
0219:                setField(EXPUID, uid);
0220:            } /* setUid(String) */
0221:
0222:            /**
0223:             * Sets the uid of the userinfo object
0224:             *
0225:             * @param uid the user id to set
0226:             * @throws DBException upon error
0227:             */
0228:            public void setUid(int uid) throws DBException {
0229:                setField(EXPUID, uid);
0230:            }
0231:
0232:            /**
0233:             * Default constructor
0234:             */
0235:            public DefaultUserInfo() throws DBException {
0236:            } /* DefaultUserInfo() */
0237:
0238:            /**
0239:             * Constructor with UID
0240:             *
0241:             * @param uid The User ID of the owner object
0242:             * @throws DBException upon error
0243:             */
0244:            public DefaultUserInfo(int uid) throws DBException {
0245:                super (uid);
0246:            }
0247:
0248:            /**
0249:             * constructor for db transactions
0250:             *
0251:             * @param localConnection the DB connection which should be used, typically because of an ongoing transaction
0252:             */
0253:            public DefaultUserInfo(DBConnection localConnection)
0254:                    throws DBException {
0255:                if (localConnection != null) {
0256:                    setConnection(localConnection);
0257:                }
0258:            }
0259:
0260:            /**
0261:             * For using DBObjects within Controllers.  Initializes based upon the current
0262:             * user and the requested db. [Of course this can be modified later]
0263:             *
0264:             * @param request - The controller request handed to you by the framework.
0265:             */
0266:            public DefaultUserInfo(ControllerRequest request)
0267:                    throws DBException {
0268:                super (request);
0269:            }
0270:
0271:            /**
0272:             * Override of add to check for duplicate emails.
0273:             *
0274:             * @throws DBException upon error
0275:             */
0276:            public void add() throws DBException {
0277:
0278:                checkEmailAddrAlreadyUsed(IS_ADD);
0279:
0280:                // At initial login, UserName == LoginName, Registation controllers can later modify this
0281:                if (getField(FULL_NAME).equals("")) {
0282:                    setField(FULL_NAME, getField(LOGIN));
0283:                }
0284:                // If a User is added without a status, we set the AccountStatus to "I"
0285:                // for security reasons
0286:                if (getField(ACCOUNT_STATUS).equals("")) {
0287:                    setField(ACCOUNT_STATUS, "I");
0288:                }
0289:                // Set the registration domain id
0290:                if (getRegistrationDomain().equals("")) {
0291:                    setRegistrationDomain("default");
0292:                }
0293:
0294:                RegistrationDomain rd = new RegistrationDomain();
0295:                rd.setDataContext(getDataContext());
0296:                rd.setField("Name", getRegistrationDomain());
0297:
0298:                if (!rd.find()) {
0299:                    throw new DBException("Registration domain \""
0300:                            + getRegistrationDomain()
0301:                            + "\" has not been defined");
0302:                }
0303:
0304:                setField(REGISTRATION_DOMAIN, rd.getField(REGISTRATION_DOMAIN));
0305:
0306:                // Check value of registration valid flag
0307:                if (getField(IS_REG_COMPLETE).equals("")) {
0308:                    setField(IS_REG_COMPLETE, "N");
0309:                }
0310:                // We should always have a CreateDate
0311:                if (getField(CREATED_DATE).equals("")) {
0312:                    setField(CREATED_DATE, DateTime.getDateTimeForDB(this 
0313:                            .getDataContext()));
0314:                }
0315:                // We should always have a UpdateDate
0316:                if (getField(UPDATED_DATE).equals("")) {
0317:                    setField(UPDATED_DATE, getField(CREATED_DATE));
0318:                }
0319:
0320:                super .add();
0321:
0322:                User user = new User();
0323:                user.setDataContext(this .getDataContext());
0324:                user.addNotify(this );
0325:
0326:            } /* add() */
0327:
0328:            /**
0329:             * Extends the checkAllRefs method to check for valid Registration Domain Id
0330:             *
0331:             * @throws DBException If a referential integrity violation is found
0332:             */
0333:            protected void checkAllRefs() throws DBException {
0334:                checkRef(REGISTRATION_DOMAIN, new RegistrationDomain(),
0335:                        "Invalid "
0336:                                + getString(getMetaData().getDescription(
0337:                                        REGISTRATION_DOMAIN)));
0338:            } /* checkAllRefs() */
0339:
0340:            /**
0341:             * Override of deleteMethod() to notify UserListeners of deltion
0342:             *
0343:             * @throws DBException upon error
0344:             */
0345:            public void delete() throws DBException {
0346:
0347:                // Nobody sets the key field UID...so we cheat here.
0348:                // Find the field first so the keyfield is set and then do a delete
0349:                find();
0350:                User user = new User();
0351:                user.setDataContext(this .getDataContext());
0352:                user.deleteNotify(this ); //We cannot delete until all listeners have
0353:                //agreed that this is workable.
0354:                super .delete();
0355:
0356:            } /* delete() */
0357:
0358:            /**
0359:             * Retrieve the account status of the user
0360:             *
0361:             * @return java.lang.String : one of the account status codes
0362:             * @throws DBException upon error
0363:             */
0364:            public String getAccountStatus() throws DBException {
0365:                return getField(ACCOUNT_STATUS);
0366:            } /* getAccountStatus() */
0367:
0368:            /**
0369:             * Retrieve a list of all users... may get REALLY intensive!
0370:             *
0371:             * @return Vector of UserInfo objects
0372:             * @throws DBException upon database error
0373:             */
0374:            public Vector getAllUsers() throws DBException {
0375:                return new Vector(searchAndRetrieveList(LOGIN));
0376:            } /* getAllUsers() */
0377:
0378:            /**
0379:             * Get the account creation date
0380:             *
0381:             * @return java.lang.String as a date formatted string
0382:             * @throws DBException upon error
0383:             */
0384:            public String getCreateDate() throws DBException {
0385:                return getField(CREATED_DATE);
0386:            } /* getCreateDate() */
0387:
0388:            /**
0389:             * Retrieve the email address of the account
0390:             *
0391:             * @return java.lang.String
0392:             * @throws DBException upon error
0393:             */
0394:            public String getEmail() throws DBException {
0395:                return getField(EMAIL_ADDRESS);
0396:            } /* getEmail() */
0397:
0398:            /**
0399:             * Create an email authorization code.  Used anymore??
0400:             *
0401:             * @return java.lang.String
0402:             * @throws DBException upon error
0403:             */
0404:            public String getEmailAuthCode() throws DBException {
0405:                Date createDate = getFieldDate(CREATED_DATE);
0406:                long dateLong = createDate.getTime();
0407:                long emailAuthCode = Math.round(dateLong * 1.71);
0408:
0409:                return Long.toString(emailAuthCode);
0410:            } /* getEmailAuthCode() */
0411:
0412:            /**
0413:             * Retrieve the email validation code
0414:             *
0415:             * @return java.lang.String
0416:             */
0417:            public String getEmailValCode() throws DBException {
0418:                return getField(VALIDATION_CODE);
0419:            } /* getEmailValCode() */
0420:
0421:            /**
0422:             * Get the groups that below to this user
0423:             *
0424:             * @return Vector of strings
0425:             * @throws DBException upon database access error
0426:             */
0427:            public Vector getGroups() throws DBException {
0428:
0429:                //
0430:                //Attempt Cache retrieval first.
0431:                //
0432:                CacheSystem cs = CacheManager.getCacheSystem(this 
0433:                        .getDataContext());
0434:                String cacheName = THIS_CLASS + ".groups";
0435:                String key = Integer.toString(this .getUid());
0436:                Cache cache = cs.getCache(cacheName);
0437:                if (cache == null) {
0438:                    try {
0439:                        cache = cs.createCache(cacheName, false, 200);
0440:                        cs
0441:                                .addListener(
0442:                                        cacheName,
0443:                                        com.jcorporate.expresso.services.dbobj.GroupMembers.class
0444:                                                .getName());
0445:                    } catch (CacheException ex) {
0446:                        log.error("Error creating cache: " + cacheName);
0447:                    }
0448:                }
0449:
0450:                if (cache != null) {
0451:                    CachedObject c = (CachedObject) cache.getItem(key);
0452:                    if (c != null) {
0453:                        return (Vector) c.getValue();
0454:                    }
0455:                }
0456:
0457:                Vector myGroups = new Vector(3);
0458:
0459:                GroupMembers memberList = new GroupMembers();
0460:                memberList.setDataContext(getDataContext());
0461:                memberList.setField(GroupMembers.EXPUID, getUid());
0462:
0463:                if (log.isDebugEnabled()) {
0464:                    log.debug("Getting groups for uid " + getUid()
0465:                            + ", login name " + getLoginName());
0466:                }
0467:                for (Iterator e = memberList.searchAndRetrieveList().iterator(); e
0468:                        .hasNext();) {
0469:                    GroupMembers oneMember = null;
0470:                    oneMember = (GroupMembers) e.next();
0471:                    myGroups.addElement(oneMember.getField("GroupName"));
0472:
0473:                    if (log.isDebugEnabled()) {
0474:                        log.debug("" + getUid() + " is a Member of group "
0475:                                + oneMember.getField("GroupName"));
0476:                    }
0477:                }
0478:
0479:                /**
0480:                 * back in the bad old days, we manually added the UserGroup.UNKNOWN_USERS_GROUP so that
0481:                 * it appeared as though everyone was a member of this group.  If your app depends on this old
0482:                 * behavior, set the following Setup value to true.
0483:                 String isAddUnknownUsersGroup = Setup.getValueUnrequired(getDataContext(), "AddUnknownUserGroup");
0484:                 if ( StringUtil.toBoolean(isAddUnknownUsersGroup) )
0485:                 myGroups.addElement(UserGroup.UNKNOWN_USERS_GROUP);
0486:                 */
0487:
0488:                myGroups.addElement(UserGroup.UNKNOWN_USERS_GROUP);
0489:
0490:                if (log.isDebugEnabled()) {
0491:                    log.debug("" + getUid() + " is a member of "
0492:                            + myGroups.size() + " groups");
0493:                }
0494:
0495:                if (cache != null) {
0496:                    CachedObject co = new CachedObject(key, myGroups);
0497:                    try {
0498:                        cs.addItem(cacheName, co, 1000 * 60 * 10); //10 minute cache;
0499:                    } catch (CacheException ex) {
0500:                        log.error("Error adding group list to cache", ex);
0501:                    }
0502:                }
0503:
0504:                return myGroups;
0505:            } /* getGroups() */
0506:
0507:            /**
0508:             * get name used for login query that is accompanied by password
0509:             */
0510:            public String getLoginName() throws DBException {
0511:                return getField(LOGIN);
0512:            } /* getLoginName() */
0513:
0514:            public String getPassword() throws DBException {
0515:                return getField(PASSWORD);
0516:            } /* getPassword() */
0517:
0518:            public boolean getRegComplete() throws DBException {
0519:                String statusString = getField(IS_REG_COMPLETE);
0520:                boolean status = false;
0521:
0522:                if (statusString.equals("Y")) {
0523:                    status = true;
0524:                }
0525:
0526:                return status;
0527:            } /* getRegComplete() */
0528:
0529:            public String getRegistrationDomain() throws DBException {
0530:                String domain = "default";
0531:                RegistrationDomain rd = new RegistrationDomain();
0532:                rd.setDataContext(getDataContext());
0533:                rd.setField(REGISTRATION_DOMAIN, getField(REGISTRATION_DOMAIN));
0534:
0535:                if (rd.find()) {
0536:                    domain = rd.getField("Name");
0537:                }
0538:
0539:                return domain;
0540:            } /* getRegistrationDomain() */
0541:
0542:            public int getUid() throws DBException {
0543:                return getFieldInt(EXPUID);
0544:            } /* getUid() */
0545:
0546:            public String getUpdateDate() throws DBException {
0547:                return getField(UPDATED_DATE);
0548:            } /* getUpdateDate() */
0549:
0550:            /**
0551:             * get descriptive, full name
0552:             *
0553:             * @deprecated Since Expresso 5.5; use getFullName()
0554:             *             instead to avoid confusion with login name
0555:             */
0556:            public String getUserName() throws DBException {
0557:                return getField(FULL_NAME);
0558:            } /* getUserName() */
0559:
0560:            /**
0561:             * get descriptive, full name (first + last names) of person
0562:             */
0563:            public String getFullName() throws DBException {
0564:                return getField(FULL_NAME);
0565:            } /* getUserName() */
0566:
0567:            /**
0568:             * Get the valid values for various fields on this data object
0569:             *
0570:             * @param fieldName The fieldname to retrieve the valid values for.
0571:             * @return a java.util.Vector of ValidValue objects
0572:             * @throws com.jcorporate.expresso.core.db.DBException
0573:             *          The exception description.
0574:             */
0575:            public synchronized Vector getValidValues(String fieldName)
0576:                    throws DBException {
0577:                if (ACCOUNT_STATUS.equals(fieldName)) {
0578:                    Vector values = new Vector();
0579:                    values.addElement(new ValidValue("A", "Active"));
0580:                    values.addElement(new ValidValue("I",
0581:                            "Inactive Until Email Confirmation"));
0582:                    values.addElement(new ValidValue("D", "Disabled"));
0583:                    values.addElement(new ValidValue("W",
0584:                            "Waiting For Approval"));
0585:                    values.addElement(new ValidValue("X",
0586:                            "Registration Denied By Administrator"));
0587:
0588:                    return values;
0589:                } else if (fieldName.equals(IS_REG_COMPLETE)) {
0590:                    Vector rv = new Vector(2);
0591:                    ValidValue rvv = new ValidValue("Y", "Complete");
0592:                    rv.addElement(rvv);
0593:                    rvv = new ValidValue("N", "Incomplete");
0594:                    rv.addElement(rvv);
0595:
0596:                    return rv;
0597:                }
0598:
0599:                // default for all other fields
0600:                return super .getValidValues(fieldName);
0601:            } /* getValidValues(String) */
0602:
0603:            public Vector getValues() throws DBException {
0604:                // FIXME: change the next line!
0605:                return getValuesDefault(EXPUID, LOGIN);
0606:            } /* getValues() */
0607:
0608:            /**
0609:             * hashEncodePassword:  If passed a plaintext string > 0 bytes, then this
0610:             * function will SHA1 hash the password, then Base64 encode it and return it
0611:             * as a string.
0612:             * <p/>
0613:             * If the password is zero length, then it will simply return a zero length
0614:             * string also.
0615:             *
0616:             * @param plaintext - the password to process in this manner: <br>
0617:             *                  returnValue = Base64(SHA-1(plaintext))
0618:             * @return a String representing a Base64 encoded Hashed Password
0619:             */
0620:            public String hashEncodePassword(String plaintext)
0621:                    throws DBException {
0622:                if (plaintext == null) {
0623:                    throw new DBException("Password Must not be NULL");
0624:                }
0625:                if (plaintext.length() == 0) {
0626:                    return plaintext;
0627:                }
0628:                try {
0629:                    return Base64.encode(CryptoManager.getInstance()
0630:                            .getStringHash().produceHash(plaintext.getBytes()));
0631:                } catch (Exception ex) {
0632:                    throw new DBException("Error hashing Password:"
0633:                            + "  You may not have installed the"
0634:                            + " Cryptography Extensions Properly:", ex);
0635:                }
0636:            } /* hashEncodePassword(String) */
0637:
0638:            /**
0639:             * Send this user a notification via e-mail.
0640:             *
0641:             * @param subject Subject of the e-mail
0642:             * @param message Message to send in body of e-mail
0643:             * @throws DBException If the mail message cannot be sent
0644:             */
0645:            public void notify(String subject, String message)
0646:                    throws DBException, LogException {
0647:                log.info("Notifying user " + getField(EXPUID) + " of "
0648:                        + subject);
0649:
0650:                String sendToUser = getField(EMAIL_ADDRESS);
0651:
0652:                try {
0653:                    EMailSender ems = new EMailSender();
0654:                    ems.setDBName(getDataContext());
0655:                    ems.send(sendToUser, subject, message);
0656:                } catch (Exception e) {
0657:                    throw new DBException("Uncaught exception sending e-mail",
0658:                            e);
0659:                }
0660:            } /* notify(String, String) */
0661:
0662:            /**
0663:             * Check if the given number is in the range of letters and
0664:             * digits that we want to use for generating a password
0665:             * Previously in com.jcorporate.expresso.ext.servlet.RegisterUser.java
0666:             *
0667:             * @param x The byte to check
0668:             * @return true if it is a printable form
0669:             */
0670:            private boolean okNumber(byte x) {
0671:                if ((x >= 65) && (x <= 90)) {
0672:                    return true;
0673:                }
0674:                if ((x >= 48) && (x <= 57)) {
0675:                    return true;
0676:                }
0677:                if ((x >= 97) && (x <= 122)) {
0678:                    return true;
0679:                }
0680:
0681:                return false;
0682:            } /* okNumber(byte) */
0683:
0684:            /**
0685:             * passwordEquals - feed it a password and it will tell you if the hash of it
0686:             * matches the one on file.
0687:             * <p/>
0688:             * Also, for backwards compatability and some other issues, this function
0689:             * will also accept a plaintext version of the password if it is sitting in
0690:             * the database.  However, if a plaintext match is encountered, then it will
0691:             * hash the password and re-write itself to the database record.
0692:             *
0693:             * @param tryPassword The value the user input for an attempted login.
0694:             * @return true if the password equals
0695:             */
0696:            public boolean passwordEquals(String tryPassword)
0697:                    throws DBException {
0698:                if (tryPassword == null) {
0699:                    throw new DBException("tryPassword Must not be NULL");
0700:                }
0701:
0702:                String fieldData = getPassword();
0703:                String trieduser = getLoginName();
0704:
0705:                if (log.isDebugEnabled()) {
0706:                    log.debug("Trying user " + trieduser + ", password '"
0707:                            + tryPassword + "' - field data is '" + fieldData
0708:                            + "'");
0709:                }
0710:
0711:                String triedhash = hashEncodePassword(tryPassword);
0712:
0713:                if (log.isDebugEnabled()) {
0714:                    log.debug("Password hashed is " + triedhash + "'");
0715:                }
0716:                if (triedhash.equals(fieldData)) {
0717:                    return true;
0718:                } else {
0719:                    if (log.isDebugEnabled()) {
0720:                        log.debug("Hash doesn't equal data - trying plaintext");
0721:                    }
0722:                    //The second compare check is to make sure somebody isn't just
0723:                    //replaying a snooped password and attempting to use it against
0724:                    //us.  If Password.length() == 28 then it's a hash.
0725:                    if (tryPassword.equals(fieldData)
0726:                            && fieldData.length() < 20) {
0727:                        if (log.isDebugEnabled()) {
0728:                            log
0729:                                    .debug("Password matches in plain text - hashing & writing to DB");
0730:                        }
0731:
0732:                        setPassword(hashEncodePassword(fieldData));
0733:                        update();
0734:
0735:                        return true;
0736:                    } else {
0737:
0738:                        //No Match
0739:                        if (log.isDebugEnabled()) {
0740:                            log
0741:                                    .debug("Password doesn't equal plain text either ('"
0742:                                            + tryPassword
0743:                                            + "' <> '"
0744:                                            + fieldData
0745:                                            + "') or field data is over 20 characters");
0746:                        }
0747:
0748:                        return false;
0749:                    }
0750:                }
0751:            } /* passwordEquals(String) */
0752:
0753:            /**
0754:             * Called by the various objects that can log in a user
0755:             * to do post-login tasks
0756:             */
0757:            public void postLogin() throws DBException, LogException {
0758:                UserGroup oneGroup = new UserGroup(
0759:                        SecuredDBObject.SYSTEM_ACCOUNT);
0760:                oneGroup.setDataContext(getDataContext());
0761:
0762:                String theEvent = null;
0763:                Hashtable allEvents = new Hashtable(1);
0764:                String oneGroupName = null;
0765:
0766:                for (Enumeration gl = getGroups().elements(); gl
0767:                        .hasMoreElements();) {
0768:                    oneGroupName = (String) gl.nextElement();
0769:                    oneGroup.clear();
0770:                    oneGroup.setField("GroupName", oneGroupName);
0771:
0772:                    if (oneGroup.find()) {
0773:                        theEvent = oneGroup.getField("LoginEvent");
0774:
0775:                        if (!theEvent.equals("")) {
0776:                            allEvents.put(theEvent, oneGroup
0777:                                    .getField("GroupName"));
0778:                        }
0779:                    } /* if the group exists */
0780:
0781:                } /* for each group user is a member of */
0782:
0783:                /* if any events need to be triggered... */
0784:                String theMessage = null;
0785:
0786:                if (allEvents.size() > 0) {
0787:                    for (Enumeration el = allEvents.keys(); el
0788:                            .hasMoreElements();) {
0789:                        theEvent = (String) el.nextElement();
0790:                        theMessage = ("User " + getLoginName() + " ("
0791:                                + getFullName() + ") who is a member "
0792:                                + " of group "
0793:                                + (String) allEvents.get(theEvent) + " has just logged in.");
0794:                        EventHandler.Event(getDataContext(), theEvent,
0795:                                theMessage, true);
0796:                    } /* for each event */
0797:
0798:                } /* if any events to be triggered */
0799:
0800:            } /* postLogin() */
0801:
0802:            /**
0803:             * @return a random generated password
0804:             */
0805:            public String randomPassword() {
0806:                int passwordLength;
0807:                int iterations = 0;
0808:
0809:                //
0810:                //Read the property value of minimum password length
0811:                //
0812:                String propValue = null;
0813:
0814:                try {
0815:                    propValue = StringUtil.notNull(ConfigManager.getContext(
0816:                            getDataContext()).getMinPasswordSize());
0817:                } catch (ConfigurationException ce) {
0818:                    throw new IllegalArgumentException(ce.getMessage());
0819:                }
0820:                if (!propValue.equals("")) {
0821:                    try {
0822:                        passwordLength = Integer.parseInt(propValue, 10);
0823:                    } catch (NumberFormatException ex) {
0824:
0825:                        //Bad number
0826:                        passwordLength = 6;
0827:                    }
0828:                } else {
0829:                    passwordLength = 6;
0830:                }
0831:                FastStringBuffer newPassword = new FastStringBuffer(
0832:                        passwordLength);
0833:
0834:                /////////////////////////////////
0835:                //
0836:                //Now Generate the new password.  (Code from servlet.RegisterUser) before)
0837:                //
0838:                //Get 400 bytes worth of
0839:                //Modified:  Fill an array of 200 possible numbers.  This is our previous max
0840:                //tries anyway.  Then try those in the array.  Saves many allocations,
0841:                //and more importantly, provides a true random number source.
0842:                byte[] possibleNumbers;
0843:
0844:                try {
0845:                    possibleNumbers = CryptoManager.getInstance()
0846:                            .getRandomGenerator().getRandomBytes(200);
0847:                } catch (ChainedException e) {
0848:                    possibleNumbers = new byte[200];
0849:
0850:                    //If an error occurs, just fill it with Math.random() after logging the
0851:                    //exception.
0852:                    Logger.getLogger("com.jcorporate.expresso.core.security.")
0853:                            .error("Random Password", e);
0854:
0855:                    for (int i = 0; i < 200; i++) {
0856:                        possibleNumbers[i] = (byte) (Math.random() * 122);
0857:                    }
0858:                }
0859:                while ((newPassword.length() < passwordLength)
0860:                        && (iterations < 200)) {
0861:                    iterations++;
0862:
0863:                    //oneNumber = Math.random() * 122;
0864:                    if (okNumber(possibleNumbers[iterations])) {
0865:                        newPassword.append((char) possibleNumbers[iterations]);
0866:                    }
0867:                }
0868:
0869:                return newPassword.toString();
0870:            } /* randomPassword() */
0871:
0872:            /**
0873:             * Sends an Authorization Email to a new User.
0874:             * The user must click on the link encoded in this email before
0875:             * his account will be activated.
0876:             */
0877:            public void sendAuthEmail() throws DBException {
0878:                try {
0879:                    String dbContext = getDataContext();
0880:                    String authURL = Setup.getValue(dbContext,
0881:                            "EmailValidateURL");
0882:                    String emailAuthCode = getEmailAuthCode();
0883:                    this .setField(VALIDATION_CODE, emailAuthCode);
0884:                    this .update();
0885:                    authURL = authURL + "?UserName=" + getField(LOGIN) + "&db="
0886:                            + getDataContext() + "&EmailAuthCode="
0887:                            + emailAuthCode;
0888:
0889:                    String subject = "New Account Validation - Please Respond";
0890:                    FastStringBuffer sb = new FastStringBuffer(512);
0891:
0892:                    if (!"".equals(getFullName())) {
0893:                        sb.append("Dear " + getFullName() + ",");
0894:                    }
0895:
0896:                    sb.append("\n");
0897:                    sb.append("\n");
0898:                    sb.append("Thank you for registering");
0899:
0900:                    String companyName = Setup.getValue(dbContext,
0901:                            "CompanyName");
0902:                    String homePageURL = Setup.getValue(dbContext,
0903:                            "HomePageURL");
0904:
0905:                    if (companyName != null && !"".equals(companyName)) {
0906:                        sb.append(" with " + companyName);
0907:                    }
0908:                    if (homePageURL != null && !"".equals(homePageURL)) {
0909:                        sb.append(" at " + homePageURL);
0910:                    }
0911:
0912:                    sb.append("!");
0913:                    sb.append("\n");
0914:                    sb.append("\n");
0915:                    sb.append("Your account has been successfully created. "
0916:                            + "The final step in the");
0917:                    sb.append("\n");
0918:                    sb
0919:                            .append("registration process is to simply follow the link "
0920:                                    + "below to let us");
0921:                    sb.append("\n");
0922:                    sb
0923:                            .append("know that you received this message. You must follow "
0924:                                    + "the link below");
0925:                    sb.append("\n");
0926:                    sb.append("before your account will be activated.");
0927:                    sb.append("\n");
0928:                    sb.append("\n");
0929:                    sb.append("NOTE: If you did not register, you may safely");
0930:                    sb.append("\n");
0931:                    sb.append("ignore this message.");
0932:                    sb.append("\n");
0933:                    sb.append("\n");
0934:                    sb
0935:                            .append("In many email clients, you may simply click on the "
0936:                                    + "link below to");
0937:                    sb.append("\n");
0938:                    sb
0939:                            .append("complete the registration process. If your email "
0940:                                    + "client does not");
0941:                    sb.append("\n");
0942:                    sb
0943:                            .append("support this, cut-and-paste the link below into your "
0944:                                    + "web browser's");
0945:                    sb.append("\n");
0946:                    sb.append("\"Location\" window:");
0947:                    sb.append("\n");
0948:                    sb.append("\n");
0949:                    sb.append(authURL);
0950:                    sb.append("\n");
0951:                    sb.append("\n");
0952:
0953:                    if (companyName != null && !"".equals(companyName)) {
0954:                        sb.append("Thank you from all of us at " + companyName
0955:                                + ".");
0956:                    }
0957:
0958:                    sb.append("\n");
0959:
0960:                    if (companyName != null && !"".equals(homePageURL)) {
0961:                        sb.append(homePageURL);
0962:                    }
0963:
0964:                    sb.append("\n");
0965:
0966:                    String message = sb.toString();
0967:                    notify(subject, message);
0968:                } catch (Exception e) {
0969:                    throw new DBException(
0970:                            "Error in sending account verification message to "
0971:                                    + getField(FULL_NAME) + " at "
0972:                                    + getField(EMAIL_ADDRESS) + ": "
0973:                                    + e.toString());
0974:                }
0975:            } /* sendAuthEmail() */
0976:
0977:            /**
0978:             * Send this user an e-mail with file attachments.
0979:             *
0980:             * @param subject   Subject of the e-mail
0981:             * @param message   Message to send in body of e-mail
0982:             * @param fileNames of the files to attach
0983:             * @throws DBException If the mail message cannot be sent
0984:             */
0985:            public void sendFileTo(String subject, String message,
0986:                    Vector fileNames) throws DBException, LogException {
0987:                log.info("Sending " + fileNames.size()
0988:                        + " files via e-mail to " + getField(LOGIN));
0989:
0990:                String sendToUser = getField(EMAIL_ADDRESS);
0991:
0992:                try { // create some properties and get the default Session
0993:                    EMailSender ems = new EMailSender();
0994:                    ems.setDBName(getDataContext());
0995:                    ems.addFileAttachments(fileNames);
0996:                    ems.send(sendToUser, subject, message);
0997:                } catch (Exception e) {
0998:                    throw new DBException("Error sending e-mail", e);
0999:                }
1000:            } /* sendFileTo(String, String, Vector) */
1001:
1002:            /**
1003:             * Once a user has validated his email address through the email validation
1004:             * servlet, the user will receive this message giving previously requested
1005:             * username/password.
1006:             * <p/>
1007:             * Creation date: (8/8/00 11:44:26 PM)
1008:             * author Adam Rossi, PlatinumSolutions, Inc.
1009:             *
1010:             * @throws com.jcorporate.expresso.core.db.DBException
1011:             *          The exception description.
1012:             */
1013:            public void sendFollowUpEmail() throws DBException {
1014:                try {
1015:                    String subject = "New Registration Complete - Welcome!";
1016:                    String dbContext = getDataContext();
1017:
1018:                    // We can't retrieve the passsword in plain text to transmit to the user
1019:                    // So we just create and set a new passord and send that over.
1020:                    String password = this .randomPassword();
1021:                    this .setPassword(password);
1022:                    this .update();
1023:
1024:                    FastStringBuffer sb = new FastStringBuffer(512);
1025:
1026:                    if (!"".equals(getFullName())) {
1027:                        sb.append("Dear " + getFullName() + ",");
1028:                    }
1029:
1030:                    sb.append("\n");
1031:                    sb.append("\n");
1032:                    sb.append("Thank you for registering");
1033:
1034:                    String companyName = Setup.getValue(dbContext,
1035:                            "CompanyName");
1036:                    String homePageURL = Setup.getValue(dbContext,
1037:                            "HomePageURL");
1038:
1039:                    if (companyName != null && !"".equals(companyName)) {
1040:                        sb.append(" with " + companyName);
1041:                    }
1042:                    if (homePageURL != null && !"".equals(homePageURL)) {
1043:                        sb.append(" at " + homePageURL);
1044:                    }
1045:
1046:                    sb.append("!");
1047:                    sb.append("\n");
1048:                    sb.append("\n");
1049:                    sb
1050:                            .append("Your account is now active. Below is the information "
1051:                                    + "you will need to log in.");
1052:                    sb.append("\n");
1053:                    sb
1054:                            .append("Please keep this information in a safe place.We hope "
1055:                                    + "you enjoy the site and");
1056:                    sb.append("\n");
1057:                    sb.append("look forward to your participation.");
1058:                    sb.append("\n");
1059:                    sb.append("\n");
1060:                    sb.append("Login Name: " + getLoginName());
1061:                    sb.append("\n");
1062:                    sb.append("Password: " + password);
1063:                    sb.append("\n");
1064:                    sb.append("\n");
1065:
1066:                    if (companyName != null && !"".equals(companyName)) {
1067:                        sb.append("Thank you from all of us at " + companyName
1068:                                + ".");
1069:                    }
1070:
1071:                    sb.append("\n");
1072:
1073:                    if (companyName != null && !"".equals(homePageURL)) {
1074:                        sb.append(homePageURL);
1075:                    }
1076:
1077:                    sb.append("\n");
1078:
1079:                    String message = sb.toString();
1080:                    notify(subject, message);
1081:                } catch (Exception e) {
1082:                    throw new DBException(
1083:                            "Error in sending account verification follow up message to "
1084:                                    + getLoginName() + " at " + getEmail()
1085:                                    + ": " + e.toString());
1086:                }
1087:            } /* sendFollowUpEmail() */
1088:
1089:            public void setAccountStatus(String accountStatus)
1090:                    throws DBException {
1091:                setField(ACCOUNT_STATUS, accountStatus);
1092:            } /* setAccountStatus(String) */
1093:
1094:            public void setEmail(String email) throws DBException {
1095:                setField(EMAIL_ADDRESS, email);
1096:            } /* setEmail(String) */
1097:
1098:            public void setEmailValCode(String code) throws DBException {
1099:                setField(VALIDATION_CODE, code);
1100:            } /* setEmailValCode(String) */
1101:
1102:            public void setLoginName(String loginName) throws DBException {
1103:                setField(LOGIN, loginName);
1104:            } /* setLoginName(String) */
1105:
1106:            public void setPassword(String password) throws DBException {
1107:                setField(PASSWORD, password);
1108:            } /* setPassword(String) */
1109:
1110:            public void setRegComplete(boolean status) throws DBException {
1111:                String statusString = "N";
1112:
1113:                if (status) {
1114:                    statusString = "Y";
1115:                }
1116:
1117:                setField(IS_REG_COMPLETE, statusString);
1118:            } /* setRegistrationComplete(String) */
1119:
1120:            public void setRegistrationDomain(String domain) throws DBException {
1121:                RegistrationDomain rd = new RegistrationDomain();
1122:                rd.setDataContext(getDataContext());
1123:                rd.setField("Name", domain);
1124:
1125:                if (rd.find()) {
1126:                    setField(REGISTRATION_DOMAIN, rd
1127:                            .getField(REGISTRATION_DOMAIN));
1128:                } else {
1129:                    throw new DBException("Registration domain \"" + domain
1130:                            + "\" has not been defined.");
1131:                }
1132:            } /* setRegistrationDomain(String) */
1133:
1134:            /**
1135:             * @see com.jcorporate.expresso.core.dbobj.SecuredDBObject#setupFields
1136:             */
1137:            public void setupFields() throws DBException {
1138:                setTargetTable("USERSTABLE");
1139:                setDescription("DBuser");
1140:                setCharset("ISO-8859-1");
1141:                addField(EXPUID, DBField.AUTOINC_TYPE, 0, false, "userId");
1142:                addField(LOGIN, DBField.CHAR_TYPE, LOGIN_LENGTH, false,
1143:                        "userLogin");
1144:                addField(PASSWORD, DBField.VARCHAR_TYPE, PASSWORD_LENGTH, true,
1145:                        "password");
1146:                addField(EMAIL_ADDRESS, DBField.VARCHAR_TYPE,
1147:                        EMAIL_ADDRESS_LENGTH, false, "email");
1148:                addField(REGISTRATION_DOMAIN, DBField.INTEGER_TYPE, 0, false,
1149:                        "RegDomainId");
1150:                addField(ACCOUNT_STATUS, DBField.CHAR_TYPE, 1, false,
1151:                        "isActive");
1152:                addField(IS_REG_COMPLETE, DBField.CHAR_TYPE, 1, false,
1153:                        "RegComplete");
1154:                addField(CREATED_DATE, DBField.DATETIME_TYPE, 0, false,
1155:                        "accountCreation");
1156:                addField(UPDATED_DATE, DBField.DATETIME_TYPE, 0, false,
1157:                        "accountUpdate");
1158:                addField(VALIDATION_CODE, DBField.VARCHAR_TYPE,
1159:                        VALIDATION_CODE_LENGTH, true, "validationCode");
1160:                addField(FULL_NAME, DBField.VARCHAR_TYPE, FULL_NAME_LENGTH,
1161:                        true, "userFullName");
1162:
1163:                //Set up the string filters.
1164:                setStringFilter(LOGIN, "stripFilter");
1165:
1166:                //Nobody should even put special characters here
1167:                setStringFilter(FULL_NAME, "stripFilter");
1168:
1169:                //Nobody should even put special characters here
1170:                setStringFilter(EMAIL_ADDRESS, "stripFilter");
1171:
1172:                //Nobody should even put special characters here
1173:                setStringFilter(PASSWORD, "rawFilter");
1174:
1175:                //Must all all characters through or Password gets mucked up.
1176:                setStringFilter(FULL_NAME, "rawFilter");
1177:
1178:                //The default for the field anyway, but included for completeness' sake
1179:                setStringFilter(VALIDATION_CODE, "stripFilter");
1180:
1181:                addKey(EXPUID);
1182:                setSecret(PASSWORD);
1183:                setSecret(VALIDATION_CODE);
1184:                setMultiValued(ACCOUNT_STATUS);
1185:                setMultiValued(IS_REG_COMPLETE);
1186:                setMultiValued(REGISTRATION_DOMAIN);
1187:                setLookupObject(REGISTRATION_DOMAIN, RegistrationDomain.class
1188:                        .getName());
1189:
1190:                setReadOnly(CREATED_DATE);
1191:                setReadOnly(UPDATED_DATE);
1192:                addIndex("LoginNames", LOGIN, true);
1193:                addIndex("EMails", EMAIL_ADDRESS, false);
1194:                addIndex("Acct_status_idx", ACCOUNT_STATUS, false);
1195:                addDetail(GroupMembers.class.getName(), EXPUID,
1196:                        GroupMembers.EXPUID);
1197:            } /* setupFields() */
1198:
1199:            public void setUserName(String name) throws DBException {
1200:                setField(FULL_NAME, name);
1201:            } /* setUserName(String) */
1202:
1203:            /**
1204:             * Override of add to check for duplicate emails, and handle empty fields
1205:             *
1206:             * @throws DBException upon error
1207:             */
1208:            public void update() throws DBException {
1209:                setCheckZeroUpdate(false);
1210:
1211:                checkEmailAddrAlreadyUsed(IS_UPDATE);
1212:
1213:                if (getField(FULL_NAME).equals("")) {
1214:                    setField(FULL_NAME, getField(LOGIN));
1215:                }
1216:                // If a User is added without a status, we set the AccountStatus to "I"
1217:                // for security reasons
1218:                if (getField(ACCOUNT_STATUS).equals("")) {
1219:                    setField(ACCOUNT_STATUS, "I");
1220:                }
1221:                // Set the registration domain id
1222:                if (getRegistrationDomain().equals("")) {
1223:                    setRegistrationDomain("default");
1224:                }
1225:
1226:                RegistrationDomain rd = new RegistrationDomain();
1227:                rd.setDataContext(getDataContext());
1228:                rd.setField("Name", getRegistrationDomain());
1229:
1230:                if (!rd.find()) {
1231:                    throw new DBException("Regsitration domain \""
1232:                            + getRegistrationDomain()
1233:                            + "\" has not been defined");
1234:                }
1235:
1236:                setField(REGISTRATION_DOMAIN, rd.getField(REGISTRATION_DOMAIN));
1237:
1238:                // Check value of registration valid flag
1239:                if (getField(IS_REG_COMPLETE).equals("")) {
1240:                    setField(IS_REG_COMPLETE, "N");
1241:                }
1242:                // We should always have a CreateDate
1243:                if (getField(CREATED_DATE).equals("")) {
1244:                    setField(CREATED_DATE, DateTime.getDateTimeForDB(this 
1245:                            .getDataContext()));
1246:                }
1247:
1248:                // touch update date
1249:                setField(UPDATED_DATE, DateTime.getDateTimeForDB(this 
1250:                        .getDataContext()));
1251:
1252:                super .update();
1253:
1254:                User user = new User();
1255:                user.setDataContext(this .getDataContext());
1256:                user.updateNotify(this );
1257:
1258:            }
1259:
1260:            /**
1261:             * Check that another user with same email doesn't exist already
1262:             *
1263:             * @param isUpdate boolean for true = update case, false = 'add' case
1264:             */
1265:            private void checkEmailAddrAlreadyUsed(boolean isUpdate)
1266:                    throws DBException {
1267:
1268:                // If this site uses email as login name, force login name equal to email
1269:                boolean useEmailAsLogin = false;
1270:
1271:                try {
1272:                    useEmailAsLogin = ConfigManager
1273:                            .getContext(getDataContext()).useEmailAsLogin();
1274:                } catch (ConfigurationException ce) {
1275:                    throw new DBException(ce);
1276:                }
1277:
1278:                if (isUpdate) {
1279:                    // update case may be shortcircuited, thus requiring no db access
1280:                    String onlychanged = Setup.getValueUnrequired(
1281:                            getDataContext(), UPDATE_CHANGED_ONLY);
1282:                    if (StringUtil.toBoolean(onlychanged)) {
1283:                        // ok, setting says that this app only updates the field which are changed
1284:                        // if email/login not changed, don't waste time checking for whether they are unique
1285:                        if (getDataField(EMAIL_ADDRESS).isChanged()
1286:                                || (!useEmailAsLogin && getDataField(LOGIN)
1287:                                        .isChanged())) {
1288:                            // go on through tests below
1289:                        } else {
1290:                            return; // shortcircuit tests--fields haven't changed
1291:                        }
1292:                    }
1293:                }
1294:
1295:                if (!getField(EMAIL_ADDRESS).equalsIgnoreCase("none")) {
1296:                    UserInfo anotherUser = new User().getUserInfo();
1297:                    anotherUser.setDBName(getDataContext());
1298:                    anotherUser.setEmail(getField(EMAIL_ADDRESS));
1299:
1300:                    boolean foundEmail = anotherUser.find();
1301:                    if (foundEmail && isUpdate
1302:                            && (anotherUser.getUid() != getUid())) {
1303:                        // update case: must also be diff. uid
1304:                        throw new DBException(
1305:                                "Another user with the same email address \""
1306:                                        + getField(EMAIL_ADDRESS)
1307:                                        + "\" already exists");
1308:                    } else if (foundEmail && !isUpdate) {
1309:                        // add case--just finding another with this email is enough to throw
1310:                        throw new DBException(
1311:                                "Another user with the same email address \""
1312:                                        + getField(EMAIL_ADDRESS)
1313:                                        + "\" already exists");
1314:
1315:                    }
1316:                }
1317:
1318:                if (useEmailAsLogin) {
1319:                    if (getField(LOGIN).equals("")) {
1320:                        setField(LOGIN, getField(EMAIL_ADDRESS));
1321:                    }
1322:                } else {
1323:
1324:                    // This site has separate login name, make sure same login name doesn't exist already
1325:                    UserInfo anotherUser = new User().getUserInfo();
1326:                    anotherUser.setDBName(getDataContext());
1327:                    anotherUser.setLoginName(getField(LOGIN));
1328:                    boolean foundLogin = anotherUser.find();
1329:
1330:                    if (!isUpdate && foundLogin) {
1331:                        throw new DBException(
1332:                                "Another user with the same login \""
1333:                                        + getField(LOGIN) + "\" already exists");
1334:                    } else if (isUpdate && foundLogin
1335:                            && (anotherUser.getUid() != getUid())) {
1336:                        throw new DBException(
1337:                                "Another user with the same login \""
1338:                                        + getField(LOGIN) + "\" already exists");
1339:                    }
1340:                }
1341:            }
1342:
1343:            /**
1344:             * Override to provide better performance.  We cache recently used LoginNames
1345:             * into a cache.  If we find the appropriate loginname, then
1346:             * we map the uid so that subsequent find() will perform a retrieve() so we can utilize the
1347:             * cache instead.
1348:             *
1349:             * @return true if successfully found the object
1350:             * @throws DBException if there's an error performing the find.
1351:             */
1352:            public boolean find()
1353:                    throws com.jcorporate.expresso.core.db.DBException {
1354:
1355:                // case where UID is known means no caching
1356:                if (this .getField(EXPUID).length() > 0) {
1357:                    boolean returnValue = super .find();
1358:                    return returnValue; // used UID so we already hit any dbobject cache during find()
1359:                }
1360:
1361:                // if we have a login name, try to find user from cache
1362:                if (getLoginName().length() > 0) {
1363:
1364:                    String keyString = getName2IdCacheKey();
1365:                    try {
1366:                        Cache cache = getName2IdCache();
1367:                        CachedObject c = (CachedObject) cache
1368:                                .getItem(keyString);
1369:                        if (c != null) {
1370:                            Integer cachedUID = (Integer) c.getValue();
1371:                            this .setUid(cachedUID.intValue());
1372:                            try {
1373:                                this .retrieve();
1374:
1375:                                // success!
1376:                                return true;
1377:                            } catch (com.jcorporate.expresso.core.db.exception.DBRecordNotFoundException e) {
1378:                                // log error
1379:                                log
1380:                                        .error(
1381:                                                "Error retrieving user from uid found in cache",
1382:                                                e);
1383:                                // and try again below
1384:                            }
1385:                        }
1386:                    } catch (CacheException e) {
1387:                        log.error("Error retrieving from cache", e);
1388:                        // and try again below
1389:                    }
1390:                }
1391:
1392:                // get here (in non-error case) when EXPID unknown, nor was any *cached* login name provided
1393:                boolean returnValue = super .find();
1394:                if (returnValue) {
1395:                    cacheUser(); // cache in case we search via loginname later
1396:                }
1397:                return returnValue;
1398:
1399:            } /* update() */
1400:
1401:            private void cacheUser() throws DBException {
1402:                String keyString = getName2IdCacheKey();
1403:                try {
1404:                    Cache cache = getName2IdCache();
1405:                    CachedObject c = (CachedObject) cache.getItem(keyString);
1406:                    if (c == null) {
1407:                        CachedObject co = new CachedObject(keyString,
1408:                                new Integer(this .getUid()));
1409:                        CacheSystem cs = CacheManager.getCacheSystem(this 
1410:                                .getDataContext());
1411:                        cs.addItem(NAME_2_ID_CACHE_NAME, co, 1000 * 60 * 10); //10 minute cache;
1412:                    }
1413:                } catch (CacheException e) {
1414:                    log.error("Error adding to cache", e);
1415:                }
1416:            }
1417:
1418:            /**
1419:             * @return cache; never null
1420:             */
1421:            private Cache getName2IdCache() throws CacheException {
1422:                CacheSystem cs = CacheManager.getCacheSystem(this 
1423:                        .getDataContext());
1424:                Cache cache = cs.getCache(NAME_2_ID_CACHE_NAME);
1425:                if (cache == null) {
1426:                    cache = cs.createCache(NAME_2_ID_CACHE_NAME, false, 20);
1427:                    cs.addListener(NAME_2_ID_CACHE_NAME, this .getClass()
1428:                            .getName());
1429:                }
1430:                return cache;
1431:            }
1432:
1433:            /**
1434:             * @return key made from context + name
1435:             * @todo use faststrbuf pool
1436:             */
1437:            private String getName2IdCacheKey() throws DBException {
1438:                FastStringBuffer key = new FastStringBuffer(16);
1439:                key.append(this .getDataContext());
1440:                key.append(".");
1441:                key.append(this .getLoginName());
1442:                String keyString = key.toString();
1443:                return keyString;
1444:            }
1445:
1446:            /**
1447:             * the primary group of this user is appropriate for unix-like purposes,
1448:             * such as setting the group for a file permission
1449:             *
1450:             * @return name of the primary group of this user; null if no group is found
1451:             * @throws DBException upon database access error
1452:             */
1453:            public String getPrimaryGroup() throws DBException {
1454:                return getPrimaryGroup(this );
1455:            }
1456:
1457:            /**
1458:             * the primary group of this user is appropriate for unix-like purposes,
1459:             * such as setting the group for a file permission
1460:             *
1461:             * @param user The userInfo object to query
1462:             * @return name of the primary group of this user; null if no group is primary
1463:             * @throws DBException upon database access error
1464:             */
1465:            public static String getPrimaryGroup(UserInfo user)
1466:                    throws DBException {
1467:                UserGroup primary = null;
1468:
1469:                UserPreference pref = new UserPreference();
1470:                pref.setDataContext(user.getDataContext());
1471:                pref.setField(UserPreference.PREF_CODE,
1472:                        UserPreferenceDef.PRIMARY_GROUP_PREF);
1473:                pref.setField(UserPreference.CLASS_NAME,
1474:                        UserPreferenceDef.ANY_CLASS);
1475:                pref.setField(UserPreference.EXPUID, user.getUid());
1476:                if (!pref.find()) {
1477:
1478:                    // if none marked as primary, use first group in membership list
1479:                    Vector groupNames = user.getGroups();
1480:                    if (groupNames.size() > 0) {
1481:                        primary = new UserGroup();
1482:                        primary.setDataContext(user.getDataContext());
1483:                        primary.setField(UserGroup.GROUP_NAME_FIELD,
1484:                                (String) groupNames.get(0));
1485:                        if (!primary.find()) {
1486:                            primary = null;
1487:                        }
1488:                    }
1489:                } else {
1490:                    // have preference; we expect this to be a real group
1491:                    String primStr = pref.getField(UserPreference.PREF_VALUE);
1492:                    primary = new UserGroup();
1493:                    primary.setDataContext(user.getDataContext());
1494:                    primary.setField(UserGroup.GROUP_NAME_FIELD, primStr);
1495:                    if (!primary.find()) {
1496:                        // unexpected
1497:                        throw new DBException("cannot locate primary group: "
1498:                                + primStr + " which is specified for user: "
1499:                                + user.getLoginName());
1500:                    }
1501:                }
1502:
1503:                if (primary == null) {
1504:                    return null;
1505:                } else {
1506:                    return primary.getField(UserGroup.GROUP_NAME_FIELD);
1507:                }
1508:            }
1509:
1510:            /**
1511:             * set the primary group of this user.  primary group is appropriate for
1512:             * unix-like purposes, such as setting the group for a file permission
1513:             *
1514:             * @param group The UserGroup object to use.
1515:             * @throws DBException upon database access error
1516:             */
1517:            public void setPrimaryGroup(UserGroup group) throws DBException {
1518:                UserPreference pref = new UserPreference();
1519:                pref.setDataContext(this .getDataContext());
1520:                pref.setField(UserPreference.PREF_CODE,
1521:                        UserPreferenceDef.PRIMARY_GROUP_PREF);
1522:                pref.setField(UserPreference.CLASS_NAME,
1523:                        UserPreferenceDef.ANY_CLASS);
1524:                pref.setField(UserPreference.EXPUID, this .getUid());
1525:                pref.setField(UserPreference.PREF_VALUE, group.getGroupName());
1526:                pref.addOrUpdate();
1527:            }
1528:        } /* UserDBObj */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.