
com.tangosol.io.pof.reflect.internal.ClassMetadata Maven / Gradle / Ivy
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
package com.tangosol.io.pof.reflect.internal;
import com.tangosol.io.pof.reflect.Codec;
import com.tangosol.util.Base;
import com.tangosol.util.ClassHelper;
import com.tangosol.util.HashHelper;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
/**
* A {@link TypeMetadata} implementation coupled to the Java type metadata
* definition language: {@link Class}, {@link java.lang.reflect.Field}, and
* {@link java.lang.reflect.Method}.
*
* @author hr
* @since 3.7.1
*
* @param the user type this metadata instance describes
*/
public class ClassMetadata
implements TypeMetadata
{
// ----- TypeMetadata interface -----------------------------------------
/**
* {@inheritDoc}
*/
public TypeKey getKey()
{
return m_key;
}
/**
* {@inheritDoc}
*/
public T newInstance()
{
try
{
return m_clz == null ? null : m_clz.newInstance();
}
catch (InstantiationException e)
{
throw Base.ensureRuntimeException(e);
}
catch (IllegalAccessException e)
{
throw Base.ensureRuntimeException(e);
}
}
/**
* {@inheritDoc}
*/
public Iterator> getAttributes()
{
return m_setAttr.iterator();
}
/**
* {@inheritDoc}
*/
public AttributeMetadata getAttribute(String sName)
{
return m_mapAttrByName.get(sName);
}
// ----- accessors ------------------------------------------------------
/**
* Specify the {@link Class} that uniquely identifies this metadata.
*
* @param clz class that defines this type
*/
void setClass(Class clz)
{
m_clz = clz;
}
/**
* Specify the {@link TypeKey}.
*
* @param key unique identifier of this metadata instance
*/
void setKey(TypeKey key)
{
m_key = key;
}
/**
* Specify all {@link AttributeMetadata} instances that represent this
* type.
*
* @param colAttr attribute metadata information to enrich this
* metadata
*/
void setAttributes(Collection> colAttr)
{
Set> setAttrs = m_setAttr;
Map mapAttrByName = m_mapAttrByName;
setAttrs.clear();
setAttrs.addAll(colAttr);
mapAttrByName.clear();
for (AttributeMetadata attribute : colAttr)
{
mapAttrByName.put(attribute.getName(), attribute);
}
}
/**
* Add an attribute to this TypeMetadata.
*
* @param attribute attribute metadata definition to add
*
* @return whether the attribute metadata was added
*/
boolean addAttribute(AttributeMetadata attribute)
{
boolean fAdded = m_setAttr.add(attribute);
// maintain reference
if (fAdded)
{
m_mapAttrByName.put(attribute.getName(), attribute);
}
return fAdded;
}
// ----- Object methods -------------------------------------------------
/**
* {@inheritDoc}
*/
public int hashCode()
{
TypeKey key = m_key;
int hash = HashHelper.hash(key.getTypeId(), 31);
hash = HashHelper.hash(key.getVersionId(), hash);
hash = HashHelper.hash(m_setAttr, hash);
return hash;
}
/**
* {@inheritDoc}
*/
public boolean equals(Object oThat)
{
if (this == oThat)
{
return true;
}
if (!(oThat instanceof TypeMetadata))
{
return false;
}
TypeMetadata that = (TypeMetadata) oThat;
// check key and version
if (!Base.equals(this.getKey(), that.getKey()))
{
return false;
}
for (Iterator> iterThis = m_setAttr.iterator(), iterThat = that.getAttributes();
iterThis.hasNext() || iterThat.hasNext(); )
{
AttributeMetadata attrThis = iterThis.hasNext() ? iterThis.next() : null;
AttributeMetadata attrThat = iterThat.hasNext() ? iterThat.next() : null;
if (!Base.equals(attrThis, attrThat))
{
return false;
}
}
return true;
}
/**
* {@inheritDoc}
*/
public String toString()
{
return String.format("%s (key=%s, attributes=%s)",
ClassHelper.getSimpleName(getClass()),
m_key, m_setAttr);
}
// ----- inner class: ClassKey ------------------------------------------
/**
* A ClassKey contains information to uniquely identify this class type
* instance. Specifically unique identification is a product of
* {@code typeId + versionId + class-hash}.
*/
class ClassKey
implements TypeKey
{
/**
* {@inheritDoc}
*/
public int getTypeId()
{
return m_nTypeId;
}
/**
* {@inheritDoc}
*/
public int getVersionId()
{
return m_nVersionId;
}
/**
* {@inheritDoc}
*/
public int getHash()
{
return m_nHash;
}
// ----- accessors --------------------------------------------------
/**
* Sets the type id of this type to uniquely identify this type.
*
* @param nTypeId type id of this type
*/
void setTypeId(int nTypeId)
{
m_nTypeId = nTypeId;
}
/**
* Sets the version of this type.
*
* @param nVersionId version identifier
*/
void setVersion(int nVersionId)
{
m_nVersionId = nVersionId;
}
/**
* Sets the hash to uniquely identify a ClassMetadata instance.
*
* @param nHash hash of a ClassMetadata instance
*/
void setHash(int nHash)
{
m_nHash = nHash;
}
// ----- Object methods ---------------------------------------------
/**
* {@inheritDoc}
*/
public int hashCode()
{
// the class key will use the hash to determine uniqueness
// whereas the ClassMetadata will not call this hashCode to
// determine its hash but instead uses the appropriate elements
int hash = HashHelper.hash(m_nTypeId, 31);
hash = HashHelper.hash(m_nVersionId, hash);
hash = HashHelper.hash(m_nHash, hash);
return hash;
}
/**
* {@inheritDoc}
*/
public boolean equals(Object oThat)
{
if (this == oThat)
{
return true;
}
if (!(oThat instanceof TypeKey))
{
return false;
}
TypeKey that = (TypeKey) oThat;
return m_nVersionId == that.getVersionId() && m_nTypeId == that.getTypeId()
&& m_nHash == that.getHash();
}
/**
* {@inheritDoc}
*/
public String toString()
{
return String.format("%s (typeId=%d, versionId=%d, hash=%d)",
ClassHelper.getSimpleName(getClass()),
m_nTypeId, m_nVersionId, m_nHash);
}
// ----- data members -----------------------------------------------
/**
* The POF user type id this key represents.
*/
private int m_nTypeId;
/**
* The version of this type.
*/
private int m_nVersionId;
/**
* A hash that uniquely identifies the structure of this class.
*/
private int m_nHash;
}
// ----- inner class: ClassAttribute ------------------------------------
/**
* An {@link AttributeMetadata} implementation acting as a container for
* attribute inspection and invocation.
*
* @see AttributeMetadata
*/
public class ClassAttribute
implements AttributeMetadata, Comparable
{
// ----- AttributeMetadata interface --------------------------------
/**
* {@inheritDoc}
*/
public String getName()
{
return m_sName;
}
/**
* {@inheritDoc}
*/
public int getVersionId()
{
return m_nVersionId;
}
/**
* {@inheritDoc}
*/
public int getIndex()
{
return m_nIndex;
}
/**
* {@inheritDoc}
*/
public Codec getCodec()
{
return m_codec;
}
/**
* {@inheritDoc}
*/
public Object get(T pofType)
{
assertState();
return m_invocationStrategy.get(pofType);
}
/**
* {@inheritDoc}
*/
public void set(T pofType, Object value)
{
assertState();
m_invocationStrategy.set(pofType, value);
}
// ----- Comparable interface ---------------------------------------
/**
* Sorting of attributes is determined by:
*
* - version
* - index
* - name
*
*
* @param o class attribute to compare against
*
* @return a negative integer, zero, or a positive integer as this
* object is less than, equal to, or greater than the
* specified object.
*/
public int compareTo(ClassAttribute o)
{
if (o == this)
{
return 0;
}
int n = m_nVersionId - o.getVersionId();
if (n == 0)
{
n = m_nIndex - o.getIndex();
if (n == 0)
{
String sThis = m_sName;
String sThat = o.getName();
n = sThis == null
? (sThat == null ? 0 : -1)
: (sThat == null ? 1 : sThis.compareTo(sThat));
}
}
return n;
}
// ----- Object methods ---------------------------------------------
/**
* {@inheritDoc}
*/
public int hashCode()
{
int hash = HashHelper.hash(m_nVersionId, 31);
hash = HashHelper.hash(m_nIndex, hash);
hash = HashHelper.hash(m_sName, hash);
return hash;
}
/**
* {@inheritDoc}
*/
public boolean equals(Object oThat)
{
if (this == oThat)
{
return true;
}
if (!(oThat instanceof AttributeMetadata))
{
return false;
}
AttributeMetadata that = (AttributeMetadata) oThat;
return m_nVersionId == that.getVersionId() && m_nIndex == that.getIndex()
&& Base.equals(m_sName, that.getName());
}
/**
* {@inheritDoc}
*/
public String toString()
{
return String.format("%s (name=%s, version=%d, index=%d)",
ClassHelper.getSimpleName(getClass()),
m_sName, m_nVersionId, m_nIndex);
}
// ----- accessors --------------------------------------------------
/**
* Specify the attribute name.
*
* @param sName the normalized name of the attribute
*/
void setName(String sName)
{
m_sName = sName;
}
/**
* Specify the version.
*
* @param nVersionId integer representing the version of this
* attribute metadata
*/
void setVersionId(int nVersionId)
{
m_nVersionId = nVersionId;
}
/**
* Specify the index.
*
* @param nIndex to identify this attribute's position in a sequence
*/
void setIndex(int nIndex)
{
m_nIndex = nIndex;
}
/**
* Specify the codec.
*
* @param codec the {@link Codec} used to (de)serialize this
* attribute
*/
void setCodec(Codec codec)
{
m_codec = codec;
}
/**
* Specify an {@link InvocationStrategy}.
*
* @param invocationStrategy the invocation strategy to use to get
* and set values
*/
void setInvocationStrategy(InvocationStrategy invocationStrategy)
{
m_invocationStrategy = invocationStrategy;
}
// ----- helpers ----------------------------------------------------
/**
* Ensures required state has been correctly set or throws an
* {@link IllegalStateException}.
*
* @throws {@link IllegalStateException} if member variables m_class
* or m_invocationStrategy are null
*/
protected void assertState()
{
if (m_invocationStrategy == null)
{
throw new IllegalStateException("ClassMetadata attribute requires an invocation strategy");
}
}
// ----- data members -----------------------------------------------
/**
* The unique name within this type representing this attribute.
*/
private String m_sName;
/**
* The version of this type information.
*/
private int m_nVersionId;
/**
* Index to identify this attribute's position in a sequence.
*/
private int m_nIndex;
/**
* A {@link Codec} allows reading/writing specific types from/to
* {@code PofReader}s and {@code PofWriter}s.
*/
private Codec m_codec;
/**
* An abstraction on how an attribute is invoked to return its value
* or replace its value.
*/
private InvocationStrategy m_invocationStrategy;
}
// ----- data members ---------------------------------------------------
/**
* The Java representation of the type structure.
*/
private Class m_clz;
/**
* The unique identifier for this type.
*/
private TypeKey m_key;
/**
* All attributes within this typeIterator.
*/
private Set> m_setAttr = new TreeSet>();
/**
* A reference store for efficient lookup from attribute name to metadata
*/
private Map m_mapAttrByName = new HashMap();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy