blob: ad299e2ba43092a4c33beae4388864e3127f6636 [file] [log] [blame]
/*=========================================================================
* (c)Copyright 2002-2011, GemStone Systems, Inc. All Rights Reserved.
* 1260 NW Waterhouse Ave., Suite 200, Beaverton, OR 97006
* All Rights Reserved.
* =======================================================================*/
package com.gemstone.gemfire.mgmt.DataBrowser.query.internal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import com.gemstone.gemfire.mgmt.DataBrowser.query.ColumnNotFoundException;
import com.gemstone.gemfire.mgmt.DataBrowser.query.ColumnValueNotAvailableException;
import com.gemstone.gemfire.mgmt.DataBrowser.query.IntrospectionException;
import com.gemstone.gemfire.mgmt.DataBrowser.query.IntrospectionRepository;
import com.gemstone.gemfire.mgmt.DataBrowser.query.IntrospectionResult;
import com.gemstone.gemfire.mgmt.DataBrowser.query.QueryExecutionException;
import com.gemstone.gemfire.mgmt.DataBrowser.query.QueryUtil;
/**
* This class provides functionality to introspect a given class and perform
* necessary object-to-relational transformations to flatten the objects.
*
* @author Hrishi
**/
public final class ObjectTypeResultImpl implements IntrospectionResult {
private Class<?> type_ = null;
private List<ObjectColumn> fields_ = null;
public ObjectTypeResultImpl(Class<?> ty) {
type_ = ty;
fields_ = new ArrayList<ObjectColumn>();
}
public int getResultType() {
return COMPOSITE_TYPE_RESULT;
}
void setObjectColumns(Collection<ObjectColumn> columns) {
fields_.clear();
fields_.addAll(columns);
}
public ObjectColumn getObjectColumn(int index) {
if (fields_.size() > index) {
return fields_.get(index);
}
return null;
}
public Class getColumnClass(int index) throws ColumnNotFoundException {
if (fields_.size() > index) {
ObjectColumn col = fields_.get(index);
return col.getFieldType();
}
throw new ColumnNotFoundException("Column not available for index :"
+ index);
}
public Class getColumnClass(Object tuple, int index)
throws ColumnNotFoundException {
int type = getColumnType(index);
ObjectColumn col = fields_.get(index);
if(type == IntrospectionResult.UNKNOWN_TYPE_COLUMN && (tuple != null)) {
try {
Object val = col.getValue(tuple);
if(val != null) {
return val.getClass();
}
}
catch (ColumnValueNotAvailableException e) {
throw new ColumnNotFoundException(e);
}
}
return col.getFieldType();
}
public Class<?> getJavaType() {
return type_;
}
public int getColumnCount() {
return fields_.size();
}
public String getColumnName(int index) throws ColumnNotFoundException {
if (fields_.size() > index) {
ObjectColumn col = fields_.get(index);
return col.getFieldName();
}
throw new ColumnNotFoundException("Column not available for index :"
+ index);
}
public int getColumnIndex(String name) throws ColumnNotFoundException {
for (ObjectColumn column : fields_) {
if (column.getFieldName().equals(name)) {
return fields_.indexOf(column);
}
}
throw new ColumnNotFoundException("Column not available for name :" + name);
}
public int getColumnType(int index) throws ColumnNotFoundException {
// TODO: Hrishi it is a zero based index right?
/*
if (index > fields_.size()) {
throw new ColumnNotFoundException("Column not available for index :"
+ index);
}
ObjectColumn col = fields_.get(index);
if (QueryUtil.isPrimitiveType(col.getFieldType()))
return IntrospectionResult.PRIMITIVE_TYPE_COLUMN;
else if (QueryUtil.isCompositeType(col.getFieldType())) {
if(col.isFinal())
return IntrospectionResult.COMPOSITE_TYPE_COLUMN;
return IntrospectionResult.UNKNOWN_TYPE_COLUMN;
} else if (QueryUtil.isCollectionType(col.getFieldType()))
return IntrospectionResult.COLLECTION_TYPE_COLUMN;
else if (QueryUtil.isMapType(col.getFieldType()))
return IntrospectionResult.MAP_TYPE_COLUMN;
throw new ColumnNotFoundException(
"Unable to detect the column type for index :" + index);
*/
final ObjectColumn col;
int iRes = IntrospectionResult.UNDEFINED;
String sXptnMsg = null;
try {
col = fields_.get(index);
if (QueryUtil.isPrimitiveType(col.getFieldType()))
iRes = IntrospectionResult.PRIMITIVE_TYPE_COLUMN;
else if (QueryUtil.isCompositeType(col.getFieldType())) {
if(col.isFinal())
iRes = IntrospectionResult.COMPOSITE_TYPE_COLUMN;
else
iRes = IntrospectionResult.UNKNOWN_TYPE_COLUMN;
} else if (QueryUtil.isCollectionType(col.getFieldType()))
iRes = IntrospectionResult.COLLECTION_TYPE_COLUMN;
else if (QueryUtil.isMapType(col.getFieldType()))
iRes = IntrospectionResult.MAP_TYPE_COLUMN;
if( IntrospectionResult.UNDEFINED == iRes ) {
sXptnMsg = "Unable to detect the column type for index :" + index;
}
}
catch( IndexOutOfBoundsException xptn ) {
sXptnMsg = "Column not available for index : " + index;
}
if( null != sXptnMsg ) {
throw new ColumnNotFoundException( sXptnMsg );
}
return iRes;
}
public int getColumnType(Object tuple, int index)
throws ColumnNotFoundException {
int type = getColumnType(index);
ObjectColumn col = fields_.get(index);
if(type == IntrospectionResult.UNKNOWN_TYPE_COLUMN && tuple != null) {
try {
Object value = col.getValue(tuple);
if(value != null) {
IntrospectionResult result = IntrospectionRepository.singleton().introspectTypeByObject(value);
switch(result.getResultType()) {
case PRIMITIVE_TYPE_RESULT : return PRIMITIVE_TYPE_COLUMN;
case COMPOSITE_TYPE_RESULT : return COMPOSITE_TYPE_COLUMN;
case COLLECTION_TYPE_RESULT : return COLLECTION_TYPE_COLUMN;
case MAP_TYPE_RESULT : return MAP_TYPE_COLUMN;
case PDX_TYPE_RESULT : return PDX_TYPE_COLUMN;
}
}
}
catch (ColumnValueNotAvailableException e) {
throw new ColumnNotFoundException(e);
} catch (IntrospectionException e) {
throw new ColumnNotFoundException(e);
}
}
return type;
}
public Object getColumnValue(Object tuple, int index)
throws ColumnNotFoundException, ColumnValueNotAvailableException {
if (fields_.size() > index) {
ObjectColumn col = fields_.get(index);
int type = getColumnType(tuple, index);
switch (type) {
case COMPOSITE_TYPE_COLUMN: {
//In this case we don't need to make sure that the type of the field is
//introspected, because that is already done in ObjectIntrospector class during init.
return col.getValue(tuple);
}
case COLLECTION_TYPE_COLUMN: {
if(col.getFieldType().isArray()) {
try {
return QueryUtil.introspectArrayType(col.getFieldType(), col.getValue(tuple));
}
catch (IntrospectionException e) {
throw new ColumnValueNotAvailableException(e);
}
}
Collection< Object > result = (Collection<Object>) col.getValue(tuple);
try {
return QueryUtil.introspectCollectionObject(result);
} catch (QueryExecutionException e) {
throw new ColumnValueNotAvailableException(e);
}
}
case MAP_TYPE_COLUMN: {
Map result = (Map)col.getValue(tuple);
Collection temp = null;
if(result != null)
temp = result.entrySet();
try {
return QueryUtil.introspectCollectionObject(temp);
}
catch (QueryExecutionException e) {
throw new ColumnValueNotAvailableException(e);
}
}
default: return col.getValue(tuple);
}
}
throw new ColumnNotFoundException("Column not available for index :"
+ index);
}
public String getJavaTypeName() {
Class<?> javaType = getJavaType();
return javaType != null ? javaType.getName() : null;
}
public boolean isCompatible(Object data) {
//checks for equality by reference not assignable. Using == assuming single
//instance of a class
return data != null && getJavaType() == data.getClass();
}
}