You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by ja...@apache.org on 2011/06/09 17:43:05 UTC

svn commit: r1133947 - in /struts/struts2/trunk: ./ core/src/main/java/org/apache/struts2/config/ core/src/main/resources/ xwork-core/src/main/java/com/opensymphony/xwork2/ xwork-core/src/main/java/com/opensymphony/xwork2/config/entities/ xwork-core/sr...

Author: jafl
Date: Thu Jun  9 15:43:04 2011
New Revision: 1133947

URL: http://svn.apache.org/viewvc?rev=1133947&view=rev
Log:
WW-3264 add allowed-methods configuration for action

Added:
    struts/struts2/trunk/core/src/main/resources/struts-2.3.dtd   (with props)
    struts/struts2/trunk/xwork-core/src/main/resources/xwork-2.3.dtd
    struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderAllowedMethodsTest.java
    struts/struts2/trunk/xwork-core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml
Modified:
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/StrutsXmlConfigurationProvider.java
    struts/struts2/trunk/core/src/main/resources/struts-default.xml
    struts/struts2/trunk/pom.xml
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/entities/PackageConfig.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/StrutsXmlConfigurationProvider.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/StrutsXmlConfigurationProvider.java?rev=1133947&r1=1133946&r2=1133947&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/StrutsXmlConfigurationProvider.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/StrutsXmlConfigurationProvider.java Thu Jun  9 15:43:04 2011
@@ -79,6 +79,7 @@ public class StrutsXmlConfigurationProvi
         dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.0//EN", "struts-2.0.dtd");
         dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.1//EN", "struts-2.1.dtd");
         dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN", "struts-2.1.7.dtd");
+        dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.3//EN", "struts-2.3.dtd");
         setDtdMappings(dtdMappings);
         File file = new File(filename);
         if (file.getParent() != null) {

Added: struts/struts2/trunk/core/src/main/resources/struts-2.3.dtd
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/struts-2.3.dtd?rev=1133947&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/struts-2.3.dtd (added)
+++ struts/struts2/trunk/core/src/main/resources/struts-2.3.dtd Thu Jun  9 15:43:04 2011
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * $Id: struts-2.0.dtd 651946 2008-04-27 13:41:38Z apetrelli $
+ *
+ * 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.
+ */
+-->
+<!-- START SNIPPET: strutsDtd -->
+
+<!--
+   Struts configuration DTD.
+   Use the following DOCTYPE
+
+   <!DOCTYPE struts PUBLIC
+	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
+	"http://struts.apache.org/dtds/struts-2.3.dtd">
+-->
+
+<!ELEMENT struts ((package|include|bean|constant)*, unknown-handler-stack?)>
+<!ATTLIST struts
+    order CDATA #IMPLIED
+>
+
+<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-exception-mappings?, action*)>
+<!ATTLIST package
+    name CDATA #REQUIRED
+    extends CDATA #IMPLIED
+    namespace CDATA #IMPLIED
+    abstract CDATA #IMPLIED
+    strict-method-invocation CDATA #IMPLIED
+    externalReferenceResolver NMTOKEN #IMPLIED
+>
+
+<!ELEMENT result-types (result-type+)>
+
+<!ELEMENT result-type (param*)>
+<!ATTLIST result-type
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    default (true|false) "false"
+>
+
+<!ELEMENT interceptors (interceptor|interceptor-stack)+>
+
+<!ELEMENT interceptor (param*)>
+<!ATTLIST interceptor
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-stack (interceptor-ref*)>
+<!ATTLIST interceptor-stack
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-ref (param*)>
+<!ATTLIST interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-interceptor-ref (#PCDATA)>
+<!ATTLIST default-interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-action-ref (#PCDATA)>
+<!ATTLIST default-action-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-class-ref (#PCDATA)>
+<!ATTLIST default-class-ref
+    class CDATA #REQUIRED
+>
+
+<!ELEMENT global-results (result+)>
+
+<!ELEMENT global-exception-mappings (exception-mapping+)>
+
+<!ELEMENT action ((param|result|interceptor-ref|exception-mapping)*,allowed-methods?)>
+<!ATTLIST action
+    name CDATA #REQUIRED
+    class CDATA #IMPLIED
+    method CDATA #IMPLIED
+    converter CDATA #IMPLIED
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT result (#PCDATA|param)*>
+<!ATTLIST result
+    name CDATA #IMPLIED
+    type CDATA #IMPLIED
+>
+
+<!ELEMENT exception-mapping (#PCDATA|param)*>
+<!ATTLIST exception-mapping
+    name CDATA #IMPLIED
+    exception CDATA #REQUIRED
+    result CDATA #REQUIRED
+>
+
+<!ELEMENT allowed-methods (#PCDATA)>
+
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include
+    file CDATA #REQUIRED
+>
+
+<!ELEMENT bean (#PCDATA)>
+<!ATTLIST bean
+    type CDATA #IMPLIED
+    name CDATA #IMPLIED
+    class CDATA #REQUIRED
+    scope CDATA #IMPLIED
+    static CDATA #IMPLIED
+    optional CDATA #IMPLIED
+>
+
+<!ELEMENT constant (#PCDATA)>
+<!ATTLIST constant
+    name CDATA #REQUIRED
+    value CDATA #REQUIRED
+>
+
+<!ELEMENT unknown-handler-stack (unknown-handler-ref*)>
+<!ELEMENT unknown-handler-ref (#PCDATA)>
+<!ATTLIST unknown-handler-ref
+    name CDATA #REQUIRED
+>
+
+<!-- END SNIPPET: strutsDtd -->
+

Propchange: struts/struts2/trunk/core/src/main/resources/struts-2.3.dtd
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: struts/struts2/trunk/core/src/main/resources/struts-default.xml
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/struts-default.xml?rev=1133947&r1=1133946&r2=1133947&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/struts-default.xml (original)
+++ struts/struts2/trunk/core/src/main/resources/struts-default.xml Thu Jun  9 15:43:04 2011
@@ -22,8 +22,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
-    "http://struts.apache.org/dtds/struts-2.1.7.dtd">
+    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
+    "http://struts.apache.org/dtds/struts-2.3.dtd">
 
 <struts>
     <bean class="com.opensymphony.xwork2.ObjectFactory" name="xwork" />

Modified: struts/struts2/trunk/pom.xml
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/pom.xml?rev=1133947&r1=1133946&r2=1133947&view=diff
==============================================================================
--- struts/struts2/trunk/pom.xml (original)
+++ struts/struts2/trunk/pom.xml Thu Jun  9 15:43:04 2011
@@ -164,10 +164,12 @@
                         -->
                     </configuration>
                 </plugin>
+<!--
                 <plugin>
                     <artifactId>maven-site-plugin</artifactId>
                     <version>3.0-beta-3</version>
                 </plugin>
+-->
                 <plugin>
                     <artifactId>maven-compiler-plugin</artifactId>
                     <configuration>

Modified: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java?rev=1133947&r1=1133946&r2=1133947&view=diff
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java (original)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java Thu Jun  9 15:43:04 2011
@@ -167,7 +167,7 @@ public class DefaultActionProxy implemen
         if (StringUtils.isEmpty(this.method)) {
             this.method = config.getMethodName();
             if (StringUtils.isEmpty(this.method)) {
-                this.method = "execute";
+                this.method = ActionConfig.DEFAULT_METHOD;
             }
             methodSpecified=false;
         }

Modified: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java?rev=1133947&r1=1133946&r2=1133947&view=diff
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java (original)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java Thu Jun  9 15:43:04 2011
@@ -1,12 +1,12 @@
 /*
  * 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.
@@ -42,6 +42,7 @@ import org.apache.commons.lang.StringUti
  */
 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>
@@ -63,7 +64,6 @@ public class ActionConfig extends Locate
         interceptors = new ArrayList<InterceptorMapping>();
         exceptionMappings = new ArrayList<ExceptionMappingConfig>();
         allowedMethods = new HashSet<String>();
-        allowedMethods.add(WILDCARD);
     }
 
     /**
@@ -131,7 +131,7 @@ public class ActionConfig extends Locate
         if (allowedMethods.size() == 1 && WILDCARD.equals(allowedMethods.iterator().next())) {
             return true;
         } else {
-            return allowedMethods.contains(method);
+            return method.equals(methodName != null ? methodName : DEFAULT_METHOD) || allowedMethods.contains(method);
         }
     }
 
@@ -178,7 +178,6 @@ public class ActionConfig extends Locate
         return true;
     }
 
-
     @Override public int hashCode() {
         int result;
         result = (interceptors != null ? interceptors.hashCode() : 0);
@@ -215,6 +214,7 @@ public class ActionConfig extends Locate
     public static class Builder implements InterceptorListHolder{
 
         protected ActionConfig target;
+        private boolean gotMethods;
 
         public Builder(ActionConfig toClone) {
             target = new ActionConfig(toClone);
@@ -316,7 +316,10 @@ public class ActionConfig extends Locate
         }
 
         public Builder addAllowedMethod(Collection<String> methods) {
-            target.allowedMethods.addAll(methods);
+            if (methods != null) {
+                gotMethods = true;
+                target.allowedMethods.addAll(methods);
+            }
             return this;
         }
 
@@ -333,6 +336,10 @@ public class ActionConfig extends Locate
         }
 
         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);

Modified: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/entities/PackageConfig.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/entities/PackageConfig.java?rev=1133947&r1=1133946&r2=1133947&view=diff
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/entities/PackageConfig.java (original)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/entities/PackageConfig.java Thu Jun  9 15:43:04 2011
@@ -1,12 +1,12 @@
 /*
  * 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.
@@ -202,17 +202,17 @@ public class PackageConfig extends Locat
     }
 
     public String getDefaultClassRef() {
-    	if((defaultClassRef == null) && !parents.isEmpty()) {
+        if((defaultClassRef == null) && !parents.isEmpty()) {
             for (PackageConfig parent : parents) {
                 String parentDefault = parent.getDefaultClassRef();
                 if (parentDefault != null) {
                     return parentDefault;
                 }
             }
-    	}
-    	return defaultClassRef;
+        }
+        return defaultClassRef;
     }
-    
+
     /**
      * Returns the default result type for this package.
      */
@@ -443,6 +443,7 @@ public class PackageConfig extends Locat
     public static class Builder implements InterceptorLocator {
 
         protected PackageConfig target;
+        private boolean strictDMI;
 
         public Builder(String name) {
             target = new PackageConfig(name);
@@ -590,6 +591,15 @@ public class PackageConfig extends Locat
             return target.getAllInterceptorConfigs().get(name);
         }
 
+        public Builder strictMethodInvocation(boolean strict) {
+            strictDMI = strict;
+            return this;
+        }
+
+        public boolean isStrictMethodInvocation() {
+            return strictDMI;
+        }
+
         public PackageConfig build() {
             embalmTarget();
             PackageConfig result = target;

Modified: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java?rev=1133947&r1=1133946&r2=1133947&view=diff
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java (original)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java Thu Jun  9 15:43:04 2011
@@ -1,12 +1,12 @@
 /*
  * 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.
@@ -86,6 +86,7 @@ public class XmlConfigurationProvider im
         this.errorIfMissing = errorIfMissing;
 
         Map<String, String> mappings = new HashMap<String, String>();
+        mappings.put("-//Apache Struts//XWork 2.3//EN", "xwork-2.3.dtd");
         mappings.put("-//Apache Struts//XWork 2.1.3//EN", "xwork-2.1.3.dtd");
         mappings.put("-//Apache Struts//XWork 2.1//EN", "xwork-2.1.dtd");
         mappings.put("-//Apache Struts//XWork 2.0//EN", "xwork-2.0.dtd");
@@ -349,7 +350,7 @@ public class XmlConfigurationProvider im
 
         if (location == null) {
             if (LOG.isWarnEnabled()) {
-        	LOG.warn("location null for " + className);
+            LOG.warn("location null for " + className);
             }
         }
         //methodName should be null if it's not set
@@ -373,8 +374,6 @@ public class XmlConfigurationProvider im
             }
         }
 
-
-
         Map<String, ResultConfig> results;
         try {
             results = buildResults(actionElement, packageContext);
@@ -386,12 +385,15 @@ public class XmlConfigurationProvider im
 
         List<ExceptionMappingConfig> exceptionMappings = buildExceptionMappings(actionElement, packageContext);
 
+        Set<String> allowedMethods = buildAllowedMethods(actionElement, packageContext);
+
         ActionConfig actionConfig = new ActionConfig.Builder(packageContext.getName(), name, className)
                 .methodName(methodName)
                 .addResultConfigs(results)
                 .addInterceptors(interceptorList)
                 .addExceptionMappings(exceptionMappings)
                 .addParams(XmlHelper.getParams(actionElement))
+                .addAllowedMethod(allowedMethods)
                 .location(location)
                 .build();
         packageContext.addActionConfig(name, actionConfig);
@@ -430,7 +432,7 @@ public class XmlConfigurationProvider im
         } catch (RuntimeException ex) {
             // Probably not a big deal, like request or session-scoped Spring 2 beans that need a real request
             if (LOG.isInfoEnabled()) {
-        	LOG.info("Unable to verify action class [" + className + "] exists at initialization");
+            LOG.info("Unable to verify action class [" + className + "] exists at initialization");
             }
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Action verification cause", ex);
@@ -536,12 +538,12 @@ public class XmlConfigurationProvider im
             return objectFactory.getClassInstance(className);
         } catch (ClassNotFoundException e) {
             if (LOG.isWarnEnabled()) {
-        	LOG.warn("Result class [" + className + "] doesn't exist (ClassNotFoundException) at " +
+            LOG.warn("Result class [" + className + "] doesn't exist (ClassNotFoundException) at " +
                     loc.toString() + ", ignoring", e);
             }
         } catch (NoClassDefFoundError e) {
             if (LOG.isWarnEnabled()) {
-        	LOG.warn("Result class [" + className + "] doesn't exist (NoClassDefFoundError) at " +
+            LOG.warn("Result class [" + className + "] doesn't exist (NoClassDefFoundError) at " +
                     loc.toString() + ", ignoring", e);
             }
         }
@@ -573,10 +575,11 @@ public class XmlConfigurationProvider im
     protected PackageConfig.Builder buildPackageContext(Element packageElement) {
         String parent = packageElement.getAttribute("extends");
         String abstractVal = packageElement.getAttribute("abstract");
-        boolean isAbstract = Boolean.valueOf(abstractVal).booleanValue();
+        boolean isAbstract = Boolean.parseBoolean(abstractVal);
         String name = StringUtils.defaultString(packageElement.getAttribute("name"));
         String namespace = StringUtils.defaultString(packageElement.getAttribute("namespace"));
-
+        String strictDMIVal = StringUtils.defaultString(packageElement.getAttribute("strict-method-invocation"));
+        boolean strictDMI = Boolean.parseBoolean(strictDMIVal);
 
         if (StringUtils.isNotEmpty(packageElement.getAttribute("externalReferenceResolver"))) {
             throw new ConfigurationException("The 'externalReferenceResolver' attribute has been removed.  Please use " +
@@ -586,9 +589,9 @@ public class XmlConfigurationProvider im
         PackageConfig.Builder cfg = new PackageConfig.Builder(name)
                 .namespace(namespace)
                 .isAbstract(isAbstract)
+                .strictMethodInvocation(strictDMI)
                 .location(DomHelper.getLocationObject(packageElement));
 
-
         if (StringUtils.isNotEmpty(StringUtils.defaultString(parent))) { // has parents, let's look it up
 
             List<PackageConfig> parents = ConfigurationUtil.buildParentsFromString(configuration, parent);
@@ -676,7 +679,7 @@ public class XmlConfigurationProvider im
                             }
                         } else {
                             if (LOG.isWarnEnabled()) {
-                        	LOG.warn("no default parameter defined for result of type " + config.getName());
+                            LOG.warn("no default parameter defined for result of type " + config.getName());
                             }
                         }
                     }
@@ -754,6 +757,26 @@ public class XmlConfigurationProvider im
         return exceptionMappings;
     }
 
+    protected Set<String> buildAllowedMethods(Element element, PackageConfig.Builder packageContext) {
+        NodeList allowedMethodsEls = element.getElementsByTagName("allowed-methods");
+
+        Set<String> allowedMethods = null;
+
+        if (allowedMethodsEls.getLength() > 0) {
+            allowedMethods = new HashSet<String>();
+            Node n = allowedMethodsEls.item(0).getFirstChild();
+            if (n != null) {
+                String s = n.getNodeValue().trim();
+                if (s.length() > 0) {
+                    allowedMethods = TextParseUtil.commaDelimitedStringToSet(s);
+                }
+            }
+        } else if (packageContext.isStrictMethodInvocation()) {
+            allowedMethods = new HashSet<String>();
+        }
+
+        return allowedMethods;
+    }
 
     protected void loadDefaultInterceptorRef(PackageConfig.Builder packageContext, Element element) {
         NodeList resultTypeList = element.getElementsByTagName("default-interceptor-ref");
@@ -898,7 +921,7 @@ public class XmlConfigurationProvider im
                     throw new ConfigurationException("Could not open files of the name " + fileName, ioException);
                 } else {
                     if (LOG.isInfoEnabled()) {
-                	LOG.info("Unable to locate configuration files of the name "
+                    LOG.info("Unable to locate configuration files of the name "
                             + fileName + ", skipping");
                     }
                     return docs;

Added: struts/struts2/trunk/xwork-core/src/main/resources/xwork-2.3.dtd
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/resources/xwork-2.3.dtd?rev=1133947&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/resources/xwork-2.3.dtd (added)
+++ struts/struts2/trunk/xwork-core/src/main/resources/xwork-2.3.dtd Thu Jun  9 15:43:04 2011
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- START SNIPPET: xworkDtd -->
+
+<!--
+   XWork configuration DTD.
+   Use the following DOCTYPE
+
+   <!DOCTYPE xwork PUBLIC
+	"-//Apache Struts//XWork 2.3//EN"
+	"http://struts.apache.org/dtds/xwork-2.3.dtd">
+-->
+
+<!ELEMENT xwork ((package|include|bean|constant)*, unknown-handler-stack?)>
+<!ATTLIST xwork
+    order CDATA #IMPLIED
+>
+
+<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-exception-mappings?, action*)>
+<!ATTLIST package
+    name CDATA #REQUIRED
+    extends CDATA #IMPLIED
+    namespace CDATA #IMPLIED
+    abstract CDATA #IMPLIED
+    strict-method-invocation CDATA #IMPLIED
+>
+
+<!ELEMENT result-types (result-type+)>
+
+<!ELEMENT result-type (param*)>
+<!ATTLIST result-type
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    default (true|false) "false"
+>
+
+<!ELEMENT interceptors (interceptor|interceptor-stack)+>
+
+<!ELEMENT interceptor (param*)>
+<!ATTLIST interceptor
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-stack (interceptor-ref*)>
+<!ATTLIST interceptor-stack
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-ref (param*)>
+<!ATTLIST interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-interceptor-ref (#PCDATA)>
+<!ATTLIST default-interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-action-ref (#PCDATA)>
+<!ATTLIST default-action-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-class-ref (#PCDATA)>
+<!ATTLIST default-class-ref
+   class CDATA #REQUIRED
+>
+
+<!ELEMENT global-results (result+)>
+
+<!ELEMENT global-exception-mappings (exception-mapping+)>
+
+<!ELEMENT action ((param|result|interceptor-ref|exception-mapping)*,allowed-methods?)>
+<!ATTLIST action
+    name CDATA #REQUIRED
+    class CDATA #IMPLIED
+    method CDATA #IMPLIED
+    converter CDATA #IMPLIED
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT result (#PCDATA|param)*>
+<!ATTLIST result
+    name CDATA #IMPLIED
+    type CDATA #IMPLIED
+>
+
+<!ELEMENT exception-mapping (#PCDATA|param)*>
+<!ATTLIST exception-mapping
+    name CDATA #IMPLIED
+    exception CDATA #REQUIRED
+    result CDATA #REQUIRED
+>
+
+<!ELEMENT allowed-methods (#PCDATA)>
+
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include
+    file CDATA #REQUIRED
+>
+
+<!ELEMENT bean (#PCDATA)>
+<!ATTLIST bean
+    type CDATA #IMPLIED
+    name CDATA #IMPLIED
+    class CDATA #REQUIRED
+    scope CDATA #IMPLIED
+    static CDATA #IMPLIED
+    optional CDATA #IMPLIED
+>
+
+<!ELEMENT constant (#PCDATA)>
+<!ATTLIST constant
+    name CDATA #REQUIRED
+    value CDATA #REQUIRED
+>
+
+<!ELEMENT unknown-handler-stack (unknown-handler-ref*)>
+<!ELEMENT unknown-handler-ref (#PCDATA)>
+<!ATTLIST unknown-handler-ref
+    name CDATA #REQUIRED
+>
+
+<!-- END SNIPPET: xworkDtd -->
+

Added: struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderAllowedMethodsTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderAllowedMethodsTest.java?rev=1133947&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderAllowedMethodsTest.java (added)
+++ struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderAllowedMethodsTest.java Thu Jun  9 15:43:04 2011
@@ -0,0 +1,133 @@
+package com.opensymphony.xwork2.config.providers;
+
+import com.opensymphony.xwork2.ActionChainResult;
+import com.opensymphony.xwork2.SimpleAction;
+import com.opensymphony.xwork2.config.ConfigurationException;
+import com.opensymphony.xwork2.config.ConfigurationProvider;
+import com.opensymphony.xwork2.config.entities.ActionConfig;
+import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig;
+import com.opensymphony.xwork2.config.entities.PackageConfig;
+import com.opensymphony.xwork2.config.entities.ResultConfig;
+import com.opensymphony.xwork2.mock.MockResult;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author John Lindal
+ */
+public class XmlConfigurationProviderAllowedMethodsTest extends ConfigurationTestBase {
+
+    public void testDefaultAllowedMethods() throws ConfigurationException {
+        final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml";
+        ConfigurationProvider provider = buildConfigurationProvider(filename);
+
+        // execute the configuration
+        provider.init(configuration);
+        provider.loadPackages();
+
+        PackageConfig pkg = configuration.getPackageConfig("default");
+        Map actionConfigs = pkg.getActionConfigs();
+
+        // assertions
+        assertEquals(5, actionConfigs.size());
+
+        ActionConfig action = (ActionConfig) actionConfigs.get("Default");
+        assertEquals(1, action.getAllowedMethods().size());
+        assertTrue(action.isAllowedMethod("execute"));
+        assertTrue(action.isAllowedMethod("foo"));
+        assertTrue(action.isAllowedMethod("bar"));
+        assertTrue(action.isAllowedMethod("baz"));
+        assertTrue(action.isAllowedMethod("xyz"));
+
+        action = (ActionConfig) actionConfigs.get("Boring");
+        assertEquals(0, action.getAllowedMethods().size());
+        assertTrue(action.isAllowedMethod("execute"));
+        assertFalse(action.isAllowedMethod("foo"));
+        assertFalse(action.isAllowedMethod("bar"));
+        assertFalse(action.isAllowedMethod("baz"));
+        assertFalse(action.isAllowedMethod("xyz"));
+
+        action = (ActionConfig) actionConfigs.get("Foo");
+        assertEquals(1, action.getAllowedMethods().size());
+        assertTrue(action.isAllowedMethod("execute"));
+        assertTrue(action.isAllowedMethod("foo"));
+        assertFalse(action.isAllowedMethod("bar"));
+        assertFalse(action.isAllowedMethod("baz"));
+        assertFalse(action.isAllowedMethod("xyz"));
+
+        action = (ActionConfig) actionConfigs.get("Bar");
+        assertEquals(2, action.getAllowedMethods().size());
+        assertTrue(action.isAllowedMethod("execute"));
+        assertTrue(action.isAllowedMethod("foo"));
+        assertTrue(action.isAllowedMethod("bar"));
+        assertFalse(action.isAllowedMethod("baz"));
+        assertFalse(action.isAllowedMethod("xyz"));
+
+        action = (ActionConfig) actionConfigs.get("Baz");
+        assertEquals(2, action.getAllowedMethods().size());
+        assertFalse(action.isAllowedMethod("execute"));
+        assertTrue(action.isAllowedMethod("foo"));
+        assertTrue(action.isAllowedMethod("bar"));
+        assertTrue(action.isAllowedMethod("baz"));
+        assertFalse(action.isAllowedMethod("xyz"));
+    }
+
+    public void testStrictAllowedMethods() throws ConfigurationException {
+        final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml";
+        ConfigurationProvider provider = buildConfigurationProvider(filename);
+
+        // execute the configuration
+        provider.init(configuration);
+        provider.loadPackages();
+
+        PackageConfig pkg = configuration.getPackageConfig("strict");
+        Map actionConfigs = pkg.getActionConfigs();
+
+        // assertions
+        assertEquals(5, actionConfigs.size());
+
+        ActionConfig action = (ActionConfig) actionConfigs.get("Default");
+        assertEquals(0, action.getAllowedMethods().size());
+        assertTrue(action.isAllowedMethod("execute"));
+        assertFalse(action.isAllowedMethod("foo"));
+        assertFalse(action.isAllowedMethod("bar"));
+        assertFalse(action.isAllowedMethod("baz"));
+        assertFalse(action.isAllowedMethod("xyz"));
+
+        action = (ActionConfig) actionConfigs.get("Boring");
+        assertEquals(0, action.getAllowedMethods().size());
+        assertTrue(action.isAllowedMethod("execute"));
+        assertFalse(action.isAllowedMethod("foo"));
+        assertFalse(action.isAllowedMethod("bar"));
+        assertFalse(action.isAllowedMethod("baz"));
+        assertFalse(action.isAllowedMethod("xyz"));
+
+        action = (ActionConfig) actionConfigs.get("Foo");
+        assertEquals(1, action.getAllowedMethods().size());
+        assertTrue(action.isAllowedMethod("execute"));
+        assertTrue(action.isAllowedMethod("foo"));
+        assertFalse(action.isAllowedMethod("bar"));
+        assertFalse(action.isAllowedMethod("baz"));
+        assertFalse(action.isAllowedMethod("xyz"));
+
+        action = (ActionConfig) actionConfigs.get("Bar");
+        assertEquals(2, action.getAllowedMethods().size());
+        assertTrue(action.isAllowedMethod("execute"));
+        assertTrue(action.isAllowedMethod("foo"));
+        assertTrue(action.isAllowedMethod("bar"));
+        assertFalse(action.isAllowedMethod("baz"));
+        assertFalse(action.isAllowedMethod("xyz"));
+
+        action = (ActionConfig) actionConfigs.get("Baz");
+        assertEquals(2, action.getAllowedMethods().size());
+        assertFalse(action.isAllowedMethod("execute"));
+        assertTrue(action.isAllowedMethod("foo"));
+        assertTrue(action.isAllowedMethod("bar"));
+        assertTrue(action.isAllowedMethod("baz"));
+        assertFalse(action.isAllowedMethod("xyz"));
+    }
+
+}

Added: struts/struts2/trunk/xwork-core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml?rev=1133947&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml (added)
+++ struts/struts2/trunk/xwork-core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml Thu Jun  9 15:43:04 2011
@@ -0,0 +1,48 @@
+<!DOCTYPE xwork PUBLIC
+    "-//Apache Struts//XWork 2.3//EN"
+    "http://struts.apache.org/dtds/xwork-2.3.dtd"
+ >
+
+<xwork>
+    <package name="default">
+        <action name="Default">
+        </action>
+
+        <action name="Boring">
+            <allowed-methods> </allowed-methods>
+        </action>
+
+        <action name="Foo">
+            <allowed-methods>foo</allowed-methods>
+        </action>
+
+        <action name="Bar">
+            <allowed-methods>foo,bar</allowed-methods>
+        </action>
+
+        <action name="Baz" method="baz">
+            <allowed-methods>foo,bar</allowed-methods>
+        </action>
+    </package>
+
+    <package name="strict" strict-method-invocation="true">
+        <action name="Default">
+        </action>
+
+        <action name="Boring">
+            <allowed-methods></allowed-methods>
+        </action>
+
+        <action name="Foo">
+            <allowed-methods>foo</allowed-methods>
+        </action>
+
+        <action name="Bar">
+            <allowed-methods>foo,bar</allowed-methods>
+        </action>
+
+        <action name="Baz" method="baz">
+            <allowed-methods>foo,bar</allowed-methods>
+        </action>
+    </package>
+</xwork>