You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2011/12/02 17:33:45 UTC
svn commit: r1209569 [13/50] - in /struts/struts2/branches/STRUTS_3_X:
apps/blank/src/main/java/example/ apps/blank/src/test/java/example/
apps/jboss-blank/src/main/java/example/
apps/jboss-blank/src/test/java/example/ apps/mailreader/src/main/java/mai...
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionContext.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionContext.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionContext.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionContext.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,369 @@
+/*
+ * Copyright 2002-2006,2009 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.
+ */
+package org.apache.struts2.xwork2;
+
+import org.apache.struts2.xwork2.inject.Container;
+import org.apache.struts2.xwork2.util.ValueStack;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+
+/**
+ * The ActionContext is the context in which an {@link Action} is executed. Each context is basically a
+ * container of objects an action needs for execution like the session, parameters, locale, etc. <p>
+ * <p/>
+ * The ActionContext is thread local which means that values stored in the ActionContext are
+ * unique per thread. See the {@link ThreadLocal} class for more information. The benefit of
+ * this is you don't need to worry about a user specific action context, you just get it:
+ * <p/>
+ * <ul><code>ActionContext context = ActionContext.getContext();</code></ul>
+ * <p/>
+ * Finally, because of the thread local usage you don't need to worry about making your actions thread safe.
+ *
+ * @author Patrick Lightbody
+ * @author Bill Lynch (docs)
+ */
+public class ActionContext implements Serializable {
+ static ThreadLocal actionContext = new ThreadLocal();
+
+ /**
+ * Constant that indicates the action is running under a "development mode".
+ * This mode provides more feedback that is useful for developers but probably
+ * too verbose/error prone for production.
+ */
+ //public static final String DEV_MODE = "__devMode";
+
+ /**
+ * Constant for the name of the action being executed.
+ */
+ public static final String ACTION_NAME = "org.apache.struts2.xwork2.ActionContext.name";
+
+ /**
+ * Constant for the {@link org.apache.struts2.xwork2.util.ValueStack OGNL value stack}.
+ */
+ public static final String VALUE_STACK = ValueStack.VALUE_STACK;
+
+ /**
+ * Constant for the action's session.
+ */
+ public static final String SESSION = "org.apache.struts2.xwork2.ActionContext.session";
+
+ /**
+ * Constant for the action's application context.
+ */
+ public static final String APPLICATION = "org.apache.struts2.xwork2.ActionContext.application";
+
+ /**
+ * Constant for the action's parameters.
+ */
+ public static final String PARAMETERS = "org.apache.struts2.xwork2.ActionContext.parameters";
+
+ /**
+ * Constant for the action's locale.
+ */
+ public static final String LOCALE = "org.apache.struts2.xwork2.ActionContext.locale";
+
+ /**
+ * Constant for the action's type converter.
+ */
+ public static final String TYPE_CONVERTER = "org.apache.struts2.xwork2.ActionContext.typeConverter";
+
+ /**
+ * Constant for the action's {@link ActionInvocation invocation} context.
+ */
+ public static final String ACTION_INVOCATION = "org.apache.struts2.xwork2.ActionContext.actionInvocation";
+
+ /**
+ * Constant for the map of type conversion errors.
+ */
+ public static final String CONVERSION_ERRORS = "org.apache.struts2.xwork2.ActionContext.conversionErrors";
+
+
+ /**
+ * Constant for the container
+ */
+ public static final String CONTAINER = "org.apache.struts2.xwork2.ActionContext.container";
+
+ Map<String, Object> context;
+
+
+ /**
+ * Creates a new ActionContext initialized with another context.
+ *
+ * @param context a context map.
+ */
+ public ActionContext(Map<String, Object> context) {
+ this.context = context;
+ }
+
+
+ /**
+ * Sets the action invocation (the execution state).
+ *
+ * @param actionInvocation the action execution state.
+ */
+ public void setActionInvocation(ActionInvocation actionInvocation) {
+ put(ACTION_INVOCATION, actionInvocation);
+ }
+
+ /**
+ * Gets the action invocation (the execution state).
+ *
+ * @return the action invocation (the execution state).
+ */
+ public ActionInvocation getActionInvocation() {
+ return (ActionInvocation) get(ACTION_INVOCATION);
+ }
+
+ /**
+ * Sets the action's application context.
+ *
+ * @param application the action's application context.
+ */
+ public void setApplication(Map<String, Object> application) {
+ put(APPLICATION, application);
+ }
+
+ /**
+ * Returns a Map of the ServletContext when in a servlet environment or a generic application level Map otherwise.
+ *
+ * @return a Map of ServletContext or generic application level Map
+ */
+ public Map<String, Object> getApplication() {
+ return (Map<String, Object>) get(APPLICATION);
+ }
+
+ /**
+ * Sets the action context for the current thread.
+ *
+ * @param context the action context.
+ */
+ public static void setContext(ActionContext context) {
+ actionContext.set(context);
+ }
+
+ /**
+ * Returns the ActionContext specific to the current thread.
+ *
+ * @return the ActionContext for the current thread, is never <tt>null</tt>.
+ */
+ public static ActionContext getContext() {
+ return (ActionContext) actionContext.get();
+
+ // Don't do lazy context creation, as it requires container; the creation of which may
+ // precede the context creation
+ //if (context == null) {
+ // ValueStack vs = ValueStackFactory.getFactory().createValueStack();
+ // context = new ActionContext(vs.getContext());
+ // setContext(context);
+ //}
+
+ }
+
+ /**
+ * Sets the action's context map.
+ *
+ * @param contextMap the context map.
+ */
+ public void setContextMap(Map<String, Object> contextMap) {
+ getContext().context = contextMap;
+ }
+
+ /**
+ * Gets the context map.
+ *
+ * @return the context map.
+ */
+ public Map<String, Object> getContextMap() {
+ return context;
+ }
+
+ /**
+ * Sets conversion errors which occurred when executing the action.
+ *
+ * @param conversionErrors a Map of errors which occurred when executing the action.
+ */
+ public void setConversionErrors(Map<String, Object> conversionErrors) {
+ put(CONVERSION_ERRORS, conversionErrors);
+ }
+
+ /**
+ * Gets the map of conversion errors which occurred when executing the action.
+ *
+ * @return the map of conversion errors which occurred when executing the action or an empty map if
+ * there were no errors.
+ */
+ public Map<String, Object> getConversionErrors() {
+ Map<String, Object> errors = (Map) get(CONVERSION_ERRORS);
+
+ if (errors == null) {
+ errors = new HashMap<String, Object>();
+ setConversionErrors(errors);
+ }
+
+ return errors;
+ }
+
+ /**
+ * Sets the Locale for the current action.
+ *
+ * @param locale the Locale for the current action.
+ */
+ public void setLocale(Locale locale) {
+ put(LOCALE, locale);
+ }
+
+ /**
+ * Gets the Locale of the current action. If no locale was ever specified the platform's
+ * {@link java.util.Locale#getDefault() default locale} is used.
+ *
+ * @return the Locale of the current action.
+ */
+ public Locale getLocale() {
+ Locale locale = (Locale) get(LOCALE);
+
+ if (locale == null) {
+ locale = Locale.getDefault();
+ setLocale(locale);
+ }
+
+ return locale;
+ }
+
+ /**
+ * Sets the name of the current Action in the ActionContext.
+ *
+ * @param name the name of the current action.
+ */
+ public void setName(String name) {
+ put(ACTION_NAME, name);
+ }
+
+ /**
+ * Gets the name of the current Action.
+ *
+ * @return the name of the current action.
+ */
+ public String getName() {
+ return (String) get(ACTION_NAME);
+ }
+
+ /**
+ * Sets the action parameters.
+ *
+ * @param parameters the parameters for the current action.
+ */
+ public void setParameters(Map<String, Object> parameters) {
+ put(PARAMETERS, parameters);
+ }
+
+ /**
+ * Returns a Map of the HttpServletRequest parameters when in a servlet environment or a generic Map of
+ * parameters otherwise.
+ *
+ * @return a Map of HttpServletRequest parameters or a multipart map when in a servlet environment, or a
+ * generic Map of parameters otherwise.
+ */
+ public Map<String, Object> getParameters() {
+ return (Map<String, Object>) get(PARAMETERS);
+ }
+
+ /**
+ * Sets a map of action session values.
+ *
+ * @param session the session values.
+ */
+ public void setSession(Map<String, Object> session) {
+ put(SESSION, session);
+ }
+
+ /**
+ * Gets the Map of HttpSession values when in a servlet environment or a generic session map otherwise.
+ *
+ * @return the Map of HttpSession values when in a servlet environment or a generic session map otherwise.
+ */
+ public Map<String, Object> getSession() {
+ return (Map<String, Object>) get(SESSION);
+ }
+
+ /**
+ * Sets the OGNL value stack.
+ *
+ * @param stack the OGNL value stack.
+ */
+ public void setValueStack(ValueStack stack) {
+ put(VALUE_STACK, stack);
+ }
+
+ /**
+ * Gets the OGNL value stack.
+ *
+ * @return the OGNL value stack.
+ */
+ public ValueStack getValueStack() {
+ return (ValueStack) get(VALUE_STACK);
+ }
+
+ /**
+ * Gets the container for this request
+ *
+ * @param cont The container
+ */
+ public void setContainer(Container cont) {
+ put(CONTAINER, cont);
+ }
+
+ /**
+ * Sets the container for this request
+ *
+ * @return The container
+ */
+ public Container getContainer() {
+ return (Container) get(CONTAINER);
+ }
+
+ public <T> T getInstance(Class<T> type) {
+ Container cont = getContainer();
+ if (cont != null) {
+ return cont.getInstance(type);
+ } else {
+ throw new XWorkException("Cannot find an initialized container for this request.");
+ }
+ }
+
+ /**
+ * Returns a value that is stored in the current ActionContext by doing a lookup using the value's key.
+ *
+ * @param key the key used to find the value.
+ * @return the value that was found using the key or <tt>null</tt> if the key was not found.
+ */
+ public Object get(String key) {
+ return context.get(key);
+ }
+
+ /**
+ * Stores a value in the current ActionContext. The value can be looked up using the key.
+ *
+ * @param key the key of the value.
+ * @param value the value to be stored.
+ */
+ public void put(String key, Object value) {
+ context.put(key, value);
+ }
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionEventListener.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionEventListener.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionEventListener.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionEventListener.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2002-2006,2009 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.
+ */
+package org.apache.struts2.xwork2;
+
+import org.apache.struts2.xwork2.util.ValueStack;
+
+/**
+ * Provides hooks for handling key action events
+ */
+public interface ActionEventListener {
+ /**
+ * Called after an action has been created.
+ *
+ * @param action The action
+ * @param stack The current value stack
+ * @return The action to use
+ */
+ public Object prepare(Object action, ValueStack stack);
+
+ /**
+ * Called when an exception is thrown by the action
+ *
+ * @param t The exception/error that was thrown
+ * @param stack The current value stack
+ * @return A result code to execute, can be null
+ */
+ public String handleException(Throwable t, ValueStack stack);
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionInvocation.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionInvocation.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionInvocation.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionInvocation.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2002-2007,2009 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.
+ */
+package org.apache.struts2.xwork2;
+
+import org.apache.struts2.xwork2.interceptor.PreResultListener;
+import org.apache.struts2.xwork2.util.ValueStack;
+
+import java.io.Serializable;
+
+
+/**
+ * An {@link ActionInvocation} represents the execution state of an {@link Action}. It holds the Interceptors and the Action instance.
+ * By repeated re-entrant execution of the <code>invoke()</code> method, initially by the {@link ActionProxy}, then by the Interceptors, the
+ * Interceptors are all executed, and then the {@link Action} and the {@link Result}.
+ *
+ * @author Jason Carreira
+ * @see ActionProxy
+ */
+public interface ActionInvocation extends Serializable {
+
+ /**
+ * Get the Action associated with this ActionInvocation.
+ *
+ * @return the Action
+ */
+ Object getAction();
+
+ /**
+ * Gets whether this ActionInvocation has executed before.
+ * This will be set after the Action and the Result have executed.
+ *
+ * @return <tt>true</tt> if this ActionInvocation has executed before.
+ */
+ boolean isExecuted();
+
+ /**
+ * Gets the ActionContext associated with this ActionInvocation. The ActionProxy is
+ * responsible for setting this ActionContext onto the ThreadLocal before invoking
+ * the ActionInvocation and resetting the old ActionContext afterwards.
+ *
+ * @return the ActionContext.
+ */
+ ActionContext getInvocationContext();
+
+ /**
+ * Get the ActionProxy holding this ActionInvocation.
+ *
+ * @return the ActionProxy.
+ */
+ ActionProxy getProxy();
+
+ /**
+ * If the ActionInvocation has been executed before and the Result is an instance of {@link ActionChainResult}, this method
+ * will walk down the chain of <code>ActionChainResult</code>s until it finds a non-chain result, which will be returned. If the
+ * ActionInvocation's result has not been executed before, the Result instance will be created and populated with
+ * the result params.
+ *
+ * @return the result.
+ * @throws Exception can be thrown.
+ */
+ Result getResult() throws Exception;
+
+ /**
+ * Gets the result code returned from this ActionInvocation.
+ *
+ * @return the result code
+ */
+ String getResultCode();
+
+ /**
+ * Sets the result code, possibly overriding the one returned by the
+ * action.
+ * <p/>
+ * The "intended" purpose of this method is to allow PreResultListeners to
+ * override the result code returned by the Action.
+ * <p/>
+ * If this method is used before the Action executes, the Action's returned
+ * result code will override what was set. However the Action could (if
+ * specifically coded to do so) inspect the ActionInvocation to see that
+ * someone "upstream" (e.g. an Interceptor) had suggested a value as the
+ * result, and it could therefore return the same value itself.
+ * <p/>
+ * If this method is called between the Action execution and the Result
+ * execution, then the value set here will override the result code the
+ * action had returned. Creating an Interceptor that implements
+ * {@link org.apache.struts2.xwork2.interceptor.PreResultListener} will give you this oportunity.
+ * <p/>
+ * If this method is called after the Result has been executed, it will
+ * have the effect of raising an IllegalStateException.
+ *
+ * @param resultCode the result code.
+ * @throws IllegalStateException if called after the Result has been executed.
+ * @see #isExecuted()
+ */
+ void setResultCode(String resultCode);
+
+ /**
+ * Gets the ValueStack associated with this ActionInvocation.
+ *
+ * @return the ValueStack
+ */
+ ValueStack getStack();
+
+ /**
+ * Register a {@link org.apache.struts2.xwork2.interceptor.PreResultListener} to be notified after the Action is executed and
+ * before the Result is executed.
+ * <p/>
+ * The ActionInvocation implementation must guarantee that listeners will be called in
+ * the order in which they are registered.
+ * <p/>
+ * Listener registration and execution does not need to be thread-safe.
+ *
+ * @param listener the listener to add.
+ */
+ void addPreResultListener(PreResultListener listener);
+
+ /**
+ * Invokes the next step in processing this ActionInvocation.
+ * <p/>
+ * If there are more Interceptors, this will call the next one. If Interceptors choose not to short-circuit
+ * ActionInvocation processing and return their own return code, they will call invoke() to allow the next Interceptor
+ * to execute. If there are no more Interceptors to be applied, the Action is executed.
+ * If the {@link ActionProxy#getExecuteResult()} method returns <tt>true</tt>, the Result is also executed.
+ *
+ * @throws Exception can be thrown.
+ * @return the return code.
+ */
+ String invoke() throws Exception;
+
+ /**
+ * Invokes only the Action (not Interceptors or Results).
+ * <p/>
+ * This is useful in rare situations where advanced usage with the interceptor/action/result workflow is
+ * being manipulated for certain functionality.
+ *
+ * @return the return code.
+ * @throws Exception can be thrown.
+ */
+ String invokeActionOnly() throws Exception;
+
+ /**
+ * Sets the action event listener to respond to key action events.
+ *
+ * @param listener the listener.
+ */
+ void setActionEventListener(ActionEventListener listener);
+
+ void init(ActionProxy proxy) ;
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionProxy.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionProxy.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionProxy.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionProxy.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2002-2007,2009 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.
+ */
+package org.apache.struts2.xwork2;
+
+import org.apache.struts2.xwork2.config.entities.ActionConfig;
+
+
+/**
+ * ActionProxy is an extra layer between XWork and the action so that different proxies are possible.
+ * <p/>
+ * An example of this would be a remote proxy, where the layer between XWork and the action might be RMI or SOAP.
+ *
+ * @author Jason Carreira
+ */
+public interface ActionProxy {
+
+ /**
+ * Gets the Action instance for this Proxy.
+ *
+ * @return the Action instance
+ */
+ Object getAction();
+
+ /**
+ * Gets the alias name this ActionProxy is mapped to.
+ *
+ * @return the alias name
+ */
+ String getActionName();
+
+ /**
+ * Gets the ActionConfig this ActionProxy is built from.
+ *
+ * @return the ActionConfig
+ */
+ ActionConfig getConfig();
+
+ /**
+ * Sets whether this ActionProxy should also execute the Result after executing the Action.
+ *
+ * @param executeResult <tt>true</tt> to also execute the Result.
+ */
+ void setExecuteResult(boolean executeResult);
+
+ /**
+ * Gets the status of whether the ActionProxy is set to execute the Result after the Action is executed.
+ *
+ * @return the status
+ */
+ boolean getExecuteResult();
+
+ /**
+ * Gets the ActionInvocation associated with this ActionProxy.
+ *
+ * @return the ActionInvocation
+ */
+ ActionInvocation getInvocation();
+
+ /**
+ * Gets the namespace the ActionConfig for this ActionProxy is mapped to.
+ *
+ * @return the namespace
+ */
+ String getNamespace();
+
+ /**
+ * Execute this ActionProxy. This will set the ActionContext from the ActionInvocation into the ActionContext
+ * ThreadLocal before invoking the ActionInvocation, then set the old ActionContext back into the ThreadLocal.
+ *
+ * @return the result code returned from executing the ActionInvocation
+ * @throws Exception can be thrown.
+ * @see ActionInvocation
+ */
+ String execute() throws Exception;
+
+ /**
+ * Gets the method name to execute, or <tt>null</tt> if no method has been specified (meaning <code>execute</code> will be invoked).
+ *
+ * @return the method to execute
+ */
+ String getMethod();
+
+ /**
+ * Gets status of the method value's initialization.
+ *
+ * @return true if the method returned by getMethod() is not a default initializer value.
+ */
+ boolean isMethodSpecified();
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionProxyFactory.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionProxyFactory.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionProxyFactory.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionProxyFactory.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2002-2007,2009 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.
+ */
+package org.apache.struts2.xwork2;
+
+import java.util.Map;
+
+
+/**
+ * The {@link ActionProxyFactory} is used to create {@link ActionProxy}s to be executed.
+ * <p/>
+ * It is the entry point to XWork that is used by a dispatcher to create an {@link ActionProxy} to execute
+ * for a particular namespace and action name.
+ *
+ * @author Jason Carreira
+ * @see DefaultActionProxyFactory
+ */
+public interface ActionProxyFactory {
+
+ /**
+ * Creates an {@link ActionProxy} for the given namespace and action name by looking up the configuration.The ActionProxy
+ * should be fully initialized when it is returned, including having an {@link ActionInvocation} instance associated.
+ * <p/>
+ * <b>Note:</b> This is the most used create method.
+ *
+ * @param namespace the namespace of the action, can be <tt>null</tt>
+ * @param actionName the name of the action
+ * @param extraContext a Map of extra parameters to be provided to the ActionProxy, can be <tt>null</tt>
+ * @return ActionProxy the created action proxy
+ * @deprecated Since 2.1.1, use {@link #createActionProxy(String,String,String,Map) instead}
+ */
+ @Deprecated public ActionProxy createActionProxy(String namespace, String actionName, Map<String, Object> extraContext);
+
+ /**
+ * Creates an {@link ActionProxy} for the given namespace and action name by looking up the configuration.The ActionProxy
+ * should be fully initialized when it is returned, including having an {@link ActionInvocation} instance associated.
+ * <p/>
+ * <b>Note:</b> This is the most used create method.
+ *
+ * @param namespace the namespace of the action, can be <tt>null</tt>
+ * @param actionName the name of the action
+ * @param methodName the name of the method to execute
+ * @param extraContext a Map of extra parameters to be provided to the ActionProxy, can be <tt>null</tt>
+ * @return ActionProxy the created action proxy
+ * @since 2.1.1
+ */
+ public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map<String, Object> extraContext);
+
+ /**
+ * Creates an {@link ActionProxy} for the given namespace and action name by looking up the configuration.The ActionProxy
+ * should be fully initialized when it is returned, including having an {@link ActionInvocation} instance associated.
+ *
+ * @param namespace the namespace of the action, can be <tt>null</tt>
+ * @param actionName the name of the action
+ * @param extraContext a Map of extra parameters to be provided to the ActionProxy, can be <tt>null</tt>
+ * @param executeResult flag which tells whether the result should be executed after the action
+ * @param cleanupContext flag which tells whether the original context should be preserved during execution of the proxy.
+ * @return ActionProxy the created action proxy
+ * @deprecated Since 2.1.1, use {@link #createActionProxy(String,String,String,Map,boolean,boolean)} instead
+ */
+ @Deprecated public ActionProxy createActionProxy(String namespace, String actionName, Map<String, Object> extraContext, boolean executeResult, boolean cleanupContext);
+
+ /**
+ * Creates an {@link ActionProxy} for the given namespace and action name by looking up the configuration.The ActionProxy
+ * should be fully initialized when it is returned, including having an {@link ActionInvocation} instance associated.
+ *
+ * @param namespace the namespace of the action, can be <tt>null</tt>
+ * @param actionName the name of the action
+ * @param methodName the name of the method to execute
+ * @param extraContext a Map of extra parameters to be provided to the ActionProxy, can be <tt>null</tt>
+ * @param executeResult flag which tells whether the result should be executed after the action
+ * @param cleanupContext flag which tells whether the original context should be preserved during execution of the proxy.
+ * @return ActionProxy the created action proxy
+ * @since 2.1.1
+ */
+ public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map<String, Object> extraContext, boolean executeResult, boolean cleanupContext);
+
+
+ /**
+ * Creates an {@link ActionProxy} for the given namespace and action name by looking up the configuration.The ActionProxy
+ * should be fully initialized when it is returned, including passed {@link ActionInvocation} instance.
+ *
+ * @param actionInvocation the action invocation instance to associate with
+ * @param namespace the namespace of the action, can be <tt>null</tt>
+ * @param actionName the name of the action
+ * @param methodName the name of the method to execute
+ * @param executeResult flag which tells whether the result should be executed after the action
+ * @param cleanupContext flag which tells whether the original context should be preserved during execution of the proxy.
+ * @return ActionProxy the created action proxy
+ * @since 2.1.1
+ */
+ public ActionProxy createActionProxy(ActionInvocation actionInvocation, String namespace, String actionName, String methodName,
+ boolean executeResult, boolean cleanupContext);
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionSupport.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionSupport.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionSupport.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ActionSupport.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,289 @@
+/*
+ * Copyright 2002-2006,2009 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.
+ */
+package org.apache.struts2.xwork2;
+
+import org.apache.struts2.xwork2.inject.Container;
+import org.apache.struts2.xwork2.inject.Inject;
+import org.apache.struts2.xwork2.util.ValueStack;
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerFactory;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+
+/**
+ * Provides a default implementation for the most common actions.
+ * See the documentation for all the interfaces this class implements for more detailed information.
+ */
+public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {
+
+ protected static Logger LOG = LoggerFactory.getLogger(ActionSupport.class);
+
+ private final ValidationAwareSupport validationAware = new ValidationAwareSupport();
+
+ private transient TextProvider textProvider;
+ private Container container;
+
+ public void setActionErrors(Collection<String> errorMessages) {
+ validationAware.setActionErrors(errorMessages);
+ }
+
+ public Collection<String> getActionErrors() {
+ return validationAware.getActionErrors();
+ }
+
+ public void setActionMessages(Collection<String> messages) {
+ validationAware.setActionMessages(messages);
+ }
+
+ public Collection<String> getActionMessages() {
+ return validationAware.getActionMessages();
+ }
+
+ /**
+ * @deprecated Use {@link #getActionErrors()}.
+ */
+ @Deprecated
+ public Collection<String> getErrorMessages() {
+ return getActionErrors();
+ }
+
+ /**
+ * @deprecated Use {@link #getFieldErrors()}.
+ */
+ @Deprecated
+ public Map<String, List<String>> getErrors() {
+ return getFieldErrors();
+ }
+
+ public void setFieldErrors(Map<String, List<String>> errorMap) {
+ validationAware.setFieldErrors(errorMap);
+ }
+
+ public Map<String, List<String>> getFieldErrors() {
+ return validationAware.getFieldErrors();
+ }
+
+ public Locale getLocale() {
+ ActionContext ctx = ActionContext.getContext();
+ if (ctx != null) {
+ return ctx.getLocale();
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Action context not initialized");
+ }
+ return null;
+ }
+ }
+
+ public boolean hasKey(String key) {
+ return getTextProvider().hasKey(key);
+ }
+
+ public String getText(String aTextName) {
+ return getTextProvider().getText(aTextName);
+ }
+
+ public String getText(String aTextName, String defaultValue) {
+ return getTextProvider().getText(aTextName, defaultValue);
+ }
+
+ public String getText(String aTextName, String defaultValue, String obj) {
+ return getTextProvider().getText(aTextName, defaultValue, obj);
+ }
+
+ public String getText(String aTextName, List<?> args) {
+ return getTextProvider().getText(aTextName, args);
+ }
+
+ public String getText(String key, String[] args) {
+ return getTextProvider().getText(key, args);
+ }
+
+ public String getText(String aTextName, String defaultValue, List<?> args) {
+ return getTextProvider().getText(aTextName, defaultValue, args);
+ }
+
+ public String getText(String key, String defaultValue, String[] args) {
+ return getTextProvider().getText(key, defaultValue, args);
+ }
+
+ public String getText(String key, String defaultValue, List<?> args, ValueStack stack) {
+ return getTextProvider().getText(key, defaultValue, args, stack);
+ }
+
+ public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
+ return getTextProvider().getText(key, defaultValue, args, stack);
+ }
+
+ public ResourceBundle getTexts() {
+ return getTextProvider().getTexts();
+ }
+
+ public ResourceBundle getTexts(String aBundleName) {
+ return getTextProvider().getTexts(aBundleName);
+ }
+
+ public void addActionError(String anErrorMessage) {
+ validationAware.addActionError(anErrorMessage);
+ }
+
+ public void addActionMessage(String aMessage) {
+ validationAware.addActionMessage(aMessage);
+ }
+
+ public void addFieldError(String fieldName, String errorMessage) {
+ validationAware.addFieldError(fieldName, errorMessage);
+ }
+
+ public String input() throws Exception {
+ return INPUT;
+ }
+
+ public String doDefault() throws Exception {
+ return SUCCESS;
+ }
+
+ /**
+ * A default implementation that does nothing an returns "success".
+ * <p/>
+ * Subclasses should override this method to provide their business logic.
+ * <p/>
+ * See also {@link Action#execute()}.
+ *
+ * @return returns {@link #SUCCESS}
+ * @throws Exception can be thrown by subclasses.
+ */
+ public String execute() throws Exception {
+ return SUCCESS;
+ }
+
+ public boolean hasActionErrors() {
+ return validationAware.hasActionErrors();
+ }
+
+ public boolean hasActionMessages() {
+ return validationAware.hasActionMessages();
+ }
+
+ public boolean hasErrors() {
+ return validationAware.hasErrors();
+ }
+
+ public boolean hasFieldErrors() {
+ return validationAware.hasFieldErrors();
+ }
+
+ /**
+ * Clears field errors. Useful for Continuations and other situations
+ * where you might want to clear parts of the state on the same action.
+ */
+ public void clearFieldErrors() {
+ validationAware.clearFieldErrors();
+ }
+
+ /**
+ * Clears action errors. Useful for Continuations and other situations
+ * where you might want to clear parts of the state on the same action.
+ */
+ public void clearActionErrors() {
+ validationAware.clearActionErrors();
+ }
+
+ /**
+ * Clears messages. Useful for Continuations and other situations
+ * where you might want to clear parts of the state on the same action.
+ */
+ public void clearMessages() {
+ validationAware.clearMessages();
+ }
+
+ /**
+ * Clears all errors. Useful for Continuations and other situations
+ * where you might want to clear parts of the state on the same action.
+ */
+ public void clearErrors() {
+ validationAware.clearErrors();
+ }
+
+ /**
+ * Clears all errors and messages. Useful for Continuations and other situations
+ * where you might want to clear parts of the state on the same action.
+ */
+ public void clearErrorsAndMessages() {
+ validationAware.clearErrorsAndMessages();
+ }
+
+ /**
+ * A default implementation that validates nothing.
+ * Subclasses should override this method to provide validations.
+ */
+ public void validate() {
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+
+ /**
+ * <!-- START SNIPPET: pause-method -->
+ * Stops the action invocation immediately (by throwing a PauseException) and causes the action invocation to return
+ * the specified result, such as {@link #SUCCESS}, {@link #INPUT}, etc.
+ * <p/>
+ * <p/>
+ * The next time this action is invoked (and using the same continuation ID), the method will resume immediately
+ * after where this method was called, with the entire call stack in the execute method restored.
+ * <p/>
+ * <p/>
+ * Note: this method can <b>only</b> be called within the {@link #execute()} method.
+ * <!-- END SNIPPET: pause-method -->
+ *
+ * @param result the result to return - the same type of return value in the {@link #execute()} method.
+ */
+ public void pause(String result) {
+ }
+
+ /**
+ * If called first time it will create {@link TextProviderFactory},
+ * inject dependency (if {@link org.apache.struts2.xwork2.inject.Container} is accesible) into in,
+ * then will create new {@link TextProvider} and store it in a field
+ * for future references and at the returns reference to that field
+ *
+ * @return reference to field with TextProvider
+ */
+ private TextProvider getTextProvider() {
+ if (textProvider == null) {
+ TextProviderFactory tpf = new TextProviderFactory();
+ if (container != null) {
+ container.inject(tpf);
+ }
+ textProvider = tpf.createInstance(getClass(), this);
+ }
+ return textProvider;
+ }
+
+ @Inject
+ public void setContainer(Container container) {
+ this.container = container;
+ }
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/CompositeTextProvider.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/CompositeTextProvider.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/CompositeTextProvider.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/CompositeTextProvider.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,267 @@
+package org.apache.struts2.xwork2;
+
+import org.apache.struts2.xwork2.util.ValueStack;
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerFactory;
+
+import java.util.*;
+
+
+/**
+ * This is a composite {@link TextProvider} that takes in an array or {@link java.util.List} of {@link TextProvider}s, it will
+ * consult each of them in order to get a composite result. To know how each method behaves, please refer to the
+ * javadoc for each methods.
+ *
+ * @author tmjee
+ * @version $Date: 2011-12-02 12:24:48 +0100 (Fri, 02 Dec 2011) $ $Id: CompositeTextProvider.java 1209415 2011-12-02 11:24:48Z lukaszlenart $
+ */
+public class CompositeTextProvider implements TextProvider {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CompositeTextProvider.class);
+
+ private List<TextProvider> textProviders = new ArrayList<TextProvider>();
+
+ /**
+ * Instantiates a {@link CompositeTextProvider} with some predefined <code>textProviders</code>.
+ *
+ * @param textProviders
+ */
+ public CompositeTextProvider(List<TextProvider> textProviders) {
+ this.textProviders.addAll(textProviders);
+ }
+
+ /**
+ * Instantiates a {@link CompositeTextProvider} with some predefined <code>textProviders</code>.
+ *
+ * @param textProviders
+ */
+ public CompositeTextProvider(TextProvider[] textProviders) {
+ this(Arrays.asList(textProviders));
+ }
+
+ /**
+ * @param key The key to lookup in ressource bundles.
+ * @return <tt>true</tt>, if the requested key is found in one of the ressource bundles.
+ * @see {@link TextProvider#hasKey(String)}
+ * It will consult each individual {@link TextProvider}s and return true if either one of the
+ * {@link TextProvider} has such a <code>key></code> else false.
+ */
+ public boolean hasKey(String key) {
+ // if there's a key in either text providers we are ok, else try the next text provider
+ for (TextProvider tp : textProviders) {
+ if (tp.hasKey(key)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * It will consult each {@link TextProvider}s and return the first valid message for this
+ * <code>key</code>
+ *
+ * @param key The key to lookup in ressource bundles.
+ * @return The i18n text for the requested key.
+ * @see {@link TextProvider#getText(String)}
+ */
+ public String getText(String key) {
+ return getText(key, key, Collections.emptyList());
+ }
+
+ /**
+ * It will consult each {@link TextProvider}s and return the first valid message for this
+ * <code>key</code> before returning <code>defaultValue</code> if every else fails.
+ *
+ * @param key
+ * @param defaultValue
+ * @return
+ * @see {@link TextProvider#getText(String, String)}
+ */
+ public String getText(String key, String defaultValue) {
+ return getText(key, defaultValue, Collections.emptyList());
+ }
+
+ /**
+ * It will consult each {@link TextProvider}s and return the first valid message for this
+ * <code>key</code>, before returining <code>defaultValue</code>
+ * if every else fails.
+ *
+ * @param key
+ * @param defaultValue
+ * @param obj
+ * @return
+ * @see {@link TextProvider#getText(String, String, String)}
+ */
+ public String getText(String key, String defaultValue, final String obj) {
+ return getText(key, defaultValue, new ArrayList<Object>() {
+ {
+ add(obj);
+ }
+
+
+ });
+ }
+
+ /**
+ * It will consult each {@link TextProvider}s and return the first valid message for this
+ * <code>key</code>.
+ *
+ * @param key
+ * @param args
+ * @return
+ * @see {@link TextProvider#getText(String, java.util.List)}
+ */
+ public String getText(String key, List<?> args) {
+ return getText(key, key, args);
+ }
+
+ /**
+ * It will consult each {@link TextProvider}s and return the first valid message for this
+ * <code>key</code>.
+ *
+ * @param key
+ * @param args
+ * @return
+ * @see {@link TextProvider#getText(String, String[])}
+ */
+ public String getText(String key, String[] args) {
+ return getText(key, key, args);
+ }
+
+
+ /**
+ * It will consult each {@link TextProvider}s and return the first valid message for this
+ * <code>key</code>, before returining <code>defaultValue</code>
+ *
+ * @param key
+ * @param defaultValue
+ * @param args
+ * @return
+ * @see {@link TextProvider#getText#getText(String, String, java.util.List)}
+ */
+ public String getText(String key, String defaultValue, List<?> args) {
+ // if there's one text provider that gives us a msg not the same as defaultValue
+ // for this key, we are ok, else try the next
+ // text provider
+ for (TextProvider textProvider : textProviders) {
+ String msg = textProvider.getText(key, defaultValue, args);
+ if (msg != null && (!msg.equals(defaultValue))) {
+ return msg;
+ }
+ }
+ return defaultValue;
+ }
+
+
+ /**
+ * It will consult each {@link TextProvider}s and return the first valid message for this
+ * <code>key</code>, before returining <code>defaultValue</code>.
+ *
+ * @param key
+ * @param defaultValue
+ * @param args
+ * @return
+ * @see {@link TextProvider#getText(String, String, String[])}
+ */
+ public String getText(String key, String defaultValue, String[] args) {
+ // if there's one text provider that gives us a msg not the same as defaultValue
+ // for this key, we are ok, else try the next
+ // text provider
+ for (TextProvider textProvider : textProviders) {
+ String msg = textProvider.getText(key, defaultValue, args);
+ if (msg != null && (!msg.equals(defaultValue))) {
+ return msg;
+ }
+ }
+ return defaultValue;
+ }
+
+
+ /**
+ * It will consult each {@link TextProvider}s and return the first valid message for this
+ * <code>key</code>, before returining <code>defaultValue</code>
+ *
+ * @param key
+ * @param defaultValue
+ * @param args
+ * @param stack
+ * @return
+ * @see {@link TextProvider#getText(String, String, java.util.List, org.apache.struts2.xwork2.util.ValueStack)}
+ */
+ public String getText(String key, String defaultValue, List<?> args, ValueStack stack) {
+ // if there's one text provider that gives us a msg not the same as defaultValue
+ // for this key, we are ok, else try the next
+ // text provider
+ for (TextProvider textProvider : textProviders) {
+ String msg = textProvider.getText(key, defaultValue, args, stack);
+ if (msg != null && (!msg.equals(defaultValue))) {
+ return msg;
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * It will consult each {@link TextProvider}s and return the first valid message for this
+ * <code>key</code>, before returining <code>defaultValue</code>
+ *
+ * @param key
+ * @param defaultValue
+ * @param args
+ * @param stack
+ * @return
+ * @see {@link TextProvider#getText(String, String, String[], org.apache.struts2.xwork2.util.ValueStack)}
+ */
+ public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
+ // if there's one text provider that gives us a msg not the same as defaultValue
+ // for this key, we are ok, else try the next
+ // text provider
+ for (TextProvider textProvider : textProviders) {
+ String msg = textProvider.getText(key, defaultValue, args, stack);
+ if (msg != null && (!msg.equals(defaultValue))) {
+ return msg;
+ }
+ }
+ return defaultValue;
+ }
+
+
+ /**
+ * It will consult each {@link TextProvider}s and return the first non-null {@link ResourceBundle}.
+ *
+ * @param bundleName
+ * @return
+ * @see {@link TextProvider#getTexts(String)}
+ */
+ public ResourceBundle getTexts(String bundleName) {
+ // if there's one text provider that gives us a non-null resource bunlde for this bundleName, we are ok, else try the next
+ // text provider
+ for (TextProvider textProvider : textProviders) {
+ ResourceBundle bundle = textProvider.getTexts(bundleName);
+ if (bundle != null) {
+ return bundle;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * It will consult each {@link TextProvider}s and return the first non-null {@link ResourceBundle}.
+ *
+ * @return
+ * @see {@link TextProvider#getTexts()}
+ */
+ public ResourceBundle getTexts() {
+ // if there's one text provider that gives us a non-null resource bundle, we are ok, else try the next
+ // text provider
+ for (TextProvider textProvider : textProviders) {
+ ResourceBundle bundle = textProvider.getTexts();
+ if (bundle != null) {
+ return bundle;
+ }
+ }
+ return null;
+ }
+}
+
+
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultActionInvocation.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultActionInvocation.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultActionInvocation.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultActionInvocation.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,497 @@
+/*
+ * Copyright 2002-2006,2009 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.
+ */
+package org.apache.struts2.xwork2;
+
+import org.apache.struts2.xwork2.config.Configuration;
+import org.apache.struts2.xwork2.config.ConfigurationException;
+import org.apache.struts2.xwork2.config.entities.ActionConfig;
+import org.apache.struts2.xwork2.config.entities.InterceptorMapping;
+import org.apache.struts2.xwork2.config.entities.ResultConfig;
+import org.apache.struts2.xwork2.inject.Container;
+import org.apache.struts2.xwork2.inject.Inject;
+import org.apache.struts2.xwork2.interceptor.PreResultListener;
+import org.apache.struts2.xwork2.util.ValueStack;
+import org.apache.struts2.xwork2.util.ValueStackFactory;
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerFactory;
+import org.apache.struts2.xwork2.util.profiling.UtilTimerStack;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * The Default ActionInvocation implementation
+ *
+ * @author Rainer Hermanns
+ * @author tmjee
+ * @version $Date: 2011-12-02 12:24:48 +0100 (Fri, 02 Dec 2011) $ $Id: DefaultActionInvocation.java 1209415 2011-12-02 11:24:48Z lukaszlenart $
+ * @see DefaultActionProxy
+ */
+public class DefaultActionInvocation implements ActionInvocation {
+
+ private static final long serialVersionUID = -585293628862447329L;
+
+ //static {
+ // if (ObjectFactory.getContinuationPackage() != null) {
+ // continuationHandler = new ContinuationHandler();
+ // }
+ //}
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultActionInvocation.class);
+
+ private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
+ private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+
+ protected Object action;
+ protected ActionProxy proxy;
+ protected List<PreResultListener> preResultListeners;
+ protected Map<String, Object> extraContext;
+ protected ActionContext invocationContext;
+ protected Iterator<InterceptorMapping> interceptors;
+ protected ValueStack stack;
+ protected Result result;
+ protected Result explicitResult;
+ protected String resultCode;
+ protected boolean executed = false;
+ protected boolean pushAction = true;
+ protected ObjectFactory objectFactory;
+ protected ActionEventListener actionEventListener;
+ protected ValueStackFactory valueStackFactory;
+ protected Container container;
+ private Configuration configuration;
+ protected UnknownHandlerManager unknownHandlerManager;
+
+ public DefaultActionInvocation(final Map<String, Object> extraContext, final boolean pushAction) {
+ DefaultActionInvocation.this.extraContext = extraContext;
+ DefaultActionInvocation.this.pushAction = pushAction;
+ }
+
+ @Inject
+ public void setUnknownHandlerManager(UnknownHandlerManager unknownHandlerManager) {
+ this.unknownHandlerManager = unknownHandlerManager;
+ }
+
+ @Inject
+ public void setValueStackFactory(ValueStackFactory fac) {
+ this.valueStackFactory = fac;
+ }
+
+ @Inject
+ public void setConfiguration(Configuration configuration) {
+ this.configuration = configuration;
+ }
+
+ @Inject
+ public void setObjectFactory(ObjectFactory fac) {
+ this.objectFactory = fac;
+ }
+
+ @Inject
+ public void setContainer(Container cont) {
+ this.container = cont;
+ }
+
+ @Inject(required=false)
+ public void setActionEventListener(ActionEventListener listener) {
+ this.actionEventListener = listener;
+ }
+
+ public Object getAction() {
+ return action;
+ }
+
+ public boolean isExecuted() {
+ return executed;
+ }
+
+ public ActionContext getInvocationContext() {
+ return invocationContext;
+ }
+
+ public ActionProxy getProxy() {
+ return proxy;
+ }
+
+ /**
+ * If the DefaultActionInvocation has been executed before and the Result is an instance of ActionChainResult, this method
+ * will walk down the chain of ActionChainResults until it finds a non-chain result, which will be returned. If the
+ * DefaultActionInvocation's result has not been executed before, the Result instance will be created and populated with
+ * the result params.
+ *
+ * @return a Result instance
+ * @throws Exception
+ */
+ public Result getResult() throws Exception {
+ Result returnResult = result;
+
+ // If we've chained to other Actions, we need to find the last result
+ while (returnResult instanceof ActionChainResult) {
+ ActionProxy aProxy = ((ActionChainResult) returnResult).getProxy();
+
+ if (aProxy != null) {
+ Result proxyResult = aProxy.getInvocation().getResult();
+
+ if ((proxyResult != null) && (aProxy.getExecuteResult())) {
+ returnResult = proxyResult;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ return returnResult;
+ }
+
+ public String getResultCode() {
+ return resultCode;
+ }
+
+ public void setResultCode(String resultCode) {
+ if (isExecuted())
+ throw new IllegalStateException("Result has already been executed.");
+
+ this.resultCode = resultCode;
+ }
+
+
+ public ValueStack getStack() {
+ return stack;
+ }
+
+ /**
+ * Register a org.apache.struts2.xwork2.interceptor.PreResultListener to be notified after the Action is executed and before the
+ * Result is executed. The ActionInvocation implementation must guarantee that listeners will be called in the order
+ * in which they are registered. Listener registration and execution does not need to be thread-safe.
+ *
+ * @param listener
+ */
+ public void addPreResultListener(PreResultListener listener) {
+ if (preResultListeners == null) {
+ preResultListeners = new ArrayList<PreResultListener>(1);
+ }
+
+ preResultListeners.add(listener);
+ }
+
+ public Result createResult() throws Exception {
+
+ if (explicitResult != null) {
+ Result ret = explicitResult;
+ explicitResult = null;
+
+ return ret;
+ }
+ ActionConfig config = proxy.getConfig();
+ Map<String, ResultConfig> results = config.getResults();
+
+ ResultConfig resultConfig = null;
+
+ try {
+ resultConfig = results.get(resultCode);
+ } catch (NullPointerException e) {
+ // swallow
+ }
+
+ if (resultConfig == null) {
+ // If no result is found for the given resultCode, try to get a wildcard '*' match.
+ resultConfig = results.get("*");
+ }
+
+ if (resultConfig != null) {
+ try {
+ return objectFactory.buildResult(resultConfig, invocationContext.getContextMap());
+ } catch (Exception e) {
+ LOG.error("There was an exception while instantiating the result of type " + resultConfig.getClassName(), e);
+ throw new XWorkException(e, resultConfig);
+ }
+ } else if (resultCode != null && !Action.NONE.equals(resultCode) && unknownHandlerManager.hasUnknownHandlers()) {
+ return unknownHandlerManager.handleUnknownResult(invocationContext, proxy.getActionName(), proxy.getConfig(), resultCode);
+ }
+ return null;
+ }
+
+ /**
+ * @throws ConfigurationException If no result can be found with the returned code
+ */
+ public String invoke() throws Exception {
+ String profileKey = "invoke: ";
+ try {
+ UtilTimerStack.push(profileKey);
+
+ if (executed) {
+ throw new IllegalStateException("Action has already executed");
+ }
+
+ if (interceptors.hasNext()) {
+ final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next();
+ String interceptorMsg = "interceptor: " + interceptor.getName();
+ UtilTimerStack.push(interceptorMsg);
+ try {
+ resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
+ }
+ finally {
+ UtilTimerStack.pop(interceptorMsg);
+ }
+ } else {
+ resultCode = invokeActionOnly();
+ }
+
+ // this is needed because the result will be executed, then control will return to the Interceptor, which will
+ // return above and flow through again
+ if (!executed) {
+ if (preResultListeners != null) {
+ for (Object preResultListener : preResultListeners) {
+ PreResultListener listener = (PreResultListener) preResultListener;
+
+ String _profileKey = "preResultListener: ";
+ try {
+ UtilTimerStack.push(_profileKey);
+ listener.beforeResult(this, resultCode);
+ }
+ finally {
+ UtilTimerStack.pop(_profileKey);
+ }
+ }
+ }
+
+ // now execute the result, if we're supposed to
+ if (proxy.getExecuteResult()) {
+ executeResult();
+ }
+
+ executed = true;
+ }
+
+ return resultCode;
+ }
+ finally {
+ UtilTimerStack.pop(profileKey);
+ }
+ }
+
+ public String invokeActionOnly() throws Exception {
+ return invokeAction(getAction(), proxy.getConfig());
+ }
+
+ protected void createAction(Map<String, Object> contextMap) {
+ // load action
+ String timerKey = "actionCreate: " + proxy.getActionName();
+ try {
+ UtilTimerStack.push(timerKey);
+ action = objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap);
+ } catch (InstantiationException e) {
+ throw new XWorkException("Unable to intantiate Action!", e, proxy.getConfig());
+ } catch (IllegalAccessException e) {
+ throw new XWorkException("Illegal access to constructor, is it public?", e, proxy.getConfig());
+ } catch (Exception e) {
+ String gripe = "";
+
+ if (proxy == null) {
+ gripe = "Whoa! No ActionProxy instance found in current ActionInvocation. This is bad ... very bad";
+ } else if (proxy.getConfig() == null) {
+ gripe = "Sheesh. Where'd that ActionProxy get to? I can't find it in the current ActionInvocation!?";
+ } else if (proxy.getConfig().getClassName() == null) {
+ gripe = "No Action defined for '" + proxy.getActionName() + "' in namespace '" + proxy.getNamespace() + "'";
+ } else {
+ gripe = "Unable to instantiate Action, " + proxy.getConfig().getClassName() + ", defined for '" + proxy.getActionName() + "' in namespace '" + proxy.getNamespace() + "'";
+ }
+
+ gripe += (((" -- " + e.getMessage()) != null) ? e.getMessage() : " [no message in exception]");
+ throw new XWorkException(gripe, e, proxy.getConfig());
+ } finally {
+ UtilTimerStack.pop(timerKey);
+ }
+
+ if (actionEventListener != null) {
+ action = actionEventListener.prepare(action, stack);
+ }
+ }
+
+ protected Map<String, Object> createContextMap() {
+ Map<String, Object> contextMap;
+
+ if ((extraContext != null) && (extraContext.containsKey(ActionContext.VALUE_STACK))) {
+ // In case the ValueStack was passed in
+ stack = (ValueStack) extraContext.get(ActionContext.VALUE_STACK);
+
+ if (stack == null) {
+ throw new IllegalStateException("There was a null Stack set into the extra params.");
+ }
+
+ contextMap = stack.getContext();
+ } else {
+ // create the value stack
+ // this also adds the ValueStack to its context
+ stack = valueStackFactory.createValueStack();
+
+ // create the action context
+ contextMap = stack.getContext();
+ }
+
+ // put extraContext in
+ if (extraContext != null) {
+ contextMap.putAll(extraContext);
+ }
+
+ //put this DefaultActionInvocation into the context map
+ contextMap.put(ActionContext.ACTION_INVOCATION, this);
+ contextMap.put(ActionContext.CONTAINER, container);
+
+ return contextMap;
+ }
+
+ /**
+ * Uses getResult to get the final Result and executes it
+ *
+ * @throws ConfigurationException If not result can be found with the returned code
+ */
+ private void executeResult() throws Exception {
+ result = createResult();
+
+ String timerKey = "executeResult: " + getResultCode();
+ try {
+ UtilTimerStack.push(timerKey);
+ if (result != null) {
+ result.execute(this);
+ } else if (resultCode != null && !Action.NONE.equals(resultCode)) {
+ throw new ConfigurationException("No result defined for action " + getAction().getClass().getName()
+ + " and result " + getResultCode(), proxy.getConfig());
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("No result returned for action " + getAction().getClass().getName() + " at " + proxy.getConfig().getLocation());
+ }
+ }
+ } finally {
+ UtilTimerStack.pop(timerKey);
+ }
+ }
+
+ public void init(ActionProxy proxy) {
+ this.proxy = proxy;
+ Map<String, Object> contextMap = createContextMap();
+
+ // Setting this so that other classes, like object factories, can use the ActionProxy and other
+ // contextual information to operate
+ ActionContext actionContext = ActionContext.getContext();
+
+ if (actionContext != null) {
+ actionContext.setActionInvocation(this);
+ }
+
+ createAction(contextMap);
+
+ if (pushAction) {
+ stack.push(action);
+ contextMap.put("action", action);
+ }
+
+ invocationContext = new ActionContext(contextMap);
+ invocationContext.setName(proxy.getActionName());
+
+ // get a new List so we don't get problems with the iterator if someone changes the list
+ List<InterceptorMapping> interceptorList = new ArrayList<InterceptorMapping>(proxy.getConfig().getInterceptors());
+ interceptors = interceptorList.iterator();
+ }
+
+ protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {
+ String methodName = proxy.getMethod();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Executing action method = " + actionConfig.getMethodName());
+ }
+
+ String timerKey = "invokeAction: " + proxy.getActionName();
+ try {
+ UtilTimerStack.push(timerKey);
+
+ boolean methodCalled = false;
+ Object methodResult = null;
+ Method method = null;
+ try {
+ method = getAction().getClass().getMethod(methodName, EMPTY_CLASS_ARRAY);
+ } catch (NoSuchMethodException e) {
+ // hmm -- OK, try doXxx instead
+ try {
+ String altMethodName = "do" + methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
+ method = getAction().getClass().getMethod(altMethodName, EMPTY_CLASS_ARRAY);
+ } catch (NoSuchMethodException e1) {
+ // well, give the unknown handler a shot
+ if (unknownHandlerManager.hasUnknownHandlers()) {
+ try {
+ methodResult = unknownHandlerManager.handleUnknownMethod(action, methodName);
+ methodCalled = true;
+ } catch (NoSuchMethodException e2) {
+ // throw the original one
+ throw e;
+ }
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ if (!methodCalled) {
+ methodResult = method.invoke(action, EMPTY_OBJECT_ARRAY);
+ }
+
+ return saveResult(actionConfig, methodResult);
+ } catch (NoSuchMethodException e) {
+ throw new IllegalArgumentException("The " + methodName + "() is not defined in action " + getAction().getClass() + "");
+ } catch (InvocationTargetException e) {
+ // We try to return the source exception.
+ Throwable t = e.getTargetException();
+
+ if (actionEventListener != null) {
+ String result = actionEventListener.handleException(t, getStack());
+ if (result != null) {
+ return result;
+ }
+ }
+ if (t instanceof Exception) {
+ throw (Exception) t;
+ } else {
+ throw e;
+ }
+ } finally {
+ UtilTimerStack.pop(timerKey);
+ }
+ }
+
+ /**
+ * Save the result to be used later.
+ * @param actionConfig
+ * @param methodResult the result of the action.
+ * @return the result code to process.
+ */
+ protected String saveResult(ActionConfig actionConfig, Object methodResult) {
+ if (methodResult instanceof Result) {
+ this.explicitResult = (Result) methodResult;
+
+ // Wire the result automatically
+ container.inject(explicitResult);
+ return null;
+ } else {
+ return (String) methodResult;
+ }
+ }
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultActionProxy.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultActionProxy.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultActionProxy.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultActionProxy.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,216 @@
+/*
+ * $Id: DefaultActionProxy.java 1209415 2011-12-02 11:24:48Z lukaszlenart $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.struts2.xwork2;
+
+import org.apache.struts2.xwork2.config.Configuration;
+import org.apache.struts2.xwork2.config.ConfigurationException;
+import org.apache.struts2.xwork2.config.entities.ActionConfig;
+import org.apache.struts2.xwork2.inject.Inject;
+import org.apache.struts2.xwork2.util.LocalizedTextUtil;
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerFactory;
+import org.apache.struts2.xwork2.util.profiling.UtilTimerStack;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
+
+import java.io.Serializable;
+import java.util.Locale;
+
+
+/**
+ * The Default ActionProxy implementation
+ *
+ * @author Rainer Hermanns
+ * @author Revised by <a href="mailto:hu_pengfei@yahoo.com.cn">Henry Hu</a>
+ * @author tmjee
+ *
+ * @version $Date: 2011-12-02 12:24:48 +0100 (Fri, 02 Dec 2011) $ $Id: DefaultActionProxy.java 1209415 2011-12-02 11:24:48Z lukaszlenart $
+ * @since 2005-8-6
+ */
+public class DefaultActionProxy implements ActionProxy, Serializable {
+
+ private static final long serialVersionUID = 3293074152487468527L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultActionProxy.class);
+
+ protected Configuration configuration;
+ protected ActionConfig config;
+ protected ActionInvocation invocation;
+ protected UnknownHandlerManager unknownHandlerManager;
+ protected String actionName;
+ protected String namespace;
+ protected String method;
+ protected boolean executeResult;
+ protected boolean cleanupContext;
+
+ protected ObjectFactory objectFactory;
+
+ protected ActionEventListener actionEventListener;
+
+ private boolean methodSpecified=true;
+
+ /**
+ * This constructor is private so the builder methods (create*) should be used to create an DefaultActionProxy.
+ * <p/>
+ * The reason for the builder methods is so that you can use a subclass to create your own DefaultActionProxy instance
+ * (like a RMIActionProxy).
+ */
+ protected DefaultActionProxy(ActionInvocation inv, String namespace, String actionName, String methodName, boolean executeResult, boolean cleanupContext) {
+
+ this.invocation = inv;
+ this.cleanupContext = cleanupContext;
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Creating an DefaultActionProxy for namespace " + namespace + " and action name " + actionName);
+ }
+
+ this.actionName = StringEscapeUtils.escapeHtml(actionName);
+ this.namespace = namespace;
+ this.executeResult = executeResult;
+ this.method = StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(methodName));
+ }
+
+ @Inject
+ public void setObjectFactory(ObjectFactory factory) {
+ this.objectFactory = factory;
+ }
+
+ @Inject
+ public void setConfiguration(Configuration config) {
+ this.configuration = config;
+ }
+
+ @Inject
+ public void setUnknownHandler(UnknownHandlerManager unknownHandlerManager) {
+ this.unknownHandlerManager = unknownHandlerManager;
+ }
+
+ @Inject(required=false)
+ public void setActionEventListener(ActionEventListener listener) {
+ this.actionEventListener = listener;
+ }
+
+ public Object getAction() {
+ return invocation.getAction();
+ }
+
+ public String getActionName() {
+ return actionName;
+ }
+
+ public ActionConfig getConfig() {
+ return config;
+ }
+
+ public void setExecuteResult(boolean executeResult) {
+ this.executeResult = executeResult;
+ }
+
+ public boolean getExecuteResult() {
+ return executeResult;
+ }
+
+ public ActionInvocation getInvocation() {
+ return invocation;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public String execute() throws Exception {
+ ActionContext nestedContext = ActionContext.getContext();
+ ActionContext.setContext(invocation.getInvocationContext());
+
+ String retCode = null;
+
+ String profileKey = "execute: ";
+ try {
+ UtilTimerStack.push(profileKey);
+
+ retCode = invocation.invoke();
+ } finally {
+ if (cleanupContext) {
+ ActionContext.setContext(nestedContext);
+ }
+ UtilTimerStack.pop(profileKey);
+ }
+
+ return retCode;
+ }
+
+
+ public String getMethod() {
+ return method;
+ }
+
+ private void resolveMethod() {
+ // if the method is set to null, use the one from the configuration
+ // if the one from the configuration is also null, use "execute"
+ if (StringUtils.isEmpty(this.method)) {
+ this.method = config.getMethodName();
+ if (StringUtils.isEmpty(this.method)) {
+ this.method = ActionConfig.DEFAULT_METHOD;
+ }
+ methodSpecified=false;
+ }
+ }
+
+ protected void prepare() {
+ String profileKey = "create DefaultActionProxy: ";
+ try {
+ UtilTimerStack.push(profileKey);
+ config = configuration.getRuntimeConfiguration().getActionConfig(namespace, actionName);
+
+ if (config == null && unknownHandlerManager.hasUnknownHandlers()) {
+ config = unknownHandlerManager.handleUnknownAction(namespace, actionName);
+ }
+ if (config == null) {
+ String message;
+
+ if ((namespace != null) && (namespace.trim().length() > 0)) {
+ message = LocalizedTextUtil.findDefaultText(XWorkMessages.MISSING_PACKAGE_ACTION_EXCEPTION, Locale.getDefault(), new String[]{
+ namespace, actionName
+ });
+ } else {
+ message = LocalizedTextUtil.findDefaultText(XWorkMessages.MISSING_ACTION_EXCEPTION, Locale.getDefault(), new String[]{
+ actionName
+ });
+ }
+ throw new ConfigurationException(message);
+ }
+
+ resolveMethod();
+
+ if (!config.isAllowedMethod(method)) {
+ throw new ConfigurationException("Invalid method: "+method+" for action "+actionName);
+ }
+
+ invocation.init(this);
+
+ } finally {
+ UtilTimerStack.pop(profileKey);
+ }
+ }
+
+ public boolean isMethodSpecified() {
+ return methodSpecified;
+ }
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultActionProxyFactory.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultActionProxyFactory.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultActionProxyFactory.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultActionProxyFactory.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2002-2007,2009 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.
+ */
+package org.apache.struts2.xwork2;
+
+import org.apache.struts2.xwork2.inject.Container;
+import org.apache.struts2.xwork2.inject.Inject;
+
+import java.util.Map;
+
+
+/**
+ * Default factory for {@link ActionProxyFactory}.
+ *
+ * @author Jason Carreira
+ */
+public class DefaultActionProxyFactory implements ActionProxyFactory {
+
+ protected Container container;
+
+ public DefaultActionProxyFactory() {
+ super();
+ }
+
+ @Inject
+ public void setContainer(Container container) {
+ this.container = container;
+ }
+
+ public ActionProxy createActionProxy(String namespace, String actionName, Map<String, Object> extraContext) {
+ return createActionProxy(namespace, actionName, null, extraContext, true, true);
+ }
+
+ public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map<String, Object> extraContext) {
+ return createActionProxy(namespace, actionName, methodName, extraContext, true, true);
+ }
+
+ public ActionProxy createActionProxy(String namespace, String actionName, Map<String, Object> extraContext, boolean executeResult, boolean cleanupContext) {
+ return createActionProxy(namespace, actionName, null, extraContext, executeResult, cleanupContext);
+ }
+
+ public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map<String, Object> extraContext, boolean executeResult, boolean cleanupContext) {
+
+ ActionInvocation inv = new DefaultActionInvocation(extraContext, true);
+ container.inject(inv);
+ return createActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);
+ }
+
+ public ActionProxy createActionProxy(ActionInvocation inv, String namespace, String actionName, boolean executeResult, boolean cleanupContext) {
+
+ return createActionProxy(inv, namespace, actionName, null, executeResult, cleanupContext);
+ }
+
+ public ActionProxy createActionProxy(ActionInvocation inv, String namespace, String actionName, String methodName, boolean executeResult, boolean cleanupContext) {
+
+ DefaultActionProxy proxy = new DefaultActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);
+ container.inject(proxy);
+ proxy.prepare();
+ return proxy;
+ }
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultTextProvider.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultTextProvider.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultTextProvider.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/DefaultTextProvider.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2002-2006,2009 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.
+ */
+package org.apache.struts2.xwork2;
+
+import org.apache.struts2.xwork2.util.LocalizedTextUtil;
+import org.apache.struts2.xwork2.util.ValueStack;
+
+import java.io.Serializable;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ResourceBundle;
+
+/**
+ * DefaultTextProvider gets texts from only the default resource bundles associated with the
+ * LocalizedTextUtil.
+ *
+ * @author Jason Carreira <jc...@gmail.com>
+ * @author Rainer Hermanns
+ * @see LocalizedTextUtil#addDefaultResourceBundle(String)
+ */
+public class DefaultTextProvider implements TextProvider, Serializable, Unchainable {
+
+ private static final Object[] EMPTY_ARGS = new Object[0];
+
+ public DefaultTextProvider() {
+ }
+
+ public boolean hasKey(String key) {
+ return getText(key) != null;
+ }
+
+ public String getText(String key) {
+ return LocalizedTextUtil.findDefaultText(key, ActionContext.getContext().getLocale());
+ }
+
+ public String getText(String key, String defaultValue) {
+ String text = getText(key);
+ if (text == null) {
+ return defaultValue;
+ }
+ return text;
+ }
+
+ public String getText(String key, List<?> args) {
+ Object[] params;
+ if (args != null) {
+ params = args.toArray();
+ } else {
+ params = EMPTY_ARGS;
+ }
+
+ return LocalizedTextUtil.findDefaultText(key, ActionContext.getContext().getLocale(), params);
+ }
+
+ public String getText(String key, String[] args) {
+ Object[] params;
+ if (args != null) {
+ params = args;
+ } else {
+ params = EMPTY_ARGS;
+ }
+
+ return LocalizedTextUtil.findDefaultText(key, ActionContext.getContext().getLocale(), params);
+ }
+
+ public String getText(String key, String defaultValue, List<?> args) {
+ String text = getText(key, args);
+ if(text == null && defaultValue == null) {
+ defaultValue = key;
+ }
+ if (text == null && defaultValue != null) {
+
+ MessageFormat format = new MessageFormat(defaultValue);
+ format.setLocale(ActionContext.getContext().getLocale());
+ format.applyPattern(defaultValue);
+
+ Object[] params;
+ if (args != null) {
+ params = args.toArray();
+ } else {
+ params = EMPTY_ARGS;
+ }
+
+ return format.format(params);
+ }
+ return text;
+ }
+
+ public String getText(String key, String defaultValue, String[] args) {
+ String text = getText(key, args);
+ if (text == null) {
+ MessageFormat format = new MessageFormat(defaultValue);
+ format.setLocale(ActionContext.getContext().getLocale());
+ format.applyPattern(defaultValue);
+
+ if (args == null) {
+ return format.format(EMPTY_ARGS);
+ }
+
+ return format.format(args);
+ }
+ return text;
+ }
+
+
+ public String getText(String key, String defaultValue, String obj) {
+ List<Object> args = new ArrayList<Object>(1);
+ args.add(obj);
+ return getText(key, defaultValue, args);
+ }
+
+ public String getText(String key, String defaultValue, List<?> args, ValueStack stack) {
+ //we're not using the value stack here
+ return getText(key, defaultValue, args);
+ }
+
+ public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
+ //we're not using the value stack here
+ List<Object> values = new ArrayList<Object>(Arrays.asList(args));
+ return getText(key, defaultValue, values);
+ }
+
+ public ResourceBundle getTexts(String bundleName) {
+ return LocalizedTextUtil.findResourceBundle(bundleName, ActionContext.getContext().getLocale());
+ }
+
+ public ResourceBundle getTexts() {
+ return null;
+ }
+
+}