Skip to content
Permalink
Browse files

Improved: Refactor ‘UtilHttp#makeParamValueFromComposite’

(OFBIZ-11138)

Use ‘LocalDateTime’ instead of ‘Calendar’ and
‘HttpServletRequest#getParameterMap’ instead of
‘HttpServletRequest#getParameterNames’.

The tests and callers has been adapted to remove the ‘locale’ arguments which
made sense only for ‘Calendar’.


git-svn-id: https://svn.apache.org/repos/asf/ofbiz/ofbiz-framework/trunk@1863439 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
mthl committed Jul 19, 2019
1 parent 479c16d commit 1720a2ff622376933cdffd10dfa48dcdbc49f0ff
@@ -36,6 +36,7 @@
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -54,6 +55,7 @@
import java.util.TimeZone;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
@@ -77,8 +79,6 @@
import org.apache.ofbiz.webapp.event.FileUploadProgressListener;
import org.apache.ofbiz.widget.renderer.VisualTheme;

import com.ibm.icu.util.Calendar;

/**
* HttpUtil - Misc HTTP Utility Functions
*/
@@ -91,7 +91,6 @@
private static final String COMPOSITE_DELIMITER = "_c_";
private static final int MULTI_ROW_DELIMITER_LENGTH = MULTI_ROW_DELIMITER.length();
private static final int ROW_SUBMIT_PREFIX_LENGTH = ROW_SUBMIT_PREFIX.length();
private static final int COMPOSITE_DELIMITER_LENGTH = COMPOSITE_DELIMITER.length();

private static final String SESSION_KEY_TIMEZONE = "timeZone";
private static final String SESSION_KEY_THEME = "visualTheme";
@@ -1371,86 +1370,65 @@ public static String makeCompositeParam(String prefix, String 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,
*
* Assembles a composite object from a set of parameters identified by a common prefix.
* <p>
* For example, consider the following form widget field:
* <pre>
* {@code
* <field name="meetingDate">
* <date-time type="timestamp" input-method="time-dropdown">
* </field>
* }
* </pre>
* The HTML result is three input boxes to input the date, hour and minutes separately.
* The parameter names are named {@code meetingDate_c_date}, {@code meetingDate_c_hour},
* {@code meetingDate_c_minutes}. Additionally, there will be a field named {@code meetingDate_c_compositeType}
* with a value of "Timestamp". where "_c_" is the {@link #COMPOSITE_DELIMITER}. These parameters will then be
* re-composed into a Timestamp object from the composite fields.
*
* 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.
* @param request the HTTP request containing the parameters
* @param prefix the string identifying the set of parameters that must be composed
* @return a composite object from data or {@code null} if not supported or a parsing error occurred.
*/
public static Object makeParamValueFromComposite(HttpServletRequest request, String prefix, Locale locale) {
public static Object makeParamValueFromComposite(HttpServletRequest request, String prefix) {
String compositeType = request.getParameter(makeCompositeParam(prefix, "compositeType"));
if (UtilValidate.isEmpty(compositeType)) {
return null;
}
// Collect the components.
String prefixDelim = prefix + COMPOSITE_DELIMITER;
Map<String, String> data = request.getParameterMap().entrySet().stream()
.filter(e -> e.getKey().startsWith(prefixDelim))
.collect(Collectors.toMap(
e -> e.getKey().substring(prefixDelim.length()),
e -> e.getValue()[0]));

// collect the composite fields into a map
Map<String, String> data = new HashMap<>();
request.getParameterMap().forEach((name, values) -> {
if (!name.startsWith(prefix + COMPOSITE_DELIMITER)) {
return;
}
// 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 = values[0];

// key = suffix, value = parameter data
data.put(suffix, value);
});
if (Debug.verboseOn()) { Debug.logVerbose("Creating composite type with parameter data: " + data.toString(), module); }
if (Debug.verboseOn()) {
Debug.logVerbose("Creating composite type with parameter data: " + data.toString(), module);
}

// handle recomposition of data into the compositeType
// Assemble the composite data from the components
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)) {
if (date == null || date.length() < 10 || UtilValidate.isEmpty(hour) || UtilValidate.isEmpty(minutes)) {
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);
Timestamp ts = Timestamp.valueOf(date.substring(0, 10) + " 00:00:00.000");
if (UtilValidate.isNotEmpty(ampm)) {
boolean isAM = "AM".equals(ampm);
if (isAM && h == 12) {
h = 0;
}
if (!isAM && h < 12) {
} else 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());
LocalDateTime ldt = ts.toLocalDateTime().withHour(h).withMinute(Integer.parseInt(minutes));
return Timestamp.valueOf(ldt);
} catch (IllegalArgumentException e) {
Debug.logWarning("User input for composite timestamp was invalid: " + e.getMessage(), module);
return null;
@@ -30,7 +30,6 @@
import java.time.Month;
import java.util.Arrays;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.function.Predicate;

@@ -135,7 +134,7 @@ public void basicMakeParamValueFromComposite() {
"meetingDate_c_date", new String[] {"2019-07-14"},
"meetingDate_c_hour", new String[] {"13"},
"meetingDate_c_minutes", new String[] {"8"}));
assertThat(UtilHttp.makeParamValueFromComposite(req, "meetingDate", Locale.ROOT),
assertThat(UtilHttp.makeParamValueFromComposite(req, "meetingDate"),
equalTo(Timestamp.valueOf(LocalDateTime.of(2019, Month.JULY, 14, 13, 8))));
}

@@ -146,7 +145,7 @@ public void emptyTypeMakeParamValueFromComposite() {
"meetingDate_c_date", new String[] {"2019-07-14"},
"meetingDate_c_hour", new String[] {"13"},
"meetingDate_c_minutes", new String[] {"8"}));
assertNull(UtilHttp.makeParamValueFromComposite(req, "meetingDate", Locale.ROOT));
assertNull(UtilHttp.makeParamValueFromComposite(req, "meetingDate"));
}

@Test
@@ -158,23 +157,23 @@ public void ampmMakeParamValueFromComposite() {
"meetingDate_c_hour", new String[] {"12"},
"meetingDate_c_minutes", new String[] {"8"},
"meetingDate_c_ampm", new String[] {"AM"}));
assertThat(UtilHttp.makeParamValueFromComposite(req, "meetingDate", Locale.ROOT),
assertThat(UtilHttp.makeParamValueFromComposite(req, "meetingDate"),
equalTo(Timestamp.valueOf(LocalDateTime.of(2019, Month.JULY, 14, 0, 8))));

when(req.getParameterMap()).thenReturn(UtilMisc.toMap(
"meetingDate_c_date", new String[] {"2019-07-14"},
"meetingDate_c_hour", new String[] {"8"},
"meetingDate_c_minutes", new String[] {"8"},
"meetingDate_c_ampm", new String[] {"PM"}));
assertThat(UtilHttp.makeParamValueFromComposite(req, "meetingDate", Locale.ROOT),
assertThat(UtilHttp.makeParamValueFromComposite(req, "meetingDate"),
equalTo(Timestamp.valueOf(LocalDateTime.of(2019, Month.JULY, 14, 20, 8))));

when(req.getParameterMap()).thenReturn(UtilMisc.toMap(
"meetingDate_c_date", new String[] {"2019-07-14"},
"meetingDate_c_hour", new String[] {"18"},
"meetingDate_c_minutes", new String[] {"8"},
"meetingDate_c_ampm", new String[] {"PM"}));
assertThat(UtilHttp.makeParamValueFromComposite(req, "meetingDate", Locale.ROOT),
assertThat(UtilHttp.makeParamValueFromComposite(req, "meetingDate"),
equalTo(Timestamp.valueOf(LocalDateTime.of(2019, Month.JULY, 14, 18, 8))));
}
}
@@ -171,7 +171,7 @@ public String invoke(Event event, RequestMap requestMap, HttpServletRequest requ

// make any composite parameter data (e.g., from a set of parameters {name_c_date, name_c_hour, name_c_minutes})
if (value == null) {
value = UtilHttp.makeParamValueFromComposite(request, name, locale);
value = UtilHttp.makeParamValueFromComposite(request, name);
}
}

@@ -269,7 +269,7 @@ public String invoke(Event event, RequestMap requestMap, HttpServletRequest requ

// make any composite parameter data (e.g., from a set of parameters {name_c_date, name_c_hour, name_c_minutes})
if (value == null) {
value = UtilHttp.makeParamValueFromComposite(request, paramName + curSuffix, locale);
value = UtilHttp.makeParamValueFromComposite(request, paramName + curSuffix);
}

if (value == null) {

0 comments on commit 1720a2f

Please sign in to comment.
You can’t perform that action at this time.