All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cristalise.kernel.persistency.outcomebuilder.utils.OutcomeUtils Maven / Gradle / Ivy

The newest version!
/**
 * This file is part of the CRISTAL-iSE XPath Outcome Initiator module.
 * Copyright (c) 2001-2016 The CRISTAL Consortium. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * http://www.fsf.org/licensing/licenses/lgpl.html
 */
package org.cristalise.kernel.persistency.outcomebuilder.utils;

import static org.apache.commons.lang3.StringUtils.equalsAny;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.cristalise.kernel.persistency.outcomebuilder.SystemProperties.Webui_format_date;
import static org.cristalise.kernel.persistency.outcomebuilder.SystemProperties.Webui_format_datetime;
import static org.cristalise.kernel.persistency.outcomebuilder.SystemProperties.Webui_format_time;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Map;

import org.apache.commons.beanutils.converters.BigDecimalConverter;
import org.apache.commons.beanutils.converters.BigIntegerConverter;
import org.apache.commons.beanutils.converters.BooleanConverter;
import org.apache.commons.beanutils.converters.StringConverter;
import org.cristalise.kernel.persistency.outcome.Outcome;
import org.cristalise.kernel.persistency.outcomebuilder.Field;
import org.cristalise.kernel.persistency.outcomebuilder.OutcomeBuilder;
import org.cristalise.kernel.persistency.outcomebuilder.OutcomeStructure;
import org.json.JSONObject;

import lombok.extern.slf4j.Slf4j;

/**
 * Utility class for generated Scripts, Script development and testing. JSONObject, Outcome and Map are the
 * 3 major formats the are used in the framework to handle outcome, and this class provides consistent type conversion
 * for fields and their valid values.
 * 

* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} */ @Slf4j public class OutcomeUtils { public static final String webuiDateFormat = Webui_format_date.getString(); public static final String webuiDateTimeFormat = Webui_format_datetime.getString(); public static final String webuiTimeFormat = Webui_format_time.getString(); /** * Check if the String has a not blank valid value, i.e. it does not equal to 'string' nor 'null'. * This is based the convention that the XML based Outcome handles values of type String only. *

* Note that 'Empty' OutcomeInitiator creates one entry for optional fields. * If this is not required it is considered invalid. * * @param value the String to be checked * @return true if the String in not blank and it does not equal to 'string' nor 'null' otherwise returns false * * @see org.apache.commons.lang3.StringUtils#isNotBlank * @see org.apache.commons.lang3.StringUtils#equalsAny */ public static boolean hasValidNotBlankValue(String value) { return isNotBlank(value) && ! equalsAny(value, "string", "null"); } /** * Checks if the input object has the field or not * * @param input either JSONObject, Outcome or Map * @param key the field to check * @return true if the input has the field regardless its value otherwise false */ public static boolean hasField(Object input, String key) { if (input instanceof JSONObject) { return ((JSONObject) input).has(key); } else if (input instanceof Outcome) { return ((Outcome) input).hasField(key); } else if (input instanceof Map) { return ((Map) input).containsKey(key); } else { throw new IllegalArgumentException("Does not handle input with type '" + input.getClass().getName() + "'"); } } /** * Returns the value if the input object has the field and a valid value. *
* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} * * @param input either JSONObject, Outcome or Map * @param key the field to check * @return the value if the input has the field with a valid value otherwise returns null */ public static Object getValueOrNull(Object input, String key) { if (!hasField(input, key)) return null; Object value = null; if (input instanceof Map) { value = ((Map) input).get(key); } else if (input instanceof JSONObject) { JSONObject json = (JSONObject) input; if (! json.isNull(key)) value = json.get(key); } else if (input instanceof Outcome) { value = ((Outcome) input).getField(key); } else { throw new IllegalArgumentException("Does not handle input with type '" + input.getClass().getName() + "'"); } if (value != null && value instanceof String && ! hasValidNotBlankValue((String)value)) { value = null; } return value; } /** * Checks if the input object has the field and a valid value. *
* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} * * @param input either JSONObject, Outcome or Map * @param key the field to check * @return true if the input has the field with a valid value otherwise returns false */ public static boolean hasValue(Object input, String key) { return getValueOrNull(input, key) != null; } /** * Uses the OutcomeBuilder (i.e. Schema) to return a value in the correct type * * @param input * @param key * @param builder * @return */ public static Object getValueOrNull(Object input, String key, OutcomeBuilder builder) { OutcomeStructure childStruct = builder.findChildStructure(key); if (childStruct == null) return null; if (!(childStruct instanceof Field)) throw new IllegalArgumentException("Key '"+key+"' is not class Field (" +input.getClass().getName()+")"); Class fieldClazz = ((Field)childStruct).getJavaType(); if (fieldClazz.equals(String.class)) { return getStringOrNull(input, key); } else if(fieldClazz.equals(Boolean.class)) { return getBooleanOrNull(input, key); } else if(fieldClazz.equals(BigInteger.class)) { return getBigIntegerOrNull(input, key); } else if(fieldClazz.equals(BigDecimal.class)) { return getBigDecimalOrNull(input, key); } else if(fieldClazz.equals(LocalDate.class)) { return getLocalDateOrNull(input, key); } else if(fieldClazz.equals(OffsetDateTime.class)) { return getOffsetDateTimeOrNull(input, key); } else if(fieldClazz.equals(OffsetTime.class)) { return getOffsetTimeOrNull(input, key); } else { throw new IllegalArgumentException("Uncovered class '"+ fieldClazz + "' for field:'"+key+"'"); } } /** * Returns the valid value of the given field as String or null. Based on apache beanutils StringConverter. *
* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} * * @param input either a JSONObject or an Outcome * @param key the field to be converted * @return value of the given field as String or null * * @see org.apache.commons.beanutils.converters.StringConverter */ public static String getStringOrNull(Object input, String key) { StringConverter converter = new StringConverter(null); Object value = getValueOrNull(input, key); if (value != null) return converter.convert(String.class, value); else return null; } /** * Returns the valid value of the given field as BigDecimal or null. No rounding is done. * Based on apache beanutils BigDecimalConverter which converts Boolean.TRUE to 1 and Boolean.FALSE to 0. *
* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} * * @param input either JSONObject, Outcome or Map * @param key the field to be converted * @return value of the given field as BigDecimal or null * * @see org.apache.commons.beanutils.converters.BigDecimalConverter */ public static BigDecimal getBigDecimalOrNull(Object input, String key) { return getBigDecimalOrNull(input, key, -1, null); } /** * Returns the valid value of the given field as BigDecimal or null. Half-up rounding is done using the * given scale. * Based on apache beanutils BigDecimalConverter which converts Boolean.TRUE to 1 and Boolean.FALSE to 0. *
* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} * * @param input either a JSONObject or an Outcome * @param key the field to be converted * @param scale to be used for half-up rounding * @return value of the given field as BigDecimal or null * * @see org.apache.commons.beanutils.converters.BigDecimalConverter */ public static BigDecimal getBigDecimalOrNull(Object input, String key, int scale) { return getBigDecimalOrNull(input, key, scale, RoundingMode.HALF_UP); } /** * Returns the valid value of the given field as BigDecimal or null. The given rounding is done using * the given scale. * Based on apache beanutils BigDecimalConverter which converts Boolean.TRUE to 1 and Boolean.FALSE to 0. *
* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} * * @param input either a JSONObject or an Outcome * @param key the field to be converted * @param scale to be used for the given rounding * @param rounding to be used * @return value of the given field as BigDecimal or null * * @see org.apache.commons.beanutils.converters.BigDecimalConverter */ public static BigDecimal getBigDecimalOrNull(Object input, String key, int scale, RoundingMode rounding) { BigDecimalConverter converter = new BigDecimalConverter(null); Object value = getValueOrNull(input, key); if (value != null) { if (scale >= 0) return converter.convert(BigDecimal.class, value).setScale(scale, rounding); else return converter.convert(BigDecimal.class, value); } return null; } /** * Returns the valid value of the given field as BigInteger or null. Based on apache beanutils BigIntegerConverter * which converts Boolean.TRUE to 1 and Boolean.FALSE to 0 *
* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} * * @param input either a JSONObject or an Outcome * @param key the field to be converted * @return value of the given field as BigInteger or null * * @see org.apache.commons.beanutils.converters.BigIntegerConverter */ public static BigInteger getBigIntegerOrNull(Object input, String key) { BigIntegerConverter converter = new BigIntegerConverter(null); Object value = getValueOrNull(input, key); if (value != null) { return converter.convert(BigInteger.class, value); } return null; } /** * Returns the valid value of the given field as Boolean or null. * Based on apache beanutils BooleanConverter which converts strings {"yes", "y", "true", "on", "1"} to true * and converts strings {"no", "n", "false", "off", "0"} to false *
* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} * * @param input either a JSONObject, an Outcome or a Map * @param key the field to be converted * @return value of the given field as Boolean or null * * @see org.apache.commons.beanutils.converters.BooleanConverter */ public static Boolean getBooleanOrNull(Object input, String key) { BooleanConverter converter = new BooleanConverter(null); Object value = getValueOrNull(input, key); if (value != null) return converter.convert(Boolean.class, value); else return null; } /** * Converts the value of the given field to LocalDate or null. If the input is a JSONObject * it uses webui specific pattern, configurable with 'Webui.format.date' system property, * default is 'yyyy-MM-dd'. If the input is an Outcome or Map the ISO_LOCAL_DATE format is used. *
* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} * * @param input either a JSONObject, an Outcome or a Map * @param key the field to be converted * @return value of the given field in LocalDate or null */ public static LocalDate getLocalDateOrNull(Object input, String key) { Object value = getValueOrNull(input, key); if (value != null) { if (value instanceof LocalDate) { return (LocalDate)value; } else if (value instanceof String) { DateTimeFormatter dtf = null; if (input instanceof JSONObject) dtf = DateTimeFormatter.ofPattern(webuiDateFormat); else dtf = DateTimeFormatter.ISO_LOCAL_DATE; try { return LocalDate.parse((String)value, dtf); } catch (DateTimeParseException e) { log.debug("getLocalDateOrNull(key:{}) - DateTimeParseException:{}", key, e.getMessage()); } } else { log.debug("getLocalDateOrNull(key:{}) - value '{}' is not a String, dropping it", key, value); } } return null; } /** * Returns the valid value of the given field as LocalDateTime or null. If the input is a JSONObject * it uses webui specific pattern, configurable with 'Webui.format.datetime' system property, * default is 'yyyy-MM-dd'T'HH:mm:ss'. If the input is an Outcome or Map the ISO_LOCAL_DATETIME * format is used. *
* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} * * @param input either a JSONObject, an Outcome or a Map * @param key the field to be converted * @return value of the given field as LocalDateTime or null */ public static LocalDateTime getLocalDateTimeOrNull(Object input, String key) { Object value = getValueOrNull(input, key); if (value != null) { if (value instanceof LocalDateTime) { return (LocalDateTime)value; } else if (value instanceof String) { DateTimeFormatter dtf = null; if (input instanceof JSONObject) dtf = DateTimeFormatter.ofPattern(webuiDateTimeFormat); else dtf = DateTimeFormatter.ISO_LOCAL_DATE_TIME; try { return LocalDateTime.parse((String)value, dtf); } catch (DateTimeParseException e) { log.debug("getLocalDateTimeOrNull(key:{}) - DateTimeParseException:{}", key, e.getMessage()); } } else { log.debug("getLocalDateTimeOrNull(key:{}) - value '{}' is not a String, dropping it", key, value); } } return null; } /** * Returns the valid value of the given field as OffsetDateTime or null. If the input is a JSONObject * it uses webui specific pattern, configurable with 'Webui.format.datetime' system property, * default is 'yyyy-MM-dd'T'HH:mm:ss'. If the input is an Outcome or Map the ISO_OFFSET_DATE_TIME * format is used. *
* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} * * @param input either a JSONObject, an Outcome or a Map * @param key the field to be converted * @return value of the given field as OffsetDateTime or null */ public static OffsetDateTime getOffsetDateTimeOrNull(Object input, String key) { Object value = getValueOrNull(input, key); if (value != null) { if (value instanceof OffsetDateTime) { return (OffsetDateTime)value; } else if (value instanceof String) { DateTimeFormatter dtf = null; try { if (input instanceof JSONObject) { dtf = DateTimeFormatter.ofPattern(webuiDateTimeFormat); OffsetDateTime odt = OffsetDateTime.now(ZoneId.systemDefault()); ZoneOffset zoneOffset = odt.getOffset(); return LocalDateTime.parse((String)value, dtf).atOffset(zoneOffset); } else { dtf = DateTimeFormatter.ISO_OFFSET_DATE_TIME; return OffsetDateTime.parse((String)value, dtf); } } catch (DateTimeParseException e) { log.debug("getOffsetDateTimeOrNull(key:{}) - DateTimeParseException:{}", key, e.getMessage()); } } else { log.debug("getOffsetDateTimeOrNull(key:{}) - value '{}' is not a String, dropping it", key, value); } } return null; } /** * Returns the valid value of the given field as OffsetTime or null. If the input is a JSONObject * it uses webui specific pattern, configurable with 'Webui.format.time' system property, * default is 'HH:mm:ss'. If the input is an Outcome or Map the ISO_OFFSET_TIME format is used. *
* Valid value: {@link OutcomeUtils#hasValidNotBlankValue(String)} * * @param input either a JSONObject, an Outcome or a Map * @param key the field to be converted * @return value of the given field as OffsetTime or null */ public static OffsetTime getOffsetTimeOrNull(Object input, String key) { Object value = getValueOrNull(input, key); if (value != null) { if (value instanceof OffsetTime) { return (OffsetTime)value; } else if (value instanceof String) { DateTimeFormatter dtf = null; try { if (input instanceof JSONObject) { dtf = DateTimeFormatter.ofPattern(webuiTimeFormat); OffsetDateTime odt = OffsetDateTime.now (ZoneId.systemDefault ()); ZoneOffset zoneOffset = odt.getOffset (); return LocalTime.parse((String)value, dtf).atOffset(zoneOffset); } else { dtf = DateTimeFormatter.ISO_OFFSET_TIME; return OffsetTime.parse((String)value, dtf); } } catch (DateTimeParseException e) { log.debug("getOffsetTimeOrNull(key:{}) - DateTimeParseException:{}", key, e.getMessage()); } } else { log.debug("getOffsetTimeOrNull(key:{}) - value '{}' is not a String, dropping it", key, value); } } return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy