001: /*
002: * CoadunationLib: The coaduntion implementation library.
003: * Copyright (C) 2006 Rift IT Contracting
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
018: *
019: * RoleManager.java
020: *
021: * The role manager, responsible for managing all the role information used
022: * in coadunation.
023: */
024:
025: // the package name
026: package com.rift.coad.lib.security;
027:
028: // java import
029: import java.util.ArrayList;
030: import java.util.List;
031: import java.util.Map;
032: import java.util.HashMap;
033: import java.util.HashSet;
034: import java.util.Set;
035: import java.util.StringTokenizer;
036: import java.util.Iterator;
037:
038: // log 4 j imports
039: import org.apache.log4j.Logger;
040:
041: // coadunation imports
042: import com.rift.coad.lib.configuration.ConfigurationFactory;
043: import com.rift.coad.lib.configuration.Configuration;
044: import com.rift.coad.lib.deployment.DeploymentMonitor;
045: import com.rift.coad.lib.thread.ThreadStateMonitor;
046:
047: /**
048: * The role manager, responsible for managing all the role information used
049: * in coadunation.
050: *
051: * @author Brett Chaldecott
052: */
053: public class RoleManager {
054:
055: /**
056: * This thread is responsible for running in the back ground and managing
057: * the loading of roles. It is self terminating based on the status of the
058: * deployment loader.
059: */
060: public class RoleLoaderThread extends Thread {
061:
062: // the thread state monitor
063: private ThreadStateMonitor stateMonitor = new ThreadStateMonitor(
064: 60000);
065:
066: /**
067: * The constructor of the roler loader thread.
068: */
069: public RoleLoaderThread() {
070:
071: }
072:
073: /**
074: * The run method for the role loader thread.
075: */
076: public void run() {
077: while (!stateMonitor.isTerminated()) {
078: stateMonitor.monitor();
079: if (!stateMonitor.isTerminated()) {
080: try {
081: loadRoles();
082: } catch (Throwable ex) {
083: log.error("Failed to load the roles : "
084: + ex.getMessage(), ex);
085: }
086: }
087: }
088: }
089:
090: /**
091: * This method is called to terminate the role loader thread
092: */
093: public void terminate() {
094: if (DeploymentMonitor.getInstance().isTerminated()) {
095: stateMonitor.terminate(true);
096: }
097: }
098: }
099:
100: // the classes constant static variables
101: private static final String ROLE_HANDLERS = "role_handlers";
102:
103: // The role manager logger
104: protected static Logger log = Logger.getLogger(RoleManager.class
105: .getName());
106:
107: // the class imports
108: private static RoleManager singleton = null;
109: private List roleHandlers = null;
110: private Map roles = null;
111: private RoleLoaderThread roleLoaderThread = null;
112:
113: /**
114: * Creates a new instance of the RoleManager.
115: *
116: * @exception SecurityException
117: */
118: private RoleManager() throws SecurityException {
119: roleHandlers = new ArrayList();
120: roles = new HashMap();
121:
122: try {
123: Configuration config = ConfigurationFactory.getInstance()
124: .getConfig(RoleManager.class);
125: StringTokenizer roleHandlerList = new StringTokenizer(
126: config.getString(ROLE_HANDLERS), ",");
127: while (roleHandlerList.hasMoreTokens()) {
128: roleHandlers.add(Class.forName(
129: roleHandlerList.nextToken().trim())
130: .newInstance());
131: }
132: } catch (Exception ex) {
133: throw new SecurityException(
134: "Failed to load the configuration role handler list : "
135: + ex.getMessage(), ex);
136: }
137: loadRoles();
138: }
139:
140: /**
141: * Load the roles into memory.
142: *
143: * @exception SecurityException
144: */
145: private void loadRoles() throws SecurityException {
146: try {
147: Map roles = new HashMap();
148: for (Iterator iter = roleHandlers.iterator(); iter
149: .hasNext();) {
150: RoleHandler handler = (RoleHandler) iter.next();
151: Map updatedRoles = handler.getRoles();
152: for (Iterator roleIter = updatedRoles.keySet()
153: .iterator(); roleIter.hasNext();) {
154: String role = (String) roleIter.next();
155: if (roles.containsKey(role)) {
156: log.info("Duplicate role [" + role
157: + "] from source : "
158: + handler.getClass().getName());
159: } else {
160: roles.put(role, updatedRoles.get(role));
161: }
162: }
163: }
164: synchronized (this ) {
165: this .roles = roles;
166: }
167: } catch (Exception ex) {
168: throw new SecurityException(
169: "Failed to load the role information : "
170: + ex.getMessage(), ex);
171: }
172: }
173:
174: /**
175: * The method that retrieves the reference to the role manager singleton.
176: *
177: * @return The reference to the role manager singleton.
178: * @exception SecurityException
179: */
180: public static synchronized RoleManager getInstance()
181: throws SecurityException {
182: if (singleton != null) {
183: return singleton;
184: }
185: singleton = new RoleManager();
186: return singleton;
187: }
188:
189: /**
190: * This method is called to start the role managers background thread.
191: */
192: public void startBackgroundThread() {
193: if (roleLoaderThread == null) {
194: roleLoaderThread = new RoleLoaderThread();
195: roleLoaderThread.start();
196: }
197: }
198:
199: /**
200: * This method is called to terminate the background threads processing. It
201: * will only succedded if the coadunation instance has been terminated.
202: */
203: public void terminateBackgroundThread() {
204: roleLoaderThread.terminate();
205: try {
206: roleLoaderThread.join();
207: } catch (Exception ex) {
208: log.error("Failed to terminate the background thread : "
209: + ex.getMessage(), ex);
210: }
211: }
212:
213: /**
214: * Retrieve the list of roles.
215: *
216: * @return The list of roles.
217: */
218: public synchronized Set getRoles() {
219: return roles.keySet();
220: }
221:
222: /**
223: * Retrieve the role with the matching name.
224: *
225: * @return The role object.
226: * @exception SecurityException
227: */
228: public synchronized Role getRole(String role)
229: throws SecurityException {
230: Role roleRef = (Role) roles.get(role);
231: if (roleRef == null) {
232: throw new SecurityException("The role [" + role
233: + "] could not be found");
234: }
235: return roleRef;
236: }
237: }
|