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