package gw.systables.verifier uses gw.api.locale.DisplayKey uses gw.xml.parser2.PLXMLNode uses java.util.Map uses java.util.ArrayList uses java.util.Date uses java.util.HashMap uses java.lang.StringBuffer uses javax.xml.namespace.QName uses java.util.List uses gw.api.upgrade.Coercions @ReadOnly class EffectiveDateCheckVerifierBase extends VerifierBase { static var EFFECTIVE_DATE : String = "EffectiveDate" static var EXPIRATION_DATE : String = "ExpirationDate" var nodesMap : HashMap> class SimpleCodeObj { var fields : List var effectiveDate : Date var expirationDate : Date construct() { fields = new ArrayList() } override function equals(o : Object) : boolean { if (this === o) { return true } if (o == null || !(o typeis SimpleCodeObj)) { return false } var that = o as SimpleCodeObj return fields.equals(that.fields) } override function hashCode() : int { return fields.hashCode() } } override function verify(importNode : PLXMLNode) : Map> { var result = super.verify(importNode) checkEffectiveDate(importNode, result) return result } protected function getEffectiveDateTag() : String { return EFFECTIVE_DATE } protected function getExpirationDateTag() : String { return EXPIRATION_DATE } /** * Returns the field names that are used to match two rows in the table when * determining whether the effective dates are overlapping. So if two rows * have the same values for these fields and also have overlapping effective * dates, the verifier will detect this as an error. * * should be overridden if sub-class wants to do checkEffectiveDateBeforeExpDate */ protected function getMatchingFieldsForEffectiveDateOverlapChecking() : String[] { return null } protected function checkEffectiveDate(importNode : PLXMLNode, results : Map>) : Map> { var entities = importNode.getChildren() var checkForDateOverlap = false if (getMatchingFieldsForEffectiveDateOverlapChecking() != null) { checkForDateOverlap = true nodesMap = new HashMap>() } for(var entity in entities) { if ( getEffectiveDateTag() != null && getExpirationDateTag() != null) { var effectiveDate = entity.getChildElement(QName.valueOf(getEffectiveDateTag())).Text var expirationDate = entity.getChildElement(QName.valueOf(getExpirationDateTag())).Text if (effectiveDate != null && expirationDate != null) { if ((Coercions.makeDateFrom(effectiveDate)).afterOrEqual(Coercions.makeDateFrom(expirationDate))) { addErrorToResults(DisplayKey.get("Java.ValidationError.SystemTables.EffDateAfterExpDate"), entity, results) } } if (checkForDateOverlap) { var code = getKeyForOverlapChecking(entity) if (code != null) { var currentCodeObj = constructFieldsAndDateObj(entity) if (isOverLap(nodesMap, currentCodeObj, code)) { addErrorToResults(DisplayKey.get("Java.ValidationError.SystemTables.EffDateOverlap", code, getFieldsDisplayValue(currentCodeObj)), entity, results) } addToNodeMap(currentCodeObj, code) } } } } return results } /** * Only node with matching keys are compared for overlap checking. Subclasses may override * this if "Code" is not appropriate. */ protected function getKeyForOverlapChecking(entity : PLXMLNode) : String { return entity.getChildElement(QName.valueOf("Code")).Text } private function isOverLap(notesMap : HashMap>, currentCodeObj : SimpleCodeObj, code : String) : boolean { var fieldsAndDateList = notesMap.get(code) if (fieldsAndDateList == null) { return false } for (comparedCodeObj in fieldsAndDateList) { if (comparedCodeObj == currentCodeObj) { if ((comparedCodeObj.expirationDate == null || currentCodeObj.effectiveDate.before(comparedCodeObj.expirationDate)) && (currentCodeObj.expirationDate == null || currentCodeObj.expirationDate.after(comparedCodeObj.effectiveDate))) { return true } } } return false } private function addToNodeMap(fieldsAndDateObj : SimpleCodeObj, code : String) { var fieldsAndDateList = nodesMap.get(code) if (fieldsAndDateList == null) { fieldsAndDateList = new ArrayList() fieldsAndDateList.add(fieldsAndDateObj) nodesMap.put(code, fieldsAndDateList) } else { fieldsAndDateList.add(fieldsAndDateObj) } } private function constructFieldsAndDateObj(entity : PLXMLNode) : SimpleCodeObj { var matchingFields = getMatchingFieldsForEffectiveDateOverlapChecking() var fieldsAndDatesObj = new SimpleCodeObj() var fieldsValueInObj = new ArrayList() for (var matchingField in matchingFields) { var field = entity.getChildElement(QName.valueOf(matchingField)) if (field != null) { var value = field.Text if (value == null) { value = field.getAttributeValue("public-id") // check if there is public-id } fieldsValueInObj.add(value) } else { fieldsValueInObj.add(null) } } fieldsAndDatesObj.fields = fieldsValueInObj fieldsAndDatesObj.effectiveDate = Coercions.makeDateFrom(entity.getChildElement(QName.valueOf(getEffectiveDateTag())).Text) fieldsAndDatesObj.expirationDate = Coercions.makeDateFrom(entity.getChildElement(QName.valueOf(getExpirationDateTag())).Text) return fieldsAndDatesObj } private function getFieldsDisplayValue(fieldsAndDateObj : SimpleCodeObj) : String { var fields = getMatchingFieldsForEffectiveDateOverlapChecking() var buf = new StringBuffer() if (fields != null) { var i = 0 for (field in fields) { buf.append("[" + field + " :" + fieldsAndDateObj.fields.get(i) + "]") i++ } } return buf.toString() } }