View Javadoc

1   package org.apache.turbine.services.security.torque;
2   
3   /*
4    * Copyright 2001-2005 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License")
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.io.ByteArrayOutputStream;
20  import java.io.PrintWriter;
21  import java.sql.Connection;
22  import java.util.Date;
23  import java.util.Hashtable;
24  
25  import javax.servlet.http.HttpSessionBindingEvent;
26  
27  import org.apache.torque.om.Persistent;
28  import org.apache.turbine.om.security.User;
29  import org.apache.turbine.services.security.TurbineSecurity;
30  import org.apache.turbine.util.ObjectUtils;
31  import org.apache.turbine.util.security.TurbineSecurityException;
32  
33  /***
34   * This is the User class used by the TorqueSecurity Service. It decouples
35   * all the database peer access from the actual Peer object
36   *
37   * @author <a href="mailto:josh@stonecottage.com">Josh Lucas</a>
38   * @author <a href="mailto:jon@collab.net">Jon S. Stevens</a>
39   * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
40   * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
41   * @author <a href="mailto:cberry@gluecode.com">Craig D. Berry</a>
42   * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
43   * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
44   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
45   * @version $Id: TorqueUser.java 278824 2005-09-05 20:01:15Z henning $
46   */
47  
48  public class TorqueUser
49      extends TorqueObject
50      implements User
51  {
52      /*** Serial Version UID */
53      private static final long serialVersionUID = 6623129207135917717L;
54  
55      /*** The date on which the user last accessed the application. */
56      private Date lastAccessDate = null;
57  
58      /*** This is data that will survive a servlet engine restart. */
59      private Hashtable permStorage = null;
60  
61      /*** This is data that will not survive a servlet engine restart. */
62      private Hashtable tempStorage = null;
63  
64      /***
65       * Constructor.
66       * Create a new User and set the createDate.
67       */
68      public TorqueUser()
69      {
70          super();
71          setCreateDate(new Date());
72          tempStorage = new Hashtable(10);
73          setHasLoggedIn(Boolean.FALSE);
74      }
75  
76      /***
77       * This Constructor is used when the UserPeerManager
78       * has retrieved a list of Database Objects from the peer and
79       * must 'wrap' them into TorqueRole Objects. You should not use it directly!
80       *
81       * @param obj An Object from the peer
82       */
83      public TorqueUser(Persistent obj)
84      {
85          super(obj);
86  
87          // Do not set creation date. This is only called on retrieval from
88          // storage!
89  
90          tempStorage = new Hashtable(10);
91          setHasLoggedIn(Boolean.FALSE);
92      }
93  
94      /***
95       * Returns the underlying Object for the Peer
96       *
97       * Used in the UserPeerManager when building a new Criteria.
98       *
99       * @return The underlying persistent object
100      *
101      */
102 
103     public Persistent getPersistentObj()
104     {
105         if (obj == null)
106         {
107             obj = UserPeerManager.newPersistentInstance();
108         }
109         return obj;
110     }
111 
112     /***
113      * Stores the object in the database.  If the object is new,
114      * it inserts it; otherwise an update is performed.
115      *
116      * @param torqueName The name under which the object should be stored.
117      *
118      * @exception Exception This method might throw an exceptions
119      */
120     public void save(String torqueName)
121             throws Exception
122     {
123         setObjectdata(ObjectUtils.serializeHashtable(getPermStorage()));
124         super.save(torqueName);
125     }
126 
127     /***
128      * Stores the object in the database.  If the object is new,
129      * it inserts it; otherwise an update is performed.  This method
130      * is meant to be used as part of a transaction, otherwise use
131      * the save() method and the connection details will be handled
132      * internally
133      *
134      * @param con A Connection object to save the object
135      *
136      * @exception Exception This method might throw an exceptions
137      */
138     public void save(Connection con)
139         throws Exception
140     {
141         setObjectdata(ObjectUtils.serializeHashtable(getPermStorage()));
142         super.save(con);
143     }
144 
145     /***
146      * Makes changes made to the User attributes permanent.
147      *
148      * @throws TurbineSecurityException if there is a problem while
149      *  saving data.
150      */
151     public void save()
152         throws TurbineSecurityException
153     {
154         //
155         // This is inconsistent with all the other security classes
156         // because it calls save() on the underlying object directly.
157         // But the UserManager calls ((Persistent)user).save()
158         // so if we do TurbineSecurity.saveUser(this) here, we get
159         // a nice endless loop. :-(
160         //
161         // Users seem to be a special kind of security objects...
162         //
163 
164         try
165         {
166             setObjectdata(ObjectUtils.serializeHashtable(getPermStorage()));
167             getPersistentObj().save();
168         }
169         catch (Exception e)
170         {
171             throw new TurbineSecurityException("User object said "
172                     + e.getMessage(), e);
173         }
174     }
175 
176     /***
177      * Returns the name of this object.
178      *
179      * @return The name of the object.
180      */
181     public String getName()
182     {
183         return UserPeerManager.getName(getPersistentObj());
184     }
185 
186     /***
187      * Sets the name of this object
188      *
189      * @param name The name of the object
190      */
191     public void setName(String name)
192     {
193         setUserName(name);
194     }
195 
196     /***
197      * Gets the Id of this object
198      *
199      * @return The Id of the object
200      */
201     public int getId()
202     {
203         return UserPeerManager.getIdAsObj(getPersistentObj()).intValue();
204     }
205 
206     /***
207      * Gets the Id of this object
208      *
209      * @return The Id of the object
210      */
211     public Integer getIdAsObj()
212     {
213         return UserPeerManager.getIdAsObj(getPersistentObj());
214     }
215 
216     /***
217      * Sets the Id of this object
218      *
219      * @param id The new Id
220      */
221     public void setId(int id)
222     {
223         UserPeerManager.setId(getPersistentObj(), id);
224     }
225 
226     /***
227      * Returns the name of this user.
228      *
229      * @return The name of the user.
230      * @deprecated Use getName() instead.
231      */
232     public String getUserName()
233     {
234         return getName();
235     }
236 
237     /***
238      * Sets the name of this user.
239      *
240      * @param name The name of the user.
241      */
242     public void setUserName(String name)
243     {
244         UserPeerManager.setUserName(getPersistentObj(), name);
245     }
246 
247     /***
248      * Returns the password of the User
249      *
250      * @return The password of the User
251      */
252     public String getPassword()
253     {
254         return UserPeerManager.getUserPassword(getPersistentObj());
255     }
256 
257     /***
258      * Sets the password of the User
259      *
260      * @param password The new password of the User
261      */
262     public void setPassword(String password)
263     {
264         UserPeerManager.setUserPassword(getPersistentObj(), password);
265     }
266 
267     /***
268      * Returns the first name of the User
269      *
270      * @return The first name of the User
271      */
272     public String getFirstName()
273     {
274         return UserPeerManager.getUserFirstName(getPersistentObj());
275     }
276 
277     /***
278      * Sets the first name of the User
279      *
280      * @param firstName The new first name of the User
281      */
282     public void setFirstName(String firstName)
283     {
284         UserPeerManager.setUserFirstName(getPersistentObj(), firstName);
285     }
286 
287     /***
288      * Returns the last name of the User
289      *
290      * @return The last name of the User
291      */
292     public String getLastName()
293     {
294         return UserPeerManager.getUserLastName(getPersistentObj());
295     }
296 
297     /***
298      * Sets the last name of User
299      *
300      * @param lastName The new last name of the User
301      */
302     public void setLastName(String lastName)
303     {
304         UserPeerManager.setUserLastName(getPersistentObj(), lastName);
305     }
306 
307     /***
308      * Returns the email address of the user
309      *
310      * @return The email address of the user
311      */
312     public String getEmail()
313     {
314         return UserPeerManager.getUserEmail(getPersistentObj());
315     }
316 
317     /***
318      * Sets the new email address of the user
319      *
320      * @param email The new email address of the user
321      */
322     public void setEmail(String email)
323     {
324         UserPeerManager.setUserEmail(getPersistentObj(), email);
325     }
326 
327     /***
328      * Returns the confirm value of the user
329      *
330      * @return The confirm value of the user
331      */
332     public String getConfirmed()
333     {
334         return UserPeerManager.getUserConfirmed(getPersistentObj());
335     }
336 
337     /***
338      * Sets the new confirm value of the user
339      *
340      * @param confirm The new confirm value of the user
341      */
342     public void setConfirmed(String confirm)
343     {
344         UserPeerManager.setUserConfirmed(getPersistentObj(), confirm);
345     }
346 
347     /***
348      * Returns the creation date of the user
349      *
350      * @return The creation date of the user
351      */
352     public java.util.Date getCreateDate()
353     {
354         return UserPeerManager.getUserCreateDate(getPersistentObj());
355     }
356 
357     /***
358      * Sets the new creation date of the user
359      *
360      * @param createDate The new creation date of the user
361      */
362     public void setCreateDate(java.util.Date createDate)
363     {
364         UserPeerManager.setUserCreateDate(getPersistentObj(), createDate);
365     }
366 
367     /***
368      * Returns the date of the last login of the user
369      *
370      * @return The date of the last login of the user
371      */
372     public java.util.Date getLastLogin()
373     {
374         return UserPeerManager.getUserLastLogin(getPersistentObj());
375     }
376 
377     /***
378      * Sets the new date of the last login of the user
379      *
380      * @param lastLogin The new the date of the last login of the user
381      */
382     public void setLastLogin(java.util.Date lastLogin)
383     {
384         UserPeerManager.setUserLastLogin(getPersistentObj(), lastLogin);
385     }
386 
387     /***
388      * Returns the value of the objectdata for this user.
389      * Objectdata is a VARBINARY column in the table used
390      * to store the permanent storage table from the User
391      * object.
392      *
393      * @return The bytes in the objectdata for this user
394      */
395     public byte [] getObjectdata()
396     {
397         return UserPeerManager.getUserObjectdata(getPersistentObj());
398     }
399 
400     /***
401      * Sets the value of the objectdata for the user
402      *
403      * @param objectdata The new the date of the last login of the user
404      */
405     public void setObjectdata(byte [] objectdata)
406     {
407         UserPeerManager.setUserObjectdata(getPersistentObj(), objectdata);
408     }
409 
410 
411     /***
412      * Gets the access counter for a user from perm storage.
413      *
414      * @return The access counter for the user.
415      */
416     public int getAccessCounter()
417     {
418         try
419         {
420             return ((Integer) getPerm(User.ACCESS_COUNTER)).intValue();
421         }
422         catch (Exception e)
423         {
424             return 0;
425         }
426     }
427 
428     /***
429      * Gets the access counter for a user during a session.
430      *
431      * @return The access counter for the user for the session.
432      */
433     public int getAccessCounterForSession()
434     {
435         try
436         {
437             return ((Integer) getTemp(User.SESSION_ACCESS_COUNTER)).intValue();
438         }
439         catch (Exception e)
440         {
441             return 0;
442         }
443     }
444 
445     /***
446      * Increments the permanent hit counter for the user.
447      */
448     public void incrementAccessCounter()
449     {
450         // Ugh. Race city, here I come...
451         setAccessCounter(getAccessCounter() + 1);
452     }
453 
454     /***
455      * Increments the session hit counter for the user.
456      */
457     public void incrementAccessCounterForSession()
458     {
459         setAccessCounterForSession(getAccessCounterForSession() + 1);
460     }
461 
462     /***
463      * Sets the access counter for a user, saved in perm storage.
464      *
465      * @param cnt The new count.
466      */
467     public void setAccessCounter(int cnt)
468     {
469         setPerm(User.ACCESS_COUNTER, new Integer(cnt));
470     }
471 
472     /***
473      * Sets the session access counter for a user, saved in temp
474      * storage.
475      *
476      * @param cnt The new count.
477      */
478     public void setAccessCounterForSession(int cnt)
479     {
480         setTemp(User.SESSION_ACCESS_COUNTER, new Integer(cnt));
481     }
482 
483     /***
484      * This method reports whether or not the user has been confirmed
485      * in the system by checking the User.CONFIRM_VALUE
486      * column in the users record to see if it is equal to
487      * User.CONFIRM_DATA.
488      *
489      * @return True if the user has been confirmed.
490      */
491     public boolean isConfirmed()
492     {
493         String value = getConfirmed();
494         return (value != null && value.equals(User.CONFIRM_DATA));
495     }
496 
497     /***
498      * The user is considered logged in if they have not timed out.
499      *
500      * @return Whether the user has logged in.
501      */
502     public boolean hasLoggedIn()
503     {
504         Boolean loggedIn = getHasLoggedIn();
505         return (loggedIn != null && loggedIn.booleanValue());
506     }
507 
508     /***
509      * This sets whether or not someone has logged in.  hasLoggedIn()
510      * returns this value.
511      *
512      * @param value Whether someone has logged in or not.
513      */
514     public void setHasLoggedIn(Boolean value)
515     {
516         setTemp(User.HAS_LOGGED_IN, value);
517     }
518 
519     /***
520      * Gets the last access date for this User.  This is the last time
521      * that the user object was referenced.
522      *
523      * @return A Java Date with the last access date for the user.
524      */
525     public java.util.Date getLastAccessDate()
526     {
527         if (lastAccessDate == null)
528         {
529             setLastAccessDate();
530         }
531         return lastAccessDate;
532     }
533 
534     /***
535      * Sets the last access date for this User. This is the last time
536      * that the user object was referenced.
537      */
538     public void setLastAccessDate()
539     {
540         lastAccessDate = new java.util.Date();
541     }
542 
543     /***
544      * Returns the permanent storage. This is implemented
545      * as a Hashtable and backed by an VARBINARY column in
546      * the database.
547      *
548      * @return A Hashtable.
549      */
550     public Hashtable getPermStorage()
551     {
552         if (permStorage == null)
553         {
554             byte [] objectdata = getObjectdata();
555 
556             if (objectdata != null)
557             {
558                 permStorage = (Hashtable) ObjectUtils.deserialize(objectdata);
559             }
560 
561             if (permStorage == null)
562             {
563                 permStorage = new Hashtable();
564             }
565         }
566 
567         return permStorage;
568     }
569 
570     /***
571      * This should only be used in the case where we want to save the
572      * data to the database.
573      *
574      * @param storage A Hashtable.
575      */
576     public void setPermStorage(Hashtable permStorage)
577     {
578         if (permStorage != null)
579         {
580             this.permStorage = permStorage;
581         }
582     }
583 
584     /***
585      * Returns the temporary storage. This is implemented
586      * as a Hashtable
587      *
588      * @return A Hashtable.
589      */
590     public Hashtable getTempStorage()
591     {
592         if (tempStorage == null)
593         {
594             tempStorage = new Hashtable();
595         }
596         return tempStorage;
597     }
598 
599     /***
600      * This should only be used in the case where we want to save the
601      * data to the database.
602      *
603      * @param storage A Hashtable.
604      */
605     public void setTempStorage(Hashtable tempStorage)
606     {
607         if (tempStorage != null)
608         {
609             this.tempStorage = tempStorage;
610         }
611     }
612 
613     /***
614      * Get an object from permanent storage.
615      *
616      * @param name The object's name.
617      * @return An Object with the given name.
618      */
619     public Object getPerm(String name)
620     {
621         return getPermStorage().get(name);
622     }
623 
624     /***
625      * Get an object from permanent storage; return default if value
626      * is null.
627      *
628      * @param name The object's name.
629      * @param def A default value to return.
630      * @return An Object with the given name.
631      */
632     public Object getPerm(String name, Object def)
633     {
634         try
635         {
636             Object val = getPermStorage().get(name);
637             return (val == null ? def : val);
638         }
639         catch (Exception e)
640         {
641             return def;
642         }
643     }
644 
645     /***
646      * Put an object into permanent storage. If the value is null,
647      * it will convert that to a "" because the underlying storage
648      * mechanism within TorqueUser is currently a Hashtable and
649      * null is not a valid value.
650      *
651      * @param name The object's name.
652      * @param value The object.
653      */
654     public void setPerm(String name, Object value)
655     {
656         getPermStorage().put(name, (value == null) ? "" : value);
657     }
658 
659     /***
660      * Get an object from temporary storage.
661      *
662      * @param name The object's name.
663      * @return An Object with the given name.
664      */
665     public Object getTemp(String name)
666     {
667         return getTempStorage().get(name);
668     }
669 
670     /***
671      * Get an object from temporary storage; return default if value
672      * is null.
673      *
674      * @param name The object's name.
675      * @param def A default value to return.
676      * @return An Object with the given name.
677      */
678     public Object getTemp(String name, Object def)
679     {
680         Object val;
681         try
682         {
683             val = getTempStorage().get(name);
684             if (val == null)
685             {
686                 val = def;
687             }
688         }
689         catch (Exception e)
690         {
691             val = def;
692         }
693         return val;
694     }
695 
696     /***
697      * Put an object into temporary storage. If the value is null,
698      * it will convert that to a "" because the underlying storage
699      * mechanism within TorqueUser is currently a Hashtable and
700      * null is not a valid value.
701      *
702      * @param name The object's name.
703      * @param value The object.
704      */
705     public void setTemp(String name, Object value)
706     {
707         getTempStorage().put(name, (value == null) ? "" : value);
708     }
709 
710     /***
711      * Remove an object from temporary storage and return the object.
712      *
713      * @param name The name of the object to remove.
714      * @return An Object.
715      */
716     public Object removeTemp(String name)
717     {
718         return getTempStorage().remove(name);
719     }
720 
721     /***
722      * Updates the last login date in the database.
723      *
724      * @exception Exception A generic exception.
725      */
726     public void updateLastLogin()
727         throws Exception
728     {
729         setLastLogin(new java.util.Date());
730     }
731 
732     /***
733      * Implement this method if you wish to be notified when the User
734      * has been Bound to the session.
735      *
736      * @param event Indication of value/session binding.
737      */
738     public void valueBound(HttpSessionBindingEvent hsbe)
739     {
740         // Currently we have no need for this method.
741     }
742 
743     /***
744      * Implement this method if you wish to be notified when the User
745      * has been Unbound from the session.
746      *
747      * @param event Indication of value/session unbinding.
748      */
749     public void valueUnbound(HttpSessionBindingEvent hsbe)
750     {
751         try
752         {
753             if (hasLoggedIn())
754             {
755                 TurbineSecurity.saveOnSessionUnbind(this);
756             }
757         }
758         catch (Exception e)
759         {
760             //Log.error("TorqueUser.valueUnbound(): " + e.getMessage(), e);
761 
762             // To prevent messages being lost in case the logging system
763             // goes away before sessions get unbound on servlet container
764             // shutdown, print the stcktrace to the container's console.
765             ByteArrayOutputStream ostr = new ByteArrayOutputStream();
766             e.printStackTrace(new PrintWriter(ostr, true));
767             String stackTrace = ostr.toString();
768             System.out.println(stackTrace);
769         }
770     }
771 
772     /***
773      * This gets whether or not someone has logged in.  hasLoggedIn()
774      * returns this value as a boolean.  This is private because you
775      * should use hasLoggedIn() instead.
776      *
777      * @return True if someone has logged in.
778      */
779     private Boolean getHasLoggedIn()
780     {
781         return (Boolean) getTemp(User.HAS_LOGGED_IN);
782     }
783 
784 }