/**************************************************************************************
* Copyright (C) 2008 EsperTech, Inc. All rights reserved. *
* http://esper.codehaus.org *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
**************************************************************************************/
package com.espertech.esper.event.property;
import com.asper.sources.net.sf.cglib.reflect.FastClass;
import com.asper.sources.net.sf.cglib.reflect.FastMethod;
import com.espertech.esper.client.EventPropertyGetter;
import com.espertech.esper.event.EventAdapterService;
import com.espertech.esper.event.EventPropertyGetterAndMapped;
import com.espertech.esper.event.arr.ObjectArrayEventPropertyGetterAndMapped;
import com.espertech.esper.event.arr.ObjectArrayMappedPropertyGetter;
import com.espertech.esper.event.bean.*;
import com.espertech.esper.event.map.MapEventPropertyGetterAndMapped;
import com.espertech.esper.event.map.MapMappedPropertyGetter;
import com.espertech.esper.event.xml.*;
import com.espertech.esper.util.JavaClassHelper;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
/**
* Represents a mapped property or array property, ie. an 'value' property with read method getValue(int index)
* or a 'array' property via read method getArray() returning an array.
*/
public class MappedProperty extends PropertyBase
{
private String key;
public MappedProperty(String propertyName) {
super(propertyName);
}
/**
* Ctor.
* @param propertyName is the property name of the mapped property
* @param key is the key value to access the mapped property
*/
public MappedProperty(String propertyName, String key)
{
super(propertyName);
this.key = key;
}
/**
* Returns the key value for mapped access.
* @return key value
*/
public String getKey()
{
return key;
}
public String[] toPropertyArray()
{
return new String[] {this.getPropertyNameAtomic()};
}
public boolean isDynamic()
{
return false;
}
public EventPropertyGetterAndMapped getGetter(BeanEventType eventType, EventAdapterService eventAdapterService)
{
InternalEventPropDescriptor propertyDesc = eventType.getMappedProperty(propertyNameAtomic);
if (propertyDesc != null)
{
Method method = propertyDesc.getReadMethod();
FastClass fastClass = eventType.getFastClass();
if (fastClass != null)
{
FastMethod fastMethod = fastClass.getMethod(method);
return new KeyedFastPropertyGetter(fastMethod, key, eventAdapterService);
}
else
{
return new KeyedMethodPropertyGetter(method, key, eventAdapterService);
}
}
// Try the array as a simple property
propertyDesc = eventType.getSimpleProperty(propertyNameAtomic);
if (propertyDesc == null)
{
return null;
}
Class returnType = propertyDesc.getReturnType();
if (!JavaClassHelper.isImplementsInterface(returnType, Map.class))
{
return null;
}
if (propertyDesc.getReadMethod() != null)
{
FastClass fastClass = eventType.getFastClass();
Method method = propertyDesc.getReadMethod();
if (fastClass != null)
{
FastMethod fastMethod = fastClass.getMethod(method);
return new KeyedMapFastPropertyGetter(method, fastMethod, key, eventAdapterService);
}
else
{
return new KeyedMapMethodPropertyGetter(method, key, eventAdapterService);
}
}
else
{
Field field = propertyDesc.getAccessorField();
return new KeyedMapFieldPropertyGetter(field, key, eventAdapterService);
}
}
public Class getPropertyType(BeanEventType eventType, EventAdapterService eventAdapterService)
{
InternalEventPropDescriptor propertyDesc = eventType.getMappedProperty(propertyNameAtomic);
if (propertyDesc != null)
{
return propertyDesc.getReadMethod().getReturnType();
}
// Check if this is an method returning array which is a type of simple property
InternalEventPropDescriptor descriptor = eventType.getSimpleProperty(propertyNameAtomic);
if (descriptor == null)
{
return null;
}
Class returnType = descriptor.getReturnType();
if (!JavaClassHelper.isImplementsInterface(returnType, Map.class))
{
return null;
}
if (descriptor.getReadMethod() != null)
{
return JavaClassHelper.getGenericReturnTypeMap(descriptor.getReadMethod(), false);
}
else if (descriptor.getAccessorField() != null)
{
return JavaClassHelper.getGenericFieldTypeMap(descriptor.getAccessorField(), false);
}
else
{
return null;
}
}
public GenericPropertyDesc getPropertyTypeGeneric(BeanEventType eventType, EventAdapterService eventAdapterService)
{
InternalEventPropDescriptor propertyDesc = eventType.getMappedProperty(propertyNameAtomic);
if (propertyDesc != null)
{
return new GenericPropertyDesc(propertyDesc.getReadMethod().getReturnType());
}
// Check if this is an method returning array which is a type of simple property
InternalEventPropDescriptor descriptor = eventType.getSimpleProperty(propertyNameAtomic);
if (descriptor == null)
{
return null;
}
Class returnType = descriptor.getReturnType();
if (!JavaClassHelper.isImplementsInterface(returnType, Map.class))
{
return null;
}
if (descriptor.getReadMethod() != null)
{
Class genericType = JavaClassHelper.getGenericReturnTypeMap(descriptor.getReadMethod(), false);
return new GenericPropertyDesc(genericType);
}
else if (descriptor.getAccessorField() != null)
{
Class genericType = JavaClassHelper.getGenericFieldTypeMap(descriptor.getAccessorField(), false);
return new GenericPropertyDesc(genericType);
}
else
{
return null;
}
}
public Class getPropertyTypeMap(Map optionalMapPropTypes, EventAdapterService eventAdapterService)
{
Object type = optionalMapPropTypes.get(this.getPropertyNameAtomic());
if (type == null)
{
return null;
}
if (type instanceof Class)
{
if (JavaClassHelper.isImplementsInterface((Class) type, Map.class))
{
return Object.class;
}
}
return null; // Mapped properties are not allowed in non-dynamic form in a map
}
public MapEventPropertyGetterAndMapped getGetterMap(Map optionalMapPropTypes, EventAdapterService eventAdapterService)
{
Object type = optionalMapPropTypes.get(getPropertyNameAtomic());
if (type == null)
{
return null;
}
if (type instanceof Class)
{
if (JavaClassHelper.isImplementsInterface((Class) type, Map.class))
{
return new MapMappedPropertyGetter(getPropertyNameAtomic(), this.getKey());
}
}
if (type instanceof Map) {
return new MapMappedPropertyGetter(getPropertyNameAtomic(), this.getKey());
}
return null;
}
public void toPropertyEPL(StringWriter writer)
{
writer.append(propertyNameAtomic);
writer.append("('");
writer.append(key);
writer.append("')");
}
public EventPropertyGetter getGetterDOM(SchemaElementComplex complexProperty, EventAdapterService eventAdapterService, BaseXMLEventType eventType, String propertyExpression)
{
for (SchemaElementComplex complex : complexProperty.getChildren())
{
if (!complex.getName().equals(propertyNameAtomic))
{
continue;
}
for (SchemaItemAttribute attribute : complex.getAttributes())
{
if (!attribute.getName().toLowerCase().equals("id"))
{
continue;
}
}
return new DOMMapGetter(propertyNameAtomic, key, null);
}
return null;
}
public EventPropertyGetter getGetterDOM()
{
return new DOMMapGetter(propertyNameAtomic, key, null);
}
public SchemaItem getPropertyTypeSchema(SchemaElementComplex complexProperty, EventAdapterService eventAdapterService)
{
for (SchemaElementComplex complex : complexProperty.getChildren())
{
if (!complex.getName().equals(propertyNameAtomic))
{
continue;
}
for (SchemaItemAttribute attribute : complex.getAttributes())
{
if (!attribute.getName().toLowerCase().equals("id"))
{
continue;
}
}
return complex;
}
return null;
}
public ObjectArrayEventPropertyGetterAndMapped getGetterObjectArray(Map<String, Integer> indexPerProperty, Map<String, Object> nestableTypes, EventAdapterService eventAdapterService) {
Integer index = indexPerProperty.get(propertyNameAtomic);
if (index == null) {
return null;
}
Object type = nestableTypes.get(getPropertyNameAtomic());
if (type instanceof Class)
{
if (JavaClassHelper.isImplementsInterface((Class) type, Map.class))
{
return new ObjectArrayMappedPropertyGetter(index, this.getKey());
}
}
if (type instanceof Map) {
return new ObjectArrayMappedPropertyGetter(index, this.getKey());
}
return null;
}
}