aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-duplications/src/test/files
diff options
context:
space:
mode:
Diffstat (limited to 'sonar-duplications/src/test/files')
-rw-r--r--sonar-duplications/src/test/files/java/MessageResources.java508
-rw-r--r--sonar-duplications/src/test/files/java/RequestUtils.java1161
2 files changed, 1669 insertions, 0 deletions
diff --git a/sonar-duplications/src/test/files/java/MessageResources.java b/sonar-duplications/src/test/files/java/MessageResources.java
new file mode 100644
index 00000000000..fbed9f7e738
--- /dev/null
+++ b/sonar-duplications/src/test/files/java/MessageResources.java
@@ -0,0 +1,508 @@
+/*
+ * $Id: MessageResources.java 471754 2006-11-06 14:55:09Z husted $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.Serializable;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Locale;
+
+/**
+ * General purpose abstract class that describes an API for retrieving
+ * Locale-sensitive messages from underlying resource locations of an
+ * unspecified design, and optionally utilizing the <code>MessageFormat</code>
+ * class to produce internationalized messages with parametric replacement.
+ * <p> Calls to <code>getMessage()</code> variants without a
+ * <code>Locale</code> argument are presumed to be requesting a message string
+ * in the default <code>Locale</code> for this JVM. <p> Calls to
+ * <code>getMessage()</code> with an unknown key, or an unknown
+ * <code>Locale</code> will return <code>null</code> if the
+ * <code>returnNull</code> property is set to <code>true</code>. Otherwise, a
+ * suitable error message will be returned instead. <p> <strong>IMPLEMENTATION
+ * NOTE</strong> - Classes that extend this class must be Serializable so that
+ * instances may be used in distributable application server environments.
+ *
+ * @version $Rev: 471754 $ $Date: 2005-08-29 23:57:50 -0400 (Mon, 29 Aug 2005)
+ * $
+ */
+public abstract class MessageResources implements Serializable {
+ // ------------------------------------------------------------- Properties
+
+ /**
+ * Commons Logging instance.
+ */
+ protected static Log log = LogFactory.getLog(MessageResources.class);
+
+ // --------------------------------------------------------- Static Methods
+
+ /**
+ * The default MessageResourcesFactory used to create MessageResources
+ * instances.
+ */
+ protected static MessageResourcesFactory defaultFactory = null;
+
+ /**
+ * The configuration parameter used to initialize this MessageResources.
+ */
+ protected String config = null;
+
+ /**
+ * The default Locale for our environment.
+ */
+ protected Locale defaultLocale = Locale.getDefault();
+
+ /**
+ * The <code>MessageResourcesFactory</code> that created this instance.
+ */
+ protected MessageResourcesFactory factory = null;
+
+ /**
+ * The set of previously created MessageFormat objects, keyed by the key
+ * computed in <code>messageKey()</code>.
+ */
+ protected HashMap formats = new HashMap();
+
+ /**
+ * Indicate is a <code>null</code> is returned instead of an error message
+ * string when an unknown Locale or key is requested.
+ */
+ protected boolean returnNull = false;
+
+ /**
+ * Indicates whether 'escape processing' should be performed on the error
+ * message string.
+ */
+ private boolean escape = true;
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ * Construct a new MessageResources according to the specified
+ * parameters.
+ *
+ * @param factory The MessageResourcesFactory that created us
+ * @param config The configuration parameter for this MessageResources
+ */
+ public MessageResources(MessageResourcesFactory factory, String config) {
+ this(factory, config, false);
+ }
+
+ /**
+ * Construct a new MessageResources according to the specified
+ * parameters.
+ *
+ * @param factory The MessageResourcesFactory that created us
+ * @param config The configuration parameter for this
+ * MessageResources
+ * @param returnNull The returnNull property we should initialize with
+ */
+ public MessageResources(MessageResourcesFactory factory, String config,
+ boolean returnNull) {
+ super();
+ this.factory = factory;
+ this.config = config;
+ this.returnNull = returnNull;
+ }
+
+ /**
+ * The configuration parameter used to initialize this MessageResources.
+ *
+ * @return parameter used to initialize this MessageResources
+ */
+ public String getConfig() {
+ return (this.config);
+ }
+
+ /**
+ * The <code>MessageResourcesFactory</code> that created this instance.
+ *
+ * @return <code>MessageResourcesFactory</code> that created instance
+ */
+ public MessageResourcesFactory getFactory() {
+ return (this.factory);
+ }
+
+ /**
+ * Indicates that a <code>null</code> is returned instead of an error
+ * message string if an unknown Locale or key is requested.
+ *
+ * @return true if null is returned if unknown key or locale is requested
+ */
+ public boolean getReturnNull() {
+ return (this.returnNull);
+ }
+
+ /**
+ * Indicates that a <code>null</code> is returned instead of an error
+ * message string if an unknown Locale or key is requested.
+ *
+ * @param returnNull true Indicates that a <code>null</code> is returned
+ * if an unknown Locale or key is requested.
+ */
+ public void setReturnNull(boolean returnNull) {
+ this.returnNull = returnNull;
+ }
+
+ /**
+ * Indicates whether 'escape processing' should be performed on the error
+ * message string.
+ *
+ * @since Struts 1.2.8
+ */
+ public boolean isEscape() {
+ return escape;
+ }
+
+ /**
+ * Set whether 'escape processing' should be performed on the error
+ * message string.
+ *
+ * @since Struts 1.2.8
+ */
+ public void setEscape(boolean escape) {
+ this.escape = escape;
+ }
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * Returns a text message for the specified key, for the default Locale.
+ *
+ * @param key The message key to look up
+ */
+ public String getMessage(String key) {
+ return this.getMessage((Locale) null, key, null);
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders.
+ *
+ * @param key The message key to look up
+ * @param args An array of replacement parameters for placeholders
+ */
+ public String getMessage(String key, Object[] args) {
+ return this.getMessage((Locale) null, key, args);
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders.
+ *
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ */
+ public String getMessage(String key, Object arg0) {
+ return this.getMessage((Locale) null, key, arg0);
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders.
+ *
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ * @param arg1 The replacement for placeholder {1} in the message
+ */
+ public String getMessage(String key, Object arg0, Object arg1) {
+ return this.getMessage((Locale) null, key, arg0, arg1);
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders.
+ *
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ * @param arg1 The replacement for placeholder {1} in the message
+ * @param arg2 The replacement for placeholder {2} in the message
+ */
+ public String getMessage(String key, Object arg0, Object arg1, Object arg2) {
+ return this.getMessage((Locale) null, key, arg0, arg1, arg2);
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders.
+ *
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ * @param arg1 The replacement for placeholder {1} in the message
+ * @param arg2 The replacement for placeholder {2} in the message
+ * @param arg3 The replacement for placeholder {3} in the message
+ */
+ public String getMessage(String key, Object arg0, Object arg1, Object arg2,
+ Object arg3) {
+ return this.getMessage((Locale) null, key, arg0, arg1, arg2, arg3);
+ }
+
+ /**
+ * Returns a text message for the specified key, for the default Locale. A
+ * null string result will be returned by this method if no relevant
+ * message resource is found for this key or Locale, if the
+ * <code>returnNull</code> property is set. Otherwise, an appropriate
+ * error message will be returned. <p> This method must be implemented by
+ * a concrete subclass.
+ *
+ * @param locale The requested message Locale, or <code>null</code> for
+ * the system default Locale
+ * @param key The message key to look up
+ */
+ public abstract String getMessage(Locale locale, String key);
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders. A null string result will be returned by this
+ * method if no resource bundle has been configured.
+ *
+ * @param locale The requested message Locale, or <code>null</code> for
+ * the system default Locale
+ * @param key The message key to look up
+ * @param args An array of replacement parameters for placeholders
+ */
+ public String getMessage(Locale locale, String key, Object[] args) {
+ // Cache MessageFormat instances as they are accessed
+ if (locale == null) {
+ locale = defaultLocale;
+ }
+
+ MessageFormat format = null;
+ String formatKey = messageKey(locale, key);
+
+ synchronized (formats) {
+ format = (MessageFormat) formats.get(formatKey);
+
+ if (format == null) {
+ String formatString = getMessage(locale, key);
+
+ if (formatString == null) {
+ return returnNull ? null : ("???" + formatKey + "???");
+ }
+
+ format = new MessageFormat(escape(formatString));
+ format.setLocale(locale);
+ formats.put(formatKey, format);
+ }
+ }
+
+ return format.format(args);
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders. A null string result will never be returned by
+ * this method.
+ *
+ * @param locale The requested message Locale, or <code>null</code> for
+ * the system default Locale
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ */
+ public String getMessage(Locale locale, String key, Object arg0) {
+ return this.getMessage(locale, key, new Object[]{arg0});
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders. A null string result will never be returned by
+ * this method.
+ *
+ * @param locale The requested message Locale, or <code>null</code> for
+ * the system default Locale
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ * @param arg1 The replacement for placeholder {1} in the message
+ */
+ public String getMessage(Locale locale, String key, Object arg0, Object arg1) {
+ return this.getMessage(locale, key, new Object[]{arg0, arg1});
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders. A null string result will never be returned by
+ * this method.
+ *
+ * @param locale The requested message Locale, or <code>null</code> for
+ * the system default Locale
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ * @param arg1 The replacement for placeholder {1} in the message
+ * @param arg2 The replacement for placeholder {2} in the message
+ */
+ public String getMessage(Locale locale, String key, Object arg0,
+ Object arg1, Object arg2) {
+ return this.getMessage(locale, key, new Object[]{arg0, arg1, arg2});
+ }
+
+ /**
+ * Returns a text message after parametric replacement of the specified
+ * parameter placeholders. A null string result will never be returned by
+ * this method.
+ *
+ * @param locale The requested message Locale, or <code>null</code> for
+ * the system default Locale
+ * @param key The message key to look up
+ * @param arg0 The replacement for placeholder {0} in the message
+ * @param arg1 The replacement for placeholder {1} in the message
+ * @param arg2 The replacement for placeholder {2} in the message
+ * @param arg3 The replacement for placeholder {3} in the message
+ */
+ public String getMessage(Locale locale, String key, Object arg0,
+ Object arg1, Object arg2, Object arg3) {
+ return this.getMessage(locale, key,
+ new Object[]{arg0, arg1, arg2, arg3});
+ }
+
+ /**
+ * Return <code>true</code> if there is a defined message for the
+ * specified key in the system default locale.
+ *
+ * @param key The message key to look up
+ */
+ public boolean isPresent(String key) {
+ return this.isPresent(null, key);
+ }
+
+ /**
+ * Return <code>true</code> if there is a defined message for the
+ * specified key in the specified Locale.
+ *
+ * @param locale The requested message Locale, or <code>null</code> for
+ * the system default Locale
+ * @param key The message key to look up
+ */
+ public boolean isPresent(Locale locale, String key) {
+ String message = getMessage(locale, key);
+
+ if (message == null) {
+ return false;
+ } else if (message.startsWith("???") && message.endsWith("???")) {
+ return false; // FIXME - Only valid for default implementation
+ } else {
+ return true;
+ }
+ }
+
+ // ------------------------------------------------------ Protected Methods
+
+ /**
+ * Escape any single quote characters that are included in the specified
+ * message string.
+ *
+ * @param string The string to be escaped
+ */
+ protected String escape(String string) {
+ if (!isEscape()) {
+ return string;
+ }
+
+ if ((string == null) || (string.indexOf('\'') < 0)) {
+ return string;
+ }
+
+ int n = string.length();
+ StringBuffer sb = new StringBuffer(n);
+
+ for (int i = 0; i < n; i++) {
+ char ch = string.charAt(i);
+
+ if (ch == '\'') {
+ sb.append('\'');
+ }
+
+ sb.append(ch);
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Compute and return a key to be used in caching information by a Locale.
+ * <strong>NOTE</strong> - The locale key for the default Locale in our
+ * environment is a zero length String.
+ *
+ * @param locale The locale for which a key is desired
+ */
+ protected String localeKey(Locale locale) {
+ return (locale == null) ? "" : locale.toString();
+ }
+
+ /**
+ * Compute and return a key to be used in caching information by Locale
+ * and message key.
+ *
+ * @param locale The Locale for which this format key is calculated
+ * @param key The message key for which this format key is calculated
+ */
+ protected String messageKey(Locale locale, String key) {
+ return (localeKey(locale) + "." + key);
+ }
+
+ /**
+ * Compute and return a key to be used in caching information by locale
+ * key and message key.
+ *
+ * @param localeKey The locale key for which this cache key is calculated
+ * @param key The message key for which this cache key is
+ * calculated
+ */
+ protected String messageKey(String localeKey, String key) {
+ return (localeKey + "." + key);
+ }
+
+ /**
+ * Create and return an instance of <code>MessageResources</code> for the
+ * created by the default <code>MessageResourcesFactory</code>.
+ *
+ * @param config Configuration parameter for this message bundle.
+ */
+ public synchronized static MessageResources getMessageResources(
+ String config) {
+ if (defaultFactory == null) {
+ defaultFactory = MessageResourcesFactory.createFactory();
+ }
+
+ return defaultFactory.createResources(config);
+ }
+
+ /**
+ * Log a message to the Writer that has been configured for our use.
+ *
+ * @param message The message to be logged
+ */
+ public void log(String message) {
+ log.debug(message);
+ }
+
+ /**
+ * Log a message and exception to the Writer that has been configured for
+ * our use.
+ *
+ * @param message The message to be logged
+ * @param throwable The exception to be logged
+ */
+ public void log(String message, Throwable throwable) {
+ log.debug(message, throwable);
+ }
+}
diff --git a/sonar-duplications/src/test/files/java/RequestUtils.java b/sonar-duplications/src/test/files/java/RequestUtils.java
new file mode 100644
index 00000000000..2591a0d190a
--- /dev/null
+++ b/sonar-duplications/src/test/files/java/RequestUtils.java
@@ -0,0 +1,1161 @@
+/*
+ * $Id: RequestUtils.java 727180 2008-12-16 21:54:10Z niallp $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts.util;
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.Globals;
+import org.apache.struts.action.*;
+import org.apache.struts.config.ActionConfig;
+import org.apache.struts.config.FormBeanConfig;
+import org.apache.struts.config.ForwardConfig;
+import org.apache.struts.config.ModuleConfig;
+import org.apache.struts.upload.FormFile;
+import org.apache.struts.upload.MultipartRequestHandler;
+import org.apache.struts.upload.MultipartRequestWrapper;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+
+/**
+ * <p>General purpose utility methods related to processing a servlet request
+ * in the Struts controller framework.</p>
+ *
+ * @version $Rev: 727180 $ $Date: 2008-12-17 00:54:10 +0300 (Ср., 17 дек. 2008) $
+ */
+public class RequestUtils {
+ // ------------------------------------------------------- Static Variables
+
+ /**
+ * <p>Commons Logging instance.</p>
+ */
+ protected static Log log = LogFactory.getLog(RequestUtils.class);
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * <p>Create and return an absolute URL for the specified context-relative
+ * path, based on the server and context information in the specified
+ * request.</p>
+ *
+ * @param request The servlet request we are processing
+ * @param path The context-relative path (must start with '/')
+ * @return absolute URL based on context-relative path
+ * @throws MalformedURLException if we cannot create an absolute URL
+ */
+ public static URL absoluteURL(HttpServletRequest request, String path)
+ throws MalformedURLException {
+ return (new URL(serverURL(request), request.getContextPath() + path));
+ }
+
+ /**
+ * <p>Return the <code>Class</code> object for the specified fully
+ * qualified class name, from this web application's class loader.</p>
+ *
+ * @param className Fully qualified class name to be loaded
+ * @return Class object
+ * @throws ClassNotFoundException if the class cannot be found
+ */
+ public static Class applicationClass(String className)
+ throws ClassNotFoundException {
+ return applicationClass(className, null);
+ }
+
+ /**
+ * <p>Return the <code>Class</code> object for the specified fully
+ * qualified class name, from this web application's class loader.</p>
+ *
+ * @param className Fully qualified class name to be loaded
+ * @param classLoader The desired classloader to use
+ * @return Class object
+ * @throws ClassNotFoundException if the class cannot be found
+ */
+ public static Class applicationClass(String className,
+ ClassLoader classLoader)
+ throws ClassNotFoundException {
+ if (classLoader == null) {
+ // Look up the class loader to be used
+ classLoader = Thread.currentThread().getContextClassLoader();
+
+ if (classLoader == null) {
+ classLoader = RequestUtils.class.getClassLoader();
+ }
+ }
+
+ // Attempt to load the specified class
+ return (classLoader.loadClass(className));
+ }
+
+ /**
+ * <p>Return a new instance of the specified fully qualified class name,
+ * after loading the class from this web application's class loader. The
+ * specified class <strong>MUST</strong> have a public zero-arguments
+ * constructor.</p>
+ *
+ * @param className Fully qualified class name to use
+ * @return new instance of class
+ * @throws ClassNotFoundException if the class cannot be found
+ * @throws IllegalAccessException if the class or its constructor is not
+ * accessible
+ * @throws InstantiationException if this class represents an abstract
+ * class, an interface, an array class, a
+ * primitive type, or void
+ * @throws InstantiationException if this class has no zero-arguments
+ * constructor
+ */
+ public static Object applicationInstance(String className)
+ throws ClassNotFoundException, IllegalAccessException,
+ InstantiationException {
+ return applicationInstance(className, null);
+ }
+
+ /**
+ * <p>Return a new instance of the specified fully qualified class name,
+ * after loading the class from this web application's class loader. The
+ * specified class <strong>MUST</strong> have a public zero-arguments
+ * constructor.</p>
+ *
+ * @param className Fully qualified class name to use
+ * @param classLoader The desired classloader to use
+ * @return new instance of class
+ * @throws ClassNotFoundException if the class cannot be found
+ * @throws IllegalAccessException if the class or its constructor is not
+ * accessible
+ * @throws InstantiationException if this class represents an abstract
+ * class, an interface, an array class, a
+ * primitive type, or void
+ * @throws InstantiationException if this class has no zero-arguments
+ * constructor
+ */
+ public static Object applicationInstance(String className,
+ ClassLoader classLoader)
+ throws ClassNotFoundException, IllegalAccessException,
+ InstantiationException {
+ return (applicationClass(className, classLoader).newInstance());
+ }
+
+ /**
+ * <p>Create (if necessary) and return an <code>ActionForm</code> instance
+ * appropriate for this request. If no <code>ActionForm</code> instance
+ * is required, return <code>null</code>.</p>
+ *
+ * @param request The servlet request we are processing
+ * @param mapping The action mapping for this request
+ * @param moduleConfig The configuration for this module
+ * @param servlet The action servlet
+ * @return ActionForm instance associated with this request
+ */
+ public static ActionForm createActionForm(HttpServletRequest request,
+ ActionMapping mapping, ModuleConfig moduleConfig, ActionServlet servlet) {
+ // Is there a form bean associated with this mapping?
+ String attribute = mapping.getAttribute();
+
+ if (attribute == null) {
+ return (null);
+ }
+
+ // Look up the form bean configuration information to use
+ String name = mapping.getName();
+ FormBeanConfig config = moduleConfig.findFormBeanConfig(name);
+
+ if (config == null) {
+ log.warn("No FormBeanConfig found under '" + name + "'");
+
+ return (null);
+ }
+
+ ActionForm instance =
+ lookupActionForm(request, attribute, mapping.getScope());
+
+ // Can we recycle the existing form bean instance (if there is one)?
+ if ((instance != null) && config.canReuse(instance)) {
+ return (instance);
+ }
+
+ return createActionForm(config, servlet);
+ }
+
+ private static ActionForm lookupActionForm(HttpServletRequest request,
+ String attribute, String scope) {
+ // Look up any existing form bean instance
+ if (log.isDebugEnabled()) {
+ log.debug(" Looking for ActionForm bean instance in scope '"
+ + scope + "' under attribute key '" + attribute + "'");
+ }
+
+ ActionForm instance = null;
+ HttpSession session = null;
+
+ if ("request".equals(scope)) {
+ instance = (ActionForm) request.getAttribute(attribute);
+ } else {
+ session = request.getSession();
+ instance = (ActionForm) session.getAttribute(attribute);
+ }
+
+ return (instance);
+ }
+
+ /**
+ * <p>Create and return an <code>ActionForm</code> instance appropriate to
+ * the information in <code>config</code>.</p>
+ * <p/>
+ * <p>Does not perform any checks to see if an existing ActionForm exists
+ * which could be reused.</p>
+ *
+ * @param config The configuration for the Form bean which is to be
+ * created.
+ * @param servlet The action servlet
+ * @return ActionForm instance associated with this request
+ */
+ public static ActionForm createActionForm(FormBeanConfig config,
+ ActionServlet servlet) {
+ if (config == null) {
+ return (null);
+ }
+
+ ActionForm instance = null;
+
+ // Create and return a new form bean instance
+ try {
+ instance = config.createActionForm(servlet);
+
+ if (log.isDebugEnabled()) {
+ log.debug(" Creating new "
+ + (config.getDynamic() ? "DynaActionForm" : "ActionForm")
+ + " instance of type '" + config.getType() + "'");
+ log.trace(" --> " + instance);
+ }
+ } catch (Throwable t) {
+ log.error(servlet.getInternal().getMessage("formBean",
+ config.getType()), t);
+ }
+
+ return (instance);
+ }
+
+ /**
+ * <p>Retrieves the servlet mapping pattern for the specified {@link ActionServlet}.</p>
+ *
+ * @return the servlet mapping
+ * @see Globals#SERVLET_KEY
+ * @since Struts 1.3.6
+ */
+ public static String getServletMapping(ActionServlet servlet) {
+ ServletContext servletContext = servlet.getServletConfig().getServletContext();
+ return (String) servletContext.getAttribute(Globals.SERVLET_KEY);
+ }
+
+ /**
+ * <p>Look up and return current user locale, based on the specified
+ * parameters.</p>
+ *
+ * @param request The request used to lookup the Locale
+ * @param locale Name of the session attribute for our user's Locale. If
+ * this is <code>null</code>, the default locale key is
+ * used for the lookup.
+ * @return current user locale
+ * @since Struts 1.2
+ */
+ public static Locale getUserLocale(HttpServletRequest request, String locale) {
+ Locale userLocale = null;
+ HttpSession session = request.getSession(false);
+
+ if (locale == null) {
+ locale = Globals.LOCALE_KEY;
+ }
+
+ // Only check session if sessions are enabled
+ if (session != null) {
+ userLocale = (Locale) session.getAttribute(locale);
+ }
+
+ if (userLocale == null) {
+ // Returns Locale based on Accept-Language header or the server default
+ userLocale = request.getLocale();
+ }
+
+ return userLocale;
+ }
+
+ /**
+ * <p>Populate the properties of the specified JavaBean from the specified
+ * HTTP request, based on matching each parameter name against the
+ * corresponding JavaBeans "property setter" methods in the bean's class.
+ * Suitable conversion is done for argument types as described under
+ * <code>convert()</code>.</p>
+ *
+ * @param bean The JavaBean whose properties are to be set
+ * @param request The HTTP request whose parameters are to be used to
+ * populate bean properties
+ * @throws ServletException if an exception is thrown while setting
+ * property values
+ */
+ public static void populate(Object bean, HttpServletRequest request)
+ throws ServletException {
+ populate(bean, null, null, request);
+ }
+
+ /**
+ * <p>Populate the properties of the specified JavaBean from the specified
+ * HTTP request, based on matching each parameter name (plus an optional
+ * prefix and/or suffix) against the corresponding JavaBeans "property
+ * setter" methods in the bean's class. Suitable conversion is done for
+ * argument types as described under <code>setProperties</code>.</p>
+ * <p/>
+ * <p>If you specify a non-null <code>prefix</code> and a non-null
+ * <code>suffix</code>, the parameter name must match
+ * <strong>both</strong> conditions for its value(s) to be used in
+ * populating bean properties. If the request's content type is
+ * "multipart/form-data" and the method is "POST", the
+ * <code>HttpServletRequest</code> object will be wrapped in a
+ * <code>MultipartRequestWrapper</code object.</p>
+ *
+ * @param bean The JavaBean whose properties are to be set
+ * @param prefix The prefix (if any) to be prepend to bean property names
+ * when looking for matching parameters
+ * @param suffix The suffix (if any) to be appended to bean property
+ * names when looking for matching parameters
+ * @param request The HTTP request whose parameters are to be used to
+ * populate bean properties
+ * @throws ServletException if an exception is thrown while setting
+ * property values
+ */
+ public static void populate(Object bean, String prefix, String suffix,
+ HttpServletRequest request)
+ throws ServletException {
+ // Build a list of relevant request parameters from this request
+ HashMap properties = new HashMap();
+
+ // Iterator of parameter names
+ Enumeration names = null;
+
+ // Map for multipart parameters
+ Map multipartParameters = null;
+
+ String contentType = request.getContentType();
+ String method = request.getMethod();
+ boolean isMultipart = false;
+
+ if (bean instanceof ActionForm) {
+ ((ActionForm) bean).setMultipartRequestHandler(null);
+ }
+
+ MultipartRequestHandler multipartHandler = null;
+ if ((contentType != null)
+ && (contentType.startsWith("multipart/form-data"))
+ && (method.equalsIgnoreCase("POST"))) {
+ // Get the ActionServletWrapper from the form bean
+ ActionServletWrapper servlet;
+
+ if (bean instanceof ActionForm) {
+ servlet = ((ActionForm) bean).getServletWrapper();
+ } else {
+ throw new ServletException("bean that's supposed to be "
+ + "populated from a multipart request is not of type "
+ + "\"org.apache.struts.action.ActionForm\", but type "
+ + "\"" + bean.getClass().getName() + "\"");
+ }
+
+ // Obtain a MultipartRequestHandler
+ multipartHandler = getMultipartHandler(request);
+
+ if (multipartHandler != null) {
+ isMultipart = true;
+
+ // Set servlet and mapping info
+ servlet.setServletFor(multipartHandler);
+ multipartHandler.setMapping((ActionMapping) request
+ .getAttribute(Globals.MAPPING_KEY));
+
+ // Initialize multipart request class handler
+ multipartHandler.handleRequest(request);
+
+ //stop here if the maximum length has been exceeded
+ Boolean maxLengthExceeded =
+ (Boolean) request.getAttribute(MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED);
+
+ if ((maxLengthExceeded != null)
+ && (maxLengthExceeded.booleanValue())) {
+ ((ActionForm) bean).setMultipartRequestHandler(multipartHandler);
+ return;
+ }
+
+ //retrieve form values and put into properties
+ multipartParameters =
+ getAllParametersForMultipartRequest(request,
+ multipartHandler);
+ names = Collections.enumeration(multipartParameters.keySet());
+ }
+ }
+
+ if (!isMultipart) {
+ names = request.getParameterNames();
+ }
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ String stripped = name;
+
+ if (prefix != null) {
+ if (!stripped.startsWith(prefix)) {
+ continue;
+ }
+
+ stripped = stripped.substring(prefix.length());
+ }
+
+ if (suffix != null) {
+ if (!stripped.endsWith(suffix)) {
+ continue;
+ }
+
+ stripped =
+ stripped.substring(0, stripped.length() - suffix.length());
+ }
+
+ Object parameterValue = null;
+
+ if (isMultipart) {
+ parameterValue = multipartParameters.get(name);
+ parameterValue = rationalizeMultipleFileProperty(bean, name, parameterValue);
+ } else {
+ parameterValue = request.getParameterValues(name);
+ }
+
+ // Populate parameters, except "standard" struts attributes
+ // such as 'org.apache.struts.action.CANCEL'
+ if (!(stripped.startsWith("org.apache.struts."))) {
+ properties.put(stripped, parameterValue);
+ }
+ }
+
+ // Set the corresponding properties of our bean
+ try {
+ BeanUtils.populate(bean, properties);
+ } catch (Exception e) {
+ throw new ServletException("BeanUtils.populate", e);
+ } finally {
+ if (multipartHandler != null) {
+ // Set the multipart request handler for our ActionForm.
+ // If the bean isn't an ActionForm, an exception would have been
+ // thrown earlier, so it's safe to assume that our bean is
+ // in fact an ActionForm.
+ ((ActionForm) bean).setMultipartRequestHandler(multipartHandler);
+ }
+ }
+ }
+
+ /**
+ * <p>Populates the parameters of the specified ActionRedirect from
+ * the specified HTTP request.</p>
+ *
+ * @param redirect The ActionRedirect whose parameters are to be set
+ * @param request The HTTP request whose parameters are to be used
+ * @since Struts 1.4
+ */
+ public static void populate(ActionRedirect redirect, HttpServletRequest request) {
+ assert (redirect != null) : "redirect is required";
+ assert (request != null) : "request is required";
+
+ Enumeration e = request.getParameterNames();
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ String[] values = request.getParameterValues(name);
+ redirect.addParameter(name, values);
+ }
+ }
+
+ /**
+ * <p>If the given form bean can accept multiple FormFile objects but the user only uploaded a single, then
+ * the property will not match the form bean type. This method performs some simple checks to try to accommodate
+ * that situation.</p>
+ *
+ * @param bean
+ * @param name
+ * @param parameterValue
+ * @return
+ * @throws ServletException if the introspection has any errors.
+ */
+ private static Object rationalizeMultipleFileProperty(Object bean, String name, Object parameterValue) throws ServletException {
+ if (!(parameterValue instanceof FormFile)) {
+ return parameterValue;
+ }
+
+ FormFile formFileValue = (FormFile) parameterValue;
+ try {
+ Class propertyType = PropertyUtils.getPropertyType(bean, name);
+
+ if (propertyType == null) {
+ return parameterValue;
+ }
+
+ if (List.class.isAssignableFrom(propertyType)) {
+ ArrayList list = new ArrayList(1);
+ list.add(formFileValue);
+ return list;
+ }
+
+ if (propertyType.isArray() && propertyType.getComponentType().equals(FormFile.class)) {
+ return new FormFile[]{formFileValue};
+ }
+
+ } catch (IllegalAccessException e) {
+ throw new ServletException(e);
+ } catch (InvocationTargetException e) {
+ throw new ServletException(e);
+ } catch (NoSuchMethodException e) {
+ throw new ServletException(e);
+ }
+
+ // no changes
+ return parameterValue;
+
+ }
+
+ /**
+ * <p>Try to locate a multipart request handler for this request. First,
+ * look for a mapping-specific handler stored for us under an attribute.
+ * If one is not present, use the global multipart handler, if there is
+ * one.</p>
+ *
+ * @param request The HTTP request for which the multipart handler should
+ * be found.
+ * @return the multipart handler to use, or null if none is found.
+ * @throws ServletException if any exception is thrown while attempting to
+ * locate the multipart handler.
+ */
+ private static MultipartRequestHandler getMultipartHandler(
+ HttpServletRequest request)
+ throws ServletException {
+ MultipartRequestHandler multipartHandler = null;
+ String multipartClass =
+ (String) request.getAttribute(Globals.MULTIPART_KEY);
+
+ request.removeAttribute(Globals.MULTIPART_KEY);
+
+ // Try to initialize the mapping specific request handler
+ if (multipartClass != null) {
+ try {
+ multipartHandler =
+ (MultipartRequestHandler) applicationInstance(multipartClass);
+ } catch (ClassNotFoundException cnfe) {
+ log.error("MultipartRequestHandler class \"" + multipartClass
+ + "\" in mapping class not found, "
+ + "defaulting to global multipart class");
+ } catch (InstantiationException ie) {
+ log.error("InstantiationException when instantiating "
+ + "MultipartRequestHandler \"" + multipartClass + "\", "
+ + "defaulting to global multipart class, exception: "
+ + ie.getMessage());
+ } catch (IllegalAccessException iae) {
+ log.error("IllegalAccessException when instantiating "
+ + "MultipartRequestHandler \"" + multipartClass + "\", "
+ + "defaulting to global multipart class, exception: "
+ + iae.getMessage());
+ }
+
+ if (multipartHandler != null) {
+ return multipartHandler;
+ }
+ }
+
+ ModuleConfig moduleConfig =
+ ModuleUtils.getInstance().getModuleConfig(request);
+
+ multipartClass = moduleConfig.getControllerConfig().getMultipartClass();
+
+ // Try to initialize the global request handler
+ if (multipartClass != null) {
+ try {
+ multipartHandler =
+ (MultipartRequestHandler) applicationInstance(multipartClass);
+ } catch (ClassNotFoundException cnfe) {
+ throw new ServletException("Cannot find multipart class \""
+ + multipartClass + "\"", cnfe);
+ } catch (InstantiationException ie) {
+ throw new ServletException(
+ "InstantiationException when instantiating "
+ + "multipart class \"" + multipartClass + "\"", ie);
+ } catch (IllegalAccessException iae) {
+ throw new ServletException(
+ "IllegalAccessException when instantiating "
+ + "multipart class \"" + multipartClass + "\"", iae);
+ }
+
+ if (multipartHandler != null) {
+ return multipartHandler;
+ }
+ }
+
+ return multipartHandler;
+ }
+
+ /**
+ * <p>Create a <code>Map</code> containing all of the parameters supplied
+ * for a multipart request, keyed by parameter name. In addition to text
+ * and file elements from the multipart body, query string parameters are
+ * included as well.</p>
+ *
+ * @param request The (wrapped) HTTP request whose parameters are
+ * to be added to the map.
+ * @param multipartHandler The multipart handler used to parse the
+ * request.
+ * @return the map containing all parameters for this multipart request.
+ */
+ private static Map getAllParametersForMultipartRequest(
+ HttpServletRequest request, MultipartRequestHandler multipartHandler) {
+ Map parameters = new HashMap();
+ Hashtable elements = multipartHandler.getAllElements();
+ Enumeration e = elements.keys();
+
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+
+ parameters.put(key, elements.get(key));
+ }
+
+ if (request instanceof MultipartRequestWrapper) {
+ request =
+ (HttpServletRequest) ((MultipartRequestWrapper) request)
+ .getRequest();
+ e = request.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+
+ parameters.put(key, request.getParameterValues(key));
+ }
+ } else {
+ log.debug("Gathering multipart parameters for unwrapped request");
+ }
+
+ return parameters;
+ }
+
+ /**
+ * <p>Compute the printable representation of a URL, leaving off the
+ * scheme/host/port part if no host is specified. This will typically be
+ * the case for URLs that were originally created from relative or
+ * context-relative URIs.</p>
+ *
+ * @param url URL to render in a printable representation
+ * @return printable representation of a URL
+ */
+ public static String printableURL(URL url) {
+ if (url.getHost() != null) {
+ return (url.toString());
+ }
+
+ String file = url.getFile();
+ String ref = url.getRef();
+
+ if (ref == null) {
+ return (file);
+ } else {
+ StringBuffer sb = new StringBuffer(file);
+
+ sb.append('#');
+ sb.append(ref);
+
+ return (sb.toString());
+ }
+ }
+
+ /**
+ * <p>Return the context-relative URL that corresponds to the specified
+ * {@link ActionConfig}, relative to the module associated with the
+ * current modules's {@link ModuleConfig}.</p>
+ *
+ * @param request The servlet request we are processing
+ * @param action ActionConfig to be evaluated
+ * @param pattern URL pattern used to map the controller servlet
+ * @return context-relative URL relative to the module
+ * @since Struts 1.1
+ */
+ public static String actionURL(HttpServletRequest request,
+ ActionConfig action, String pattern) {
+ StringBuffer sb = new StringBuffer();
+
+ if (pattern.endsWith("/*")) {
+ sb.append(pattern.substring(0, pattern.length() - 2));
+ sb.append(action.getPath());
+ } else if (pattern.startsWith("*.")) {
+ ModuleConfig appConfig =
+ ModuleUtils.getInstance().getModuleConfig(request);
+
+ sb.append(appConfig.getPrefix());
+ sb.append(action.getPath());
+ sb.append(pattern.substring(1));
+ } else {
+ throw new IllegalArgumentException(pattern);
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * <p>Return the context-relative URL that corresponds to the specified
+ * <code>ForwardConfig</code>. The URL is calculated based on the
+ * properties of the {@link ForwardConfig} instance as follows:</p>
+ * <p/>
+ * <ul>
+ * <p/>
+ * <p/>
+ * <li>If the <code>contextRelative</code> property is set, it is assumed
+ * that the <code>path</code> property contains a path that is already
+ * context-relative:
+ * <p/>
+ * <ul>
+ * <p/>
+ * <li>If the <code>path</code> property value starts with a slash, it is
+ * returned unmodified.</li> <li>If the <code>path</code> property value
+ * does not start with a slash, a slash is prepended.</li>
+ * <p/>
+ * </ul></li>
+ * <p/>
+ * <li>Acquire the <code>forwardPattern</code> property from the
+ * <code>ControllerConfig</code> for the application module used to
+ * process this request. If no pattern was configured, default to a
+ * pattern of <code>$M$P</code>, which is compatible with the hard-coded
+ * mapping behavior in Struts 1.0.</li>
+ * <p/>
+ * <li>Process the acquired <code>forwardPattern</code>, performing the
+ * following substitutions:
+ * <p/>
+ * <ul>
+ * <p/>
+ * <li><strong>$M</strong> - Replaced by the module prefix for the
+ * application module processing this request.</li>
+ * <p/>
+ * <li><strong>$P</strong> - Replaced by the <code>path</code> property of
+ * the specified {@link ForwardConfig}, prepended with a slash if it does
+ * not start with one.</li>
+ * <p/>
+ * <li><strong>$$</strong> - Replaced by a single dollar sign
+ * character.</li>
+ * <p/>
+ * <li><strong>$x</strong> (where "x" is any charater not listed above) -
+ * Silently omit these two characters from the result value. (This has
+ * the side effect of causing all other $+letter combinations to be
+ * reserved.)</li>
+ * <p/>
+ * </ul></li>
+ * <p/>
+ * </ul>
+ *
+ * @param request The servlet request we are processing
+ * @param forward ForwardConfig to be evaluated
+ * @return context-relative URL
+ * @since Struts 1.1
+ */
+ public static String forwardURL(HttpServletRequest request,
+ ForwardConfig forward) {
+ return forwardURL(request, forward, null);
+ }
+
+ /**
+ * <p>Return the context-relative URL that corresponds to the specified
+ * <code>ForwardConfig</code>. The URL is calculated based on the
+ * properties of the {@link ForwardConfig} instance as follows:</p>
+ * <p/>
+ * <ul>
+ * <p/>
+ * <li>If the <code>contextRelative</code> property is set, it is assumed
+ * that the <code>path</code> property contains a path that is already
+ * context-relative: <ul>
+ * <p/>
+ * <li>If the <code>path</code> property value starts with a slash, it is
+ * returned unmodified.</li> <li>If the <code>path</code> property value
+ * does not start with a slash, a slash is prepended.</li>
+ * <p/>
+ * </ul></li>
+ * <p/>
+ * <li>Acquire the <code>forwardPattern</code> property from the
+ * <code>ControllerConfig</code> for the application module used to
+ * process this request. If no pattern was configured, default to a
+ * pattern of <code>$M$P</code>, which is compatible with the hard-coded
+ * mapping behavior in Struts 1.0.</li>
+ * <p/>
+ * <li>Process the acquired <code>forwardPattern</code>, performing the
+ * following substitutions: <ul> <li><strong>$M</strong> - Replaced by the
+ * module prefix for the application module processing this request.</li>
+ * <p/>
+ * <li><strong>$P</strong> - Replaced by the <code>path</code> property of
+ * the specified {@link ForwardConfig}, prepended with a slash if it does
+ * not start with one.</li>
+ * <p/>
+ * <li><strong>$$</strong> - Replaced by a single dollar sign
+ * character.</li>
+ * <p/>
+ * <li><strong>$x</strong> (where "x" is any charater not listed above) -
+ * Silently omit these two characters from the result value. (This has
+ * the side effect of causing all other $+letter combinations to be
+ * reserved.)</li>
+ * <p/>
+ * </ul></li></ul>
+ *
+ * @param request The servlet request we are processing
+ * @param forward ForwardConfig to be evaluated
+ * @param moduleConfig Base forward on this module config.
+ * @return context-relative URL
+ * @since Struts 1.2
+ */
+ public static String forwardURL(HttpServletRequest request,
+ ForwardConfig forward, ModuleConfig moduleConfig) {
+ //load the current moduleConfig, if null
+ if (moduleConfig == null) {
+ moduleConfig = ModuleUtils.getInstance().getModuleConfig(request);
+ }
+
+ String path = forward.getPath();
+
+ //load default prefix
+ String prefix = moduleConfig.getPrefix();
+
+ //override prefix if supplied by forward
+ if (forward.getModule() != null) {
+ prefix = forward.getModule();
+
+ if ("/".equals(prefix)) {
+ prefix = "";
+ }
+ }
+
+ StringBuffer sb = new StringBuffer();
+
+ // Calculate a context relative path for this ForwardConfig
+ String forwardPattern =
+ moduleConfig.getControllerConfig().getForwardPattern();
+
+ if (forwardPattern == null) {
+ // Performance optimization for previous default behavior
+ sb.append(prefix);
+
+ // smoothly insert a '/' if needed
+ if (!path.startsWith("/")) {
+ sb.append("/");
+ }
+
+ sb.append(path);
+ } else {
+ boolean dollar = false;
+
+ for (int i = 0; i < forwardPattern.length(); i++) {
+ char ch = forwardPattern.charAt(i);
+
+ if (dollar) {
+ switch (ch) {
+ case 'M':
+ sb.append(prefix);
+
+ break;
+
+ case 'P':
+
+ // add '/' if needed
+ if (!path.startsWith("/")) {
+ sb.append("/");
+ }
+
+ sb.append(path);
+
+ break;
+
+ case '$':
+ sb.append('$');
+
+ break;
+
+ default:
+ ; // Silently swallow
+ }
+
+ dollar = false;
+
+ continue;
+ } else if (ch == '$') {
+ dollar = true;
+ } else {
+ sb.append(ch);
+ }
+ }
+ }
+
+ return (sb.toString());
+ }
+
+ /**
+ * <p>Return the URL representing the current request. This is equivalent
+ * to <code>HttpServletRequest.getRequestURL</code> in Servlet 2.3.</p>
+ *
+ * @param request The servlet request we are processing
+ * @return URL representing the current request
+ * @throws MalformedURLException if a URL cannot be created
+ */
+ public static URL requestURL(HttpServletRequest request)
+ throws MalformedURLException {
+ StringBuffer url = requestToServerUriStringBuffer(request);
+
+ return (new URL(url.toString()));
+ }
+
+ /**
+ * <p>Return the URL representing the scheme, server, and port number of
+ * the current request. Server-relative URLs can be created by simply
+ * appending the server-relative path (starting with '/') to this.</p>
+ *
+ * @param request The servlet request we are processing
+ * @return URL representing the scheme, server, and port number of the
+ * current request
+ * @throws MalformedURLException if a URL cannot be created
+ */
+ public static URL serverURL(HttpServletRequest request)
+ throws MalformedURLException {
+ StringBuffer url = requestToServerStringBuffer(request);
+
+ return (new URL(url.toString()));
+ }
+
+ /**
+ * <p>Return the string representing the scheme, server, and port number
+ * of the current request. Server-relative URLs can be created by simply
+ * appending the server-relative path (starting with '/') to this.</p>
+ *
+ * @param request The servlet request we are processing
+ * @return URL representing the scheme, server, and port number of the
+ * current request
+ * @since Struts 1.2.0
+ */
+ public static StringBuffer requestToServerUriStringBuffer(
+ HttpServletRequest request) {
+ StringBuffer serverUri =
+ createServerUriStringBuffer(request.getScheme(),
+ request.getServerName(), request.getServerPort(),
+ request.getRequestURI());
+
+ return serverUri;
+ }
+
+ /**
+ * <p>Return <code>StringBuffer</code> representing the scheme, server,
+ * and port number of the current request. Server-relative URLs can be
+ * created by simply appending the server-relative path (starting with
+ * '/') to this.</p>
+ *
+ * @param request The servlet request we are processing
+ * @return URL representing the scheme, server, and port number of the
+ * current request
+ * @since Struts 1.2.0
+ */
+ public static StringBuffer requestToServerStringBuffer(
+ HttpServletRequest request) {
+ return createServerStringBuffer(request.getScheme(),
+ request.getServerName(), request.getServerPort());
+ }
+
+ /**
+ * <p>Return <code>StringBuffer</code> representing the scheme, server,
+ * and port number of the current request.</p>
+ *
+ * @param scheme The scheme name to use
+ * @param server The server name to use
+ * @param port The port value to use
+ * @return StringBuffer in the form scheme: server: port
+ * @since Struts 1.2.0
+ */
+ public static StringBuffer createServerStringBuffer(String scheme,
+ String server, int port) {
+ StringBuffer url = new StringBuffer();
+
+ if (port < 0) {
+ port = 80; // Work around java.net.URL bug
+ }
+
+ url.append(scheme);
+ url.append("://");
+ url.append(server);
+
+ if ((scheme.equals("http") && (port != 80))
+ || (scheme.equals("https") && (port != 443))) {
+ url.append(':');
+ url.append(port);
+ }
+
+ return url;
+ }
+
+ /**
+ * <p>Return <code>StringBuffer</code> representing the scheme, server,
+ * and port number of the current request.</p>
+ *
+ * @param scheme The scheme name to use
+ * @param server The server name to use
+ * @param port The port value to use
+ * @param uri The uri value to use
+ * @return StringBuffer in the form scheme: server: port
+ * @since Struts 1.2.0
+ */
+ public static StringBuffer createServerUriStringBuffer(String scheme,
+ String server, int port, String uri) {
+ StringBuffer serverUri = createServerStringBuffer(scheme, server, port);
+
+ serverUri.append(uri);
+
+ return serverUri;
+ }
+
+ /**
+ * <p>Returns the true path of the destination action if the specified forward
+ * is an action-aliased URL. This method version forms the URL based on
+ * the current request; selecting the current module if the forward does not
+ * explicitly contain a module path.</p>
+ *
+ * @param forward the forward config
+ * @param request the current request
+ * @param servlet the servlet handling the current request
+ * @return the context-relative URL of the action if the forward has an action identifier; otherwise <code>null</code>.
+ * @since Struts 1.3.6
+ */
+ public static String actionIdURL(ForwardConfig forward, HttpServletRequest request, ActionServlet servlet) {
+ ModuleConfig moduleConfig = null;
+ if (forward.getModule() != null) {
+ String prefix = forward.getModule();
+ moduleConfig = ModuleUtils.getInstance().getModuleConfig(prefix, servlet.getServletContext());
+ } else {
+ moduleConfig = ModuleUtils.getInstance().getModuleConfig(request);
+ }
+ return actionIdURL(forward.getPath(), moduleConfig, servlet);
+ }
+
+ /**
+ * <p>Returns the true path of the destination action if the specified forward
+ * is an action-aliased URL. This method version forms the URL based on
+ * the specified module.
+ *
+ * @param originalPath the action-aliased path
+ * @param moduleConfig the module config for this request
+ * @param servlet the servlet handling the current request
+ * @return the context-relative URL of the action if the path has an action identifier; otherwise <code>null</code>.
+ * @since Struts 1.3.6
+ */
+ public static String actionIdURL(String originalPath, ModuleConfig moduleConfig, ActionServlet servlet) {
+ if (originalPath.startsWith("http") || originalPath.startsWith("/")) {
+ return null;
+ }
+
+ // Split the forward path into the resource and query string;
+ // it is possible a forward (or redirect) has added parameters.
+ String actionId = null;
+ String qs = null;
+ int qpos = originalPath.indexOf("?");
+ if (qpos == -1) {
+ actionId = originalPath;
+ } else {
+ actionId = originalPath.substring(0, qpos);
+ qs = originalPath.substring(qpos);
+ }
+
+ // Find the action of the given actionId
+ ActionConfig actionConfig = moduleConfig.findActionConfigId(actionId);
+ if (actionConfig == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("No actionId found for " + actionId);
+ }
+ return null;
+ }
+
+ String path = actionConfig.getPath();
+ String mapping = RequestUtils.getServletMapping(servlet);
+ StringBuffer actionIdPath = new StringBuffer();
+
+ // Form the path based on the servlet mapping pattern
+ if (mapping.startsWith("*")) {
+ actionIdPath.append(path);
+ actionIdPath.append(mapping.substring(1));
+ } else if (mapping.startsWith("/")) { // implied ends with a *
+ mapping = mapping.substring(0, mapping.length() - 1);
+ if (mapping.endsWith("/") && path.startsWith("/")) {
+ actionIdPath.append(mapping);
+ actionIdPath.append(path.substring(1));
+ } else {
+ actionIdPath.append(mapping);
+ actionIdPath.append(path);
+ }
+ } else {
+ log.warn("Unknown servlet mapping pattern");
+ actionIdPath.append(path);
+ }
+
+ // Lastly add any query parameters (the ? is part of the query string)
+ if (qs != null) {
+ actionIdPath.append(qs);
+ }
+
+ // Return the path
+ if (log.isDebugEnabled()) {
+ log.debug(originalPath + " unaliased to " + actionIdPath.toString());
+ }
+ return actionIdPath.toString();
+ }
+
+ /**
+ * Determines whether the current request is forwarded.
+ *
+ * @param request current HTTP request
+ * @return true if the request is forwarded; otherwise false
+ * @since Struts 1.4
+ */
+ public static boolean isRequestForwarded(HttpServletRequest request) {
+ return (request.getAttribute("javax.servlet.forward.request_uri") != null);
+ }
+
+ /**
+ * Determines whether the current request is included.
+ *
+ * @param request current HTTP request
+ * @return true if the request is included; otherwise false
+ * @since Struts 1.4
+ */
+ public static boolean isRequestIncluded(HttpServletRequest request) {
+ return (request.getAttribute("javax.servlet.include.request_uri") != null);
+ }
+
+ /**
+ * Verifies whether current request is forwarded from one action to
+ * another or not.
+ *
+ * @param request current HTTP request
+ * @return true if the request is chained; otherwise false
+ * @since Struts 1.4
+ */
+ public static boolean isRequestChained(HttpServletRequest request) {
+ return (request.getAttribute(Globals.CHAIN_KEY) != null);
+ }
+}