com.tangosol.util.extractor.ReflectionUpdater 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, 2024, 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.io.ExternalizableLite;
import com.tangosol.io.ResolvingObjectInputStream;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
import com.tangosol.util.ClassHelper;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import javax.json.bind.annotation.JsonbProperty;
/**
* Reflection-based ValueUpdater implementation.
*
* @author gg 2005.10.27
*
* @see CompositeUpdater
*/
public class ReflectionUpdater
extends AbstractUpdater
implements ExternalizableLite, PortableObject
{
// ----- constructors ---------------------------------------------------
/**
* Default constructor (necessary for the ExternalizableLite interface).
*/
public ReflectionUpdater()
{
}
/**
* Construct a ReflectionUpdater for a given method name.
* This implementation assumes that the corresponding classes will have
* one and only one method with a specified name and this method will have
* exactly one parameter.
*
* @param sMethod the name of the method to invoke via reflection
*/
public ReflectionUpdater(String sMethod)
{
azzert(sMethod != null);
m_sMethod = sMethod;
}
// ----- ValueUpdater interface -----------------------------------------
/**
* {@inheritDoc}
*/
public void update(Object oTarget, Object oValue)
{
if (oTarget == null)
{
throw new IllegalArgumentException(
"Target object is missing for the Updater: " + this);
}
Class clzTarget = oTarget.getClass();
String sMethod = getMethodName();
try
{
Method method = m_methodPrev;
if (method == null || method.getDeclaringClass() != clzTarget)
{
Class[] aclzParam = new Class[1];
if (oValue != null)
{
aclzParam[0] = oValue.getClass();
}
if (!ClassHelper.isReflectionAllowed(oTarget))
{
throw new IllegalArgumentException("The type, " + clzTarget.getName() +
", is disallowed as a reflection target by the current " +
"reflection filter configuration");
}
m_methodPrev = method =
ClassHelper.findMethod(clzTarget, sMethod, aclzParam, false);
}
method.invoke(oTarget, oValue);
}
catch (NullPointerException e)
{
throw new RuntimeException("Missing or inaccessible method: " +
clzTarget.getName() + '#' + sMethod);
}
catch (Exception e)
{
throw ensureRuntimeException(e,
clzTarget.getName() + '#' + sMethod + '(' + oTarget +')');
}
}
// ----- accessors and helpers ------------------------------------------
/**
* Determine the name of the method that this extractor is configured to
* invoke.
*
* @return the name of the method to invoke using reflection
*/
public String getMethodName()
{
return m_sMethod;
}
// ----- Object methods -------------------------------------------------
/**
* Compare the ReflectionUpdater with another object to determine
* equality.
*
* @return true iff this ReflectionUpdater and the passed object are
* equivalent ReflectionUpdaters
*/
public boolean equals(Object o)
{
if (o instanceof ReflectionUpdater)
{
ReflectionUpdater that = (ReflectionUpdater) o;
return this.m_sMethod.equals(that.m_sMethod);
}
return false;
}
/**
* Determine a hash value for the ReflectionUpdater object according to
* the general {@link Object#hashCode()} contract.
*
* @return an integer hash value for this ReflectionUpdater object
*/
public int hashCode()
{
return m_sMethod.hashCode();
}
/**
* Provide a human-readable description of this ValueUpdater object.
*
* @return a human-readable description of this ValueUpdater object
*/
public String toString()
{
return '&' + m_sMethod;
}
// ----- ExternalizableLite interface -----------------------------------
/**
* {@inheritDoc}
*/
public void readExternal(DataInput in)
throws IOException
{
m_sMethod = in.readUTF();
}
/**
* {@inheritDoc}
*/
public void writeExternal(DataOutput out)
throws IOException
{
out.writeUTF(m_sMethod);
}
// ----- PortableObject interface ---------------------------------------
/**
* {@inheritDoc}
*/
public void readExternal(PofReader in)
throws IOException
{
m_sMethod = in.readString(0);
}
/**
* {@inheritDoc}
*/
public void writeExternal(PofWriter out)
throws IOException
{
out.writeString(0, m_sMethod);
}
// ----- Serializable methods -------------------------------------------
/**
* See {@link java.io.Serializable} for documentation on this method.
*
* @param inputStream the input stream
*
* @throws NotSerializableException, ClassNotFoundException, IOException
*
* @since 12.2.1.4.22
*/
private void readObject(ObjectInputStream inputStream) throws ClassNotFoundException, IOException
{
if (inputStream instanceof ResolvingObjectInputStream)
{
// the input stream was created by ExternalizableHelper; proceed with deserialization
inputStream.defaultReadObject();
}
else
{
// this class is not intended for "external" use
throw new NotSerializableException();
}
}
// ----- data members ---------------------------------------------------
/**
* The name of the method to invoke.
*/
@JsonbProperty("method")
protected String m_sMethod;
/**
* A cached reflection method (to avoid repeated look-ups).
*/
@JsonbProperty("methodPrev")
private transient Method m_methodPrev;
}