View Javadoc

    1   /*
    2    * $Id: CompositeActionMapper.java 478625 2006-11-23 17:31:52Z wsmoak $
    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  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   * &lt;bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="struts"
    53   *       class="org.apache.struts2.dispatcher.mapper.CompositeActionMapper" /&gt;
    54   * &lt;constant name="struts.mapper.composite"
    55   *       value="org.apache.struts2.dispatcher.mapper.DefaultActionMapper,org.apache.struts2.dispatcher.mapper.RestfulActionMapperorg.apache.struts2.dispatcher.mapper.Restful2ActionMapper" /&gt;
    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   *    &lt;bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="struts"
    72   *       class="org.apache.struts2.dispatcher.mapper.CompositeActionMapper" /&gt;
    73   *    &lt;constant name="struts.mapper.composite"
    74   *       value="org.apache.struts2.dispatcher.mapper.DefaultActionMapper,foo.bar.MyActionMapper,foo.bar.MyAnotherActionMapper" /&gt;
    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 12:31:52 -0500 (Thu, 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 }