blob: c5c13a585dae3aa20605089c95e54f0618d1db02 [file] [log] [blame]
/*
* =========================================================================
* Copyright (c) 2002-2012 VMware, Inc. All Rights Reserved.
* This product is protected by U.S. and international copyright
* and intellectual property laws. VMware products are covered by
* more patents listed at http://www.vmware.com/go/patents.
* All Rights Reserved.
* ========================================================================
*/
package com.gemstone.gemfire.mgmt.DataBrowser.query.internal;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.gemstone.gemfire.mgmt.DataBrowser.query.ColumnNotFoundException;
import com.gemstone.gemfire.mgmt.DataBrowser.query.ColumnValueNotAvailableException;
import com.gemstone.gemfire.mgmt.DataBrowser.query.IntrospectionResult;
import com.gemstone.gemfire.pdx.PdxInstance;
/**
* Wraps the IntrospectionResult types for Pdx objects which are:
* <ol> All PdxSeriailzable objects which are available as PdxInstanceImpl
* <ol> or enum which are available as PdxInstance
*
* Wrapped type is decided using the argument passed to the constructor
* {@link #PdxTypesIntrospectionResult(Object, String)}.
*
* @author abhishek
* @since 1.4 (GemFire 6.6.2)
*/
public class PdxTypesIntrospectionResult implements IntrospectionResult {
/* Methods handle to access the isEnum() methods of PdxInstance added in 6.6.2 */
private static final Method isEnumMethod;
/* Wrapped Pdx IntrospectionResult type */
private IntrospectionResult wrapped;
static {
Method methodHandle = null;
try {
methodHandle = PdxInstance.class.getDeclaredMethod("isEnum", new Class[0]);
} catch (SecurityException e) {
methodHandle = null;
} catch (NoSuchMethodException e) {
methodHandle = null;
} finally {
isEnumMethod = methodHandle;
}
}
/**
* Creates a wrapper IntrospectionResult for Pdx Types.
*
* @param pdxInstanceArg
* PdxInstance object to be introspected.
* @param fieldTypeClass
* FieldType fully qualified class name
* @throws PdxIntrospectionException
* if isEnum() method exists & its invocation fails on the given
* PdxInstance
*/
//Note: used by PdxHelper over reflection
public PdxTypesIntrospectionResult(Object pdxInstanceArg, String fieldTypeClass)
throws PdxIntrospectionException {
PdxInstance pdxInstance = null;
if (pdxInstanceArg instanceof PdxInstance) {
pdxInstance = (PdxInstance) pdxInstanceArg;
if (isEnum(pdxInstance)) {
wrapped = new PdxEnumIntrospectionResult(pdxInstance);
// System.out.println("PdxTypesIntrospectionResult.PdxTypesIntrospectionResult(): pdxInstance :: "+pdxInstance +", isEnum: true");
} else {
wrapped = new PdxIntrospectionResult(pdxInstance, fieldTypeClass);
// System.out.println("PdxTypesIntrospectionResult.PdxTypesIntrospectionResult(): pdxInstance :: "+pdxInstance +", isEnum: false");
}
} else {
throw new IllegalArgumentException("Only PdxInstance class is expected.");
}
}
/**
* Returns <code>true</code> if the given PdxInstance has isEnum() methods &
* if it represents a non-PdxSerializable Java enum. Hence, for
* GemFire >= 6.6 & < 6.6.2 this method should return <code>false</code>.
*
* @param pdxInstance
* Pdx Instance to be checked whether it's an enum
* @return true if the given PdxInstance has isEnum() methods & if it
* represents a non-PdxSerializable Java enum.; false otherwise
* @throws PdxIntrospectionException
* if isEnum method exists & its invocation fails on the given
* PdxInstance
*/
private boolean isEnum(PdxInstance pdxInstance) throws PdxIntrospectionException {
boolean isEnum = false;
if (isEnumMethod != null) { // PdxInstance class has isEnum() i.e. it's 6.6.2 or later
try {
isEnum = (Boolean) isEnumMethod.invoke(pdxInstance, new Object[0]);
} catch (IllegalArgumentException e) {
isEnum = false;
throw new PdxIntrospectionException("Could not find PdxInstance.isEnum() in "+pdxInstance);
} catch (IllegalAccessException e) {
throw new PdxIntrospectionException("Could not find PdxInstance.isEnum() in "+pdxInstance);
} catch (InvocationTargetException e) {
throw new PdxIntrospectionException("Could not find PdxInstance.isEnum() in "+pdxInstance);
}
}
return isEnum;
}
@Override
public Class<?> getColumnClass(int index) throws ColumnNotFoundException {
return wrapped.getColumnClass(index);
}
@Override
public Class<?> getColumnClass(Object tuple, int index)
throws ColumnNotFoundException {
return wrapped.getColumnClass(tuple, index);
}
@Override
public int getColumnCount() {
return wrapped.getColumnCount();
}
@Override
public int getColumnIndex(String name) throws ColumnNotFoundException {
return wrapped.getColumnIndex(name);
}
@Override
public String getColumnName(int index) throws ColumnNotFoundException {
return wrapped.getColumnName(index);
}
@Override
public int getColumnType(int index) throws ColumnNotFoundException {
return wrapped.getColumnType(index);
}
@Override
public int getColumnType(Object tuple, int index)
throws ColumnNotFoundException {
return wrapped.getColumnType(tuple, index);
}
@Override
public Object getColumnValue(Object tuple, int index)
throws ColumnNotFoundException, ColumnValueNotAvailableException {
return wrapped.getColumnValue(tuple, index);
}
@Override
public Class<?> getJavaType() {
return wrapped.getJavaType();
}
@Override
public String getJavaTypeName() {
return wrapped.getJavaTypeName();
}
@Override
public int getResultType() {
return wrapped.getResultType();
}
@Override
public boolean isCompatible(Object data) {
return wrapped.isCompatible(data);
}
/**
* Create or return existing PdxInfoType for the given object. If given object
* - 'pdxInstanceArg' - is not of the type PdxInstance, it returns null.
*
* @param pdxInstanceArg
* PdxInstance for which PdxInfoType is to be retrieved
* @return new or existing PdxInfoType for the given object.
*/
//Note: used by PdxHelper over reflection
static PdxInfoType getPdxInfoType(Object pdxInstanceArg) {
//1. Check if it's a 'PdxInstanceImpl'. If yes, retrieve/return PdxInfoType for it
PdxInfoType pdxInfoType = PdxIntrospectionResult.getPdxInfoType(pdxInstanceArg);
//2. Check if it's a 'PdxInstance'. If yes, retrieve/return PdxInfoType for it.
if (pdxInfoType == null) {
pdxInfoType = PdxEnumIntrospectionResult.getPdxInfoType(pdxInstanceArg);
}
return pdxInfoType;
}
/**
* Clears cached known Pdx Instance type Information.
*/
//Note: used by PdxHelper over reflection
static void clearKnownPdxTypeInfo() {
PdxIntrospectionResult.clearKnownPdxTypeInfo();
PdxEnumIntrospectionResult.clearKnownPdxTypeInfo();
}
}