public MapEventPropertyGetter getGetterMap( Map optionalMapPropTypes, EventAdapterService eventAdapterService) { List<EventPropertyGetter> getters = new LinkedList<EventPropertyGetter>(); Map currentDictionary = optionalMapPropTypes; int count = 0; for (Iterator<Property> it = properties.iterator(); it.hasNext(); ) { count++; Property property = it.next(); // manufacture a getter for getting the item out of the map EventPropertyGetter getter = property.getGetterMap(currentDictionary, eventAdapterService); if (getter == null) { return null; } getters.add(getter); PropertyBase theBase = (PropertyBase) property; String propertyName = theBase.getPropertyNameAtomic(); // For the next property if there is one, check how to property type is defined if (!it.hasNext()) { continue; } if (currentDictionary != null) { // check the type that this property will return Object propertyReturnType = currentDictionary.get(propertyName); if (propertyReturnType == null) { currentDictionary = null; } if (propertyReturnType != null) { if (propertyReturnType instanceof Map) { currentDictionary = (Map) propertyReturnType; } else if (propertyReturnType == Map.class) { currentDictionary = null; } else if (propertyReturnType instanceof String) { String nestedName = propertyReturnType.toString(); boolean isArray = EventTypeUtility.isPropertyArray(nestedName); if (isArray) { nestedName = EventTypeUtility.getPropertyRemoveArray(nestedName); } EventType innerType = eventAdapterService.getExistsTypeByName(nestedName); if (innerType == null) { return null; } String remainingProps = toPropertyEPL(properties, count); EventPropertyGetter getterInner = innerType.getGetter(remainingProps); if (getterInner == null) { return null; } getters.add(getterInner); break; // the single Pojo getter handles the rest } else if (propertyReturnType instanceof EventType) { EventType innerType = (EventType) propertyReturnType; String remainingProps = toPropertyEPL(properties, count); EventPropertyGetter getterInner = innerType.getGetter(remainingProps); if (getterInner == null) { return null; } getters.add(getterInner); break; // the single Pojo getter handles the rest } else { // treat the return type of the map property as a POJO Class pojoClass = (Class) propertyReturnType; if (!pojoClass.isArray()) { BeanEventType beanType = eventAdapterService .getBeanEventTypeFactory() .createBeanType(pojoClass.getName(), pojoClass, false, false, false); String remainingProps = toPropertyEPL(properties, count); EventPropertyGetter getterInner = beanType.getGetter(remainingProps); if (getterInner == null) { return null; } getters.add(getterInner); break; // the single Pojo getter handles the rest } else { Class componentType = pojoClass.getComponentType(); BeanEventType beanType = eventAdapterService .getBeanEventTypeFactory() .createBeanType(componentType.getName(), componentType, false, false, false); String remainingProps = toPropertyEPL(properties, count); EventPropertyGetter getterInner = beanType.getGetter(remainingProps); if (getterInner == null) { return null; } getters.add(getterInner); break; // the single Pojo getter handles the rest } } } } } boolean hasNonmapGetters = false; for (int i = 0; i < getters.size(); i++) { if (!(getters.get(i) instanceof MapEventPropertyGetter)) { hasNonmapGetters = true; } } if (!hasNonmapGetters) { return new MapNestedPropertyGetterMapOnly(getters, eventAdapterService); } else { return new MapNestedPropertyGetterMixedType(getters, eventAdapterService); } }