View Javadoc

1   package org.apache.turbine.om.security.peer;
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.sql.Connection;
20  
21  import java.util.ArrayList;
22  import java.util.Hashtable;
23  import java.util.List;
24  
25  import com.workingdogs.village.Column;
26  import com.workingdogs.village.Record;
27  import com.workingdogs.village.Schema;
28  import com.workingdogs.village.Value;
29  
30  import org.apache.torque.TorqueException;
31  import org.apache.torque.map.TableMap;
32  import org.apache.torque.om.NumberKey;
33  import org.apache.torque.om.Persistent;
34  import org.apache.torque.util.BasePeer;
35  import org.apache.torque.util.Criteria;
36  
37  import org.apache.turbine.om.security.User;
38  import org.apache.turbine.services.security.TurbineSecurity;
39  import org.apache.turbine.util.ObjectUtils;
40  import org.apache.turbine.util.db.map.TurbineMapBuilder;
41  import org.apache.turbine.util.security.DataBackendException;
42  
43  /***
44   * This class handles all the database access for the User/User
45   * table.  This table contains all the information for a given user.
46   *
47   * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
48   * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a>
49   * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
50   * @version $Id: TurbineUserPeer.java 280284 2005-09-12 07:57:42Z henning $
51   */
52  public class TurbineUserPeer extends BasePeer implements UserPeer
53  {
54      /*** Serial Version UID */
55      private static final long serialVersionUID = -5981268145973167352L;
56  
57      /*** The mapBuilder for this Peer. */
58      private static final TurbineMapBuilder MAP_BUILDER = (TurbineMapBuilder)
59              getMapBuilder(TurbineMapBuilder.class.getName());
60  
61      // column names
62      /*** The column name for the visitor id field. */
63      private static final String USER_ID_COLUMN = MAP_BUILDER.getUserId();
64  
65      /*** This is the value that is stored in the database for confirmed users. */
66      public static final String CONFIRM_DATA
67              = org.apache.turbine.om.security.User.CONFIRM_DATA;
68  
69      /*** The column name for the visitor id field. */
70      private static final String OBJECT_DATA_COLUMN = MAP_BUILDER.getObjectData();
71  
72      /*** The table name for this peer. */
73      private static final String TABLE_NAME = MAP_BUILDER.getTableUser();
74  
75      // Criteria Keys
76      /*** The key name for the visitor id field. */
77      public static final String USER_ID = MAP_BUILDER.getUser_UserId();
78  
79      /*** The key name for the username field. */
80      public static final String USERNAME = MAP_BUILDER.getUser_Username();
81  
82      /*** The key name for the password field. */
83      public static final String PASSWORD = MAP_BUILDER.getUser_Password();
84  
85      /*** The key name for the first name field. */
86      public static final String FIRST_NAME = MAP_BUILDER.getUser_FirstName();
87  
88      /*** The key name for the last name field. */
89      public static final String LAST_NAME = MAP_BUILDER.getUser_LastName();
90  
91      /*** The key name for the modified field. */
92      public static final String MODIFIED = MAP_BUILDER.getUser_Modified();
93  
94      /*** The key name for the created field. */
95      public static final String CREATED = MAP_BUILDER.getUser_Created();
96  
97      /*** The key name for the email field. */
98      public static final String EMAIL = MAP_BUILDER.getUser_Email();
99  
100     /*** The key name for the last_login field. */
101     public static final String LAST_LOGIN = MAP_BUILDER.getUser_LastLogin();
102 
103     /*** The key name for the confirm_value field. */
104     public static final String CONFIRM_VALUE
105             = MAP_BUILDER.getUser_ConfirmValue();
106 
107     /*** The key name for the object_data field. */
108     public static final String OBJECT_DATA = MAP_BUILDER.getUser_ObjectData();
109 
110     /*** The schema. */
111     private static Schema schema = initTableSchema(TABLE_NAME);
112 
113     /*** The columns. */
114     private static Column[] columns
115             = initTableColumns(schema);
116 
117     /*** The names of the columns. */
118     public static String[] columnNames = initColumnNames(columns);
119 
120     /*** The keys for the criteria. */
121     public static String[] criteriaKeys
122             = initCriteriaKeys(TABLE_NAME, columnNames);
123 
124 
125     /***
126      * Get the name of this table.
127      *
128      * @return A String with the name of the table.
129      */
130     public static String getTableName()
131     {
132         return TABLE_NAME;
133     }
134 
135     /***
136      * Returns the full name of a column.
137      *
138      * @param name name of a column
139      * @return A String with the full name of the column.
140      */
141     public static String getColumnName(String name)
142     {
143         StringBuffer sb = new StringBuffer();
144         sb.append(TABLE_NAME);
145         sb.append(".");
146         sb.append(name);
147         return sb.toString();
148     }
149 
150     /***
151      *
152      * Returns the full name of a column.
153      *
154      * @param name name of a column
155      * @return A String with the full name of the column.
156      */
157     public String getFullColumnName(String name)
158     {
159         StringBuffer sb = new StringBuffer();
160         sb.append(TABLE_NAME);
161         sb.append(".");
162         sb.append(name);
163         return sb.toString();
164     }
165 
166     /***
167      * Builds a criteria object based upon an User object.  Data
168      * stored in the permData table which a key matching a column
169      * name is removed from the permData table and added as a criterion.
170      * All remaining data in the permData table is serialized and
171      * added as a criterion for the OBJECT_DATA column.
172      *
173      * @param user object to build the criteria
174      * @return the Criteria
175      */
176     public static Criteria buildCriteria(User user)
177     {
178         Hashtable permData = (Hashtable) user.getPermStorage().clone();
179         Criteria criteria = new Criteria();
180         if (!((Persistent) user).isNew())
181         {
182             criteria.add(USER_ID, ((Persistent) user).getPrimaryKey());
183         }
184 
185         for (int i = 1; i < TurbineUserPeer.columnNames.length; i++)
186         {
187             if (permData.containsKey(TurbineUserPeer.columnNames[i]))
188             {
189                 criteria.add(TurbineUserPeer.criteriaKeys[i],
190                         permData.remove(TurbineUserPeer.columnNames[i]));
191             }
192         }
193         criteria.add(TurbineUserPeer.OBJECT_DATA, permData);
194         return criteria;
195     }
196 
197     /***
198      * Add all the columns needed to create a new object
199      *
200      * @param criteria The criteria to use.
201      * @exception TorqueException a generic exception.
202      */
203     public static void addSelectColumns(Criteria criteria)
204             throws TorqueException
205     {
206         for (int i = 0; i < columnNames.length; i++)
207         {
208             criteria.addSelectColumn(new StringBuffer()
209                 .append(TABLE_NAME)
210                 .append(".")
211                 .append(columnNames[i]).toString());
212         }
213     }
214 
215     /***
216      *
217      * @param row
218      * @param offset
219      * @param obj
220      * @throws TorqueException
221      */
222     public static void populateObject(Record row, int offset, User obj)
223         throws TorqueException
224     {
225         try
226         {
227             // Set values are where columns are expected.  They are not
228             // required to be in these positions, as we set the positions
229             // immediately following.
230             int idPosition = 1;
231             int objectDataPosition = columnNames.length;
232             for (int i = 0; i < columnNames.length; i++)
233             {
234                 if (columnNames[i].equals(USER_ID_COLUMN))
235                 {
236                     idPosition = i + 1;
237                 }
238                 if (columnNames[i].equals(OBJECT_DATA_COLUMN))
239                 {
240                     objectDataPosition = i + 1;
241                 }
242             }
243 
244             ((Persistent) obj).setPrimaryKey(
245                 new NumberKey(row.getValue(idPosition).asBigDecimal()));
246 
247             // Restore the Permanent Storage Hashtable.  First the
248             // Hashtable is restored, then any explicit table columns
249             // which should be included in the Hashtable are added.
250             byte[] objectData = row.getValue(objectDataPosition).asBytes();
251             Hashtable tempHash = (Hashtable)
252                     ObjectUtils.deserialize(objectData);
253             if (tempHash == null)
254             {
255                 tempHash = new Hashtable(10);
256             }
257 
258             for (int j = 0; j < columnNames.length; j++)
259             {
260                 if (!(columnNames[j].equalsIgnoreCase(USER_ID_COLUMN)
261                         || columnNames[j].equalsIgnoreCase(OBJECT_DATA_COLUMN)))
262                 {
263                     Object obj2 = null;
264                     Value value = row.getValue(j + 1);
265                     if (value.isByte())
266                     {
267                         obj2 = new Byte(value.asByte());
268                     }
269                     if (value.isBigDecimal())
270                     {
271                         obj2 = value.asBigDecimal();
272                     }
273                     if (value.isBytes())
274                     {
275                         obj2 = value.asBytes();
276                     }
277                     if (value.isDate())
278                     {
279                         obj2 = value.asDate();
280                     }
281                     if (value.isShort())
282                     {
283                         obj2 = new Short(value.asShort());
284                     }
285                     if (value.isInt())
286                     {
287                         obj2 = new Integer(value.asInt());
288                     }
289                     if (value.isLong())
290                     {
291                         obj2 = new Long(value.asLong());
292                     }
293                     if (value.isDouble())
294                     {
295                         obj2 = new Double(value.asDouble());
296                     }
297                     if (value.isFloat())
298                     {
299                         obj2 = new Float(value.asFloat());
300                     }
301                     if (value.isBoolean())
302                     {
303                         // JDK 1.3 has no Boolean.valueOf(boolean)
304                         obj2 = new Boolean(value.asBoolean());
305                     }
306                     if (value.isString())
307                     {
308                         obj2 = value.asString();
309                     }
310                     if (value.isTime())
311                     {
312                         obj2 = value.asTime();
313                     }
314                     if (value.isTimestamp())
315                     {
316                         obj2 = value.asTimestamp();
317                     }
318                     if (value.isUtilDate())
319                     {
320                         obj2 = value.asUtilDate();
321                     }
322                     if (obj2 != null)
323                     {
324                         tempHash.put(columnNames[j], obj2);
325                     }
326                 }
327             }
328             obj.setPermStorage(tempHash);
329         }
330         catch (Exception ex)
331         {
332             throw new TorqueException(ex);
333         }
334     }
335 
336     /***
337      * Issues a select based on a criteria.
338      *
339      * @param criteria Object containing data that is used to create
340      *        the SELECT statement.
341      * @return Vector containing TurbineUser objects.
342      * @exception TorqueException a generic exception.
343      */
344     public static List doSelect(Criteria criteria)
345         throws TorqueException
346     {
347         return doSelect(criteria, (User) null);
348     }
349 
350     /***
351      * Issues a select based on a criteria.
352      *
353      * @param criteria Object containing data that is used to create
354      *        the SELECT statement.
355      * @param current User object that is to be used as part of the
356      *        results - if not passed, then a new one is created.
357      * @return Vector containing TurbineUser objects.
358      * @exception TorqueException a generic exception.
359      */
360     public static List doSelect(Criteria criteria, User current)
361         throws TorqueException
362     {
363         // add User table columns
364         addSelectColumns(criteria);
365 
366         if (criteria.getOrderByColumns() == null)
367         {
368             criteria.addAscendingOrderByColumn(LAST_NAME);
369         }
370 
371         // Place any checks here to intercept criteria which require
372         // custom SQL.  For example:
373         // if ( criteria.containsKey("SomeTable.SomeColumn") )
374         // {
375         //     String whereSql = "SomeTable.SomeColumn IN (Select ...";
376         //     criteria.add("SomeTable.SomeColumn",
377         //                  whereSQL, criteria.CUSTOM);
378         // }
379 
380         // BasePeer returns a Vector of Record (Village) objects.  The
381         // array order follows the order columns were placed in the
382         // Select clause.
383         List rows = BasePeer.doSelect(criteria);
384         List results = new ArrayList();
385 
386         // Populate the object(s).
387         for (int i = 0; i < rows.size(); i++)
388         {
389             Record row = (Record) rows.get(i);
390             // Add User to the return Vector.
391             if (current == null)
392             {
393                 results.add(row2Object(row, 1, null));
394             }
395             else
396             {
397                 populateObject(row, 1, current);
398                 ((Persistent) current).setNew(false);
399             }
400         }
401         return results;
402     }
403 
404     /***
405      * Issues a select based on a criteria.
406      *
407      * @param criteria Object containing data that is used to create
408      *        the SELECT statement.
409      * @param dbConn
410      * @return List containing TurbineUser objects.
411      * @exception TorqueException a generic exception.
412      */
413     public static List doSelect(Criteria criteria, Connection dbConn)
414         throws TorqueException
415     {
416         // add User table columns
417         addSelectColumns(criteria);
418 
419         if (criteria.getOrderByColumns() == null)
420         {
421             criteria.addAscendingOrderByColumn(LAST_NAME);
422         }
423 
424         // BasePeer returns a List of Record (Village) objects.  The
425         // array order follows the order columns were placed in the
426         // Select clause.
427         List rows = BasePeer.doSelect(criteria, dbConn);
428         List results = new ArrayList();
429 
430         // Populate the object(s).
431         for (int i = 0; i < rows.size(); i++)
432         {
433             Record row = (Record) rows.get(i);
434             // Add User to the return Vector.
435             results.add(row2Object(row, 1, null));
436         }
437         return results;
438     }
439 
440     /***
441      * Implementss torque peers' method.  Does not use the Class argument
442      * as Users need to go through TurbineSecurity
443      *
444      * @exception TorqueException a generic exception.
445      */
446     public static User row2Object(Record row, int offset, Class cls)
447         throws TorqueException
448     {
449         try
450         {
451             User obj = TurbineSecurity.getUserInstance();
452             populateObject(row, offset, obj);
453             ((Persistent) obj).setNew(false);
454             ((Persistent) obj).setModified(false);
455             return obj;
456         }
457         catch (Exception ex)
458         {
459             throw new TorqueException (ex);
460         }
461     }
462 
463     /***
464      * The type of User this peer will instantiate.
465      *
466      * @exception Exception a generic exception.
467      */
468     public static Class getOMClass() throws Exception
469     {
470         return TurbineSecurity.getUserClass();
471     }
472 
473     /***
474      * Issues an update based on a criteria.
475      * The criteria only uses USER_ID.
476      *
477      * @param criteria Object containing data that is used to create
478      *        the UPDATE statement.
479      * @exception TorqueException a generic exception.
480      */
481     public static void doUpdate(Criteria criteria)
482         throws TorqueException
483     {
484         Criteria selectCriteria = new Criteria(2);
485         selectCriteria.put(USER_ID, criteria.remove(USER_ID));
486         BasePeer.doUpdate(selectCriteria, criteria);
487     }
488 
489     /***
490      * Checks if a User is defined in the system. The name
491      * is used as query criteria.
492      *
493      * @param user The User to be checked.
494      * @return <code>true</code> if given User exists in the system.
495      * @throws DataBackendException when more than one User with
496      *         the same name exists.
497      * @throws Exception a generic exception.
498      */
499     public static boolean checkExists(User user)
500         throws DataBackendException, Exception
501     {
502         Criteria criteria = new Criteria();
503         criteria.addSelectColumn(USER_ID);
504         criteria.add(USERNAME, user.getName());
505         List results = BasePeer.doSelect(criteria);
506         if (results.size() > 1)
507         {
508             throw new DataBackendException("Multiple users named '"
509                     + user.getName() + "' exist!");
510         }
511         return (results.size() == 1);
512     }
513 
514     /***
515      * Returns a vector of all User objects.
516      *
517      * @return A Vector with all users in the system.
518      * @exception Exception a generic exception.
519      */
520     public static List selectAllUsers()
521         throws Exception
522     {
523         Criteria criteria = new Criteria();
524         criteria.addAscendingOrderByColumn(TurbineUserPeer.LAST_NAME);
525         criteria.addAscendingOrderByColumn(TurbineUserPeer.FIRST_NAME);
526         criteria.setIgnoreCase(true);
527         return TurbineUserPeer.doSelect(criteria);
528     }
529 
530     /***
531      * Returns a vector of all confirmed User objects.
532      *
533      * @return A Vector with all confirmed users in the system.
534      * @exception Exception a generic exception.
535      */
536     public static List selectAllConfirmedUsers()
537         throws Exception
538     {
539         Criteria criteria = new Criteria();
540         criteria.add(User.CONFIRM_VALUE, User.CONFIRM_DATA);
541         criteria.addAscendingOrderByColumn(TurbineUserPeer.LAST_NAME);
542         criteria.addAscendingOrderByColumn(TurbineUserPeer.FIRST_NAME);
543         criteria.setIgnoreCase(true);
544         return TurbineUserPeer.doSelect(criteria);
545     }
546 
547     /***
548      * Returns the TableMap related to this peer.  This method is not
549      * needed for general use but a specific application could have a
550      * need.
551      */
552     protected static TableMap getTableMap()
553     {
554         return MAP_BUILDER.getDatabaseMap().getTable(TABLE_NAME);
555     }
556 }