| /******************************************************************************* |
| * 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.ofbiz.base.util; |
| |
| import java.io.BufferedInputStream; |
| import java.io.BufferedOutputStream; |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.net.FileNameMap; |
| import java.net.URLConnection; |
| import java.nio.ByteBuffer; |
| import java.sql.Timestamp; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Currency; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.StringTokenizer; |
| import java.util.TimeZone; |
| |
| import javax.servlet.ServletContext; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import javax.servlet.http.HttpSession; |
| |
| import org.apache.commons.lang.RandomStringUtils; |
| import org.apache.oro.text.regex.MalformedPatternException; |
| import org.apache.oro.text.regex.Pattern; |
| import org.apache.oro.text.regex.PatternMatcher; |
| import org.apache.oro.text.regex.Perl5Matcher; |
| import org.owasp.esapi.errors.EncodingException; |
| import org.owasp.esapi.errors.IntrusionException; |
| |
| import com.ibm.icu.util.Calendar; |
| |
| /** |
| * HttpUtil - Misc HTTP Utility Functions |
| */ |
| public class UtilHttp { |
| |
| public static final String module = UtilHttp.class.getName(); |
| |
| public static final String MULTI_ROW_DELIMITER = "_o_"; |
| public static final String ROW_SUBMIT_PREFIX = "_rowSubmit_o_"; |
| public static final String COMPOSITE_DELIMITER = "_c_"; |
| public static final int MULTI_ROW_DELIMITER_LENGTH = MULTI_ROW_DELIMITER.length(); |
| public static final int ROW_SUBMIT_PREFIX_LENGTH = ROW_SUBMIT_PREFIX.length(); |
| public static final int COMPOSITE_DELIMITER_LENGTH = COMPOSITE_DELIMITER.length(); |
| |
| /** |
| * Create a combined map from servlet context, session, attributes and parameters |
| * @return The resulting Map |
| */ |
| public static Map<String, Object> getCombinedMap(HttpServletRequest request) { |
| return getCombinedMap(request, null); |
| } |
| |
| /** |
| * Create a combined map from servlet context, session, attributes and parameters |
| * -- this method will only use the skip names for session and servlet context attributes |
| * @return The resulting Map |
| */ |
| public static Map<String, Object> getCombinedMap(HttpServletRequest request, Set<? extends String> namesToSkip) { |
| Map<String, Object> combinedMap = new HashMap<String, Object>(); |
| combinedMap.putAll(getParameterMap(request)); // parameters override nothing |
| combinedMap.putAll(getServletContextMap(request, namesToSkip)); // bottom level application attributes |
| combinedMap.putAll(getSessionMap(request, namesToSkip)); // session overrides application |
| combinedMap.putAll(getAttributeMap(request)); // attributes trump them all |
| |
| return combinedMap; |
| } |
| |
| /** |
| * Create a map from a HttpServletRequest (parameters) object |
| * @return The resulting Map |
| */ |
| public static Map<String, Object> getParameterMap(HttpServletRequest request) { |
| return getParameterMap(request, null, null); |
| } |
| |
| public static Map<String, Object> getParameterMap(HttpServletRequest request, Set<? extends String> nameSet) { |
| return getParameterMap(request, nameSet, null); |
| } |
| |
| /** |
| * Create a map from a HttpServletRequest (parameters) object |
| * @param onlyIncludeOrSkip If true only include, if false skip, the named parameters in the nameSet. If this is null and nameSet is not null, default to skip. |
| * @return The resulting Map |
| */ |
| public static Map<String, Object> getParameterMap(HttpServletRequest request, Set<? extends String> nameSet, Boolean onlyIncludeOrSkip) { |
| boolean onlyIncludeOrSkipPrim = onlyIncludeOrSkip == null ? true : onlyIncludeOrSkip.booleanValue(); |
| Map<String, Object> paramMap = new HashMap<String, Object>(); |
| |
| // add all the actual HTTP request parameters |
| Enumeration<String> e = UtilGenerics.cast(request.getParameterNames()); |
| while (e.hasMoreElements()) { |
| String name = e.nextElement(); |
| if (nameSet != null && (onlyIncludeOrSkipPrim ^ nameSet.contains(name))) { |
| continue; |
| } |
| |
| Object value = null; |
| String[] paramArr = request.getParameterValues(name); |
| if (paramArr != null) { |
| if (paramArr.length > 1) { |
| value = Arrays.asList(paramArr); |
| } else { |
| value = paramArr[0]; |
| // does the same thing basically, nothing better about it as far as I can see: value = request.getParameter(name); |
| } |
| } |
| paramMap.put(name, value); |
| } |
| |
| paramMap.putAll(getPathInfoOnlyParameterMap(request, nameSet, onlyIncludeOrSkip)); |
| |
| if (paramMap.size() == 0) { |
| // nothing found in the parameters; maybe we read the stream instead |
| Map<String, Object> multiPartMap = UtilGenerics.checkMap(request.getAttribute("multiPartMap")); |
| if (UtilValidate.isNotEmpty(multiPartMap)) { |
| paramMap.putAll(multiPartMap); |
| } |
| } |
| |
| if (Debug.verboseOn()) { |
| Debug.logVerbose("Made Request Parameter Map with [" + paramMap.size() + "] Entries", module); |
| Debug.logVerbose("Request Parameter Map Entries: " + System.getProperty("line.separator") + UtilMisc.printMap(paramMap), module); |
| } |
| |
| return canonicalizeParameterMap(paramMap); |
| } |
| |
| public static Map<String, Object> getQueryStringOnlyParameterMap(String queryString) { |
| Map<String, Object> paramMap = new HashMap<String, Object>(); |
| if (UtilValidate.isNotEmpty(queryString)) { |
| StringTokenizer queryTokens = new StringTokenizer(queryString, "&"); |
| while (queryTokens.hasMoreTokens()) { |
| String token = queryTokens.nextToken(); |
| if (token.startsWith("amp;")) { |
| // this is most likely a split value that had an & in it, so don't consider this a name; note that some old code just stripped the "amp;" and went with it |
| //token = token.substring(4); |
| continue; |
| } |
| int equalsIndex = token.indexOf("="); |
| String name = token; |
| if (equalsIndex > 0) { |
| name = token.substring(0, equalsIndex); |
| paramMap.put(name, token.substring(equalsIndex + 1)); |
| } |
| } |
| } |
| return canonicalizeParameterMap(paramMap); |
| } |
| |
| public static Map<String, Object> getPathInfoOnlyParameterMap(HttpServletRequest request, Set<? extends String> nameSet, Boolean onlyIncludeOrSkip) { |
| return getPathInfoOnlyParameterMap(request.getPathInfo(), nameSet, onlyIncludeOrSkip); |
| } |
| |
| public static Map<String, Object> getPathInfoOnlyParameterMap(String pathInfoStr, Set<? extends String> nameSet, Boolean onlyIncludeOrSkip) { |
| boolean onlyIncludeOrSkipPrim = onlyIncludeOrSkip == null ? true : onlyIncludeOrSkip.booleanValue(); |
| Map<String, Object> paramMap = new HashMap<String, Object>(); |
| |
| // now add in all path info parameters /~name1=value1/~name2=value2/ |
| // note that if a parameter with a given name already exists it will be put into a list with all values |
| |
| if (UtilValidate.isNotEmpty(pathInfoStr)) { |
| // make sure string ends with a trailing '/' so we get all values |
| if (!pathInfoStr.endsWith("/")) pathInfoStr += "/"; |
| |
| int current = pathInfoStr.indexOf('/'); |
| int last = current; |
| while ((current = pathInfoStr.indexOf('/', last + 1)) != -1) { |
| String element = pathInfoStr.substring(last + 1, current); |
| last = current; |
| if (element.charAt(0) == '~' && element.indexOf('=') > -1) { |
| String name = element.substring(1, element.indexOf('=')); |
| if (nameSet != null && (onlyIncludeOrSkipPrim ^ nameSet.contains(name))) { |
| continue; |
| } |
| |
| String value = element.substring(element.indexOf('=') + 1); |
| Object curValue = paramMap.get(name); |
| if (curValue != null) { |
| List<String> paramList = null; |
| if (curValue instanceof List<?>) { |
| paramList = UtilGenerics.checkList(curValue); |
| paramList.add(value); |
| } else { |
| String paramString = (String) curValue; |
| paramList = new LinkedList<String>(); |
| paramList.add(paramString); |
| paramList.add(value); |
| } |
| paramMap.put(name, paramList); |
| } else { |
| paramMap.put(name, value); |
| } |
| } |
| } |
| } |
| |
| return canonicalizeParameterMap(paramMap); |
| } |
| |
| public static Map<String, Object> getUrlOnlyParameterMap(HttpServletRequest request) { |
| // NOTE: these have already been through canonicalizeParameterMap, so not doing it again here |
| Map<String, Object> paramMap = getQueryStringOnlyParameterMap(request.getQueryString()); |
| paramMap.putAll(getPathInfoOnlyParameterMap(request.getPathInfo(), null, null)); |
| return paramMap; |
| } |
| |
| public static Map<String, Object> canonicalizeParameterMap(Map<String, Object> paramMap) { |
| for (Map.Entry<String, Object> paramEntry: paramMap.entrySet()) { |
| if (paramEntry.getValue() instanceof String) { |
| paramEntry.setValue(canonicalizeParameter((String) paramEntry.getValue())); |
| } else if (paramEntry.getValue() instanceof Collection<?>) { |
| List<String> newList = new LinkedList<String>(); |
| for (String listEntry: UtilGenerics.<String>checkCollection(paramEntry.getValue())) { |
| newList.add(canonicalizeParameter(listEntry)); |
| } |
| paramEntry.setValue(newList); |
| } |
| } |
| return paramMap; |
| } |
| |
| public static String canonicalizeParameter(String paramValue) { |
| try { |
| String cannedStr = StringUtil.defaultWebEncoder.canonicalize(paramValue, StringUtil.esapiCanonicalizeStrict); |
| if (Debug.verboseOn()) Debug.logVerbose("Canonicalized parameter with " + (cannedStr.equals(paramValue) ? "no " : "") + "change: original [" + paramValue + "] canned [" + cannedStr + "]", module); |
| return cannedStr; |
| } catch (IntrusionException e) { |
| Debug.logError(e, "Error in canonicalize parameter value [" + paramValue + "]: " + e.toString(), module); |
| return paramValue; |
| } |
| } |
| |
| /** |
| * Create a map from a HttpRequest (attributes) object used in JSON requests |
| * @return The resulting Map |
| */ |
| public static Map<String, Object> getJSONAttributeMap(HttpServletRequest request) { |
| Map<String, Object> returnMap = new HashMap<String, Object>(); |
| Map<String, Object> attrMap = getAttributeMap(request); |
| for (Map.Entry<String, Object> entry : attrMap.entrySet()) { |
| String key = entry.getKey(); |
| Object val = entry.getValue(); |
| if (val instanceof java.sql.Timestamp) { |
| val = val.toString(); |
| } |
| if (val instanceof String || val instanceof Number || val instanceof Map<?, ?> || val instanceof List<?> || val instanceof Boolean) { |
| if (Debug.verboseOn()) Debug.logVerbose("Adding attribute to JSON output: " + key, module); |
| returnMap.put(key, val); |
| } |
| } |
| |
| return returnMap; |
| } |
| |
| /** |
| * Create a map from a HttpRequest (attributes) object |
| * @return The resulting Map |
| */ |
| public static Map<String, Object> getAttributeMap(HttpServletRequest request) { |
| return getAttributeMap(request, null); |
| } |
| |
| /** |
| * Create a map from a HttpRequest (attributes) object |
| * @return The resulting Map |
| */ |
| public static Map<String, Object> getAttributeMap(HttpServletRequest request, Set<? extends String> namesToSkip) { |
| Map<String, Object> attributeMap = new HashMap<String, Object>(); |
| |
| // look at all request attributes |
| Enumeration<String> requestAttrNames = UtilGenerics.cast(request.getAttributeNames()); |
| while (requestAttrNames.hasMoreElements()) { |
| String attrName = requestAttrNames.nextElement(); |
| if (namesToSkip != null && namesToSkip.contains(attrName)) |
| continue; |
| |
| Object attrValue = request.getAttribute(attrName); |
| attributeMap.put(attrName, attrValue); |
| } |
| |
| if (Debug.verboseOn()) { |
| Debug.logVerbose("Made Request Attribute Map with [" + attributeMap.size() + "] Entries", module); |
| Debug.logVerbose("Request Attribute Map Entries: " + System.getProperty("line.separator") + UtilMisc.printMap(attributeMap), module); |
| } |
| |
| return attributeMap; |
| } |
| |
| /** |
| * Create a map from a HttpSession object |
| * @return The resulting Map |
| */ |
| public static Map<String, Object> getSessionMap(HttpServletRequest request) { |
| return getSessionMap(request, null); |
| } |
| |
| /** |
| * Create a map from a HttpSession object |
| * @return The resulting Map |
| */ |
| public static Map<String, Object> getSessionMap(HttpServletRequest request, Set<? extends String> namesToSkip) { |
| Map<String, Object> sessionMap = new HashMap<String, Object>(); |
| HttpSession session = request.getSession(); |
| |
| // look at all the session attributes |
| Enumeration<String> sessionAttrNames = UtilGenerics.cast(session.getAttributeNames()); |
| while (sessionAttrNames.hasMoreElements()) { |
| String attrName = sessionAttrNames.nextElement(); |
| if (namesToSkip != null && namesToSkip.contains(attrName)) |
| continue; |
| |
| Object attrValue = session.getAttribute(attrName); |
| sessionMap.put(attrName, attrValue); |
| } |
| |
| if (Debug.verboseOn()) { |
| Debug.logVerbose("Made Session Attribute Map with [" + sessionMap.size() + "] Entries", module); |
| Debug.logVerbose("Session Attribute Map Entries: " + System.getProperty("line.separator") + UtilMisc.printMap(sessionMap), module); |
| } |
| |
| return sessionMap; |
| } |
| |
| /** |
| * Create a map from a ServletContext object |
| * @return The resulting Map |
| */ |
| public static Map<String, Object> getServletContextMap(HttpServletRequest request) { |
| return getServletContextMap(request, null); |
| } |
| |
| /** |
| * Create a map from a ServletContext object |
| * @return The resulting Map |
| */ |
| public static Map<String, Object> getServletContextMap(HttpServletRequest request, Set<? extends String> namesToSkip) { |
| Map<String, Object> servletCtxMap = new HashMap<String, Object>(); |
| |
| // look at all servlet context attributes |
| ServletContext servletContext = (ServletContext) request.getAttribute("servletContext"); |
| Enumeration<String> applicationAttrNames = UtilGenerics.cast(servletContext.getAttributeNames()); |
| while (applicationAttrNames.hasMoreElements()) { |
| String attrName = applicationAttrNames.nextElement(); |
| if (namesToSkip != null && namesToSkip.contains(attrName)) |
| continue; |
| |
| Object attrValue = servletContext.getAttribute(attrName); |
| servletCtxMap.put(attrName, attrValue); |
| } |
| |
| if (Debug.verboseOn()) { |
| Debug.logVerbose("Made ServletContext Attribute Map with [" + servletCtxMap.size() + "] Entries", module); |
| Debug.logVerbose("ServletContext Attribute Map Entries: " + System.getProperty("line.separator") + UtilMisc.printMap(servletCtxMap), module); |
| } |
| |
| return servletCtxMap; |
| } |
| |
| public static Map<String, Object> makeParamMapWithPrefix(HttpServletRequest request, String prefix, String suffix) { |
| return makeParamMapWithPrefix(request, null, prefix, suffix); |
| } |
| |
| public static Map<String, Object> makeParamMapWithPrefix(HttpServletRequest request, Map<String, ? extends Object> additionalFields, String prefix, String suffix) { |
| return makeParamMapWithPrefix(getParameterMap(request), additionalFields, prefix, suffix); |
| } |
| |
| public static Map<String, Object> makeParamMapWithPrefix(Map<String, ? extends Object> context, Map<String, ? extends Object> additionalFields, String prefix, String suffix) { |
| Map<String, Object> paramMap = new HashMap<String, Object>(); |
| for (Map.Entry<String, ? extends Object> entry: context.entrySet()) { |
| String parameterName = entry.getKey(); |
| if (parameterName.startsWith(prefix)) { |
| if (UtilValidate.isNotEmpty(suffix)) { |
| if (parameterName.endsWith(suffix)) { |
| String key = parameterName.substring(prefix.length(), parameterName.length() - (suffix.length())); |
| if (entry.getValue() instanceof ByteBuffer) { |
| ByteBuffer value = (ByteBuffer) entry.getValue(); |
| paramMap.put(key, value); |
| } else { |
| String value = (String) entry.getValue(); |
| paramMap.put(key, value); |
| } |
| } |
| } else { |
| String key = parameterName.substring(prefix.length()); |
| if (context.get(parameterName) instanceof ByteBuffer) { |
| ByteBuffer value = (ByteBuffer) entry.getValue(); |
| paramMap.put(key, value); |
| } else { |
| String value = (String) entry.getValue(); |
| paramMap.put(key, value); |
| } |
| } |
| } |
| } |
| if (additionalFields != null) { |
| for (Map.Entry<String, ? extends Object> entry: additionalFields.entrySet()) { |
| String fieldName = entry.getKey(); |
| if (fieldName.startsWith(prefix)) { |
| if (UtilValidate.isNotEmpty(suffix)) { |
| if (fieldName.endsWith(suffix)) { |
| String key = fieldName.substring(prefix.length(), fieldName.length() - (suffix.length() - 1)); |
| Object value = entry.getValue(); |
| paramMap.put(key, value); |
| |
| // check for image upload data |
| if (!(value instanceof String)) { |
| String nameKey = "_" + key + "_fileName"; |
| Object nameVal = additionalFields.get("_" + fieldName + "_fileName"); |
| if (nameVal != null) { |
| paramMap.put(nameKey, nameVal); |
| } |
| |
| String typeKey = "_" + key + "_contentType"; |
| Object typeVal = additionalFields.get("_" + fieldName + "_contentType"); |
| if (typeVal != null) { |
| paramMap.put(typeKey, typeVal); |
| } |
| |
| String sizeKey = "_" + key + "_size"; |
| Object sizeVal = additionalFields.get("_" + fieldName + "_size"); |
| if (sizeVal != null) { |
| paramMap.put(sizeKey, sizeVal); |
| } |
| } |
| } |
| } else { |
| String key = fieldName.substring(prefix.length()); |
| Object value = entry.getValue(); |
| paramMap.put(key, value); |
| |
| // check for image upload data |
| if (!(value instanceof String)) { |
| String nameKey = "_" + key + "_fileName"; |
| Object nameVal = additionalFields.get("_" + fieldName + "_fileName"); |
| if (nameVal != null) { |
| paramMap.put(nameKey, nameVal); |
| } |
| |
| String typeKey = "_" + key + "_contentType"; |
| Object typeVal = additionalFields.get("_" + fieldName + "_contentType"); |
| if (typeVal != null) { |
| paramMap.put(typeKey, typeVal); |
| } |
| |
| String sizeKey = "_" + key + "_size"; |
| Object sizeVal = additionalFields.get("_" + fieldName + "_size"); |
| if (sizeVal != null) { |
| paramMap.put(sizeKey, sizeVal); |
| } |
| } |
| } |
| } |
| } |
| } |
| return paramMap; |
| } |
| |
| public static List<Object> makeParamListWithSuffix(HttpServletRequest request, String suffix, String prefix) { |
| return makeParamListWithSuffix(request, null, suffix, prefix); |
| } |
| |
| public static List<Object> makeParamListWithSuffix(HttpServletRequest request, Map<String, ? extends Object> additionalFields, String suffix, String prefix) { |
| List<Object> paramList = new ArrayList<Object>(); |
| Enumeration<String> parameterNames = UtilGenerics.cast(request.getParameterNames()); |
| while (parameterNames.hasMoreElements()) { |
| String parameterName = parameterNames.nextElement(); |
| if (parameterName.endsWith(suffix)) { |
| if (UtilValidate.isNotEmpty(prefix)) { |
| if (parameterName.startsWith(prefix)) { |
| String value = request.getParameter(parameterName); |
| paramList.add(value); |
| } |
| } else { |
| String value = request.getParameter(parameterName); |
| paramList.add(value); |
| } |
| } |
| } |
| if (additionalFields != null) { |
| for (Map.Entry<String, ? extends Object> entry: additionalFields.entrySet()) { |
| String fieldName = entry.getKey(); |
| if (fieldName.endsWith(suffix)) { |
| if (UtilValidate.isNotEmpty(prefix)) { |
| if (fieldName.startsWith(prefix)) { |
| paramList.add(entry.getValue()); |
| } |
| } else { |
| paramList.add(entry.getValue()); |
| } |
| } |
| } |
| } |
| return paramList; |
| } |
| |
| /** |
| * Given a request, returns the application name or "root" if deployed on root |
| * @param request An HttpServletRequest to get the name info from |
| * @return String |
| */ |
| public static String getApplicationName(HttpServletRequest request) { |
| String appName = "root"; |
| if (request.getContextPath().length() > 1) { |
| appName = request.getContextPath().substring(1); |
| } |
| return appName; |
| } |
| |
| public static void setInitialRequestInfo(HttpServletRequest request) { |
| HttpSession session = request.getSession(); |
| if (UtilValidate.isNotEmpty(session.getAttribute("_WEBAPP_NAME_"))) { |
| // oops, info already in place... |
| return; |
| } |
| |
| String fullRequestUrl = getFullRequestUrl(request); |
| |
| session.setAttribute("_WEBAPP_NAME_", getApplicationName(request)); |
| session.setAttribute("_CLIENT_LOCALE_", request.getLocale()); |
| session.setAttribute("_CLIENT_REQUEST_", fullRequestUrl); |
| session.setAttribute("_CLIENT_USER_AGENT_", request.getHeader("User-Agent") != null ? request.getHeader("User-Agent") : ""); |
| session.setAttribute("_CLIENT_REFERER_", request.getHeader("Referer") != null ? request.getHeader("Referer") : ""); |
| |
| session.setAttribute("_CLIENT_FORWARDED_FOR_", request.getHeader("X-Forwarded-For")); |
| session.setAttribute("_CLIENT_REMOTE_ADDR_", request.getRemoteAddr()); |
| session.setAttribute("_CLIENT_REMOTE_HOST_", request.getRemoteHost()); |
| session.setAttribute("_CLIENT_REMOTE_USER_", request.getRemoteUser()); |
| } |
| |
| /** |
| * Put request parameters in request object as attributes. |
| * @param request |
| */ |
| public static void parametersToAttributes(HttpServletRequest request) { |
| java.util.Enumeration<String> e = UtilGenerics.cast(request.getParameterNames()); |
| while (e.hasMoreElements()) { |
| String name = e.nextElement(); |
| request.setAttribute(name, request.getParameter(name)); |
| } |
| } |
| |
| |
| private static StringBuilder prepareServerRootUrl(HttpServletRequest request) { |
| StringBuilder requestUrl = new StringBuilder(); |
| requestUrl.append(request.getScheme()); |
| requestUrl.append("://" + request.getServerName()); |
| if (request.getServerPort() != 80 && request.getServerPort() != 443) |
| requestUrl.append(":" + request.getServerPort()); |
| return requestUrl; |
| } |
| |
| public static String getServerRootUrl(HttpServletRequest request) { |
| return prepareServerRootUrl(request).toString(); |
| } |
| |
| public static String getFullRequestUrl(HttpServletRequest request) { |
| StringBuilder requestUrl = prepareServerRootUrl(request); |
| requestUrl.append(request.getRequestURI()); |
| if (request.getQueryString() != null) { |
| requestUrl.append("?" + request.getQueryString()); |
| } |
| return requestUrl.toString(); |
| } |
| |
| public static Locale getLocale(HttpServletRequest request, HttpSession session, Object appDefaultLocale) { |
| // check session first, should override all if anything set there |
| Object localeObject = session != null ? session.getAttribute("locale") : null; |
| |
| // next see if the userLogin has a value |
| if (localeObject == null) { |
| Map<?, ?> userLogin = (Map<?, ?>) session.getAttribute("userLogin"); |
| if (userLogin == null) { |
| userLogin = (Map<?,?>) session.getAttribute("autoUserLogin"); |
| } |
| |
| if (userLogin != null) { |
| localeObject = userLogin.get("lastLocale"); |
| } |
| } |
| |
| // no user locale? before global default try appDefaultLocale if specified |
| if (localeObject == null && !UtilValidate.isEmpty(appDefaultLocale)) { |
| localeObject = appDefaultLocale; |
| } |
| |
| // finally request (w/ a fall back to default) |
| if (localeObject == null) { |
| localeObject = request != null ? request.getLocale() : null; |
| } |
| |
| return UtilMisc.ensureLocale(localeObject); |
| } |
| |
| /** |
| * Get the Locale object from a session variable; if not found use the browser's default |
| * @param request HttpServletRequest object to use for lookup |
| * @return Locale The current Locale to use |
| */ |
| public static Locale getLocale(HttpServletRequest request) { |
| if (request == null) return Locale.getDefault(); |
| return getLocale(request, request.getSession(), null); |
| } |
| |
| /** |
| * Get the Locale object from a session variable; if not found use the system's default. |
| * NOTE: This method is not recommended because it ignores the Locale from the browser not having the request object. |
| * @param session HttpSession object to use for lookup |
| * @return Locale The current Locale to use |
| */ |
| public static Locale getLocale(HttpSession session) { |
| if (session == null) return Locale.getDefault(); |
| return getLocale(null, session, null); |
| } |
| |
| public static void setLocale(HttpServletRequest request, String localeString) { |
| setLocale(request.getSession(), UtilMisc.parseLocale(localeString)); |
| } |
| |
| public static void setLocale(HttpSession session, Locale locale) { |
| session.setAttribute("locale", locale); |
| } |
| |
| public static void setLocaleIfNone(HttpSession session, String localeString) { |
| if (UtilValidate.isNotEmpty(localeString) && session.getAttribute("locale") == null) { |
| setLocale(session, UtilMisc.parseLocale(localeString)); |
| } |
| } |
| |
| public static void setTimeZone(HttpServletRequest request, String tzId) { |
| setTimeZone(request.getSession(), UtilDateTime.toTimeZone(tzId)); |
| } |
| |
| public static void setTimeZone(HttpSession session, TimeZone timeZone) { |
| session.setAttribute("timeZone", timeZone); |
| } |
| |
| public static TimeZone getTimeZone(HttpServletRequest request) { |
| HttpSession session = request.getSession(); |
| TimeZone timeZone = null; |
| Map<String, String> userLogin = UtilGenerics.cast(session.getAttribute("userLogin")); |
| if (userLogin != null) { |
| String tzId = userLogin.get("lastTimeZone"); |
| if (tzId != null) { |
| timeZone = TimeZone.getTimeZone(tzId); |
| } |
| } |
| if (timeZone == null) { |
| timeZone = TimeZone.getDefault(); |
| } |
| session.setAttribute("timeZone", timeZone); |
| return timeZone; |
| } |
| |
| |
| /** |
| * Get the currency string from the session. |
| * @param session HttpSession object to use for lookup |
| * @return String The ISO currency code |
| */ |
| public static String getCurrencyUom(HttpSession session, String appDefaultCurrencyUom) { |
| // session, should override all if set there |
| String iso = (String) session.getAttribute("currencyUom"); |
| |
| // check userLogin next, ie if nothing to override in the session |
| if (iso == null) { |
| Map<String, ?> userLogin = UtilGenerics.cast(session.getAttribute("userLogin")); |
| if (userLogin == null) { |
| userLogin = UtilGenerics.cast(session.getAttribute("autoUserLogin")); |
| } |
| |
| if (userLogin != null) { |
| iso = (String) userLogin.get("lastCurrencyUom"); |
| } |
| } |
| |
| // no user currency? before global default try appDefaultCurrencyUom if specified |
| if (iso == null && !UtilValidate.isEmpty(appDefaultCurrencyUom)) { |
| iso = appDefaultCurrencyUom; |
| } |
| |
| // if none is set we will use the configured default |
| if (iso == null) { |
| try { |
| iso = UtilProperties.getPropertyValue("general", "currency.uom.id.default", "USD"); |
| } catch (Exception e) { |
| Debug.logWarning("Error getting the general:currency.uom.id.default value: " + e.toString(), module); |
| } |
| } |
| |
| |
| // if still none we will use the default for whatever locale we can get... |
| if (iso == null) { |
| Currency cur = Currency.getInstance(getLocale(session)); |
| iso = cur.getCurrencyCode(); |
| } |
| |
| return iso; |
| } |
| |
| /** |
| * Get the currency string from the session. |
| * @param request HttpServletRequest object to use for lookup |
| * @return String The ISO currency code |
| */ |
| public static String getCurrencyUom(HttpServletRequest request) { |
| return getCurrencyUom(request.getSession(), null); |
| } |
| |
| /** Simple event to set the users per-session currency uom value */ |
| public static void setCurrencyUom(HttpSession session, String currencyUom) { |
| session.setAttribute("currencyUom", currencyUom); |
| } |
| |
| public static void setCurrencyUomIfNone(HttpSession session, String currencyUom) { |
| if (UtilValidate.isNotEmpty(currencyUom) && session.getAttribute("currencyUom") == null) { |
| session.setAttribute("currencyUom", currencyUom); |
| } |
| } |
| |
| /** URL Encodes a Map of arguements */ |
| public static String urlEncodeArgs(Map<String, ? extends Object> args) { |
| return urlEncodeArgs(args, true); |
| } |
| |
| /** URL Encodes a Map of arguements */ |
| public static String urlEncodeArgs(Map<String, ? extends Object> args, boolean useExpandedEntites) { |
| StringBuilder buf = new StringBuilder(); |
| if (args != null) { |
| for (Map.Entry<String, ? extends Object> entry: args.entrySet()) { |
| String name = entry.getKey(); |
| Object value = entry.getValue(); |
| String valueStr = null; |
| if (name == null || value == null) { |
| continue; |
| } |
| |
| Collection<?> col; |
| if (value instanceof String) { |
| col = Arrays.asList(value); |
| } else if (value instanceof Collection) { |
| col = UtilGenerics.cast(value); |
| } else if (value.getClass().isArray()) { |
| col = Arrays.asList((Object[]) value); |
| } else { |
| col = Arrays.asList(value); |
| } |
| for (Object colValue: col) { |
| if (colValue instanceof String) { |
| valueStr = (String) colValue; |
| } else if (colValue == null) { |
| continue; |
| } else { |
| valueStr = colValue.toString(); |
| } |
| |
| if (UtilValidate.isNotEmpty(valueStr)) { |
| if (buf.length() > 0) { |
| if (useExpandedEntites) { |
| buf.append("&"); |
| } else { |
| buf.append("&"); |
| } |
| } |
| try { |
| buf.append(StringUtil.defaultWebEncoder.encodeForURL(name)); |
| } catch (EncodingException e) { |
| Debug.logError(e, module); |
| } |
| /* the old way: try { |
| buf.append(URLEncoder.encode(name, "UTF-8")); |
| } catch (UnsupportedEncodingException e) { |
| Debug.logError(e, module); |
| } */ |
| buf.append('='); |
| try { |
| buf.append(StringUtil.defaultWebEncoder.encodeForURL(valueStr)); |
| } catch (EncodingException e) { |
| Debug.logError(e, module); |
| } |
| /* the old way: try { |
| buf.append(URLEncoder.encode(valueStr, "UTF-8")); |
| } catch (UnsupportedEncodingException e) { |
| Debug.logError(e, module); |
| } */ |
| } |
| } |
| } |
| } |
| return buf.toString(); |
| } |
| |
| public static String getRequestUriFromTarget(String target) { |
| if (UtilValidate.isEmpty(target)) return null; |
| int endOfRequestUri = target.length(); |
| if (target.indexOf('?') > 0) { |
| endOfRequestUri = target.indexOf('?'); |
| } |
| int slashBeforeRequestUri = target.lastIndexOf('/', endOfRequestUri); |
| String requestUri = null; |
| if (slashBeforeRequestUri < 0) { |
| requestUri = target.substring(0, endOfRequestUri); |
| } else { |
| requestUri = target.substring(slashBeforeRequestUri, endOfRequestUri); |
| } |
| return requestUri; |
| } |
| |
| /** Returns the query string contained in a request target - basically everything |
| * after and including the ? character. |
| * @param target The request target |
| * @return The query string |
| */ |
| public static String getQueryStringFromTarget(String target) { |
| if (UtilValidate.isEmpty(target)) return ""; |
| int queryStart = target.indexOf('?'); |
| if (queryStart != -1) { |
| return target.substring(queryStart); |
| } |
| return ""; |
| } |
| |
| /** Removes the query string from a request target - basically everything |
| * after and including the ? character. |
| * @param target The request target |
| * @return The request target string |
| */ |
| public static String removeQueryStringFromTarget(String target) { |
| if (UtilValidate.isEmpty(target)) return null; |
| int queryStart = target.indexOf('?'); |
| if (queryStart < 0) { |
| return target; |
| } |
| return target.substring(0, queryStart); |
| } |
| |
| public static String getWebappMountPointFromTarget(String target) { |
| int firstChar = 0; |
| if (UtilValidate.isEmpty(target)) return null; |
| if (target.charAt(0) == '/') firstChar = 1; |
| int pathSep = target.indexOf('/', 1); |
| String webappMountPoint = null; |
| if (pathSep > 0) { |
| // if not then no good, supposed to be a inter-app, but there is no path sep! will do general search with null and treat like an intra-app |
| webappMountPoint = target.substring(firstChar, pathSep); |
| } |
| return webappMountPoint; |
| } |
| |
| public static String encodeAmpersands(String htmlString) { |
| StringBuilder htmlBuffer = new StringBuilder(htmlString); |
| int ampLoc = -1; |
| while ((ampLoc = htmlBuffer.indexOf("&", ampLoc + 1)) != -1) { |
| //NOTE: this should work fine, but if it doesn't could try making sure all characters between & and ; are letters, that would qualify as an entity |
| |
| // found ampersand, is it already and entity? if not change it to & |
| int semiLoc = htmlBuffer.indexOf(";", ampLoc); |
| if (semiLoc != -1) { |
| // found a semi colon, if it has another & or an = before it, don't count it as an entity, otherwise it may be an entity, so skip it |
| int eqLoc = htmlBuffer.indexOf("=", ampLoc); |
| int amp2Loc = htmlBuffer.indexOf("&", ampLoc + 1); |
| if ((eqLoc == -1 || eqLoc > semiLoc) && (amp2Loc == -1 || amp2Loc > semiLoc)) { |
| continue; |
| } |
| } |
| |
| // at this point not an entity, no substitute with a & |
| htmlBuffer.insert(ampLoc + 1, "amp;"); |
| } |
| return htmlBuffer.toString(); |
| } |
| |
| public static String encodeBlanks(String htmlString) { |
| return htmlString.replaceAll(" ", "%20"); |
| } |
| |
| public static String setResponseBrowserProxyNoCache(HttpServletRequest request, HttpServletResponse response) { |
| setResponseBrowserProxyNoCache(response); |
| return "success"; |
| } |
| |
| public static void setResponseBrowserProxyNoCache(HttpServletResponse response) { |
| long nowMillis = System.currentTimeMillis(); |
| response.setDateHeader("Expires", nowMillis); |
| response.setDateHeader("Last-Modified", nowMillis); // always modified |
| response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); // HTTP/1.1 |
| response.addHeader("Cache-Control", "post-check=0, pre-check=0, false"); |
| response.setHeader("Pragma", "no-cache"); // HTTP/1.0 |
| } |
| |
| public static String getContentTypeByFileName(String fileName) { |
| FileNameMap mime = URLConnection.getFileNameMap(); |
| return mime.getContentTypeFor(fileName); |
| } |
| |
| /** |
| * Stream an array of bytes to the browser |
| * This method will close the ServletOutputStream when finished |
| * |
| * @param response HttpServletResponse object to get OutputStream from |
| * @param bytes Byte array of content to stream |
| * @param contentType The content type to pass to the browser |
| * @param fileName the fileName to tell the browser we are downloading |
| * @throws IOException |
| */ |
| public static void streamContentToBrowser(HttpServletResponse response, byte[] bytes, String contentType, String fileName) throws IOException { |
| // tell the browser not the cache |
| setResponseBrowserProxyNoCache(response); |
| |
| // set the response info |
| response.setContentLength(bytes.length); |
| if (contentType != null) { |
| response.setContentType(contentType); |
| } |
| if (fileName != null) { |
| response.setHeader("Content-Disposition", "attachment;filename=" + fileName); |
| } |
| |
| // create the streams |
| OutputStream out = response.getOutputStream(); |
| InputStream in = new ByteArrayInputStream(bytes); |
| |
| // stream the content |
| try { |
| streamContent(out, in, bytes.length); |
| } catch (IOException e) { |
| in.close(); |
| out.close(); // should we close the ServletOutputStream on error?? |
| throw e; |
| } |
| |
| // close the input stream |
| in.close(); |
| |
| // close the servlet output stream |
| out.flush(); |
| out.close(); |
| } |
| |
| public static void streamContentToBrowser(HttpServletResponse response, byte[] bytes, String contentType) throws IOException { |
| streamContentToBrowser(response, bytes, contentType, null); |
| } |
| |
| /** |
| * Streams content from InputStream to the ServletOutputStream |
| * This method will close the ServletOutputStream when finished |
| * This method does not close the InputSteam passed |
| * |
| * @param response HttpServletResponse object to get OutputStream from |
| * @param in InputStream of the actual content |
| * @param length Size (in bytes) of the content |
| * @param contentType The content type to pass to the browser |
| * @throws IOException |
| */ |
| public static void streamContentToBrowser(HttpServletResponse response, InputStream in, int length, String contentType, String fileName) throws IOException { |
| // tell the browser not the cache |
| setResponseBrowserProxyNoCache(response); |
| |
| // set the response info |
| response.setContentLength(length); |
| if (contentType != null) { |
| response.setContentType(contentType); |
| } |
| if (fileName != null) { |
| response.setHeader("Content-Disposition", "attachment;filename=" + fileName); |
| } |
| |
| // stream the content |
| OutputStream out = response.getOutputStream(); |
| try { |
| streamContent(out, in, length); |
| } catch (IOException e) { |
| out.close(); |
| throw e; |
| } |
| |
| // close the servlet output stream |
| out.flush(); |
| out.close(); |
| } |
| |
| public static void streamContentToBrowser(HttpServletResponse response, InputStream in, int length, String contentType) throws IOException { |
| streamContentToBrowser(response, in, length, contentType, null); |
| } |
| |
| /** |
| * Stream binary content from InputStream to OutputStream |
| * This method does not close the streams passed |
| * |
| * @param out OutputStream content should go to |
| * @param in InputStream of the actual content |
| * @param length Size (in bytes) of the content |
| * @throws IOException |
| */ |
| public static void streamContent(OutputStream out, InputStream in, int length) throws IOException { |
| int bufferSize = 512; // same as the default buffer size; change as needed |
| |
| // make sure we have something to write to |
| if (out == null) { |
| throw new IOException("Attempt to write to null output stream"); |
| } |
| |
| // make sure we have something to read from |
| if (in == null) { |
| throw new IOException("Attempt to read from null input stream"); |
| } |
| |
| // make sure we have some content |
| if (length == 0) { |
| throw new IOException("Attempt to write 0 bytes of content to output stream"); |
| } |
| |
| // initialize the buffered streams |
| BufferedOutputStream bos = new BufferedOutputStream(out, bufferSize); |
| BufferedInputStream bis = new BufferedInputStream(in, bufferSize); |
| |
| byte[] buffer = new byte[length]; |
| int read = 0; |
| try { |
| while ((read = bis.read(buffer, 0, buffer.length)) != -1) { |
| bos.write(buffer, 0, read); |
| } |
| } catch (IOException e) { |
| Debug.logError(e, "Problem reading/writing buffers", module); |
| bis.close(); |
| bos.close(); |
| throw e; |
| } finally { |
| if (bis != null) { |
| bis.close(); |
| } |
| if (bos != null) { |
| bos.flush(); |
| bos.close(); |
| } |
| } |
| } |
| |
| public static String stripViewParamsFromQueryString(String queryString) { |
| return stripViewParamsFromQueryString(queryString, null); |
| } |
| |
| public static String stripViewParamsFromQueryString(String queryString, String paginatorNumber) { |
| Set<String> paramNames = new HashSet<String>(); |
| if (UtilValidate.isNotEmpty(paginatorNumber)) { |
| paginatorNumber = "_" + paginatorNumber; |
| } |
| paramNames.add("VIEW_INDEX" + paginatorNumber); |
| paramNames.add("VIEW_SIZE" + paginatorNumber); |
| paramNames.add("viewIndex" + paginatorNumber); |
| paramNames.add("viewSize" + paginatorNumber); |
| return stripNamedParamsFromQueryString(queryString, paramNames); |
| } |
| |
| public static String stripNamedParamsFromQueryString(String queryString, Collection<String> paramNames) { |
| String retStr = null; |
| if (UtilValidate.isNotEmpty(queryString)) { |
| StringTokenizer queryTokens = new StringTokenizer(queryString, "&"); |
| StringBuilder cleanQuery = new StringBuilder(); |
| while (queryTokens.hasMoreTokens()) { |
| String token = queryTokens.nextToken(); |
| if (token.startsWith("amp;")) { |
| token = token.substring(4); |
| } |
| int equalsIndex = token.indexOf("="); |
| String name = token; |
| if (equalsIndex > 0) { |
| name = token.substring(0, equalsIndex); |
| } |
| if (!paramNames.contains(name)) { |
| if (cleanQuery.length() > 0) { |
| cleanQuery.append("&"); |
| } |
| cleanQuery.append(token); |
| } |
| } |
| retStr = cleanQuery.toString(); |
| } |
| return retStr; |
| } |
| |
| /** |
| * Given multi form data with the ${param}_o_N notation, creates a Collection |
| * of Maps for the submitted rows. Each Map contains the key/value pairs |
| * of a particular row. The keys will be stripped of the _o_N suffix. |
| * There is an additionaly key "row" for each Map that holds the |
| * index of the row. |
| */ |
| public static Collection<Map<String, Object>> parseMultiFormData(Map<String, Object> parameters) { |
| Map<Integer, Map<String, Object>> rows = new HashMap<Integer, Map<String, Object>>(); // stores the rows keyed by row number |
| |
| // first loop through all the keys and create a hashmap for each ${ROW_SUBMIT_PREFIX}${N} = Y |
| for (String key: parameters.keySet()) { |
| // skip everything that is not ${ROW_SUBMIT_PREFIX}N |
| if (key == null || key.length() <= ROW_SUBMIT_PREFIX_LENGTH) continue; |
| if (key.indexOf(MULTI_ROW_DELIMITER) <= 0) continue; |
| if (!key.substring(0, ROW_SUBMIT_PREFIX_LENGTH).equals(ROW_SUBMIT_PREFIX)) continue; |
| if (!parameters.get(key).equals("Y")) continue; |
| |
| // decode the value of N and create a new map for it |
| Integer n = Integer.decode(key.substring(ROW_SUBMIT_PREFIX_LENGTH, key.length())); |
| Map<String, Object> m = new HashMap<String, Object>(); |
| m.put("row", n); // special "row" = N tuple |
| rows.put(n, m); // key it to N |
| } |
| |
| // next put all parameters with matching N in the right map |
| for (Map.Entry<String, Object> entry : parameters.entrySet()) { |
| String key = entry.getKey(); |
| // skip keys without DELIMITER and skip ROW_SUBMIT_PREFIX |
| if (key == null) continue; |
| int index = key.indexOf(MULTI_ROW_DELIMITER); |
| if (index <= 0) continue; |
| if (key.length() > ROW_SUBMIT_PREFIX_LENGTH && key.substring(0, ROW_SUBMIT_PREFIX_LENGTH).equals(ROW_SUBMIT_PREFIX)) continue; |
| |
| // get the map with index N |
| Integer n = Integer.decode(key.substring(index + MULTI_ROW_DELIMITER_LENGTH, key.length())); // N from ${param}${DELIMITER}${N} |
| Map<String, Object> map = rows.get(n); |
| if (map == null) continue; |
| |
| // get the key without the <DELIMITER>N suffix and store it and its value |
| String newKey = key.substring(0, index); |
| map.put(newKey, entry.getValue()); |
| } |
| // return only the values, which is the list of maps |
| return rows.values(); |
| } |
| |
| /** |
| * Returns a new map containing all the parameters from the input map except for the |
| * multi form parameters (usually named according to the ${param}_o_N notation). |
| */ |
| public static <V> Map<String, V> removeMultiFormParameters(Map<String, V> parameters) { |
| Map<String, V> filteredParameters = new HashMap<String, V>(); |
| for (Map.Entry<String, V> entry : parameters.entrySet()) { |
| String key = entry.getKey(); |
| if (key != null && (key.indexOf(MULTI_ROW_DELIMITER) != -1 || key.indexOf("_useRowSubmit") != -1 || key.indexOf("_rowCount") != -1)) { |
| continue; |
| } |
| |
| filteredParameters.put(key, entry.getValue()); |
| } |
| return filteredParameters; |
| } |
| |
| /** |
| * Utility to make a composite parameter from the given prefix and suffix. |
| * The prefix should be a regular paramter name such as meetingDate. The |
| * suffix is the composite field, such as the hour of the meeting. The |
| * result would be meetingDate_${COMPOSITE_DELIMITER}_hour. |
| * |
| * @param prefix |
| * @param suffix |
| * @return the composite parameter |
| */ |
| public static String makeCompositeParam(String prefix, String suffix) { |
| return prefix + COMPOSITE_DELIMITER + suffix; |
| } |
| |
| /** |
| * Given the prefix of a composite parameter, recomposes a single Object from |
| * the composite according to compositeType. For example, consider the following |
| * form widget field, |
| * |
| * <field name="meetingDate"> |
| * <date-time type="timestamp" input-method="time-dropdown"> |
| * </field> |
| * |
| * The result in HTML is three input boxes to input the date, hour and minutes separately. |
| * The parameter names are named meetingDate_c_date, meetingDate_c_hour, meetingDate_c_minutes. |
| * Additionally, there will be a field named meetingDate_c_compositeType with a value of "Timestamp". |
| * where _c_ is the COMPOSITE_DELIMITER. These parameters will then be recomposed into a Timestamp |
| * object from the composite fields. |
| * |
| * @param request |
| * @param prefix |
| * @return Composite object from data or null if not supported or a parsing error occurred. |
| */ |
| public static Object makeParamValueFromComposite(HttpServletRequest request, String prefix, Locale locale) { |
| String compositeType = request.getParameter(makeCompositeParam(prefix, "compositeType")); |
| if (UtilValidate.isEmpty(compositeType)) return null; |
| |
| // collect the composite fields into a map |
| Map<String, String> data = new HashMap<String, String>(); |
| for (Enumeration<String> names = UtilGenerics.cast(request.getParameterNames()); names.hasMoreElements();) { |
| String name = names.nextElement(); |
| if (!name.startsWith(prefix + COMPOSITE_DELIMITER)) continue; |
| |
| // extract the suffix of the composite name |
| String suffix = name.substring(name.indexOf(COMPOSITE_DELIMITER) + COMPOSITE_DELIMITER_LENGTH); |
| |
| // and the value of this parameter |
| String value = request.getParameter(name); |
| |
| // key = suffix, value = parameter data |
| data.put(suffix, value); |
| } |
| if (Debug.verboseOn()) { Debug.logVerbose("Creating composite type with parameter data: " + data.toString(), module); } |
| |
| // handle recomposition of data into the compositeType |
| if ("Timestamp".equals(compositeType)) { |
| String date = data.get("date"); |
| String hour = data.get("hour"); |
| String minutes = data.get("minutes"); |
| String ampm = data.get("ampm"); |
| if (date == null || date.length() < 10) return null; |
| if (UtilValidate.isEmpty(hour)) return null; |
| if (UtilValidate.isEmpty(minutes)) return null; |
| boolean isTwelveHour = UtilValidate.isNotEmpty(ampm); |
| |
| // create the timestamp from the data |
| try { |
| int h = Integer.parseInt(hour); |
| Timestamp timestamp = Timestamp.valueOf(date.substring(0, 10) + " 00:00:00.000"); |
| Calendar cal = Calendar.getInstance(locale); |
| cal.setTime(timestamp); |
| if (isTwelveHour) { |
| boolean isAM = ("AM".equals(ampm) ? true : false); |
| if (isAM && h == 12) h = 0; |
| if (!isAM && h < 12) h += 12; |
| } |
| cal.set(Calendar.HOUR_OF_DAY, h); |
| cal.set(Calendar.MINUTE, Integer.parseInt(minutes)); |
| return new Timestamp(cal.getTimeInMillis()); |
| } catch (IllegalArgumentException e) { |
| Debug.logWarning("User input for composite timestamp was invalid: " + e.getMessage(), module); |
| return null; |
| } |
| } |
| |
| // we don't support any other compositeTypes (yet) |
| return null; |
| } |
| |
| /** Obtains the session ID from the request, or "unknown" if no session pressent. */ |
| public static String getSessionId(HttpServletRequest request) { |
| HttpSession session = request.getSession(); |
| return (session == null ? "unknown" : session.getId()); |
| } |
| /** |
| * checks, if the current request comes from a searchbot |
| * |
| * @param request |
| * @return whether the request is from a web searchbot |
| */ |
| public static boolean checkURLforSpiders(HttpServletRequest request) { |
| boolean result = false; |
| |
| String spiderRequest = (String) request.getAttribute("_REQUEST_FROM_SPIDER_"); |
| if (UtilValidate.isNotEmpty(spiderRequest)) { |
| if ("Y".equals(spiderRequest)) { |
| return true; |
| } else { |
| return false; |
| } |
| } else { |
| String initialUserAgent = request.getHeader("User-Agent") != null ? request.getHeader("User-Agent") : ""; |
| List<String> spiderList = StringUtil.split(UtilProperties.getPropertyValue("url", "link.remove_lsessionid.user_agent_list"), ","); |
| |
| if (UtilValidate.isNotEmpty(spiderList)) { |
| for (String spiderNameElement : spiderList) { |
| Pattern pattern = null; |
| try { |
| pattern = PatternFactory.createOrGetPerl5CompiledPattern(spiderNameElement, false); |
| } catch (MalformedPatternException e) { |
| Debug.logError(e, module); |
| } |
| PatternMatcher matcher = new Perl5Matcher(); |
| if (matcher.contains(initialUserAgent, pattern)) { |
| request.setAttribute("_REQUEST_FROM_SPIDER_", "Y"); |
| result = true; |
| break; |
| } |
| } |
| } |
| } |
| |
| if (!result) { |
| request.setAttribute("_REQUEST_FROM_SPIDER_", "N"); |
| } |
| |
| return result; |
| } |
| |
| /** Returns true if the user has JavaScript enabled. |
| * @param request |
| * @return whether javascript is enabled |
| */ |
| public static boolean isJavaScriptEnabled(HttpServletRequest request) { |
| HttpSession session = request.getSession(); |
| Boolean javaScriptEnabled = (Boolean) session.getAttribute("javaScriptEnabled"); |
| if (javaScriptEnabled != null) { |
| return javaScriptEnabled.booleanValue(); |
| } |
| return false; |
| } |
| |
| /** Returns the number or rows submitted by a multi form. |
| */ |
| public static int getMultiFormRowCount(HttpServletRequest request) { |
| return getMultiFormRowCount(getParameterMap(request)); |
| } |
| /** Returns the number or rows submitted by a multi form. |
| */ |
| public static int getMultiFormRowCount(Map<String, ?> requestMap) { |
| // The number of multi form rows is computed selecting the maximum index |
| int rowCount = 0; |
| String maxRowIndex = ""; |
| int rowDelimiterLength = MULTI_ROW_DELIMITER.length(); |
| for (String parameterName: requestMap.keySet()) { |
| int rowDelimiterIndex = (parameterName != null? parameterName.indexOf(MULTI_ROW_DELIMITER): -1); |
| if (rowDelimiterIndex > 0) { |
| String thisRowIndex = parameterName.substring(rowDelimiterIndex + rowDelimiterLength); |
| if (thisRowIndex.indexOf("_") > -1) { |
| thisRowIndex = thisRowIndex.substring(0, thisRowIndex.indexOf("_")); |
| } |
| if (maxRowIndex.length() < thisRowIndex.length()) { |
| maxRowIndex = thisRowIndex; |
| } else if (maxRowIndex.length() == thisRowIndex.length() && maxRowIndex.compareTo(thisRowIndex) < 0) { |
| maxRowIndex = thisRowIndex; |
| } |
| } |
| } |
| if (UtilValidate.isNotEmpty(maxRowIndex)) { |
| try { |
| rowCount = Integer.parseInt(maxRowIndex); |
| rowCount++; // row indexes are zero based |
| } catch (NumberFormatException e) { |
| Debug.logWarning("Invalid value for row index found: " + maxRowIndex, module); |
| } |
| } |
| return rowCount; |
| } |
| |
| public static String stashParameterMap(HttpServletRequest request) { |
| HttpSession session = request.getSession(); |
| Map<String, Map<String, Object>> paramMapStore = UtilGenerics.checkMap(session.getAttribute("_PARAM_MAP_STORE_")); |
| if (paramMapStore == null) { |
| paramMapStore = new HashMap<String, Map<String, Object>>(); |
| session.setAttribute("_PARAM_MAP_STORE_", paramMapStore); |
| } |
| Map<String, Object> parameters = getParameterMap(request); |
| String paramMapId = RandomStringUtils.randomAlphanumeric(10); |
| paramMapStore.put(paramMapId, parameters); |
| return paramMapId; |
| } |
| |
| public static void restoreStashedParameterMap(HttpServletRequest request, String paramMapId) { |
| HttpSession session = request.getSession(); |
| Map<String, Map<String, Object>> paramMapStore = UtilGenerics.checkMap(session.getAttribute("_PARAM_MAP_STORE_")); |
| if (paramMapStore != null) { |
| Map<String, Object> paramMap = paramMapStore.get(paramMapId); |
| if (paramMap != null) { |
| paramMapStore.remove(paramMapId); |
| for (Map.Entry<String, Object> paramEntry : paramMap.entrySet()) { |
| if (request.getAttribute(paramEntry.getKey()) != null) { |
| Debug.logWarning("Skipped loading parameter [" + paramEntry.getKey() + "] because it would have overwritten a request attribute" , module); |
| continue; |
| } |
| request.setAttribute(paramEntry.getKey(), paramEntry.getValue()); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Returns a unique Id for the current request |
| * @param request An HttpServletRequest to get the name info from |
| * @return String |
| */ |
| public static String getNextUniqueId(HttpServletRequest request) { |
| Integer uniqueIdNumber= (Integer)request.getAttribute("UNIQUE_ID"); |
| if (uniqueIdNumber == null) { |
| uniqueIdNumber = Integer.valueOf(1); |
| } |
| |
| request.setAttribute("UNIQUE_ID", Integer.valueOf(uniqueIdNumber.intValue() + 1)); |
| return "autoId_" + uniqueIdNumber; |
| } |
| } |