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

org.jpmml.evaluator.FieldValue Maven / Gradle / Ivy

There is a newer version: 1.6.8
Show newest version
/*
 * Copyright (c) 2013 Villu Ruusmann
 *
 * This file is part of JPMML-Evaluator
 *
 * JPMML-Evaluator is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * JPMML-Evaluator is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with JPMML-Evaluator.  If not, see .
 */
package org.jpmml.evaluator;

import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;

import org.dmg.pmml.Array;
import org.dmg.pmml.DataType;
import org.dmg.pmml.Expression;
import org.dmg.pmml.Field;
import org.dmg.pmml.HasValue;
import org.dmg.pmml.HasValueSet;
import org.dmg.pmml.OpType;
import org.dmg.pmml.PMMLObject;
import org.jpmml.model.ToStringHelper;

/**
 * 

* A field value representation that meets the requirements of PMML type system. *

* * Type information has two components to it: *
    *
  • {@link #getOpType() Operational type}. Determines supported type equality and type comparison operations.
  • *
  • {@link #getDataType() Data type}. Determines supported type conversions.
  • *
* *

* A field value is created after a {@link Field field}. * It may be later refined by {@link Expression transformations} and {@link Function functions}. *

* * @see FieldValueUtil */ abstract public class FieldValue implements Comparable, Serializable { private DataType dataType = null; private Object value = null; FieldValue(DataType dataType, Object value){ setDataType(Objects.requireNonNull(dataType)); setValue(filterValue(Objects.requireNonNull(value))); } abstract public OpType getOpType(); /** *

* Checks if this value is equal to the reference value. *

*/ public boolean equals(HasValue hasValue){ if(hasValue instanceof HasParsedValue){ HasParsedValue hasParsedValue = (HasParsedValue)hasValue; return equals(hasParsedValue); } return equalsString(ensureValue(hasValue)); } public boolean equals(HasParsedValue hasParsedValue){ FieldValue value = hasParsedValue.getValue(getDataType(), getOpType()); return this.equals(value); } /** *

* Checks if this value is contained in the set of reference values. *

*/ public boolean isIn(HasValueSet hasValueSet){ if(hasValueSet instanceof HasParsedValueSet){ HasParsedValueSet hasParsedValueSet = (HasParsedValueSet)hasValueSet; return isIn(hasParsedValueSet); } Array array = hasValueSet.getArray(); if(array == null){ throw new MissingElementException(MissingElementException.formatMessage(XPathUtil.formatElement((Class)hasValueSet.getClass()) + "/" + XPathUtil.formatElement(Array.class)), (PMMLObject)hasValueSet); } List values = ArrayUtil.getContent(array); return values.stream() .anyMatch(value -> equalsValue(value)); } public boolean isIn(HasParsedValueSet hasParsedValueSet){ Set values = hasParsedValueSet.getValueSet(getDataType(), getOpType()); return values.contains(this); } /** *

* Calculates the order between this value and the reference value. *

*/ public int compareTo(HasValue hasValue){ if(hasValue instanceof HasParsedValue){ HasParsedValue hasParsedValue = (HasParsedValue)hasValue; return compareTo(hasParsedValue); } return compareToString(ensureValue(hasValue)); } public int compareTo(HasParsedValue hasParsedValue){ FieldValue value = hasParsedValue.getValue(getDataType(), getOpType()); return this.compareTo(value); } public boolean equalsString(String string){ Object value = TypeUtil.parse(getDataType(), string); return (getValue()).equals(value); } /** *

* A value-safe replacement for {@link #equals(Object)}. *

*/ public boolean equalsValue(FieldValue value){ if(sameScalarType(value)){ return (getValue()).equals(value.getValue()); } return equalsValue(value.getValue()); } private boolean equalsValue(Object value){ value = TypeUtil.parseOrCast(getDataType(), value); return (getValue()).equals(value); } public boolean isIn(Collection values){ Predicate predicate = new Predicate(){ @Override public boolean test(FieldValue value){ if(Objects.equals(FieldValues.MISSING_VALUE, value)){ return false; } return equalsValue(value); } }; return values.stream() .anyMatch(predicate); } public int compareToString(String string){ Object value = TypeUtil.parse(getDataType(), string); return ((Comparable)getValue()).compareTo(value); } /** *

* A value-safe replacement for {@link #compareTo(FieldValue)} *

*/ public int compareToValue(FieldValue value){ if(sameScalarType(value)){ return ((Comparable)getValue()).compareTo(value.getValue()); } return compareToValue(value.getValue()); } private int compareToValue(Object value){ value = TypeUtil.parseOrCast(getDataType(), value); return ((Comparable)getValue()).compareTo(value); } public V getMapping(HasParsedValueMapping hasParsedValueMapping){ Map values = hasParsedValueMapping.getValueMapping(getDataType(), getOpType()); return values.get(this); } private boolean isScalar(){ return (this instanceof Scalar); } private boolean sameScalarType(FieldValue value){ if(isScalar()){ return (getClass()).equals(value.getClass()); } return false; } public String asString(){ return (String)getValue(DataType.STRING); } public Number asNumber(){ Object value = getValue(); if(value instanceof Number){ return (Number)value; } return (Double)getValue(DataType.DOUBLE); } public Integer asInteger(){ return (Integer)getValue(DataType.INTEGER); } public Float asFloat(){ Number number = asNumber(); return number.floatValue(); } /** * Getting the value of a field as {@link Double}: *
	 * FieldValue value = ...;
	 * Double result = value.asDouble();
	 * 
* * Getting the value of a field as double: *
	 * FieldValue value = ...;
	 * double result = (value.asNumber()).doubleValue();
	 * 
* * @see #asNumber() */ public Double asDouble(){ Number number = asNumber(); return number.doubleValue(); } public Boolean asBoolean(){ return (Boolean)getValue(DataType.BOOLEAN); } public LocalDateTime asLocalDateTime(){ return (LocalDateTime)getValue(DataType.DATE_TIME); } public LocalDate asLocalDate(){ return (LocalDate)getValue(DataType.DATE); } public LocalTime asLocalTime(){ return (LocalTime)getValue(DataType.TIME); } public ZonedDateTime asZonedDateTime(ZoneId zoneId){ try { LocalDateTime dateTime = asLocalDateTime(); return dateTime.atZone(zoneId); } catch(TypeCheckException tceDateTime){ try { LocalDate localDate = asLocalDate(); LocalTime localTime = LocalTime.MIDNIGHT; return ZonedDateTime.of(localDate, localTime, zoneId); } catch(TypeCheckException tceDate){ // Ignored } try { LocalDate localDate = LocalDate.now(); LocalTime localTime = asLocalTime(); return ZonedDateTime.of(localDate, localTime, zoneId); } catch(TypeCheckException tceTime){ // Ignored } throw tceDateTime; } } private Object getValue(DataType dataType){ Object value = getValue(); try { return TypeUtil.cast(dataType, value); } catch(TypeCheckException tce){ try { if(value instanceof String){ String string = (String)value; return TypeUtil.parse(dataType, string); } } catch(IllegalArgumentException iae){ // Ignored } throw tce; } } @Override public int compareTo(FieldValue that){ if((this.getOpType() != that.getOpType()) || (this.getDataType() != that.getDataType())){ throw new ClassCastException(); } return compareToValue(that); } @Override public int hashCode(){ return (31 * (getOpType().hashCode() ^ getDataType().hashCode())) + getValue().hashCode(); } @Override public boolean equals(Object object){ if(object instanceof FieldValue){ FieldValue that = (FieldValue)object; return (this.getOpType() == that.getOpType()) && (this.getDataType() == that.getDataType()) && (this.getValue()).equals(that.getValue()); } return false; } @Override public String toString(){ ToStringHelper helper = new ToStringHelper(this) .add("opType", getOpType()) .add("dataType", getDataType()) .add("value", getValue()); return helper.toString(); } public DataType getDataType(){ return this.dataType; } private void setDataType(DataType dataType){ this.dataType = dataType; } public Object getValue(){ return this.value; } private void setValue(Object value){ this.value = value; } static private String ensureValue(HasValue hasValue){ String value = hasValue.getValue(); if(value == null){ throw new MissingAttributeException(MissingAttributeException.formatMessage(XPathUtil.formatElement((Class)hasValue.getClass()) + "@value"), (PMMLObject)hasValue); } return value; } static private Object filterValue(Object value){ if(value instanceof Float){ return filterValue((Float)value); } else if(value instanceof Double){ return filterValue((Double)value); } return value; } static private Float filterValue(Float value){ if(value.doubleValue() == 0f){ return Numbers.FLOAT_ZERO; } return value; } static private Double filterValue(Double value){ if(value.doubleValue() == 0d){ return Numbers.DOUBLE_ZERO; } return value; } static interface Scalar { } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy