/**************************************************************************************
* 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.bean;
import com.espertech.esper.event.bean.InternalEventPropDescriptor;
import com.espertech.esper.event.EventPropertyType;
import com.espertech.esper.client.ConfigurationEventTypeLegacy;
import com.espertech.esper.client.ConfigurationException;
import java.util.List;
import java.util.LinkedList;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* Introspector that considers explicitly configured event properties only.
*/
public class PropertyListBuilderExplicit implements PropertyListBuilder
{
private ConfigurationEventTypeLegacy legacyConfig;
/**
* Ctor.
* @param legacyConfig is a legacy type specification containing
* information about explicitly configured fields and methods
*/
public PropertyListBuilderExplicit(ConfigurationEventTypeLegacy legacyConfig)
{
if (legacyConfig == null)
{
throw new IllegalArgumentException("Required configuration not passed");
}
this.legacyConfig = legacyConfig;
}
public List<InternalEventPropDescriptor> assessProperties(Class clazz)
{
List<InternalEventPropDescriptor> result = new LinkedList<InternalEventPropDescriptor>();
getExplicitProperties(result, clazz, legacyConfig);
return result;
}
/**
* Populates explicitly-defined properties into the result list.
* @param result is the resulting list of event property descriptors
* @param clazz is the class to introspect
* @param legacyConfig supplies specification of explicit methods and fields to expose
*/
protected static void getExplicitProperties(List<InternalEventPropDescriptor> result,
Class clazz,
ConfigurationEventTypeLegacy legacyConfig)
{
for (ConfigurationEventTypeLegacy.LegacyFieldPropDesc desc : legacyConfig.getFieldProperties())
{
result.add(makeDesc(clazz, desc));
}
for (ConfigurationEventTypeLegacy.LegacyMethodPropDesc desc : legacyConfig.getMethodProperties())
{
result.add(makeDesc(clazz, desc));
}
}
private static InternalEventPropDescriptor makeDesc(Class clazz, ConfigurationEventTypeLegacy.LegacyMethodPropDesc methodDesc)
{
Method[] methods = clazz.getMethods();
Method method = null;
for (int i = 0; i < methods.length; i++)
{
if (!methods[i].getName().equals(methodDesc.getAccessorMethodName()))
{
continue;
}
if (methods[i].getReturnType() == void.class)
{
continue;
}
if (methods[i].getParameterTypes().length >= 2)
{
continue;
}
if (methods[i].getParameterTypes().length == 0)
{
method = methods[i];
break;
}
Class parameterType = methods[i].getParameterTypes()[0];
if ((parameterType != int.class) && ((parameterType != Integer.class)) &&
(parameterType != String.class))
{
continue;
}
method = methods[i];
break;
}
if (method == null)
{
throw new ConfigurationException("Configured method named '" +
methodDesc.getAccessorMethodName() + "' not found for class " + clazz.getName());
}
return makeMethodDesc(method, methodDesc.getName());
}
private static InternalEventPropDescriptor makeDesc(Class clazz, ConfigurationEventTypeLegacy.LegacyFieldPropDesc fieldDesc)
{
Field field;
try
{
field = clazz.getField(fieldDesc.getAccessorFieldName());
}
catch (NoSuchFieldException ex)
{
throw new ConfigurationException("Configured field named '" +
fieldDesc.getAccessorFieldName() + "' not found for class " + clazz.getName());
}
return makeFieldDesc(field, fieldDesc.getName());
}
/**
* Makes a simple-type event property descriptor based on a reflected field.
* @param field is the public field
* @param name is the name of the event property
* @return property descriptor
*/
protected static InternalEventPropDescriptor makeFieldDesc(Field field, String name)
{
return new InternalEventPropDescriptor(name, field, EventPropertyType.SIMPLE);
}
/**
* Makes an event property descriptor based on a reflected method, considering
* the methods parameters to determine if this is an indexed or mapped event property.
* @param method is the public method
* @param name is the name of the event property
* @return property descriptor
*/
protected static InternalEventPropDescriptor makeMethodDesc(Method method, String name)
{
EventPropertyType propertyType;
if (method.getParameterTypes().length == 1)
{
Class parameterType = method.getParameterTypes()[0];
if (parameterType == String.class)
{
propertyType = EventPropertyType.MAPPED;
}
else
{
propertyType = EventPropertyType.INDEXED;
}
}
else
{
propertyType = EventPropertyType.SIMPLE;
}
return new InternalEventPropDescriptor(name, method, propertyType);
}
}