예제 #1
0
  public GenericPropertyDesc getPropertyTypeGeneric(
      BeanEventType eventType, EventAdapterService eventAdapterService) {
    GenericPropertyDesc result = null;

    for (Iterator<Property> it = properties.iterator(); it.hasNext(); ) {
      Property property = it.next();
      result = property.getPropertyTypeGeneric(eventType, eventAdapterService);

      if (result == null) {
        // property not found, return null
        return null;
      }

      if (it.hasNext()) {
        // Map cannot be used to further nest as the type cannot be determined
        if (result.getType() == Map.class) {
          return null;
        }

        if (result.getType().isArray()) {
          return null;
        }

        eventType =
            eventAdapterService
                .getBeanEventTypeFactory()
                .createBeanType(result.getType().getName(), result.getType(), false, false, false);
      }
    }

    return result;
  }
 public void addEventType(String eventTypeName, Class javaEventClass) {
   try {
     eventAdapterService.addBeanType(eventTypeName, javaEventClass, false, true, true);
   } catch (EventAdapterException t) {
     throw new ConfigurationException(t.getMessage(), t);
   }
 }
예제 #3
0
  public Class getPropertyType(BeanEventType eventType, EventAdapterService eventAdapterService) {
    Class result = null;

    for (Iterator<Property> it = properties.iterator(); it.hasNext(); ) {
      Property property = it.next();
      result = property.getPropertyType(eventType, eventAdapterService);

      if (result == null) {
        // property not found, return null
        return null;
      }

      if (it.hasNext()) {
        // Map cannot be used to further nest as the type cannot be determined
        if (result == Map.class) {
          return null;
        }

        if (result.isArray()
            || result.isPrimitive()
            || JavaClassHelper.isJavaBuiltinDataType(result)) {
          return null;
        }

        eventType =
            eventAdapterService
                .getBeanEventTypeFactory()
                .createBeanType(result.getName(), result, false, false, false);
      }
    }

    return result;
  }
  public EventBean copy(EventBean theEvent) {
    ObjectArrayBackedEventBean arrayBacked = (ObjectArrayBackedEventBean) theEvent;
    Object[] props = arrayBacked.getProperties();
    Object[] shallowCopy = new Object[props.length];
    System.arraycopy(props, 0, shallowCopy, 0, props.length);

    for (int index : mapIndexesToCopy) {
      Map<String, Object> innerMap = (Map<String, Object>) shallowCopy[index];
      if (innerMap != null) {
        Map copy = new HashMap<String, Object>(innerMap);
        shallowCopy[index] = copy;
      }
    }

    for (int index : arrayIndexesToCopy) {
      Object array = shallowCopy[index];
      if (array != null && array.getClass().isArray() && Array.getLength(array) != 0) {
        Object copied =
            Array.newInstance(array.getClass().getComponentType(), Array.getLength(array));
        System.arraycopy(array, 0, copied, 0, Array.getLength(array));
        shallowCopy[index] = copied;
      }
    }
    return eventAdapterService.adapterForTypedObjectArray(shallowCopy, eventType);
  }
예제 #5
0
  private static StreamTypeService getStreamTypeService(
      String engineURI,
      String statementId,
      EventAdapterService eventAdapterService,
      Map<String, Pair<EventType, String>> taggedEventTypes,
      Map<String, Pair<EventType, String>> arrayEventTypes,
      Deque<Integer> subexpressionIdStack,
      String objectType) {
    LinkedHashMap<String, Pair<EventType, String>> filterTypes =
        new LinkedHashMap<String, Pair<EventType, String>>();
    filterTypes.putAll(taggedEventTypes);

    // handle array tags (match-until clause)
    if (arrayEventTypes != null) {
      String patternSubexEventType =
          getPatternSubexEventType(statementId, objectType, subexpressionIdStack);
      EventType arrayTagCompositeEventType =
          eventAdapterService.createSemiAnonymousMapType(
              patternSubexEventType, new HashMap(), arrayEventTypes, false);
      for (Map.Entry<String, Pair<EventType, String>> entry : arrayEventTypes.entrySet()) {
        String tag = entry.getKey();
        if (!filterTypes.containsKey(tag)) {
          Pair<EventType, String> pair =
              new Pair<EventType, String>(arrayTagCompositeEventType, tag);
          filterTypes.put(tag, pair);
        }
      }
    }

    return new StreamTypeServiceImpl(filterTypes, engineURI, true, false);
  }
  public Object getFragment(EventBean obj) {
    Object underlying = obj.getUnderlying();

    // The underlying is expected to be a map
    if (!(underlying instanceof Map)) {
      throw new PropertyAccessException(
          "Mismatched property getter to event bean type, "
              + "the underlying data object is not of type java.lang.Map");
    }

    Map map = (Map) underlying;

    Object value = map.get(propertyMap);
    if (value == null) {
      return null;
    }
    if (!value.getClass().isArray()) {
      return null;
    }
    if (Array.getLength(value) <= index) {
      return null;
    }
    Object valueMap = Array.get(value, index);
    if (!(valueMap instanceof Map)) {
      if (value instanceof EventBean) {
        return eventBeanEntryGetter.getFragment((EventBean) value);
      }
      return null;
    }

    // If the map does not contain the key, this is allowed and represented as null
    EventBean eventBean = eventAdapterService.adaptorForTypedMap((Map) valueMap, innerType);
    return eventBeanEntryGetter.getFragment(eventBean);
  }
 public void updateMapEventType(String mapeventTypeName, Map<String, Object> typeMap)
     throws ConfigurationException {
   try {
     eventAdapterService.updateMapEventType(mapeventTypeName, typeMap);
   } catch (EventAdapterException e) {
     throw new ConfigurationException("Error updating Map event type: " + e.getMessage(), e);
   }
 }
 public void addPlugInEventType(
     String eventTypeName, URI[] resolutionURIs, Serializable initializer) {
   try {
     eventAdapterService.addPlugInEventType(eventTypeName, resolutionURIs, initializer);
   } catch (EventAdapterException e) {
     throw new ConfigurationException("Error adding plug-in event type: " + e.getMessage(), e);
   }
 }
 public void addEventType(
     String eventTypeName, String eventClass, ConfigurationEventTypeLegacy legacyEventTypeDesc) {
   try {
     Map<String, ConfigurationEventTypeLegacy> map =
         new HashMap<String, ConfigurationEventTypeLegacy>();
     map.put(eventClass, legacyEventTypeDesc);
     eventAdapterService.setClassLegacyConfigs(map);
     eventAdapterService.addBeanType(eventTypeName, eventClass, false, false, false, true);
   } catch (EventAdapterException ex) {
     throw new ConfigurationException(
         "Failed to add legacy event type definition for type '"
             + eventTypeName
             + "': "
             + ex.getMessage(),
         ex);
   }
 }
 public void addEventType(String eventTypeName, Properties typeMap) {
   Map<String, Object> types = JavaClassHelper.getClassObjectFromPropertyTypeNames(typeMap);
   try {
     eventAdapterService.addNestableMapType(
         eventTypeName, types, null, false, true, true, false, false);
   } catch (EventAdapterException t) {
     throw new ConfigurationException(t.getMessage(), t);
   }
 }
 public EventBean process(
     EventBean[] eventsPerStream,
     boolean isNewData,
     boolean isSynthesize,
     ExprEvaluatorContext exprEvaluatorContext) {
   ObjectArrayBackedEventBean theEvent = (ObjectArrayBackedEventBean) eventsPerStream[0];
   return eventAdapterService.adapterForTypedObjectArray(
       theEvent.getProperties(), resultEventType);
 }
 public void addEventType(
     String eventTypeName, Map<String, Object> typeMap, ConfigurationEventTypeMap mapConfig)
     throws ConfigurationException {
   try {
     eventAdapterService.addNestableMapType(
         eventTypeName, typeMap, mapConfig, false, true, true, false, false);
   } catch (EventAdapterException t) {
     throw new ConfigurationException(t.getMessage(), t);
   }
 }
  public boolean removeEventType(String name, boolean force) throws ConfigurationException {
    if (!force) {
      Set<String> statements = statementEventTypeRef.getStatementNamesForType(name);
      if ((statements != null) && (!statements.isEmpty())) {
        throw new ConfigurationException(
            "Event type '" + name + "' is in use by one or more statements");
      }
    }

    EventType type = eventAdapterService.getExistsTypeByName(name);
    if (type == null) {
      return false;
    }

    eventAdapterService.removeType(name);
    statementEventTypeRef.removeReferencesType(name);
    filterService.removeType(type);
    return true;
  }
 public void addEventType(String eventTypeName, Map<String, Object> typeMap) {
   try {
     Map<String, Object> compiledProperties =
         EventTypeUtility.compileMapTypeProperties(typeMap, eventAdapterService);
     eventAdapterService.addNestableMapType(
         eventTypeName, compiledProperties, null, false, true, true, false, false);
   } catch (EventAdapterException t) {
     throw new ConfigurationException(t.getMessage(), t);
   }
 }
 public void updateObjectArrayEventType(
     String objectArrayEventTypeName, String[] propertyNames, Object[] propertyTypes)
     throws ConfigurationException {
   try {
     LinkedHashMap<String, Object> typeMap =
         EventTypeUtility.validateObjectArrayDef(propertyNames, propertyTypes);
     eventAdapterService.updateObjectArrayEventType(objectArrayEventTypeName, typeMap);
   } catch (EventAdapterException e) {
     throw new ConfigurationException(
         "Error updating Object-array event type: " + e.getMessage(), e);
   }
 }
  public void addEventType(String eventTypeName, Map<String, Object> typeMap, String[] superTypes)
      throws ConfigurationException {
    ConfigurationEventTypeMap optionalConfig = null;
    if ((superTypes != null) && (superTypes.length > 0)) {
      optionalConfig = new ConfigurationEventTypeMap();
      optionalConfig.getSuperTypes().addAll(Arrays.asList(superTypes));
    }

    try {
      eventAdapterService.addNestableMapType(
          eventTypeName, typeMap, optionalConfig, false, true, true, false, false);
    } catch (EventAdapterException t) {
      throw new ConfigurationException(t.getMessage(), t);
    }
  }
  public EventBean copy(EventBean theEvent) {
    Object underlying = theEvent.getUnderlying();
    Object copied;
    try {
      copied = SerializableObjectCopier.copy(underlying);
    } catch (IOException e) {
      log.error("IOException copying event object for update: " + e.getMessage(), e);
      return null;
    } catch (ClassNotFoundException e) {
      log.error("Exception copying event object for update: " + e.getMessage(), e);
      return null;
    }

    return eventAdapterService.adapterForTypedBean(copied, beanEventType);
  }
  public void replaceXMLEventType(String xmlEventTypeName, ConfigurationEventTypeXMLDOM config)
      throws ConfigurationException {
    SchemaModel schemaModel = null;
    if (config.getSchemaResource() != null || config.getSchemaText() != null) {
      try {
        schemaModel =
            XSDSchemaMapper.loadAndMap(config.getSchemaResource(), config.getSchemaText(), 2);
      } catch (Exception ex) {
        throw new ConfigurationException(ex.getMessage(), ex);
      }
    }

    try {
      eventAdapterService.replaceXMLEventType(xmlEventTypeName, config, schemaModel);
    } catch (EventAdapterException e) {
      throw new ConfigurationException("Error updating XML event type: " + e.getMessage(), e);
    }
  }
  public void addEventType(String eventTypeName, ConfigurationEventTypeXMLDOM xmlDOMEventTypeDesc) {
    SchemaModel schemaModel = null;

    if ((xmlDOMEventTypeDesc.getSchemaResource() != null)
        || (xmlDOMEventTypeDesc.getSchemaText() != null)) {
      try {
        schemaModel =
            XSDSchemaMapper.loadAndMap(
                xmlDOMEventTypeDesc.getSchemaResource(), xmlDOMEventTypeDesc.getSchemaText(), 2);
      } catch (Exception ex) {
        throw new ConfigurationException(ex.getMessage(), ex);
      }
    }

    try {
      eventAdapterService.addXMLDOMType(eventTypeName, xmlDOMEventTypeDesc, schemaModel, false);
    } catch (EventAdapterException t) {
      throw new ConfigurationException(t.getMessage(), t);
    }
  }
예제 #20
0
  public EventPropertyGetter getGetter(
      BeanEventType eventType, EventAdapterService eventAdapterService) {
    List<EventPropertyGetter> getters = new LinkedList<EventPropertyGetter>();

    Property lastProperty = null;
    for (Iterator<Property> it = properties.iterator(); it.hasNext(); ) {
      Property property = it.next();
      lastProperty = property;
      EventPropertyGetter getter = property.getGetter(eventType, eventAdapterService);
      if (getter == null) {
        return null;
      }

      if (it.hasNext()) {
        Class clazz = property.getPropertyType(eventType, eventAdapterService);
        if (clazz == null) {
          // if the property is not valid, return null
          return null;
        }
        // Map cannot be used to further nest as the type cannot be determined
        if (clazz == Map.class) {
          return null;
        }
        if (clazz.isArray()) {
          return null;
        }
        eventType =
            eventAdapterService
                .getBeanEventTypeFactory()
                .createBeanType(clazz.getName(), clazz, false, false, false);
      }
      getters.add(getter);
    }

    GenericPropertyDesc finalPropertyType =
        lastProperty.getPropertyTypeGeneric(eventType, eventAdapterService);
    return new NestedPropertyGetter(
        getters, eventAdapterService, finalPropertyType.getType(), finalPropertyType.getGeneric());
  }
  public Object getMap(Map<String, Object> map) throws PropertyAccessException {
    Object value = map.get(propertyMap);
    if (value == null) {
      return null;
    }
    if (!value.getClass().isArray()) {
      return null;
    }
    if (Array.getLength(value) <= index) {
      return null;
    }
    Object valueMap = Array.get(value, index);
    if (!(valueMap instanceof Map)) {
      if (value instanceof EventBean) {
        return eventBeanEntryGetter.get((EventBean) value);
      }
      return null;
    }

    // If the map does not contain the key, this is allowed and represented as null
    EventBean eventBean = eventAdapterService.adaptorForTypedMap((Map) valueMap, innerType);
    return eventBeanEntryGetter.get(eventBean);
  }
 public void addEventType(
     String eventTypeName,
     String[] propertyNames,
     Object[] propertyTypes,
     ConfigurationEventTypeObjectArray optionalConfiguration)
     throws ConfigurationException {
   try {
     LinkedHashMap<String, Object> propertyTypesMap =
         EventTypeUtility.validateObjectArrayDef(propertyNames, propertyTypes);
     Map<String, Object> compiledProperties =
         EventTypeUtility.compileMapTypeProperties(propertyTypesMap, eventAdapterService);
     eventAdapterService.addNestableObjectArrayType(
         eventTypeName,
         compiledProperties,
         optionalConfiguration,
         false,
         true,
         true,
         false,
         false);
   } catch (EventAdapterException t) {
     throw new ConfigurationException(t.getMessage(), t);
   }
 }
  public List<EventBean> poll(Object[] lookupValues) {
    List<EventBean> rowResult = null;
    try {
      Object invocationResult = method.invoke(null, lookupValues);
      if (invocationResult != null) {
        if (isArray) {
          int length = Array.getLength(invocationResult);
          if (length > 0) {
            rowResult = new ArrayList<EventBean>();
            for (int i = 0; i < length; i++) {
              Object value = Array.get(invocationResult, i);
              if (value == null) {
                log.warn(
                    "Expected non-null return result from method '"
                        + method.getName()
                        + "', but received null value");
                continue;
              }

              EventBean theEvent;
              if (useMapType) {
                if (!(value instanceof Map)) {
                  log.warn(
                      "Expected Map-type return result from method '"
                          + method.getName()
                          + "', but received type '"
                          + value.getClass()
                          + "'");
                  continue;
                }
                Map mapValues = (Map) value;
                theEvent = eventAdapterService.adapterForTypedMap(mapValues, eventType);
              } else {
                theEvent = eventAdapterService.adapterForBean(value);
              }

              rowResult.add(theEvent);
            }
          }
        } else {
          rowResult = new LinkedList<EventBean>();

          EventBean theEvent;
          if (useMapType) {
            if (!(invocationResult instanceof Map)) {
              log.warn(
                  "Expected Map-type return result from method '"
                      + method.getName()
                      + "', but received type '"
                      + invocationResult.getClass()
                      + "'");
            } else {
              Map mapValues = (Map) invocationResult;
              theEvent = eventAdapterService.adapterForTypedMap(mapValues, eventType);
              rowResult.add(theEvent);
            }
          } else {
            theEvent = eventAdapterService.adapterForBean(invocationResult);
            rowResult.add(theEvent);
          }
        }
      }
    } catch (InvocationTargetException ex) {
      throw new EPException(
          "Method '"
              + method.getName()
              + "' of class '"
              + method.getJavaMethod().getDeclaringClass().getName()
              + "' reported an exception: "
              + ex.getTargetException(),
          ex.getTargetException());
    }

    return rowResult;
  }
  private List<EventBean> execute(
      PreparedStatement preparedStatement, Object[] lookupValuePerStream) {
    if (ExecutionPathDebugLog.isDebugEnabled && log.isInfoEnabled()) {
      log.info(".execute Executing prepared statement '" + preparedStatementText + "'");
    }

    // set parameters
    SQLInputParameterContext inputParameterContext = null;
    if (columnTypeConversionHook != null) {
      inputParameterContext = new SQLInputParameterContext();
    }

    int count = 1;
    for (int i = 0; i < lookupValuePerStream.length; i++) {
      try {
        Object parameter = lookupValuePerStream[i];
        if (ExecutionPathDebugLog.isDebugEnabled && log.isInfoEnabled()) {
          log.info(
              ".execute Setting parameter "
                  + count
                  + " to "
                  + parameter
                  + " typed "
                  + ((parameter == null) ? "null" : parameter.getClass()));
        }

        if (columnTypeConversionHook != null) {
          inputParameterContext.setParameterNumber(i + 1);
          inputParameterContext.setParameterValue(parameter);
          parameter = columnTypeConversionHook.getParameterValue(inputParameterContext);
        }

        setObject(preparedStatement, count, parameter);
      } catch (SQLException ex) {
        throw new EPException("Error setting parameter " + count, ex);
      }

      count++;
    }

    // execute
    ResultSet resultSet;
    if (enableJDBCLogging && jdbcPerfLog.isInfoEnabled()) {
      long startTimeNS = System.nanoTime();
      long startTimeMS = System.currentTimeMillis();
      try {
        resultSet = preparedStatement.executeQuery();
      } catch (SQLException ex) {
        throw new EPException("Error executing statement '" + preparedStatementText + '\'', ex);
      }
      long endTimeNS = System.nanoTime();
      long endTimeMS = System.currentTimeMillis();
      jdbcPerfLog.info(
          "Statement '"
              + preparedStatementText
              + "' delta nanosec "
              + (endTimeNS - startTimeNS)
              + " delta msec "
              + (endTimeMS - startTimeMS));
    } else {
      try {
        resultSet = preparedStatement.executeQuery();
      } catch (SQLException ex) {
        throw new EPException("Error executing statement '" + preparedStatementText + '\'', ex);
      }
    }

    // generate events for result set
    List<EventBean> rows = new LinkedList<EventBean>();
    try {
      SQLColumnValueContext valueContext = null;
      if (columnTypeConversionHook != null) {
        valueContext = new SQLColumnValueContext();
      }

      SQLOutputRowValueContext rowContext = null;
      if (outputRowConversionHook != null) {
        rowContext = new SQLOutputRowValueContext();
      }

      int rowNum = 0;
      while (resultSet.next()) {
        int colNum = 1;
        Map<String, Object> row = new HashMap<String, Object>();
        for (Map.Entry<String, DBOutputTypeDesc> entry : outputTypes.entrySet()) {
          String columnName = entry.getKey();

          Object value;
          DatabaseTypeBinding binding = entry.getValue().getOptionalBinding();
          if (binding != null) {
            value = binding.getValue(resultSet, columnName);
          } else {
            value = resultSet.getObject(columnName);
          }

          if (columnTypeConversionHook != null) {
            valueContext.setColumnName(columnName);
            valueContext.setColumnNumber(colNum);
            valueContext.setColumnValue(value);
            valueContext.setResultSet(resultSet);
            value = columnTypeConversionHook.getColumnValue(valueContext);
          }

          row.put(columnName, value);
          colNum++;
        }

        EventBean eventBeanRow = null;
        if (this.outputRowConversionHook == null) {
          eventBeanRow = eventAdapterService.adapterForTypedMap(row, eventType);
        } else {
          rowContext.setValues(row);
          rowContext.setRowNum(rowNum);
          rowContext.setResultSet(resultSet);
          Object rowData = outputRowConversionHook.getOutputRow(rowContext);
          if (rowData != null) {
            eventBeanRow =
                eventAdapterService.adapterForTypedBean(rowData, (BeanEventType) eventType);
          }
        }

        if (eventBeanRow != null) {
          rows.add(eventBeanRow);
          rowNum++;
        }
      }
    } catch (SQLException ex) {
      throw new EPException(
          "Error reading results for statement '" + preparedStatementText + '\'', ex);
    }

    if (enableJDBCLogging && jdbcPerfLog.isInfoEnabled()) {
      jdbcPerfLog.info("Statement '" + preparedStatementText + "' " + rows.size() + " rows");
    }

    try {
      resultSet.close();
    } catch (SQLException ex) {
      throw new EPException("Error closing statement '" + preparedStatementText + '\'', ex);
    }

    return rows;
  }
  /**
   * Initialize event adapter service for config snapshot.
   *
   * @param eventAdapterService is events adapter
   * @param configSnapshot is the config snapshot
   */
  protected static void init(
      EventAdapterService eventAdapterService, ConfigurationInformation configSnapshot) {
    // Extract legacy event type definitions for each event type name, if supplied.
    //
    // We supply this information as setup information to the event adapter service
    // to allow discovery of superclasses and interfaces during event type construction for bean
    // events,
    // such that superclasses and interfaces can use the legacy type definitions.
    Map<String, ConfigurationEventTypeLegacy> classLegacyInfo =
        new HashMap<String, ConfigurationEventTypeLegacy>();
    for (Map.Entry<String, String> entry : configSnapshot.getEventTypeNames().entrySet()) {
      String typeName = entry.getKey();
      String className = entry.getValue();
      ConfigurationEventTypeLegacy legacyDef = configSnapshot.getEventTypesLegacy().get(typeName);
      if (legacyDef != null) {
        classLegacyInfo.put(className, legacyDef);
      }
    }
    eventAdapterService.setClassLegacyConfigs(classLegacyInfo);
    eventAdapterService.setDefaultPropertyResolutionStyle(
        configSnapshot.getEngineDefaults().getEventMeta().getClassPropertyResolutionStyle());
    eventAdapterService.setDefaultAccessorStyle(
        configSnapshot.getEngineDefaults().getEventMeta().getDefaultAccessorStyle());

    for (String javaPackage : configSnapshot.getEventTypeAutoNamePackages()) {
      eventAdapterService.addAutoNamePackage(javaPackage);
    }

    // Add from the configuration the Java event class names
    Map<String, String> javaClassNames = configSnapshot.getEventTypeNames();
    for (Map.Entry<String, String> entry : javaClassNames.entrySet()) {
      // Add Java class
      try {
        String typeName = entry.getKey();
        eventAdapterService.addBeanType(typeName, entry.getValue(), false, true, true, true);
      } catch (EventAdapterException ex) {
        throw new ConfigurationException("Error configuring engine: " + ex.getMessage(), ex);
      }
    }

    // Add from the configuration the XML DOM names and type def
    Map<String, ConfigurationEventTypeXMLDOM> xmlDOMNames = configSnapshot.getEventTypesXMLDOM();
    for (Map.Entry<String, ConfigurationEventTypeXMLDOM> entry : xmlDOMNames.entrySet()) {
      SchemaModel schemaModel = null;
      if ((entry.getValue().getSchemaResource() != null)
          || (entry.getValue().getSchemaText() != null)) {
        try {
          schemaModel =
              XSDSchemaMapper.loadAndMap(
                  entry.getValue().getSchemaResource(), entry.getValue().getSchemaText(), 2);
        } catch (Exception ex) {
          throw new ConfigurationException(ex.getMessage(), ex);
        }
      }

      // Add XML DOM type
      try {
        eventAdapterService.addXMLDOMType(entry.getKey(), entry.getValue(), schemaModel, true);
      } catch (EventAdapterException ex) {
        throw new ConfigurationException("Error configuring engine: " + ex.getMessage(), ex);
      }
    }

    // Add maps in dependency order such that supertypes are added before subtypes
    Set<String> dependentMapOrder;
    try {
      Map<String, Set<String>> typesReferences =
          toTypesReferences(configSnapshot.getMapTypeConfigurations());
      dependentMapOrder = GraphUtil.getTopDownOrder(typesReferences);
    } catch (GraphCircularDependencyException e) {
      throw new ConfigurationException(
          "Error configuring engine, dependency graph between map type names is circular: "
              + e.getMessage(),
          e);
    }

    Map<String, Properties> mapNames = configSnapshot.getEventTypesMapEvents();
    Map<String, Map<String, Object>> nestableMapNames =
        configSnapshot.getEventTypesNestableMapEvents();
    dependentMapOrder.addAll(mapNames.keySet());
    dependentMapOrder.addAll(nestableMapNames.keySet());
    try {
      for (String mapName : dependentMapOrder) {
        ConfigurationEventTypeMap mapConfig =
            configSnapshot.getMapTypeConfigurations().get(mapName);
        Properties propertiesUnnested = mapNames.get(mapName);
        if (propertiesUnnested != null) {
          Map<String, Object> propertyTypes = createPropertyTypes(propertiesUnnested);
          Map<String, Object> propertyTypesCompiled =
              EventTypeUtility.compileMapTypeProperties(propertyTypes, eventAdapterService);
          eventAdapterService.addNestableMapType(
              mapName, propertyTypesCompiled, mapConfig, true, true, true, false, false);
        }

        Map<String, Object> propertiesNestable = nestableMapNames.get(mapName);
        if (propertiesNestable != null) {
          Map<String, Object> propertiesNestableCompiled =
              EventTypeUtility.compileMapTypeProperties(propertiesNestable, eventAdapterService);
          eventAdapterService.addNestableMapType(
              mapName, propertiesNestableCompiled, mapConfig, true, true, true, false, false);
        }
      }
    } catch (EventAdapterException ex) {
      throw new ConfigurationException("Error configuring engine: " + ex.getMessage(), ex);
    }

    // Add object-array in dependency order such that supertypes are added before subtypes
    Set<String> dependentObjectArrayOrder;
    try {
      Map<String, Set<String>> typesReferences =
          toTypesReferences(configSnapshot.getObjectArrayTypeConfigurations());
      dependentObjectArrayOrder = GraphUtil.getTopDownOrder(typesReferences);
    } catch (GraphCircularDependencyException e) {
      throw new ConfigurationException(
          "Error configuring engine, dependency graph between object array type names is circular: "
              + e.getMessage(),
          e);
    }
    Map<String, Map<String, Object>> nestableObjectArrayNames =
        configSnapshot.getEventTypesNestableObjectArrayEvents();
    dependentObjectArrayOrder.addAll(nestableObjectArrayNames.keySet());
    try {
      for (String objectArrayName : dependentObjectArrayOrder) {
        ConfigurationEventTypeObjectArray objectArrayConfig =
            configSnapshot.getObjectArrayTypeConfigurations().get(objectArrayName);
        Map<String, Object> propertyTypes = nestableObjectArrayNames.get(objectArrayName);
        propertyTypes = resolveClassesForStringPropertyTypes(propertyTypes);
        Map<String, Object> propertyTypesCompiled =
            EventTypeUtility.compileMapTypeProperties(propertyTypes, eventAdapterService);
        eventAdapterService.addNestableObjectArrayType(
            objectArrayName,
            propertyTypesCompiled,
            objectArrayConfig,
            true,
            true,
            true,
            false,
            false,
            false,
            null);
      }
    } catch (EventAdapterException ex) {
      throw new ConfigurationException("Error configuring engine: " + ex.getMessage(), ex);
    }

    // Add plug-in event representations
    Map<URI, ConfigurationPlugInEventRepresentation> plugInReps =
        configSnapshot.getPlugInEventRepresentation();
    for (Map.Entry<URI, ConfigurationPlugInEventRepresentation> entry : plugInReps.entrySet()) {
      String className = entry.getValue().getEventRepresentationClassName();
      Class eventRepClass;
      try {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        eventRepClass = Class.forName(className, true, cl);
      } catch (ClassNotFoundException ex) {
        throw new ConfigurationException(
            "Failed to load plug-in event representation class '" + className + "'", ex);
      }

      Object pluginEventRepObj;
      try {
        pluginEventRepObj = eventRepClass.newInstance();
      } catch (InstantiationException ex) {
        throw new ConfigurationException(
            "Failed to instantiate plug-in event representation class '"
                + className
                + "' via default constructor",
            ex);
      } catch (IllegalAccessException ex) {
        throw new ConfigurationException(
            "Illegal access to instantiate plug-in event representation class '"
                + className
                + "' via default constructor",
            ex);
      }

      if (!(pluginEventRepObj instanceof PlugInEventRepresentation)) {
        throw new ConfigurationException(
            "Plug-in event representation class '"
                + className
                + "' does not implement the required interface "
                + PlugInEventRepresentation.class.getName());
      }

      URI eventRepURI = entry.getKey();
      PlugInEventRepresentation pluginEventRep = (PlugInEventRepresentation) pluginEventRepObj;
      Serializable initializer = entry.getValue().getInitializer();
      PlugInEventRepresentationContext context =
          new PlugInEventRepresentationContext(eventAdapterService, eventRepURI, initializer);

      try {
        pluginEventRep.init(context);
        eventAdapterService.addEventRepresentation(eventRepURI, pluginEventRep);
      } catch (Throwable t) {
        throw new ConfigurationException(
            "Plug-in event representation class '"
                + className
                + "' and URI '"
                + eventRepURI
                + "' did not initialize correctly : "
                + t.getMessage(),
            t);
      }
    }

    // Add plug-in event type names
    Map<String, ConfigurationPlugInEventType> plugInNames = configSnapshot.getPlugInEventTypes();
    for (Map.Entry<String, ConfigurationPlugInEventType> entry : plugInNames.entrySet()) {
      String name = entry.getKey();
      ConfigurationPlugInEventType config = entry.getValue();
      eventAdapterService.addPlugInEventType(
          name, config.getEventRepresentationResolutionURIs(), config.getInitializer());
    }
  }
예제 #26
0
  /**
   * Write new variable values and commit, evaluating assignment expressions using the given events
   * per stream.
   *
   * <p>Populates an optional map of new values if a non-null map is passed.
   *
   * @param variableService variable service
   * @param eventsPerStream events per stream
   * @param valuesWritten null or an empty map to populate with written values
   * @param exprEvaluatorContext expression evaluation context
   */
  public void writeVariables(
      VariableService variableService,
      EventBean[] eventsPerStream,
      Map<String, Object> valuesWritten,
      ExprEvaluatorContext exprEvaluatorContext) {
    Set<String> variablesBeansCopied = null;
    if (!copyMethods.isEmpty()) {
      variablesBeansCopied = new HashSet<String>();
    }

    // We obtain a write lock global to the variable space
    // Since expressions can contain variables themselves, these need to be unchangeable for the
    // duration
    // as there could be multiple statements that do "var1 = var1 + 1".
    variableService.getReadWriteLock().writeLock().lock();
    try {
      variableService.setLocalVersion();

      int count = 0;
      for (VariableTriggerSetDesc assignment : assignments) {
        VariableMetaData variableMetaData = metaData[count];
        int agentInstanceId =
            variableMetaData.getContextPartitionName() == null
                ? VariableService.NOCONTEXT_AGENTINSTANCEID
                : exprEvaluatorContext.getAgentInstanceId();
        Object value = assignment.evaluator.evaluate(eventsPerStream, true, exprEvaluatorContext);

        if (writers[count] != null) {
          VariableReader reader =
              variableService.getReader(
                  variableMetaData.getVariableName(), exprEvaluatorContext.getAgentInstanceId());
          EventBean current = (EventBean) reader.getValue();
          if (current == null) {
            value = null;
          } else {
            WriteDesc writeDesc = writers[count];
            boolean copy = variablesBeansCopied.add(writeDesc.getVariableName());
            if (copy) {
              EventBean copied = copyMethods.get(writeDesc.getType()).copy(current);
              current = copied;
            }
            variableService.write(variableMetaData.getVariableNumber(), agentInstanceId, current);
            writeDesc.getWriter().write(value, current);
          }
        } else if (variableMetaData.getEventType() != null) {
          EventBean eventBean =
              eventAdapterService.adapterForType(value, variableMetaData.getEventType());
          variableService.write(variableMetaData.getVariableNumber(), agentInstanceId, eventBean);
        } else {
          if ((value != null) && (mustCoerce[count])) {
            value = JavaClassHelper.coerceBoxed((Number) value, variableMetaData.getType());
          }
          variableService.write(variableMetaData.getVariableNumber(), agentInstanceId, value);
        }

        count++;

        if (valuesWritten != null) {
          valuesWritten.put(assignment.variableName, value);
        }
      }

      variableService.commit();
    } catch (RuntimeException ex) {
      log.error("Error evaluating on-set variable expressions: " + ex.getMessage(), ex);
      variableService.rollback();
    } finally {
      variableService.getReadWriteLock().writeLock().unlock();
    }
  }
 public void addEventTypeAutoName(String javaPackageName) {
   eventAdapterService.addAutoNamePackage(javaPackageName);
 }
예제 #28
0
  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);
    }
  }
  public SelectExprProcessor getEvaluator() throws ExprValidationException {

    // Get the named and un-named stream selectors (i.e. select s0.* from S0 as s0), if any
    List<SelectClauseStreamCompiledSpec> namedStreams =
        new ArrayList<SelectClauseStreamCompiledSpec>();
    List<SelectExprStreamDesc> unnamedStreams = new ArrayList<SelectExprStreamDesc>();
    for (SelectExprStreamDesc spec : selectedStreams) {
      if (spec.getStreamSelected() != null && spec.getStreamSelected().getOptionalName() == null) {
        unnamedStreams.add(spec);
      } else if (spec.getExpressionSelectedAsStream()
          != null) { // handle special "transpose(...)" function
        unnamedStreams.add(spec);
      } else {
        namedStreams.add(spec.getStreamSelected());
        if (spec.getStreamSelected().isProperty()) {
          throw new ExprValidationException(
              "The property wildcard syntax must be used without column name");
        }
      }
    }

    // Error if there are more then one un-named streams (i.e. select s0.*, s1.* from S0 as s0, S1
    // as s1)
    // Thus there is only 1 unnamed stream selector maximum.
    if (unnamedStreams.size() > 1) {
      throw new ExprValidationException(
          "A column name must be supplied for all but one stream if multiple streams are selected via the stream.* notation");
    }

    if (selectedStreams.isEmpty() && selectionList.isEmpty() && !isUsingWildcard) {
      throw new IllegalArgumentException("Empty selection list not supported");
    }

    for (SelectClauseExprCompiledSpec entry : selectionList) {
      if (entry.getAssignedName() == null) {
        throw new IllegalArgumentException(
            "Expected name for each expression has not been supplied");
      }
    }

    // Verify insert into clause
    if (insertIntoDesc != null) {
      verifyInsertInto(insertIntoDesc, selectionList);
    }

    // Build a subordinate wildcard processor for joins
    SelectExprProcessor joinWildcardProcessor = null;
    if (typeService.getStreamNames().length > 1 && isUsingWildcard) {
      joinWildcardProcessor =
          SelectExprJoinWildcardProcessorFactory.create(
              assignedTypeNumberStack,
              statementId,
              typeService.getStreamNames(),
              typeService.getEventTypes(),
              eventAdapterService,
              null,
              selectExprEventTypeRegistry,
              methodResolutionService,
              annotations,
              configuration);
    }

    // Resolve underlying event type in the case of wildcard select
    EventType eventType = null;
    boolean singleStreamWrapper = false;
    if (isUsingWildcard) {
      if (joinWildcardProcessor != null) {
        eventType = joinWildcardProcessor.getResultEventType();
      } else {
        eventType = typeService.getEventTypes()[0];
        if (eventType instanceof WrapperEventType) {
          singleStreamWrapper = true;
        }
      }
    }

    // Get expression nodes
    ExprEvaluator[] exprEvaluators = new ExprEvaluator[selectionList.size()];
    ExprNode[] exprNodes = new ExprNode[selectionList.size()];
    Object[] expressionReturnTypes = new Object[selectionList.size()];
    for (int i = 0; i < selectionList.size(); i++) {
      ExprNode expr = selectionList.get(i).getSelectExpression();
      exprNodes[i] = expr;
      exprEvaluators[i] = expr.getExprEvaluator();
      Map<String, Object> eventTypeExpr = exprEvaluators[i].getEventType();
      if (eventTypeExpr == null) {
        expressionReturnTypes[i] = exprEvaluators[i].getType();
      } else {
        final ExprEvaluator innerExprEvaluator = expr.getExprEvaluator();
        final EventType mapType =
            eventAdapterService.createAnonymousMapType(
                statementId
                    + "_innereval_"
                    + CollectionUtil.toString(assignedTypeNumberStack, "_")
                    + "_"
                    + i,
                eventTypeExpr);
        ExprEvaluator evaluatorFragment =
            new ExprEvaluator() {
              public Object evaluate(
                  EventBean[] eventsPerStream,
                  boolean isNewData,
                  ExprEvaluatorContext exprEvaluatorContext) {
                Map<String, Object> values =
                    (Map<String, Object>)
                        innerExprEvaluator.evaluate(
                            eventsPerStream, isNewData, exprEvaluatorContext);
                if (values == null) {
                  values = Collections.emptyMap();
                }
                return eventAdapterService.adapterForTypedMap(values, mapType);
              }

              public Class getType() {
                return Map.class;
              }

              public Map<String, Object> getEventType() {
                return null;
              }
            };

        expressionReturnTypes[i] = mapType;
        exprEvaluators[i] = evaluatorFragment;
      }
    }

    // Get column names
    String[] columnNames;
    String[] columnNamesAsProvided;
    if ((insertIntoDesc != null) && (!insertIntoDesc.getColumnNames().isEmpty())) {
      columnNames =
          insertIntoDesc
              .getColumnNames()
              .toArray(new String[insertIntoDesc.getColumnNames().size()]);
      columnNamesAsProvided = columnNames;
    } else if (!selectedStreams.isEmpty()) { // handle stream selection column names
      int numStreamColumnsJoin = 0;
      if (isUsingWildcard && typeService.getEventTypes().length > 1) {
        numStreamColumnsJoin = typeService.getEventTypes().length;
      }
      columnNames = new String[selectionList.size() + namedStreams.size() + numStreamColumnsJoin];
      columnNamesAsProvided = new String[columnNames.length];
      int count = 0;
      for (SelectClauseExprCompiledSpec aSelectionList : selectionList) {
        columnNames[count] = aSelectionList.getAssignedName();
        columnNamesAsProvided[count] = aSelectionList.getProvidedName();
        count++;
      }
      for (SelectClauseStreamCompiledSpec aSelectionList : namedStreams) {
        columnNames[count] = aSelectionList.getOptionalName();
        columnNamesAsProvided[count] = aSelectionList.getOptionalName();
        count++;
      }
      // for wildcard joins, add the streams themselves
      if (isUsingWildcard && typeService.getEventTypes().length > 1) {
        for (String streamName : typeService.getStreamNames()) {
          columnNames[count] = streamName;
          columnNamesAsProvided[count] = streamName;
          count++;
        }
      }
    } else // handle regular column names
    {
      columnNames = new String[selectionList.size()];
      columnNamesAsProvided = new String[selectionList.size()];
      for (int i = 0; i < selectionList.size(); i++) {
        columnNames[i] = selectionList.get(i).getAssignedName();
        columnNamesAsProvided[i] = selectionList.get(i).getProvidedName();
      }
    }

    // Find if there is any fragments selected
    EventType targetType = null;
    if (insertIntoDesc != null) {
      targetType = eventAdapterService.getExistsTypeByName(insertIntoDesc.getEventTypeName());
    }

    // Find if there is any fragment event types:
    // This is a special case for fragments: select a, b from pattern [a=A -> b=B]
    // We'd like to maintain 'A' and 'B' EventType in the Map type, and 'a' and 'b' EventBeans in
    // the event bean
    for (int i = 0; i < selectionList.size(); i++) {
      if (!(exprNodes[i] instanceof ExprIdentNode)) {
        continue;
      }

      ExprIdentNode identNode = (ExprIdentNode) exprNodes[i];
      String propertyName = identNode.getResolvedPropertyName();
      final int streamNum = identNode.getStreamId();

      EventType eventTypeStream = typeService.getEventTypes()[streamNum];
      if (eventTypeStream instanceof NativeEventType) {
        continue; // we do not transpose the native type for performance reasons
      }

      FragmentEventType fragmentType = eventTypeStream.getFragmentType(propertyName);
      if ((fragmentType == null) || (fragmentType.isNative())) {
        continue; // we also ignore native Java classes as fragments for performance reasons
      }

      // may need to unwrap the fragment if the target type has this underlying type
      FragmentEventType targetFragment = null;
      if (targetType != null) {
        targetFragment = targetType.getFragmentType(columnNames[i]);
      }
      if ((targetType != null)
          && (fragmentType.getFragmentType().getUnderlyingType() == expressionReturnTypes[i])
          && ((targetFragment == null) || (targetFragment != null && targetFragment.isNative()))) {
        ExprEvaluator evaluatorFragment;

        // A match was found, we replace the expression
        final EventPropertyGetter getter = eventTypeStream.getGetter(propertyName);
        final Class returnType = eventTypeStream.getPropertyType(propertyName);
        evaluatorFragment =
            new ExprEvaluator() {
              public Object evaluate(
                  EventBean[] eventsPerStream,
                  boolean isNewData,
                  ExprEvaluatorContext exprEvaluatorContext) {
                EventBean streamEvent = eventsPerStream[streamNum];
                if (streamEvent == null) {
                  return null;
                }
                return getter.get(streamEvent);
              }

              public Class getType() {
                return returnType;
              }

              @Override
              public Map<String, Object> getEventType() {
                return null;
              }
            };
        exprEvaluators[i] = evaluatorFragment;
      }
      // same for arrays: may need to unwrap the fragment if the target type has this underlying
      // type
      else if ((targetType != null)
          && expressionReturnTypes[i] instanceof Class
          && (fragmentType.getFragmentType().getUnderlyingType()
              == ((Class) expressionReturnTypes[i]).getComponentType())
          && ((targetFragment == null) || (targetFragment != null && targetFragment.isNative()))) {
        ExprEvaluator evaluatorFragment;
        final EventPropertyGetter getter = eventTypeStream.getGetter(propertyName);
        final Class returnType =
            JavaClassHelper.getArrayType(eventTypeStream.getPropertyType(propertyName));
        evaluatorFragment =
            new ExprEvaluator() {
              public Object evaluate(
                  EventBean[] eventsPerStream,
                  boolean isNewData,
                  ExprEvaluatorContext exprEvaluatorContext) {
                EventBean streamEvent = eventsPerStream[streamNum];
                if (streamEvent == null) {
                  return null;
                }
                return getter.get(streamEvent);
              }

              public Class getType() {
                return returnType;
              }

              @Override
              public Map<String, Object> getEventType() {
                return null;
              }
            };
        exprEvaluators[i] = evaluatorFragment;
      } else {
        ExprEvaluator evaluatorFragment;
        final EventPropertyGetter getter = eventTypeStream.getGetter(propertyName);
        final Class returnType =
            eventTypeStream.getFragmentType(propertyName).getFragmentType().getUnderlyingType();

        // A match was found, we replace the expression
        evaluatorFragment =
            new ExprEvaluator() {

              public Object evaluate(
                  EventBean[] eventsPerStream,
                  boolean isNewData,
                  ExprEvaluatorContext exprEvaluatorContext) {
                EventBean streamEvent = eventsPerStream[streamNum];
                if (streamEvent == null) {
                  return null;
                }
                return getter.getFragment(streamEvent);
              }

              public Class getType() {
                return returnType;
              }

              public Map<String, Object> getEventType() {
                return null;
              }
            };

        exprEvaluators[i] = evaluatorFragment;
        if (!fragmentType.isIndexed()) {
          expressionReturnTypes[i] = fragmentType.getFragmentType();
        } else {
          expressionReturnTypes[i] = new EventType[] {fragmentType.getFragmentType()};
        }
      }
    }

    // Find if there is any stream expression (ExprStreamNode) :
    // This is a special case for stream selection: select a, b from A as a, B as b
    // We'd like to maintain 'A' and 'B' EventType in the Map type, and 'a' and 'b' EventBeans in
    // the event bean
    for (int i = 0; i < selectionList.size(); i++) {
      if (!(exprEvaluators[i] instanceof ExprStreamUnderlyingNode)) {
        continue;
      }

      ExprStreamUnderlyingNode undNode = (ExprStreamUnderlyingNode) exprEvaluators[i];
      final int streamNum = undNode.getStreamId();
      final Class returnType = undNode.getExprEvaluator().getType();
      EventType eventTypeStream = typeService.getEventTypes()[streamNum];

      // A match was found, we replace the expression
      ExprEvaluator evaluator =
          new ExprEvaluator() {

            public Object evaluate(
                EventBean[] eventsPerStream,
                boolean isNewData,
                ExprEvaluatorContext exprEvaluatorContext) {
              return eventsPerStream[streamNum];
            }

            public Class getType() {
              return returnType;
            }

            public Map<String, Object> getEventType() {
              return null;
            }
          };

      exprEvaluators[i] = evaluator;
      expressionReturnTypes[i] = eventTypeStream;
    }

    // Build event type that reflects all selected properties
    Map<String, Object> selPropertyTypes = new LinkedHashMap<String, Object>();
    int count = 0;
    for (int i = 0; i < exprEvaluators.length; i++) {
      Object expressionReturnType = expressionReturnTypes[count];
      selPropertyTypes.put(columnNames[count], expressionReturnType);
      count++;
    }
    if (!selectedStreams.isEmpty()) {
      for (SelectClauseStreamCompiledSpec element : namedStreams) {
        EventType eventTypeStream = typeService.getEventTypes()[element.getStreamNumber()];
        selPropertyTypes.put(columnNames[count], eventTypeStream);
        count++;
      }
      if (isUsingWildcard && typeService.getEventTypes().length > 1) {
        for (int i = 0; i < typeService.getEventTypes().length; i++) {
          EventType eventTypeStream = typeService.getEventTypes()[i];
          selPropertyTypes.put(columnNames[count], eventTypeStream);
          count++;
        }
      }
    }

    // Handle stream selection
    EventType underlyingEventType = null;
    int underlyingStreamNumber = 0;
    boolean underlyingIsFragmentEvent = false;
    EventPropertyGetter underlyingPropertyEventGetter = null;
    ExprEvaluator underlyingExprEvaluator = null;
    boolean useMapOutput =
        EventRepresentationUtil.isMap(
            annotations, configuration, CreateSchemaDesc.AssignedType.NONE);

    if (!selectedStreams.isEmpty()) {
      // Resolve underlying event type in the case of wildcard or non-named stream select.
      // Determine if the we are considering a tagged event or a stream name.
      if ((isUsingWildcard) || (!unnamedStreams.isEmpty())) {
        if (!unnamedStreams.isEmpty()) {
          if (unnamedStreams.get(0).getStreamSelected() != null) {
            SelectClauseStreamCompiledSpec streamSpec = unnamedStreams.get(0).getStreamSelected();

            // the tag.* syntax for :  select tag.* from pattern [tag = A]
            underlyingStreamNumber = streamSpec.getStreamNumber();
            if (streamSpec.isFragmentEvent()) {
              EventType compositeMap = typeService.getEventTypes()[underlyingStreamNumber];
              FragmentEventType fragment = compositeMap.getFragmentType(streamSpec.getStreamName());
              underlyingEventType = fragment.getFragmentType();
              underlyingIsFragmentEvent = true;
            }
            // the property.* syntax for :  select property.* from A
            else if (streamSpec.isProperty()) {
              String propertyName = streamSpec.getStreamName();
              Class propertyType = streamSpec.getPropertyType();
              int streamNumber = streamSpec.getStreamNumber();

              if (JavaClassHelper.isJavaBuiltinDataType(streamSpec.getPropertyType())) {
                throw new ExprValidationException(
                    "The property wildcard syntax cannot be used on built-in types as returned by property '"
                        + propertyName
                        + "'");
              }

              // create or get an underlying type for that Class
              underlyingEventType =
                  eventAdapterService.addBeanType(
                      propertyType.getName(), propertyType, false, false, false);
              selectExprEventTypeRegistry.add(underlyingEventType);
              underlyingPropertyEventGetter =
                  typeService.getEventTypes()[streamNumber].getGetter(propertyName);
              if (underlyingPropertyEventGetter == null) {
                throw new ExprValidationException(
                    "Unexpected error resolving property getter for property " + propertyName);
              }
            }
            // the stream.* syntax for:  select a.* from A as a
            else {
              underlyingEventType = typeService.getEventTypes()[underlyingStreamNumber];
            }
          }
          // handle case where the unnamed stream is a "transpose" function
          else {
            ExprNode expression =
                unnamedStreams.get(0).getExpressionSelectedAsStream().getSelectExpression();
            Class returnType = expression.getExprEvaluator().getType();
            underlyingEventType =
                eventAdapterService.addBeanType(
                    returnType.getName(), returnType, false, false, false);
            selectExprEventTypeRegistry.add(underlyingEventType);
            underlyingExprEvaluator = expression.getExprEvaluator();
          }
        } else {
          // no un-named stream selectors, but a wildcard was specified
          if (typeService.getEventTypes().length == 1) {
            // not a join, we are using the selected event
            underlyingEventType = typeService.getEventTypes()[0];
            if (underlyingEventType instanceof WrapperEventType) {
              singleStreamWrapper = true;
            }
          } else {
            // For joins, all results are placed in a map with properties for each stream
            underlyingEventType = null;
          }
        }
      }
    }

    SelectExprContext selectExprContext =
        new SelectExprContext(exprEvaluators, columnNames, eventAdapterService);

    if (insertIntoDesc == null) {
      if (!selectedStreams.isEmpty()) {
        EventType resultEventType;
        if (underlyingEventType != null) {
          resultEventType =
              eventAdapterService.createAnonymousWrapperType(
                  statementId + "_wrapout_" + CollectionUtil.toString(assignedTypeNumberStack, "_"),
                  underlyingEventType,
                  selPropertyTypes);
          return new EvalSelectStreamWUnderlying(
              selectExprContext,
              resultEventType,
              namedStreams,
              isUsingWildcard,
              unnamedStreams,
              singleStreamWrapper,
              underlyingIsFragmentEvent,
              underlyingStreamNumber,
              underlyingPropertyEventGetter,
              underlyingExprEvaluator);
        } else {
          resultEventType =
              eventAdapterService.createAnonymousMapType(
                  statementId + "_mapout_" + CollectionUtil.toString(assignedTypeNumberStack, "_"),
                  selPropertyTypes);
          return new EvalSelectStreamNoUnderlyingMap(
              selectExprContext, resultEventType, namedStreams, isUsingWildcard);
        }
      }

      if (isUsingWildcard) {
        EventType resultEventType =
            eventAdapterService.createAnonymousWrapperType(
                statementId
                    + "_wrapoutwild_"
                    + CollectionUtil.toString(assignedTypeNumberStack, "_"),
                eventType,
                selPropertyTypes);
        if (singleStreamWrapper) {
          return new EvalSelectWildcardSSWrapper(selectExprContext, resultEventType);
        }
        if (joinWildcardProcessor == null) {
          return new EvalSelectWildcard(selectExprContext, resultEventType);
        }
        return new EvalSelectWildcardJoin(
            selectExprContext, resultEventType, joinWildcardProcessor);
      }

      EventType resultEventType;
      if (!useMapOutput) {
        resultEventType =
            eventAdapterService.createAnonymousObjectArrayType(
                statementId + "_result_" + CollectionUtil.toString(assignedTypeNumberStack, "_"),
                selPropertyTypes);
      } else {
        resultEventType =
            eventAdapterService.createAnonymousMapType(
                statementId + "_result_" + CollectionUtil.toString(assignedTypeNumberStack, "_"),
                selPropertyTypes);
      }
      if (selectExprContext.getExpressionNodes().length == 0) {
        return new EvalSelectNoWildcardEmptyProps(selectExprContext, resultEventType);
      } else {
        if (!useMapOutput) {
          return new EvalSelectNoWildcardObjectArray(selectExprContext, resultEventType);
        }
        return new EvalSelectNoWildcardMap(selectExprContext, resultEventType);
      }
    }

    EventType vaeInnerEventType = null;
    boolean singleColumnWrapOrBeanCoercion =
        false; // Additional single-column coercion for non-wrapped type done by
    // SelectExprInsertEventBeanFactory
    boolean isRevisionEvent = false;

    try {
      if (!selectedStreams.isEmpty()) {
        EventType resultEventType;
        if (underlyingEventType
            != null) // a single stream was selected via "stream.*" and there is no column name
        {
          // recast as a Map-type
          if (underlyingEventType instanceof MapEventType && targetType instanceof MapEventType) {
            return new EvalSelectStreamWUnderlyingRecastMap(
                selectExprContext,
                selectedStreams.get(0).getStreamSelected().getStreamNumber(),
                targetType);
          }

          // recast as a Object-array-type
          if (underlyingEventType instanceof ObjectArrayEventType
              && targetType instanceof ObjectArrayEventType) {
            return new EvalSelectStreamWUnderlyingRecastObjectArray(
                selectExprContext,
                selectedStreams.get(0).getStreamSelected().getStreamNumber(),
                targetType);
          }

          // recast as a Bean-type
          if (underlyingEventType instanceof BeanEventType && targetType instanceof BeanEventType) {
            SelectClauseExprCompiledSpec expressionAsStream =
                selectedStreams.get(0).getExpressionSelectedAsStream();
            if (expressionAsStream != null) {
              return new EvalSelectStreamWUnderlyingRecastBean(
                  selectExprContext,
                  expressionAsStream,
                  underlyingEventType,
                  targetType,
                  exprEvaluators.length);
            } else {
              return new EvalInsertBeanRecast(
                  targetType,
                  eventAdapterService,
                  selectedStreams.get(0).getStreamSelected().getStreamNumber(),
                  typeService.getEventTypes());
            }
          }

          // wrap if no recast possible
          resultEventType =
              eventAdapterService.addWrapperType(
                  insertIntoDesc.getEventTypeName(),
                  underlyingEventType,
                  selPropertyTypes,
                  false,
                  true);
          return new EvalSelectStreamWUnderlying(
              selectExprContext,
              resultEventType,
              namedStreams,
              isUsingWildcard,
              unnamedStreams,
              singleStreamWrapper,
              underlyingIsFragmentEvent,
              underlyingStreamNumber,
              underlyingPropertyEventGetter,
              underlyingExprEvaluator);
        } else // there are one or more streams selected with column name such as "stream.* as
        // columnOne"
        {
          EventType existingType =
              eventAdapterService.getExistsTypeByName(insertIntoDesc.getEventTypeName());
          if (existingType instanceof BeanEventType) {
            String name = selectedStreams.get(0).getStreamSelected().getStreamName();
            String alias = selectedStreams.get(0).getStreamSelected().getOptionalName();
            String syntaxUsed = name + ".*" + (alias != null ? " as " + alias : "");
            String syntaxInstead = name + (alias != null ? " as " + alias : "");
            throw new ExprValidationException(
                "The '"
                    + syntaxUsed
                    + "' syntax is not allowed when inserting into an existing bean event type, use the '"
                    + syntaxInstead
                    + "' syntax instead");
          }
          if (existingType == null || existingType instanceof MapEventType) {
            resultEventType =
                eventAdapterService.addNestableMapType(
                    insertIntoDesc.getEventTypeName(),
                    selPropertyTypes,
                    null,
                    false,
                    false,
                    false,
                    false,
                    true);
            Set<String> propertiesToUnwrap =
                getEventBeanToObjectProps(selPropertyTypes, resultEventType);
            if (propertiesToUnwrap.isEmpty()) {
              return new EvalSelectStreamNoUnderlyingMap(
                  selectExprContext, resultEventType, namedStreams, isUsingWildcard);
            } else {
              return new EvalSelectStreamNoUndWEventBeanToObj(
                  selectExprContext,
                  resultEventType,
                  namedStreams,
                  isUsingWildcard,
                  propertiesToUnwrap);
            }
          } else {
            Set<String> propertiesToUnwrap =
                getEventBeanToObjectProps(selPropertyTypes, existingType);
            if (propertiesToUnwrap.isEmpty()) {
              return new EvalSelectStreamNoUnderlyingObjectArray(
                  selectExprContext, existingType, namedStreams, isUsingWildcard);
            } else {
              return new EvalSelectStreamNoUndWEventBeanToObjObjArray(
                  selectExprContext,
                  existingType,
                  namedStreams,
                  isUsingWildcard,
                  propertiesToUnwrap);
            }
          }
        }
      }

      ValueAddEventProcessor vaeProcessor =
          valueAddEventService.getValueAddProcessor(insertIntoDesc.getEventTypeName());
      EventType resultEventType;
      if (isUsingWildcard) {
        if (vaeProcessor != null) {
          resultEventType = vaeProcessor.getValueAddEventType();
          isRevisionEvent = true;
          vaeProcessor.validateEventType(eventType);
        } else {
          EventType existingType =
              eventAdapterService.getExistsTypeByName(insertIntoDesc.getEventTypeName());

          SelectExprProcessor existingTypeProcessor = null;
          if (existingType != null) {
            // we may get away with re-casting an existing bean-event-type event to another
            // bean-event-type
            if ((existingType instanceof BeanEventType)
                && (typeService.getEventTypes()[0] instanceof BeanEventType)
                && (selPropertyTypes.isEmpty())) {
              return new EvalInsertBeanRecast(
                  existingType, eventAdapterService, 0, typeService.getEventTypes());
            }
            if ((existingType instanceof WrapperEventType)
                && (typeService.getEventTypes()[0] instanceof BeanEventType)
                && (exprEvaluators.length == 0)) {

              WrapperEventType wrapperType = (WrapperEventType) existingType;
              if (wrapperType.getUnderlyingEventType() instanceof BeanEventType) {
                return new EvalInsertBeanWrapRecast(
                    wrapperType, eventAdapterService, 0, typeService.getEventTypes());
              }
            }

            existingTypeProcessor =
                SelectExprInsertEventBeanFactory.getInsertUnderlyingNonJoin(
                    eventAdapterService,
                    existingType,
                    isUsingWildcard,
                    typeService,
                    exprEvaluators,
                    columnNames,
                    expressionReturnTypes,
                    methodResolutionService.getEngineImportService(),
                    insertIntoDesc,
                    columnNamesAsProvided);
          }

          if (existingTypeProcessor != null) {
            return existingTypeProcessor;
          } else if (existingType != null
              && selPropertyTypes.isEmpty()
              && existingType instanceof MapEventType) {
            resultEventType = existingType;
            return new EvalInsertCoercionMap(resultEventType, eventAdapterService);
          } else if (existingType != null
              && selPropertyTypes.isEmpty()
              && existingType instanceof ObjectArrayEventType) {
            resultEventType = existingType;
            return new EvalInsertCoercionObjectArray(resultEventType, eventAdapterService);
          } else if (selPropertyTypes.isEmpty() && eventType instanceof BeanEventType) {
            BeanEventType beanEventType = (BeanEventType) eventType;
            resultEventType =
                eventAdapterService.addBeanTypeByName(
                    insertIntoDesc.getEventTypeName(), beanEventType.getUnderlyingType(), false);
          } else {
            resultEventType =
                eventAdapterService.addWrapperType(
                    insertIntoDesc.getEventTypeName(), eventType, selPropertyTypes, false, true);
          }
        }

        if (singleStreamWrapper) {
          if (!isRevisionEvent) {
            return new EvalInsertWildcardSSWrapper(selectExprContext, resultEventType);
          } else {
            return new EvalInsertWildcardSSWrapperRevision(
                selectExprContext, resultEventType, vaeProcessor);
          }
        }
        if (joinWildcardProcessor == null) {
          if (!isRevisionEvent) {
            if (resultEventType instanceof WrapperEventType) {
              return new EvalInsertWildcardWrapper(selectExprContext, resultEventType);
            } else {
              return new EvalInsertWildcardBean(selectExprContext, resultEventType);
            }
          } else {
            if (exprEvaluators.length == 0) {
              return new EvalInsertWildcardRevision(
                  selectExprContext, resultEventType, vaeProcessor);
            } else {
              EventType wrappingEventType =
                  eventAdapterService.addWrapperType(
                      insertIntoDesc.getEventTypeName() + "_wrapped",
                      eventType,
                      selPropertyTypes,
                      false,
                      true);
              return new EvalInsertWildcardRevisionWrapper(
                  selectExprContext, resultEventType, vaeProcessor, wrappingEventType);
            }
          }
        } else {
          if (!isRevisionEvent) {
            return new EvalInsertWildcardJoin(
                selectExprContext, resultEventType, joinWildcardProcessor);
          } else {
            return new EvalInsertWildcardJoinRevision(
                selectExprContext, resultEventType, joinWildcardProcessor, vaeProcessor);
          }
        }
      }

      // not using wildcard
      resultEventType = null;
      if ((columnNames.length == 1) && (insertIntoDesc.getColumnNames().size() == 0)) {
        EventType existingType =
            eventAdapterService.getExistsTypeByName(insertIntoDesc.getEventTypeName());
        if (existingType != null) {
          // check if the existing type and new type are compatible
          Object columnOneType = expressionReturnTypes[0];
          if (existingType instanceof WrapperEventType) {
            WrapperEventType wrapperType = (WrapperEventType) existingType;
            // Map and Object both supported
            if (wrapperType.getUnderlyingEventType().getUnderlyingType() == columnOneType) {
              singleColumnWrapOrBeanCoercion = true;
              resultEventType = existingType;
            }
          }
          if ((existingType instanceof BeanEventType) && (columnOneType instanceof Class)) {
            BeanEventType beanType = (BeanEventType) existingType;
            // Map and Object both supported
            if (JavaClassHelper.isSubclassOrImplementsInterface(
                (Class) columnOneType, beanType.getUnderlyingType())) {
              singleColumnWrapOrBeanCoercion = true;
              resultEventType = existingType;
            }
          }
        }
      }
      if (singleColumnWrapOrBeanCoercion) {
        if (!isRevisionEvent) {
          if (resultEventType instanceof WrapperEventType) {
            WrapperEventType wrapper = (WrapperEventType) resultEventType;
            if (wrapper.getUnderlyingEventType() instanceof MapEventType) {
              return new EvalInsertNoWildcardSingleColCoercionMapWrap(
                  selectExprContext, resultEventType);
            } else if (wrapper.getUnderlyingEventType() instanceof ObjectArrayEventType) {
              return new EvalInsertNoWildcardSingleColCoercionObjectArrayWrap(
                  selectExprContext, resultEventType);
            } else if (wrapper.getUnderlyingEventType() instanceof VariantEventType) {
              VariantEventType variantEventType =
                  (VariantEventType) wrapper.getUnderlyingEventType();
              vaeProcessor = valueAddEventService.getValueAddProcessor(variantEventType.getName());
              return new EvalInsertNoWildcardSingleColCoercionBeanWrapVariant(
                  selectExprContext, resultEventType, vaeProcessor);
            } else {
              return new EvalInsertNoWildcardSingleColCoercionBeanWrap(
                  selectExprContext, resultEventType);
            }
          } else {
            if (resultEventType instanceof BeanEventType) {
              return new EvalInsertNoWildcardSingleColCoercionBean(
                  selectExprContext, resultEventType);
            }
          }
        } else {
          if (resultEventType instanceof MapEventType) {
            return new EvalInsertNoWildcardSingleColCoercionRevisionMap(
                selectExprContext, resultEventType, vaeProcessor, vaeInnerEventType);
          } else if (resultEventType instanceof ObjectArrayEventType) {
            return new EvalInsertNoWildcardSingleColCoercionRevisionObjectArray(
                selectExprContext, resultEventType, vaeProcessor, vaeInnerEventType);
          } else if (resultEventType instanceof BeanEventType) {
            return new EvalInsertNoWildcardSingleColCoercionRevisionBean(
                selectExprContext, resultEventType, vaeProcessor, vaeInnerEventType);
          } else {
            return new EvalInsertNoWildcardSingleColCoercionRevisionBeanWrap(
                selectExprContext, resultEventType, vaeProcessor, vaeInnerEventType);
          }
        }
      }
      if (resultEventType == null) {
        if (vaeProcessor != null) {
          // Use an anonymous type if the target is not a variant stream
          if (valueAddEventService.getValueAddProcessor(insertIntoDesc.getEventTypeName())
              == null) {
            resultEventType =
                eventAdapterService.createAnonymousMapType(
                    statementId + "_vae_" + CollectionUtil.toString(assignedTypeNumberStack, "_"),
                    selPropertyTypes);
          } else {
            String statementName = "stmt_" + statementId + "_insert";
            resultEventType =
                eventAdapterService.addNestableMapType(
                    statementName, selPropertyTypes, null, false, false, false, false, true);
          }
        } else {
          EventType existingType =
              eventAdapterService.getExistsTypeByName(insertIntoDesc.getEventTypeName());

          if (existingType == null) {
            // The type may however be an auto-import or fully-qualified class name
            Class clazz = null;
            try {
              clazz = this.methodResolutionService.resolveClass(insertIntoDesc.getEventTypeName());
            } catch (EngineImportException e) {
              log.debug(
                  "Target stream name '"
                      + insertIntoDesc.getEventTypeName()
                      + "' is not resolved as a class name");
            }
            if (clazz != null) {
              existingType =
                  eventAdapterService.addBeanType(clazz.getName(), clazz, false, false, false);
            }
          }

          SelectExprProcessor selectExprInsertEventBean = null;
          if (existingType != null) {
            selectExprInsertEventBean =
                SelectExprInsertEventBeanFactory.getInsertUnderlyingNonJoin(
                    eventAdapterService,
                    existingType,
                    isUsingWildcard,
                    typeService,
                    exprEvaluators,
                    columnNames,
                    expressionReturnTypes,
                    methodResolutionService.getEngineImportService(),
                    insertIntoDesc,
                    columnNamesAsProvided);
          }
          if (selectExprInsertEventBean != null) {
            return selectExprInsertEventBean;
          } else {
            boolean useMap =
                EventRepresentationUtil.isMap(
                    annotations, configuration, CreateSchemaDesc.AssignedType.NONE);
            if (useMap) {
              resultEventType =
                  eventAdapterService.addNestableMapType(
                      insertIntoDesc.getEventTypeName(),
                      selPropertyTypes,
                      null,
                      false,
                      false,
                      false,
                      false,
                      true);
            } else {
              resultEventType =
                  eventAdapterService.addNestableObjectArrayType(
                      insertIntoDesc.getEventTypeName(),
                      selPropertyTypes,
                      null,
                      false,
                      false,
                      false,
                      false,
                      true);
            }
          }
        }
      }
      if (vaeProcessor != null) {
        vaeProcessor.validateEventType(resultEventType);
        vaeInnerEventType = resultEventType;
        resultEventType = vaeProcessor.getValueAddEventType();
        isRevisionEvent = true;
      }

      if (!isRevisionEvent) {
        if (resultEventType instanceof MapEventType) {
          return new EvalInsertNoWildcardMap(selectExprContext, resultEventType);
        } else {
          return new EvalInsertNoWildcardObjectArray(selectExprContext, resultEventType);
        }
      } else {
        return new EvalInsertNoWildcardRevision(
            selectExprContext, resultEventType, vaeProcessor, vaeInnerEventType);
      }
    } catch (EventAdapterException ex) {
      log.debug("Exception provided by event adapter: " + ex.getMessage(), ex);
      throw new ExprValidationException(ex.getMessage(), ex);
    }
  }
예제 #30
0
  public Class getPropertyTypeMap(
      Map optionalMapPropTypes, EventAdapterService eventAdapterService) {
    Map currentDictionary = optionalMapPropTypes;

    int count = 0;
    for (Iterator<Property> it = properties.iterator(); it.hasNext(); ) {
      count++;
      Property property = it.next();
      PropertyBase theBase = (PropertyBase) property;
      String propertyName = theBase.getPropertyNameAtomic();

      Object nestedType = null;
      if (currentDictionary != null) {
        nestedType = currentDictionary.get(propertyName);
      }

      if (nestedType == null) {
        if (property instanceof DynamicProperty) {
          return Object.class;
        } else {
          return null;
        }
      }

      if (!it.hasNext()) {
        if (nestedType instanceof Class) {
          return (Class) nestedType;
        }
        if (nestedType instanceof Map) {
          return Map.class;
        }
      }

      if (nestedType == Map.class) {
        return Object.class;
      }

      if (nestedType instanceof Class) {
        Class pojoClass = (Class) nestedType;
        if (!pojoClass.isArray()) {
          BeanEventType beanType =
              eventAdapterService
                  .getBeanEventTypeFactory()
                  .createBeanType(pojoClass.getName(), pojoClass, false, false, false);
          String remainingProps = toPropertyEPL(properties, count);
          return beanType.getPropertyType(remainingProps);
        } else if (property instanceof IndexedProperty) {
          Class componentType = pojoClass.getComponentType();
          BeanEventType beanType =
              eventAdapterService
                  .getBeanEventTypeFactory()
                  .createBeanType(componentType.getName(), componentType, false, false, false);
          String remainingProps = toPropertyEPL(properties, count);
          return beanType.getPropertyType(remainingProps);
        }
      }

      if (nestedType instanceof String) // property type is the name of a map event type
      {
        String nestedName = nestedType.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);
        return innerType.getPropertyType(remainingProps);
      } else if (nestedType instanceof EventType) // property type is the name of a map event type
      {
        EventType innerType = (EventType) nestedType;
        String remainingProps = toPropertyEPL(properties, count);
        return innerType.getPropertyType(remainingProps);
      } else {
        if (!(nestedType instanceof Map)) {
          String message =
              "Nestable map type configuration encountered an unexpected value type of '"
                  + nestedType.getClass()
                  + " for property '"
                  + propertyName
                  + "', expected Class, Map.class or Map<String, Object> as value type";
          throw new PropertyAccessException(message);
        }
      }

      currentDictionary = (Map) nestedType;
    }
    throw new IllegalStateException("Unexpected end of nested property");
  }