View Javadoc

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