Author: tmjee
Date: Sun Nov  5 06:22:54 2006
New Revision: 471435

URL: http://svn.apache.org/viewvc?view=rev&rev=471435
Log:
WW-1490
 - Have a composite ActionMapper that decides which ActionMapper it contains 
should be used


Added:
    
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapper.java
    
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapperTest.java
Modified:
    
struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java
    
struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/Settings.java
    
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/default.properties

Modified: 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java?view=diff&rev=471435&r1=471434&r2=471435
==============================================================================
--- 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java 
(original)
+++ 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java 
Sun Nov  5 06:22:54 2006
@@ -17,6 +17,8 @@
  */
 package org.apache.struts2;
 
+import org.apache.struts2.dispatcher.mapper.CompositeActionMapper;
+
 /**
  * This class provides a central location for framework configuration keys
  * used to retrieve and store Struts configuration settings.
@@ -134,4 +136,6 @@
     /** Whether slashes in action names are allowed or not */ 
     public static final String STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES = 
"struts.enable.SlashesInActionNames";
      
+    /** Prefix used by [EMAIL PROTECTED] CompositeActionMapper} to identified 
its containing [EMAIL PROTECTED] ActionMapper} class. */
+    public static final String STRUTS_MAPPER_COMPOSITE = 
"struts.mapper.composite.";
 }

Modified: 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/Settings.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/Settings.java?view=diff&rev=471435&r1=471434&r2=471435
==============================================================================
--- 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/Settings.java 
(original)
+++ 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/Settings.java 
Sun Nov  5 06:22:54 2006
@@ -135,7 +135,7 @@
 
         return val;
     }
-
+    
     /**
      * Returns an Iterator of all properties names.
      *

Added: 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapper.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapper.java?view=auto&rev=471435
==============================================================================
--- 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapper.java
 (added)
+++ 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapper.java
 Sun Nov  5 06:22:54 2006
@@ -0,0 +1,254 @@
+/*
+ * $Id: ActionMapper.java 449367 2006-09-24 06:49:04Z mrdon $
+ *
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.dispatcher.mapper;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts2.StrutsConstants;
+import org.apache.struts2.config.Settings;
+
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.config.ConfigurationManager;
+import com.opensymphony.xwork2.util.FileManager;
+
+/**
+ * A composite action mapper that is capable of delegating to a series of 
[EMAIL PROTECTED] ActionMapper} if the former 
+ * failed to obtained a valid [EMAIL PROTECTED] ActionMapping} or uri.
+ * <p/>
+ * It is configured through struts.properties. 
+ * <p/>
+ * For example, with the following entries in struts.properties
+ * <pre>
+ * 
struts.mapper.class=org.apache.struts2.dispatcher.mapper.CompositeActionMapper
+ * 
struts.mapper.composite.1=org.apache.struts2.dispatcher.mapper.DefaultActionMapper
+ * 
struts.mapper.composite.2=org.apache.struts2.dispatcher.mapper.RestfulActionMapper
+ * 
struts.mapper.composite.3=org.apache.struts2.dispatcher.mapper.Restful2ActionMapper
+ * </pre>
+ * When [EMAIL PROTECTED] CompositeActionMapper#getMapping(HttpServletRequest, 
ConfigurationManager)} or 
+ * [EMAIL PROTECTED] 
CompositeActionMapper#getUriFromActionMapping(ActionMapping)} is invoked, 
+ * [EMAIL PROTECTED] CompositeActionMapper} would go through these [EMAIL 
PROTECTED] ActionMapper}s in sequence 
+ * starting from [EMAIL PROTECTED] ActionMapper} identified by 
'struts.mapper.composite.1', followed by 
+ * 'struts.mapper.composite.2' and finally 'struts.mapper.composite.3' (in 
this case) until either
+ * one of the [EMAIL PROTECTED] ActionMapper} return a valid result (not null) 
or it runs out of [EMAIL PROTECTED] ActionMapper}
+ * in which case it will just return null for both 
+ * [EMAIL PROTECTED] CompositeActionMapper#getMapping(HttpServletRequest, 
ConfigurationManager)} and 
+ * [EMAIL PROTECTED] 
CompositeActionMapper#getUriFromActionMapping(ActionMapping)} methods.
+ * 
+ * <p/>
+ * 
+ * @see ActionMapper
+ * @see ActionMapperFactory
+ * @see ActionMapping
+ * @see IndividualActionMapperEntry
+ * 
+ * @version $Date$ $Id$
+ */
+public class CompositeActionMapper implements ActionMapper {
+
+       private static final Log LOG = 
LogFactory.getLog(CompositeActionMapper.class);
+       
+       protected List<IndividualActionMapperEntry> orderedActionMappers;
+       
+       
+       public ActionMapping getMapping(HttpServletRequest request, 
ConfigurationManager configManager) {
+               
+               for (IndividualActionMapperEntry actionMapperEntry: 
getOrderedActionMapperEntries()) {
+                       ActionMapping actionMapping = 
actionMapperEntry.actionMapper.getMapping(request, configManager);
+                       if (LOG.isDebugEnabled()) {
+                               LOG.debug("Using ActionMapper from entry 
["+actionMapperEntry.propertyName+"="+actionMapperEntry.propertyValue+"]");
+                       }
+                       if (actionMapping == null) {
+                               if (LOG.isDebugEnabled()) {
+                                       LOG.debug("ActionMapper from entry 
["+actionMapperEntry.propertyName+"="+actionMapperEntry.propertyValue+"] failed 
to return an ActionMapping (null)");
+                               }
+                       }
+                       else {
+                               return actionMapping;
+                       }
+               }
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("exhausted from ActionMapper that could 
return an ActionMapping");
+               }
+               return null;
+       }
+
+       public String getUriFromActionMapping(ActionMapping mapping) {
+               
+               for (IndividualActionMapperEntry actionMapperEntry: 
getOrderedActionMapperEntries()) {
+                       String uri = 
actionMapperEntry.actionMapper.getUriFromActionMapping(mapping);
+                       if (LOG.isDebugEnabled()) {
+                               LOG.debug("Using ActionMapper from entry 
["+actionMapperEntry.propertyName+"="+actionMapperEntry.propertyValue+"]");
+                       }
+                       if (uri == null) {
+                               if (LOG.isDebugEnabled()) {
+                                       LOG.debug("ActionMapper from entry 
["+actionMapperEntry.propertyName+"="+actionMapperEntry.propertyValue+"] failed 
to return a uri (null)");
+                               }
+                       }
+                       else {
+                               return uri;
+                       }
+               }
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("exhausted from ActionMapper that could 
return a uri");
+               }
+               return null;
+       }
+       
+       
+       protected List<IndividualActionMapperEntry> 
getOrderedActionMapperEntries() {
+               if (this.orderedActionMappers == null || 
FileManager.isReloadingConfigs()) {
+                       
+                       List<IndividualActionMapperEntry> 
actionMapperEntriesContainer = new ArrayList<IndividualActionMapperEntry>();
+                       Iterator settings = Settings.list();
+                       while(settings.hasNext()) {
+                               String setting = settings.next().toString();
+                               if 
(setting.startsWith(StrutsConstants.STRUTS_MAPPER_COMPOSITE)) {
+                                       try {
+                                               int order = 
Integer.valueOf(setting.substring(StrutsConstants.STRUTS_MAPPER_COMPOSITE.length(),
 setting.length()));
+                                               String propertyValue = 
Settings.get(setting);
+                                               if (propertyValue != null && 
propertyValue.trim().length() > 0) {
+                                                       
actionMapperEntriesContainer.add(
+                                                                       new 
IndividualActionMapperEntry(order, setting, propertyValue));
+                                               }
+                                               else {
+                                                       LOG.warn("Ignoring 
property "+setting+" that contains no value");
+                                               }
+                                       }
+                                       catch(NumberFormatException e) {
+                                               LOG.warn("Ignoring malformed 
property "+setting);
+                                       }
+                               }
+                       }
+               
+                       Collections.sort(actionMapperEntriesContainer, new 
Comparator<IndividualActionMapperEntry>() {
+                               public int compare(IndividualActionMapperEntry 
o1, IndividualActionMapperEntry o2) {
+                                       return o1.compareTo(o2);
+                               }
+                       });
+               
+               
+                       ObjectFactory objectFactory = 
ObjectFactory.getObjectFactory();
+                       List<IndividualActionMapperEntry> result = new 
ArrayList<IndividualActionMapperEntry>();
+                       for (IndividualActionMapperEntry entry: 
actionMapperEntriesContainer) {
+                               String actionMapperClassName = 
entry.propertyValue;
+                               try {
+                                       // Let us get ClassCastException if it 
does not implement ActionMapper
+                                       ActionMapper actionMapper = 
(ActionMapper) objectFactory.buildBean(actionMapperClassName, null);
+                                       result.add(new 
IndividualActionMapperEntry(entry.order, entry.propertyName, 
entry.propertyValue, actionMapper));
+                               }
+                               catch(Exception e) {
+                                       LOG.warn("failed to create action 
mapper "+actionMapperClassName+", ignoring it", e);
+                               }
+                       }
+               
+                       this.orderedActionMappers = result;
+               }
+               
+               return this.orderedActionMappers;
+       }
+       
+       
+       /**
+        * A value object (holder) that holds information regarding [EMAIL 
PROTECTED] ActionMapper} this [EMAIL PROTECTED] CompositeActionMapper}
+        * is capable of delegating to.
+        * <p/>
+        * The information stored are :-
+        * <ul>
+        *      <li> order</li>
+        *      <li> propertyValue</li>
+        *      <li> propertyName</li>
+        *      <li> actionMapper</li>
+        * </ul>
+        * 
+        * eg. if we have the following entry in struts.properties
+        * <pre>
+        * struts.mapper.composite.1=foo.bar.ActionMapper1
+        * struts.mapper.composite.2=foo.bar.ActionMapper2
+        * struts.mapper.composite.3=foo.bar.ActionMapper3
+        * </pre>
+        * 
+        * <table border="1">
+        *      <tr>
+        *              <td>order</td>
+        *      <td>propertyName</td>
+        *      <td>propertyValue</td>
+        *      <td>actionMapper</td>
+        *  </tr>
+        *  <tr>
+        *      <td>1</td>
+        *      <td>struts.mapper.composite.1</td>
+        *      <td>foo.bar.ActionMapper1</td>
+        *      <td>instance of foo.bar.ActionMapper1</td>
+        *  </tr>
+        *  <tr>
+        *      <td>2</td>
+        *      <td>struts.mapper.composite.2</td>
+        *      <td>foo.bar.ActionMapper2</td>
+        *      <td>instance of foo.bar.ActionMapper2</td>
+        *  </tr>
+        *  <tr>
+        *      <td>3</td>
+        *      <td>struts.mapper.composite.3</td>
+        *      <td>foo.bar.ActionMapper3</td>
+        *      <td>instance of foo.bar.ActionMapper3</td>
+        *  </tr>
+        * </table>
+        * 
+        * @version $Date$ $Id$
+        */
+       public class IndividualActionMapperEntry implements 
Comparable<IndividualActionMapperEntry> {
+               
+               public Integer order;
+               public String propertyValue;
+               public String propertyName;
+               public ActionMapper actionMapper;
+               
+               
+               private IndividualActionMapperEntry(Integer order, String 
propertyName, String propertyValue) {
+                       assert(order != null);
+                       assert(propertyValue != null);
+                       assert(propertyName != null);
+                       this.order = order;
+                       this.propertyValue = propertyValue;
+                       this.propertyName = propertyName;
+               }
+               
+               public IndividualActionMapperEntry(Integer order, String 
propertyName, String propertyValue, ActionMapper actionMapper) {
+                       assert(order != null);
+                       assert(propertyValue != null);
+                       assert(propertyName != null);
+                       assert(actionMapper != null);
+                       this.order = order;
+                       this.propertyValue = propertyValue;
+                       this.propertyName = propertyName;
+                       this.actionMapper = actionMapper;
+               }
+
+               public int compareTo(IndividualActionMapperEntry o) {
+                       return order - o.order;
+               }
+       }
+}

Modified: 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/default.properties
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/default.properties?view=diff&rev=471435&r1=471434&r2=471435
==============================================================================
--- 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/default.properties
 (original)
+++ 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/default.properties
 Sun Nov  5 06:22:54 2006
@@ -49,6 +49,15 @@
 
 ### How request URLs are mapped to and from actions
 struts.mapper.class=org.apache.struts2.dispatcher.mapper.DefaultActionMapper
+### The above line is to be commented and following are to be uncommented to 
+### enable CompositeActionMapper
+### - With CompositeActionMapper one could specified many ActionMapper 
instance, where
+###   each of them will be chosen according to the order. Lower order number 
has
+###   higher precedence
+#struts.mapper.class=org.apache.struts2.dispatcher.mapper.CompositeActionMapper
+#struts.mapper.composite.1=org.apache.struts2.dispatcher.mapper.DefaultActionMapper
+#struts.mapper.composite.2=foo.bar.MyActionMapper
+#struts.mapper.composite.3=foo.bar.MyAnotherActionMapper
 
 ### Used by the DefaultActionMapper
 ### You may provide a comma separated list, e.g. 
struts.action.extension=action,jnlp,do

Added: 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapperTest.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapperTest.java?view=auto&rev=471435
==============================================================================
--- 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapperTest.java
 (added)
+++ 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapperTest.java
 Sun Nov  5 06:22:54 2006
@@ -0,0 +1,347 @@
+/*
+ * $Id: ActionMapper.java 449367 2006-09-24 06:49:04Z mrdon $
+ *
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.dispatcher.mapper;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.struts2.StrutsConstants;
+import org.apache.struts2.config.Settings;
+import 
org.apache.struts2.dispatcher.mapper.CompositeActionMapper.IndividualActionMapperEntry;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+import com.opensymphony.xwork2.config.ConfigurationManager;
+
+import junit.framework.TestCase;
+
+/**
+ * 
+ * @version $Date$ $Id$
+ */
+public class CompositeActionMapperTest extends TestCase {
+       
+       /**
+        * Test with empty settings (settings with no entries of interest)
+        * 
+        * @throws Exception
+        */
+       public void testGetOrderActionMapperEntries1() throws Exception {
+               CompositeActionMapper compositeActionMapper = new 
CompositeActionMapper();
+               List<IndividualActionMapperEntry> result = 
+                       compositeActionMapper.getOrderedActionMapperEntries();
+               
+               assertEquals(result.size(), 0);
+       }
+       
+       /**
+        * Test with a normal settings.
+        * 
+        * @throws Exception
+        */
+       public void testGetOrderActionMapperEntries2() throws Exception {
+               CompositeActionMapper compositeActionMapper = new 
CompositeActionMapper();
+               
+               Settings old = Settings.getInstance();
+               try {
+                       Settings.setInstance(new InnerSettings());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1", 
InnerActionMapper1.class.getName());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2", 
InnerActionMapper2.class.getName());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3", 
InnerActionMapper3.class.getName());
+               
+                       List<IndividualActionMapperEntry> result = 
+                               
compositeActionMapper.getOrderedActionMapperEntries();
+               
+                       assertEquals(result.size(), 3);
+                       
+                       IndividualActionMapperEntry e = null;
+                       Iterator<IndividualActionMapperEntry> i = 
result.iterator();
+                       
+                       // 1
+                       e = i.next();
+                       
+                       assertEquals(e.order, new Integer(1));
+                       assertEquals(e.propertyName, 
StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1");
+                       assertEquals(e.propertyValue, 
InnerActionMapper1.class.getName());
+                       assertEquals(e.actionMapper.getClass(), 
InnerActionMapper1.class);
+                       
+                       // 2
+                       e = i.next();
+                       
+                       assertEquals(e.order, new Integer(2));
+                       assertEquals(e.propertyName, 
StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2");
+                       assertEquals(e.propertyValue, 
InnerActionMapper2.class.getName());
+                       assertEquals(e.actionMapper.getClass(), 
InnerActionMapper2.class);
+                       
+                       // 3
+                       e = i.next();
+                       assertEquals(e.order, new Integer(3));
+                       assertEquals(e.propertyName, 
StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3");
+                       assertEquals(e.propertyValue, 
InnerActionMapper3.class.getName());
+                       assertEquals(e.actionMapper.getClass(), 
InnerActionMapper3.class);
+               }
+               finally {
+                       Settings.setInstance(old);
+               }
+       }
+       
+       /**
+        * Test with settings where entries are out-of-order, it needs to be 
able to retrieve them
+        * back in proper order.
+        * 
+        * @throws Exception
+        */
+       public void testGetOrderActionMapperEntries3() throws Exception {
+               CompositeActionMapper compositeActionMapper = new 
CompositeActionMapper();
+               
+               Settings old = Settings.getInstance();
+               try {
+                       Settings.setInstance(new InnerSettings());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3", 
InnerActionMapper3.class.getName());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2", 
InnerActionMapper2.class.getName());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1", 
InnerActionMapper1.class.getName());
+               
+                       List<IndividualActionMapperEntry> result = 
+                               
compositeActionMapper.getOrderedActionMapperEntries();
+               
+                       assertEquals(result.size(), 3);
+                       
+                       IndividualActionMapperEntry e = null;
+                       Iterator<IndividualActionMapperEntry> i = 
result.iterator();
+                       
+                       // 1
+                       e = i.next();
+                       
+                       assertEquals(e.order, new Integer(1));
+                       assertEquals(e.propertyName, 
StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1");
+                       assertEquals(e.propertyValue, 
InnerActionMapper1.class.getName());
+                       assertEquals(e.actionMapper.getClass(), 
InnerActionMapper1.class);
+                       
+                       // 2
+                       e = i.next();
+                       
+                       assertEquals(e.order, new Integer(2));
+                       assertEquals(e.propertyName, 
StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2");
+                       assertEquals(e.propertyValue, 
InnerActionMapper2.class.getName());
+                       assertEquals(e.actionMapper.getClass(), 
InnerActionMapper2.class);
+                       
+                       // 3
+                       e = i.next();
+                       assertEquals(e.order, new Integer(3));
+                       assertEquals(e.propertyName, 
StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3");
+                       assertEquals(e.propertyValue, 
InnerActionMapper3.class.getName());
+                       assertEquals(e.actionMapper.getClass(), 
InnerActionMapper3.class);
+               }
+               finally {
+                       Settings.setInstance(old);
+               }
+       }
+       
+       /**
+        * Test with a bad entry
+        * 
+        * @throws Exception
+        */
+       public void testGetOrderActionMapperEntries4() throws Exception {
+               CompositeActionMapper compositeActionMapper = new 
CompositeActionMapper();
+               
+               Settings old = Settings.getInstance();
+               try {
+                       Settings.setInstance(new InnerSettings());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1", 
InnerActionMapper1.class.getName());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"NotANumber", 
InnerActionMapper2.class.getName());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3", 
InnerActionMapper3.class.getName());
+               
+                       List<IndividualActionMapperEntry> result = 
+                               
compositeActionMapper.getOrderedActionMapperEntries();
+               
+                       assertEquals(result.size(), 2);
+                       
+                       IndividualActionMapperEntry e = null;
+                       Iterator<IndividualActionMapperEntry> i = 
result.iterator();
+                       
+                       // 1
+                       e = i.next();
+                       
+                       assertEquals(e.order, new Integer(1));
+                       assertEquals(e.propertyName, 
StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1");
+                       assertEquals(e.propertyValue, 
InnerActionMapper1.class.getName());
+                       assertEquals(e.actionMapper.getClass(), 
InnerActionMapper1.class);
+                       
+                       // 2
+                       e = i.next();
+                       assertEquals(e.order, new Integer(3));
+                       assertEquals(e.propertyName, 
StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3");
+                       assertEquals(e.propertyValue, 
InnerActionMapper3.class.getName());
+                       assertEquals(e.actionMapper.getClass(), 
InnerActionMapper3.class);
+               }
+               finally {
+                       Settings.setInstance(old);
+               }
+       }
+       
+       /**
+        * Test with an entry where the action mapper class is bogus.
+        * @throws Exception
+        */
+       public void testGetOrderActionMapperEntries5() throws Exception {
+               CompositeActionMapper compositeActionMapper = new 
CompositeActionMapper();
+               
+               Settings old = Settings.getInstance();
+               try {
+                       Settings.setInstance(new InnerSettings());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1", 
InnerActionMapper1.class.getName());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2", "bogus.class.name");
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3", 
InnerActionMapper3.class.getName());
+               
+                       List<IndividualActionMapperEntry> result = 
+                               
compositeActionMapper.getOrderedActionMapperEntries();
+               
+                       assertEquals(result.size(), 2);
+                       
+                       IndividualActionMapperEntry e = null;
+                       Iterator<IndividualActionMapperEntry> i = 
result.iterator();
+                       
+                       // 1
+                       e = i.next();
+                       
+                       assertEquals(e.order, new Integer(1));
+                       assertEquals(e.propertyName, 
StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1");
+                       assertEquals(e.propertyValue, 
InnerActionMapper1.class.getName());
+                       assertEquals(e.actionMapper.getClass(), 
InnerActionMapper1.class);
+                       
+                       
+                       // 2
+                       e = i.next();
+                       assertEquals(e.order, new Integer(3));
+                       assertEquals(e.propertyName, 
StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3");
+                       assertEquals(e.propertyValue, 
InnerActionMapper3.class.getName());
+                       assertEquals(e.actionMapper.getClass(), 
InnerActionMapper3.class);
+               }
+               finally {
+                       Settings.setInstance(old);
+               }
+       }
+       
+       
+       
+       public void testGetActionMappingAndUri1() throws Exception {
+               CompositeActionMapper compositeActionMapper = new 
CompositeActionMapper();
+               
+               Settings old = Settings.getInstance();
+               try {
+                       Settings.setInstance(new InnerSettings());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1", 
InnerActionMapper1.class.getName());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2", 
InnerActionMapper2.class.getName());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3", 
InnerActionMapper3.class.getName());
+               
+                       
+                       ActionMapping actionMapping = 
compositeActionMapper.getMapping(new MockHttpServletRequest(), new 
ConfigurationManager());
+                       String uri = 
compositeActionMapper.getUriFromActionMapping(new ActionMapping());
+                       
+                       assertNotNull(actionMapping);
+                       assertNotNull(uri);
+                       assertTrue(actionMapping == 
InnerActionMapper3.actionMapping);
+                       assertTrue(uri == InnerActionMapper3.uri);
+               }
+               finally {
+                       Settings.setInstance(old);
+               }
+       }
+       
+       public void testGetActionMappingAndUri2() throws Exception {
+               CompositeActionMapper compositeActionMapper = new 
CompositeActionMapper();
+               
+               Settings old = Settings.getInstance();
+               try {
+                       Settings.setInstance(new InnerSettings());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1", 
InnerActionMapper1.class.getName());
+                       
Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2", 
InnerActionMapper2.class.getName());
+               
+                       
+                       ActionMapping actionMapping = 
compositeActionMapper.getMapping(new MockHttpServletRequest(), new 
ConfigurationManager());
+                       String uri = 
compositeActionMapper.getUriFromActionMapping(new ActionMapping());
+                       
+                       assertNull(actionMapping);
+                       assertNull(uri);
+               }
+               finally {
+                       Settings.setInstance(old);
+               }
+       }
+       
+       
+       public static class InnerActionMapper1 implements ActionMapper {
+               public static ActionMapping actionMapping = new ActionMapping();
+               public static String uri="uri1";
+               
+               public ActionMapping getMapping(HttpServletRequest request, 
ConfigurationManager configManager) {
+                       return null;
+               }
+               public String getUriFromActionMapping(ActionMapping mapping) {
+                       return null;
+               }
+       }
+       public static class InnerActionMapper2 implements ActionMapper {
+               public static ActionMapping actionMapping = new ActionMapping();
+               public static String uri="uri2";
+               
+               public ActionMapping getMapping(HttpServletRequest request, 
ConfigurationManager configManager) {
+                       return null;
+               }
+               public String getUriFromActionMapping(ActionMapping mapping) {
+                       return null;
+               }
+       }
+       public static class InnerActionMapper3 implements ActionMapper {
+               public static ActionMapping actionMapping = new ActionMapping();
+               public static String uri = "uri3";
+               
+               public ActionMapping getMapping(HttpServletRequest request, 
ConfigurationManager configManager) {
+                       return actionMapping;
+               }
+               public String getUriFromActionMapping(ActionMapping mapping) {
+                       return uri;
+               }
+       }
+       
+       class InnerSettings extends Settings {
+               private Map<String, String> _impl = new LinkedHashMap<String, 
String>();
+               
+               @Override
+               public boolean isSetImpl(String name) {
+                       return _impl.containsKey(name);
+               }
+               @Override
+               public void setImpl(String name, String value) throws 
IllegalArgumentException, UnsupportedOperationException {
+                       _impl.put(name, value);
+               }
+               @Override
+               public String getImpl(String name) throws 
IllegalArgumentException {
+                       return (String) _impl.get(name);
+               }
+               @Override
+               public Iterator listImpl() {
+                       return _impl.keySet().iterator();
+               }
+       }
+       
+}


Reply via email to