/************************************************************************************** * 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; import com.espertech.esper.client.*; import com.espertech.esper.collection.Pair; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.HashMap; import java.util.List; import java.util.Map; /** * EventType than can be supplied with a preconfigured list of properties getters (aka. explicit properties). * @author pablo */ public abstract class BaseConfigurableEventType implements EventTypeSPI { private static Log log = LogFactory.getLog(BaseConfigurableEventType.class); private EventAdapterService eventAdapterService; private final int eventTypeId; private final EventTypeMetadata metadata; private Class underlyngType; private EventPropertyDescriptor[] propertyDescriptors; private String[] propertyNames; private Map<String, Pair<ExplicitPropertyDescriptor, FragmentEventType>> propertyFragmentTypes; /** * Getters for each known property. */ protected Map<String,EventPropertyGetter> propertyGetters; /** * Descriptors for each known property. */ protected Map<String, EventPropertyDescriptor> propertyDescriptorMap; /** * Ctor. * @param underlyngType is the underlying type returned by the event type * @param metadata event type metadata * @param eventAdapterService for dynamic event type creation */ protected BaseConfigurableEventType(EventAdapterService eventAdapterService, EventTypeMetadata metadata, int eventTypeId, Class underlyngType) { this.eventTypeId = eventTypeId; this.eventAdapterService = eventAdapterService; this.metadata = metadata; this.underlyngType = underlyngType; } public int getEventTypeId() { return eventTypeId; } /** * Subclasses must implement this and supply a getter to a given property. * @param property is the property expression * @return getter for property */ protected abstract EventPropertyGetter doResolvePropertyGetter(String property); /** * Subclasses must implement this and return a type for a property. * @param property is the property expression * @return property type */ protected abstract Class doResolvePropertyType(String property); /** * Subclasses must implement this and return a fragment type for a property. * @param property is the property expression * @return fragment property type */ protected abstract FragmentEventType doResolveFragmentType(String property); public String getName() { return metadata.getPrimaryName(); } /** * Returns the event adapter service. * @return event adapter service */ public EventAdapterService getEventAdapterService() { return eventAdapterService; } /** * Sets explicit properties using a map of event property name and getter instance for each property. * @param explicitProperties property descriptors for explicit properties */ protected void initialize(List<ExplicitPropertyDescriptor> explicitProperties) { propertyGetters = new HashMap<String,EventPropertyGetter>(); propertyDescriptors = new EventPropertyDescriptor[explicitProperties.size()]; propertyNames = new String[explicitProperties.size()]; propertyDescriptorMap = new HashMap<String, EventPropertyDescriptor>(); propertyFragmentTypes = new HashMap<String, Pair<ExplicitPropertyDescriptor, FragmentEventType>>(); int count = 0; for (ExplicitPropertyDescriptor explicit : explicitProperties) { propertyNames[count] = explicit.getDescriptor().getPropertyName(); propertyGetters.put(explicit.getDescriptor().getPropertyName(), explicit.getGetter()); EventPropertyDescriptor desc = explicit.getDescriptor(); propertyDescriptors[count] = desc; propertyDescriptorMap.put(desc.getPropertyName(), desc); if (explicit.getOptionalFragmentTypeName() != null) { propertyFragmentTypes.put(explicit.getDescriptor().getPropertyName(), new Pair<ExplicitPropertyDescriptor, FragmentEventType>(explicit, null)); } if (!desc.isFragment()) { propertyFragmentTypes.put(explicit.getDescriptor().getPropertyName(), null); } count++; } } public Class getPropertyType(String propertyExpression) { EventPropertyDescriptor desc = propertyDescriptorMap.get(propertyExpression); if (desc != null) { return desc.getPropertyType(); } return doResolvePropertyType(propertyExpression); } public Class getUnderlyingType() { return underlyngType; } public EventPropertyGetter getGetter(String propertyExpression) { EventPropertyGetter getter = propertyGetters.get(propertyExpression); if (getter != null) { return getter; } return doResolvePropertyGetter(propertyExpression); } public EventPropertyGetterMapped getGetterMapped(String mappedProperty) { return null; } public EventPropertyGetterIndexed getGetterIndexed(String indexedProperty) { return null; } public synchronized FragmentEventType getFragmentType(String property) { Pair<ExplicitPropertyDescriptor, FragmentEventType> pair = propertyFragmentTypes.get(property); if (pair == null) { if (propertyFragmentTypes.containsKey(property)) { return null; } return doResolveFragmentType(property); } // if a type is assigned, use that if (pair.getSecond() != null) { return pair.getSecond(); } // resolve event type EventType existingType = eventAdapterService.getExistsTypeByName(pair.getFirst().getOptionalFragmentTypeName()); if (!(existingType instanceof BaseConfigurableEventType)) { log.warn("Type configured for fragment event property '" + property + "' by name '" + pair.getFirst() + "' could not be found"); return null; } FragmentEventType fragmentType = new FragmentEventType(existingType, pair.getFirst().isFragmentArray(), false); pair.setSecond(fragmentType); return fragmentType; } public String[] getPropertyNames() { return propertyNames; } public boolean isProperty(String property) { return (getGetter(property) != null); } public EventPropertyDescriptor[] getPropertyDescriptors() { return propertyDescriptors; } public EventTypeMetadata getMetadata() { return metadata; } public EventPropertyDescriptor getPropertyDescriptor(String propertyName) { return propertyDescriptorMap.get(propertyName); } }