1. opensymphony
  2. xwork

Commits

dres  committed ae85d84

Issue: XW-328
Submitted by: Andres March

Added default action element and support to enable specification of an action that is called when no other action is found

git-svn-id: http://svn.opensymphony.com/svn/xwork/trunk@773e221344d-f017-0410-9bd5-d282ab1896d7

  • Participants
  • Parent commits 0189277
  • Branches master

Comments (0)

Files changed (4)

File src/java/com/opensymphony/xwork/config/entities/PackageConfig.java

View file
     private List globalExceptionMappingConfigs = new ArrayList();
     private Set parents = new HashSet();
     private String defaultInterceptorRef;
+	private String defaultActionRef;
     private String defaultResultType;
     private String name;
     private String namespace = "";
     private boolean isAbstract = false;
 
 
+
+
     public PackageConfig() {
     }
 
     public String getDefaultInterceptorRef() {
         return defaultInterceptorRef;
     }
+    
+	public void setDefaultActionRef(String name) {
+		defaultActionRef = name;
+	}
+	
+	public String getDefaultActionRef() {
+        return defaultActionRef;
+    }
 
     /**
      * sets the default Result type for this package
 
         return defaultInterceptorRef;
     }
+    
+    /**
+     * gets the default action-ref name. If this is not set on this PackageConfig, it searches the parent
+     * PackageConfigs in order until it finds one.
+     */
+    public String getFullDefaultActionRef() {
+        if ((defaultActionRef == null) && !parents.isEmpty()) {
+            for (Iterator iterator = parents.iterator(); iterator.hasNext();) {
+                PackageConfig parent = (PackageConfig) iterator.next();
+                String parentDefault = parent.getFullDefaultActionRef();
+
+                if (parentDefault != null) {
+                    return parentDefault;
+                }
+            }
+        }
+        return defaultActionRef;
+    }
 
     /**
      * Returns the default result type for this package.
         // note, this isn't perfect (could come from different parents), but it is "good enough"
         return full.compareTo(otherFull);
     }
+
 }

File src/java/com/opensymphony/xwork/config/impl/DefaultConfiguration.java

View file
      */
     protected synchronized RuntimeConfiguration buildRuntimeConfiguration() throws ConfigurationException {
         Map namespaceActionConfigs = new TreeMap();
+        Map namespaceConfigs = new TreeMap();
 
         for (Iterator iterator = packageContexts.values().iterator();
              iterator.hasNext();) {
             PackageConfig packageContext = (PackageConfig) iterator.next();
 
             if (!packageContext.isAbstract()) {
-                String namespace = packageContext.getNamespace();
+                String namespace = packageContext.getNamespace();                
                 Map configs = (Map) namespaceActionConfigs.get(namespace);
 
                 if (configs == null) {
                 }
 
                 namespaceActionConfigs.put(namespace, configs);
+                namespaceConfigs.put(namespace, packageContext.getFullDefaultActionRef());
             }
         }
 
-        return new RuntimeConfigurationImpl(namespaceActionConfigs);
+        return new RuntimeConfigurationImpl(namespaceActionConfigs, namespaceConfigs);
     }
 
     private void setDefaultResults(Map results, PackageConfig packageContext) {
 
     private class RuntimeConfigurationImpl implements RuntimeConfiguration {
         private Map namespaceActionConfigs;
+        private Map namespaceConfigs;
 
-        public RuntimeConfigurationImpl(Map namespaceActionConfigs) {
+        public RuntimeConfigurationImpl(Map namespaceActionConfigs, Map namespaceConfigs) {
             this.namespaceActionConfigs = namespaceActionConfigs;
+            this.namespaceConfigs = namespaceConfigs;
         }
+        
+        
 
         /**
          * Gets the configuration information for an action name, or returns null if the
 
             if (actions != null) {
                 config = (ActionConfig) actions.get(name);
+                // fail over to default action
+                if (config == null) {
+                	String defaultActionRef = (String) namespaceConfigs.get((namespace == null) ? "" : namespace);
+                	config = (ActionConfig) actions.get(defaultActionRef);
+                }
             }
 
             // fail over to empty namespace
 
                 if (actions != null) {
                     config = (ActionConfig) actions.get(name);
+                    // fail over to default action
+                    if (config == null) {
+                    	String defaultActionRef = (String) namespaceConfigs.get((namespace == null) ? "" : namespace);
+                    	config = (ActionConfig) actions.get(defaultActionRef);
+                    }
                 }
             }
+            
 
             return config;
         }

File src/java/com/opensymphony/xwork/config/providers/XmlConfigurationProvider.java

View file
             db.setEntityResolver(new EntityResolver() {
                 public InputSource resolveEntity(String publicId, String systemId) {
                     if ("-//OpenSymphony Group//XWork 1.0//EN".equals(publicId)) {
-                        return new InputSource(ClassLoaderUtil.getResourceAsStream("xwork-1.1.dtd", XmlConfigurationProvider.class));
+                        return new InputSource(ClassLoaderUtil.getResourceAsStream("xwork-1.1.1.dtd", XmlConfigurationProvider.class));
                     }
 
                     return null;
             Element actionElement = (Element) actionList.item(i);
             addAction(actionElement, newPackage);
         }
+        
+        // load the default action reference for this package
+        loadDefaultActionRef(newPackage, packageElement);
 
         configuration.addPackageConfig(newPackage.getName(), newPackage);
     }
             packageContext.setDefaultInterceptorRef(defaultRefElement.getAttribute("name"));
         }
     }
+    
+    protected void loadDefaultActionRef(PackageConfig packageContext, Element element) {
+        NodeList resultTypeList = element.getElementsByTagName("default-action-ref");
+
+        if (resultTypeList.getLength() > 0) {
+            Element defaultRefElement = (Element) resultTypeList.item(0);
+            packageContext.setDefaultActionRef(defaultRefElement.getAttribute("name"));
+        }
+    }
 
     /**
      * Load all of the global results for this package from the XML element.

File src/java/xwork-1.1.1.dtd

View file
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+   XWork configuration DTD.
+   Use the following DOCTYPE
+   
+   <!DOCTYPE xwork PUBLIC 
+	"-//OpenSymphony Group//XWork 1.0//EN" 
+	"http://www.opensymphony.com/xwork/xwork-1.1.dtd">
+-->
+
+<!ELEMENT xwork (package|include)*>
+
+<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, global-results?, global-exception-mappings?, action*)>
+<!ATTLIST package
+    name CDATA #REQUIRED
+    extends CDATA #IMPLIED
+    namespace CDATA #IMPLIED
+    abstract 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 (param*)>
+<!ATTLIST default-interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-action-ref (param*)>
+<!ATTLIST default-action-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT external-ref (#PCDATA)>
+<!ATTLIST external-ref
+    name NMTOKEN #REQUIRED
+    required (true|false) "true"
+>
+
+<!ELEMENT global-results (result+)>
+
+<!ELEMENT global-exception-mappings (exception-mapping+)>
+
+<!ELEMENT action (param|result|interceptor-ref|exception-mapping|external-ref)*>
+<!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 include (#PCDATA)>
+<!ATTLIST include
+    file CDATA #REQUIRED
+>
+
+