com.tangosol.util.extractor.KeyExtractor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of coherence Show documentation
Show all versions of coherence Show documentation
Oracle Coherence Community Edition
/*
* 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.internal.util.invoke.Lambdas;
import com.tangosol.io.ExternalizableLite;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
import com.tangosol.util.Base;
import com.tangosol.util.ClassHelper;
import com.tangosol.util.ValueExtractor;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import jakarta.json.bind.annotation.JsonbProperty;
/**
* The KeyExtractor is a special purpose ValueExtractor implementation that
* serves as an indicator that a query should be run against the key objects
* rather than the values. The major difference between the KeyExtractor and a
* standard {@link ReflectionExtractor} is that when used in various
* {@link com.tangosol.util.filter.EntryFilter} implementations it forces
* the evaluation of entry keys rather than entry values.
*
* For example, consider a key object that consists of two properties:
* "FirstName" and "LastName". To retrieve all keys that have a value of the
* "LastName" property equal to "Smith", the following query could be used:
*
* ValueExtractor extractor = new KeyExtractor("getLastName");
* Set setKeys = cache.keySet(new EqualsFilter(extractor, "Smith"));
*
*
* As of Coherence 3.5, the same effect can be achieved for subclasses of the
* AbstractExtractor, for example:
*
* ValueExtractor extractor = new ReflectionExtractor("getLastName", null,
* AbstractExtractor.KEY);
* Set setKeys = cache.keySet(new EqualsFilter(extractor, "Smith"));
*
*
* Note: This class does not function with
* {@link com.tangosol.util.extractor.PofExtractor} and the mechanism
* described above is recommended.
*
* @author gg 2006.06.12
* @since Coherence 3.2
*/
public class KeyExtractor
extends AbstractExtractor
implements ExternalizableLite, PortableObject
{
// ----- constructors ---------------------------------------------------
/**
* Default constructor (necessary for the ExternalizableLite
* and PortableObject interfaces).
*/
public KeyExtractor()
{
// this forces the m_nTarget to be initialized as KEY
this((ValueExtractor) null);
}
/**
* Construct a KeyExtractor based on a specified ValueExtractor.
*
* @param extractor the underlying ValueExtractor
*/
public KeyExtractor(ValueExtractor super T, ? extends E> extractor)
{
m_nTarget = KEY;
m_extractor = extractor == null
? IdentityExtractor.INSTANCE
: Lambdas.ensureRemotable(extractor);
}
/**
* Construct a KeyExtractor for a specified method name.
*
* @param sMethod a method name to construct an underlying
* {@link ReflectionExtractor} for;
* this parameter can also be a dot-delimited sequence
* of method names which would result in a KeyExtractor
* based on the {@link ChainedExtractor} that is based on
* an array of corresponding ReflectionExtractor objects
*/
public KeyExtractor(String sMethod)
{
azzert(sMethod != null, "Method name is missing");
m_nTarget = KEY;
m_extractor = sMethod.indexOf('.') < 0 ? (ValueExtractor)
new ReflectionExtractor(sMethod) :
new ChainedExtractor(sMethod);
}
// ----- ValueExtractor interface ---------------------------------------
/**
* {@inheritDoc}
*/
public E extract(T oTarget)
{
return m_extractor.extract(oTarget);
}
// ----- CanonicallyNamed interface -------------------------------------
@Override
public String getCanonicalName()
{
if (m_sNameCanon == null)
{
// optimization in AbstractExtractor#equals(Object) requires
// AbstractExtractor.m_sNameCanon to be set.
m_sNameCanon = m_extractor.getCanonicalName();
}
return m_sNameCanon;
}
// ----- accessors ------------------------------------------------------
/**
* Obtain the underlying ValueExtractor.
*
* @return the ValueExtractor
*/
public ValueExtractor super T, ? extends E> getExtractor()
{
return m_extractor;
}
// ----- helper methods -------------------------------------------------
/**
* Factory method for key extractor.
*
* @param the type of the value to extract from
* @param the type of value that will be extracted
* @param extractor an extractor to convert to key extractor
*
* @return key extractor based on the specified extractor
*/
public static ValueExtractor of(ValueExtractor extractor)
{
return extractor instanceof KeyExtractor ? extractor : new KeyExtractor<>(extractor);
}
// ----- Object methods -------------------------------------------------
@Override
public boolean equals(Object o)
{
// the super.equals() uses the canonical name comparison (if applies);
// if that succeeds, no other checks are to be made.
if (super.equals(o))
{
return true;
}
else if (isCanonicallyEquatable(o))
{
return false;
}
if (o instanceof KeyExtractor &&
m_extractor instanceof AbstractExtractor)
{
KeyExtractor that = (KeyExtractor) o;
return Base.equals(this.m_extractor, that.m_extractor);
}
return false;
}
/**
* Compute hashCode from underlying {@link ValueExtractor ValueExtractor}.
*
* @return an integer hash value for this KeyExtractor object
*/
@Override
public int hashCode()
{
return m_extractor.hashCode();
}
/**
* Return a human-readable description for this KeyExtractor.
*
* @return a String description of the KeyExtractor
*/
@Override
public String toString()
{
return ClassHelper.getSimpleName(getClass()) +
"(extractor=" + m_extractor + ')';
}
// ----- ExternalizableLite interface -----------------------------------
/**
* {@inheritDoc}
*/
public void readExternal(DataInput in)
throws IOException
{
m_extractor = readObject(in);
}
/**
* {@inheritDoc}
*/
public void writeExternal(DataOutput out)
throws IOException
{
writeObject(out, m_extractor);
}
// ----- PortableObject interface ---------------------------------------
/**
* {@inheritDoc}
*/
public void readExternal(PofReader in)
throws IOException
{
m_extractor = in.readObject(0);
}
/**
* {@inheritDoc}
*/
public void writeExternal(PofWriter out)
throws IOException
{
out.writeObject(0, m_extractor);
}
// ----- data fields ----------------------------------------------------
/**
* The underlying ValueExtractor.
*/
@JsonbProperty("extractor")
protected ValueExtractor super T, ? extends E> m_extractor;
}