001: package org.apache.turbine.services.security.torque;
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.beans.PropertyDescriptor;
023:
024: import java.util.ArrayList;
025: import java.util.Iterator;
026: import java.util.List;
027:
028: import org.apache.commons.configuration.Configuration;
029:
030: import org.apache.commons.logging.Log;
031: import org.apache.commons.logging.LogFactory;
032:
033: import org.apache.turbine.om.security.Group;
034: import org.apache.turbine.om.security.Role;
035: import org.apache.turbine.om.security.User;
036: import org.apache.turbine.services.InitializationException;
037: import org.apache.turbine.services.security.TurbineSecurity;
038: import org.apache.turbine.services.security.torque.om.TurbineUserGroupRolePeer;
039: import org.apache.turbine.util.security.DataBackendException;
040: import org.apache.turbine.util.security.RoleSet;
041:
042: import org.apache.torque.TorqueException;
043: import org.apache.torque.om.Persistent;
044: import org.apache.torque.util.BasePeer;
045: import org.apache.torque.util.Criteria;
046:
047: /**
048: * This class capsulates all direct Peer access for the Role entities.
049: * It allows the exchange of the default Turbine supplied TurbineRolePeer
050: * class against a custom class
051: *
052: * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
053: * @version $Id: RolePeerManager.java 534527 2007-05-02 16:10:59Z tv $
054: */
055:
056: public class RolePeerManager implements RolePeerManagerConstants {
057: /** The class of the Peer the TorqueSecurityService uses */
058: private static Class rolePeerClass = null;
059:
060: /** The class name of the objects returned by the configured peer. */
061: private static Class roleObject = null;
062:
063: /** The name of the Table used for Role Object queries */
064: private static String tableName = null;
065:
066: /** The name of the column used as "Name" Column */
067: private static String nameColumn = null;
068:
069: /** The name of the column used as "Id" Column */
070: private static String idColumn = null;
071:
072: /** The "Name" property descriptor */
073: private static PropertyDescriptor namePropDesc = null;
074:
075: /** The "Id" property descriptor */
076: private static PropertyDescriptor idPropDesc = null;
077:
078: /** Logging */
079: static Log log = LogFactory.getLog(RolePeerManager.class);
080:
081: /**
082: * Initializes the RolePeerManager, loading the class object for the
083: * Peer used to retrieve Role objects
084: *
085: * @param conf The configuration object used to configure the Manager
086: *
087: * @exception InitializationException A problem occured during
088: * initialization
089: */
090:
091: public static void init(Configuration conf)
092: throws InitializationException {
093: String rolePeerClassName = conf.getString(ROLE_PEER_CLASS_KEY,
094: ROLE_PEER_CLASS_DEFAULT);
095:
096: String roleObjectName = null;
097:
098: try {
099: rolePeerClass = Class.forName(rolePeerClassName);
100:
101: tableName = (String) rolePeerClass.getField("TABLE_NAME")
102: .get(null);
103:
104: //
105: // We have either an user configured Object class or we use the
106: // default as supplied by the Peer class
107: //
108:
109: // Default from Peer, can be overridden
110:
111: roleObject = getPersistenceClass();
112:
113: roleObjectName = conf.getString(ROLE_CLASS_KEY, roleObject
114: .getName());
115:
116: // Maybe the user set a new value...
117: roleObject = Class.forName(roleObjectName);
118:
119: /* If any of the following Field queries fails, the role
120: * subsystem is unusable. So check this right here at init time,
121: * which saves us much time and hassle if it fails...
122: */
123:
124: nameColumn = (String) rolePeerClass.getField(
125: conf.getString(ROLE_NAME_COLUMN_KEY,
126: ROLE_NAME_COLUMN_DEFAULT)).get(null);
127:
128: idColumn = (String) rolePeerClass.getField(
129: conf.getString(ROLE_ID_COLUMN_KEY,
130: ROLE_ID_COLUMN_DEFAULT)).get(null);
131:
132: namePropDesc = new PropertyDescriptor(
133: conf.getString(ROLE_NAME_PROPERTY_KEY,
134: ROLE_NAME_PROPERTY_DEFAULT), roleObject);
135:
136: idPropDesc = new PropertyDescriptor(conf.getString(
137: ROLE_ID_PROPERTY_KEY, ROLE_ID_PROPERTY_DEFAULT),
138: roleObject);
139:
140: } catch (Exception e) {
141: if (rolePeerClassName == null || rolePeerClass == null) {
142: throw new InitializationException(
143: "Could not find RolePeer class ("
144: + rolePeerClassName + ")", e);
145: }
146: if (tableName == null) {
147: throw new InitializationException(
148: "Failed to get the table name from the Peer object",
149: e);
150: }
151:
152: if (roleObject == null || roleObjectName == null) {
153: throw new InitializationException(
154: "Failed to get the object type from the Peer object",
155: e);
156: }
157:
158: if (nameColumn == null || namePropDesc == null) {
159: throw new InitializationException("RolePeer "
160: + rolePeerClassName
161: + " has no name column information!", e);
162: }
163: if (idColumn == null || idPropDesc == null) {
164: throw new InitializationException("RolePeer "
165: + rolePeerClassName
166: + " has no id column information!", e);
167: }
168: }
169: }
170:
171: /**
172: * Get the name of this table.
173: *
174: * @return A String with the name of the table.
175: */
176: public static String getTableName() {
177: return tableName;
178: }
179:
180: /**
181: * Returns the fully qualified name of the Column to
182: * use as the Name Column for a role
183: *
184: * @return A String containing the column name
185: */
186: public static String getNameColumn() {
187: return nameColumn;
188: }
189:
190: /**
191: * Returns the fully qualified name of the Column to
192: * use as the Id Column for a role
193: *
194: * @return A String containing the column id
195: */
196: public static String getIdColumn() {
197: return idColumn;
198: }
199:
200: /**
201: * Returns the full name of a column.
202: *
203: * @param name The column to fully qualify
204: *
205: * @return A String with the full name of the column.
206: */
207: public static String getColumnName(String name) {
208: StringBuffer sb = new StringBuffer();
209: sb.append(getTableName());
210: sb.append(".");
211: sb.append(name);
212: return sb.toString();
213: }
214:
215: /**
216: * Returns a new, empty object for the underlying peer.
217: * Used to create a new underlying object
218: *
219: * @return A new object which is compatible to the Peer
220: * and can be used as a User object
221: *
222: */
223:
224: public static Persistent newPersistentInstance() {
225: Persistent obj = null;
226:
227: if (roleObject == null) {
228: // This can happen if the Turbine wants to determine the
229: // name of the anonymous user before the security service
230: // has been initialized. In this case, the Peer Manager
231: // has not yet been inited and the roleObject is still
232: // null. Return null in this case.
233: //
234: return obj;
235: }
236:
237: try {
238: obj = (Persistent) roleObject.newInstance();
239: } catch (Exception e) {
240: log.error("Could not instantiate a role object", e);
241: obj = null;
242: }
243: return obj;
244: }
245:
246: /**
247: * Retrieves/assembles a RoleSet based on the Criteria passed in
248: *
249: * @param criteria A criteria containing a pre-assembled set of criterias
250: * for the RoleSet
251: *
252: * @return A Set of roles which fulfil the required criterias
253: *
254: * @exception Exception A generic exception.
255: *
256: */
257: public static RoleSet retrieveSet(Criteria criteria)
258: throws Exception {
259: List results = doSelect(criteria);
260: RoleSet rs = new RoleSet();
261:
262: for (Iterator it = results.iterator(); it.hasNext();) {
263: rs.add((Role) it.next());
264: }
265: return rs;
266: }
267:
268: /**
269: * Retrieves a set of Roles that an User was assigned in a Group
270: *
271: * @param user An user object
272: * @param group A group object
273: *
274: * @return A Set of Roles of this User in the Group
275: *
276: * @exception Exception A generic exception.
277: */
278: public static RoleSet retrieveSet(User user, Group group)
279: throws Exception {
280: Criteria criteria = new Criteria();
281:
282: criteria.add(UserPeerManager.getNameColumn(), user.getName());
283:
284: criteria.add(TurbineUserGroupRolePeer.GROUP_ID,
285: ((Persistent) group).getPrimaryKey());
286:
287: criteria.addJoin(UserPeerManager.getIdColumn(),
288: TurbineUserGroupRolePeer.USER_ID);
289:
290: criteria.addJoin(TurbineUserGroupRolePeer.ROLE_ID,
291: getIdColumn());
292:
293: return retrieveSet(criteria);
294: }
295:
296: /**
297: * Checks if a Role is defined in the system. The name
298: * is used as query criteria.
299: *
300: * @param role The Role to be checked.
301: * @return <code>true</code> if given Role exists in the system.
302: * @throws DataBackendException when more than one Role with
303: * the same name exists.
304: * @throws Exception A generic exception.
305: */
306: public static boolean checkExists(Role role)
307: throws DataBackendException, Exception {
308: Criteria criteria = new Criteria();
309:
310: criteria.addSelectColumn(getIdColumn());
311:
312: criteria.add(getNameColumn(), role.getName());
313:
314: List results = BasePeer.doSelect(criteria);
315:
316: if (results.size() > 1) {
317: throw new DataBackendException("Multiple roles named '"
318: + role.getName() + "' exist!");
319: }
320: return (results.size() == 1);
321: }
322:
323: /*
324: * ========================================================================
325: *
326: * WARNING! Do not read on if you have a weak stomach. What follows here
327: * are some abominations thanks to the braindead static peers of Torque
328: * and the rigidity of Java....
329: *
330: * ========================================================================
331: *
332: */
333:
334: /**
335: * Calls buildCriteria(Role role) in the configured RolePeer. If you get
336: * a ClassCastException in this routine, you put a Role object into this
337: * method which can't be cast into an object for the TorqueSecurityService. This is a
338: * configuration error most of the time.
339: *
340: * @param role An object which implements the Role interface
341: *
342: * @return A criteria for the supplied role object
343: */
344:
345: public static Criteria buildCriteria(Role role) {
346: Criteria crit;
347:
348: try {
349: Class[] clazz = new Class[] { roleObject };
350: Object[] params = new Object[] { ((TorqueRole) role)
351: .getPersistentObj() };
352:
353: crit = (Criteria) rolePeerClass.getMethod("buildCriteria",
354: clazz).invoke(null, params);
355: } catch (Exception e) {
356: crit = null;
357: }
358:
359: return crit;
360: }
361:
362: /**
363: * Invokes doUpdate(Criteria c) on the configured Peer Object
364: *
365: * @param criteria A Criteria Object
366: *
367: * @exception TorqueException A problem occured.
368: */
369:
370: public static void doUpdate(Criteria criteria)
371: throws TorqueException {
372: try {
373: Class[] clazz = new Class[] { Criteria.class };
374: Object[] params = new Object[] { criteria };
375:
376: rolePeerClass.getMethod("doUpdate", clazz).invoke(null,
377: params);
378: } catch (Exception e) {
379: throw new TorqueException("doUpdate failed", e);
380: }
381: }
382:
383: /**
384: * Invokes doInsert(Criteria c) on the configured Peer Object
385: *
386: * @param criteria A Criteria Object
387: *
388: * @exception TorqueException A problem occured.
389: */
390:
391: public static void doInsert(Criteria criteria)
392: throws TorqueException {
393: try {
394: Class[] clazz = new Class[] { Criteria.class };
395: Object[] params = new Object[] { criteria };
396:
397: rolePeerClass.getMethod("doInsert", clazz).invoke(null,
398: params);
399: } catch (Exception e) {
400: throw new TorqueException("doInsert failed", e);
401: }
402: }
403:
404: /**
405: * Invokes doSelect(Criteria c) on the configured Peer Object
406: *
407: * @param criteria A Criteria Object
408: *
409: * @return A List of Role Objects selected by the Criteria
410: *
411: * @exception TorqueException A problem occured.
412: */
413: public static List doSelect(Criteria criteria)
414: throws TorqueException {
415: List list;
416:
417: try {
418: Class[] clazz = new Class[] { Criteria.class };
419: Object[] params = new Object[] { criteria };
420:
421: list = (List) rolePeerClass.getMethod("doSelect", clazz)
422: .invoke(null, params);
423: } catch (Exception e) {
424: throw new TorqueException("doSelect failed", e);
425: }
426: List newList = new ArrayList(list.size());
427:
428: //
429: // Wrap the returned Objects into TorqueRoles.
430: //
431: for (Iterator it = list.iterator(); it.hasNext();) {
432: Role r = getNewRole((Persistent) it.next());
433: newList.add(r);
434: }
435:
436: return newList;
437: }
438:
439: /**
440: * Invokes doDelete(Criteria c) on the configured Peer Object
441: *
442: * @param criteria A Criteria Object
443: *
444: * @exception TorqueException A problem occured.
445: */
446: public static void doDelete(Criteria criteria)
447: throws TorqueException {
448: try {
449: Class[] clazz = new Class[] { Criteria.class };
450: Object[] params = new Object[] { criteria };
451:
452: rolePeerClass.getMethod("doDelete", clazz).invoke(null,
453: params);
454: } catch (Exception e) {
455: throw new TorqueException("doDelete failed", e);
456: }
457: }
458:
459: /**
460: * Invokes setName(String s) on the supplied base object
461: *
462: * @param obj The object to use for setting the name
463: * @param name The Name to set
464: *
465: */
466: public static void setRoleName(Persistent obj, String name) {
467: if (obj == null) {
468: return;
469: }
470:
471: try {
472: Object[] params = new Object[] { name };
473: namePropDesc.getWriteMethod().invoke(obj, params);
474: } catch (ClassCastException cce) {
475: String msg = obj.getClass().getName()
476: + " does not seem to be a Role Object!";
477: log.error(msg);
478: throw new RuntimeException(msg);
479: } catch (Exception e) {
480: log.error(e, e);
481: }
482: }
483:
484: /**
485: * Invokes getName() on the supplied base object
486: *
487: * @param obj The object to use for getting the name
488: *
489: * @return A string containing the name
490: */
491: public static String getRoleName(Persistent obj) {
492: String name = null;
493:
494: if (obj == null) {
495: return null;
496: }
497:
498: try {
499: name = (String) namePropDesc.getReadMethod().invoke(obj,
500: new Object[] {});
501: } catch (ClassCastException cce) {
502: String msg = obj.getClass().getName()
503: + " does not seem to be a Role Object!";
504: log.error(msg);
505: throw new RuntimeException(msg);
506: } catch (Exception e) {
507: log.error(e, e);
508: }
509: return name;
510: }
511:
512: /**
513: * Invokes setId(int n) on the supplied base object
514: *
515: * @param obj The object to use for setting the name
516: * @param id The new Id
517: */
518: public static void setId(Persistent obj, int id) {
519: if (obj == null) {
520: return;
521: }
522:
523: try {
524: Object[] params = new Object[] { Integer.TYPE };
525: idPropDesc.getWriteMethod().invoke(obj, params);
526: } catch (ClassCastException cce) {
527: String msg = obj.getClass().getName()
528: + " does not seem to be a Role Object!";
529: log.error(msg);
530: throw new RuntimeException(msg);
531: } catch (Exception e) {
532: log.error(e, e);
533: }
534: }
535:
536: /**
537: * Invokes getId() on the supplied base object
538: *
539: * @param obj The object to use for getting the id
540: *
541: * @return The Id of this object
542: */
543: public static Integer getIdAsObj(Persistent obj) {
544: Integer id = null;
545:
546: if (obj == null) {
547: return new Integer(0);
548: }
549:
550: try {
551: id = (Integer) idPropDesc.getReadMethod().invoke(obj,
552: new Object[] {});
553: } catch (ClassCastException cce) {
554: String msg = obj.getClass().getName()
555: + " does not seem to be a Role Object!";
556: log.error(msg);
557: throw new RuntimeException(msg);
558: } catch (Exception e) {
559: log.error(e, e);
560: }
561: return id;
562: }
563:
564: /**
565: * Returns the Class of the configured Object class
566: * from the peer
567: *
568: * @return The class of the objects returned by the configured peer
569: */
570:
571: private static Class getPersistenceClass() {
572: Class persistenceClass = null;
573:
574: try {
575: Object[] params = new Object[0];
576:
577: persistenceClass = (Class) rolePeerClass.getMethod(
578: "getOMClass", (Class[]) null).invoke(null, params);
579: } catch (Exception e) {
580: persistenceClass = null;
581: }
582:
583: return persistenceClass;
584: }
585:
586: /**
587: * Returns a new, configured Role Object with
588: * a supplied Persistent object at its core
589: *
590: * @param p The persistent object
591: *
592: * @return a new, configured Role Object
593: *
594: * @exception Exception Could not create a new Object
595: *
596: */
597:
598: public static Role getNewRole(Persistent p) {
599: Role r = null;
600: try {
601: Class roleWrapperClass = TurbineSecurity.getRoleClass();
602:
603: Class[] clazz = new Class[] { Persistent.class };
604: Object[] params = new Object[] { p };
605:
606: r = (Role) roleWrapperClass.getConstructor(clazz)
607: .newInstance(params);
608: } catch (Exception e) {
609: log
610: .error(
611: "Could not instantiate a new role from supplied persistent: ",
612: e);
613: }
614:
615: return r;
616: }
617: }
|