View Javadoc

1   /*
2    * $Id: CompositeActionMapper.java 651946 2008-04-27 13:41:38Z apetrelli $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  package org.apache.struts2.dispatcher.mapper;
23  
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  import javax.servlet.http.HttpServletRequest;
28  
29  import org.apache.struts2.StrutsConstants;
30  
31  import com.opensymphony.xwork2.config.ConfigurationManager;
32  import com.opensymphony.xwork2.inject.Container;
33  import com.opensymphony.xwork2.inject.Inject;
34  import com.opensymphony.xwork2.util.logging.Logger;
35  import com.opensymphony.xwork2.util.logging.LoggerFactory;
36  
37  /***
38   * <!-- START SNIPPET: description -->
39   *
40   * A composite action mapper that is capable of delegating to a series of {@link ActionMapper} if the former
41   * failed to obtained a valid {@link ActionMapping} or uri.
42   * <p/>
43   * It is configured through struts.properties.
44   * <p/>
45   * For example, with the following entries in struts.properties
46   * <p/>
47   * <pre>
48   * &lt;bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="struts" 
49   *       class="org.apache.struts2.dispatcher.mapper.CompositeActionMapper" /&gt;
50   * &lt;constant name="struts.mapper.composite" 
51   *       value="org.apache.struts2.dispatcher.mapper.DefaultActionMapper,org.apache.struts2.dispatcher.mapper.RestfulActionMapperorg.apache.struts2.dispatcher.mapper.Restful2ActionMapper" /&gt;
52   * </pre>
53   * <p/>
54   * When {@link CompositeActionMapper#getMapping(HttpServletRequest, ConfigurationManager)} or
55   * {@link CompositeActionMapper#getUriFromActionMapping(ActionMapping)} is invoked,
56   * {@link CompositeActionMapper} would go through these {@link ActionMapper}s in sequence
57   * starting from {@link ActionMapper} identified by 'struts.mapper.composite.1', followed by
58   * 'struts.mapper.composite.2' and finally 'struts.mapper.composite.3' (in this case) until either
59   * one of the {@link ActionMapper} return a valid result (not null) or it runs out of {@link ActionMapper}
60   * in which case it will just return null for both
61   * {@link CompositeActionMapper#getMapping(HttpServletRequest, ConfigurationManager)} and
62   * {@link CompositeActionMapper#getUriFromActionMapping(ActionMapping)} methods.
63   * <p/>
64   *
65   * For example with the following in struts-*.xml :-
66   * <pre>
67   *    &lt;bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="struts" 
68   *       class="org.apache.struts2.dispatcher.mapper.CompositeActionMapper" /&gt;
69   *    &lt;constant name="struts.mapper.composite" 
70   *       value="org.apache.struts2.dispatcher.mapper.DefaultActionMapper,foo.bar.MyActionMapper,foo.bar.MyAnotherActionMapper" /&gt;
71   * </pre>
72   * <p/>
73   * <code>CompositeActionMapper</code> will be configured with 3 ActionMapper, namely
74   * "DefaultActionMapper", "MyActionMapper" and "MyAnotherActionMapper".
75   * <code>CompositeActionMapper</code> would consult each of them in order described above.
76   *
77   * <!-- END SNIPPET: description -->
78   *
79   * @see ActionMapper
80   * @see ActionMapping
81   *
82   * @version $Date: 2008-04-27 08:41:38 -0500 (Sun, 27 Apr 2008) $ $Id: CompositeActionMapper.java 651946 2008-04-27 13:41:38Z apetrelli $
83   */
84  public class CompositeActionMapper implements ActionMapper {
85  
86      private static final Logger LOG = LoggerFactory.getLogger(CompositeActionMapper.class);
87  
88      protected Container container;
89      
90      protected List<ActionMapper> actionMappers = new ArrayList<ActionMapper>();
91      
92      @Inject
93      public void setContainer(Container container) {
94          this.container = container;
95      }
96      
97      @Inject(StrutsConstants.STRUTS_MAPPER_COMPOSITE)
98      public void setActionMappers(String list) {
99          if (list != null) {
100             String[] arr = list.split(",");
101             for (String name : arr) {
102                 Object obj = container.getInstance(ActionMapper.class, name);
103                 if (obj != null) {
104                     actionMappers.add((ActionMapper) obj);
105                 }
106             }
107         }
108     }
109 
110 
111     public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) {
112 
113         for (ActionMapper actionMapper : actionMappers) {
114             ActionMapping actionMapping = actionMapper.getMapping(request, configManager);
115             if (LOG.isDebugEnabled()) {
116                 LOG.debug("Using ActionMapper "+actionMapper);
117             }
118             if (actionMapping == null) {
119                 if (LOG.isDebugEnabled()) {
120                     LOG.debug("ActionMapper "+actionMapper+" failed to return an ActionMapping (null)");
121                 }
122             }
123             else {
124                 return actionMapping;
125             }
126         }
127         if (LOG.isDebugEnabled()) {
128             LOG.debug("exhausted from ActionMapper that could return an ActionMapping");
129         }
130         return null;
131     }
132 
133     public ActionMapping getMappingFromActionName(String actionName) {
134 
135         for (ActionMapper actionMapper : actionMappers) {
136             ActionMapping actionMapping = actionMapper.getMappingFromActionName(actionName);
137             if (LOG.isDebugEnabled()) {
138                 LOG.debug("Using ActionMapper "+actionMapper);
139             }
140             if (actionMapping == null) {
141                 if (LOG.isDebugEnabled()) {
142                     LOG.debug("ActionMapper "+actionMapper+" failed to return an ActionMapping (null)");
143                 }
144             }
145             else {
146                 return actionMapping;
147             }
148         }
149         if (LOG.isDebugEnabled()) {
150             LOG.debug("exhausted from ActionMapper that could return an ActionMapping");
151         }
152         return null;
153     }
154 
155     public String getUriFromActionMapping(ActionMapping mapping) {
156 
157         for (ActionMapper actionMapper : actionMappers) {
158             String uri = actionMapper.getUriFromActionMapping(mapping);
159             if (LOG.isDebugEnabled()) {
160                 LOG.debug("Using ActionMapper "+actionMapper);
161             }
162             if (uri == null) {
163                 if (LOG.isDebugEnabled()) {
164                     LOG.debug("ActionMapper "+actionMapper+" failed to return an ActionMapping (null)");
165                 }
166             }
167             else {
168                 return uri;
169             }
170         }
171         if (LOG.isDebugEnabled()) {
172             LOG.debug("exhausted from ActionMapper that could return a uri");
173         }
174         return null;
175     }
176 }