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 }