public void build(
      final RuleBuildContext context,
      final BoundIdentifiers usedIdentifiers,
      final Declaration[] previousDeclarations,
      final Declaration[] localDeclarations,
      final PredicateConstraint predicate,
      final PredicateDescr predicateDescr,
      final AnalysisResult analysis) {
    MVELDialect dialect = (MVELDialect) context.getDialect(context.getDialect().getId());

    try {
      Map<String, Class<?>> declIds =
          context.getDeclarationResolver().getDeclarationClasses(context.getRule());

      Pattern p = (Pattern) context.getBuildStack().peek();
      if (p.getObjectType() instanceof ClassObjectType) {
        declIds.put("this", ((ClassObjectType) p.getObjectType()).getClassType());
      }

      MVELCompilationUnit unit =
          dialect.getMVELCompilationUnit(
              (String) predicateDescr.getContent(),
              analysis,
              previousDeclarations,
              localDeclarations,
              null,
              context);

      MVELPredicateExpression expr =
          new MVELPredicateExpression(unit, context.getDialect().getId());
      predicate.setPredicateExpression(expr);

      MVELDialectRuntimeData data =
          (MVELDialectRuntimeData)
              context
                  .getPkg()
                  .getDialectRuntimeRegistry()
                  .getDialectData(context.getDialect().getId());
      data.addCompileable(predicate, expr);

      expr.compile(context.getPackageBuilder().getRootClassLoader());
    } catch (final Exception e) {
      context
          .getErrors()
          .add(
              new DescrBuildError(
                  context.getParentDescr(),
                  predicateDescr,
                  e,
                  "Unable to build expression for 'inline-eval' : "
                      + e.getMessage()
                      + "'"
                      + predicateDescr.getContent()
                      + "'\n"
                      + e.getMessage()));
    }
  }
예제 #2
0
  /**
   * @param context
   * @param pattern
   * @param betaConstraints
   */
  private void checkRemoveIdentities(
      final BuildContext context, final Pattern pattern, final List<Constraint> betaConstraints) {
    if (context.getRuleBase().getConfiguration().isRemoveIdentities()
        && pattern.getObjectType().getClass() == ClassObjectType.class) {
      // Check if this object type exists before
      // If it does we need stop instance equals cross product
      final Class<?> thisClass = ((ClassObjectType) pattern.getObjectType()).getClassType();
      for (final Iterator<Pattern> it = context.getObjectType().iterator(); it.hasNext(); ) {
        final Pattern previousPattern = it.next();
        final Class<?> previousClass =
            ((ClassObjectType) previousPattern.getObjectType()).getClassType();
        if (thisClass.isAssignableFrom(previousClass)) {
          betaConstraints.add(new InstanceNotEqualsConstraint(previousPattern));
        }
      }

      // Must be added after the checking, otherwise it matches against itself
      context.getObjectType().add(pattern);
    }
  }
예제 #3
0
  private void createConstraints(
      BuildContext context,
      BuildUtils utils,
      Pattern pattern,
      List<Constraint> alphaConstraints,
      List<Constraint> betaConstraints) {

    final List<?> constraints = pattern.getConstraints();

    // check if cross products for identity patterns should be disabled
    checkRemoveIdentities(context, pattern, betaConstraints);

    // checks if this pattern is nested inside a NOT CE
    final boolean isNegative = isNegative(context);

    for (final Iterator<?> it = constraints.iterator(); it.hasNext(); ) {
      final Object object = it.next();
      // Check if its a declaration
      if (object instanceof Declaration) {
        // nothing to be done
        continue;
      }

      final Constraint constraint = (Constraint) object;
      if (constraint.getType().equals(Constraint.ConstraintType.ALPHA)) {
        alphaConstraints.add(constraint);
      } else if (constraint.getType().equals(Constraint.ConstraintType.BETA)) {
        betaConstraints.add(constraint);
        if (isNegative
            && context.getRuleBase().getConfiguration().getEventProcessingMode()
                == EventProcessingOption.STREAM
            && pattern.getObjectType().isEvent()
            && constraint.isTemporal()) {
          checkDelaying(context, constraint);
        }
      } else {
        throw new RuntimeDroolsException(
            "Unknown constraint type: "
                + constraint.getType()
                + ". This is a bug. Please contact development team.");
      }
    }
  }
예제 #4
0
  @Override
  protected void initDeclaredMask(BuildContext context, LeftTupleSource leftInput) {
    if (context == null || context.getLastBuiltPatterns() == null) {
      // only happens during unit tests
      rightDeclaredMask = Long.MAX_VALUE;
      super.initDeclaredMask(context, leftInput);
      return;
    }

    if (!(rightInput instanceof RightInputAdapterNode)) {
      Pattern pattern = context.getLastBuiltPatterns()[0]; // right input pattern
      ObjectType objectType = pattern.getObjectType();

      if (!(objectType instanceof ClassObjectType)) {
        // InitialFact has no type declaration and cannot be property specific
        // Only ClassObjectType can use property specific
        rightDeclaredMask = Long.MAX_VALUE;
      }

      Class objectClass = ((ClassObjectType) objectType).getClassType();
      if (isPropertyReactive(context, objectClass)) {
        rightListenedProperties = pattern.getListenedProperties();
        List<String> settableProperties = getSettableProperties(context.getRuleBase(), objectClass);
        rightDeclaredMask = calculatePositiveMask(rightListenedProperties, settableProperties);
        rightDeclaredMask |= constraints.getListenedPropertyMask(settableProperties);
        rightNegativeMask = calculateNegativeMask(rightListenedProperties, settableProperties);
      } else {
        // if property reactive is not on, then accept all modification propagations
        rightDeclaredMask = Long.MAX_VALUE;
      }
    } else {
      rightDeclaredMask = Long.MAX_VALUE;
      // There would have been no right input pattern, so swap current to first, so leftInput can
      // still work
      context.setLastBuiltPattern(context.getLastBuiltPatterns()[0]);
    }

    super.initDeclaredMask(context, leftInput);
  }
예제 #5
0
  public void attachAlphaNodes(
      final BuildContext context,
      final BuildUtils utils,
      final Pattern pattern,
      List<Constraint> alphaConstraints)
      throws InvalidPatternException {

    // Drools Query ObjectTypeNode never has memory, but other ObjectTypeNode/AlphaNoesNodes may (if
    // not in sequential),
    // so need to preserve, so we can restore after this node is added. LeftMemory  and Terminal
    // remain the same once set.

    boolean objectMemory = context.isObjectTypeNodeMemoryEnabled();
    boolean alphaMemory = context.isAlphaMemoryAllowed();

    ObjectType objectType = pattern.getObjectType();

    if (pattern.getObjectType() instanceof ClassObjectType) {
      // Is this the query node, if so we don't want any memory
      if (DroolsQuery.class == ((ClassObjectType) pattern.getObjectType()).getClassType()) {
        context.setTupleMemoryEnabled(false);
        context.setObjectTypeNodeMemoryEnabled(false);
        context.setTerminalNodeMemoryEnabled(false);
        context.setAlphaNodeMemoryAllowed(false);
      }
    }

    context.setObjectSource(
        (ObjectSource)
            utils.attachNode(
                context,
                new EntryPointNode(context.getNextId(), context.getRuleBase().getRete(), context)));

    ObjectTypeNode otn =
        new ObjectTypeNode(
            context.getNextId(), (EntryPointNode) context.getObjectSource(), objectType, context);
    if (objectType.isEvent()
        && EventProcessingOption.STREAM.equals(
            context.getRuleBase().getConfiguration().getEventProcessingMode())) {
      long expirationOffset = getExpiratioOffsetForType(context, objectType);
      if (expirationOffset != -1) {
        // expiration policy is set, so use it
        otn.setExpirationOffset(expirationOffset);
      } else {
        // otherwise calculate it based on behaviours and temporal constraints
        for (Behavior behavior : pattern.getBehaviors()) {
          if (behavior.getExpirationOffset() != -1) {
            expirationOffset = Math.max(behavior.getExpirationOffset(), expirationOffset);
          }
        }
        long distance = context.getTemporalDistance().getExpirationOffset(pattern);
        if (distance == -1) {
          // it means the rules have no temporal constraints, or
          // the constraints require events to be hold forever. In this
          // case, we allow type declarations to override the implicit
          // expiration offset by defining an expiration policy with the
          // @expires tag
          otn.setExpirationOffset(expirationOffset);
        } else {
          otn.setExpirationOffset(Math.max(distance, expirationOffset));
        }
      }
    }

    context.setObjectSource((ObjectSource) utils.attachNode(context, otn));

    for (final Iterator<Constraint> it = alphaConstraints.iterator(); it.hasNext(); ) {
      final AlphaNodeFieldConstraint constraint = (AlphaNodeFieldConstraint) it.next();

      context.pushRuleComponent(constraint);
      context.setObjectSource(
          (ObjectSource)
              utils.attachNode(
                  context,
                  new AlphaNode(
                      context.getNextId(),
                      (AlphaNodeFieldConstraint) constraint,
                      context.getObjectSource(),
                      context)));
      context.popRuleComponent();
    }

    // now restore back to original values
    context.setObjectTypeNodeMemoryEnabled(objectMemory);
    context.setAlphaNodeMemoryAllowed(alphaMemory);
  }