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