/************************************************************************************** * 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.client.EventBean; import com.espertech.esper.client.EventPropertyGetter; import com.espertech.esper.event.EventAdapterService; import com.espertech.esper.util.JavaClassHelper; import java.lang.reflect.Array; import java.util.ArrayDeque; import java.util.Iterator; /** * Base getter for native fragments. */ public abstract class BaseNativePropertyGetter implements EventPropertyGetter { private final EventAdapterService eventAdapterService; private volatile BeanEventType fragmentEventType; private final Class fragmentClassType; private boolean isFragmentable; private final boolean isArray; private final boolean isIterable; /** * Constructor. * @param eventAdapterService factory for event beans and event types * @param returnType type of the entry returned * @param genericType type generic parameter, if any */ public BaseNativePropertyGetter(EventAdapterService eventAdapterService, Class returnType, Class genericType) { this.eventAdapterService = eventAdapterService; if (returnType.isArray()) { this.fragmentClassType = returnType.getComponentType(); isArray = true; isIterable = false; } else if (JavaClassHelper.isImplementsInterface(returnType, Iterable.class)) { this.fragmentClassType = genericType; isArray = false; isIterable = true; } else { this.fragmentClassType = returnType; isArray = false; isIterable = false; } isFragmentable = true; } /** * Returns the fragment for dynamic properties. * @param object to inspect * @param eventAdapterService factory for event beans and event types * @return fragment */ public static Object getFragmentDynamic(Object object, EventAdapterService eventAdapterService) { if (object == null) { return null; } BeanEventType fragmentEventType = null; boolean isArray = false; if (object.getClass().isArray()) { if (JavaClassHelper.isFragmentableType(object.getClass().getComponentType())) { isArray = true; fragmentEventType = eventAdapterService.getBeanEventTypeFactory().createBeanTypeDefaultName(object.getClass().getComponentType()); } } else { if (JavaClassHelper.isFragmentableType(object.getClass())) { fragmentEventType = eventAdapterService.getBeanEventTypeFactory().createBeanTypeDefaultName(object.getClass()); } } if (fragmentEventType == null) { return null; } if (isArray) { int len = Array.getLength(object); EventBean[] events = new EventBean[len]; int countFilled = 0; for (int i = 0; i < len; i++) { Object element = Array.get(object, i); if (element == null) { continue; } events[countFilled] = eventAdapterService.adapterForTypedBean(element, fragmentEventType); countFilled++; } if (countFilled == len) { return events; } if (countFilled == 0) { return new EventBean[0]; } EventBean[] returnVal = new EventBean[countFilled]; System.arraycopy(events, 0, returnVal, 0, countFilled); return returnVal; } else { return eventAdapterService.adapterForTypedBean(object, fragmentEventType); } } public Object getFragment(EventBean eventBean) { Object object = get(eventBean); if (object == null) { return null; } if (!isFragmentable) { return null; } if (fragmentEventType == null) { if (JavaClassHelper.isFragmentableType(fragmentClassType)) { fragmentEventType = eventAdapterService.getBeanEventTypeFactory().createBeanTypeDefaultName(fragmentClassType); } else { isFragmentable = false; return null; } } if (isArray) { int len = Array.getLength(object); EventBean[] events = new EventBean[len]; int countFilled = 0; for (int i = 0; i < len; i++) { Object element = Array.get(object, i); if (element == null) { continue; } events[countFilled] = eventAdapterService.adapterForTypedBean(element, fragmentEventType); countFilled++; } if (countFilled == len) { return events; } if (countFilled == 0) { return new EventBean[0]; } EventBean[] returnVal = new EventBean[countFilled]; System.arraycopy(events, 0, returnVal, 0, countFilled); return returnVal; } else if (isIterable) { if (!(object instanceof Iterable)) { return null; } Iterator iterator = ((Iterable) object).iterator(); if (!iterator.hasNext()) { return new EventBean[0]; } ArrayDeque<EventBean> events = new ArrayDeque<EventBean>(); while (iterator.hasNext()) { Object next = iterator.next(); if (next == null) { continue; } events.add(eventAdapterService.adapterForTypedBean(next, fragmentEventType)); } return events.toArray(new EventBean[events.size()]); } else { return eventAdapterService.adapterForTypedBean(object, fragmentEventType); } } }