
woko.Woko Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2001-2012 Remi Vankeisbelck
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package woko;
import net.sourceforge.jfacets.FacetDescriptor;
import net.sourceforge.jfacets.IFacetDescriptorManager;
import net.sourceforge.jfacets.JFacets;
import net.sourceforge.jfacets.JFacetsBuilder;
import net.sourceforge.jfacets.annotations.AnnotatedFacetDescriptorManager;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.controller.StripesFilter;
import woko.facets.FacetNotFoundException;
import woko.facets.WokoFacetContextFactory;
import woko.facets.WokoProfileRepository;
import woko.facets.builtin.RenderObjectJson;
import woko.ioc.SimpleWokoIocContainer;
import woko.ioc.WokoInjectHelper;
import woko.ioc.WokoIocContainer;
import woko.persistence.ObjectStore;
import woko.users.UserManager;
import woko.users.UsernameResolutionStrategy;
import woko.util.JsonResolution;
import woko.util.LinkUtil;
import woko.util.Util;
import woko.util.WLogger;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.MessageFormat;
import java.util.*;
/**
* The infamous Woko !
* This is the top-level component in a Woko application. It provides access to the various
* components of the system ({@link ObjectStore}, {@link UserManager}, etc.) and to the facet
* retrieval APIs.
*
* @param the type of the ObjectStore
* @param the type of the UserManager
* @param the type of the UsernameResolutionStrategy
* @param the type of the IFacetDescriptorManager
*/
public class Woko<
OsType extends ObjectStore,
UmType extends UserManager,
UnsType extends UsernameResolutionStrategy,
FdmType extends IFacetDescriptorManager
> implements Closeable {
public static final WLogger logger = WLogger.getLogger(Woko.class);
/**
* Environment file name
*/
public static final String ENVI_FILE = "woko.environment";
/**
* Cached environment name
*/
private static String ENVI = null;
/**
* List of the default facet packages
*/
public static final List DEFAULT_FACET_PACKAGES =
Collections.unmodifiableList(Arrays.asList("facets", "woko.facets.builtin"));
/**
* Default role "all"
*/
public static final String ROLE_ALL = "all";
/**
* Default role "guest"
*/
public static final String ROLE_GUEST = "guest";
/**
* ServletContext attribute name for binding Woko
*/
public static final String CTX_KEY = "woko";
/**
* facet request attribute name
*/
public static final String REQ_ATTR_FACET = "facet";
/**
* Woko version
*/
public static final String VERSION = "2.4-beta7";
/**
* Return the Woko instance for passed servletContext
* @param ctx the servlet context
* @return the Woko instance bound to the servlet context
*/
@SuppressWarnings("unchecked")
public static <
OsType extends ObjectStore,
UmType extends UserManager,
UnsType extends UsernameResolutionStrategy,
FdmType extends IFacetDescriptorManager> Woko getWoko(ServletContext ctx) {
return (Woko)ctx.getAttribute(CTX_KEY);
}
/**
* Reference to JFacets (created at init)
*/
protected JFacets jFacets;
/**
* Reference to the IOC container (passed at init)
*/
private WokoIocContainer iocContainer = null;
/**
* List of the fallback role(s) (role(s) for unauthenticated users)
*/
private List fallbackRoles = null;
/**
* Create and initialize Woko with passed parameters
* @deprecated use constructor that takes IOC container as argument
*/
@Deprecated
public Woko(OsType objectStore,
UmType userManager,
List fallbackRoles,
FdmType facetDescriptorManager,
UnsType usernameResolutionStrategy) {
iocContainer = new SimpleWokoIocContainer(objectStore, userManager, usernameResolutionStrategy, facetDescriptorManager);
this.fallbackRoles = fallbackRoles;
init();
}
/**
* Create and initialize Woko with passed parameters
* @param ioc the IOC container
* @param fallbackRoles the fallback role(s)
*/
public Woko(WokoIocContainer ioc, List fallbackRoles) {
this.iocContainer = ioc;
this.fallbackRoles = fallbackRoles;
init();
}
/**
* Init JFacets and call customInit().
*/
private void init() {
logger.info("Initializing Woko...");
initJFacets();
customInit();
logger.info("");
logger.info("__ __ _ __");
logger.info("\\ \\ _ / /___ | |/ / ___");
logger.info(" \\ \\/ \\/ // o \\| K / \\");
logger.info(" \\__W__/ \\___/|_|\\_\\\\_o_/ " + VERSION);
logger.info(" POJOs on the Web !");
logger.info("");
logger.info("Woko is ready :");
logger.info(" * userManager : " + getUserManager());
logger.info(" * objectStore : " + getObjectStore());
logger.info(" * jFacets : " + jFacets);
logger.info(" * fallbackRole : " + fallbackRoles);
logger.info(" * usernameResolutionStrategy : " + getUsernameResolutionStrategy());
}
/**
* Initialize JFacets for the application (invoked at init).
*/
protected void initJFacets() {
logger.info("Initializing JFacets...");
WokoProfileRepository profileRepository = new WokoProfileRepository(getUserManager(), true);
WokoFacetContextFactory facetContextFactory = new WokoFacetContextFactory(this);
jFacets = new JFacetsBuilder(profileRepository, getFacetDescriptorManager()).
setFacetContextFactory(facetContextFactory).
build();
List descriptors = jFacets.getFacetRepository().getFacetDescriptorManager().getDescriptors();
logger.info(descriptors.size() + " facets found :");
for (FacetDescriptor d : descriptors) {
logger.info(" * " + d.getName() + ", " + d.getProfileId() + ", " + d.getTargetObjectType() + " -> " + d.getFacetClass());
}
logger.info("JFacets init OK.");
}
/**
* Post-init hook, called after JFacets init. Does nothing, by default.
*/
protected void customInit() {
}
/**
* Return the IOC container
* @return the IOC container
*/
public final WokoIocContainer getIoc() {
return iocContainer;
}
/**
* Return the fallback roles, used when there is no user authenticated
* @return the configured fallback roles
*/
public final List getFallbackRoles() {
return Collections.unmodifiableList(fallbackRoles);
}
/**
* Return the ObjectStore
from IOC
* @return the ObjectStore
from IOC
*/
public OsType getObjectStore() {
return getIoc().getObjectStore();
}
/**
* Return the UserManager
from IOC
* @return the UserManager
from IOC
*/
public UmType getUserManager() {
return getIoc().getUserManager();
}
/**
* Return the IFacetDescriptorManager
from IOC
* @return the IFacetDescriptorManager
from IOC
*/
public FdmType getFacetDescriptorManager() {
return getIoc().getFacetDescriptorManager();
}
/**
* Return the UsernameResolutionStrategy
from IOC
* @return the UsernameResolutionStrategy
from IOC
*/
public UnsType getUsernameResolutionStrategy() {
return getIoc().getUsernameResolutionStrategy();
}
/**
* Return the JFacets instance
* @return the JFacets instance
*/
public JFacets getJFacets() {
return jFacets;
}
/**
* Close Woko (close IOC).
*/
public final void close() {
logger.info("Closing...");
WokoIocContainer,?,?,?> ioc = getIoc();
if (ioc instanceof Closeable) {
logger.info("Closing IOC...");
((Closeable)ioc).close();
}
doClose();
logger.info("Woko has been closed.");
}
/**
* Post-close hook, invoked after IOC has been closed.
* Does nothing by default.
*/
protected void doClose() {
}
/**
* Return the facet for passed parameters.
* @param name the facet name
* @param request the request
* @param targetObject the target object (not null)
* @param the facet type
* @return the facet if any (null
if no such facet exists)
*/
@SuppressWarnings("unchecked")
public T getFacet(String name, HttpServletRequest request, Object targetObject) {
return getFacet(name, request, targetObject, null);
}
/**
* Return the facet for passed parameters
* @param name the facet name
* @param request the request
* @param targetObject the target object (can be null)
* @param targetObjectClass the target object class (not null)
* @param throwIfNotFound throw a FacetNotFoundException
if the facet is not found and this flag is true
* @param the type of the facet
* @return the facet if found (or null or throws FacetNotFoundException
depending on passed args)
*/
public T getFacet(String name, HttpServletRequest request, Object targetObject, Class> targetObjectClass, boolean throwIfNotFound) {
T f = getFacet(name, request, targetObject, targetObjectClass);
if (f == null && throwIfNotFound) {
throw new FacetNotFoundException(name, targetObject, targetObjectClass, getUsername(request));
}
return f;
}
/**
* Return the facet for passed parameters
* @param name the facet name
* @param request the request
* @param targetObject the target object (can be null)
* @param targetObjectClass the target object class (not null)
* @param the facet type
* @return the facet if found, null
otherwise
*/
public T getFacet(String name, HttpServletRequest request, Object targetObject, Class> targetObjectClass) {
logger.debug("Trying to get facet " + name + " for target object " + targetObject + ", targetObjectClass " + targetObjectClass + "...");
String username = getUsername(request);
List roles;
if (username == null) {
roles = fallbackRoles;
logger.debug("Username not supplied, using fallback roles : " + fallbackRoles);
} else {
roles = getUserManager().getRoles(username);
if (roles == null || roles.size() == 0) {
logger.debug("No roles returned for user '" + username + "', using fallback roles : " + fallbackRoles);
roles = fallbackRoles;
}
logger.debug("Using roles " + roles + " for user " + username);
}
if (!roles.contains(ROLE_ALL)) {
roles = new ArrayList(roles);
roles.add(ROLE_ALL);
}
if (targetObject == null && targetObjectClass == null) {
logger.debug("No object or class provided, defaulting to Object.class");
targetObjectClass = Object.class;
}
if (targetObjectClass == null && targetObject != null) {
targetObjectClass = targetObject.getClass();
}
for (String role : roles) {
logger.debug("Trying role : " + role);
@SuppressWarnings("unchecked")
T facet = (T)jFacets.getFacet(name, role, targetObject, targetObjectClass);
if (facet != null) {
request.setAttribute(name, facet);
request.setAttribute(REQ_ATTR_FACET, facet);
logger.debug("Facet found and bound to request with name '" + name + "', returning " + facet);
// inject components for methods marked with @WokoInject
WokoInjectHelper.injectComponents(this, facet);
return facet;
}
}
logger.debug("Facet not found for name: " + name + ", roles: " + roles + ", targetObject: " + targetObject + ", targetObjectClass: " + targetObjectClass + ", returning null");
return null;
}
/**
* Return the username for passed request, using configured
* UsernameResolutionStrategy
.
* @param request the request
* @return the username for the request if any, null
otherwise
*/
public String getUsername(HttpServletRequest request) {
return getUsernameResolutionStrategy().getUsername(request);
}
/**
* Return the URL for passed (resolution) facet name and target object
* @param facetName the facet name
* @param obj the target object
* @return the URL to the resolution facet (like /view/MyClass/123)
*/
public String facetUrl(String facetName, Object obj) {
return "/" + LinkUtil.getUrl(this, obj, facetName);
}
/**
* Create facet descriptor manager for passed package names and the app's classloader.
* @param packageNames the facet package names
* @return a freshly created and initialized IFacetDescriptorManager
*/
public static IFacetDescriptorManager createFacetDescriptorManager(List packageNames) {
return createFacetDescriptorManager(packageNames, Woko.class.getClassLoader());
}
/**
* Create facet descriptor manager for passed package names and classloader.
* @param packageNames the facet package names
* @param classLoader the classloader to be used for facet class lookup
* @return a freshly created and initialized IFacetDescriptorManager
*/
public static IFacetDescriptorManager createFacetDescriptorManager(List packageNames, ClassLoader classLoader) {
Util.assertArg("packageNames", packageNames);
Util.assertArg("classLoader", classLoader);
logger.info("Creating Annotated Facets, scanning packages : " + packageNames);
return new AnnotatedFacetDescriptorManager(packageNames)
.setClassLoader(classLoader)
.initialize();
}
/**
* Check if some environment has been used to build the app
* @param ifNoEnv the value to return in case no environment was used at all (getEnvironment()==null)
* @param envNames the name of the environments to check
* @return true if the environment used matches passed parameter (null safe), false otherwise
*/
public static boolean isUsingEnvironment(boolean ifNoEnv, String... envNames) {
String actualEnv = getEnvironment();
if (actualEnv==null) {
return ifNoEnv;
}
for (String en : envNames) {
if (actualEnv.equals(en)) {
return true;
}
}
return false;
}
/**
* Return the environment used
* @return the environment used at build-time (as found in the woko.environment file)
*/
public static String getEnvironment() {
if (ENVI==null) {
InputStream is = Woko.class.getResourceAsStream("/" + ENVI_FILE);
if (is!=null) {
BufferedReader r = new BufferedReader(new InputStreamReader(is));
try {
try {
ENVI = r.readLine();
} finally {
r.close();
}
} catch(Exception e) {
logger.error("Unable to read environment file at " + ENVI_FILE,e);
}
}
}
return ENVI;
}
/**
* Return the localized message for passed key and args, looking up in the
* configured resource bundles.
* @param request the request
* @param key the message key
* @param args the message arguments
* @return the formatted message
*/
public String getLocalizedMessage(HttpServletRequest request, String key, String... args) {
Locale locale = request.getLocale();
return getLocalizedMessage(locale, key, args);
}
/**
* Return the localized message for passed locale, key and args, looking up in the
* configured resource bundles.
* @param locale the locale
* @param key the message key
* @param args the message arguments
* @return the formatted message
*/
public String getLocalizedMessage(Locale locale, String key, String... args) {
ResourceBundle b = StripesFilter.getConfiguration().
getLocalizationBundleFactory().getFormFieldBundle(locale);
try {
String msgTemplate = b.getString(key);
if (args.length==0) {
return msgTemplate;
}
MessageFormat f = new MessageFormat(msgTemplate, locale);
return f.format(args, new StringBuffer(), null).toString();
} catch(MissingResourceException e) {
return key;
}
}
/**
* Return the Resolutions helper.
*/
public Resolutions resolutions() {
return RESOLUTIONS;
}
private final Resolutions RESOLUTIONS = new Resolutions(this);
/**
* Helper class for returning resolutions in a compact fashion.
*/
public static class Resolutions {
private final Woko,?,?,?> woko;
public Resolutions(Woko, ?, ?, ?> woko) {
this.woko = woko;
}
public RedirectResolution redirect(String facetName, Object targetObject) {
return new RedirectResolution(woko.facetUrl(facetName, targetObject));
}
public ForwardResolution forward(String facetName, Object targetObject) {
return new ForwardResolution(woko.facetUrl(facetName, targetObject));
}
public JsonResolution json(Object targetObject, HttpServletRequest request) {
return new JsonResolution(targetObject, request);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy