You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by mr...@apache.org on 2005/08/26 07:46:58 UTC
svn commit: r240168 [12/30] - in /struts/sandbox/trunk/ti: ./
core/src/java/org/apache/ti/ core/src/java/org/apache/ti/config/
core/src/java/org/apache/ti/config/mapper/
core/src/java/org/apache/ti/core/ core/src/java/org/apache/ti/core/factory/
core/s...
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/InternalUtils.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/InternalUtils.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/InternalUtils.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/InternalUtils.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,675 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+import org.apache.commons.chain.web.WebContext;
+import org.apache.commons.chain.web.servlet.ServletWebContext;
+import org.apache.ti.Globals;
+import org.apache.ti.core.ActionMessage;
+import org.apache.ti.pageflow.ActionResolver;
+import org.apache.ti.pageflow.FacesBackingBean;
+import org.apache.ti.pageflow.FlowControllerException;
+import org.apache.ti.pageflow.ModuleConfig;
+import org.apache.ti.pageflow.PageFlowConstants;
+import org.apache.ti.pageflow.PageFlowController;
+import org.apache.ti.pageflow.SessionExpiredException;
+import org.apache.ti.pageflow.handler.Handlers;
+import org.apache.ti.pageflow.handler.ModuleRegistrationHandler;
+import org.apache.ti.pageflow.handler.ReloadableClassHandler;
+import org.apache.ti.pageflow.handler.StorageHandler;
+import org.apache.ti.pageflow.xwork.PageFlowAction;
+import org.apache.ti.pageflow.xwork.PageFlowActionContext;
+import org.apache.ti.schema.config.PageflowConfig;
+import org.apache.ti.util.Bundle;
+import org.apache.ti.util.MessageResources;
+import org.apache.ti.util.config.ConfigUtil;
+import org.apache.ti.util.internal.InternalStringBuilder;
+import org.apache.ti.util.internal.ServletUtils;
+import org.apache.ti.util.logging.Logger;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+
+
+public class InternalUtils
+ implements PageFlowConstants, InternalConstants {
+
+ private static final Logger _log = Logger.getInstance(InternalUtils.class);
+
+ private static final String LONGLIVED_PAGEFLOWS_ATTR_PREFIX = ATTR_PREFIX + "longLivedPageFlow:";
+ private static final String ACTIONOUTPUT_MAP_ATTR = ATTR_PREFIX + "actionOutputs";
+ private static final String BINDING_UPDATE_ERRORS_ATTR = ATTR_PREFIX + "bindingUpdateErrors";
+ private static final String SHARED_FLOW_CLASSNAME_ATTR = ATTR_PREFIX + "sharedFlowClass";
+ private static final String AVOID_DIRECT_RESPONSE_OUTPUT_ATTR = ATTR_PREFIX + "_avoidDirectResponseOutput";
+ private static final String FORWARDED_FORMBEAN_ATTR = ATTR_PREFIX + "forwardedForm";
+ private static final String FORWARDING_MODULE_ATTR = ATTR_PREFIX + "forwardingModule";
+ private static final String IGNORE_INCLUDE_SERVLET_PATH_ATTR = ATTR_PREFIX + "ignoreIncludeServletPath";
+
+
+ /**
+ * If not in production mode, write an error to the response; otherwise, set a response error code.
+ */
+ public static void sendDevTimeError(String messageKey, Throwable cause, int productionTimeErrorCode,
+ Object[] messageArgs) {
+ // TODO: re-add this
+ }
+
+ /**
+ * Write an error to the response.
+ */
+ public static void sendError(String messageKey, Throwable cause, Object[] messageArgs) {
+ sendError(messageKey, messageArgs, cause, avoidDirectResponseOutput());
+ }
+
+ /**
+ * Write an error to the response.
+ */
+ public static void sendError(String messageKey, Object[] messageArgs, Throwable cause,
+ boolean avoidDirectResponseOutput) {
+ assert messageArgs.length == 0 || !(messageArgs[0] instanceof Object[])
+ : "Object[] passed to sendError; this is probably a mistaken use of varargs";
+
+ // request may be null because of deprecated FlowController.sendError().
+ if (avoidDirectResponseOutput) {
+ String baseMessage = Bundle.getString(messageKey + "_Message", messageArgs);
+ throw new ResponseOutputException(baseMessage, cause);
+ }
+
+ String html = Bundle.getString(messageKey + "_Page", messageArgs);
+ // TODO re-add
+ //ServletUtils.writeHtml(getWebContext(), html, true);
+ System.err.println(html);
+ throw new UnsupportedOperationException("NYI -- HTML is: \n" + html); // TODO: NYI
+ }
+
+ /**
+ * Get a Method in a Class.
+ *
+ * @param parentClass the Class in which to find the Method.
+ * @param methodName the name of the Method.
+ * @param signature the argument types for the Method.
+ * @return the Method with the given name and signature, or <code>null</code> if the method does not exist.
+ */
+ public static Method lookupMethod(Class parentClass, String methodName, Class[] signature) {
+ try {
+ return parentClass.getDeclaredMethod(methodName, signature);
+ } catch (NoSuchMethodException e) {
+ Class superClass = parentClass.getSuperclass();
+ return superClass != null ? lookupMethod(superClass, methodName, signature) : null;
+ }
+ }
+
+ public static String getLongLivedFlowAttr(String namespace) {
+ return LONGLIVED_PAGEFLOWS_ATTR_PREFIX + namespace;
+ }
+
+ public static void setCurrentPageFlow(PageFlowController jpf) {
+ setCurrentActionResolver(jpf);
+ }
+
+ public static void removeCurrentPageFlow() {
+ StorageHandler sh = Handlers.get().getStorageHandler();
+ String currentJpfAttrName = getScopedAttrName(CURRENT_JPF_ATTR);
+ String currentLongLivedAttrName = getScopedAttrName(CURRENT_LONGLIVED_ATTR);
+ sh.removeAttribute(currentJpfAttrName);
+ sh.removeAttribute(currentLongLivedAttrName);
+ }
+
+ public static void removeCurrentFacesBackingBean() {
+ StorageHandler sh = Handlers.get().getStorageHandler();
+ String attrName = getScopedAttrName(FACES_BACKING_ATTR);
+ sh.removeAttribute(attrName);
+ }
+
+ public static void addActionOutputs(Map toAdd, boolean overwrite) {
+ if (toAdd != null) {
+ Map map = getActionOutputMap(true);
+
+ for (Iterator i = toAdd.entrySet().iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ String name = (String) entry.getKey();
+ boolean alreadyExists = map.containsKey(name);
+
+ if (overwrite || !alreadyExists) {
+ if (alreadyExists) {
+ if (_log.isWarnEnabled()) {
+ _log.warn("Overwriting action output \"" + name + "\".");
+ }
+ }
+
+ map.put(name, entry.getValue());
+ }
+ }
+ }
+ }
+
+ public static void addActionError(String propertyName, ActionMessage error) {
+ /* TODO: re-add error/message support
+ ActionErrors errors = ( ActionErrors ) request.getAttribute( Globals.ERROR_KEY );
+ if ( errors == null ) request.setAttribute( Globals.ERROR_KEY, errors = new ActionErrors() );
+ errors.add( propertyName, error );
+ */
+ }
+
+ public static Object newReloadableInstance(String className)
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+ return getReloadableClass(className).newInstance();
+ }
+
+ public static Class getReloadableClass(String className)
+ throws ClassNotFoundException {
+ ReloadableClassHandler handler = Handlers.get().getReloadableClassHandler();
+ return handler.loadClass(className);
+ }
+
+ public static Map getActionOutputMap(boolean createIfNotExist) {
+ Map requestScope = PageFlowActionContext.get().getRequestScope();
+ Map map = (Map) requestScope.get(ACTIONOUTPUT_MAP_ATTR);
+
+ if (map == null && createIfNotExist) {
+ map = new HashMap();
+ requestScope.put(ACTIONOUTPUT_MAP_ATTR, map);
+ }
+
+ return map;
+ }
+
+ public static Map getPageInputMap() {
+ Map actionOutputsFromPageFlow = getActionOutputMap(false);
+ if (actionOutputsFromPageFlow != null) return actionOutputsFromPageFlow;
+ FacesBackingBean fbb = getFacesBackingBean();
+ return fbb != null ? fbb.getPageInputMap() : null;
+ }
+
+ /**
+ * Add a BindingUpdateError to the request.
+ *
+ * @param expression the expression associated with this error.
+ * @param message the error message.
+ * @param cause the Throwable that caused the error.
+ */
+ public static void addBindingUpdateError(String expression, String message, Throwable cause) {
+ Map errors = (Map) getWebContext().getRequestScope().get(BINDING_UPDATE_ERRORS_ATTR);
+
+ if (errors == null) {
+ errors = new LinkedHashMap();
+ getWebContext().getRequestScope().put(BINDING_UPDATE_ERRORS_ATTR, errors);
+ }
+
+ errors.put(expression, new BindingUpdateError(expression, message, cause));
+ }
+
+ /**
+ * Get a map of BindingUpdateErrors stored in the request.
+ *
+ * @return a Map of expression (String) -> BindingUpdateError.
+ */
+ public static Map getBindingUpdateErrors() {
+ return (Map) getWebContext().getRequestScope().get(BINDING_UPDATE_ERRORS_ATTR);
+ }
+
+ public static WebContext getWebContext() {
+ return PageFlowActionContext.get().getWebContext();
+ }
+
+ /**
+ * Set the given form in either the request or session, as appropriate, so Struts/NetUI
+ * tags will have access to it.
+ */
+ public static void setFormInScope(String formAttribute, Object formBean, boolean overwrite) {
+ if (formBean != null) {
+ //String formName = PageFlowActionContext.getContext().getAction().getFormBeanAttribute();
+ assert formAttribute != null;
+
+ if (overwrite || getWebContext().getRequestScope().get(formAttribute) == null) {
+ getWebContext().getRequestScope().put(formAttribute, formBean);
+ }
+ }
+ }
+
+ public static Object getFormBean(PageFlowAction action) {
+ String attrName = action.getFormBeanAttribute();
+
+ if (attrName != null) {
+ return getWebContext().getRequestScope().get(attrName);
+ }
+
+ return null;
+ }
+
+ /**
+ * Set the current ActionResolver ({@link PageFlowController}) in the user session.
+ *
+ * @param resolver the ActionResolver to set as the current one in the user session.
+ */
+ public static void setCurrentActionResolver(ActionResolver resolver) {
+ StorageHandler sh = Handlers.get().getStorageHandler();
+ String currentJpfAttrName = getScopedAttrName(CURRENT_JPF_ATTR);
+ String currentLongLivedJpfAttrName = getScopedAttrName(CURRENT_LONGLIVED_ATTR);
+
+ if (resolver == null) {
+ sh.removeAttribute(currentJpfAttrName);
+ sh.removeAttribute(currentLongLivedJpfAttrName);
+ return;
+ }
+
+ //
+ // If this is a long-lived page flow, also store the instance in an attribute that never goes away.
+ //
+ if (resolver.getModuleConfig().isLongLivedFlow()) {
+ String longLivedAttrName = getLongLivedFlowAttr(resolver.getNamespace());
+ longLivedAttrName = getScopedAttrName(longLivedAttrName);
+
+ // Only set this attribute if it's not already there. We want to avoid our onDestroy() callback that's
+ // invoked when the page flow's session attribute is unbound.
+ if (sh.getAttribute(longLivedAttrName) != resolver) {
+ sh.setAttribute(longLivedAttrName, resolver);
+ }
+
+ sh.setAttribute(currentLongLivedJpfAttrName, resolver.getNamespace());
+ sh.removeAttribute(currentJpfAttrName);
+ } else {
+ sh.setAttribute(currentJpfAttrName, resolver);
+ sh.removeAttribute(currentLongLivedJpfAttrName);
+ }
+ }
+
+ public static String getFlowControllerClassName(String namespace) {
+ assert namespace != null;
+ ModuleRegistrationHandler mrh = Handlers.get().getModuleRegistrationHandler();
+ ModuleConfig moduleConfig = mrh.getModuleConfig(namespace);
+ return moduleConfig != null ? moduleConfig.getControllerClassName() : null;
+ }
+
+ public static FacesBackingBean getFacesBackingBean() {
+ StorageHandler sh = Handlers.get().getStorageHandler();
+ String attrName = getScopedAttrName(FACES_BACKING_ATTR);
+ return (FacesBackingBean) sh.getAttribute(attrName);
+ }
+
+ public static String inferNamespaceFromClassName(String className) {
+ int lastDot = className.lastIndexOf('.');
+
+ if (lastDot != -1) {
+ className = className.substring(0, lastDot);
+ return '/' + className.replace('.', '/');
+ } else {
+ return "/";
+ }
+ }
+
+ public static PageflowConfig.MultipartHandler.Enum getMultipartHandlerType() {
+ PageflowConfig pfConfig = ConfigUtil.getConfig().getPageflowConfig();
+ return pfConfig != null ? pfConfig.getMultipartHandler() : null;
+ }
+
+ /**
+ * Simply adds the context path and parent directory, based on the current request URI.
+ */
+ public static String createActionURL(String qualifiedAction) {
+ PageFlowActionContext actionContext = PageFlowActionContext.get();
+ String pageURI = actionContext.getRequestURI();
+ int lastSlash = pageURI.lastIndexOf('/');
+
+ if (lastSlash != -1) {
+ InternalStringBuilder value = new InternalStringBuilder(qualifiedAction.length() + lastSlash);
+ value.append(pageURI.substring(0, lastSlash));
+ value.append(qualifiedAction);
+ return value.toString();
+ }
+
+ return qualifiedAction;
+ }
+
+ public static String createActionPath(String qualifiedAction) {
+ ModuleConfig moduleConfig = PageFlowActionContext.get().getModuleConfig();
+
+
+ if (moduleConfig != null) {
+ InternalStringBuilder value = new InternalStringBuilder(qualifiedAction.length() + 16);
+ value.append(moduleConfig.getNamespace());
+ value.append(qualifiedAction);
+ return value.toString();
+ }
+
+ return qualifiedAction;
+ }
+
+ public static String qualifyAction(String action) {
+ assert action != null;
+ InternalStringBuilder sb = null;
+
+ String queryString = null;
+ int question = action.indexOf('?');
+ if (question >= 0) queryString = action.substring(question);
+
+ String actionMapping = getActionMappingName(action);
+ sb = new InternalStringBuilder(action.length() + ACTION_EXTENSION_LEN + 1);
+ sb.append(actionMapping);
+ sb.append(ACTION_EXTENSION);
+ if (queryString != null) sb.append(queryString);
+
+ return sb.toString();
+ }
+
+ /**
+ * Return the form action converted into an action mapping path. The
+ * value of the <code>action</code> property is manipulated as follows in
+ * computing the name of the requested mapping:
+ * <ul>
+ * <li>Any filename extension is removed (on the theory that extension
+ * mapping is being used to select the controller servlet).</li>
+ * <li>If the resulting value does not start with a slash, then a
+ * slash is prepended.</li>
+ * </ul>
+ *
+ * @param action the action name to be converted.
+ * @return an action path, suitable for lookup in the Struts configuration file.
+ */
+ public static String getActionMappingName(String action) {
+ return getCleanActionName(action, true);
+ }
+
+ public static String getCleanActionName(String action, boolean prependSlash) {
+ int question = action.indexOf('?');
+ if (question >= 0) {
+ action = action.substring(0, question);
+ }
+
+ if (action.endsWith(ACTION_EXTENSION)) {
+ action = action.substring(0, action.length() - ACTION_EXTENSION_LEN);
+ }
+
+ if (action.charAt(0) == '/') {
+ if (!prependSlash) action = action.substring(1);
+ } else {
+ if (prependSlash) action = '/' + action;
+ }
+
+ return action;
+ }
+
+
+ /**
+ * Add a parameter to the given URL. Assumes there is no trailing
+ * anchor/fragment indicated with a '#'.
+ *
+ * @param url the URL to which to append.
+ * @param paramName the name of the parameter to add.
+ * @param paramVal the value of the parameter to add.
+ * @return the URL, with the given parameter added.
+ */
+ public static String addParam(String url, String paramName, String paramVal) {
+ return url + (url.indexOf('?') != -1 ? '&' : '?') + paramName + '=' + paramVal;
+ }
+
+ public static void throwPageFlowException(FlowControllerException effect)
+ throws FlowControllerException {
+ if (effect.causeMayBeSessionExpiration() && ServletUtils.isSessionExpired(getWebContext())) {
+ PageflowConfig pfc = ConfigUtil.getConfig().getPageflowConfig();
+ if (pfc == null || !pfc.isSetThrowSessionExpiredException() || pfc.getThrowSessionExpiredException()) {
+ throw new SessionExpiredException(effect);
+ }
+ }
+
+ throw effect;
+ }
+
+ /**
+ * Get the request URI, relative to the URI of the given PageFlowController.
+ *
+ * @param relativeTo a PageFlowController to which the returned URI should be relative, or
+ * <code>null</code> if the returned URI should be relative to the webapp root.
+ */
+ public static final String getRelativeURI(PageFlowController relativeTo) {
+ PageFlowActionContext actionContext = PageFlowActionContext.get();
+ if (relativeTo == null) return actionContext.getRequestPath();
+ return getRelativeURI(actionContext.getRequestURI(), relativeTo);
+ }
+
+ /**
+ * Get a URI relative to the URI of the given PageFlowController.
+ *
+ * @param uri the URI which should be made relative.
+ * @param relativeTo a PageFlowController to which the returned URI should be relative, or
+ * <code>null</code> if the returned URI should be relative to the webapp root.
+ */
+ public static final String getRelativeURI(String uri, PageFlowController relativeTo) {
+ String contextPath = PageFlowActionContext.get().getRequestPath();
+ if (relativeTo != null) contextPath += relativeTo.getNamespace();
+ int overlap = uri.indexOf(contextPath + '/');
+ if (overlap == -1) return null;
+ return uri.substring(overlap + contextPath.length());
+ }
+
+ /**
+ * Set the forwarded form. This overrides the auto-generated form created by processActionForm
+ * and populated by processPopulate (in PageFlowRequestProcessor).
+ */
+ public static void setForwardedFormBean(Object formBean) {
+ if (formBean == null) {
+ getWebContext().getRequestScope().remove(FORWARDED_FORMBEAN_ATTR);
+ } else {
+ getWebContext().getRequestScope().put(FORWARDED_FORMBEAN_ATTR, formBean);
+ }
+ }
+
+ public static Object getForwardedFormBean(boolean removeFromRequest) {
+ Map requestScope = getWebContext().getRequestScope();
+ Object form = requestScope.get(FORWARDED_FORMBEAN_ATTR);
+ if (removeFromRequest) requestScope.remove(FORWARDED_FORMBEAN_ATTR);
+ return form;
+ }
+
+ /**
+ * Tell whether a special request attribute was set, indicating that we should avoid writing to the response (or
+ * setting response error codes).
+ */
+ public static boolean avoidDirectResponseOutput() {
+ Boolean avoid = (Boolean) getWebContext().getRequestScope().get(AVOID_DIRECT_RESPONSE_OUTPUT_ATTR);
+ return avoid != null && avoid.booleanValue();
+ }
+
+ /**
+ * Set a special request attribute to indicate that we should avoid writing to the response (or
+ * setting response error codes).
+ */
+ public static void setAvoidDirectResponseOutput() {
+ getWebContext().getRequestScope().put(AVOID_DIRECT_RESPONSE_OUTPUT_ATTR, Boolean.TRUE);
+ }
+
+ /**
+ * Set the module prefix for the ModuleConfig that is performing a forward in this request.
+ */
+ public static void setForwardingModule(String modulePrefix) {
+ getWebContext().getRequestScope().put(FORWARDING_MODULE_ATTR, modulePrefix);
+ }
+
+ /**
+ * Set the module prefix for the ModuleConfig that is performing a forward in this request.
+ */
+ public static String getForwardingModule() {
+ return (String) getWebContext().getRequestScope().get(FORWARDING_MODULE_ATTR);
+ }
+
+ /**
+ * Tell {@link #getRequestPath} (and all that call it) to ignore the attribute that specifies the Servlet
+ * Include path, which is set when a Servlet include is done through RequestDispatcher. Normally,
+ * getDecodedServletPath tries the Servlet Include path before falling back to getServletPath() on the request.
+ * Note that this is basically a stack of instructions to ignore the include path, and this method expects each
+ * call with <code>ignore</code>==<code>true</code> to be balanced by a call with
+ * <code>ignore</code>==<code>false</code>.
+ */
+ /* TODO: re-add for page template support
+ public static void setIgnoreIncludeServletPath( boolean ignore )
+ {
+ Map requestScope = getWebContext().getRequestScope();
+ Integer depth = ( Integer ) requestScope.get( IGNORE_INCLUDE_SERVLET_PATH_ATTR );
+
+ if ( ignore )
+ {
+ if ( depth == null ) depth = new Integer( 0 );
+ requestScope.put( IGNORE_INCLUDE_SERVLET_PATH_ATTR, new Integer( depth.intValue() + 1 ) );
+ }
+ else
+ {
+ assert depth != null : "call to setIgnoreIncludeServletPath() was imbalanced";
+ depth = new Integer( depth.intValue() - 1 );
+
+ if ( depth.intValue() == 0 )
+ {
+ requestScope.remove( IGNORE_INCLUDE_SERVLET_PATH_ATTR );
+ }
+ else
+ {
+ requestScope.put( IGNORE_INCLUDE_SERVLET_PATH_ATTR, depth );
+ }
+ }
+ }
+ */
+
+ public static boolean ignoreIncludeServletPath() {
+ return getWebContext().getRequestScope().get(IGNORE_INCLUDE_SERVLET_PATH_ATTR) != null;
+ }
+
+ /**
+ * Set the given Struts module in the request, and expose its set of MessageResources as request attributes.
+ *
+ * @param namespace the namespace of the desired module.
+ * @return the selected ModuleConfig, or <code>null</code> if there is none for the given module prefix.
+ */
+ public static ModuleConfig selectModule(String namespace) {
+ ModuleRegistrationHandler mrh = Handlers.get().getModuleRegistrationHandler();
+ return selectModule(mrh.getModuleConfig(namespace));
+ }
+
+ public static ModuleConfig selectModule(ModuleConfig config) {
+ PageFlowActionContext actionContext = PageFlowActionContext.get();
+
+ if (config == null) {
+ actionContext.setModuleConfig(null);
+ return null;
+ }
+
+ // Just return it if it's already registered.
+ if (actionContext.getModuleConfig() == config) return config;
+ actionContext.setModuleConfig(config);
+
+ /* TODO: re-add messages support
+ MessageResourcesConfig[] mrConfig = config.findMessageResourcesConfigs();
+ Object formBean = PageFlowActionContext.getContext().getAction().getFormBean();
+
+ for ( int i = 0; i < mrConfig.length; i++ )
+ {
+ String key = mrConfig[i].getKey();
+ MessageResources resources = ( MessageResources ) servletContext.getAttribute( key + prefix );
+
+ if ( resources != null )
+ {
+ if ( ! ( resources instanceof ExpressionAwareMessageResources ) )
+ {
+ resources = new ExpressionAwareMessageResources( resources, formBean, request, servletContext );
+ }
+
+ requestScope.put( key, resources );
+ }
+ else
+ {
+ requestScope.remove( key );
+ }
+ }
+ */
+
+ return config;
+ }
+
+ public static MessageResources getMessageResources(String bundleName) {
+ PageFlowActionContext actionContext = PageFlowActionContext.get();
+ MessageResources resources = (MessageResources) actionContext.getRequestScope().get(bundleName);
+
+ if (resources == null) {
+ String qualified = getQualifiedBundleName(bundleName);
+ resources = (MessageResources) getWebContext().getApplicationScope().get(qualified);
+ }
+
+ // If we can't find resources with this name, try them at the root (unqualified).
+ if (resources == null) resources = (MessageResources) getWebContext().getApplicationScope().get(bundleName);
+
+ return resources;
+ }
+
+ /**
+ * Qualify the given bundle name with the current namespace to return a full bundle name.
+ *
+ * @return the qualified Bundle name
+ */
+ public static String getQualifiedBundleName(String bundleName) {
+ if (bundleName != null) {
+ if (bundleName.indexOf('/') == -1) {
+ PageFlowActionContext actionContext = PageFlowActionContext.get();
+ ModuleConfig mc = actionContext.getModuleConfig();
+
+ // Note that we don't append the namespace for the root module.
+ if (mc != null && mc.getNamespace() != null && mc.getNamespace().length() > 1) {
+ bundleName += mc.getNamespace();
+ }
+ } else if (bundleName.endsWith("/")) {
+ // Special handling for bundles referring to the root module
+ bundleName = bundleName.substring(0, bundleName.length() - 1);
+ }
+ }
+
+ return bundleName;
+ }
+
+ public static Locale lookupLocale() {
+ WebContext webContext = getWebContext();
+ Locale locale = (Locale) webContext.getSessionScope().get(Globals.LOCALE_KEY);
+ if (locale == null && webContext instanceof ServletWebContext) {
+ locale = ((ServletWebContext) webContext).getRequest().getLocale();
+ }
+ return locale;
+ }
+
+ /**
+ * If the request is a ScopedRequest, this returns an attribute name scoped to
+ * that request's scope-ID; otherwise, it returns the given attribute name.
+ */
+ public static String getScopedAttrName(String attrName) {
+ // Now, this is simply handled by the ActionContext implementation. If it needs to wrap session attribute
+ // names, it does.
+
+ /*
+ String requestScopeParam = request.getParameter( SCOPE_ID_PARAM );
+
+ if ( requestScopeParam != null )
+ {
+ return getScopedName( attrName, requestScopeParam );
+ }
+
+ ScopedRequest scopedRequest = unwrapRequest( request );
+ return scopedRequest != null ? scopedRequest.getScopedName( attrName ) : attrName;
+ */
+ return attrName;
+ }
+
+}
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/JavaControlUtils.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/JavaControlUtils.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/JavaControlUtils.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/JavaControlUtils.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+import org.apache.ti.pageflow.ControlFieldInitializationException;
+import org.apache.ti.pageflow.PageFlowManagedObject;
+
+import java.util.Map;
+
+
+public class JavaControlUtils {
+
+ /* TODO: re-add Controls support (as a Handler)
+
+ private static final Logger _log = Logger.getInstance( JavaControlUtils.class );
+ private static final String CONTROL_CONTEXT_CLASSNAME = ServletBeanContext.class.getName();
+ private static final String CONTROL_ANNOTATION_CLASSNAME = Control.class.getName();
+
+ /** Map of control-container-class (e.g., PageFlowController) to Map of fields/control-properties. *
+ private static InternalConcurrentHashMap/*< String, Map< Field, PropertyMap > >* _controlFieldCache =
+ new InternalConcurrentHashMap/*< String, Map< Field, PropertyMap > >*();
+
+ */
+ public static void initializeControlContext() {
+ /*
+ ControlBeanContext beanContext = getControlBeanContext( request, response, servletContext, true );
+
+ //
+ // Start a new execution context
+ //
+ if ( beanContext instanceof ServletBeanContext )
+ {
+ ( ( ServletBeanContext ) beanContext ).beginContext( servletContext, request, response );
+ }
+ */
+ }
+
+ public static void uninitializeControlContext() {
+ /*
+ ControlBeanContext beanContext = getControlBeanContext( request, response, servletContext, false );
+
+ if ( beanContext instanceof ServletBeanContext )
+ {
+ ( ( ServletBeanContext ) beanContext ).endContext();
+ }
+ */
+ }
+
+ /*
+ public static class ControlInstantiationException
+ extends Exception
+ {
+ private String _controlBeanClassName;
+
+ public ControlInstantiationException( String controlBeanClassName, Throwable cause_ )
+ {
+ super( cause_ );
+ _controlBeanClassName = controlBeanClassName;
+ }
+
+ public String getControlBeanClassName()
+ {
+ return _controlBeanClassName;
+ }
+ }
+
+ private static ControlBeanContext getControlBeanContext( HttpServletRequest request, HttpServletResponse response,
+ ServletContext servletContext, boolean createIfMissing )
+ {
+ //
+ // Retrieve the control bean context from the request, and if it's not there, from the session.
+ // Using the request first ensures that we don't get confused by session invalidation.
+ //
+ ControlBeanContext beanContext = ( ControlBeanContext ) request.getAttribute( CONTROL_CONTEXT_CLASSNAME );
+ if ( beanContext != null ) return beanContext;
+
+ HttpSession session = request.getSession( false );
+ if ( session != null )
+ {
+ beanContext = ( ControlBeanContext ) session.getAttribute( CONTROL_CONTEXT_CLASSNAME );
+
+ if ( beanContext != null )
+ {
+ request.setAttribute( CONTROL_CONTEXT_CLASSNAME, beanContext );
+ return beanContext;
+ }
+ }
+
+ //
+ // If no context exists, then create a new one and store it in the session.
+ //
+ if ( createIfMissing )
+ {
+ beanContext = ( ControlBeanContext )
+ AdapterManager.getContainerAdapter( servletContext ).createControlBeanContext( request, response );
+ request.getSession().setAttribute( CONTROL_CONTEXT_CLASSNAME, beanContext );
+ request.setAttribute( CONTROL_CONTEXT_CLASSNAME, beanContext );
+ }
+
+ return beanContext;
+ }
+
+ */
+ public static void destroyControl(Object controlInstance) {
+ /*
+ assert controlInstance instanceof ControlBean : controlInstance.getClass().getName();
+ BeanContext beanContext = ( ( ControlBean ) controlInstance ).getBeanContext();
+ if ( beanContext != null ) beanContext.remove( controlInstance );
+ */
+ }
+
+
+ /**
+ * @return a map of Field (accessible) -> AnnotationMap
+ */
+ private static Map getAccessibleControlFieldAnnotations(Class controlContainerClass) {
+ /*
+ String className = controlContainerClass.getName();
+
+ //
+ // Reading the annotations is expensive. See if there's a cached copy of the map.
+ //
+ Map/*< Field, PropertyMap >* cached = ( Map ) _controlFieldCache.get( className );
+
+ if ( cached != null )
+ {
+ return cached;
+ }
+
+
+ HashMap/*< Field, PropertyMap >* ret = new HashMap/*< Field, PropertyMap >*();
+ boolean accessPrivateFields = true;
+
+ // Note that the annnotation reader doesn't change per-class. Inherited annotated elements are all read.
+ AnnotationReader annReader = AnnotationReader.getAnnotationReader( controlContainerClass, servletContext );
+
+ //
+ // Go through this class and all superclasses, looking for control fields. Make sure that a superclass control
+ // field never replaces a subclass control field (this is what the 'fieldNames' HashSet is for).
+ //
+
+ HashSet fieldNames = new HashSet();
+
+ do
+ {
+ Field[] fields = controlContainerClass.getDeclaredFields();
+
+ for ( int i = 0; i < fields.length; i++ )
+ {
+ Field field = fields[i];
+ String fieldName = field.getName();
+ int modifiers = field.getModifiers();
+
+ if ( ! fieldNames.contains( fieldName ) && ! Modifier.isStatic( modifiers )
+ && annReader.getAnnotation( field.getName(), CONTROL_ANNOTATION_CLASSNAME ) != null )
+ {
+ if ( accessPrivateFields || ! Modifier.isPrivate( modifiers ) )
+ {
+ if ( ! Modifier.isPublic( field.getModifiers() ) ) field.setAccessible( true );
+ ret.put( field, new AnnotatedElementMap( field ) );
+ fieldNames.add( fieldName );
+ }
+ }
+ }
+
+ accessPrivateFields = false;
+ controlContainerClass = controlContainerClass.getSuperclass();
+ } while ( controlContainerClass != null );
+
+ _controlFieldCache.put( className, ret );
+ return ret;
+ */
+
+ return null;
+ }
+
+ /**
+ * Initialize all null member variables that are Java Controls.
+ */
+ public static void initJavaControls(PageFlowManagedObject controlClient)
+ throws ControlFieldInitializationException {
+ /*
+ Class controlClientClass = controlClient.getClass();
+
+ //
+ // First, just return if there are no annotated Control fields. This saves us from having to catch a
+ // (wrapped) ClassNotFoundException for the control client initializer if we were to simply call
+ // Controls.initializeClient().
+ //
+ Map controlFields = getAccessibleControlFieldAnnotations( controlClientClass, servletContext );
+ if ( controlFields.isEmpty() ) return;
+
+ request = PageFlowUtils.unwrapMultipart( request );
+ ControlBeanContext beanContext = getControlBeanContext( request, response, servletContext, false );
+ assert beanContext != null : "ControlBeanContext was not initialized by PageFlowRequestProcessor";
+ try
+ {
+ Controls.initializeClient(null, controlClient, beanContext);
+ }
+ catch ( Exception e )
+ {
+ _log.error( "Exception occurred while initializing controls", e);
+ throw new ControlFieldInitializationException( controlClientClass.getName(), controlClient, e );
+ }
+ */
+ }
+
+ /**
+ * Clean up all member variables that are Java Controls.
+ */
+ public static void uninitJavaControls(PageFlowManagedObject controlClient) {
+ /*
+ Map controlFields = getAccessibleControlFieldAnnotations( controlClient.getClass(), servletContext );
+
+ for ( Iterator i = controlFields.keySet().iterator(); i.hasNext(); )
+ {
+ Field controlField = ( Field ) i.next();
+
+ try
+ {
+ Object fieldValue = controlField.get( controlClient );
+
+ if ( fieldValue != null )
+ {
+ controlField.set( controlClient, null );
+ destroyControl( fieldValue );
+ }
+ }
+ catch ( IllegalAccessException e )
+ {
+ _log.error( "Exception while uninitializing Java Control " + controlField.getName(), e );
+ }
+ }
+ */
+ }
+}
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/NavigateToException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/NavigateToException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/NavigateToException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/NavigateToException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+import org.apache.ti.pageflow.FlowController;
+import org.apache.ti.pageflow.FlowControllerException;
+import org.apache.ti.pageflow.xwork.NavigateToResult;
+
+public abstract class NavigateToException extends FlowControllerException {
+
+ private String _returnToType;
+
+
+ protected NavigateToException(NavigateToResult result, FlowController fc) {
+ super(fc);
+ _returnToType = result.getNavigateToAsString();
+ }
+
+ public String getReturnToType() {
+ return _returnToType;
+ }
+
+ protected Object[] getMessageArgs() {
+ return new Object[]{_returnToType, getActionName(), getFlowControllerURI()};
+ }
+
+ protected abstract String[] getMessageParts();
+
+ /**
+ * Tell whether the root cause may be session expiration in cases where the requested session ID is different than
+ * the actual session ID. In this case, the answer is <code>true</code>.
+ */
+ public boolean causeMayBeSessionExpiration() {
+ return true;
+ }
+}
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/NullActionForm.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/NullActionForm.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/NullActionForm.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/NullActionForm.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * ActionForm/Map that stores no properties and emits no errors.
+ */
+public class NullActionForm implements Map {
+
+ public int size() {
+ return 0;
+ }
+
+ public boolean isEmpty() {
+ return true;
+ }
+
+ public boolean containsKey(Object key) {
+ return false;
+ }
+
+ public boolean containsValue(Object value) {
+ return false;
+ }
+
+ public Object get(Object key) {
+ return null;
+ }
+
+ public Object put(Object o, Object o1) {
+ return null;
+ }
+
+ public Object remove(Object key) {
+ return null;
+ }
+
+ public void putAll(Map map) {
+ }
+
+ public void clear() {
+ }
+
+ public Set keySet() {
+ return Collections.EMPTY_SET;
+ }
+
+ public Collection values() {
+ return Collections.EMPTY_LIST;
+ }
+
+ public Set entrySet() {
+ return Collections.EMPTY_SET;
+ }
+}
+
+
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/PageFlowBeanContext.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/PageFlowBeanContext.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/PageFlowBeanContext.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/PageFlowBeanContext.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+
+
+/**
+ * Specialization of the base ServletBeanContext that adds a Page Flow service provider to offer
+ * initialization for PageFlowController and SharedFlowControler members in a Control.
+ */
+public class PageFlowBeanContext {
+
+}
+
+/* TODO: re-add this, under a controls-support module
+ extends ServletBeanContext
+ implements PageFlowServiceProvider.HasServletRequest
+{
+ public ServletRequest getServletRequest()
+ {
+ return super.getServletRequest();
+ }
+
+ /**
+ * Called by BeanContextSupport superclass during construction and deserialization to
+ * initialize subclass transient state
+ *
+ public void initialize()
+ {
+ super.initialize();
+ addService( PageFlowController.class, PageFlowServiceProvider.getProvider() );
+ }
+}
+*/
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/PageFlowServiceProvider.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/PageFlowServiceProvider.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/PageFlowServiceProvider.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/PageFlowServiceProvider.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+import org.apache.ti.pageflow.PageFlowController;
+import org.apache.ti.pageflow.PageFlowUtils;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import java.beans.beancontext.BeanContextServiceProvider;
+import java.beans.beancontext.BeanContextServices;
+import java.util.Iterator;
+
+
+/**
+ * Service provider that offers initialization for PageFlowController and SharedFlowControler members in a Control.
+ */
+public class PageFlowServiceProvider implements BeanContextServiceProvider {
+
+ private static final PageFlowServiceProvider _provider = new PageFlowServiceProvider();
+
+ public static final PageFlowServiceProvider getProvider() {
+ return _provider;
+ }
+
+ private PageFlowServiceProvider() {
+ }
+
+ public static interface HasServletRequest {
+
+ ServletRequest getServletRequest();
+ }
+
+ public Object getService(BeanContextServices bcs, Object requestor, Class serviceClass,
+ Object serviceSelector) {
+ //
+ // These services are only available to controls running within the scope of a PageFlowBeanContext
+ //
+ if (!(bcs instanceof HasServletRequest)) return null;
+
+ if (PageFlowController.class.equals(serviceClass)) {
+ ServletRequest request = ((HasServletRequest) bcs).getServletRequest();
+ if (!(request instanceof HttpServletRequest)) return null;
+ return PageFlowUtils.getCurrentPageFlow();
+ }
+
+ return null;
+ }
+
+ public void releaseService(BeanContextServices bcs, Object requestor, Object service) {
+ }
+
+ public Iterator getCurrentServiceSelectors(BeanContextServices bcs, Class serviceClass) {
+ return null;
+ }
+}
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/ProcessPopulate.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/ProcessPopulate.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/ProcessPopulate.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/ProcessPopulate.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,326 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+import org.apache.ti.pageflow.RequestParameterHandler;
+import org.apache.ti.pageflow.xwork.PageFlowActionContext;
+import org.apache.ti.script.Expression;
+import org.apache.ti.script.ExpressionEvaluator;
+import org.apache.ti.script.ExpressionEvaluatorFactory;
+import org.apache.ti.script.ExpressionUpdateException;
+import org.apache.ti.script.common.ImplicitObjectUtil;
+import org.apache.ti.util.Bundle;
+import org.apache.ti.util.internal.InternalStringBuilder;
+import org.apache.ti.util.logging.Logger;
+
+import javax.servlet.jsp.el.VariableResolver;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Implement the processPopulate stage of the Struts / PageFlow request
+ * processing lifecycle. The {@link #populate(Object, boolean)} method is
+ * invoked in order to take request parameters from the request
+ * use the key / value pairs from the request to perform an update to the underlying
+ * JavaBean objects.
+ * <br/>
+ * <br/>
+ * Updates are performed on a key / value pair if the key is an expression; otherwise,
+ * the updates are delegated to the Struts processPopulate infrastructure.
+ */
+public class ProcessPopulate {
+
+ /**
+ * This defines the name of the parameter that will contain the NetUI ID map..
+ */
+ public static final String IDMAP_PARAMETER_NAME = "netuiIdMap";
+
+ private static final Logger _logger = Logger.getInstance(ProcessPopulate.class);
+
+ // these must be kept in sync with the context names specified in the scripting languages
+ private static final String PAGE_FLOW_CONTEXT = "pageFlow";
+ private static final String GLOBAL_APP_CONTEXT = "globalApp";
+
+ private static final String WLW_TAG_HANDLER_PREFIX = "wlw-";
+ private static final String WLW_TAG_HANDLER_SUFFIX = ":";
+
+ private static final Map handlerMap = new HashMap();
+
+ /**
+ * An inner class that represnts the data that will be used to
+ * perform an update. If a key has a prefix handler, this
+ * node is constructed and passed to the prefix handler
+ * so that the prefix handler can change the expression or
+ * values that will be used to execute the expression update.
+ */
+ public final static class ExpressionUpdateNode {
+
+ public String expression = null;
+ public String[] values = null;
+
+ // can't be constructed outside of this class
+ private ExpressionUpdateNode() {
+ }
+
+ public String toString() {
+ InternalStringBuilder buf = new InternalStringBuilder();
+ buf.append("expression: " + expression + "\n");
+ if (values != null)
+ for (int i = 0; i < values.length; i++)
+ buf.append("value[" + i + "]: " + values[i]);
+ else
+ buf.append("values are null");
+
+ return buf.toString();
+ }
+ }
+
+ /**
+ * Register a {@link org.apache.ti.pageflow.RequestParameterHandler} that is added to handle a
+ * particular prefix which be present as a prefix to a request parameter
+ * key. For keys that match the prefix, the key / value from the request
+ * are put in an {@link ExpressionUpdateNode} struct and handed to the
+ * {@link org.apache.ti.pageflow.RequestParameterHandler} for processing. The returned {@link ExpressionUpdateNode}
+ * is used to perform an expression update.
+ *
+ * @param prefix the String prefix that will be appended to request paramters that
+ * should pass through the {@link org.apache.ti.pageflow.RequestParameterHandler} before being updated.
+ * @param handler the handler that should handle all request paramters with
+ * the given <code>prefix</code>
+ */
+ public static void registerPrefixHandler(String prefix, RequestParameterHandler handler) {
+ // should happen very infrequently
+ synchronized (handlerMap) {
+ String msg = "Register RequestParameterHandler with\n\tprefix: " + prefix + "\n\thandler: " + (handler != null ? handler.getClass().getName() : null);
+
+ if (_logger.isInfoEnabled()) _logger.info(msg);
+
+ if (handlerMap.get(prefix) == null)
+ handlerMap.put(prefix, handler);
+ }
+ }
+
+ /**
+ * Write the handler name specified onto the given expression.
+ */
+ public static String writeHandlerName(String handler, String expression) {
+ if (!ExpressionEvaluatorFactory.getInstance().isExpression(expression))
+ throw new IllegalArgumentException(Bundle.getErrorString("ProcessPopulate_handler_nonAtomicExpression", new Object[]{expression}));
+
+ if (!handlerMap.containsKey(handler))
+ throw new IllegalStateException(Bundle.getErrorString("ProcessPopulate_handler_notRegistered", new Object[]{handler}));
+
+ InternalStringBuilder buf = new InternalStringBuilder();
+ buf.append(WLW_TAG_HANDLER_PREFIX);
+ buf.append(handler);
+ buf.append(WLW_TAG_HANDLER_SUFFIX);
+ buf.append(expression);
+
+ return buf.toString();
+ }
+
+ /**
+ * Use the request parameters to populate all properties that have expression keys into
+ * the underlying JavaBeans.
+ * Creates a <code>java.util.Map</code> of objects that will be consumed by
+ * Struts processPopulate. This includes all request attributes that
+ * were not expressions
+ *
+ * @param form if this request references an action and it has an <code>ActionForm</code>
+ * associated with it, then the <code>form</code> parameter is non-null.
+ */
+ public static void populate(Object form, boolean requestHasPopulated) {
+ String key = null;
+ Map strutsProperties = null;
+ ExpressionEvaluator ee = ExpressionEvaluatorFactory.getInstance();
+ PageFlowActionContext actionContext = PageFlowActionContext.get();
+
+ // a boolean so that we can avoid an instanceof below...
+ boolean isMultipart = false;
+
+ // if this returns null, it's not a mulitpart request
+ // TODO: re-add multipart request support
+ //Map params = MultipartRequestUtils.handleMultipartRequest(request, form);
+ Map params = null;
+
+ // make adjustments
+ if (params != null)
+ isMultipart = true;
+ else
+ params = actionContext.getParameters();
+
+ if (params == null) {
+ if (_logger.isWarnEnabled()) _logger.warn("An error occurred checking a request for multipart status. No model values were updated.");
+ return;
+ }
+
+ /* explicitly build a variable resolver that is used to provide objects that may be updated to the expression engine */
+ VariableResolver variableResolver = ImplicitObjectUtil.getUpdateVariableResolver(form, true);
+
+ /* todo: are there any ordering issues with using an Iterator vs. an Enumeration here? */
+ Iterator iterator = params.keySet().iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ String expr = null;
+
+ // if there is an expression map, lookup the real expression from the name
+ expr = key;
+ if (_logger.isDebugEnabled())
+ _logger.debug("key: " + key + " value type: " + params.get(key).getClass().getName() + " value: " + params.get(key));
+
+ try {
+ Object paramsValue = params.get(key);
+ if (ee.containsExpression(expr)) {
+ Object updateValue = null;
+ if (!isMultipart || paramsValue instanceof String[]) {
+ String[] values = (String[]) paramsValue;
+
+ // the only "contains" case that is accepted
+ if (expr.startsWith(WLW_TAG_HANDLER_PREFIX)) {
+ if (_logger.isDebugEnabled()) _logger.debug("Found an expression requiring a TAG HANDLER");
+
+ ExpressionUpdateNode node = doTagHandler(key, expr, values);
+
+ expr = node.expression;
+ values = node.values;
+ }
+
+ if (values != null && values.length == 1)
+ updateValue = values[0];
+ else
+ updateValue = values;
+ }
+ // handle funky types that Struts returns for a file upload request handler
+ else {
+ updateValue = params.get(key);
+ }
+
+ try {
+ // trap any bad expressions here
+ if (ee.isExpression(expr)) {
+ // common case, make this fast
+ if (!requestHasPopulated)
+ ee.update(expr, updateValue, variableResolver, true);
+ // must check the expression to make sure pageFlow. and globalApp. don't get executed more than once
+ else {
+ Expression pe = ee.parseExpression(expr);
+ String contextName = pe.getContext();
+ if (!contextName.equals(PAGE_FLOW_CONTEXT) && !contextName.equals(GLOBAL_APP_CONTEXT))
+ ee.update(expr, updateValue, variableResolver, true);
+ }
+ }
+ }
+ // catch any errors, particularly expression parse failures
+ catch (ExpressionUpdateException e) {
+ String s = Bundle.getString("ExprUpdateError", new Object[]{expr, e});
+
+ // this is the hairy NetUI Warning that gets printed to the console
+ System.err.println(s);
+ if (_logger.isErrorEnabled()) _logger.error(s);
+
+ // add binding errors via PageFlowUtils
+ InternalUtils.addBindingUpdateError(expr, s, e);
+ }
+ } else {
+ if (_logger.isDebugEnabled()) _logger.debug("HTTP request parameter key \"" + key + "\" is not an expression, handle with Struts");
+
+ if (strutsProperties == null)
+ strutsProperties = new HashMap();
+
+ strutsProperties.put(key, paramsValue);
+ }
+ }
+ // catch any unexpected exception
+ catch (Exception e) {
+ String s = Bundle.getString("ProcessPopulate_exprUpdateError", new Object[]{expr, e});
+ //e.printStackTrace();
+
+ System.err.println(s);
+
+ if (_logger.isWarnEnabled()) _logger.warn(s, e);
+
+ // add binding errors via PageFlowUtils
+ InternalUtils.addBindingUpdateError(expr, s, e);
+ }
+ }
+
+ //handleStrutsProperties(strutsProperties, form);
+ }
+
+ /**
+ * Process a single key.
+ *
+ * @param key the request key that is being processed
+ */
+ static final ExpressionUpdateNode doTagHandler(String key, String expression, String[] values) {
+ // not sure if this array will be mutable. don't want to find out at this point.
+ String[] _values = values;
+
+ // key might be mangled here; make a copy
+ String expr = expression;
+
+ if (_logger.isDebugEnabled()) _logger.debug("Found prefixed tag; handlerName: " + key.substring(WLW_TAG_HANDLER_PREFIX.length(), key.indexOf(WLW_TAG_HANDLER_SUFFIX)));
+
+ String handlerName = expression.substring(WLW_TAG_HANDLER_PREFIX.length(), expression.indexOf(WLW_TAG_HANDLER_SUFFIX));
+
+ // execute callback to parameter handler. Generally, these are tags.
+ RequestParameterHandler handler = (RequestParameterHandler) handlerMap.get(handlerName);
+
+ if (handler != null) {
+ expr = expression.substring(expression.indexOf(WLW_TAG_HANDLER_SUFFIX) + 1);
+
+ if (_logger.isDebugEnabled())
+ _logger.debug("found handler for prefix \"" + handlerName + "\" type: " +
+ (handler != null ? handler.getClass().getName() : null) + "\n\t" +
+ "key: \"" + key + "\" expr: \"" + expr + "\"");
+
+ ExpressionUpdateNode node = new ExpressionUpdateNode();
+ node.expression = expr;
+ node.values = _values;
+
+ // request, request key, the standalone expression (may have other stuff bracketing the expression
+ handler.process(key, expression, node);
+
+ return node;
+ } else
+ throw new IllegalStateException("Request parameter references a tag handler prefix \"" +
+ handlerName + "\" that is not registered for expression \"" + key + "\"");
+ }
+
+ /*
+ // @struts: org.apache.struts.util.RequestUtils.populate
+ private static final void handleStrutsProperties(Map strutsProperties, ActionForm form)
+ {
+ if(strutsProperties != null)
+ {
+ if(_logger.isDebugEnabled()) _logger.debug("Handle Struts request parameters.");
+
+ // default to Struts for non-expression keys
+ try
+ {
+ BeanUtils.populate(form, strutsProperties);
+ }
+ catch(Exception e)
+ {
+ throw new RuntimeException("Exception processing bean and request parameters: ", e);
+ }
+ }
+ }
+ */
+}
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/ResponseOutputException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/ResponseOutputException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/ResponseOutputException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/ResponseOutputException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+/**
+ * Unchecked exception thrown in situations where output would normally be written to the response,
+ * but when the runtime is configured to throw an exception instead.
+ */
+public class ResponseOutputException extends RuntimeException {
+
+ public ResponseOutputException(String msg) {
+ super(msg);
+ }
+
+ public ResponseOutputException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+}
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/SimpleSessionStorageHandler.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/SimpleSessionStorageHandler.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/SimpleSessionStorageHandler.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/SimpleSessionStorageHandler.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+import org.apache.ti.pageflow.handler.StorageHandler;
+import org.apache.ti.pageflow.xwork.PageFlowActionContext;
+
+import java.util.Map;
+
+/**
+ * This storage handler simply puts/gets attributes in the session. It does not do anything to support multiple
+ * concurrent forwarded requests that are simultaneously modifying session data.
+ *
+ * @see DeferredSessionStorageHandler
+ */
+public class SimpleSessionStorageHandler
+ extends DefaultHandler
+ implements StorageHandler {
+
+ public SimpleSessionStorageHandler() {
+ }
+
+ public void setAttribute(String attributeName, Object value) {
+ Map sessionScope = PageFlowActionContext.get().getSession();
+ sessionScope.put(attributeName, value);
+ }
+
+ public void removeAttribute(String attributeName) {
+ Map sessionScope = PageFlowActionContext.get().getSession();
+ sessionScope.remove(attributeName);
+ }
+
+ public Object getAttribute(String attributeName) {
+ Map sessionScope = PageFlowActionContext.get().getSession();
+ return sessionScope.get(attributeName);
+ }
+
+ public void ensureFailover(String attributeName, Object value) {
+ AdapterManager.getContainerAdapter().ensureFailover(attributeName, value);
+ }
+
+ public boolean allowBindingEvent(Object event) {
+ return true;
+ }
+
+ public Object getStorageLocation() {
+ // TODO: create a Servlet version of this class that returns the actual session object
+ return PageFlowActionContext.get().getSession();
+ }
+
+ public void applyChanges() {
+ }
+}
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/URIContextFactory.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/URIContextFactory.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/URIContextFactory.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/URIContextFactory.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+import org.apache.ti.core.urls.MutableURI;
+import org.apache.ti.core.urls.URIContext;
+import org.apache.ti.schema.config.UrlConfig;
+import org.apache.ti.util.config.ConfigUtil;
+
+/**
+ * Factory for the {@link URIContext} with the data needed to write out
+ * a string form of a {@link MutableURI}.
+ */
+public final class URIContextFactory {
+
+ /* do not construct */
+ private URIContextFactory() {
+ }
+
+ /**
+ * Get a URIContext. The context has data used to write a MutableURI
+ * as a string. For example, it will indicate that the URI should be
+ * written using the "&amp;" entity, rather than the
+ * character, '&'. This returns the default context, but also
+ * checks for any overriding setting in the NetUI config.
+ *
+ * @return the URIContext
+ */
+ public static final URIContext getInstance() {
+ URIContext uriContext = MutableURI.getDefaultContext();
+ UrlConfig urlConfig = ConfigUtil.getConfig().getUrlConfig();
+
+ if (urlConfig != null && urlConfig.isSetHtmlAmpEntity()) {
+ uriContext.setUseAmpEntity(urlConfig.getHtmlAmpEntity());
+ }
+
+ return uriContext;
+ }
+
+ /**
+ * Get a URIContext. If it's for an XML document type, the context
+ * will indicate that the URI should be written using the
+ * "&amp;" entity, rather than the character, '&'.
+ * If it's not for an XML doc type, then use the default context,
+ * but check for any overriding setting in the NetUI config.
+ *
+ * @param forXML flag indicating that the URI is for an XML doc type
+ * @return the URIContext
+ */
+ public static final URIContext getInstance(boolean forXML) {
+ URIContext uriContext = null;
+
+ if (forXML) {
+ uriContext = new URIContext();
+ uriContext.setUseAmpEntity(true);
+ } else {
+ uriContext = getInstance();
+ }
+
+ return uriContext;
+ }
+}
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/UnhandledException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/UnhandledException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/UnhandledException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/UnhandledException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+import org.apache.ti.pageflow.PageFlowException;
+
+/**
+ * ServletException derivative thrown when an exception occurred during action processing, and the exception was not
+ * handled by any exception handler. This wrapper is used to prevent any outer try/catch blocks from re-processing
+ * the exception.
+ */
+public class UnhandledException
+ extends PageFlowException {
+
+ public UnhandledException(Throwable baseCause) {
+ super(baseCause);
+ }
+}
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/ViewRenderer.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/ViewRenderer.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/ViewRenderer.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/ViewRenderer.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+import java.io.IOException;
+
+public interface ViewRenderer {
+
+ public void init();
+
+ public void renderView()
+ throws IOException;
+}
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/XmlBeanActionForm.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/XmlBeanActionForm.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/XmlBeanActionForm.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/internal/XmlBeanActionForm.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.internal;
+
+import org.apache.ti.util.logging.Logger;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class XmlBeanActionForm {
+
+ private static final Logger _log = Logger.getInstance(XmlBeanActionForm.class);
+
+ private Object _bean;
+ private String _xmlBeanInterfaceClassName;
+
+
+ public XmlBeanActionForm(Object xml, String formClassName) {
+ setBean(xml);
+ _xmlBeanInterfaceClassName = formClassName;
+ }
+
+ public Object getBean() {
+ return _bean;
+ }
+
+ public void setBean(Object bean) {
+ _bean = bean;
+ }
+
+ public String getXmlString() {
+ Object xmlBean = getBean();
+
+ if (xmlBean == null) return null;
+
+ try {
+ return (String) xmlBean.getClass().getMethod("xmlText", (Class[]) null).invoke(xmlBean, (Object[]) null);
+ } catch (InvocationTargetException e) {
+ _log.error("Error while getting XML String", e.getCause());
+ } catch (Exception e) {
+ assert e instanceof NoSuchMethodException || e instanceof IllegalAccessException : e.getClass().getName();
+ _log.error("Error while getting XML String", e);
+ }
+
+ return null;
+ }
+
+ public void setXmlString(String xml) {
+ setBean(invokeFactoryMethod("parse", new Class[]{String.class}, new Object[]{xml}));
+ }
+
+ public void reset() {
+ if (getBean() == null) {
+ setBean(invokeFactoryMethod("newInstance", new Class[0], new Object[0]));
+ }
+ }
+
+ private Object invokeFactoryMethod(String methodName, Class[] argTypes, Object[] args) {
+ String factoryClassName = _xmlBeanInterfaceClassName + "$Factory";
+
+ try {
+ Class factoryClass = Class.forName(factoryClassName);
+ Method newInstanceMethod = factoryClass.getMethod(methodName, argTypes);
+ return newInstanceMethod.invoke(factoryClass, args);
+ } catch (Exception e) {
+ // Can be any exception -- not just the reflection-related exceptions...
+ // because the exception could be thrown while creating the XML bean.
+ if (_log.isErrorEnabled()) {
+ _log.error("Error while creating XML object of type " + _xmlBeanInterfaceClassName, e);
+ }
+
+ return null;
+ }
+ }
+}
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/requeststate/INameable.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/requeststate/INameable.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/requeststate/INameable.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/requeststate/INameable.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.requeststate;
+
+/**
+ * This interface defines what it means to be a namable object. The name
+ * service will name an INameable object which will be unique for the life
+ * time of the session.
+ */
+public interface INameable {
+
+ /**
+ * Set the ObjectName of the INameable object. This should only
+ * be set once. If it is called a second time an IllegalStateException
+ * should be thrown
+ *
+ * @param name the Object's name.
+ * @throws IllegalStateException if this method is called more than once for an object
+ */
+ public void setObjectName(String name);
+
+ /**
+ * Returns the ObjectName of the INameable object.
+ *
+ * @return the ObjectName.
+ */
+ public String getObjectName();
+}
Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/requeststate/NameService.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/requeststate/NameService.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/requeststate/NameService.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/requeststate/NameService.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.requeststate;
+
+import javax.servlet.http.HttpSession;
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+
+/**
+ *
+ */
+public class NameService {
+
+ private static final String NAME_SERVICE = "netui.nameService";
+
+ private HashMap/*<String,WeakReference>*/ _nameMap;
+ private int _nextValue;
+
+ /**
+ * private constructor allowing for a factory method to access NameService objects.
+ */
+ private NameService() {
+ _nameMap = new HashMap/*<String,WeakReference>*/();
+ _nextValue = 0;
+ }
+
+ /**
+ * This will return the session specific instance of a NameService. There
+ * will only be a single NameService per session.
+ *
+ * @param session the HttpSession that contains the NameService
+ * @return the NameService associated with the session.
+ */
+ public static NameService instance(HttpSession session) {
+ // synchronize on the session so we only create a single NameService
+ // within the session.
+ synchronized (session) {
+ NameService nameService = (NameService) session.getAttribute(NAME_SERVICE);
+ if (nameService == null) {
+ nameService = new NameService();
+ session.setAttribute(NAME_SERVICE, nameService);
+ }
+ assert(nameService != null) : "Found invalid null name service";
+ return nameService;
+ }
+ }
+
+ /**
+ * This method will create a unique name for an INameable object. The name
+ * will be unque within the session. This will throw an IllegalStateException
+ * if INameable.setObjectName has previously been called on object.
+ *
+ * @param namePrefix The prefix of the generated name.
+ * @param object the INameable object.
+ * @throws IllegalStateException if this method is called more than once for an object
+ */
+ public synchronized void nameObject(String namePrefix, INameable object) {
+ String name = namePrefix + Integer.toString(_nextValue++);
+ object.setObjectName(name);
+ }
+
+ /**
+ * This is a debug method that will set the next integer value. This is used
+ * so tests can force the name.
+ *
+ * @param val
+ */
+ public void debugSetNameIntValue(int val) {
+ _nextValue = val;
+ }
+
+ /**
+ * @param object
+ */
+ public void put(INameable object) {
+ if (object == null)
+ throw new IllegalStateException("object must not be null");
+ String name = object.getObjectName();
+ if (name == null)
+ throw new IllegalStateException("object has not been named");
+
+ _nameMap.put(name, new WeakReference(object));
+ }
+
+ /**
+ * @param name
+ * @return INameable
+ */
+ public INameable get(String name) {
+ if (name == null)
+ throw new IllegalStateException("name must not be null");
+ WeakReference wr = (WeakReference) _nameMap.get(name);
+ if (wr == null)
+ return null;
+ INameable object = (INameable) wr.get();
+ if (object == null) {
+ _nameMap.remove(name);
+ }
+ return object;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org