Issue #1451 Allow overriding of IUserManager via ServiceLoader.

Change-Id: Iec63c05fe7365051e7bd1a01ecca701b5553c9e9

Former-commit-id: 452729a647 [formerly 46d756ba5cd37ae22fc31ae67dac0751c2c02985]
Former-commit-id: 19f1b30437
This commit is contained in:
Dustin Johnson 2013-01-04 09:53:51 -06:00
parent 424cb12ef6
commit 818664e557
3 changed files with 227 additions and 73 deletions

View file

@ -0,0 +1,47 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.core.auth;
/**
* Defines a method of retrieving the {@link IUserManager} implementation.
* Intentionally package-private as all access should be constrained to
* {@link UserController}.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 04, 2013 1451 djohnson Initial creation
*
* </pre>
*
* @author djohnson
* @version 1.0
*/
interface IUserManagerLoader {
/**
* Load the {@link IUserManager} that should be used on the system.
*
* @return the user manager
*/
IUserManager getUserManager();
}

View file

@ -38,6 +38,7 @@ import com.raytheon.uf.common.auth.user.IUser;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.ServiceLoaderUtil;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.requests.INotAuthHandler;
@ -51,6 +52,7 @@ import com.raytheon.uf.viz.core.requests.INotAuthHandler;
* ------------ ---------- ----------- --------------------------
* May 21, 2010 mschenke Initial creation
* Nov 06, 2012 1302 djohnson Add ability to retrieve the {@link IUserManager}.
* Jan 04, 2013 1451 djohnson Move static block code to an implementation of an interface.
*
* </pre>
*
@ -59,92 +61,125 @@ import com.raytheon.uf.viz.core.requests.INotAuthHandler;
*/
public class UserController {
private static IUFStatusHandler statusHandler = UFStatus
.getHandler(UserController.class, "CAVE");
private static final String EXTENSION_POINT = "com.raytheon.uf.viz.core.userManager";
/**
* Loads the {@link IUserManager} implementation from extension points. This
* code was moved in verbatim from the static block below.
*/
private static class ExtensionPointManagerLoader implements
IUserManagerLoader {
private static final IUFStatusHandler statusHandler = UFStatus.getHandler(
ExtensionPointManagerLoader.class, "CAVE");
private static final String EXTENSION_POINT = "com.raytheon.uf.viz.core.userManager";
private static IUserManager manager;
private static final ExtensionPointManagerLoader INSTANCE = new ExtensionPointManagerLoader();
private ExtensionPointManagerLoader() {
}
static {
IExtensionRegistry registry = Platform.getExtensionRegistry();
IExtensionPoint point = registry.getExtensionPoint(EXTENSION_POINT);
if (point != null) {
IExtension[] extensions = point.getExtensions();
/**
* {@inheritDoc}
*/
@Override
public IUserManager getUserManager() {
IUserManager manager = null;
for (IExtension ext : extensions) {
for (IConfigurationElement elem : ext
.getConfigurationElements()) {
if (manager != null) {
statusHandler
.handle(Priority.PROBLEM,
"Not using user authentication manager: "
+ elem.getAttribute("class")
+ ".\nViz does not currently support multiple authentication methods,"
+ " using first one found in extension point. Remove any authentication"
+ " plugins not on edex server");
} else {
try {
manager = (IUserManager) elem
.createExecutableExtension("class");
} catch (CoreException e) {
IExtensionRegistry registry = Platform.getExtensionRegistry();
IExtensionPoint point = registry.getExtensionPoint(EXTENSION_POINT);
if (point != null) {
IExtension[] extensions = point.getExtensions();
for (IExtension ext : extensions) {
for (IConfigurationElement elem : ext
.getConfigurationElements()) {
if (manager != null) {
statusHandler
.handle(Priority.PROBLEM,
"Error creating IUserManager from extension point",
e);
"Not using user authentication manager: "
+ elem.getAttribute("class")
+ ".\nViz does not currently support multiple authentication methods,"
+ " using first one found in extension point. Remove any authentication"
+ " plugins not on edex server");
} else {
try {
manager = (IUserManager) elem
.createExecutableExtension("class");
} catch (CoreException e) {
statusHandler
.handle(Priority.PROBLEM,
"Error creating IUserManager from extension point",
e);
}
}
}
}
}
if (manager == null) {
manager = new IUserManager() {
@Override
public IUser getUserObject() {
return null;
}
@Override
public void updateUserObject(IUser user,
IAuthenticationData authData) {
}
@Override
public INotAuthHandler getNotAuthHandler() {
return new INotAuthHandler() {
@Override
public Object notAuthenticated(
UserNotAuthenticated response)
throws VizException {
throw new VizException(
"Could not perform request, user is not authenticated with server.");
}
@Override
public Object notAuthorized(
UserNotAuthorized response)
throws VizException {
throw new VizException(response.getMessage());
}
};
}
/**
* {@inheritDoc}
*/
@Override
public List<IPermission> getPermissions(String application) {
return Collections.emptyList();
}
@Override
public List<IRole> getRoles(String application) {
return Collections.emptyList();
}
};
}
return manager;
}
}
if (manager == null) {
manager = new IUserManager() {
@Override
public IUser getUserObject() {
return null;
}
private static final IUserManager manager;
static {
// This static block will perform exactly as before, with a few
// caveats...
// If a service loader config file for the interface is present on the
// classpath, it can change the implementation, such as in a test case
IUserManagerLoader userManagerLoader = ServiceLoaderUtil.load(
IUserManagerLoader.class, ExtensionPointManagerLoader.INSTANCE);
@Override
public void updateUserObject(IUser user,
IAuthenticationData authData) {
}
@Override
public INotAuthHandler getNotAuthHandler() {
return new INotAuthHandler() {
@Override
public Object notAuthenticated(
UserNotAuthenticated response)
throws VizException {
throw new VizException(
"Could not perform request, user is not authenticated with server.");
}
@Override
public Object notAuthorized(UserNotAuthorized response)
throws VizException {
throw new VizException(response.getMessage());
}
};
}
/**
* {@inheritDoc}
*/
@Override
public List<IPermission> getPermissions(String application) {
return Collections.emptyList();
}
@Override
public List<IRole> getRoles(String application) {
return Collections.emptyList();
}
};
}
// manager is now final, it can't be changed once it is initialized
manager = userManagerLoader.getUserManager();
}

View file

@ -0,0 +1,72 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.util;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* Utilities for interacting with {@link ServiceLoader}.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 04, 2013 1451 djohnson Initial creation
*
* </pre>
*
* @author djohnson
* @version 1.0
*/
public final class ServiceLoaderUtil {
/**
* Prevent construction.
*/
private ServiceLoaderUtil() {
}
/**
* Loads the first implementation of an interface found using
* {@link ServiceLoader}. If no results are found, will return the provided
* default implementation.
*
* @param interfaceClass
* the class instance to search for a service loader
* implementation of
* @param defaultImplementation
* the default implementation
* @return the loaded implementation, or the default implementation is no
* configuration file found
*/
public static <T> T load(Class<T> interfaceClass, T defaultImplementation) {
ServiceLoader<T> overridden = ServiceLoader.load(interfaceClass);
final Iterator<T> iter = overridden.iterator();
if (iter.hasNext()) {
return iter.next();
}
return defaultImplementation;
}
}