001: package org.apache.turbine.om.security.peer;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.sql.Connection;
023: import java.util.ArrayList;
024: import java.util.Hashtable;
025: import java.util.List;
026:
027: import org.apache.torque.Torque;
028: import org.apache.torque.TorqueException;
029: import org.apache.torque.map.TableMap;
030: import org.apache.torque.om.NumberKey;
031: import org.apache.torque.om.Persistent;
032: import org.apache.torque.util.BasePeer;
033: import org.apache.torque.util.Criteria;
034: import org.apache.turbine.om.security.User;
035: import org.apache.turbine.services.security.TurbineSecurity;
036: import org.apache.turbine.util.ObjectUtils;
037: import org.apache.turbine.util.db.map.TurbineMapBuilder;
038: import org.apache.turbine.util.security.DataBackendException;
039:
040: import com.workingdogs.village.Column;
041: import com.workingdogs.village.Record;
042: import com.workingdogs.village.Schema;
043: import com.workingdogs.village.Value;
044:
045: /**
046: * This class handles all the database access for the User/User
047: * table. This table contains all the information for a given user.
048: *
049: * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
050: * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a>
051: * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
052: *
053: * @deprecated Use {@link org.apache.turbine.services.security.torque.TorqueSecurityService}
054: * instead.
055: *
056: * @version $Id: TurbineUserPeer.java 571795 2007-09-01 13:09:35Z tv $
057: */
058: public class TurbineUserPeer extends BasePeer implements UserPeer {
059: /** Serial Version UID */
060: private static final long serialVersionUID = -5981268145973167352L;
061:
062: /** The mapBuilder for this Peer. */
063: private static final TurbineMapBuilder MAP_BUILDER;
064:
065: // column names
066: /** The column name for the visitor id field. */
067: private static final String USER_ID_COLUMN;
068:
069: /** This is the value that is stored in the database for confirmed users. */
070: public static final String CONFIRM_DATA;
071:
072: /** The column name for the visitor id field. */
073: private static final String OBJECT_DATA_COLUMN;
074:
075: /** The table name for this peer. */
076: private static final String TABLE_NAME;
077:
078: // Criteria Keys
079: /** The key name for the visitor id field. */
080: public static final String USER_ID;
081:
082: /** The key name for the username field. */
083: public static final String USERNAME;
084:
085: /** The key name for the password field. */
086: public static final String PASSWORD;
087:
088: /** The key name for the first name field. */
089: public static final String FIRST_NAME;
090:
091: /** The key name for the last name field. */
092: public static final String LAST_NAME;
093:
094: /** The key name for the modified field. */
095: public static final String MODIFIED;
096:
097: /** The key name for the created field. */
098: public static final String CREATED;
099:
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: try {
126: MAP_BUILDER = (TurbineMapBuilder) Torque
127: .getMapBuilder(TurbineMapBuilder.class.getName());
128: } catch (TorqueException e) {
129: log.error("Could not initialize Peer", e);
130: throw new RuntimeException(e);
131: }
132:
133: USER_ID_COLUMN = MAP_BUILDER.getUserId();
134: CONFIRM_DATA = org.apache.turbine.om.security.User.CONFIRM_DATA;
135: OBJECT_DATA_COLUMN = MAP_BUILDER.getObjectData();
136: TABLE_NAME = MAP_BUILDER.getTableUser();
137:
138: USER_ID = MAP_BUILDER.getUser_UserId();
139: USERNAME = MAP_BUILDER.getUser_Username();
140: PASSWORD = MAP_BUILDER.getUser_Password();
141: FIRST_NAME = MAP_BUILDER.getUser_FirstName();
142: LAST_NAME = MAP_BUILDER.getUser_LastName();
143: MODIFIED = MAP_BUILDER.getUser_Modified();
144: CREATED = MAP_BUILDER.getUser_Created();
145: EMAIL = MAP_BUILDER.getUser_Email();
146: LAST_LOGIN = MAP_BUILDER.getUser_LastLogin();
147: CONFIRM_VALUE = MAP_BUILDER.getUser_ConfirmValue();
148: OBJECT_DATA = MAP_BUILDER.getUser_ObjectData();
149:
150: schema = initTableSchema(TABLE_NAME);
151: columns = initTableColumns(schema);
152: columnNames = initColumnNames(columns);
153: criteriaKeys = initCriteriaKeys(TABLE_NAME, columnNames);
154: }
155:
156: /**
157: * Get the name of this table.
158: *
159: * @return A String with the name of the table.
160: */
161: public static String getTableName() {
162: return TABLE_NAME;
163: }
164:
165: /**
166: * Returns the full name of a column.
167: *
168: * @param name name of a column
169: * @return A String with the full name of the column.
170: */
171: public static String getColumnName(String name) {
172: StringBuffer sb = new StringBuffer();
173: sb.append(TABLE_NAME);
174: sb.append(".");
175: sb.append(name);
176: return sb.toString();
177: }
178:
179: /**
180: *
181: * Returns the full name of a column.
182: *
183: * @param name name of a column
184: * @return A String with the full name of the column.
185: */
186: public String getFullColumnName(String name) {
187: StringBuffer sb = new StringBuffer();
188: sb.append(TABLE_NAME);
189: sb.append(".");
190: sb.append(name);
191: return sb.toString();
192: }
193:
194: /**
195: * Builds a criteria object based upon an User object. Data
196: * stored in the permData table which a key matching a column
197: * name is removed from the permData table and added as a criterion.
198: * All remaining data in the permData table is serialized and
199: * added as a criterion for the OBJECT_DATA column.
200: *
201: * @param user object to build the criteria
202: * @return the Criteria
203: */
204: public static Criteria buildCriteria(User user) {
205: Hashtable permData = (Hashtable) user.getPermStorage().clone();
206: Criteria criteria = new Criteria();
207: if (!((Persistent) user).isNew()) {
208: criteria.add(USER_ID, ((Persistent) user).getPrimaryKey());
209: }
210:
211: for (int i = 1; i < TurbineUserPeer.columnNames.length; i++) {
212: if (permData.containsKey(TurbineUserPeer.columnNames[i])) {
213: criteria.add(TurbineUserPeer.criteriaKeys[i], permData
214: .remove(TurbineUserPeer.columnNames[i]));
215: }
216: }
217: criteria.add(TurbineUserPeer.OBJECT_DATA, permData);
218: return criteria;
219: }
220:
221: /**
222: * Add all the columns needed to create a new object
223: *
224: * @param criteria The criteria to use.
225: * @exception TorqueException a generic exception.
226: */
227: public static void addSelectColumns(Criteria criteria)
228: throws TorqueException {
229: for (int i = 0; i < columnNames.length; i++) {
230: criteria.addSelectColumn(new StringBuffer().append(
231: TABLE_NAME).append(".").append(columnNames[i])
232: .toString());
233: }
234: }
235:
236: /**
237: *
238: * @param row
239: * @param offset
240: * @param obj
241: * @throws TorqueException
242: */
243: public static void populateObject(Record row, int offset, User obj)
244: throws TorqueException {
245: try {
246: // Set values are where columns are expected. They are not
247: // required to be in these positions, as we set the positions
248: // immediately following.
249: int idPosition = 1;
250: int objectDataPosition = columnNames.length;
251: for (int i = 0; i < columnNames.length; i++) {
252: if (columnNames[i].equals(USER_ID_COLUMN)) {
253: idPosition = i + 1;
254: }
255: if (columnNames[i].equals(OBJECT_DATA_COLUMN)) {
256: objectDataPosition = i + 1;
257: }
258: }
259:
260: ((Persistent) obj).setPrimaryKey(new NumberKey(row
261: .getValue(idPosition).asBigDecimal()));
262:
263: // Restore the Permanent Storage Hashtable. First the
264: // Hashtable is restored, then any explicit table columns
265: // which should be included in the Hashtable are added.
266: byte[] objectData = row.getValue(objectDataPosition)
267: .asBytes();
268: Hashtable tempHash = (Hashtable) ObjectUtils
269: .deserialize(objectData);
270: if (tempHash == null) {
271: tempHash = new Hashtable(10);
272: }
273:
274: for (int j = 0; j < columnNames.length; j++) {
275: if (!(columnNames[j].equalsIgnoreCase(USER_ID_COLUMN) || columnNames[j]
276: .equalsIgnoreCase(OBJECT_DATA_COLUMN))) {
277: Object obj2 = null;
278: Value value = row.getValue(j + 1);
279: if (value.isByte()) {
280: obj2 = new Byte(value.asByte());
281: }
282: if (value.isBigDecimal()) {
283: obj2 = value.asBigDecimal();
284: }
285: if (value.isBytes()) {
286: obj2 = value.asBytes();
287: }
288: if (value.isDate()) {
289: obj2 = value.asDate();
290: }
291: if (value.isShort()) {
292: obj2 = new Short(value.asShort());
293: }
294: if (value.isInt()) {
295: obj2 = new Integer(value.asInt());
296: }
297: if (value.isLong()) {
298: obj2 = new Long(value.asLong());
299: }
300: if (value.isDouble()) {
301: obj2 = new Double(value.asDouble());
302: }
303: if (value.isFloat()) {
304: obj2 = new Float(value.asFloat());
305: }
306: if (value.isBoolean()) {
307: // JDK 1.3 has no Boolean.valueOf(boolean)
308: obj2 = new Boolean(value.asBoolean());
309: }
310: if (value.isString()) {
311: obj2 = value.asString();
312: }
313: if (value.isTime()) {
314: obj2 = value.asTime();
315: }
316: if (value.isTimestamp()) {
317: obj2 = value.asTimestamp();
318: }
319: if (value.isUtilDate()) {
320: obj2 = value.asUtilDate();
321: }
322: if (obj2 != null) {
323: tempHash.put(columnNames[j], obj2);
324: }
325: }
326: }
327: obj.setPermStorage(tempHash);
328: } catch (Exception ex) {
329: throw new TorqueException(ex);
330: }
331: }
332:
333: /**
334: * Issues a select based on a criteria.
335: *
336: * @param criteria Object containing data that is used to create
337: * the SELECT statement.
338: * @return Vector containing TurbineUser objects.
339: * @exception TorqueException a generic exception.
340: */
341: public static List doSelect(Criteria criteria)
342: throws TorqueException {
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: // add User table columns
359: addSelectColumns(criteria);
360:
361: if (criteria.getOrderByColumns() == null) {
362: criteria.addAscendingOrderByColumn(LAST_NAME);
363: }
364:
365: // Place any checks here to intercept criteria which require
366: // custom SQL. For example:
367: // if ( criteria.containsKey("SomeTable.SomeColumn") )
368: // {
369: // String whereSql = "SomeTable.SomeColumn IN (Select ...";
370: // criteria.add("SomeTable.SomeColumn",
371: // whereSQL, criteria.CUSTOM);
372: // }
373:
374: // BasePeer returns a Vector of Record (Village) objects. The
375: // array order follows the order columns were placed in the
376: // Select clause.
377: List rows = BasePeer.doSelect(criteria);
378: List results = new ArrayList();
379:
380: // Populate the object(s).
381: for (int i = 0; i < rows.size(); i++) {
382: Record row = (Record) rows.get(i);
383: // Add User to the return Vector.
384: if (current == null) {
385: results.add(row2Object(row, 1, null));
386: } else {
387: populateObject(row, 1, current);
388: ((Persistent) current).setNew(false);
389: }
390: }
391: return results;
392: }
393:
394: /**
395: * Issues a select based on a criteria.
396: *
397: * @param criteria Object containing data that is used to create
398: * the SELECT statement.
399: * @param dbConn
400: * @return List containing TurbineUser objects.
401: * @exception TorqueException a generic exception.
402: */
403: public static List doSelect(Criteria criteria, Connection dbConn)
404: throws TorqueException {
405: // add User table columns
406: addSelectColumns(criteria);
407:
408: if (criteria.getOrderByColumns() == null) {
409: criteria.addAscendingOrderByColumn(LAST_NAME);
410: }
411:
412: // BasePeer returns a List of Record (Village) objects. The
413: // array order follows the order columns were placed in the
414: // Select clause.
415: List rows = BasePeer.doSelect(criteria, dbConn);
416: List results = new ArrayList();
417:
418: // Populate the object(s).
419: for (int i = 0; i < rows.size(); i++) {
420: Record row = (Record) rows.get(i);
421: // Add User to the return Vector.
422: results.add(row2Object(row, 1, null));
423: }
424: return results;
425: }
426:
427: /**
428: * Implementss torque peers' method. Does not use the Class argument
429: * as Users need to go through TurbineSecurity
430: *
431: * @exception TorqueException a generic exception.
432: */
433: public static User row2Object(Record row, int offset, Class cls)
434: throws TorqueException {
435: try {
436: User obj = TurbineSecurity.getUserInstance();
437: populateObject(row, offset, obj);
438: ((Persistent) obj).setNew(false);
439: ((Persistent) obj).setModified(false);
440: return obj;
441: } catch (Exception ex) {
442: throw new TorqueException(ex);
443: }
444: }
445:
446: /**
447: * The type of User this peer will instantiate.
448: *
449: * @exception Exception a generic exception.
450: */
451: public static Class getOMClass() throws Exception {
452: return TurbineSecurity.getUserClass();
453: }
454:
455: /**
456: * Issues an update based on a criteria.
457: * The criteria only uses USER_ID.
458: *
459: * @param criteria Object containing data that is used to create
460: * the UPDATE statement.
461: * @exception TorqueException a generic exception.
462: */
463: public static void doUpdate(Criteria criteria)
464: throws TorqueException {
465: Criteria selectCriteria = new Criteria(2);
466: selectCriteria.put(USER_ID, criteria.remove(USER_ID));
467: BasePeer.doUpdate(selectCriteria, criteria);
468: }
469:
470: /**
471: * Checks if a User is defined in the system. The name
472: * is used as query criteria.
473: *
474: * @param user The User to be checked.
475: * @return <code>true</code> if given User exists in the system.
476: * @throws DataBackendException when more than one User with
477: * the same name exists.
478: * @throws Exception a generic exception.
479: */
480: public static boolean checkExists(User user)
481: throws DataBackendException, Exception {
482: Criteria criteria = new Criteria();
483: criteria.addSelectColumn(USER_ID);
484: criteria.add(USERNAME, user.getName());
485: List results = BasePeer.doSelect(criteria);
486: if (results.size() > 1) {
487: throw new DataBackendException("Multiple users named '"
488: + user.getName() + "' exist!");
489: }
490: return (results.size() == 1);
491: }
492:
493: /**
494: * Returns a vector of all User objects.
495: *
496: * @return A Vector with all users in the system.
497: * @exception Exception a generic exception.
498: */
499: public static List selectAllUsers() throws Exception {
500: Criteria criteria = new Criteria();
501: criteria.addAscendingOrderByColumn(TurbineUserPeer.LAST_NAME);
502: criteria.addAscendingOrderByColumn(TurbineUserPeer.FIRST_NAME);
503: criteria.setIgnoreCase(true);
504: return TurbineUserPeer.doSelect(criteria);
505: }
506:
507: /**
508: * Returns a vector of all confirmed User objects.
509: *
510: * @return A Vector with all confirmed users in the system.
511: * @exception Exception a generic exception.
512: */
513: public static List selectAllConfirmedUsers() throws Exception {
514: Criteria criteria = new Criteria();
515: criteria.add(User.CONFIRM_VALUE, User.CONFIRM_DATA);
516: criteria.addAscendingOrderByColumn(TurbineUserPeer.LAST_NAME);
517: criteria.addAscendingOrderByColumn(TurbineUserPeer.FIRST_NAME);
518: criteria.setIgnoreCase(true);
519: return TurbineUserPeer.doSelect(criteria);
520: }
521:
522: /**
523: * Returns the TableMap related to this peer. This method is not
524: * needed for general use but a specific application could have a
525: * need.
526: */
527: protected static TableMap getTableMap() {
528: return MAP_BUILDER.getDatabaseMap().getTable(TABLE_NAME);
529: }
530: }
|