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

com.tangosol.util.extractor.ComparisonValueExtractor Maven / Gradle / Ivy

There is a newer version: 24.09
Show newest version
/*
 * Copyright (c) 2000, 2022, Oracle and/or its affiliates.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * https://oss.oracle.com/licenses/upl.
 */

package com.tangosol.util.extractor;


import com.tangosol.util.ValueExtractor;

import com.tangosol.util.comparator.SafeComparator;

import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;

import java.util.Comparator;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import java.math.BigDecimal;
import java.math.BigInteger;

import jakarta.json.bind.annotation.JsonbProperty;


/**
* A synthetic ValueExtractor that returns a result of comparison between two
* values extracted from the same target. In a most general case, the extracted
* value represents an Integer value calculated accordingly to the contract of
* {@link Comparable#compareTo} or {@link Comparator#compare} methods. However,
* in more specific cases, when the compared values are of common numeric type,
* the ComparisonValueExtractor will return a numeric difference between those
* values. The Java type of the comparing values will dictate the Java type of
* the result.
* 

* For example, lets assume that a cache contains business objects that have two * properties: SellPrice and BuyPrice (both double). Then, to query for all * objects that have SellPrice less than BuyPrice we would use the following: *

* ValueExtractor extractDiff = new ComparisonValueExtractor(
*   new ReflectionExtractor("getSellPrice"),
*   new ReflectionExtractor("getBuyPrice"));
* Filter filter = new LessFilter(extractDiff, new Double(0.0));
* Set entries = cache.entrySet(filter);
* 
* * @author gg 2008.02.15 * @since Coherence 3.4 */ public class ComparisonValueExtractor extends AbstractCompositeExtractor { /** * Default constructor (necessary for the ExternalizableLite interface). */ public ComparisonValueExtractor() { } /** * Construct a ComparisonValueExtractor based on two method names. * Note: values returned by both methods must be {@link Comparable}. * * @param sMethod1 the name of the first method to invoke via reflection * @param sMethod2 the name of the second method to invoke via reflection */ public ComparisonValueExtractor(String sMethod1, String sMethod2) { this(sMethod1, sMethod2, null); } /** * Construct a ComparisonValueExtractor based on two method names and a * Comparator object. * * @param sMethod1 the name of the first method to invoke via reflection * @param sMethod2 the name of the second method to invoke via reflection * @param comp the comparator used to compare the extracted values (optional) */ public ComparisonValueExtractor(String sMethod1, String sMethod2, Comparator comp) { this(new ReflectionExtractor(sMethod1), new ReflectionExtractor(sMethod2), comp); } /** * Construct a ComparisonValueExtractor based on two specified extractors. * Note: values returned by both extractors must be {@link Comparable}. * * @param ve1 the ValueExtractor for the first value * @param ve2 the ValueExtractor for the second value */ public ComparisonValueExtractor(ValueExtractor ve1, ValueExtractor ve2) { this(ve1, ve2, null); } /** * Construct a ComparisonValueExtractor based on two specified extractors and * a Comparator object. * * @param ve1 the ValueExtractor for the first value * @param ve2 the ValueExtractor for the second value * @param comp the comparator used to compare the extracted values (optional) */ public ComparisonValueExtractor(ValueExtractor ve1, ValueExtractor ve2, Comparator comp) { super(new ValueExtractor[] {ve1, ve2}); m_comparator = comp; } // ----- accessors ------------------------------------------------------ /** * Return a Comparator used by this extractor. * * @return a Comparator used by this extractor; null if the natural value * comparison should be used */ public Comparator getComparator() { return m_comparator; } // ----- ValueExtractor interface --------------------------------------- /** * {@inheritDoc} */ public E extract(Object oTarget) { ValueExtractor[] aExtractor = getExtractors(); Comparator comparator = getComparator(); Object o1 = aExtractor[0].extract(oTarget); Object o2 = aExtractor[1].extract(oTarget); if (o1 instanceof Number && o2 instanceof Number && comparator == null) { Number num1 = (Number) o1; Number num2 = (Number) o2; int nType; if (num1.getClass() == num2.getClass()) { // most common case; same types nType = getStreamFormat(o1); } else { int[] anType = new int[] { FMT_BYTE, // 0 FMT_SHORT, // 1 FMT_INT, // 2 FMT_LONG, // 3 FMT_FLOAT, // 4 FMT_DOUBLE, // 5 FMT_INTEGER, // 6 FMT_DECIMAL // 7 }; int nType1 = getStreamFormat(num1); int nType2 = getStreamFormat(num2); int cTypes, ix1, ix2; ix1 = ix2 = cTypes = anType.length; for (int i = 0; i < cTypes; i++) { int nT = anType[i]; if (nT == nType1) { ix1 = i; } if (nT == nType2) { ix2 = i; } } switch (Math.max(ix1, ix2)) { case 1: case 2: nType = FMT_INT; break; case 3: nType = FMT_LONG; break; case 4: case 5: nType = FMT_DOUBLE; break; case 6: case 7: nType = FMT_INTEGER; num1 = ensureBigDecimal(num1); num2 = ensureBigDecimal(num2); break; default: nType = FMT_NONE; break; } } switch (nType) { case FMT_BYTE: case FMT_SHORT: case FMT_INT: return (E) Integer.valueOf(num1.intValue() - num2.intValue()); case FMT_LONG: return (E) Long.valueOf(num1.longValue() - num2.longValue()); case FMT_FLOAT: return (E) Float.valueOf(num1.floatValue() - num2.floatValue()); case FMT_DOUBLE: return (E) Double.valueOf(num1.doubleValue() - num2.doubleValue()); case FMT_INTEGER: return (E) ((BigInteger) num1).subtract((BigInteger) num2); case FMT_DECIMAL: return (E) ((BigDecimal) num1).subtract((BigDecimal) num2); } } return (E) Integer.valueOf(SafeComparator.compareSafe(comparator, o1, o2)); } // ----- ExternalizableLite interface ----------------------------------- /** * {@inheritDoc} */ public void readExternal(DataInput in) throws IOException { super.readExternal(in); m_comparator = readObject(in); } /** * {@inheritDoc} */ public void writeExternal(DataOutput out) throws IOException { super.writeExternal(out); writeObject(out, m_comparator); } // ----- PortableObject interface --------------------------------------- /** * {@inheritDoc} */ public void readExternal(PofReader in) throws IOException { super.readExternal(in); m_comparator = in.readObject(1); } /** * {@inheritDoc} */ public void writeExternal(PofWriter out) throws IOException { super.writeExternal(out); out.writeObject(1, m_comparator); } // ----- data members --------------------------------------------------- /** * An underlying Comparator object (optional). */ @JsonbProperty("comparator") protected Comparator m_comparator; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy