001: package org.esupportail.cas.server.util;
002:
003: import java.lang.reflect.Constructor;
004: import java.lang.reflect.InvocationTargetException;
005: import java.util.Iterator;
006: import java.util.LinkedList;
007: import java.util.List;
008:
009: import org.dom4j.Element;
010:
011: /**
012: * This abstract class implements a redundant handler, with a list
013: * of servers that will be used for redundancy.
014: *
015: * @author Pascal Aubry <pascal.aubry at univ-rennes1.fr>
016: */
017: public abstract class RedundantHandler extends BasicHandler {
018:
019: /**
020: * the list of servers to be used for authentication. Modified by
021: * addServer().
022: */
023: private LinkedList servers;
024:
025: /**
026: * retrieve the list of the servers.
027: *
028: * @return the list of the servers used for authentication.
029: */
030: public final List getServers() {
031: return servers;
032: }
033:
034: /**
035: * Constructor.
036: *
037: * @param handlerElement the XML element that declares the handler
038: * in the configuration file
039: * @param configDebug debugging mode of the global configuration
040: */
041: protected RedundantHandler(final Element handlerElement,
042: final Boolean configDebug) {
043: super (handlerElement, configDebug);
044: traceBegin();
045: servers = new LinkedList();
046: traceEnd();
047: }
048:
049: /**
050: * Constructor.
051: *
052: * @param serverElementNeeded true to force the handler to have at least one server sub-element
053: * @param serverClassname the classname of the server to create for the handler
054: * @throws Exception Exception
055: */
056: protected final void addServers(final boolean serverElementNeeded,
057: final String serverClassname) throws Exception {
058: traceBegin();
059:
060: Element configElement = getConfigElement();
061:
062: // check if a config/server element is needed
063: if (configElement == null) {
064: if (serverElementNeeded) {
065: traceThrow(new MisconfiguredHandlerException(
066: "A \"config\" element is needed by \""
067: + getClass().getName() + "\" handlers."));
068: }
069: return;
070: }
071:
072: trace("Looking for servers...");
073:
074: // get the list of all the server elements
075: List serverElements = configElement.elements("server");
076:
077: // check that at least one server is declared
078: if (serverElementNeeded) {
079: if (serverElements.isEmpty()) {
080: traceThrow(new MisconfiguredHandlerException(
081: "At least one \"server\" element is needed to configure \""
082: + getClass().getName() + "\" handlers."));
083: }
084: }
085:
086: for (Iterator i = serverElements.iterator(); i.hasNext();) {
087: trace("Found a server.");
088:
089: // load the server class
090: Class serverClass = null;
091: try {
092: trace("Getting the " + serverClassname + " class...");
093: serverClass = Class.forName(serverClassname);
094: } catch (ClassNotFoundException e) {
095: // this should never happen
096: traceThrow(new MisconfiguredHandlerException("Class \""
097: + serverClassname + "\" could not be loaded."));
098: }
099:
100: // get the constructor
101: Class[] serverConstructorArgumentTypes = { Boolean.class,
102: RedundantHandler.class, Element.class };
103: Constructor serverConstructor = null;
104: try {
105: trace("Getting the constructor...");
106: serverConstructor = serverClass
107: .getConstructor(serverConstructorArgumentTypes);
108: } catch (Exception e) {
109: traceThrow(new MisconfiguredHandlerException(
110: "The constructor of Class \"" + serverClassname
111: + "\" could not be loaded because a \""
112: + e.getClass().getName()
113: + "\" exception was raised: "
114: + e.getMessage()));
115: }
116:
117: // create an instance
118: Object[] serverConstructorArguments = {
119: new Boolean(isDebug()), this , i.next() };
120: Server server = null;
121: try {
122: trace("Creating a new instance...");
123: server = (Server) serverConstructor
124: .newInstance(serverConstructorArguments);
125: } catch (InvocationTargetException e) {
126: traceThrow(new MisconfiguredHandlerException(e
127: .getCause().getMessage()));
128: } catch (Exception e) {
129: traceThrow(new MisconfiguredHandlerException("Class \""
130: + serverClassname
131: + "\" could not be instanciated because a \""
132: + e.getClass().getName()
133: + "\" exception was raised: " + e.getMessage()));
134: }
135:
136: // add the newly created object to the list of servers
137: servers.add(server);
138:
139: trace("Server added.");
140: }
141:
142: trace(servers.size() + " servers found.");
143: traceEnd();
144: }
145:
146: /**
147: * Tries to Authenticate a user by accessing all the servers.
148: *
149: * @param username the username to authenticate
150: * @param password the correspoding password
151: *
152: * @return BasicHandlerSUCCEDED on success, or
153: * BasicHandler.FAILED_CONTINUE otherwise.
154: */
155: public final int authenticate(final String username,
156: final String password) {
157: traceBegin();
158:
159: for (Iterator i = servers.iterator(); i.hasNext();) {
160: Server server = (Server) i.next();
161: switch (server.authenticate(username, password)) {
162: case Server.AUTHENTICATE_SUCCESS:
163: trace("Server matched.");
164: traceEnd("SUCCEEDED");
165: return SUCCEEDED;
166: case Server.AUTHENTICATE_NOAUTH:
167: trace("Server did not match.");
168: traceEnd("FAILED_CONTINUE");
169: return FAILED_CONTINUE;
170: default:
171: trace("Server failure, trying next");
172: break;
173: }
174: }
175: trace("No server matched.");
176: traceEnd("FAILED_CONTINUE");
177: return FAILED_CONTINUE;
178: }
179:
180: }
|