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 2015/06/17 23:09:48 UTC
[48/57] [partial] struts git commit: Merges xwork packages into struts
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/ValidationAware.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/ValidationAware.java b/core/src/main/java/com/opensymphony/xwork2/ValidationAware.java
new file mode 100644
index 0000000..4ae5e84
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/ValidationAware.java
@@ -0,0 +1,130 @@
+/*
+ * 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 com.opensymphony.xwork2;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * ValidationAware classes can accept Action (class level) or field level error messages. Action level messages are kept
+ * in a Collection. Field level error messages are kept in a Map from String field name to a List of field error msgs.
+ *
+ * @author plightbo
+ */
+public interface ValidationAware {
+
+ /**
+ * Set the Collection of Action-level String error messages.
+ *
+ * @param errorMessages Collection of String error messages
+ */
+ void setActionErrors(Collection<String> errorMessages);
+
+ /**
+ * Get the Collection of Action-level error messages for this action. Error messages should not
+ * be added directly here, as implementations are free to return a new Collection or an
+ * Unmodifiable Collection.
+ *
+ * @return Collection of String error messages
+ */
+ Collection<String> getActionErrors();
+
+ /**
+ * Set the Collection of Action-level String messages (not errors).
+ *
+ * @param messages Collection of String messages (not errors).
+ */
+ void setActionMessages(Collection<String> messages);
+
+ /**
+ * Get the Collection of Action-level messages for this action. Messages should not be added
+ * directly here, as implementations are free to return a new Collection or an Unmodifiable
+ * Collection.
+ *
+ * @return Collection of String messages
+ */
+ Collection<String> getActionMessages();
+
+ /**
+ * Set the field error map of fieldname (String) to Collection of String error messages.
+ *
+ * @param errorMap field error map
+ */
+ void setFieldErrors(Map<String, List<String>> errorMap);
+
+ /**
+ * Get the field specific errors associated with this action. Error messages should not be added
+ * directly here, as implementations are free to return a new Collection or an Unmodifiable
+ * Collection.
+ *
+ * @return Map with errors mapped from fieldname (String) to Collection of String error messages
+ */
+ Map<String, List<String>> getFieldErrors();
+
+ /**
+ * Add an Action-level error message to this Action.
+ *
+ * @param anErrorMessage the error message
+ */
+ void addActionError(String anErrorMessage);
+
+ /**
+ * Add an Action-level message to this Action.
+ *
+ * @param aMessage the message
+ */
+ void addActionMessage(String aMessage);
+
+ /**
+ * Add an error message for a given field.
+ *
+ * @param fieldName name of field
+ * @param errorMessage the error message
+ */
+ void addFieldError(String fieldName, String errorMessage);
+
+ /**
+ * Check whether there are any Action-level error messages.
+ *
+ * @return true if any Action-level error messages have been registered
+ */
+ boolean hasActionErrors();
+
+ /**
+ * Checks whether there are any Action-level messages.
+ *
+ * @return true if any Action-level messages have been registered
+ */
+ boolean hasActionMessages();
+
+ /**
+ * Checks whether there are any action errors or field errors.
+ * <p/>
+ * <b>Note</b>: that this does not have the same meaning as in WW 1.x.
+ *
+ * @return <code>(hasActionErrors() || hasFieldErrors())</code>
+ */
+ boolean hasErrors();
+
+ /**
+ * Check whether there are any field errors associated with this action.
+ *
+ * @return whether there are any field errors
+ */
+ boolean hasFieldErrors();
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/ValidationAwareSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/ValidationAwareSupport.java b/core/src/main/java/com/opensymphony/xwork2/ValidationAwareSupport.java
new file mode 100644
index 0000000..520513b
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/ValidationAwareSupport.java
@@ -0,0 +1,169 @@
+/*
+ * 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 com.opensymphony.xwork2;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * Provides a default implementation of ValidationAware. Returns new collections for
+ * errors and messages (defensive copy).
+ *
+ * @author Jason Carreira
+ * @author tm_jee
+ * @version $Date$ $Id$
+ */
+public class ValidationAwareSupport implements ValidationAware, Serializable {
+
+ private Collection<String> actionErrors;
+ private Collection<String> actionMessages;
+ private Map<String, List<String>> fieldErrors;
+
+
+ public synchronized void setActionErrors(Collection<String> errorMessages) {
+ this.actionErrors = errorMessages;
+ }
+
+ public synchronized Collection<String> getActionErrors() {
+ return new LinkedList<>(internalGetActionErrors());
+ }
+
+ public synchronized void setActionMessages(Collection<String> messages) {
+ this.actionMessages = messages;
+ }
+
+ public synchronized Collection<String> getActionMessages() {
+ return new LinkedList<>(internalGetActionMessages());
+ }
+
+ public synchronized void setFieldErrors(Map<String, List<String>> errorMap) {
+ this.fieldErrors = errorMap;
+ }
+
+ public synchronized Map<String, List<String>> getFieldErrors() {
+ return new LinkedHashMap<>(internalGetFieldErrors());
+ }
+
+ public synchronized void addActionError(String anErrorMessage) {
+ internalGetActionErrors().add(anErrorMessage);
+ }
+
+ public synchronized void addActionMessage(String aMessage) {
+ internalGetActionMessages().add(aMessage);
+ }
+
+ public synchronized void addFieldError(String fieldName, String errorMessage) {
+ final Map<String, List<String>> errors = internalGetFieldErrors();
+ List<String> thisFieldErrors = errors.get(fieldName);
+
+ if (thisFieldErrors == null) {
+ thisFieldErrors = new ArrayList<>();
+ errors.put(fieldName, thisFieldErrors);
+ }
+
+ thisFieldErrors.add(errorMessage);
+ }
+
+ public synchronized boolean hasActionErrors() {
+ return (actionErrors != null) && !actionErrors.isEmpty();
+ }
+
+ public synchronized boolean hasActionMessages() {
+ return (actionMessages != null) && !actionMessages.isEmpty();
+ }
+
+ public synchronized boolean hasErrors() {
+ return (hasActionErrors() || hasFieldErrors());
+ }
+
+ public synchronized boolean hasFieldErrors() {
+ return (fieldErrors != null) && !fieldErrors.isEmpty();
+ }
+
+ private Collection<String> internalGetActionErrors() {
+ if (actionErrors == null) {
+ actionErrors = new ArrayList<>();
+ }
+
+ return actionErrors;
+ }
+
+ private Collection<String> internalGetActionMessages() {
+ if (actionMessages == null) {
+ actionMessages = new ArrayList<>();
+ }
+
+ return actionMessages;
+ }
+
+ private Map<String, List<String>> internalGetFieldErrors() {
+ if (fieldErrors == null) {
+ fieldErrors = new LinkedHashMap<>();
+ }
+
+ return fieldErrors;
+ }
+
+ /**
+ * Clears field errors map.
+ * <p/>
+ * Will clear the map that contains field errors.
+ */
+ public synchronized void clearFieldErrors() {
+ internalGetFieldErrors().clear();
+ }
+
+ /**
+ * Clears action errors list.
+ * <p/>
+ * Will clear the list that contains action errors.
+ */
+ public synchronized void clearActionErrors() {
+ internalGetActionErrors().clear();
+ }
+
+ /**
+ * Clears messages list.
+ * <p/>
+ * Will clear the list that contains action messages.
+ */
+ public synchronized void clearMessages() {
+ internalGetActionMessages().clear();
+ }
+
+ /**
+ * Clears all error list/maps.
+ * <p/>
+ * Will clear the map and list that contain
+ * field errors and action errors.
+ */
+ public synchronized void clearErrors() {
+ internalGetFieldErrors().clear();
+ internalGetActionErrors().clear();
+ }
+
+ /**
+ * Clears all error and messages list/maps.
+ * <p/>
+ * Will clear the maps/lists that contain
+ * field errors, action errors and action messages.
+ */
+ public synchronized void clearErrorsAndMessages() {
+ internalGetFieldErrors().clear();
+ internalGetActionErrors().clear();
+ internalGetActionMessages().clear();
+ }
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/XWork.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/XWork.java b/core/src/main/java/com/opensymphony/xwork2/XWork.java
new file mode 100644
index 0000000..fddc75b
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/XWork.java
@@ -0,0 +1,79 @@
+/*
+ * 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 com.opensymphony.xwork2;
+
+import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.ConfigurationManager;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Simple facade to make using XWork standalone easier
+ */
+public class XWork {
+
+ ConfigurationManager configurationManager;
+
+ public XWork() {
+ this(new ConfigurationManager());
+ }
+
+ public XWork(ConfigurationManager mgr) {
+ this.configurationManager = mgr;
+ }
+
+ public void setLoggerFactory(LoggerFactory factory) {
+ LoggerFactory.setLoggerFactory(factory);
+ }
+
+ /**
+ * Executes an action
+ *
+ * @param namespace The namespace
+ * @param name The action name
+ * @param method The method name
+ * @throws Exception If anything goes wrong
+ */
+ public void executeAction(String namespace, String name, String method) throws XWorkException {
+ Map<String, Object> extraContext = Collections.emptyMap();
+ executeAction(namespace, name, method, extraContext);
+ }
+
+ /**
+ * Executes an action with extra context information
+ *
+ * @param namespace The namespace
+ * @param name The action name
+ * @param method The method name
+ * @param extraContext A map of extra context information
+ * @throws Exception If anything goes wrong
+ */
+ public void executeAction(String namespace, String name, String method, Map<String, Object> extraContext) throws XWorkException {
+ Configuration config = configurationManager.getConfiguration();
+ try {
+ ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
+ namespace, name, method, extraContext, true, false);
+
+ proxy.execute();
+ } catch (Exception e) {
+ throw new XWorkException(e);
+ } finally {
+ ActionContext.setContext(null);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/XWorkConstants.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/XWorkConstants.java b/core/src/main/java/com/opensymphony/xwork2/XWorkConstants.java
new file mode 100644
index 0000000..433b005
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/XWorkConstants.java
@@ -0,0 +1,30 @@
+package com.opensymphony.xwork2;
+
+/**
+ * Constants used across framework
+ */
+public final class XWorkConstants {
+
+ public static final String COLLECTION_CONVERTER = "collectionConverter";
+ public static final String DATE_CONVERTER = "dateConverter";
+ public static final String NUMBER_CONVERTER = "numberConverter";
+ public static final String STRING_CONVERTER = "stringConverter";
+ public static final String ARRAY_CONVERTER = "arrayConverter";
+ public static final String DEV_MODE = "devMode";
+ public static final String LOG_MISSING_PROPERTIES = "logMissingProperties";
+ public static final String ENABLE_OGNL_EXPRESSION_CACHE = "enableOGNLExpressionCache";
+ public static final String ENABLE_OGNL_EVAL_EXPRESSION = "enableOGNLEvalExpression";
+ public static final String RELOAD_XML_CONFIGURATION = "reloadXmlConfiguration";
+ public static final String ALLOW_STATIC_METHOD_ACCESS = "allowStaticMethodAccess";
+ public static final String XWORK_LOGGER_FACTORY = "xwork.loggerFactory";
+
+ public static final String OGNL_EXCLUDED_CLASSES = "ognlExcludedClasses";
+ public static final String OGNL_EXCLUDED_PACKAGE_NAME_PATTERNS = "ognlExcludedPackageNamePatterns";
+
+ public static final String ADDITIONAL_EXCLUDED_PATTERNS = "additionalExcludedPatterns";
+ public static final String ADDITIONAL_ACCEPTED_PATTERNS = "additionalAcceptedPatterns";
+
+ public static final String OVERRIDE_EXCLUDED_PATTERNS = "overrideExcludedPatterns";
+ public static final String OVERRIDE_ACCEPTED_PATTERNS = "overrideAcceptedPatterns";
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/XWorkException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/XWorkException.java b/core/src/main/java/com/opensymphony/xwork2/XWorkException.java
new file mode 100644
index 0000000..8445a1c
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/XWorkException.java
@@ -0,0 +1,154 @@
+/*
+ * 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 com.opensymphony.xwork2;
+
+import com.opensymphony.xwork2.util.location.Locatable;
+import com.opensymphony.xwork2.util.location.Location;
+import com.opensymphony.xwork2.util.location.LocationUtils;
+
+
+/**
+ * A generic runtime exception that optionally contains Location information
+ *
+ * @author Jason Carreira
+ */
+public class XWorkException extends RuntimeException implements Locatable {
+
+ private Location location;
+
+
+ /**
+ * Constructs a <code>XWorkException</code> with no detail message.
+ */
+ public XWorkException() {
+ }
+
+ /**
+ * Constructs a <code>XWorkException</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public XWorkException(String s) {
+ this(s, null, null);
+ }
+
+ /**
+ * Constructs a <code>XWorkException</code> with the specified
+ * detail message and target.
+ *
+ * @param s the detail message.
+ * @param target the target of the exception.
+ */
+ public XWorkException(String s, Object target) {
+ this(s, null, target);
+ }
+
+ /**
+ * Constructs a <code>XWorkException</code> with the root cause
+ *
+ * @param cause The wrapped exception
+ */
+ public XWorkException(Throwable cause) {
+ this(null, cause, null);
+ }
+
+ /**
+ * Constructs a <code>XWorkException</code> with the root cause and target
+ *
+ * @param cause The wrapped exception
+ * @param target The target of the exception
+ */
+ public XWorkException(Throwable cause, Object target) {
+ this(null, cause, target);
+ }
+
+ /**
+ * Constructs a <code>XWorkException</code> with the specified
+ * detail message and exception cause.
+ *
+ * @param s the detail message.
+ * @param cause the wrapped exception
+ */
+ public XWorkException(String s, Throwable cause) {
+ this(s, cause, null);
+ }
+
+
+ /**
+ * Constructs a <code>XWorkException</code> with the specified
+ * detail message, cause, and target
+ *
+ * @param s the detail message.
+ * @param cause The wrapped exception
+ * @param target The target of the exception
+ */
+ public XWorkException(String s, Throwable cause, Object target) {
+ super(s, cause);
+
+ this.location = LocationUtils.getLocation(target);
+ if (this.location == Location.UNKNOWN) {
+ this.location = LocationUtils.getLocation(cause);
+ }
+ }
+
+
+ /**
+ * Gets the underlying cause
+ *
+ * @return the underlying cause, <tt>null</tt> if no cause
+ * @deprecated Use {@link #getCause()}
+ */
+ @Deprecated public Throwable getThrowable() {
+ return getCause();
+ }
+
+
+ /**
+ * Gets the location of the error, if available
+ *
+ * @return the location, <tt>null</tt> if not available
+ */
+ public Location getLocation() {
+ return this.location;
+ }
+
+
+ /**
+ * Returns a short description of this throwable object, including the
+ * location. If no detailed message is available, it will use the message
+ * of the underlying exception if available.
+ *
+ * @return a string representation of this <code>Throwable</code>.
+ */
+ @Override
+ public String toString() {
+ String msg = getMessage();
+ if (msg == null && getCause() != null) {
+ msg = getCause().getMessage();
+ }
+
+ if (location != null) {
+ if (msg != null) {
+ return msg + " - " + location.toString();
+ } else {
+ return location.toString();
+ }
+ } else {
+ return msg;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/XWorkJUnit4TestCase.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/XWorkJUnit4TestCase.java b/core/src/main/java/com/opensymphony/xwork2/XWorkJUnit4TestCase.java
new file mode 100644
index 0000000..90b53d2
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/XWorkJUnit4TestCase.java
@@ -0,0 +1,79 @@
+/*
+ * 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 com.opensymphony.xwork2;
+
+import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.ConfigurationException;
+import com.opensymphony.xwork2.config.ConfigurationManager;
+import com.opensymphony.xwork2.config.ConfigurationProvider;
+import com.opensymphony.xwork2.inject.*;
+import com.opensymphony.xwork2.test.StubConfigurationProvider;
+import com.opensymphony.xwork2.util.XWorkTestCaseHelper;
+import com.opensymphony.xwork2.util.location.LocatableProperties;
+import org.junit.After;
+import org.junit.Before;
+
+public abstract class XWorkJUnit4TestCase {
+
+ protected ConfigurationManager configurationManager;
+ protected Configuration configuration;
+ protected Container container;
+ protected ActionProxyFactory actionProxyFactory;
+
+ @Before
+ public void setUp() throws Exception {
+ configurationManager = XWorkTestCaseHelper.setUp();
+ configuration = configurationManager.getConfiguration();
+ container = configuration.getContainer();
+ actionProxyFactory = container.getInstance(ActionProxyFactory.class);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ XWorkTestCaseHelper.tearDown(configurationManager);
+ configurationManager = null;
+ configuration = null;
+ container = null;
+ actionProxyFactory = null;
+ }
+
+ protected void loadConfigurationProviders(ConfigurationProvider... providers) {
+ configurationManager = XWorkTestCaseHelper.loadConfigurationProviders(configurationManager, providers);
+ configuration = configurationManager.getConfiguration();
+ container = configuration.getContainer();
+ actionProxyFactory = container.getInstance(ActionProxyFactory.class);
+ }
+
+ protected void loadButAdd(final Class<?> type, final Object impl) {
+ loadButAdd(type, Container.DEFAULT_NAME, impl);
+ }
+
+ protected void loadButAdd(final Class<?> type, final String name, final Object impl) {
+ loadConfigurationProviders(new StubConfigurationProvider() {
+ @Override
+ public void register(ContainerBuilder builder,
+ LocatableProperties props) throws ConfigurationException {
+ builder.factory(type, name, new Factory() {
+ public Object create(Context context) throws Exception {
+ return impl;
+ }
+
+ }, Scope.SINGLETON);
+ }
+ });
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/XWorkMessages.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/XWorkMessages.java b/core/src/main/java/com/opensymphony/xwork2/XWorkMessages.java
new file mode 100644
index 0000000..d187acc
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/XWorkMessages.java
@@ -0,0 +1,31 @@
+/*
+ * 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 com.opensymphony.xwork2;
+
+
+/**
+ * Contains constants for some default XWork messages.
+ *
+ * @author Jason Carreira
+ */
+public interface XWorkMessages {
+
+ public static final String ACTION_EXECUTION_ERROR = "xwork.error.action.execution";
+ public static final String MISSING_ACTION_EXCEPTION = "xwork.exception.missing-action";
+ public static final String MISSING_PACKAGE_ACTION_EXCEPTION = "xwork.exception.missing-package-action";
+ public static final String DEFAULT_INVALID_FIELDVALUE = "xwork.default.invalid.fieldvalue";
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/XWorkTestCase.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/XWorkTestCase.java b/core/src/main/java/com/opensymphony/xwork2/XWorkTestCase.java
new file mode 100644
index 0000000..c9b4e32
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/XWorkTestCase.java
@@ -0,0 +1,90 @@
+/*
+ * 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 com.opensymphony.xwork2;
+
+import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.ConfigurationException;
+import com.opensymphony.xwork2.config.ConfigurationManager;
+import com.opensymphony.xwork2.config.ConfigurationProvider;
+import com.opensymphony.xwork2.inject.*;
+import com.opensymphony.xwork2.test.StubConfigurationProvider;
+import com.opensymphony.xwork2.util.XWorkTestCaseHelper;
+import com.opensymphony.xwork2.util.location.LocatableProperties;
+import junit.framework.TestCase;
+
+
+/**
+ * Base JUnit TestCase to extend for XWork specific JUnit tests. Uses
+ * the generic test setup for logic.
+ *
+ * @author plightbo
+ */
+public abstract class XWorkTestCase extends TestCase {
+
+ protected ConfigurationManager configurationManager;
+ protected Configuration configuration;
+ protected Container container;
+ protected ActionProxyFactory actionProxyFactory;
+
+ public XWorkTestCase() {
+ super();
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ configurationManager = XWorkTestCaseHelper.setUp();
+ configuration = configurationManager.getConfiguration();
+ container = configuration.getContainer();
+ actionProxyFactory = container.getInstance(ActionProxyFactory.class);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ XWorkTestCaseHelper.tearDown(configurationManager);
+ configurationManager = null;
+ configuration = null;
+ container = null;
+ actionProxyFactory = null;
+ }
+
+ protected void loadConfigurationProviders(ConfigurationProvider... providers) {
+ configurationManager = XWorkTestCaseHelper.loadConfigurationProviders(configurationManager, providers);
+ configuration = configurationManager.getConfiguration();
+ container = configuration.getContainer();
+ actionProxyFactory = container.getInstance(ActionProxyFactory.class);
+ }
+
+ protected void loadButAdd(final Class<?> type, final Object impl) {
+ loadButAdd(type, Container.DEFAULT_NAME, impl);
+ }
+
+ protected void loadButAdd(final Class<?> type, final String name, final Object impl) {
+ loadConfigurationProviders(new StubConfigurationProvider() {
+ @Override
+ public void register(ContainerBuilder builder,
+ LocatableProperties props) throws ConfigurationException {
+ builder.factory(type, name, new Factory() {
+ public Object create(Context context) throws Exception {
+ return impl;
+ }
+
+ }, Scope.SINGLETON);
+ }
+ });
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/BeanSelectionProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/BeanSelectionProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/BeanSelectionProvider.java
new file mode 100644
index 0000000..d6cef8b
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/BeanSelectionProvider.java
@@ -0,0 +1,8 @@
+package com.opensymphony.xwork2.config;
+
+/**
+ * When implemented allows to alias already existing beans
+ */
+public interface BeanSelectionProvider extends ConfigurationProvider {
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/Configuration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/Configuration.java b/core/src/main/java/com/opensymphony/xwork2/config/Configuration.java
new file mode 100644
index 0000000..be1359d
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/Configuration.java
@@ -0,0 +1,98 @@
+/*
+ * 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 com.opensymphony.xwork2.config;
+
+import com.opensymphony.xwork2.config.entities.PackageConfig;
+import com.opensymphony.xwork2.config.entities.UnknownHandlerConfig;
+import com.opensymphony.xwork2.inject.Container;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * XWork configuration.
+ *
+ * @author Mike
+ */
+public interface Configuration extends Serializable {
+
+ void rebuildRuntimeConfiguration();
+
+ PackageConfig getPackageConfig(String name);
+
+ Set<String> getPackageConfigNames();
+
+ Map<String, PackageConfig> getPackageConfigs();
+
+ /**
+ * The current runtime configuration. Currently, if changes have been made to the Configuration since the last
+ * time buildRuntimeConfiguration() was called, you'll need to make sure to.
+ *
+ * @return the current runtime configuration
+ */
+ RuntimeConfiguration getRuntimeConfiguration();
+
+ void addPackageConfig(String name, PackageConfig packageConfig);
+
+ /**
+ * Removes a package from the the list of packages. Changes to the configuration won't take effect until buildRuntimeConfiguration
+ * is called.
+ * @param packageName the name of the package to remove
+ * @return the package removed (if any)
+ */
+ PackageConfig removePackageConfig(String packageName);
+
+ /**
+ * Allow the Configuration to clean up any resources that have been used.
+ */
+ void destroy();
+
+ /**
+ * @deprecated Since 2.1
+ * @param providers
+ * @throws ConfigurationException
+ */
+ @Deprecated void reload(List<ConfigurationProvider> providers) throws ConfigurationException;
+
+ /**
+ * @since 2.1
+ * @param containerProviders
+ * @throws ConfigurationException
+ */
+ List<PackageProvider> reloadContainer(List<ContainerProvider> containerProviders) throws ConfigurationException;
+
+ /**
+ * @return the container
+ */
+ Container getContainer();
+
+ Set<String> getLoadedFileNames();
+
+ /**
+ * @since 2.1
+ * @return list of unknown handlers
+ */
+ List<UnknownHandlerConfig> getUnknownHandlerStack();
+
+ /**
+ * @since 2.1
+ * @param unknownHandlerStack
+ */
+ void setUnknownHandlerStack(List<UnknownHandlerConfig> unknownHandlerStack);
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationException.java b/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationException.java
new file mode 100644
index 0000000..fcbb11b
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationException.java
@@ -0,0 +1,87 @@
+/*
+ * 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 com.opensymphony.xwork2.config;
+
+import com.opensymphony.xwork2.XWorkException;
+
+
+/**
+ * ConfigurationException
+ *
+ * @author Jason Carreira
+ */
+public class ConfigurationException extends XWorkException {
+
+ /**
+ * Constructs a <code>ConfigurationException</code> with no detail message.
+ */
+ public ConfigurationException() {
+ }
+
+ /**
+ * Constructs a <code>ConfigurationException</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public ConfigurationException(String s) {
+ super(s);
+ }
+
+ /**
+ * Constructs a <code>ConfigurationException</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public ConfigurationException(String s, Object target) {
+ super(s, target);
+ }
+
+ /**
+ * Constructs a <code>ConfigurationException</code> with no detail message.
+ */
+ public ConfigurationException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a <code>ConfigurationException</code> with no detail message.
+ */
+ public ConfigurationException(Throwable cause, Object target) {
+ super(cause, target);
+ }
+
+ /**
+ * Constructs a <code>ConfigurationException</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public ConfigurationException(String s, Throwable cause) {
+ super(s, cause);
+ }
+
+ /**
+ * Constructs a <code>ConfigurationException</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public ConfigurationException(String s, Throwable cause, Object target) {
+ super(s, cause, target);
+ }
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationManager.java b/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationManager.java
new file mode 100644
index 0000000..38920f7
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationManager.java
@@ -0,0 +1,232 @@
+/*
+ * 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 com.opensymphony.xwork2.config;
+
+import com.opensymphony.xwork2.XWorkConstants;
+import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
+import com.opensymphony.xwork2.config.providers.XWorkConfigurationProvider;
+import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+
+/**
+ * ConfigurationManager - central for XWork Configuration management, including
+ * its ConfigurationProvider.
+ *
+ * @author Jason Carreira
+ * @author tm_jee
+ * @version $Date$ $Id$
+ */
+public class ConfigurationManager {
+
+ protected static final Logger LOG = LogManager.getLogger(ConfigurationManager.class);
+ protected Configuration configuration;
+ protected Lock providerLock = new ReentrantLock();
+ private List<ContainerProvider> containerProviders = new CopyOnWriteArrayList<>();
+ private List<PackageProvider> packageProviders = new CopyOnWriteArrayList<>();
+ protected String defaultFrameworkBeanName;
+ private boolean providersChanged = false;
+ private boolean reloadConfigs = true; // for the first time
+
+ public ConfigurationManager() {
+ this("xwork");
+ }
+
+ public ConfigurationManager(String name) {
+ this.defaultFrameworkBeanName = name;
+ }
+
+ /**
+ * Get the current XWork configuration object. By default an instance of DefaultConfiguration will be returned
+ *
+ * @see com.opensymphony.xwork2.config.impl.DefaultConfiguration
+ */
+ public synchronized Configuration getConfiguration() {
+ if (configuration == null) {
+ setConfiguration(createConfiguration(defaultFrameworkBeanName));
+ try {
+ configuration.reloadContainer(getContainerProviders());
+ } catch (ConfigurationException e) {
+ setConfiguration(null);
+ throw new ConfigurationException("Unable to load configuration.", e);
+ }
+ } else {
+ conditionalReload();
+ }
+
+ return configuration;
+ }
+
+ protected Configuration createConfiguration(String beanName) {
+ return new DefaultConfiguration(beanName);
+ }
+
+ public synchronized void setConfiguration(Configuration configuration) {
+ this.configuration = configuration;
+ }
+
+ /**
+ * Get the current list of ConfigurationProviders. If no custom ConfigurationProviders have been added, this method
+ * will return a list containing only the default ConfigurationProvider, XMLConfigurationProvider. if a custom
+ * ConfigurationProvider has been added, then the XmlConfigurationProvider must be added by hand.
+ * </p>
+ * <p/>
+ * TODO: the lazy instantiation of XmlConfigurationProvider should be refactored to be elsewhere. the behavior described above seems unintuitive.
+ *
+ * @return the list of registered ConfigurationProvider objects
+ * @see ConfigurationProvider
+ */
+ public List<ContainerProvider> getContainerProviders() {
+ providerLock.lock();
+ try {
+ if (containerProviders.size() == 0) {
+ containerProviders.add(new XWorkConfigurationProvider());
+ containerProviders.add(new XmlConfigurationProvider("xwork.xml", false));
+ }
+
+ return containerProviders;
+ } finally {
+ providerLock.unlock();
+ }
+ }
+
+ /**
+ * Set the list of configuration providers
+ *
+ * @param containerProviders list of {@link ConfigurationProvider} to be set
+ */
+ public void setContainerProviders(List<ContainerProvider> containerProviders) {
+ providerLock.lock();
+ try {
+ this.containerProviders = new CopyOnWriteArrayList<>(containerProviders);
+ providersChanged = true;
+ } finally {
+ providerLock.unlock();
+ }
+ }
+
+ /**
+ * adds a configuration provider to the List of ConfigurationProviders. a given ConfigurationProvider may be added
+ * more than once
+ *
+ * @param provider the ConfigurationProvider to register
+ */
+ public void addContainerProvider(ContainerProvider provider) {
+ if (!containerProviders.contains(provider)) {
+ containerProviders.add(provider);
+ providersChanged = true;
+ }
+ }
+
+ public void clearContainerProviders() {
+ for (ContainerProvider containerProvider : containerProviders) {
+ clearContainerProvider(containerProvider);
+ }
+ containerProviders.clear();
+ providersChanged = true;
+ }
+
+ private void clearContainerProvider(ContainerProvider containerProvider) {
+ try {
+ containerProvider.destroy();
+ } catch (Exception e) {
+ LOG.warn("Error while destroying container provider [{}]", containerProvider.toString(), e);
+ }
+ }
+
+ /**
+ * Destroy its managing Configuration instance
+ */
+ public synchronized void destroyConfiguration() {
+ clearContainerProviders(); // let's destroy the ConfigurationProvider first
+ containerProviders = new CopyOnWriteArrayList<ContainerProvider>();
+ if (configuration != null)
+ configuration.destroy(); // let's destroy it first, before nulling it.
+ configuration = null;
+ }
+
+
+ /**
+ * Reloads the Configuration files if the configuration files indicate that they need to be reloaded.
+ */
+ public synchronized void conditionalReload() {
+ if (reloadConfigs || providersChanged) {
+ LOG.debug("Checking ConfigurationProviders for reload.");
+ List<ContainerProvider> providers = getContainerProviders();
+ boolean reload = needReloadContainerProviders(providers);
+ if (!reload) {
+ reload = needReloadPackageProviders();
+ }
+ if (reload) {
+ reloadProviders(providers);
+ }
+ updateReloadConfigsFlag();
+ providersChanged = false;
+ }
+ }
+
+ private void updateReloadConfigsFlag() {
+ reloadConfigs = Boolean.parseBoolean(configuration.getContainer().getInstance(String.class, XWorkConstants.RELOAD_XML_CONFIGURATION));
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Updating [{}], current value is [{}], new value [{}]",
+ XWorkConstants.RELOAD_XML_CONFIGURATION, String.valueOf(reloadConfigs), String.valueOf(reloadConfigs));
+ }
+ }
+
+ private boolean needReloadPackageProviders() {
+ if (packageProviders != null) {
+ for (PackageProvider provider : packageProviders) {
+ if (provider.needsReload()) {
+ LOG.info("Detected package provider [{}] needs to be reloaded. Reloading all providers.", provider);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean needReloadContainerProviders(List<ContainerProvider> providers) {
+ for (ContainerProvider provider : providers) {
+ if (provider.needsReload()) {
+ LOG.info("Detected container provider [{}] needs to be reloaded. Reloading all providers.", provider);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void reloadProviders(List<ContainerProvider> providers) {
+ for (ContainerProvider containerProvider : containerProviders) {
+ try {
+ containerProvider.destroy();
+ } catch (Exception e) {
+ LOG.warn("error while destroying configuration provider [{}]", containerProvider, e);
+ }
+ }
+ packageProviders = this.configuration.reloadContainer(providers);
+ }
+
+ public synchronized void reload() {
+ packageProviders = getConfiguration().reloadContainer(getContainerProviders());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationProvider.java
new file mode 100644
index 0000000..146532b
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationProvider.java
@@ -0,0 +1,22 @@
+/*
+ * 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 com.opensymphony.xwork2.config;
+
+/**
+ * Interface to be implemented by all forms of XWork configuration classes.
+ */
+public interface ConfigurationProvider extends ContainerProvider, PackageProvider {
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationUtil.java b/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationUtil.java
new file mode 100644
index 0000000..e7ba7a6
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/ConfigurationUtil.java
@@ -0,0 +1,83 @@
+/*
+ * 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 com.opensymphony.xwork2.config;
+
+import com.opensymphony.xwork2.config.entities.PackageConfig;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * ConfigurationUtil
+ *
+ * @author Jason Carreira Created May 23, 2003 11:22:49 PM
+ */
+public class ConfigurationUtil {
+
+ private static final Logger LOG = LogManager.getLogger(ConfigurationUtil.class);
+
+ private ConfigurationUtil() {
+ }
+
+ /**
+ * Get the {@link PackageConfig} elements with the specified names.
+ * @param configuration Configuration from which to find the package elements
+ * @param parent Comma separated list of parent package names
+ * @return The package elements that correspond to the names in the {@code parent} parameter.
+ */
+ public static List<PackageConfig> buildParentsFromString(Configuration configuration, String parent) {
+ List<String> parentPackageNames = buildParentListFromString(parent);
+ List<PackageConfig> parentPackageConfigs = new ArrayList<>();
+ for (String parentPackageName : parentPackageNames) {
+ PackageConfig parentPackageContext = configuration.getPackageConfig(parentPackageName);
+
+ if (parentPackageContext != null) {
+ parentPackageConfigs.add(parentPackageContext);
+ }
+ }
+
+ return parentPackageConfigs;
+ }
+
+ /**
+ * Splits the string into a list using a comma as the token separator.
+ * @param parent The comma separated string.
+ * @return A list of tokens from the specified string.
+ */
+ public static List<String> buildParentListFromString(String parent) {
+ if (StringUtils.isEmpty(parent)) {
+ return Collections.emptyList();
+ }
+
+ StringTokenizer tokenizer = new StringTokenizer(parent, ",");
+ List<String> parents = new ArrayList<>();
+
+ while (tokenizer.hasMoreTokens()) {
+ String parentName = tokenizer.nextToken().trim();
+
+ if (StringUtils.isNotEmpty(parentName)) {
+ parents.add(parentName);
+ }
+ }
+
+ return parents;
+ }
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/ContainerProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/ContainerProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/ContainerProvider.java
new file mode 100644
index 0000000..de943f0
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/ContainerProvider.java
@@ -0,0 +1,57 @@
+/*
+ * 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 com.opensymphony.xwork2.config;
+
+import com.opensymphony.xwork2.inject.ContainerBuilder;
+import com.opensymphony.xwork2.util.location.LocatableProperties;
+
+
+/**
+ * Provides beans and constants/properties for the Container
+ *
+ * @since 2.1
+ */
+public interface ContainerProvider {
+
+ /**
+ * Called before removed from the configuration manager
+ */
+ public void destroy();
+
+ /**
+ * Initializes with the configuration
+ * @param configuration The configuration
+ * @throws ConfigurationException If anything goes wrong
+ */
+ public void init(Configuration configuration) throws ConfigurationException;
+
+ /**
+ * Tells whether the ContainerProvider should reload its configuration
+ *
+ * @return <tt>true</tt>, whether the ContainerProvider should reload its configuration, <tt>false</tt>otherwise.
+ */
+ public boolean needsReload();
+
+ /**
+ * Registers beans and properties for the Container
+ *
+ * @param builder The builder to register beans with
+ * @param props The properties to register constants with
+ * @throws ConfigurationException If anything goes wrong
+ */
+ public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException;
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/FileManagerFactoryProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/FileManagerFactoryProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/FileManagerFactoryProvider.java
new file mode 100644
index 0000000..392b138
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/FileManagerFactoryProvider.java
@@ -0,0 +1,33 @@
+package com.opensymphony.xwork2.config;
+
+import com.opensymphony.xwork2.FileManagerFactory;
+import com.opensymphony.xwork2.inject.ContainerBuilder;
+import com.opensymphony.xwork2.inject.Scope;
+import com.opensymphony.xwork2.util.location.LocatableProperties;
+
+/**
+ * Allows to specify custom {@link FileManagerFactory}
+ */
+public class FileManagerFactoryProvider implements ContainerProvider {
+
+ private Class<? extends FileManagerFactory> factoryClass;
+
+ public FileManagerFactoryProvider(Class<? extends FileManagerFactory> factoryClass) {
+ this.factoryClass = factoryClass;
+ }
+
+ public void destroy() {
+ }
+
+ public void init(Configuration configuration) throws ConfigurationException {
+ }
+
+ public boolean needsReload() {
+ return false;
+ }
+
+ public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {
+ builder.factory(FileManagerFactory.class, factoryClass.getSimpleName(), factoryClass, Scope.SINGLETON);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/FileManagerProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/FileManagerProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/FileManagerProvider.java
new file mode 100644
index 0000000..100f458
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/FileManagerProvider.java
@@ -0,0 +1,35 @@
+package com.opensymphony.xwork2.config;
+
+import com.opensymphony.xwork2.FileManager;
+import com.opensymphony.xwork2.inject.ContainerBuilder;
+import com.opensymphony.xwork2.inject.Scope;
+import com.opensymphony.xwork2.util.location.LocatableProperties;
+
+/**
+ * Allows to specify custom {@link FileManager} by user
+ */
+public class FileManagerProvider implements ContainerProvider {
+
+ private Class<? extends FileManager> fileManagerClass;
+ private String name;
+
+ public FileManagerProvider(Class<? extends FileManager> fileManagerClass, String name) {
+ this.fileManagerClass = fileManagerClass;
+ this.name = name;
+ }
+
+ public void destroy() {
+ }
+
+ public void init(Configuration configuration) throws ConfigurationException {
+ }
+
+ public boolean needsReload() {
+ return false;
+ }
+
+ public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {
+ builder.factory(FileManager.class, name, fileManagerClass, Scope.SINGLETON);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/PackageProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/PackageProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/PackageProvider.java
new file mode 100644
index 0000000..dd0dfae
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/PackageProvider.java
@@ -0,0 +1,46 @@
+/*
+ * 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 com.opensymphony.xwork2.config;
+
+/**
+ * Provides configuration packages. The separate init and loadPackages calls are due to the need to
+ * preserve backwards compatibility with the 2.0 {@link ConfigurationProvider} interface
+ *
+ * @since 2.1
+ */
+public interface PackageProvider {
+
+ /**
+ * Initializes with the configuration
+ * @param configuration The configuration
+ * @throws ConfigurationException If anything goes wrong
+ */
+ public void init(Configuration configuration) throws ConfigurationException;
+
+ /**
+ * Tells whether the PackageProvider should reload its configuration
+ *
+ * @return <tt>true</tt>, whether the PackageProvider should reload its configuration, <tt>false</tt>otherwise.
+ */
+ public boolean needsReload();
+
+ /**
+ * Loads the packages for the configuration.
+ * @throws ConfigurationException
+ */
+ public void loadPackages() throws ConfigurationException;
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/ReferenceResolverException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/ReferenceResolverException.java b/core/src/main/java/com/opensymphony/xwork2/config/ReferenceResolverException.java
new file mode 100644
index 0000000..00f1adb
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/ReferenceResolverException.java
@@ -0,0 +1,43 @@
+/*
+ * 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 com.opensymphony.xwork2.config;
+
+import com.opensymphony.xwork2.XWorkException;
+
+
+/**
+ * Exception when a reference can't be resolved.
+ *
+ * @author Mike
+ */
+public class ReferenceResolverException extends XWorkException {
+
+ public ReferenceResolverException() {
+ super();
+ }
+
+ public ReferenceResolverException(String s) {
+ super(s);
+ }
+
+ public ReferenceResolverException(String s, Throwable cause) {
+ super(s, cause);
+ }
+
+ public ReferenceResolverException(Throwable cause) {
+ super(cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/RuntimeConfiguration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/RuntimeConfiguration.java b/core/src/main/java/com/opensymphony/xwork2/config/RuntimeConfiguration.java
new file mode 100644
index 0000000..f24c766
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/RuntimeConfiguration.java
@@ -0,0 +1,53 @@
+/*
+ * 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 com.opensymphony.xwork2.config;
+
+import com.opensymphony.xwork2.config.entities.ActionConfig;
+
+import java.io.Serializable;
+import java.util.Map;
+
+
+/**
+ * RuntimeConfiguration
+ *
+ * @author Jason Carreira
+ * Created Feb 25, 2003 10:56:02 PM
+ */
+public interface RuntimeConfiguration extends Serializable {
+
+ /**
+ * get the fully expanded ActionConfig for a specified namespace and (action) name
+ *
+ * @param namespace the namespace of the Action. if this is null, then the empty namespace, "", will be used
+ * @param name the name of the Action. may not be null.
+ * @return the requested ActionConfig or null if there was no ActionConfig associated with the specified namespace
+ * and name
+ */
+ ActionConfig getActionConfig(String namespace, String name);
+
+ /**
+ * returns a Map of all the registered ActionConfigs. Again, these ActionConfigs are fully expanded so that any
+ * inherited interceptors, results, etc. will be included
+ *
+ * @return a Map of Map keyed by namespace and name respectively such that
+ * <pre>
+ * ActionConfig config = (ActionConfig)((Map)getActionConfigs.get(namespace)).get(name);
+ * </pre>
+ * should return a valid config for valid namespace/name pairs
+ */
+ Map<String, Map<String, ActionConfig>> getActionConfigs();
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java
new file mode 100644
index 0000000..d796c02
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java
@@ -0,0 +1,351 @@
+/*
+ * 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 com.opensymphony.xwork2.config.entities;
+
+import com.opensymphony.xwork2.util.location.Located;
+import com.opensymphony.xwork2.util.location.Location;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.Serializable;
+import java.util.*;
+
+
+/**
+ * Contains everything needed to configure and execute an action:
+ * <ul>
+ * <li>methodName - the method name to execute on the action. If this is null, the Action will be cast to the Action
+ * Interface and the execute() method called</li>
+ * <li>clazz - the class name for the action</li>
+ * <li>params - the params to be set for this action just before execution</li>
+ * <li>results - the result map {String -> View class}</li>
+ * <li>resultParameters - params for results {String -> Map}</li>
+ * <li>typeConverter - the Ognl TypeConverter to use when getting/setting properties</li>
+ * </ul>
+ *
+ * @author Mike
+ * @author Rainer Hermanns
+ * @version $Revision$
+ */
+public class ActionConfig extends Located implements Serializable {
+
+ public static final String DEFAULT_METHOD = "execute";
+ public static final String WILDCARD = "*";
+
+ protected List<InterceptorMapping> interceptors; // a list of interceptorMapping Objects eg. List<InterceptorMapping>
+ protected Map<String,String> params;
+ protected Map<String, ResultConfig> results;
+ protected List<ExceptionMappingConfig> exceptionMappings;
+ protected String className;
+ protected String methodName;
+ protected String packageName;
+ protected String name;
+ protected Set<String> allowedMethods;
+
+ protected ActionConfig(String packageName, String name, String className) {
+ this.packageName = packageName;
+ this.name = name;
+ this.className = className;
+ params = new LinkedHashMap<String, String>();
+ results = new LinkedHashMap<String, ResultConfig>();
+ interceptors = new ArrayList<InterceptorMapping>();
+ exceptionMappings = new ArrayList<ExceptionMappingConfig>();
+ allowedMethods = new HashSet<String>();
+ }
+
+ /**
+ * Clones an ActionConfig, copying data into new maps and lists
+ * @param orig The ActionConfig to clone
+ * @Since 2.1
+ */
+ protected ActionConfig(ActionConfig orig) {
+ this.name = orig.name;
+ this.className = orig.className;
+ this.methodName = orig.methodName;
+ this.packageName = orig.packageName;
+ this.params = new LinkedHashMap<>(orig.params);
+ this.interceptors = new ArrayList<>(orig.interceptors);
+ this.results = new LinkedHashMap<>(orig.results);
+ this.exceptionMappings = new ArrayList<>(orig.exceptionMappings);
+ this.allowedMethods = new HashSet<>(orig.allowedMethods);
+ this.location = orig.location;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public List<ExceptionMappingConfig> getExceptionMappings() {
+ return exceptionMappings;
+ }
+
+ public List<InterceptorMapping> getInterceptors() {
+ return interceptors;
+ }
+
+ public Set<String> getAllowedMethods() {
+ return allowedMethods;
+ }
+
+ /**
+ * Returns name of the action method
+ *
+ * @return name of the method to execute
+ */
+ public String getMethodName() {
+ return methodName;
+ }
+
+ /**
+ * @return Returns the packageName.
+ */
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public Map<String, String> getParams() {
+ return params;
+ }
+
+ public Map<String, ResultConfig> getResults() {
+ return results;
+ }
+
+ public boolean isAllowedMethod(String method) {
+ if (allowedMethods.size() == 1 && WILDCARD.equals(allowedMethods.iterator().next())) {
+ return true;
+ } else {
+ return method.equals(methodName != null ? methodName : DEFAULT_METHOD) || allowedMethods.contains(method);
+ }
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof ActionConfig)) {
+ return false;
+ }
+
+ final ActionConfig actionConfig = (ActionConfig) o;
+
+ if ((className != null) ? (!className.equals(actionConfig.className)) : (actionConfig.className != null)) {
+ return false;
+ }
+
+ if ((name != null) ? (!name.equals(actionConfig.name)) : (actionConfig.name != null)) {
+ return false;
+ }
+
+ if ((interceptors != null) ? (!interceptors.equals(actionConfig.interceptors)) : (actionConfig.interceptors != null))
+ {
+ return false;
+ }
+
+ if ((methodName != null) ? (!methodName.equals(actionConfig.methodName)) : (actionConfig.methodName != null)) {
+ return false;
+ }
+
+ if ((params != null) ? (!params.equals(actionConfig.params)) : (actionConfig.params != null)) {
+ return false;
+ }
+
+ if ((results != null) ? (!results.equals(actionConfig.results)) : (actionConfig.results != null)) {
+ return false;
+ }
+
+ if ((allowedMethods != null) ? (!allowedMethods.equals(actionConfig.allowedMethods)) : (actionConfig.allowedMethods != null)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override public int hashCode() {
+ int result;
+ result = (interceptors != null ? interceptors.hashCode() : 0);
+ result = 31 * result + (params != null ? params.hashCode() : 0);
+ result = 31 * result + (results != null ? results.hashCode() : 0);
+ result = 31 * result + (exceptionMappings != null ? exceptionMappings.hashCode() : 0);
+ result = 31 * result + (className != null ? className.hashCode() : 0);
+ result = 31 * result + (methodName != null ? methodName.hashCode() : 0);
+ result = 31 * result + (packageName != null ? packageName.hashCode() : 0);
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ result = 31 * result + (allowedMethods != null ? allowedMethods.hashCode() : 0);
+ return result;
+ }
+
+ @Override public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{ActionConfig ");
+ sb.append(name).append(" (");
+ sb.append(className);
+ if (methodName != null) {
+ sb.append(".").append(methodName).append("()");
+ }
+ sb.append(")");
+ sb.append(" - ").append(location);
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * The builder for this object. An instance of this object is the only way to construct a new instance. The
+ * purpose is to enforce the immutability of the object. The methods are structured in a way to support chaining.
+ * After setting any values you need, call the {@link #build()} method to create the object.
+ */
+ public static class Builder implements InterceptorListHolder{
+
+ protected ActionConfig target;
+ private boolean gotMethods;
+
+ public Builder(ActionConfig toClone) {
+ target = new ActionConfig(toClone);
+ addAllowedMethod(toClone.getAllowedMethods());
+ }
+
+ public Builder(String packageName, String name, String className) {
+ target = new ActionConfig(packageName, name, className);
+ }
+
+ public Builder packageName(String name) {
+ target.packageName = name;
+ return this;
+ }
+
+ public Builder name(String name) {
+ target.name = name;
+ return this;
+ }
+
+ public Builder className(String name) {
+ target.className = name;
+ return this;
+ }
+
+ public Builder defaultClassName(String name) {
+ if (StringUtils.isEmpty(target.className)) {
+ target.className = name;
+ }
+ return this;
+ }
+
+ public Builder methodName(String method) {
+ target.methodName = method;
+ return this;
+ }
+
+ public Builder addExceptionMapping(ExceptionMappingConfig exceptionMapping) {
+ target.exceptionMappings.add(exceptionMapping);
+ return this;
+ }
+
+ public Builder addExceptionMappings(Collection<? extends ExceptionMappingConfig> mappings) {
+ target.exceptionMappings.addAll(mappings);
+ return this;
+ }
+
+ public Builder exceptionMappings(Collection<? extends ExceptionMappingConfig> mappings) {
+ target.exceptionMappings.clear();
+ target.exceptionMappings.addAll(mappings);
+ return this;
+ }
+
+ public Builder addInterceptor(InterceptorMapping interceptor) {
+ target.interceptors.add(interceptor);
+ return this;
+ }
+
+ public Builder addInterceptors(List<InterceptorMapping> interceptors) {
+ target.interceptors.addAll(interceptors);
+ return this;
+ }
+
+ public Builder interceptors(List<InterceptorMapping> interceptors) {
+ target.interceptors.clear();
+ target.interceptors.addAll(interceptors);
+ return this;
+ }
+
+ public Builder addParam(String name, String value) {
+ target.params.put(name, value);
+ return this;
+ }
+
+ public Builder addParams(Map<String,String> params) {
+ target.params.putAll(params);
+ return this;
+ }
+
+ public Builder addResultConfig(ResultConfig resultConfig) {
+ target.results.put(resultConfig.getName(), resultConfig);
+ return this;
+ }
+
+ public Builder addResultConfigs(Collection<ResultConfig> configs) {
+ for (ResultConfig rc : configs) {
+ target.results.put(rc.getName(), rc);
+ }
+ return this;
+ }
+
+ public Builder addResultConfigs(Map<String,ResultConfig> configs) {
+ target.results.putAll(configs);
+ return this;
+ }
+
+ public Builder addAllowedMethod(String methodName) {
+ target.allowedMethods.add(methodName);
+ return this;
+ }
+
+ public Builder addAllowedMethod(Collection<String> methods) {
+ if (methods != null) {
+ gotMethods = true;
+ target.allowedMethods.addAll(methods);
+ }
+ return this;
+ }
+
+ public Builder location(Location loc) {
+ target.location = loc;
+ return this;
+ }
+
+ public ActionConfig build() {
+ embalmTarget();
+ ActionConfig result = target;
+ target = new ActionConfig(target);
+ return result;
+ }
+
+ protected void embalmTarget() {
+ if (!gotMethods && target.allowedMethods.isEmpty()) {
+ target.allowedMethods.add(WILDCARD);
+ }
+
+ target.params = Collections.unmodifiableMap(target.params);
+ target.results = Collections.unmodifiableMap(target.results);
+ target.interceptors = Collections.unmodifiableList(target.interceptors);
+ target.exceptionMappings = Collections.unmodifiableList(target.exceptionMappings);
+ target.allowedMethods = Collections.unmodifiableSet(target.allowedMethods);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/entities/ExceptionMappingConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/ExceptionMappingConfig.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/ExceptionMappingConfig.java
new file mode 100644
index 0000000..21a791e
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/ExceptionMappingConfig.java
@@ -0,0 +1,181 @@
+/*
+ * 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 com.opensymphony.xwork2.config.entities;
+
+import com.opensymphony.xwork2.util.location.Located;
+import com.opensymphony.xwork2.util.location.Location;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Configuration for exception mapping.
+ *
+ * @author Rainer Hermanns
+ * @author Matthew E. Porter (matthew dot porter at metissian dot com)
+ */
+public class ExceptionMappingConfig extends Located implements Serializable {
+
+ protected String name;
+ protected String exceptionClassName;
+ protected String result;
+ protected Map<String,String> params;
+
+ protected ExceptionMappingConfig(String name, String exceptionClassName, String result) {
+ this.name = name;
+ this.exceptionClassName = exceptionClassName;
+ this.result = result;
+ this.params = new LinkedHashMap<>();
+ }
+
+ protected ExceptionMappingConfig(ExceptionMappingConfig target) {
+ this.name = target.name;
+ this.exceptionClassName = target.exceptionClassName;
+ this.result = target.result;
+ this.params = new LinkedHashMap<>(target.params);
+ this.location = target.location;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getExceptionClassName() {
+ return exceptionClassName;
+ }
+
+ public String getResult() {
+ return result;
+ }
+
+ public Map<String,String> getParams() {
+ return params;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof ExceptionMappingConfig)) {
+ return false;
+ }
+
+ final ExceptionMappingConfig exceptionMappingConfig = (ExceptionMappingConfig) o;
+
+ if ((name != null) ? (!name.equals(exceptionMappingConfig.name)) : (exceptionMappingConfig.name != null)) {
+ return false;
+ }
+
+ if ((exceptionClassName != null) ? (!exceptionClassName.equals(exceptionMappingConfig.exceptionClassName)) : (exceptionMappingConfig.exceptionClassName != null))
+ {
+ return false;
+ }
+
+ if ((result != null) ? (!result.equals(exceptionMappingConfig.result)) : (exceptionMappingConfig.result != null))
+ {
+ return false;
+ }
+
+ if ((params != null) ? (!params.equals(exceptionMappingConfig.params)) : (exceptionMappingConfig.params != null))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode;
+ hashCode = ((name != null) ? name.hashCode() : 0);
+ hashCode = (29 * hashCode) + ((exceptionClassName != null) ? exceptionClassName.hashCode() : 0);
+ hashCode = (29 * hashCode) + ((result != null) ? result.hashCode() : 0);
+ hashCode = (29 * hashCode) + ((params != null) ? params.hashCode() : 0);
+
+ return hashCode;
+ }
+
+ @Override
+ public String toString() {
+ return "ExceptionMappingConfig: [" + name + "] handle ["
+ + exceptionClassName + "] to result [" + result + "] with params " + params;
+ }
+
+ /**
+ * The builder for this object. An instance of this object is the only way to construct a new instance. The
+ * purpose is to enforce the immutability of the object. The methods are structured in a way to support chaining.
+ * After setting any values you need, call the {@link #build()} method to create the object.
+ */
+ public static class Builder{
+
+ protected ExceptionMappingConfig target;
+
+ public Builder(ExceptionMappingConfig toClone) {
+ target = new ExceptionMappingConfig(toClone);
+ }
+
+ public Builder(String name, String exceptionClassName, String result) {
+ target = new ExceptionMappingConfig(name, exceptionClassName, result);
+ }
+
+ public Builder name(String name) {
+ target.name = name;
+ return this;
+ }
+
+ public Builder exceptionClassName(String name) {
+ target.exceptionClassName = name;
+ return this;
+ }
+
+ public Builder result(String result) {
+ target.result = result;
+ return this;
+ }
+
+ public Builder addParam(String name, String value) {
+ target.params.put(name, value);
+ return this;
+ }
+
+ public Builder addParams(Map<String,String> params) {
+ target.params.putAll(params);
+ return this;
+ }
+
+ public Builder location(Location loc) {
+ target.location = loc;
+ return this;
+ }
+
+ public ExceptionMappingConfig build() {
+ embalmTarget();
+ ExceptionMappingConfig result = target;
+ target = new ExceptionMappingConfig(target);
+ return result;
+ }
+
+ protected void embalmTarget() {
+ target.params = Collections.unmodifiableMap(target.params);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorConfig.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorConfig.java
new file mode 100644
index 0000000..b04bbd9
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorConfig.java
@@ -0,0 +1,158 @@
+/*
+ * 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 com.opensymphony.xwork2.config.entities;
+
+import com.opensymphony.xwork2.util.location.Located;
+import com.opensymphony.xwork2.util.location.Location;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Configuration for Interceptors.
+ * <p/>
+ * In the xml configuration file this is defined as the <code>interceptors</code> tag.
+ *
+ * @author Mike
+ */
+public class InterceptorConfig extends Located implements Serializable {
+
+ protected Map<String,String> params;
+ protected String className;
+ protected String name;
+
+ protected InterceptorConfig(String name, String className) {
+ this.params = new LinkedHashMap<>();
+ this.name = name;
+ this.className = className;
+ }
+
+ protected InterceptorConfig(InterceptorConfig orig) {
+ this.name = orig.name;
+ this.className = orig.className;
+ this.params = new LinkedHashMap<>(orig.params);
+ this.location = orig.location;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Map<String,String> getParams() {
+ return params;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof InterceptorConfig)) {
+ return false;
+ }
+
+ final InterceptorConfig interceptorConfig = (InterceptorConfig) o;
+
+ if ((className != null) ? (!className.equals(interceptorConfig.className)) : (interceptorConfig.className != null)) {
+ return false;
+ }
+
+ if ((name != null) ? (!name.equals(interceptorConfig.name)) : (interceptorConfig.name != null)) {
+ return false;
+ }
+
+ if ((params != null) ? (!params.equals(interceptorConfig.params)) : (interceptorConfig.params != null)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ result = ((name != null) ? name.hashCode() : 0);
+ result = (29 * result) + ((className != null) ? className.hashCode() : 0);
+ result = (29 * result) + ((params != null) ? params.hashCode() : 0);
+
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "InterceptorConfig: [" + name + "] => [" + className + "] with params " + params;
+ }
+
+ /**
+ * The builder for this object. An instance of this object is the only way to construct a new instance. The
+ * purpose is to enforce the immutability of the object. The methods are structured in a way to support chaining.
+ * After setting any values you need, call the {@link #build()} method to create the object.
+ */
+ public static final class Builder {
+ protected InterceptorConfig target;
+
+ public Builder(String name, String className) {
+ target = new InterceptorConfig(name, className);
+ }
+
+ public Builder(InterceptorConfig orig) {
+ target = new InterceptorConfig(orig);
+ }
+
+ public Builder name(String name) {
+ target.name = name;
+ return this;
+ }
+
+ public Builder className(String name) {
+ target.className = name;
+ return this;
+ }
+
+ public Builder addParam(String name, String value) {
+ target.params.put(name, value);
+ return this;
+ }
+
+ public Builder addParams(Map<String,String> params) {
+ target.params.putAll(params);
+ return this;
+ }
+
+ public Builder location(Location loc) {
+ target.location = loc;
+ return this;
+ }
+
+ public InterceptorConfig build() {
+ embalmTarget();
+ InterceptorConfig result = target;
+ target = new InterceptorConfig(target);
+ return result;
+ }
+
+ protected void embalmTarget() {
+ target.params = Collections.unmodifiableMap(target.params);
+ }
+ }
+}