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.util;
22
23 import jakarta.servlet.ServletContext;
24 import jakarta.servlet.http.HttpServletRequest;
25
26 import org.apache.struts.Globals;
27 import org.apache.struts.action.RequestProcessor;
28 import org.apache.struts.config.MessageResourcesConfig;
29 import org.apache.struts.config.ModuleConfig;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34 * General purpose utility methods related to module processing.
35 *
36 * @version $Rev$
37 * @since Struts 1.2
38 */
39 public class ModuleUtils {
40 /**
41 * The Singleton instance.
42 */
43 private static final ModuleUtils instance = new ModuleUtils();
44
45 /**
46 * The {@code Log} instance for this class.
47 */
48 private final Logger log =
49 LoggerFactory.getLogger(ModuleUtils.class);
50
51 /**
52 * Constructor for ModuleUtils.
53 */
54 protected ModuleUtils() {
55 super();
56 }
57
58 /**
59 * Returns the Singleton instance of TagUtils.
60 */
61 public static ModuleUtils getInstance() {
62 return instance;
63 }
64
65 /**
66 * Return the current ModuleConfig object stored in request, if it exists,
67 * null otherwise. This method can be used by plugin to retrieve the
68 * current module config object. If no moduleConfig is found, this means
69 * that the request haven't hit the server throught the struts servlet.
70 * The appropriate module config can be set and found with <code>{@link
71 * ModuleUtils#selectModule(HttpServletRequest, ServletContext)} </code>.
72 *
73 * @param request The servlet request we are processing
74 * @return the ModuleConfig object from request, or null if none is set in
75 * the request.
76 */
77 public ModuleConfig getModuleConfig(HttpServletRequest request) {
78 return (ModuleConfig) request.getAttribute(Globals.MODULE_KEY);
79 }
80
81 /**
82 * Return the desired ModuleConfig object stored in context, if it exists,
83 * null otherwise.
84 *
85 * @param prefix The module prefix of the desired module
86 * @param context The ServletContext for this web application
87 * @return the ModuleConfig object specified, or null if not found in the
88 * context.
89 */
90 public ModuleConfig getModuleConfig(String prefix, ServletContext context) {
91 if ((prefix == null) || "/".equals(prefix)) {
92 return (ModuleConfig) context.getAttribute(Globals.MODULE_KEY);
93 } else {
94 return (ModuleConfig) context.getAttribute(Globals.MODULE_KEY
95 + prefix);
96 }
97 }
98
99 /**
100 * Return the desired ModuleConfig object stored in context, if it exists,
101 * otherwise return the current ModuleConfig
102 *
103 * @param prefix The module prefix of the desired module
104 * @param request The servlet request we are processing
105 * @param context The ServletContext for this web application
106 * @return the ModuleConfig object specified, or null if not found in the
107 * context.
108 */
109 public ModuleConfig getModuleConfig(String prefix,
110 HttpServletRequest request, ServletContext context) {
111 ModuleConfig moduleConfig = null;
112
113 if (prefix != null) {
114 //lookup module stored with the given prefix.
115 moduleConfig = this.getModuleConfig(prefix, context);
116 } else {
117 //return the current module if no prefix was supplied.
118 moduleConfig = this.getModuleConfig(request, context);
119 }
120
121 return moduleConfig;
122 }
123
124 /**
125 * Return the ModuleConfig object is it exists, null otherwise.
126 *
127 * @param request The servlet request we are processing
128 * @param context The ServletContext for this web application
129 * @return the ModuleConfig object
130 */
131 public ModuleConfig getModuleConfig(HttpServletRequest request,
132 ServletContext context) {
133 ModuleConfig moduleConfig = this.getModuleConfig(request);
134
135 if (moduleConfig == null) {
136 moduleConfig = this.getModuleConfig("", context);
137 request.setAttribute(Globals.MODULE_KEY, moduleConfig);
138 }
139
140 return moduleConfig;
141 }
142
143 /**
144 * Get the module name to which the specified request belong.
145 *
146 * @param request The servlet request we are processing
147 * @param context The ServletContext for this web application
148 * @return The module prefix or ""
149 */
150 public String getModuleName(HttpServletRequest request,
151 ServletContext context) {
152 // Acquire the path used to compute the module
153 String matchPath =
154 (String) request.getAttribute(RequestProcessor.INCLUDE_SERVLET_PATH);
155
156 if (matchPath == null) {
157 matchPath = request.getServletPath();
158 }
159
160 return this.getModuleName(matchPath, context);
161 }
162
163 /**
164 * Get the module name to which the specified uri belong.
165 *
166 * @param matchPath The uri from which we want the module name.
167 * @param context The ServletContext for this web application
168 * @return The module prefix or ""
169 */
170 public String getModuleName(String matchPath, ServletContext context) {
171 log.debug("Get module name for path {}", matchPath);
172
173 String prefix = ""; // Initialize prefix before we try lookup
174 String[] prefixes = getModulePrefixes(context);
175
176 // Get all other possible prefixes
177 int lastSlash = 0; // Initialize before loop
178
179 while (prefix.isEmpty()
180 && ((lastSlash = matchPath.lastIndexOf("/")) > 0)) {
181 // We may be in a non-default module. Try to get it's prefix.
182 matchPath = matchPath.substring(0, lastSlash);
183
184 // Match against the list of module prefixes
185 for (int i = 0; i < prefixes.length; i++) {
186 if (matchPath.equals(prefixes[i])) {
187 prefix = prefixes[i];
188
189 break;
190 }
191 }
192 }
193
194 if (log.isDebugEnabled()) {
195 log.debug("Module name found: {}",
196 prefix.isEmpty() ? "default" : prefix);
197 }
198
199 return prefix;
200 }
201
202 /**
203 * Return the list of module prefixes that are defined for this web
204 * application. <strong>NOTE</strong> - the "" prefix for the default
205 * module is not included in this list.
206 *
207 * @param context The ServletContext for this web application.
208 * @return An array of module prefixes.
209 */
210 public String[] getModulePrefixes(ServletContext context) {
211 return (String[]) context.getAttribute(Globals.MODULE_PREFIXES_KEY);
212 }
213
214 /**
215 * Select the module to which the specified request belongs, and add
216 * corresponding request attributes to this request.
217 *
218 * @param request The servlet request we are processing
219 * @param context The ServletContext for this web application
220 */
221 public void selectModule(HttpServletRequest request, ServletContext context) {
222 // Compute module name
223 String prefix = getModuleName(request, context);
224
225 // Expose the resources for this module
226 this.selectModule(prefix, request, context);
227 }
228
229 /**
230 * Select the module to which the specified request belongs, and add
231 * corresponding request attributes to this request.
232 *
233 * @param prefix The module prefix of the desired module
234 * @param request The servlet request we are processing
235 * @param context The ServletContext for this web application
236 */
237 public void selectModule(String prefix, HttpServletRequest request,
238 ServletContext context) {
239 // Expose the resources for this module
240 ModuleConfig config = getModuleConfig(prefix, context);
241
242 if (config != null) {
243 request.setAttribute(Globals.MODULE_KEY, config);
244
245 MessageResourcesConfig[] mrConfig =
246 config.findMessageResourcesConfigs();
247
248 for (int i = 0; i < mrConfig.length; i++) {
249 String key = mrConfig[i].getKey();
250 MessageResources resources =
251 (MessageResources) context.getAttribute(key + prefix);
252
253 if (resources != null) {
254 request.setAttribute(key, resources);
255 } else {
256 request.removeAttribute(key);
257 }
258 }
259 } else {
260 request.removeAttribute(Globals.MODULE_KEY);
261 }
262 }
263 }