/**
   * Ctor.
   *
   * @param statementStopService for indicating a statement was stopped or destroyed for cleanup
   * @param lookupStrategy for handling trigger events to determine deleted events
   * @param rootView the named window root view
   * @param internalEventRouter for insert-into behavior
   * @param resultSetProcessor for processing aggregation, having and ordering
   * @param statementHandle required for routing events
   * @param statementResultService for coordinating on whether insert and remove stream events
   *     should be posted
   * @param statementContext statement services
   * @param isDistinct is true for distinct output
   */
  public NamedWindowOnSelectView(
      StatementStopService statementStopService,
      NamedWindowLookupStrategy lookupStrategy,
      NamedWindowRootView rootView,
      InternalEventRouter internalEventRouter,
      boolean addToFront,
      ResultSetProcessor resultSetProcessor,
      EPStatementHandle statementHandle,
      StatementResultService statementResultService,
      StatementContext statementContext,
      boolean isDistinct) {
    super(statementStopService, lookupStrategy, rootView, statementContext);
    this.internalEventRouter = internalEventRouter;
    this.addToFront = addToFront;
    this.resultSetProcessor = resultSetProcessor;
    this.statementHandle = statementHandle;
    this.statementResultService = statementResultService;
    this.statementContext = statementContext;
    this.isDistinct = isDistinct;

    if (isDistinct) {
      if (resultSetProcessor.getResultEventType() instanceof EventTypeSPI) {
        eventBeanReader = ((EventTypeSPI) resultSetProcessor.getResultEventType()).getReader();
      }
      if (eventBeanReader == null) {
        eventBeanReader = new EventBeanReaderDefaultImpl(resultSetProcessor.getResultEventType());
      }
    }
  }
  public void handleMatching(EventBean[] triggerEvents, EventBean[] matchingEvents) {
    EventBean[] newData;

    // clear state from prior results
    resultSetProcessor.clear();

    // build join result
    // use linked hash set to retain order of join results for last/first/window to work most
    // intuitively
    Set<MultiKey<EventBean>> newEvents = new LinkedHashSet<MultiKey<EventBean>>();
    for (int i = 0; i < triggerEvents.length; i++) {
      EventBean triggerEvent = triggerEvents[0];
      if (matchingEvents != null) {
        for (int j = 0; j < matchingEvents.length; j++) {
          EventBean[] eventsPerStream = new EventBean[2];
          eventsPerStream[0] = matchingEvents[j];
          eventsPerStream[1] = triggerEvent;
          newEvents.add(new MultiKey<EventBean>(eventsPerStream));
        }
      }
    }

    // process matches
    UniformPair<EventBean[]> pair =
        resultSetProcessor.processJoinResult(newEvents, oldEvents, false);
    newData = (pair != null ? pair.getFirst() : null);

    if (isDistinct) {
      newData = EventBeanUtility.getDistinctByProp(newData, eventBeanReader);
    }

    if (internalEventRouter != null) {
      if (newData != null) {
        for (int i = 0; i < newData.length; i++) {
          internalEventRouter.route(
              newData[i],
              statementHandle,
              statementContext.getInternalEventEngineRouteDest(),
              statementContext,
              addToFront);
        }
      }
    }

    // The on-select listeners receive the events selected
    if ((newData != null) && (newData.length > 0)) {
      // And post only if we have listeners/subscribers that need the data
      if (statementResultService.isMakeNatural() || statementResultService.isMakeSynthetic()) {
        updateChildren(newData, null);
      }
    }
    lastResult = newData;

    // clear state from prior results
    resultSetProcessor.clear();
  }
 public EventType getEventType() {
   if (resultSetProcessor != null) {
     return resultSetProcessor.getResultEventType();
   } else {
     return namedWindowEventType;
   }
 }
  public static Iterator<EventBean> getIterator(
      JoinExecutionStrategy joinExecutionStrategy,
      ResultSetProcessor resultSetProcessor,
      Viewable parentView,
      boolean distinct) {
    Iterator<EventBean> iterator;
    EventType eventType;
    if (joinExecutionStrategy != null) {
      Set<MultiKey<EventBean>> joinSet = joinExecutionStrategy.staticJoin();
      iterator = resultSetProcessor.getIterator(joinSet);
      eventType = resultSetProcessor.getResultEventType();
    } else if (resultSetProcessor != null) {
      iterator = resultSetProcessor.getIterator(parentView);
      eventType = resultSetProcessor.getResultEventType();
    } else {
      iterator = parentView.iterator();
      eventType = parentView.getEventType();
    }

    if (!distinct) {
      return iterator;
    }
    return new EventDistinctIterator(iterator, eventType);
  }