View Javadoc

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