com.imsweb.validation.functions.MetafileContextFunctions Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of validation Show documentation
Show all versions of validation Show documentation
This framework allows edits to be defined in Groovy and to be executed on various data types.
/*
* Copyright (C) 2010 Information Management Services, Inc.
*/
package com.imsweb.validation.functions;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import groovy.lang.Binding;
import com.imsweb.staging.Staging;
import com.imsweb.validation.ValidationEngine;
import com.imsweb.validation.entities.ContextTable;
import com.imsweb.validation.entities.ContextTableIndex;
/**
* Metafile-related helper methods made available to the edits. If you want to execute translated edits in your project, you need to initialize
* the context functions with an instance of this class.
*
* None of these methods should be called from regular (non-translated) edits.
*
* As of version 5.3 of the engine, it is now possible to treat WARNINGS in translated edits as a failing state. To do that, just call
* the setFailWarnings() method with an argument of "true" after instanciating this class.
*/
@SuppressWarnings("ALL")
public class MetafileContextFunctions extends StagingContextFunctions {
// Special Geneedits constant
public static final int DT_VALID = 1342177279;
// Special Geneedits constant
public static final int DT_MISSING = 1610612735;
// Special Geneedits constant
public static final int DT_ERROR = 1879048191;
// Special Geneedits constant
public static final int DT_UNKNOWN = 2147483647;
// Special Geneedits constant
public static final int DT_EMPTY = 1073741823;
// Special Geneedits constant
public static final int DT_DAY_EMPTY = 805306367;
// Special Geneedits constant
public static final int DT_MONTH_EMPTY = 536870911;
// sentinel threshold, no sentinel value should be lower than this!
public static final int SENTINEL_TRESHOLD = DT_MONTH_EMPTY;
// Special Geneedits constant
public static final int DT_MIN = 1;
// Special Geneedits constant
public static final int DT_MAX = 2;
// Special Geneedits constant
public static final int DT_EXACT = 3;
// Special Geneedits constant
public static final int TRIM_RIGHT = 0;
// Special Geneedits constant
public static final int TRIM_LEFT = 1;
// Special Geneedits constant
public static final int TRIM_BOTH = 2;
// Special Geneedits constant
public static final int JUSTIFIED_RIGHT = 0;
// Special Geneedits constant
public static final int JUSTIFIED_LEFT = 1;
// Special genedits binding keys
public static final String BINDING_KEY_FUTURE_DATE = "__years_into_future";
// Special genedits binding keys
public static final String BINDING_KEY_DATE_COMPONENT = "__date_component";
// Pre-compiled regex and formatters...
private static final Pattern _GEN_VAL_P1 = Pattern.compile("(-?\\d+)(.*)");
private static final Pattern _GEN_VALID_DATE_IOP_P1 = Pattern.compile("(\\d{8}|\\d{6}\\s{2}|\\d{4}\\s{4})");
private static final DateTimeFormatter _GEN_DATECMP_IOP_FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
private static final Pattern _GEN_TRIM_P1 = Pattern.compile("^\\s+");
private static final Pattern _GEN_TRIM_P2 = Pattern.compile("\\s+$");
private static final Pattern _GEN_TRIM_P3 = Pattern.compile("(^\\s+|\\s+$)");
private static final Pattern _GEN_MATCH_P1 = Pattern.compile("\\s");
private static final Pattern _GEN_MATCH_P2 = Pattern.compile("(\\\\s)+");
private static final Pattern _GEN_MATCH_P3 = Pattern.compile("((\\\\s)+)\\)$");
private static final Pattern _GEN_MATCH_P4 = Pattern.compile("((\\\\s)+)$");
private static final Pattern _GEN_FMTSTR_P1 = Pattern.compile("%(.*)ld");
private static final Pattern _GEN_INLIST_P1 = Pattern.compile("(\\d+)\\D*.*");
// I don't love giving a state to this class, but I am not sure how else to do it since we already have multiple flavors for the constructor...
private boolean _failWarnings = false;
/**
* Minimal constructor. The metafile context methods use the CS staging client and therefore require a staging algorithm to be registered with this constructor.
*
* Note that this class can also be initialized with an instance of a TNM and EDO staging client, but no metafile conext methods need those. Historically, Genedits
* relied on the CS DLL, but not on any TNM or EOD DLL.
*
* You may provide null for the CS staging object, but any CS-related context methods won't work correctly.
*
* Here is an example of how to create the required CS staging object:
*
* Staging csStaging = Staging.getInstance(CsDataProvider.getInstance(CsDataProvider.CsVersion.v020550));
*
* You will also need to add a dependency to the CS algorithm in your project, see https://github.com/imsweb/staging-algorithm-cs
*/
public MetafileContextFunctions(Staging csStaging) {
super(csStaging, null, null);
}
/**
* Constructor.
* @param csStaging Staging
instance to use for Collaboriative-Stage-related operations.
* @param tnmStaging Staging
instance to use for TNM-related operations.
* @param eodStaging Staging
instance to use for EOD-related operations.
*/
public MetafileContextFunctions(Staging csStaging, Staging tnmStaging, Staging eodStaging) {
super(csStaging, tnmStaging, eodStaging);
}
/**
* If set to true, then warnings in translated edits will make the edit fail.
*/
public void setFailWarnings(boolean failWarnings) {
_failWarnings = failWarnings;
}
/**
* @return whether warnings in translated edits are considered as failures.
*/
public boolean isFailWarnings() {
return _failWarnings;
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
*/
public void GEN_NOOP() {
return;
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param binding
*/
public void GEN_RESET_LOCAL_CONTEXT(Binding binding) {
binding.setVariable(BINDING_KEY_FUTURE_DATE, null);
binding.setVariable(BINDING_KEY_DATE_COMPONENT, null);
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param value
* @return - internal use only -
*/
public boolean GEN_EMPTY(Object value) {
if (value == null)
return true;
return StringUtils.isBlank(GEN_TO_STRING(value));
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param value
* @return - internal use only -
*/
public int GEN_VAL(Object value) {
int result = 0;
String val = value == null ? "" : GEN_TO_STRING(value).trim();
Matcher match = _GEN_VAL_P1.matcher(val);
if (match.matches())
result = Integer.parseInt(match.group(1));
return result;
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value
* @return - internal use only -
*/
public boolean GEN_VALID_DATE_IOP(Binding binding, Object value) {
String val = GEN_TO_STRING(value);
if (val == null || val.isEmpty()) {
binding.setVariable(BINDING_KEY_DATE_COMPONENT, "date is an empty string");
return false;
}
if (!_GEN_VALID_DATE_IOP_P1.matcher(val).matches()) {
binding.setVariable(BINDING_KEY_DATE_COMPONENT, "date format must be CCYYMMDD");
return false;
}
LocalDate currentTime = LocalDate.now();
int maxYear = currentTime.getYear();
Integer futureYears = null;
if (binding.hasVariable(BINDING_KEY_FUTURE_DATE))
futureYears = (Integer)binding.getVariable(BINDING_KEY_FUTURE_DATE);
if (futureYears != null)
maxYear += futureYears;
int year = Integer.parseInt(val.substring(0, 4));
if (year < 1850 || year > maxYear) {
binding.setVariable(BINDING_KEY_DATE_COMPONENT, "invalid as to year");
return false;
}
int month = val.trim().length() >= 6 ? Integer.parseInt(val.substring(4, 6)) : 1;
if (month <= 0 || month > 12) {
binding.setVariable(BINDING_KEY_DATE_COMPONENT, "invalid as to month");
return false;
}
try {
int day = val.trim().length() == 8 ? Integer.parseInt(val.substring(6, 8)) : 1;
LocalDate toCheck = LocalDate.of(year, month, day);
int actualMaxDay = YearMonth.of(year, month).lengthOfMonth();
if (day <= 0 || day > actualMaxDay) {
binding.setVariable(BINDING_KEY_DATE_COMPONENT, "invalid as to day");
return false;
}
if (futureYears != null)
currentTime = currentTime.plusYears(futureYears);
if (toCheck.compareTo(currentTime) > 0) {
binding.setVariable(BINDING_KEY_DATE_COMPONENT, "future date");
return false;
}
}
catch (DateTimeException e) {
return false; // Invalid date. Like Feb 29th 2010.
}
return true;
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param binding
* @param yearsIntoFuture
*/
public void GEN_ALLOW_FUTURE_DATE_IOP(Binding binding, Object yearsIntoFuture) {
binding.setVariable(BINDING_KEY_FUTURE_DATE, yearsIntoFuture);
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value
* @return - internal use only -
*/
public int GEN_DATE_YEAR_IOP(Binding binding, Object value) {
String val = GEN_TO_STRING(value);
if (val == null || val.trim().isEmpty())
return DT_EMPTY;
if (!GEN_VALID_DATE_IOP(binding, value))
return DT_ERROR;
return Integer.parseInt(val.substring(0, 4));
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value
* @return - internal use only -
*/
public int GEN_DATE_MONTH_IOP(Binding binding, Object value) {
String val = GEN_TO_STRING(value);
if (val == null || val.length() < 5 || (val.length() >= 6 && val.substring(4, 6).trim().isEmpty()))
return DT_MONTH_EMPTY;
if (!GEN_VALID_DATE_IOP(binding, value))
return DT_ERROR;
return Integer.parseInt(val.substring(4, 6));
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value
* @return - internal use only -
*/
public int GEN_DATE_DAY_IOP(Binding binding, Object value) {
String val = GEN_TO_STRING(value);
if (val == null || val.length() < 7 || val.substring(6).trim().isEmpty())
return DT_DAY_EMPTY;
if (!GEN_VALID_DATE_IOP(binding, value))
return DT_ERROR;
return Integer.parseInt(val.substring(6));
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value1
* @param value2
* @param minMaxFlagObj
* @return - internal use only -
*/
public int GEN_DATECMP_IOP(Binding binding, Object value1, Object value2, Object minMaxFlagObj) {
StringBuilder buf1 = new StringBuilder();
StringBuilder buf2 = new StringBuilder();
int minMaxFlag = (Integer)minMaxFlagObj;
if (minMaxFlag == DT_MIN && !runMinFlagLogic(binding, value1, value2, minMaxFlag, value1, value2))
return 0;
int result = applyMinMaxFlag(binding, value1, value2, minMaxFlag, buf1, buf2);
if (result != 0)
return result;
LocalDate date1 = LocalDate.parse(buf1.toString(), _GEN_DATECMP_IOP_FORMAT);
LocalDate date2 = LocalDate.parse(buf2.toString(), _GEN_DATECMP_IOP_FORMAT);
if (date1.compareTo(date2) > 0)
return 1;
else if (date1.compareTo(date2) < 0)
return -1;
else
return 0;
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value1
* @param value2
* @param minMaxFlagObj
* @return - internal use only -
*/
public int GEN_YEARDIFF_IOP(Binding binding, String value1, String value2, Object minMaxFlagObj) {
int dayDiff = GEN_DAYDIFF_IOP(binding, value1, value2, minMaxFlagObj);
if (dayDiff > SENTINEL_TRESHOLD)
return dayDiff;
return (int)Math.floor((double)dayDiff / (double)365);
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value1
* @param value2
* @param minInt
* @param maxInt
* @param minMaxFlagObj
* @return - internal use only -
*/
public int GEN_YEARINTERNAL_IOP(Binding binding, String value1, String value2, Integer minInt, Integer maxInt, Object minMaxFlagObj) {
return GEN_YEARINTERVAL_IOP(binding, value1, value2, minInt, maxInt, minMaxFlagObj); // made a mistake on the name, leaving the old name in place for now...
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value1
* @param value2
* @param minInt
* @param maxInt
* @param minMaxFlagObj
* @return - internal use only -
*/
public int GEN_YEARINTERVAL_IOP(Binding binding, String value1, String value2, Integer minInt, Integer maxInt, Object minMaxFlagObj) {
int yearDiff = GEN_YEARDIFF_IOP(binding, value1, value2, minMaxFlagObj);
if (yearDiff > SENTINEL_TRESHOLD)
return yearDiff;
return yearDiff >= minInt && yearDiff <= maxInt ? 1 : 0;
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value1
* @param value2
* @param minMaxFlagObj
* @return - internal use only -
*/
public int GEN_MONTHDIFF_IOP(Binding binding, String value1, String value2, Object minMaxFlagObj) {
int dayDiff = GEN_DAYDIFF_IOP(binding, value1, value2, minMaxFlagObj);
if (dayDiff > SENTINEL_TRESHOLD)
return dayDiff;
return dayDiff < 0 ? (int)Math.ceil((double)dayDiff / (double)30) : (int)Math.floor((double)dayDiff / (double)30);
}
/**
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value1
* @param value2
* @param minInt
* @param maxInt
* @param minMaxFlagObj
* @return - internal use only -
*/
public int GEN_MONTHINTERNAL_IOP(Binding binding, String value1, String value2, Integer minInt, Integer maxInt, Object minMaxFlagObj) {
return GEN_MONTHINTERVAL_IOP(binding, value1, value2, minInt, maxInt, minMaxFlagObj); // made a mistake on the name, leaving the old name in place for now...
}
/**
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value1
* @param value2
* @param minInt
* @param maxInt
* @param minMaxFlagObj
* @return - internal use only -
*/
public int GEN_MONTHINTERVAL_IOP(Binding binding, String value1, String value2, Integer minInt, Integer maxInt, Object minMaxFlagObj) {
int monthDiff = GEN_MONTHDIFF_IOP(binding, value1, value2, minMaxFlagObj);
if (monthDiff > SENTINEL_TRESHOLD)
return monthDiff;
return monthDiff >= minInt && monthDiff <= maxInt ? 1 : 0;
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value1
* @param value2
* @param minMaxFlagObj
* @return - internal use only -
*/
public int GEN_DAYDIFF_IOP(Binding binding, String value1, String value2, Object minMaxFlagObj) {
StringBuilder buf1 = new StringBuilder();
StringBuilder buf2 = new StringBuilder();
int minMaxFlag = (Integer)minMaxFlagObj;
int result = applyMinMaxDayDiffFlag(binding, value1, value2, minMaxFlag, buf1, buf2);
if (result != 0)
return result;
LocalDate date1 = LocalDate.parse(buf1.toString(), _GEN_DATECMP_IOP_FORMAT);
LocalDate date2 = LocalDate.parse(buf2.toString(), _GEN_DATECMP_IOP_FORMAT);
return (int)ChronoUnit.DAYS.between(date1, date2);
}
/**
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value1
* @param value2
* @param minInt
* @param maxInt
* @param minMaxFlagObj
* @return - internal use only -
*/
public int GEN_DAYINTERNAL_IOP(Binding binding, String value1, String value2, Integer minInt, Integer maxInt, Object minMaxFlagObj) {
return GEN_DAYINTERVAL_IOP(binding, value1, value2, minInt, maxInt, minMaxFlagObj); // made a mistake on the name, leaving the old name in place for now...
}
/**
* Created on Apr 5, 2011 by depryf
* @param binding
* @param value1
* @param value2
* @param minInt
* @param maxInt
* @param minMaxFlagObj
* @return - internal use only -
*/
public int GEN_DAYINTERVAL_IOP(Binding binding, String value1, String value2, Integer minInt, Integer maxInt, Object minMaxFlagObj) {
int dayDiff = GEN_DAYDIFF_IOP(binding, value1, value2, minMaxFlagObj);
if (dayDiff > SENTINEL_TRESHOLD)
return dayDiff;
return dayDiff >= minInt && dayDiff <= maxInt ? 1 : 0;
}
// helper
private boolean runMinFlagLogic(Binding binding, Object value1, Object value2, Object minMaxFlagObj, Object date1, Object date2) {
String val1 = GEN_TO_STRING(value1);
String val2 = GEN_TO_STRING(value2);
if (val1 == null || val1.trim().isEmpty() || val2 == null || val2.trim().isEmpty())
return true;
if (!GEN_VALID_DATE_IOP(binding, val1) || !GEN_VALID_DATE_IOP(binding, val2))
return true;
int y1 = GEN_DATE_YEAR_IOP(binding, val1);
int y2 = GEN_DATE_YEAR_IOP(binding, val2);
int m1 = GEN_DATE_MONTH_IOP(binding, val1);
int m2 = GEN_DATE_MONTH_IOP(binding, val2);
int d1 = GEN_DATE_DAY_IOP(binding, val1);
int d2 = GEN_DATE_DAY_IOP(binding, val2);
if (y1 == y2 && (m1 == DT_MONTH_EMPTY || m2 == DT_MONTH_EMPTY))
return false;
if (y1 == y2 && m1 == m2 && (d1 == DT_DAY_EMPTY || d2 == DT_DAY_EMPTY))
return false;
return true;
}
// helper
private int applyMinMaxDayDiffFlag(Binding binding, Object value1, Object value2, Object minMaxFlagObj, StringBuilder date1Buf, StringBuilder date2Buf) {
String val1 = GEN_TO_STRING(value1);
String val2 = GEN_TO_STRING(value2);
if (val1 == null || val1.trim().isEmpty() || val2 == null || val2.trim().isEmpty())
return DT_EMPTY;
if (!GEN_VALID_DATE_IOP(binding, val1) || !GEN_VALID_DATE_IOP(binding, val2))
return DT_ERROR;
int y1 = GEN_DATE_YEAR_IOP(binding, val1);
int y2 = GEN_DATE_YEAR_IOP(binding, val2);
int m1 = GEN_DATE_MONTH_IOP(binding, val1);
int m2 = GEN_DATE_MONTH_IOP(binding, val2);
int d1 = GEN_DATE_DAY_IOP(binding, val1);
int d2 = GEN_DATE_DAY_IOP(binding, val2);
date1Buf.append(pad(String.valueOf(y1), 4, "0", true));
date2Buf.append(pad(String.valueOf(y2), 4, "0", true));
int minMaxFlag = (Integer)minMaxFlagObj;
// handle month of first value
int safeBeginningMonth = m1;
if (m1 == DT_MONTH_EMPTY) {
if (minMaxFlag == DT_MIN) {
if (y1 == y2 && m2 != DT_MONTH_EMPTY)
safeBeginningMonth = m2;
else if (y1 < y2)
safeBeginningMonth = 12; // December
else
safeBeginningMonth = 1; // January
}
else if (minMaxFlag == DT_MAX)
safeBeginningMonth = 1; // January
else
return DT_UNKNOWN;
}
date1Buf.append(pad(String.valueOf(safeBeginningMonth), 2, "0", true));
// handle month of second value
int safeEndMonth = m2;
if (m2 == DT_MONTH_EMPTY) {
if (minMaxFlag == DT_MIN) {
if (y1 == y2)
safeEndMonth = safeBeginningMonth;
else if (m1 == DT_MONTH_EMPTY && m2 == DT_MONTH_EMPTY && y1 > y2)
safeEndMonth = 12;
else if (y1 > y2)
safeEndMonth = 12;
else
safeEndMonth = 1; // January
}
else if (minMaxFlag == DT_MAX)
safeEndMonth = 12; // December
else
return DT_UNKNOWN;
}
date2Buf.append(pad(String.valueOf(safeEndMonth), 2, "0", true));
int numDaysInBeginningMonth = YearMonth.of(y1, safeBeginningMonth).lengthOfMonth();
int numDaysInEndMonth = YearMonth.of(y2, safeEndMonth).lengthOfMonth();
// handle day of first value
int safeBeginningDay = d1;
if (d1 == DT_DAY_EMPTY) {
if (minMaxFlag == DT_MIN) {
if (y1 == y2 && m1 != DT_MONTH_EMPTY && m2 != DT_MONTH_EMPTY && d2 != DT_DAY_EMPTY)
safeBeginningDay = 1;
else if (y1 == y2 && m1 == DT_MONTH_EMPTY && d2 != DT_DAY_EMPTY)
safeBeginningDay = d2;
else if (y1 < y2)
safeBeginningDay = numDaysInBeginningMonth; // last day
else if (y1 > y2 || m1 == DT_MONTH_EMPTY)
safeBeginningDay = 1; // first day
else
safeBeginningDay = numDaysInBeginningMonth; // last day
}
else if (minMaxFlag == DT_MAX)
safeBeginningDay = 1; // first day
else
return DT_UNKNOWN;
}
date1Buf.append(pad(String.valueOf(safeBeginningDay), 2, "0", true));
// handle day of second value
int safeEndDay = d2;
if (d2 == DT_DAY_EMPTY) {
if (minMaxFlag == DT_MIN) {
if (y1 == y2 && safeBeginningMonth == safeEndMonth)
safeEndDay = safeBeginningDay;
else if (m1 == DT_MONTH_EMPTY && m2 == DT_MONTH_EMPTY && y1 > y2)
safeEndDay = numDaysInEndMonth;
else if (y1 > y2)
safeEndDay = numDaysInEndMonth;
else
safeEndDay = 1; // first day
}
else if (minMaxFlag == DT_MAX)
safeEndDay = numDaysInEndMonth; // last day
else
return DT_UNKNOWN;
}
date2Buf.append(pad(String.valueOf(safeEndDay), 2, "0", true));
return 0;
}
// helper
private int applyMinMaxFlag(Binding binding, Object value1, Object value2, Object minMaxFlagObj, StringBuilder date1Buf, StringBuilder date2Buf) {
String val1 = GEN_TO_STRING(value1);
String val2 = GEN_TO_STRING(value2);
if (val1 == null || val1.trim().isEmpty() || val2 == null || val2.trim().isEmpty())
return DT_EMPTY;
if (!GEN_VALID_DATE_IOP(binding, val1) || !GEN_VALID_DATE_IOP(binding, val2))
return DT_ERROR;
int y1 = GEN_DATE_YEAR_IOP(binding, val1);
int y2 = GEN_DATE_YEAR_IOP(binding, val2);
int m1 = GEN_DATE_MONTH_IOP(binding, val1);
int m2 = GEN_DATE_MONTH_IOP(binding, val2);
int d1 = GEN_DATE_DAY_IOP(binding, val1);
int d2 = GEN_DATE_DAY_IOP(binding, val2);
date1Buf.append(pad(String.valueOf(y1), 4, "0", true));
date2Buf.append(pad(String.valueOf(y2), 4, "0", true));
int minMaxFlag = (Integer)minMaxFlagObj;
// handle month of first value
int safeBeginningMonth = m1;
if (m1 == DT_MONTH_EMPTY) {
if (minMaxFlag == DT_MIN)
safeBeginningMonth = 12; // December
else if (minMaxFlag == DT_MAX)
safeBeginningMonth = 1; // January
else
return DT_UNKNOWN;
}
date1Buf.append(pad(String.valueOf(safeBeginningMonth), 2, "0", true));
// handle month of second value
int safeEndMonth = m2;
if (m2 == DT_MONTH_EMPTY) {
if (minMaxFlag == DT_MIN) {
if (y1 == y2)
safeEndMonth = safeBeginningMonth;
else
safeEndMonth = 1; // January
}
else if (minMaxFlag == DT_MAX)
safeEndMonth = 12; // December
else
return DT_UNKNOWN;
}
date2Buf.append(pad(String.valueOf(safeEndMonth), 2, "0", true));
int numDaysInBeginningMonth = YearMonth.of(y1, safeBeginningMonth).lengthOfMonth();
int numDaysInEndMonth = YearMonth.of(y2, safeEndMonth).lengthOfMonth();
// handle day of first value
int safeBeginningDay = d1;
if (d1 == DT_DAY_EMPTY) {
if (minMaxFlag == DT_MIN)
safeBeginningDay = numDaysInBeginningMonth; // last day
else if (minMaxFlag == DT_MAX)
safeBeginningDay = 1; // first day
else
return DT_UNKNOWN;
}
date1Buf.append(pad(String.valueOf(safeBeginningDay), 2, "0", true));
// handle day of second value
int safeEndDay = d2;
if (d2 == DT_DAY_EMPTY) {
if (minMaxFlag == DT_MIN) {
if (y1 == y2 && safeBeginningMonth == safeEndMonth)
safeEndDay = safeBeginningDay;
else
safeEndDay = 1; // first day
}
else if (minMaxFlag == DT_MAX)
safeEndDay = numDaysInEndMonth; // last day
else
return DT_UNKNOWN;
}
date2Buf.append(pad(String.valueOf(safeEndDay), 2, "0", true));
return 0;
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param value
* @param typeObj
* @return - internal use only -
*/
public String GEN_TRIM(Object value, Object typeObj) {
String val = GEN_TO_STRING(value);
if (val == null || val.isEmpty())
return val;
int type = (Integer)typeObj;
String result;
switch (type) {
case TRIM_LEFT:
result = _GEN_TRIM_P1.matcher(val).replaceAll("");
break;
case TRIM_RIGHT:
result = _GEN_TRIM_P2.matcher(val).replaceAll("");
if (result.isEmpty()) // non-documented "feature"
result = " ";
break;
case TRIM_BOTH:
result = _GEN_TRIM_P3.matcher(val).replaceAll("");
break;
default:
throw new RuntimeException("Unsupported type: " + type);
}
return result;
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param value
* @return - internal use only -
*/
public int GEN_STRLEN(Object value) {
String val = GEN_TO_STRING(value);
return val == null ? 0 : val.length();
}
// helper
private boolean isValInList2(String val, String list) {
// if the value has trailing non-numeric values, trim off those non-numeric values first
String numericVal = removeTrailingNonNumerics(val);
if (" ".equals(list))
return " ".equals(val);
for (String term : StringUtils.split(list, ',')) {
String[] parts = StringUtils.split(term, '-');
// term is single value
if (parts.length == 1 && val.equals(term.trim()))
return true;
// term is a range
else if (parts.length == 2) {
// if the input value is a digit
if (numericVal != null) {
String low = parts[0].trim(), high = parts[1].trim();
//remove trailing non-numeric values from range numbers
low = removeTrailingNonNumerics(low);
high = removeTrailingNonNumerics(high);
// if both the low and high values are numeric
if (low != null && high != null) {
int iVal = Integer.parseInt(numericVal);
int iLow = Integer.parseInt(low);
int iHigh = Integer.parseInt(high);
if (iVal >= iLow && iVal <= iHigh)
return true;
}// if low is numeric but the high value is non-numeric
else if (low != null && high == null) {
int iVal = Integer.parseInt(numericVal);
int iLow = Integer.parseInt(low);
if (iVal >= iLow)
return true;
}// if low is non-numeric but the high value is numeric
else if (low == null && high != null) {
int iVal = Integer.parseInt(numericVal);
int iHigh = Integer.parseInt(high);
if (iVal <= iHigh)
return true;
}
else
return true;
}
}
}
return false;
}
// helper
private String removeTrailingNonNumerics(String input) {
String newString = null;
Matcher m4 = _GEN_INLIST_P1.matcher(input);
if (m4.matches())
newString = m4.group(1);
return newString;
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param value
* @param list
* @return - internal use only -
*/
public boolean GEN_INLIST(Object value, Object list) {
return GEN_INLIST(value, list, null, null, null);
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param value
* @param list
* @param regex
* @return - internal use only -
*/
public boolean GEN_INLIST(Object value, Object list, Object regex) {
return GEN_INLIST(value, list, regex, null, null);
}
/**
* Special genedit method. Internal use only.
*
* Created on Apr 5, 2011 by depryf
* @param value
* @param list
* @param regex
* @param startPos
* @param length
* @return - internal use only -
*/
public boolean GEN_INLIST(Object value, Object list, Object regex, Integer startPos, Integer length) {
String val = GEN_TO_STRING(value), l = GEN_TO_STRING(list);
if (val == null || val.isEmpty() || l == null || l.isEmpty())
return false;
if (regex != null && !GEN_MATCH(val, regex))
return false;
// weird corner case
if (StringUtils.isBlank(l))
return list.equals(val);
// another weird corner case
if (StringUtils.isBlank(val) && regex != null)
return true;
if (startPos != null && length != null) {
int start = startPos - 1; // Genedits uses 1-based index...
int end = Math.min(startPos - 1 + length, val.length()); // Gendits allows a length going past the end of the string...
if (start >= end)
return false;
val = val.substring(start, end);
}
for (String term : StringUtils.split(StringUtils.replace(l, " ", ""), ',')) {
String[] parts = StringUtils.split(term, '-');
if ((parts.length == 1 && val.equals(term)) || (parts.length == 2 && val.compareTo(parts[0]) >= 0 && val.compareTo(parts[1]) <= 0))
return true;
// value "1 " is found in list "1"; my best guess is that the trailing spaces are removed...
val = StringUtils.stripEnd(val, null);
if ((parts.length == 1 && val.equals(term)) || (parts.length == 2 && val.compareTo(parts[0]) >= 0 && val.compareTo(parts[1]) <= 0))
return true;
}
return false;
}
public boolean GEN_MATCH(Object value, Object regex) {
return matches(GEN_TO_STRING(value), GEN_TO_STRING(regex));
}
@SuppressWarnings("unchecked")
public boolean GEN_LOOKUP(Object value, Object tableObj, Object indexObj, Map, char[]> tableVars) {
String val = GEN_TO_STRING(value);
if (val == null || (tableObj == null && indexObj == null))
return false;
if (tableObj instanceof ContextTable || indexObj instanceof ContextTableIndex)
return GEN_LOOKUP_V5(val, (ContextTable)tableObj, (ContextTableIndex)indexObj, (Map)tableVars);
else
return GEN_LOOKUP_V4(val, (List>)tableObj, indexObj, (Map)tableVars);
}
// this is the old engine (v4) implementation
@SuppressWarnings("unchecked")
private boolean GEN_LOOKUP_V4(String val, List> table, Object indexObj, Map tableVars) {
// index values are trimmed, so the incoming one also need to be trimmed...
String trimmedVal = trimRight(val);
// if an index exists, use it!
boolean found = false;
Integer valIndex = null;
if (indexObj != null) {
if (indexObj instanceof List) {
for (Object elem : (List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy