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