public void validate(
      StreamTypeService streamTypeService,
      MethodResolutionService methodResolutionService,
      ViewResourceDelegate viewResourceDelegate,
      TimeProvider timeProvider,
      VariableService variableService,
      ExprEvaluatorContext exprEvaluatorContext)
      throws ExprValidationException {
    if (this.getChildNodes().size() < 2) {
      throw new ExprValidationException("MinMax node must have at least 2 child nodes");
    }
    evaluators = ExprNodeUtility.getEvaluators(this.getChildNodes());

    for (ExprEvaluator child : evaluators) {
      Class childType = child.getType();
      if (!JavaClassHelper.isNumeric(childType)) {
        throw new ExprValidationException(
            "Implicit conversion from datatype '"
                + childType.getSimpleName()
                + "' to numeric is not allowed");
      }
    }

    // Determine result type, set up compute function
    Class childTypeOne = evaluators[0].getType();
    Class childTypeTwo = evaluators[1].getType();
    resultType = JavaClassHelper.getArithmaticCoercionType(childTypeOne, childTypeTwo);

    for (int i = 2; i < this.getChildNodes().size(); i++) {
      resultType = JavaClassHelper.getArithmaticCoercionType(resultType, evaluators[i].getType());
    }

    ExprNode[] childNodes = this.getChildNodes().toArray(new ExprNode[this.getChildNodes().size()]);
    if (resultType == BigInteger.class) {
      SimpleNumberBigIntegerCoercer[] convertors =
          new SimpleNumberBigIntegerCoercer[childNodes.length];
      for (int i = 0; i < childNodes.length; i++) {
        convertors[i] = SimpleNumberCoercerFactory.getCoercerBigInteger(evaluators[i].getType());
      }
      computer =
          new MinMaxTypeEnum.ComputerBigIntCoerce(
              evaluators, convertors, (minMaxTypeEnum == MinMaxTypeEnum.MAX));
    } else if (resultType == BigDecimal.class) {
      SimpleNumberBigDecimalCoercer[] convertors =
          new SimpleNumberBigDecimalCoercer[childNodes.length];
      for (int i = 0; i < childNodes.length; i++) {
        convertors[i] = SimpleNumberCoercerFactory.getCoercerBigDecimal(evaluators[i].getType());
      }
      computer =
          new MinMaxTypeEnum.ComputerBigDecCoerce(
              evaluators, convertors, (minMaxTypeEnum == MinMaxTypeEnum.MAX));
    } else {
      if (minMaxTypeEnum == MinMaxTypeEnum.MAX) {
        computer = new MinMaxTypeEnum.MaxComputerDoubleCoerce(evaluators);
      } else {
        computer = new MinMaxTypeEnum.MinComputerDoubleCoerce(evaluators);
      }
    }
  }
Esempio n. 2
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;
  }
 /**
  * Adds configured variables to the variable service.
  *
  * @param variableService service to add to
  * @param variables configured variables
  */
 protected static void initVariables(
     VariableService variableService,
     Map<String, ConfigurationVariable> variables,
     EngineImportService engineImportService) {
   for (Map.Entry<String, ConfigurationVariable> entry : variables.entrySet()) {
     try {
       Pair<String, Boolean> arrayType =
           JavaClassHelper.isGetArrayType(entry.getValue().getType());
       variableService.createNewVariable(
           null,
           entry.getKey(),
           arrayType.getFirst(),
           entry.getValue().isConstant(),
           arrayType.getSecond(),
           false,
           entry.getValue().getInitializationValue(),
           engineImportService);
       variableService.allocateVariableState(entry.getKey(), 0, null);
     } catch (VariableExistsException e) {
       throw new ConfigurationException("Error configuring variables: " + e.getMessage(), e);
     } catch (VariableTypeException e) {
       throw new ConfigurationException("Error configuring variables: " + e.getMessage(), e);
     }
   }
 }
Esempio n. 4
0
 public void validate(ExprValidationContext validationContext) throws ExprValidationException {
   evaluator = this.getChildNodes().get(0).getExprEvaluator();
   Class type = evaluator.getType();
   if (!(JavaClassHelper.isNumericNonFP(type))) {
     throw new ExprValidationException("Frequency operator requires an integer-type parameter");
   }
 }
  /**
   * Constructor - takes the services context as argument.
   *
   * @param adminContext - administrative context
   */
  public EPAdministratorImpl(EPAdministratorContext adminContext) {
    this.services = adminContext.getServices();
    this.configurationOperations = adminContext.getConfigurationOperations();
    this.defaultStreamSelector = adminContext.getDefaultStreamSelector();

    ConfigurationEngineDefaults.AlternativeContext alternativeContext =
        adminContext.getServices().getConfigSnapshot().getEngineDefaults().getAlternativeContext();
    StatementIdGenerator statementIdGenerator = null;
    if (alternativeContext != null && alternativeContext.getStatementIdGeneratorFactory() != null) {
      StatementIdGeneratorFactory statementIdGeneratorFactory =
          (StatementIdGeneratorFactory)
              JavaClassHelper.instantiate(
                  StatementIdGeneratorFactory.class,
                  alternativeContext.getStatementIdGeneratorFactory());
      statementIdGenerator =
          statementIdGeneratorFactory.create(
              new StatementIdGeneratorFactoryContext(services.getEngineURI()));
    }
    this.deploymentAdminService =
        new EPDeploymentAdminImpl(
            this,
            adminContext.getServices().getDeploymentStateService(),
            adminContext.getServices().getStatementEventTypeRefService(),
            adminContext.getServices().getEventAdapterService(),
            adminContext.getServices().getStatementIsolationService(),
            statementIdGenerator,
            adminContext.getServices().getFilterService());
  }
Esempio n. 6
0
  public void setViewParameters(
      ViewFactoryContext viewFactoryContext, List<ExprNode> expressionParameters)
      throws ViewParameterException {
    List<Object> viewParameters =
        ViewFactorySupport.validateAndEvaluate(
            "Time batch view", viewFactoryContext.getStatementContext(), expressionParameters);
    String errorMessage =
        "Time batch view requires a single numeric or time period parameter, and an optional long-typed reference point in msec, and an optional list of control keywords as a string parameter (please see the documentation)";
    if ((viewParameters.size() < 1) || (viewParameters.size() > 3)) {
      throw new ViewParameterException(errorMessage);
    }

    processExpiry(
        viewParameters.get(0), errorMessage, "Time batch view requires a size of at least 1 msec");

    if ((viewParameters.size() == 2) && (viewParameters.get(1) instanceof String)) {
      processKeywords(viewParameters.get(1), errorMessage);
    } else {
      if (viewParameters.size() >= 2) {
        Object paramRef = viewParameters.get(1);
        if ((!(paramRef instanceof Number))
            || (JavaClassHelper.isFloatingPointNumber((Number) paramRef))) {
          throw new ViewParameterException(
              "Time batch view requires a Long-typed reference point in msec as a second parameter");
        }
        optionalReferencePoint = ((Number) paramRef).longValue();
      }

      if (viewParameters.size() == 3) {
        processKeywords(viewParameters.get(2), errorMessage);
      }
    }
  }
 public Object evaluate(
     EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) {
   Number result = computer.execute(eventsPerStream, isNewData, exprEvaluatorContext);
   if (result == null) {
     return null;
   }
   return JavaClassHelper.coerceBoxed(result, resultType);
 }
Esempio n. 8
0
  /**
   * Ctor.
   *
   * @param configurationEventTypeXMLDOM is the XML DOM configuration such as root element and
   *     schema names
   * @param metadata event type metadata
   * @param eventAdapterService for registration and lookup of types
   */
  public BaseXMLEventType(
      EventTypeMetadata metadata,
      int eventTypeId,
      ConfigurationEventTypeXMLDOM configurationEventTypeXMLDOM,
      EventAdapterService eventAdapterService) {
    super(eventAdapterService, metadata, eventTypeId, Node.class);
    this.rootElementName = configurationEventTypeXMLDOM.getRootElementName();
    this.configurationEventTypeXMLDOM = configurationEventTypeXMLDOM;
    xPathFactory = XPathFactory.newInstance();

    if (configurationEventTypeXMLDOM.getXPathFunctionResolver() != null) {
      try {
        XPathFunctionResolver fresolver =
            (XPathFunctionResolver)
                JavaClassHelper.instantiate(
                    XPathFunctionResolver.class,
                    configurationEventTypeXMLDOM.getXPathFunctionResolver());
        xPathFactory.setXPathFunctionResolver(fresolver);
      } catch (ClassInstantiationException ex) {
        throw new ConfigurationException(
            "Error configuring XPath function resolver for XML type '"
                + configurationEventTypeXMLDOM.getRootElementName()
                + "' : "
                + ex.getMessage(),
            ex);
      }
    }

    if (configurationEventTypeXMLDOM.getXPathVariableResolver() != null) {
      try {
        XPathVariableResolver vresolver =
            (XPathVariableResolver)
                JavaClassHelper.instantiate(
                    XPathVariableResolver.class,
                    configurationEventTypeXMLDOM.getXPathVariableResolver());
        xPathFactory.setXPathVariableResolver(vresolver);
      } catch (ClassInstantiationException ex) {
        throw new ConfigurationException(
            "Error configuring XPath variable resolver for XML type '"
                + configurationEventTypeXMLDOM.getRootElementName()
                + "' : "
                + 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 ExprNode validate(ExprValidationContext validationContext) throws ExprValidationException {
    // Must have 2 child nodes
    if (this.getChildNodes().length < 1) {
      throw new IllegalStateException("Group relational op node must have 1 or more parameters");
    }
    evaluators = ExprNodeUtility.getEvaluators(this.getChildNodes());

    Class typeOne = JavaClassHelper.getBoxedType(evaluators[0].getType());

    // collections, array or map not supported
    if ((typeOne.isArray())
        || (JavaClassHelper.isImplementsInterface(typeOne, Collection.class))
        || (JavaClassHelper.isImplementsInterface(typeOne, Map.class))) {
      throw new ExprValidationException(
          "Collection or array comparison is not allowed for the IN, ANY, SOME or ALL keywords");
    }

    List<Class> comparedTypes = new ArrayList<Class>();
    comparedTypes.add(typeOne);
    hasCollectionOrArray = false;
    for (int i = 0; i < this.getChildNodes().length - 1; i++) {
      Class propType = evaluators[i + 1].getType();
      if (propType.isArray()) {
        hasCollectionOrArray = true;
        if (propType.getComponentType() != Object.class) {
          comparedTypes.add(propType.getComponentType());
        }
      } else if (JavaClassHelper.isImplementsInterface(propType, Collection.class)) {
        hasCollectionOrArray = true;
      } else if (JavaClassHelper.isImplementsInterface(propType, Map.class)) {
        hasCollectionOrArray = true;
      } else {
        comparedTypes.add(propType);
      }
    }

    // Determine common denominator type
    Class coercionType;
    try {
      coercionType =
          JavaClassHelper.getCommonCoercionType(
              comparedTypes.toArray(new Class[comparedTypes.size()]));
    } catch (CoercionException ex) {
      throw new ExprValidationException("Implicit conversion not allowed: " + ex.getMessage());
    }

    // Must be either numeric or string
    if (coercionType != String.class) {
      if (!JavaClassHelper.isNumeric(coercionType)) {
        throw new ExprValidationException(
            "Implicit conversion from datatype '"
                + coercionType.getSimpleName()
                + "' to numeric is not allowed");
      }
    }

    computer = relationalOpEnum.getComputer(coercionType, coercionType, coercionType);
    return null;
  }
  private EngineImportException convert(
      Class clazz,
      String methodName,
      Class[] paramTypes,
      EngineNoSuchMethodException e,
      boolean isInstance) {
    String expected = JavaClassHelper.getParameterAsString(paramTypes);
    String message = "Could not find ";
    if (!isInstance) {
      message += "static ";
    } else {
      message += "instance ";
    }

    if (paramTypes.length > 0) {
      message +=
          "method named '"
              + methodName
              + "' in class '"
              + JavaClassHelper.getClassNameFullyQualPretty(clazz)
              + "' with matching parameter number and expected parameter type(s) '"
              + expected
              + "'";
    } else {
      message +=
          "method named '"
              + methodName
              + "' in class '"
              + JavaClassHelper.getClassNameFullyQualPretty(clazz)
              + "' taking no parameters";
    }

    if (e.getNearestMissMethod() != null) {
      message +=
          (" (nearest match found was '"
              + e.getNearestMissMethod().getName()
              + "' taking type(s) '"
              + JavaClassHelper.getParameterAsString(e.getNearestMissMethod().getParameterTypes())
              + "')");
    }
    return new EngineImportException(message, e);
  }
  /**
   * Finds a class by class name using the auto-import information provided.
   *
   * @param className is the class name to find
   * @return class
   * @throws ClassNotFoundException if the class cannot be loaded
   */
  protected Class resolveClassInternal(String className) throws ClassNotFoundException {
    // Attempt to retrieve the class with the name as-is
    try {
      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      return Class.forName(className, true, cl);
    } catch (ClassNotFoundException e) {
      if (log.isDebugEnabled()) {
        log.debug("Class not found for resolving from name as-is '" + className + "'");
      }
    }

    // Try all the imports
    for (String importName : imports) {
      boolean isClassName = isClassName(importName);

      // Import is a class name
      if (isClassName) {
        if (importName.endsWith(className)) {
          ClassLoader cl = Thread.currentThread().getContextClassLoader();
          return Class.forName(importName, true, cl);
        }
      } else {
        // Import is a package name
        String prefixedClassName = getPackageName(importName) + '.' + className;
        try {
          ClassLoader cl = Thread.currentThread().getContextClassLoader();
          return Class.forName(prefixedClassName, true, cl);
        } catch (ClassNotFoundException e) {
          if (log.isDebugEnabled()) {
            log.debug("Class not found for resolving from name '" + prefixedClassName + "'");
          }
        }
      }
    }

    // try to resolve from method references
    for (String name : methodInvocationRef.keySet()) {
      if (JavaClassHelper.isSimpleNameFullyQualfied(className, name)) {
        try {
          ClassLoader cl = Thread.currentThread().getContextClassLoader();
          return Class.forName(name, true, cl);
        } catch (ClassNotFoundException e1) {
          if (log.isDebugEnabled()) {
            log.debug("Class not found for resolving from method invocation ref:" + name);
          }
        }
      }
    }

    // No import worked, the class isn't resolved
    throw new ClassNotFoundException("Unknown class " + className);
  }
  /**
   * Process view expiry parameter
   *
   * @param parameter the parameter to parse
   * @param errorMessage error text
   * @param errorMessage2 error text
   * @throws ViewParameterException if validation failed
   */
  protected void processExpiry(Object parameter, String errorMessage, String errorMessage2)
      throws ViewParameterException {
    if (!(parameter instanceof Number)) {
      throw new ViewParameterException(errorMessage);
    } else {
      Number param = (Number) parameter;
      if (JavaClassHelper.isFloatingPointNumber(param)) {
        millisecondsBeforeExpiry = Math.round(1000d * param.doubleValue());
      } else {
        millisecondsBeforeExpiry = 1000 * param.longValue();
      }
    }

    if (millisecondsBeforeExpiry < 1) {
      throw new ViewParameterException(errorMessage2);
    }
  }
  private static Class resolveClassForTypeName(String type) {
    boolean isArray = false;
    if (type != null && EventTypeUtility.isPropertyArray(type)) {
      isArray = true;
      type = EventTypeUtility.getPropertyRemoveArray(type);
    }

    if (type == null) {
      throw new ConfigurationException("A null value has been provided for the type");
    }
    Class clazz = JavaClassHelper.getClassForSimpleName(type);
    if (clazz == null) {
      throw new ConfigurationException("The type '" + type + "' is not a recognized type");
    }

    if (isArray) {
      clazz = Array.newInstance(clazz, 0).getClass();
    }
    return clazz;
  }
 public void addVariable(
     String variableName, String type, Object initializationValue, boolean constant)
     throws ConfigurationException {
   try {
     Pair<String, Boolean> arrayType = JavaClassHelper.isGetArrayType(type);
     variableService.createNewVariable(
         variableName,
         arrayType.getFirst(),
         initializationValue,
         constant,
         arrayType.getSecond(),
         null,
         engineImportService);
     statementVariableRef.addConfiguredVariable(variableName);
   } catch (VariableExistsException e) {
     throw new ConfigurationException("Error creating variable: " + e.getMessage(), e);
   } catch (VariableTypeException e) {
     throw new ConfigurationException("Error creating variable: " + e.getMessage(), e);
   }
 }
  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);
    }
  }
Esempio n. 17
0
  private static void recursiveCompile(
      EvalNode evalNode,
      StatementContext context,
      Set<String> eventTypeReferences,
      boolean isInsertInto,
      MatchEventSpec tags,
      Deque<Integer> subexpressionIdStack)
      throws ExprValidationException {
    int counter = 0;
    for (EvalNode child : evalNode.getChildNodes()) {
      subexpressionIdStack.addLast(counter++);
      recursiveCompile(
          child, context, eventTypeReferences, isInsertInto, tags, subexpressionIdStack);
      subexpressionIdStack.removeLast();
    }

    LinkedHashMap<String, Pair<EventType, String>> newTaggedEventTypes = null;
    LinkedHashMap<String, Pair<EventType, String>> newArrayEventTypes = null;

    if (evalNode instanceof EvalFilterNode) {
      EvalFilterNode filterNode = (EvalFilterNode) evalNode;
      String eventName = filterNode.getRawFilterSpec().getEventTypeName();
      EventType resolvedEventType =
          FilterStreamSpecRaw.resolveType(
              context.getEngineURI(),
              eventName,
              context.getEventAdapterService(),
              context.getPlugInTypeResolutionURIs());
      EventType finalEventType = resolvedEventType;
      String optionalTag = filterNode.getEventAsName();
      boolean isPropertyEvaluation = false;

      // obtain property event type, if final event type is properties
      if (filterNode.getRawFilterSpec().getOptionalPropertyEvalSpec() != null) {
        PropertyEvaluator optionalPropertyEvaluator =
            PropertyEvaluatorFactory.makeEvaluator(
                filterNode.getRawFilterSpec().getOptionalPropertyEvalSpec(),
                resolvedEventType,
                filterNode.getEventAsName(),
                context.getEventAdapterService(),
                context.getMethodResolutionService(),
                context.getSchedulingService(),
                context.getVariableService(),
                context.getEngineURI(),
                context.getStatementId(),
                context.getStatementName(),
                context.getAnnotations(),
                subexpressionIdStack);
        finalEventType = optionalPropertyEvaluator.getFragmentEventType();
        isPropertyEvaluation = true;
      }

      if (finalEventType instanceof EventTypeSPI) {
        eventTypeReferences.add(((EventTypeSPI) finalEventType).getMetadata().getPrimaryName());
      }

      // If a tag was supplied for the type, the tags must stay with this type, i.e. a=BeanA ->
      // b=BeanA -> a=BeanB is a no
      if (optionalTag != null) {
        Pair<EventType, String> pair = tags.getTaggedEventTypes().get(optionalTag);
        EventType existingType = null;
        if (pair != null) {
          existingType = pair.getFirst();
        }
        if (existingType == null) {
          pair = tags.getArrayEventTypes().get(optionalTag);
          if (pair != null) {
            throw new ExprValidationException(
                "Tag '"
                    + optionalTag
                    + "' for event '"
                    + eventName
                    + "' used in the repeat-until operator cannot also appear in other filter expressions");
          }
        }
        if ((existingType != null) && (existingType != finalEventType)) {
          throw new ExprValidationException(
              "Tag '"
                  + optionalTag
                  + "' for event '"
                  + eventName
                  + "' has already been declared for events of type "
                  + existingType.getUnderlyingType().getName());
        }
        pair = new Pair<EventType, String>(finalEventType, eventName);

        // add tagged type
        if (isPropertyEvaluation) {
          newArrayEventTypes = new LinkedHashMap<String, Pair<EventType, String>>();
          newArrayEventTypes.put(optionalTag, pair);
        } else {
          newTaggedEventTypes = new LinkedHashMap<String, Pair<EventType, String>>();
          newTaggedEventTypes.put(optionalTag, pair);
        }
      }

      // For this filter, filter types are all known tags at this time,
      // and additionally stream 0 (self) is our event type.
      // Stream type service allows resolution by property name event if that name appears in other
      // tags.
      // by defaulting to stream zero.
      // Stream zero is always the current event type, all others follow the order of the map
      // (stream 1 to N).
      String selfStreamName = optionalTag;
      if (selfStreamName == null) {
        selfStreamName = "s_" + UuidGenerator.generate();
      }
      LinkedHashMap<String, Pair<EventType, String>> filterTypes =
          new LinkedHashMap<String, Pair<EventType, String>>();
      Pair<EventType, String> typePair = new Pair<EventType, String>(finalEventType, eventName);
      filterTypes.put(selfStreamName, typePair);
      filterTypes.putAll(tags.getTaggedEventTypes());

      // for the filter, specify all tags used
      LinkedHashMap<String, Pair<EventType, String>> filterTaggedEventTypes =
          new LinkedHashMap<String, Pair<EventType, String>>(tags.getTaggedEventTypes());
      filterTaggedEventTypes.remove(optionalTag);

      // handle array tags (match-until clause)
      LinkedHashMap<String, Pair<EventType, String>> arrayCompositeEventTypes = null;
      if (tags.getArrayEventTypes() != null) {
        arrayCompositeEventTypes = new LinkedHashMap<String, Pair<EventType, String>>();
        String patternSubexEventType =
            getPatternSubexEventType(context.getStatementId(), "pattern", subexpressionIdStack);
        EventType arrayTagCompositeEventType =
            context
                .getEventAdapterService()
                .createSemiAnonymousMapType(
                    patternSubexEventType, new HashMap(), tags.getArrayEventTypes(), isInsertInto);
        for (Map.Entry<String, Pair<EventType, String>> entry :
            tags.getArrayEventTypes().entrySet()) {
          String tag = entry.getKey();
          if (!filterTypes.containsKey(tag)) {
            Pair<EventType, String> pair =
                new Pair<EventType, String>(arrayTagCompositeEventType, tag);
            filterTypes.put(tag, pair);
            arrayCompositeEventTypes.put(tag, pair);
          }
        }
      }

      StreamTypeService streamTypeService =
          new StreamTypeServiceImpl(filterTypes, context.getEngineURI(), true, false);
      List<ExprNode> exprNodes = filterNode.getRawFilterSpec().getFilterExpressions();

      FilterSpecCompiled spec =
          FilterSpecCompiler.makeFilterSpec(
              resolvedEventType,
              eventName,
              exprNodes,
              filterNode.getRawFilterSpec().getOptionalPropertyEvalSpec(),
              filterTaggedEventTypes,
              arrayCompositeEventTypes,
              streamTypeService,
              context.getMethodResolutionService(),
              context.getSchedulingService(),
              context.getVariableService(),
              context.getEventAdapterService(),
              context.getEngineURI(),
              null,
              context,
              subexpressionIdStack);
      filterNode.setFilterSpec(spec);
    } else if (evalNode instanceof EvalObserverNode) {
      EvalObserverNode observerNode = (EvalObserverNode) evalNode;
      try {
        ObserverFactory observerFactory =
            context.getPatternResolutionService().create(observerNode.getPatternObserverSpec());

        StreamTypeService streamTypeService =
            getStreamTypeService(
                context.getEngineURI(),
                context.getStatementId(),
                context.getEventAdapterService(),
                tags.taggedEventTypes,
                tags.arrayEventTypes,
                subexpressionIdStack,
                "observer");
        ExprValidationContext validationContext =
            new ExprValidationContext(
                streamTypeService,
                context.getMethodResolutionService(),
                null,
                context.getSchedulingService(),
                context.getVariableService(),
                context,
                context.getEventAdapterService(),
                context.getStatementName(),
                context.getStatementId(),
                context.getAnnotations());
        List<ExprNode> validated =
            validateExpressions(
                observerNode.getPatternObserverSpec().getObjectParameters(), validationContext);

        MatchedEventConvertor convertor =
            new MatchedEventConvertorImpl(
                tags.taggedEventTypes, tags.arrayEventTypes, context.getEventAdapterService());

        observerNode.setObserverFactory(observerFactory);
        observerFactory.setObserverParameters(validated, convertor);
      } catch (ObserverParameterException e) {
        throw new ExprValidationException(
            "Invalid parameter for pattern observer: " + e.getMessage(), e);
      } catch (PatternObjectException e) {
        throw new ExprValidationException(
            "Failed to resolve pattern observer: " + e.getMessage(), e);
      }
    } else if (evalNode instanceof EvalGuardNode) {
      EvalGuardNode guardNode = (EvalGuardNode) evalNode;
      try {
        GuardFactory guardFactory =
            context.getPatternResolutionService().create(guardNode.getPatternGuardSpec());

        StreamTypeService streamTypeService =
            getStreamTypeService(
                context.getEngineURI(),
                context.getStatementId(),
                context.getEventAdapterService(),
                tags.taggedEventTypes,
                tags.arrayEventTypes,
                subexpressionIdStack,
                "guard");
        ExprValidationContext validationContext =
            new ExprValidationContext(
                streamTypeService,
                context.getMethodResolutionService(),
                null,
                context.getSchedulingService(),
                context.getVariableService(),
                context,
                context.getEventAdapterService(),
                context.getStatementName(),
                context.getStatementId(),
                context.getAnnotations());
        List<ExprNode> validated =
            validateExpressions(
                guardNode.getPatternGuardSpec().getObjectParameters(), validationContext);

        MatchedEventConvertor convertor =
            new MatchedEventConvertorImpl(
                tags.taggedEventTypes, tags.arrayEventTypes, context.getEventAdapterService());

        guardNode.setGuardFactory(guardFactory);
        guardFactory.setGuardParameters(validated, convertor);
      } catch (GuardParameterException e) {
        throw new ExprValidationException(
            "Invalid parameter for pattern guard: " + e.getMessage(), e);
      } catch (PatternObjectException e) {
        throw new ExprValidationException("Failed to resolve pattern guard: " + e.getMessage(), e);
      }
    } else if (evalNode instanceof EvalEveryDistinctNode) {
      EvalEveryDistinctNode distinctNode = (EvalEveryDistinctNode) evalNode;
      MatchEventSpec matchEventFromChildNodes = analyzeMatchEvent(distinctNode);
      StreamTypeService streamTypeService =
          getStreamTypeService(
              context.getEngineURI(),
              context.getStatementId(),
              context.getEventAdapterService(),
              matchEventFromChildNodes.getTaggedEventTypes(),
              matchEventFromChildNodes.getArrayEventTypes(),
              subexpressionIdStack,
              "every-distinct");
      ExprValidationContext validationContext =
          new ExprValidationContext(
              streamTypeService,
              context.getMethodResolutionService(),
              null,
              context.getSchedulingService(),
              context.getVariableService(),
              context,
              context.getEventAdapterService(),
              context.getStatementName(),
              context.getStatementId(),
              context.getAnnotations());
      List<ExprNode> validated;
      try {
        validated = validateExpressions(distinctNode.getExpressions(), validationContext);
      } catch (ExprValidationPropertyException ex) {
        throw new ExprValidationPropertyException(
            ex.getMessage()
                + ", every-distinct requires that all properties resolve from sub-expressions to the every-distinct",
            ex.getCause());
      }

      MatchedEventConvertor convertor =
          new MatchedEventConvertorImpl(
              matchEventFromChildNodes.getTaggedEventTypes(),
              matchEventFromChildNodes.getArrayEventTypes(),
              context.getEventAdapterService());

      distinctNode.setConvertor(convertor);

      // Determine whether some expressions are constants or time period
      List<ExprNode> distinctExpressions = new ArrayList<ExprNode>();
      Long msecToExpire = null;
      for (ExprNode expr : validated) {
        if (expr instanceof ExprTimePeriod) {
          Double secondsExpire = (Double) ((ExprTimePeriod) expr).evaluate(null, true, context);
          if ((secondsExpire != null) && (secondsExpire > 0)) {
            msecToExpire = Math.round(1000d * secondsExpire);
          }
          log.debug("Setting every-distinct msec-to-expire to " + msecToExpire);
        } else if (expr.isConstantResult()) {
          log.warn(
              "Every-distinct node utilizes an expression returning a constant value, please check expression '"
                  + expr.toExpressionString()
                  + "', not adding expression to distinct-value expression list");
        } else {
          distinctExpressions.add(expr);
        }
      }
      if (distinctExpressions.isEmpty()) {
        throw new ExprValidationException(
            "Every-distinct node requires one or more distinct-value expressions that each return non-constant result values");
      }
      distinctNode.setExpressions(distinctExpressions, msecToExpire);
    } else if (evalNode instanceof EvalMatchUntilNode) {
      EvalMatchUntilNode matchUntilNode = (EvalMatchUntilNode) evalNode;

      // compile bounds expressions, if any
      MatchEventSpec untilMatchEventSpec =
          new MatchEventSpec(tags.getTaggedEventTypes(), tags.getArrayEventTypes());
      StreamTypeService streamTypeService =
          getStreamTypeService(
              context.getEngineURI(),
              context.getStatementId(),
              context.getEventAdapterService(),
              untilMatchEventSpec.getTaggedEventTypes(),
              untilMatchEventSpec.getArrayEventTypes(),
              subexpressionIdStack,
              "until");
      ExprValidationContext validationContext =
          new ExprValidationContext(
              streamTypeService,
              context.getMethodResolutionService(),
              null,
              context.getSchedulingService(),
              context.getVariableService(),
              context,
              context.getEventAdapterService(),
              context.getStatementName(),
              context.getStatementId(),
              context.getAnnotations());

      String message = "Match-until bounds value expressions must return a numeric value";
      if (matchUntilNode.getLowerBounds() != null) {
        ExprNode validated =
            ExprNodeUtility.getValidatedSubtree(matchUntilNode.getLowerBounds(), validationContext);
        matchUntilNode.setLowerBounds(validated);
        if ((validated.getExprEvaluator().getType() == null)
            || (!JavaClassHelper.isNumeric(validated.getExprEvaluator().getType()))) {
          throw new ExprValidationException(message);
        }
      }

      if (matchUntilNode.getUpperBounds() != null) {
        ExprNode validated =
            ExprNodeUtility.getValidatedSubtree(matchUntilNode.getUpperBounds(), validationContext);
        matchUntilNode.setUpperBounds(validated);
        if ((validated.getExprEvaluator().getType() == null)
            || (!JavaClassHelper.isNumeric(validated.getExprEvaluator().getType()))) {
          throw new ExprValidationException(message);
        }
      }

      MatchedEventConvertor convertor =
          new MatchedEventConvertorImpl(
              untilMatchEventSpec.getTaggedEventTypes(),
              untilMatchEventSpec.getArrayEventTypes(),
              context.getEventAdapterService());
      matchUntilNode.setConvertor(convertor);

      // compile new tag lists
      Set<String> arrayTags = null;
      EvalNodeAnalysisResult matchUntilAnalysisResult =
          EvalNodeUtil.recursiveAnalyzeChildNodes(matchUntilNode.getChildNodes().get(0));
      for (EvalFilterNode filterNode : matchUntilAnalysisResult.getFilterNodes()) {
        String optionalTag = filterNode.getEventAsName();
        if (optionalTag != null) {
          if (arrayTags == null) {
            arrayTags = new HashSet<String>();
          }
          arrayTags.add(optionalTag);
        }
      }

      if (arrayTags != null) {
        for (String arrayTag : arrayTags) {
          if (!tags.arrayEventTypes.containsKey(arrayTag)) {
            tags.arrayEventTypes.put(arrayTag, tags.taggedEventTypes.get(arrayTag));
            tags.taggedEventTypes.remove(arrayTag);
          }
        }
      }
      matchUntilNode.setTagsArrayedSet(arrayTags);
    } else if (evalNode instanceof EvalFollowedByNode) {
      EvalFollowedByNode followedByNode = (EvalFollowedByNode) evalNode;
      StreamTypeService streamTypeService =
          new StreamTypeServiceImpl(context.getEngineURI(), false);
      ExprValidationContext validationContext =
          new ExprValidationContext(
              streamTypeService,
              context.getMethodResolutionService(),
              null,
              context.getSchedulingService(),
              context.getVariableService(),
              context,
              context.getEventAdapterService(),
              context.getStatementName(),
              context.getStatementId(),
              context.getAnnotations());

      if (followedByNode.getOptionalMaxExpressions() != null) {
        List<ExprNode> validated = new ArrayList<ExprNode>();
        for (ExprNode maxExpr : followedByNode.getOptionalMaxExpressions()) {
          if (maxExpr == null) {
            validated.add(null);
          } else {
            ExprNodeSummaryVisitor visitor = new ExprNodeSummaryVisitor();
            maxExpr.accept(visitor);
            if (!visitor.isPlain()) {
              String errorMessage =
                  "Invalid maximum expression in followed-by, "
                      + visitor.getMessage()
                      + " are not allowed within the expression";
              log.error(errorMessage);
              throw new ExprValidationException(errorMessage);
            }

            ExprNode validatedExpr =
                ExprNodeUtility.getValidatedSubtree(maxExpr, validationContext);
            validated.add(validatedExpr);
            if ((validatedExpr.getExprEvaluator().getType() == null)
                || (!JavaClassHelper.isNumeric(validatedExpr.getExprEvaluator().getType()))) {
              String message =
                  "Invalid maximum expression in followed-by, the expression must return an integer value";
              throw new ExprValidationException(message);
            }
          }
        }
        followedByNode.setOptionalMaxExpressions(validated);
      }
    }

    if (newTaggedEventTypes != null) {
      tags.getTaggedEventTypes().putAll(newTaggedEventTypes);
    }
    if (newArrayEventTypes != null) {
      tags.getArrayEventTypes().putAll(newArrayEventTypes);
    }
  }
  /**
   * 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();
    }
  }
  /**
   * Ctor.
   *
   * @param assignments the list of variable assignments
   * @param variableService variable service
   * @param eventAdapterService event adapters
   * @throws com.espertech.esper.epl.expression.core.ExprValidationException when variables cannot
   *     be found
   */
  public VariableReadWritePackage(
      List<OnTriggerSetAssignment> assignments,
      VariableService variableService,
      EventAdapterService eventAdapterService)
      throws ExprValidationException {
    this.metaData = new VariableMetaData[assignments.size()];
    this.readersForGlobalVars = new VariableReader[assignments.size()];
    this.mustCoerce = new boolean[assignments.size()];
    this.writers = new WriteDesc[assignments.size()];

    this.variableTypes = new HashMap<String, Object>();
    this.eventAdapterService = eventAdapterService;
    this.variableService = variableService;

    Map<EventTypeSPI, CopyMethodDesc> eventTypeWrittenProps =
        new HashMap<EventTypeSPI, CopyMethodDesc>();
    int count = 0;
    List<VariableTriggerSetDesc> assignmentList = new ArrayList<VariableTriggerSetDesc>();

    for (OnTriggerSetAssignment expressionWithAssignments : assignments) {
      Pair<String, ExprNode> possibleVariableAssignment =
          ExprNodeUtility.checkGetAssignmentToVariableOrProp(
              expressionWithAssignments.getExpression());
      if (possibleVariableAssignment == null) {
        throw new ExprValidationException(
            "Missing variable assignment expression in assignment number " + count);
      }
      assignmentList.add(
          new VariableTriggerSetDesc(
              possibleVariableAssignment.getFirst(),
              possibleVariableAssignment.getSecond().getExprEvaluator()));

      String fullVariableName = possibleVariableAssignment.getFirst();
      String variableName = fullVariableName;
      String subPropertyName = null;

      int indexOfDot = variableName.indexOf('.');
      if (indexOfDot != -1) {
        subPropertyName = variableName.substring(indexOfDot + 1, variableName.length());
        variableName = variableName.substring(0, indexOfDot);
      }

      VariableMetaData variableMetadata = variableService.getVariableMetaData(variableName);
      metaData[count] = variableMetadata;
      if (variableMetadata == null) {
        throw new ExprValidationException(
            "Variable by name '" + variableName + "' has not been created or configured");
      }
      if (variableMetadata.isConstant()) {
        throw new ExprValidationException(
            "Variable by name '" + variableName + "' is declared constant and may not be set");
      }
      if (variableMetadata.getContextPartitionName() == null) {
        readersForGlobalVars[count] =
            variableService.getReader(variableName, VariableService.NOCONTEXT_AGENTINSTANCEID);
      }

      if (subPropertyName != null) {
        if (variableMetadata.getEventType() == null) {
          throw new ExprValidationException(
              "Variable by name '"
                  + variableName
                  + "' does not have a property named '"
                  + subPropertyName
                  + "'");
        }
        EventType type = variableMetadata.getEventType();
        if (!(type instanceof EventTypeSPI)) {
          throw new ExprValidationException(
              "Variable by name '"
                  + variableName
                  + "' event type '"
                  + type.getName()
                  + "' not writable");
        }
        EventTypeSPI spi = (EventTypeSPI) type;
        EventPropertyWriter writer = spi.getWriter(subPropertyName);
        EventPropertyGetter getter = spi.getGetter(subPropertyName);
        if (writer == null) {
          throw new ExprValidationException(
              "Variable by name '"
                  + variableName
                  + "' the property '"
                  + subPropertyName
                  + "' is not writable");
        }

        variableTypes.put(fullVariableName, spi.getPropertyType(subPropertyName));
        CopyMethodDesc writtenProps = eventTypeWrittenProps.get(spi);
        if (writtenProps == null) {
          writtenProps = new CopyMethodDesc(variableName, new ArrayList<String>());
          eventTypeWrittenProps.put(spi, writtenProps);
        }
        writtenProps.getPropertiesCopied().add(subPropertyName);

        writers[count] = new WriteDesc(spi, variableName, writer, getter);
      } else {

        // determine types
        Class expressionType = possibleVariableAssignment.getSecond().getExprEvaluator().getType();

        if (variableMetadata.getEventType() != null) {
          if ((expressionType != null)
              && (!JavaClassHelper.isSubclassOrImplementsInterface(
                  expressionType, variableMetadata.getEventType().getUnderlyingType()))) {
            throw new VariableValueException(
                "Variable '"
                    + variableName
                    + "' of declared event type '"
                    + variableMetadata.getEventType().getName()
                    + "' underlying type '"
                    + variableMetadata.getEventType().getUnderlyingType().getName()
                    + "' cannot be assigned a value of type '"
                    + expressionType.getName()
                    + "'");
          }
          variableTypes.put(variableName, variableMetadata.getEventType().getUnderlyingType());
        } else {

          Class variableType = variableMetadata.getType();
          variableTypes.put(variableName, variableType);

          // determine if the expression type can be assigned
          if (variableType != java.lang.Object.class) {
            if ((JavaClassHelper.getBoxedType(expressionType) != variableType)
                && (expressionType != null)) {
              if ((!JavaClassHelper.isNumeric(variableType))
                  || (!JavaClassHelper.isNumeric(expressionType))) {
                throw new ExprValidationException(
                    VariableServiceUtil.getAssigmentExMessage(
                        variableName, variableType, expressionType));
              }

              if (!(JavaClassHelper.canCoerce(expressionType, variableType))) {
                throw new ExprValidationException(
                    VariableServiceUtil.getAssigmentExMessage(
                        variableName, variableType, expressionType));
              }

              mustCoerce[count] = true;
            }
          }
        }
      }

      count++;
    }

    this.assignments = assignmentList.toArray(new VariableTriggerSetDesc[assignmentList.size()]);

    if (eventTypeWrittenProps.isEmpty()) {
      copyMethods = Collections.EMPTY_MAP;
      return;
    }

    copyMethods = new HashMap<EventTypeSPI, EventBeanCopyMethod>();
    for (Map.Entry<EventTypeSPI, CopyMethodDesc> entry : eventTypeWrittenProps.entrySet()) {
      List<String> propsWritten = entry.getValue().getPropertiesCopied();
      String[] props = propsWritten.toArray(new String[propsWritten.size()]);
      EventBeanCopyMethod copyMethod = entry.getKey().getCopyMethod(props);
      if (copyMethod == null) {
        throw new ExprValidationException(
            "Variable '"
                + entry.getValue().getVariableName()
                + "' of declared type "
                + JavaClassHelper.getClassNameFullyQualPretty(entry.getKey().getUnderlyingType())
                + "' cannot be assigned to");
      }
      copyMethods.put(entry.getKey(), copyMethod);
    }
  }
  protected static ExceptionHandlingService initExceptionHandling(
      String engineURI,
      ConfigurationEngineDefaults.ExceptionHandling exceptionHandling,
      ConfigurationEngineDefaults.ConditionHandling conditionHandling)
      throws ConfigurationException {
    List<ExceptionHandler> exceptionHandlers;
    if (exceptionHandling.getHandlerFactories() == null
        || exceptionHandling.getHandlerFactories().isEmpty()) {
      exceptionHandlers = Collections.emptyList();
    } else {
      exceptionHandlers = new ArrayList<ExceptionHandler>();
      ExceptionHandlerFactoryContext context = new ExceptionHandlerFactoryContext(engineURI);
      for (String className : exceptionHandling.getHandlerFactories()) {
        try {
          ExceptionHandlerFactory factory =
              (ExceptionHandlerFactory)
                  JavaClassHelper.instantiate(ExceptionHandlerFactory.class, className);
          ExceptionHandler handler = factory.getHandler(context);
          if (handler == null) {
            log.warn(
                "Exception handler factory '"
                    + className
                    + "' returned a null handler, skipping factory");
            continue;
          }
          exceptionHandlers.add(handler);
        } catch (RuntimeException ex) {
          throw new ConfigurationException(
              "Exception initializing exception handler from exception handler factory '"
                  + className
                  + "': "
                  + ex.getMessage(),
              ex);
        }
      }
    }

    List<ConditionHandler> conditionHandlers;
    if (conditionHandling.getHandlerFactories() == null
        || conditionHandling.getHandlerFactories().isEmpty()) {
      conditionHandlers = Collections.emptyList();
    } else {
      conditionHandlers = new ArrayList<ConditionHandler>();
      ConditionHandlerFactoryContext context = new ConditionHandlerFactoryContext(engineURI);
      for (String className : conditionHandling.getHandlerFactories()) {
        try {
          ConditionHandlerFactory factory =
              (ConditionHandlerFactory)
                  JavaClassHelper.instantiate(ConditionHandlerFactory.class, className);
          ConditionHandler handler = factory.getHandler(context);
          if (handler == null) {
            log.warn(
                "Condition handler factory '"
                    + className
                    + "' returned a null handler, skipping factory");
            continue;
          }
          conditionHandlers.add(handler);
        } catch (RuntimeException ex) {
          throw new ConfigurationException(
              "Exception initializing exception handler from exception handler factory '"
                  + className
                  + "': "
                  + ex.getMessage(),
              ex);
        }
      }
    }
    return new ExceptionHandlingService(engineURI, exceptionHandlers, conditionHandlers);
  }
Esempio n. 21
0
  public IntervalOpImpl(
      DatetimeMethodEnum method,
      String methodNameUse,
      EventType[] typesPerStream,
      List<ExprNode> expressions)
      throws ExprValidationException {

    ExprEvaluator evaluatorEndTimestamp = null;
    Class timestampType;

    if (expressions.get(0) instanceof ExprStreamUnderlyingNode) {
      ExprStreamUnderlyingNode und = (ExprStreamUnderlyingNode) expressions.get(0);
      parameterStreamNum = und.getStreamId();
      EventType type = typesPerStream[parameterStreamNum];
      parameterPropertyStart = type.getStartTimestampPropertyName();
      if (parameterPropertyStart == null) {
        throw new ExprValidationException(
            "For date-time method '"
                + methodNameUse
                + "' the first parameter is event type '"
                + type.getName()
                + "', however no timestamp property has been defined for this event type");
      }

      timestampType = type.getPropertyType(parameterPropertyStart);
      EventPropertyGetter getter = type.getGetter(parameterPropertyStart);
      evaluatorTimestamp = new ExprEvaluatorStreamLongProp(parameterStreamNum, getter);

      if (type.getEndTimestampPropertyName() != null) {
        parameterPropertyEnd = type.getEndTimestampPropertyName();
        EventPropertyGetter getterEndTimestamp = type.getGetter(type.getEndTimestampPropertyName());
        evaluatorEndTimestamp =
            new ExprEvaluatorStreamLongProp(parameterStreamNum, getterEndTimestamp);
      } else {
        parameterPropertyEnd = parameterPropertyStart;
      }
    } else {
      evaluatorTimestamp = expressions.get(0).getExprEvaluator();
      timestampType = evaluatorTimestamp.getType();

      if (expressions.get(0) instanceof ExprIdentNode) {
        ExprIdentNode identNode = (ExprIdentNode) expressions.get(0);
        parameterStreamNum = identNode.getStreamId();
        parameterPropertyStart = identNode.getResolvedPropertyName();
        parameterPropertyEnd = parameterPropertyStart;
      }

      if (!JavaClassHelper.isDatetimeClass(evaluatorTimestamp.getType())) {
        throw new ExprValidationException(
            "For date-time method '"
                + methodNameUse
                + "' the first parameter expression returns '"
                + evaluatorTimestamp.getType()
                + "', however requires a Date, Calendar, Long-type return value or event (with timestamp)");
      }
    }

    IntervalComputer intervalComputer = IntervalComputerFactory.make(method, expressions);

    // evaluation without end timestamp
    if (evaluatorEndTimestamp == null) {
      if (JavaClassHelper.isSubclassOrImplementsInterface(timestampType, Calendar.class)) {
        intervalOpEval = new IntervalOpEvalCal(intervalComputer);
      } else if (JavaClassHelper.isSubclassOrImplementsInterface(timestampType, Date.class)) {
        intervalOpEval = new IntervalOpEvalDate(intervalComputer);
      } else if (JavaClassHelper.getBoxedType(timestampType) == Long.class) {
        intervalOpEval = new IntervalOpEvalLong(intervalComputer);
      } else {
        throw new IllegalArgumentException(
            "Invalid interval first parameter type '" + timestampType + "'");
      }
    } else {
      if (JavaClassHelper.isSubclassOrImplementsInterface(timestampType, Calendar.class)) {
        intervalOpEval = new IntervalOpEvalCalWithEnd(intervalComputer, evaluatorEndTimestamp);
      } else if (JavaClassHelper.isSubclassOrImplementsInterface(timestampType, Date.class)) {
        intervalOpEval = new IntervalOpEvalDateWithEnd(intervalComputer, evaluatorEndTimestamp);
      } else if (JavaClassHelper.getBoxedType(timestampType) == Long.class) {
        intervalOpEval = new IntervalOpEvalLongWithEnd(intervalComputer, evaluatorEndTimestamp);
      } else {
        throw new IllegalArgumentException(
            "Invalid interval first parameter type '" + timestampType + "'");
      }
    }
  }
  public EPServicesContext createServicesContext(
      EPServiceProvider epServiceProvider, ConfigurationInformation configSnapshot) {
    // JNDI context for binding resources
    EngineEnvContext jndiContext = new EngineEnvContext();

    EventTypeIdGenerator eventTypeIdGenerator;
    if (configSnapshot.getEngineDefaults().getAlternativeContext() == null
        || configSnapshot
                .getEngineDefaults()
                .getAlternativeContext()
                .getEventTypeIdGeneratorFactory()
            == null) {
      eventTypeIdGenerator = new EventTypeIdGeneratorImpl();
    } else {
      EventTypeIdGeneratorFactory eventTypeIdGeneratorFactory =
          (EventTypeIdGeneratorFactory)
              JavaClassHelper.instantiate(
                  EventTypeIdGeneratorFactory.class,
                  configSnapshot
                      .getEngineDefaults()
                      .getAlternativeContext()
                      .getEventTypeIdGeneratorFactory());
      eventTypeIdGenerator =
          eventTypeIdGeneratorFactory.create(
              new EventTypeIdGeneratorContext(epServiceProvider.getURI()));
    }

    // Make services that depend on snapshot config entries
    EventAdapterServiceImpl eventAdapterService =
        new EventAdapterServiceImpl(
            eventTypeIdGenerator,
            configSnapshot.getEngineDefaults().getEventMeta().getAnonymousCacheSize());
    init(eventAdapterService, configSnapshot);

    // New read-write lock for concurrent event processing
    ManagedReadWriteLock eventProcessingRWLock = new ManagedReadWriteLock("EventProcLock", false);

    TimeSourceService timeSourceService = makeTimeSource(configSnapshot);
    SchedulingServiceSPI schedulingService =
        SchedulingServiceProvider.newService(timeSourceService);
    SchedulingMgmtService schedulingMgmtService = new SchedulingMgmtServiceImpl();
    EngineImportService engineImportService = makeEngineImportService(configSnapshot);
    EngineSettingsService engineSettingsService =
        new EngineSettingsService(
            configSnapshot.getEngineDefaults(), configSnapshot.getPlugInEventTypeResolutionURIs());
    DatabaseConfigService databaseConfigService =
        makeDatabaseRefService(configSnapshot, schedulingService, schedulingMgmtService);

    PluggableObjectCollection plugInViews = new PluggableObjectCollection();
    plugInViews.addViews(
        configSnapshot.getPlugInViews(), configSnapshot.getPlugInVirtualDataWindows());
    PluggableObjectCollection plugInPatternObj = new PluggableObjectCollection();
    plugInPatternObj.addPatternObjects(configSnapshot.getPlugInPatternObjects());

    // exception handling
    ExceptionHandlingService exceptionHandlingService =
        initExceptionHandling(
            epServiceProvider.getURI(),
            configSnapshot.getEngineDefaults().getExceptionHandling(),
            configSnapshot.getEngineDefaults().getConditionHandling());

    // Statement context factory
    Class systemVirtualDWViewFactory = null;
    if (configSnapshot.getEngineDefaults().getAlternativeContext().getVirtualDataWindowViewFactory()
        != null) {
      try {
        systemVirtualDWViewFactory =
            Class.forName(
                configSnapshot
                    .getEngineDefaults()
                    .getAlternativeContext()
                    .getVirtualDataWindowViewFactory());
        if (!JavaClassHelper.isImplementsInterface(
            systemVirtualDWViewFactory, VirtualDataWindowFactory.class)) {
          throw new ConfigurationException(
              "Class "
                  + systemVirtualDWViewFactory.getName()
                  + " does not implement the interface "
                  + VirtualDataWindowFactory.class.getName());
        }
      } catch (ClassNotFoundException e) {
        throw new ConfigurationException("Failed to look up class " + systemVirtualDWViewFactory);
      }
    }
    StatementContextFactory statementContextFactory =
        new StatementContextFactoryDefault(
            plugInViews, plugInPatternObj, systemVirtualDWViewFactory);

    long msecTimerResolution =
        configSnapshot.getEngineDefaults().getThreading().getInternalTimerMsecResolution();
    if (msecTimerResolution <= 0) {
      throw new ConfigurationException(
          "Timer resolution configuration not set to a valid value, expecting a non-zero value");
    }
    TimerService timerService =
        new TimerServiceImpl(epServiceProvider.getURI(), msecTimerResolution);

    VariableService variableService =
        new VariableServiceImpl(
            configSnapshot.getEngineDefaults().getVariables().getMsecVersionRelease(),
            schedulingService,
            eventAdapterService,
            null);
    initVariables(variableService, configSnapshot.getVariables(), engineImportService);

    TableService tableService = new TableServiceImpl();

    StatementLockFactory statementLockFactory =
        new StatementLockFactoryImpl(
            configSnapshot.getEngineDefaults().getExecution().isFairlock(),
            configSnapshot.getEngineDefaults().getExecution().isDisableLocking());
    StreamFactoryService streamFactoryService =
        StreamFactoryServiceProvider.newService(
            epServiceProvider.getURI(),
            configSnapshot.getEngineDefaults().getViewResources().isShareViews());
    FilterServiceSPI filterService =
        FilterServiceProvider.newService(
            configSnapshot.getEngineDefaults().getExecution().getFilterServiceProfile(),
            configSnapshot.getEngineDefaults().getExecution().isAllowIsolatedService());
    MetricReportingServiceImpl metricsReporting =
        new MetricReportingServiceImpl(
            configSnapshot.getEngineDefaults().getMetricsReporting(), epServiceProvider.getURI());
    NamedWindowService namedWindowService =
        new NamedWindowServiceImpl(
            schedulingService,
            variableService,
            tableService,
            engineSettingsService.getEngineSettings().getExecution().isPrioritized(),
            eventProcessingRWLock,
            exceptionHandlingService,
            configSnapshot.getEngineDefaults().getLogging().isEnableQueryPlan(),
            metricsReporting);

    ValueAddEventService valueAddEventService = new ValueAddEventServiceImpl();
    valueAddEventService.init(
        configSnapshot.getRevisionEventTypes(),
        configSnapshot.getVariantStreams(),
        eventAdapterService,
        eventTypeIdGenerator);

    StatementEventTypeRef statementEventTypeRef = new StatementEventTypeRefImpl();
    StatementVariableRef statementVariableRef =
        new StatementVariableRefImpl(variableService, tableService);

    ThreadingService threadingService =
        new ThreadingServiceImpl(configSnapshot.getEngineDefaults().getThreading());

    InternalEventRouterImpl internalEventRouterImpl = new InternalEventRouterImpl();

    StatementIsolationServiceImpl statementIsolationService = new StatementIsolationServiceImpl();

    DeploymentStateService deploymentStateService = new DeploymentStateServiceImpl();

    StatementMetadataFactory stmtMetadataFactory;
    if (configSnapshot.getEngineDefaults().getAlternativeContext().getStatementMetadataFactory()
        == null) {
      stmtMetadataFactory = new StatementMetadataFactoryDefault();
    } else {
      stmtMetadataFactory =
          (StatementMetadataFactory)
              JavaClassHelper.instantiate(
                  StatementMetadataFactory.class,
                  configSnapshot
                      .getEngineDefaults()
                      .getAlternativeContext()
                      .getStatementMetadataFactory());
    }

    ContextManagementService contextManagementService = new ContextManagementServiceImpl();

    SchedulableAgentInstanceDirectory schedulableAgentInstanceDirectory =
        null; // not required for Non-HA.

    PatternSubexpressionPoolEngineSvc patternSubexpressionPoolSvc = null;
    if (configSnapshot.getEngineDefaults().getPatterns().getMaxSubexpressions() != null) {
      patternSubexpressionPoolSvc =
          new PatternSubexpressionPoolEngineSvc(
              configSnapshot.getEngineDefaults().getPatterns().getMaxSubexpressions(),
              configSnapshot.getEngineDefaults().getPatterns().isMaxSubexpressionPreventStart());
    }

    MatchRecognizeStatePoolEngineSvc matchRecognizeStatePoolEngineSvc = null;
    if (configSnapshot.getEngineDefaults().getMatchRecognize().getMaxStates() != null) {
      matchRecognizeStatePoolEngineSvc =
          new MatchRecognizeStatePoolEngineSvc(
              configSnapshot.getEngineDefaults().getMatchRecognize().getMaxStates(),
              configSnapshot.getEngineDefaults().getMatchRecognize().isMaxStatesPreventStart());
    }

    // New services context
    EPServicesContext services =
        new EPServicesContext(
            epServiceProvider.getURI(),
            schedulingService,
            eventAdapterService,
            engineImportService,
            engineSettingsService,
            databaseConfigService,
            plugInViews,
            statementLockFactory,
            eventProcessingRWLock,
            null,
            jndiContext,
            statementContextFactory,
            plugInPatternObj,
            timerService,
            filterService,
            streamFactoryService,
            namedWindowService,
            variableService,
            tableService,
            timeSourceService,
            valueAddEventService,
            metricsReporting,
            statementEventTypeRef,
            statementVariableRef,
            configSnapshot,
            threadingService,
            internalEventRouterImpl,
            statementIsolationService,
            schedulingMgmtService,
            deploymentStateService,
            exceptionHandlingService,
            new PatternNodeFactoryImpl(),
            eventTypeIdGenerator,
            stmtMetadataFactory,
            contextManagementService,
            schedulableAgentInstanceDirectory,
            patternSubexpressionPoolSvc,
            matchRecognizeStatePoolEngineSvc,
            new DataFlowServiceImpl(epServiceProvider, new DataFlowConfigurationStateServiceImpl()),
            new ExprDeclaredServiceImpl(),
            new ContextControllerFactoryFactorySvcImpl(),
            new ContextManagerFactoryServiceImpl(),
            new EPStatementFactoryDefault(),
            new RegexHandlerFactoryDefault(),
            new ViewableActivatorFactoryDefault() {});

    // Engine services subset available to statements
    statementContextFactory.setStmtEngineServices(services);

    // Circular dependency
    StatementLifecycleSvc statementLifecycleSvc =
        new StatementLifecycleSvcImpl(epServiceProvider, services);
    services.setStatementLifecycleSvc(statementLifecycleSvc);

    // Observers to statement events
    statementLifecycleSvc.addObserver(metricsReporting);

    // Circular dependency
    statementIsolationService.setEpServicesContext(services);

    return services;
  }