| /* |
| * 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.ofbiz.base.util; |
| |
| import java.math.BigDecimal; |
| import java.nio.charset.StandardCharsets; |
| import java.text.DateFormat; |
| import java.util.Base64; |
| import java.util.Date; |
| import java.util.Locale; |
| import java.util.TimeZone; |
| |
| import com.ibm.icu.text.DecimalFormat; |
| import org.apache.ofbiz.entity.Delegator; |
| import org.apache.ofbiz.entity.util.EntityUtilProperties; |
| |
| /** |
| * General output formatting functions - mainly for helping in JSPs |
| */ |
| public final class UtilFormatOut { |
| |
| private static final String MODULE = UtilFormatOut.class.getName(); |
| public static final String DEFAULT_FORMAT = "default"; |
| public static final String AMOUNT_FORMAT = "amount"; |
| public static final String QUANTITY_FORMAT = "quantity"; |
| public static final String PERCENTAGE_FORMAT = "percentage"; |
| public static final String SPELLED_OUT_FORMAT = "spelled-out"; |
| |
| private UtilFormatOut() { } |
| |
| public static String safeToString(Object obj) { |
| if (obj != null) { |
| return obj.toString(); |
| } |
| return ""; |
| } |
| |
| /** Format a number with format type define by properties |
| */ |
| public static String formatNumber(Double number, String formatType, Delegator delegator, Locale locale) { |
| if (number == null) { |
| return ""; |
| } |
| if (formatType == null) { |
| formatType = DEFAULT_FORMAT; |
| } |
| if (locale == null) { |
| locale = Locale.getDefault(); |
| } |
| |
| //lookup for known specific format |
| if (formatType.equals(SPELLED_OUT_FORMAT)) { |
| return formatSpelledOutAmount(number, locale); |
| } |
| |
| //Resolve template to use from formatType |
| String formatTypeKey = formatType + ".displaying.format"; |
| String template = delegator != null |
| ? EntityUtilProperties.getPropertyValue("number", formatTypeKey, delegator) |
| : UtilProperties.getPropertyValue("number", formatTypeKey); |
| if (UtilValidate.isEmpty(template)) { |
| Debug.logWarning("Number template not found for format " + formatType |
| + ", please check your property on number for " + formatTypeKey, MODULE); |
| template = delegator != null |
| ? EntityUtilProperties.getPropertyValue("number", "default.displaying.format", delegator) |
| : UtilProperties.getPropertyValue("number", "default.displaying.format"); |
| } |
| if (UtilValidate.isEmpty(template)) { |
| Debug.logWarning("Number template not found for default displaying.format" |
| + ", please check your property on number for default.displaying.format", MODULE); |
| template = "##0.00"; |
| } |
| |
| //With the template parse the number to display it |
| return formatDecimalNumber(number, template, locale); |
| } |
| |
| public static String formatNumber(BigDecimal number, String formatType, Delegator delegator, Locale locale) { |
| if (number == null) { |
| return ""; |
| } |
| return formatNumber(number.doubleValue(), formatType, delegator, locale); |
| } |
| |
| /** Formats a Double representing a price into a string |
| * @param price The price Double to be formatted |
| * @return A String with the formatted price |
| */ |
| @Deprecated |
| public static String formatPrice(Double price) { |
| return formatNumber(price, AMOUNT_FORMAT, null, null); |
| } |
| |
| /** Formats a BigDecimal representing a price into a string |
| * @param price The price BigDecimal to be formatted |
| * @return A String with the formatted price |
| */ |
| @Deprecated |
| public static String formatPrice(BigDecimal price) { |
| return formatNumber(price, AMOUNT_FORMAT, null, null); |
| } |
| |
| /** Formats a double into a properly formatted currency string based on isoCode and Locale |
| * @param price The price double to be formatted |
| * @param isoCode the currency ISO code |
| * @param locale The Locale used to format the number |
| * @param maximumFractionDigits The maximum number of fraction digits used; if set to -1 than the default value for the locale is used |
| * @return A String with the formatted price |
| */ |
| public static String formatCurrency(double price, String isoCode, Locale locale, int maximumFractionDigits) { |
| com.ibm.icu.text.NumberFormat nf = com.ibm.icu.text.NumberFormat.getCurrencyInstance(locale); |
| if (isoCode != null && isoCode.length() > 1) { |
| nf.setCurrency(com.ibm.icu.util.Currency.getInstance(isoCode)); |
| } else { |
| if (Debug.verboseOn()) { |
| Debug.logVerbose("No isoCode specified to format currency value:" + price, MODULE); |
| } |
| } |
| if (maximumFractionDigits >= 0) { |
| nf.setMaximumFractionDigits(maximumFractionDigits); |
| } |
| return nf.format(price); |
| } |
| |
| /** Formats a BigDecimal into a properly formatted currency string based on isoCode and Locale |
| * @param price The price BigDecimal to be formatted |
| * @param isoCode the currency ISO code |
| * @param locale The Locale used to format the number |
| * @param maximumFractionDigits The maximum number of fraction digits used; if set to -1 than the default value for the locale is used |
| * @return A String with the formatted price |
| */ |
| public static String formatCurrency(BigDecimal price, String isoCode, Locale locale, int maximumFractionDigits) { |
| return formatCurrency(price.doubleValue(), isoCode, locale, maximumFractionDigits); |
| } |
| |
| /** Format a decimal number to the pattern given |
| * @param number The price double to be formatted |
| * @param pattern pattern apply to format number |
| * @param locale The Locale used to format the number |
| * @return A String with the formatted price |
| */ |
| public static String formatDecimalNumber(double number, String pattern, Locale locale) { |
| DecimalFormat nf = (DecimalFormat) com.ibm.icu.text.NumberFormat.getNumberInstance(locale); |
| String nbParsing = ""; |
| nf.applyPattern(pattern); |
| nf.toPattern(); |
| nbParsing = nf.format(number); |
| return nbParsing; |
| } |
| |
| /** Formats a BigDecimal into a properly formatted currency string based on isoCode and Locale |
| * @param price The price BigDecimal to be formatted |
| * @param isoCode the currency ISO code |
| * @param locale The Locale used to format the number |
| * @return A String with the formatted price |
| */ |
| public static String formatCurrency(BigDecimal price, String isoCode, Locale locale) { |
| return formatCurrency(price, isoCode, locale, -1); |
| } |
| |
| /** Formats a Double into a properly spelled out number string based on Locale |
| * @param amount The amount Double to be formatted |
| * @param locale The Locale used to format the number |
| * @return A String with the formatted number |
| */ |
| public static String formatSpelledOutAmount(Double amount, Locale locale) { |
| com.ibm.icu.text.NumberFormat nf = new com.ibm.icu.text.RuleBasedNumberFormat(locale, com.ibm.icu.text.RuleBasedNumberFormat.SPELLOUT); |
| return nf.format(amount); |
| } |
| |
| /** Formats a double into a properly formatted string, with two decimals, based on Locale |
| * @param amount The amount double to be formatted |
| * @param locale The Locale used to format the number |
| * @return A String with the formatted amount |
| */ |
| // This method should be used in place of formatPrice because it is locale aware. |
| public static String formatAmount(double amount, Locale locale) { |
| return formatNumber(amount, AMOUNT_FORMAT, null, locale); |
| } |
| |
| /** Formats a Double representing a percentage into a string |
| * @param percentage The percentage Double to be formatted |
| * @return A String with the formatted percentage |
| */ |
| public static String formatPercentage(Double percentage) { |
| return formatNumber(percentage, PERCENTAGE_FORMAT, null, null); |
| } |
| |
| /** Formats a BigDecimal representing a percentage into a string |
| * @param percentage The percentage Decimal to be formatted |
| * @return A String with the formatted percentage |
| */ |
| public static String formatPercentage(BigDecimal percentage) { |
| return formatNumber(percentage, PERCENTAGE_FORMAT, null, null); |
| |
| } |
| |
| /** |
| * Formats a BigDecimal value 1:1 into a percentage string (e.g. 10 to 10% instead of 0,1 to 10%) |
| * @param percentage The percentage Decimal to be formatted |
| * @return A String with the formatted percentage |
| */ |
| public static String formatPercentageRate(BigDecimal percentage, boolean negate) { |
| if (percentage == null) { |
| return ""; |
| } |
| BigDecimal hundred = BigDecimal.valueOf(negate ? -100 : 100); |
| return formatNumber(percentage.divide(hundred), PERCENTAGE_FORMAT, null, null); |
| } |
| |
| /** Formats an Long representing a quantity into a string |
| * @param quantity The quantity Long to be formatted |
| * @return A String with the formatted quantity |
| */ |
| public static String formatQuantity(Long quantity) { |
| if (quantity == null) { |
| return ""; |
| } |
| return formatQuantity(quantity.doubleValue()); |
| } |
| |
| /** Formats an Integer representing a quantity into a string |
| * @param quantity The quantity Integer to be formatted |
| * @return A String with the formatted quantity |
| */ |
| public static String formatQuantity(Integer quantity) { |
| if (quantity == null) { |
| return ""; |
| } |
| return formatQuantity(quantity.doubleValue()); |
| } |
| |
| /** Formats a Float representing a quantity into a string |
| * @param quantity The quantity Float to be formatted |
| * @return A String with the formatted quantity |
| */ |
| public static String formatQuantity(Float quantity) { |
| if (quantity == null) { |
| return ""; |
| } |
| return formatQuantity(quantity.doubleValue()); |
| } |
| |
| /** Formats an Double representing a quantity into a string |
| * @param quantity The quantity Double to be formatted |
| * @return A String with the formatted quantity |
| */ |
| public static String formatQuantity(Double quantity) { |
| return formatNumber(quantity, QUANTITY_FORMAT, null, null); |
| } |
| |
| /** Formats an BigDecimal representing a quantity into a string |
| * @param quantity The quantity BigDecimal to be formatted |
| * @return A String with the formatted quantity |
| */ |
| public static String formatQuantity(BigDecimal quantity) { |
| return formatNumber(quantity, QUANTITY_FORMAT, null, null); |
| } |
| |
| public static String formatPaddedNumber(long number, int numericPadding) { |
| StringBuilder outStrBfr = new StringBuilder(Long.toString(number)); |
| while (numericPadding > outStrBfr.length()) { |
| outStrBfr.insert(0, '0'); |
| } |
| return outStrBfr.toString(); |
| } |
| |
| public static String formatPaddingRemove(String original) { |
| if (original == null) { |
| return null; |
| } |
| StringBuilder orgBuf = new StringBuilder(original); |
| while (orgBuf.length() > 0 && orgBuf.charAt(0) == '0') { |
| orgBuf.deleteCharAt(0); |
| } |
| return orgBuf.toString(); |
| } |
| |
| // ------------------- date handlers ------------------- |
| |
| /** Formats a <code>Timestamp</code> into a date-time <code>String</code> using the default locale and time zone. |
| * Returns an empty <code>String</code> if <code>timestamp</code> is <code>null</code>. |
| * @param timestamp The <code>Timestamp</code> to format |
| * @return A <code>String</code> with the formatted date/time, or an empty <code>String</code> if <code>timestamp</code> is <code>null</code> |
| */ |
| public static String formatDate(java.sql.Timestamp timestamp) { |
| if (timestamp == null) { |
| return ""; |
| } |
| DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.FULL); |
| java.util.Date date = timestamp; |
| return df.format(date); |
| } |
| |
| /** Formats a <code>Date</code> into a date-only <code>String</code> using the specified locale and time zone, |
| * or using the specified format. |
| * @param date The date to format |
| * @param dateTimeFormat Optional format string |
| * @param locale The format locale - can be <code>null</code> if <code>dateFormat</code> is not <code>null</code> |
| * @param timeZone The format time zone |
| * @return <code>date</code> formatted as a date-only <code>String</code> |
| * @throws NullPointerException if any required parameter is <code>null</code> |
| */ |
| public static String formatDate(Date date, String dateTimeFormat, Locale locale, TimeZone timeZone) { |
| return UtilDateTime.toDateFormat(dateTimeFormat, timeZone, locale).format(date); |
| } |
| |
| /** Formats a <code>Date</code> into a date-time <code>String</code> using the specified locale and time zone, |
| * or using the specified format. |
| * @param date The date to format |
| * @param dateTimeFormat Optional format string |
| * @param locale The format locale - can be <code>null</code> if <code>dateFormat</code> is not <code>null</code> |
| * @param timeZone The format time zone |
| * @return <code>date</code> formatted as a date-time <code>String</code> |
| * @throws NullPointerException if any required parameter is <code>null</code> |
| */ |
| public static String formatDateTime(Date date, String dateTimeFormat, Locale locale, TimeZone timeZone) { |
| return UtilDateTime.toDateTimeFormat(dateTimeFormat, timeZone, locale).format(date); |
| } |
| |
| // ------------------- null string handlers ------------------- |
| /** Checks to see if the passed Object is null, if it is returns an empty but non-null string, otherwise calls toString() on the object |
| * @param obj1 The passed Object |
| * @return The toString() of the passed Object if not null, otherwise an empty non-null String |
| */ |
| public static String makeString(Object obj1) { |
| if (obj1 != null) { |
| if (obj1 instanceof byte[]) { |
| byte[] data = (byte[]) obj1; |
| if (data.length > 5120) { |
| return "[...binary data]"; |
| } |
| return new String(Base64.getMimeEncoder().encode(data), StandardCharsets.UTF_8); |
| } |
| return obj1.toString(); |
| } |
| return ""; |
| } |
| |
| /** Checks to see if the passed string is null, if it is returns an empty but non-null string. |
| * @param string1 The passed String |
| * @return The passed String if not null, otherwise an empty non-null String |
| */ |
| public static String checkNull(String string1) { |
| if (string1 != null) { |
| return string1; |
| } |
| return ""; |
| } |
| |
| /** Returns the first passed String if not null, otherwise the second if not null, otherwise an empty but non-null String. |
| * @param string1 The first passed String |
| * @param string2 The second passed String |
| * @return The first passed String if not null, otherwise the second if not null, otherwise an empty but non-null String |
| */ |
| public static String checkNull(String string1, String string2) { |
| if (string1 != null) { |
| return string1; |
| } else if (string2 != null) { |
| return string2; |
| } else { |
| return ""; |
| } |
| } |
| |
| /** Returns the first passed String if not null, otherwise the second if not null, otherwise the third if not null, |
| * otherwise an empty but non-null String. |
| * @param string1 The first passed String |
| * @param string2 The second passed String |
| * @param string3 The third passed String |
| * @return The first passed String if not null, otherwise the second if not null, otherwise the third if not null, |
| * otherwise an empty but non-null String |
| */ |
| public static String checkNull(String string1, String string2, String string3) { |
| if (string1 != null) { |
| return string1; |
| } else if (string2 != null) { |
| return string2; |
| } else if (string3 != null) { |
| return string3; |
| } else { |
| return ""; |
| } |
| } |
| |
| /** Returns the first passed String if not null, otherwise the second if not null, otherwise the third if not null, |
| * otherwise the fourth if not null, otherwise an empty but non-null String. |
| * @param string1 The first passed String |
| * @param string2 The second passed String |
| * @param string3 The third passed String |
| * @param string4 The fourth passed String |
| * @return The first passed String if not null, otherwise the second if not null, otherwise the third if not null, |
| * otherwise the fourth if not null, otherwise an empty but non-null String |
| */ |
| public static String checkNull(String string1, String string2, String string3, String string4) { |
| if (string1 != null) { |
| return string1; |
| } else if (string2 != null) { |
| return string2; |
| } else if (string3 != null) { |
| return string3; |
| } else if (string4 != null) { |
| return string4; |
| } else { |
| return ""; |
| } |
| } |
| |
| /** Returns <code>pre + base + post</code> if base String is not null or empty, otherwise an empty but non-null String. |
| * @param base The base String |
| * @param pre The pre String |
| * @param post The post String |
| * @return <code>pre + base + post</code> if base String is not null or empty, otherwise an empty but non-null String. |
| */ |
| public static String ifNotEmpty(String base, String pre, String post) { |
| if (UtilValidate.isNotEmpty(base)) { |
| return pre + base + post; |
| } |
| return ""; |
| } |
| |
| /** Returns the first passed String if not empty, otherwise the second if not empty, otherwise an empty but non-null String. |
| * @param string1 The first passed String |
| * @param string2 The second passed String |
| * @return The first passed String if not empty, otherwise the second if not empty, otherwise an empty but non-null String |
| */ |
| public static String checkEmpty(String string1, String string2) { |
| if (UtilValidate.isNotEmpty(string1)) { |
| return string1; |
| } else if (UtilValidate.isNotEmpty(string2)) { |
| return string2; |
| } else { |
| return ""; |
| } |
| } |
| |
| /** Returns the first passed String if not empty, otherwise the second if not empty, otherwise the third if not empty, |
| * otherwise an empty but non-null String. |
| * @param string1 The first passed String |
| * @param string2 The second passed String |
| * @param string3 The third passed String |
| * @return The first passed String if not empty, otherwise the second if not empty, otherwise the third if not empty, |
| * otherwise an empty but non-null String |
| */ |
| public static String checkEmpty(String string1, String string2, String string3) { |
| if (UtilValidate.isNotEmpty(string1)) { |
| return string1; |
| } else if (UtilValidate.isNotEmpty(string2)) { |
| return string2; |
| } else if (UtilValidate.isNotEmpty(string3)) { |
| return string3; |
| } else { |
| return ""; |
| } |
| } |
| |
| // ------------------- web encode handlers ------------------- |
| /** |
| * Encodes an HTTP URL query String, replacing characters used for other |
| * things in HTTP URL query strings, but not touching the separator |
| * characters '?', '=', and '&' |
| * @param query The plain query String |
| * @return The encoded String |
| */ |
| public static String encodeQuery(String query) { |
| String retString; |
| |
| retString = replaceString(query, "%", "%25"); |
| retString = replaceString(retString, " ", "%20"); |
| return retString; |
| } |
| |
| /** Encodes a single HTTP URL query value, replacing characters used for other things in HTTP URL query strings |
| * @param query The plain query value String |
| * @return The encoded String |
| */ |
| public static String encodeQueryValue(String query) { |
| String retString; |
| |
| retString = replaceString(query, "%", "%25"); |
| retString = replaceString(retString, " ", "%20"); |
| retString = replaceString(retString, "&", "%26"); |
| retString = replaceString(retString, "?", "%3F"); |
| retString = replaceString(retString, "=", "%3D"); |
| return retString; |
| } |
| |
| /** Replaces all occurrences of oldString in mainString with newString |
| * @param mainString The original string |
| * @param oldString The string to replace |
| * @param newString The string to insert in place of the old |
| * @return mainString with all occurrences of oldString replaced by newString |
| */ |
| public static String replaceString(String mainString, String oldString, String newString) { |
| return StringUtil.replaceString(mainString, oldString, newString); |
| } |
| |
| /** Decodes a single query value from an HTTP URL parameter, replacing %ASCII values with characters |
| * @param query The encoded query value String |
| * @return The plain, decoded String |
| */ |
| public static String decodeQueryValue(String query) { |
| String retString; |
| |
| retString = replaceString(query, "%25", "%"); |
| retString = replaceString(retString, "%20", " "); |
| retString = replaceString(retString, "%26", "&"); |
| retString = replaceString(retString, "%3F", "?"); |
| retString = replaceString(retString, "%3D", "="); |
| return retString; |
| } |
| |
| // ------------------- web encode handlers ------------------- |
| /** |
| * Encodes an XML string replacing the characters '<', '>', '"', ''', '&' |
| * @param inString The plain value String |
| * @return The encoded String |
| */ |
| public static String encodeXmlValue(String inString) { |
| String retString = inString; |
| |
| retString = StringUtil.replaceString(retString, "&", "&"); |
| retString = StringUtil.replaceString(retString, "<", "<"); |
| retString = StringUtil.replaceString(retString, ">", ">"); |
| retString = StringUtil.replaceString(retString, "\"", """); |
| retString = StringUtil.replaceString(retString, "'", "'"); |
| return retString; |
| } |
| |
| public static String padString(String str, int setLen, boolean padEnd, char padChar) { |
| if (str == null) { |
| return null; |
| } |
| if (setLen == 0) { |
| return str; |
| } |
| int stringLen = str.length(); |
| int diff = setLen - stringLen; |
| if (diff < 0) { |
| return str.substring(0, setLen); |
| } |
| StringBuilder newString = new StringBuilder(); |
| if (padEnd) { |
| newString.append(str); |
| } |
| for (int i = 0; i < diff; i++) { |
| newString.append(padChar); |
| } |
| if (!padEnd) { |
| newString.append(str); |
| } |
| return newString.toString(); |
| } |
| public static String makeSqlSafe(String unsafeString) { |
| return unsafeString.replaceAll("'", "''"); |
| } |
| |
| public static String formatPrintableCreditCard(String original) { |
| if (original == null) { |
| return null; |
| } |
| if (original.length() <= 4) { |
| return original; |
| } |
| |
| StringBuilder buffer = new StringBuilder(); |
| for (int i = 0; i < original.length() - 4; i++) { |
| buffer.append('*'); |
| } |
| buffer.append(original.substring(original.length() - 4)); |
| return buffer.toString(); |
| } |
| } |