1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts2.dispatcher.mapper;
22
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.Iterator;
27 import java.util.List;
28
29 import javax.servlet.http.HttpServletRequest;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.struts2.StrutsConstants;
34
35 import com.opensymphony.xwork2.ObjectFactory;
36 import com.opensymphony.xwork2.config.ConfigurationManager;
37 import com.opensymphony.xwork2.inject.Container;
38 import com.opensymphony.xwork2.inject.Inject;
39 import com.opensymphony.xwork2.util.FileManager;
40
41 /***
42 * <!-- START SNIPPET: description -->
43 *
44 * A composite action mapper that is capable of delegating to a series of {@link ActionMapper} if the former
45 * failed to obtained a valid {@link ActionMapping} or uri.
46 * <p/>
47 * It is configured through struts.properties.
48 * <p/>
49 * For example, with the following entries in struts.properties
50 * <p/>
51 * <pre>
52 * <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="struts"
53 * class="org.apache.struts2.dispatcher.mapper.CompositeActionMapper" />
54 * <constant name="struts.mapper.composite"
55 * value="org.apache.struts2.dispatcher.mapper.DefaultActionMapper,org.apache.struts2.dispatcher.mapper.RestfulActionMapperorg.apache.struts2.dispatcher.mapper.Restful2ActionMapper" />
56 * </pre>
57 * <p/>
58 * When {@link CompositeActionMapper#getMapping(HttpServletRequest, ConfigurationManager)} or
59 * {@link CompositeActionMapper#getUriFromActionMapping(ActionMapping)} is invoked,
60 * {@link CompositeActionMapper} would go through these {@link ActionMapper}s in sequence
61 * starting from {@link ActionMapper} identified by 'struts.mapper.composite.1', followed by
62 * 'struts.mapper.composite.2' and finally 'struts.mapper.composite.3' (in this case) until either
63 * one of the {@link ActionMapper} return a valid result (not null) or it runs out of {@link ActionMapper}
64 * in which case it will just return null for both
65 * {@link CompositeActionMapper#getMapping(HttpServletRequest, ConfigurationManager)} and
66 * {@link CompositeActionMapper#getUriFromActionMapping(ActionMapping)} methods.
67 * <p/>
68 *
69 * For example with the following in struts-*.xml :-
70 * <pre>
71 * <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="struts"
72 * class="org.apache.struts2.dispatcher.mapper.CompositeActionMapper" />
73 * <constant name="struts.mapper.composite"
74 * value="org.apache.struts2.dispatcher.mapper.DefaultActionMapper,foo.bar.MyActionMapper,foo.bar.MyAnotherActionMapper" />
75 * </pre>
76 * <p/>
77 * <code>CompositeActionMapper</code> will be configured with 3 ActionMapper, namely
78 * "DefaultActionMapper", "MyActionMapper" and "MyAnotherActionMapper".
79 * <code>CompositeActionMapper</code> would consult each of them in order described above.
80 *
81 * <!-- END SNIPPET: description -->
82 *
83 * @see ActionMapper
84 * @see ActionMapperFactory
85 * @see ActionMapping
86 * @see IndividualActionMapperEntry
87 *
88 * @version $Date: 2006-11-23 18:31:52 +0100 (Do, 23. Nov 2006) $ $Id: CompositeActionMapper.java 478625 2006-11-23 17:31:52Z wsmoak $
89 */
90 public class CompositeActionMapper implements ActionMapper {
91
92 private static final Log LOG = LogFactory.getLog(CompositeActionMapper.class);
93
94 protected Container container;
95
96 protected List<ActionMapper> actionMappers = new ArrayList<ActionMapper>();
97
98 @Inject
99 public void setContainer(Container container) {
100 this.container = container;
101 }
102
103 @Inject(StrutsConstants.STRUTS_MAPPER_COMPOSITE)
104 public void setActionMappers(String list) {
105 if (list != null) {
106 String[] arr = list.split(",");
107 for (String name : arr) {
108 Object obj = container.getInstance(ActionMapper.class, name);
109 if (obj != null) {
110 actionMappers.add((ActionMapper) obj);
111 }
112 }
113 }
114 }
115
116
117 public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) {
118
119 for (ActionMapper actionMapper : actionMappers) {
120 ActionMapping actionMapping = actionMapper.getMapping(request, configManager);
121 if (LOG.isDebugEnabled()) {
122 LOG.debug("Using ActionMapper "+actionMapper);
123 }
124 if (actionMapping == null) {
125 if (LOG.isDebugEnabled()) {
126 LOG.debug("ActionMapper "+actionMapper+" failed to return an ActionMapping (null)");
127 }
128 }
129 else {
130 return actionMapping;
131 }
132 }
133 if (LOG.isDebugEnabled()) {
134 LOG.debug("exhausted from ActionMapper that could return an ActionMapping");
135 }
136 return null;
137 }
138
139 public String getUriFromActionMapping(ActionMapping mapping) {
140
141 for (ActionMapper actionMapper : actionMappers) {
142 String uri = actionMapper.getUriFromActionMapping(mapping);
143 if (LOG.isDebugEnabled()) {
144 LOG.debug("Using ActionMapper "+actionMapper);
145 }
146 if (uri == null) {
147 if (LOG.isDebugEnabled()) {
148 LOG.debug("ActionMapper "+actionMapper+" failed to return an ActionMapping (null)");
149 }
150 }
151 else {
152 return uri;
153 }
154 }
155 if (LOG.isDebugEnabled()) {
156 LOG.debug("exhausted from ActionMapper that could return a uri");
157 }
158 return null;
159 }
160 }