View Javadoc
1   /*
2    * $Id$
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.struts.chain.commands;
22  
23  import org.apache.commons.chain.Catalog;
24  import org.apache.commons.chain.CatalogFactory;
25  import org.apache.commons.chain.Command;
26  import org.apache.struts.chain.contexts.ActionContext;
27  import org.apache.struts.config.ActionConfig;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  /**
32   * Invoke the appropriate {@code Command} for this request. If the context's
33   * {@code ActionConfig} has no {@code command} property defined, no action will
34   * be taken. If the specified command cannot be found, a warning will be
35   * logged, but processing will continue. Depending on how the chain is
36   * configured, this can be used in place of an {@code Action} or as a method of
37   * performing pre-processing.
38   *
39   * <p>If used instead of an action, the command which is looked up should put
40   * an ActionForward into the context, unless it has already dealt with the
41   * response.</p>
42   */
43  public class ExecuteCommand extends ActionCommandBase {
44      // ------------------------------------------------------ Instance Variables
45  
46      /**
47       * The {@code Log} instance for this class.
48       */
49      private final Logger log =
50          LoggerFactory.getLogger(ExecuteCommand.class);
51  
52      // ---------------------------------------------------------- Public Methods
53  
54      /**
55       * If the {@code context} is "valid", lookup a command and execute it.
56       *
57       * @param actionCtx The {@code ActionContext} for the current request
58       *
59       * @return the result of the lookup command's {@code execute} method,
60       *         if executed, or {@code false} if it was not executed.
61       * @throws Exception on any error
62       */
63      @Override
64      protected boolean execute_(ActionContext actionCtx)
65          throws Exception {
66          if (shouldProcess(actionCtx)) {
67              Command<ActionContext> command = getCommand(actionCtx);
68  
69              if (command != null) {
70                  return command.execute(actionCtx);
71              }
72          }
73  
74          return CONTINUE_PROCESSING;
75      }
76  
77      /**
78       * Evaluate the current context to see if a command should even be
79       * executed.
80       *
81       * @param context A valid ActionContext
82       *
83       * @return TRUE if the pending Command should be executed
84       */
85      protected boolean shouldProcess(ActionContext context) {
86          // Skip processing if the current request is not valid
87          Boolean valid = context.getFormValid();
88  
89          return valid != null && valid.booleanValue();
90      }
91  
92      /**
93       * Find the {@code ActionConfig} in the current context and, if it is
94       * properly configured, lookup the appropriate {@code commons-chain}
95       * command.
96       *
97       * @param context A valid ActionContext
98       *
99       * @return a {@code Command} to execute, or null if none is specified
100      *         or if the specified command cannot be found.
101      */
102     protected Command<ActionContext> getCommand(ActionContext context) {
103         ActionConfig actionConfig = context.getActionConfig();
104 
105         String commandName = actionConfig.getCommand();
106 
107         if (commandName == null) {
108             return null;
109         }
110 
111         String catalogName = actionConfig.getCatalog();
112 
113         return getCommand(commandName, catalogName);
114     }
115 
116     /**
117      * Retrieve the specified Command from the specified Catalog.
118      *
119      * @param commandName The Command to retrieve.
120      * @param catalogName The Catalog to search.
121      *
122      * @return Instantiated Command, or null
123      */
124     protected Command<ActionContext> getCommand(String commandName,
125             String catalogName) {
126 
127         if (commandName == null) {
128             return null;
129         }
130 
131         final CatalogFactory<ActionContext> catalogFactory =
132                 CatalogFactory.getInstance();
133 
134         final Catalog<ActionContext> catalog;
135 
136         if (catalogName != null) {
137             catalog = catalogFactory.getCatalog(catalogName);
138 
139             if (catalog == null) {
140                 log.warn("When looking up {}, no catalog found under {}",
141                     commandName, catalogName);
142 
143                 return null;
144             }
145         } else {
146             catalogName = "the default catalog";
147             catalog = catalogFactory.getCatalog();
148 
149             if (catalog == null) {
150                 log.warn("When looking up {}, no default catalog found.",
151                     commandName);
152 
153                 return null;
154             }
155         }
156 
157         log.debug("looking up command {} in {}",
158             commandName, catalogName);
159 
160         return catalog.getCommand(commandName);
161     }
162 }