Ejemplo n.º 1
0
  public void closeLiveQuery(final InternalFactHandle factHandle) {

    try {
      startOperation();
      this.ruleBase.readLock();
      this.lock.lock();

      final PropagationContext pCtx =
          new PropagationContextImpl(
              getNextPropagationIdCounter(),
              PropagationContext.INSERTION,
              null,
              null,
              factHandle,
              getEntryPoint());

      if (this.ruleBase.getConfiguration().isPhreakEnabled()) {
        LeftInputAdapterNode lian =
            (LeftInputAdapterNode)
                factHandle.getFirstLeftTuple().getLeftTupleSink().getLeftTupleSource();
        LiaNodeMemory lmem = (LiaNodeMemory) getNodeMemory((MemoryFactory) lian);
        SegmentMemory lsmem = lmem.getSegmentMemory();

        LeftTuple childLeftTuple =
            factHandle.getFirstLeftTuple(); // there is only one, all other LTs are peers
        LeftInputAdapterNode.doDeleteObject(
            childLeftTuple, childLeftTuple.getPropagationContext(), lsmem, this, lian, false, lmem);

        List<PathMemory> rmems = lmem.getSegmentMemory().getPathMemories();
        for (int i = 0, length = rmems.size(); i < length; i++) {
          PathMemory rm = rmems.get(i);

          RuleNetworkEvaluatorActivation evaluator =
              agenda.createRuleNetworkEvaluatorActivation(
                  Integer.MAX_VALUE, rm, (TerminalNode) rm.getNetworkNode());
          evaluator.evaluateNetwork(this, 0, -1);
        }
      } else {
        getEntryPointNode().retractQuery(factHandle, pCtx, this);

        pCtx.evaluateActionQueue(this);
      }

      getFactHandleFactory().destroyFactHandle(factHandle);

    } finally {
      this.lock.unlock();
      this.ruleBase.readUnlock();
      endOperation();
    }
  }
Ejemplo n.º 2
0
    public void execute(InternalWorkingMemory workingMemory) {
      DroolsQuery query = (DroolsQuery) factHandle.getObject();
      RightTupleList rightTuples = query.getResultInsertRightTupleList();
      query.setResultInsertRightTupleList(
          null); // null so further operations happen on a new stack element

      for (RightTuple rightTuple = rightTuples.getFirst(); rightTuple != null; ) {
        RightTuple tmp = (RightTuple) rightTuple.getNext();
        rightTuples.remove(rightTuple);
        for (LeftTuple childLeftTuple = rightTuple.firstChild;
            childLeftTuple != null;
            childLeftTuple = (LeftTuple) childLeftTuple.getRightParentNext()) {
          node.getSinkPropagator()
              .doPropagateAssertLeftTuple(
                  context, workingMemory, childLeftTuple, childLeftTuple.getLeftTupleSink());
        }
        rightTuple = tmp;
      }

      // @FIXME, this should work, but it's closing needed fact handles
      // actually an evaluation 34 appears on the stack twice....
      //            if ( !node.isOpenQuery() ) {
      //                workingMemory.getFactHandleFactory().destroyFactHandle( this.factHandle );
      //            }
    }
Ejemplo n.º 3
0
 public void execute(InternalWorkingMemory workingMemory) {
   InternalFactHandle factHandle = (InternalFactHandle) leftTuple.getObject();
   if (node.isOpenQuery()) {
     // iterate to the query terminal node, as the child leftTuples will get picked up there
     workingMemory
         .getEntryPointNode()
         .retractObject(
             factHandle,
             context,
             workingMemory
                 .getObjectTypeConfigurationRegistry()
                 .getObjectTypeConf(workingMemory.getEntryPoint(), factHandle.getObject()),
             workingMemory);
     // workingMemory.getFactHandleFactory().destroyFactHandle( factHandle );
   } else {
     // get child left tuples, as there is no open query
     if (leftTuple.getFirstChild() != null) {
       node.getSinkPropagator().propagateRetractLeftTuple(leftTuple, context, workingMemory);
     }
   }
 }
Ejemplo n.º 4
0
    public void execute(InternalWorkingMemory workingMemory) {
      DroolsQuery query = (DroolsQuery) factHandle.getObject();
      RightTupleList rightTuples = query.getResultRetractRightTupleList();
      query.setResultRetractRightTupleList(
          null); // null so further operations happen on a new stack element

      for (RightTuple rightTuple = rightTuples.getFirst(); rightTuple != null; ) {
        RightTuple tmp = (RightTuple) rightTuple.getNext();
        rightTuples.remove(rightTuple);
        this.node
            .getSinkPropagator()
            .propagateRetractRightTuple(rightTuple, context, workingMemory);
        rightTuple = tmp;
      }
    }
Ejemplo n.º 5
0
 public EqualityKey(final InternalFactHandle handle, final int status) {
   super((DefaultFactHandle) handle);
   this.hashCode = handle.getObjectHashCode();
   this.status = status;
 }
Ejemplo n.º 6
0
 /** Side-effects, will add the created key to the handle. */
 private EqualityKey createEqualityKey(InternalFactHandle handle) {
   EqualityKey key = new EqualityKey(handle);
   handle.setEqualityKey(key);
   return key;
 }
Ejemplo n.º 7
0
  protected void addPropertyChangeListener(
      final InternalFactHandle handle, final boolean dynamicFlag) {
    Object object = handle.getObject();
    try {
      final Method method =
          object
              .getClass()
              .getMethod(
                  "addPropertyChangeListener",
                  NamedEntryPoint.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES);

      method.invoke(object, this.addRemovePropertyChangeListenerArgs);

      if (dynamicFlag) {
        if (dynamicFacts == null) {
          dynamicFacts = new HashSet<InternalFactHandle>();
        }
        dynamicFacts.add(handle);
      }
    } catch (final NoSuchMethodException e) {
      System.err.println(
          "Warning: Method addPropertyChangeListener not found"
              + " on the class "
              + object.getClass()
              + " so Drools will be unable to process JavaBean"
              + " PropertyChangeEvents on the asserted Object");
    } catch (final IllegalArgumentException e) {
      System.err.println(
          "Warning: The addPropertyChangeListener method"
              + " on the class "
              + object.getClass()
              + " does not take"
              + " a simple PropertyChangeListener argument"
              + " so Drools will be unable to process JavaBean"
              + " PropertyChangeEvents on the asserted Object");
    } catch (final IllegalAccessException e) {
      System.err.println(
          "Warning: The addPropertyChangeListener method"
              + " on the class "
              + object.getClass()
              + " is not public"
              + " so Drools will be unable to process JavaBean"
              + " PropertyChangeEvents on the asserted Object");
    } catch (final InvocationTargetException e) {
      System.err.println(
          "Warning: The addPropertyChangeListener method"
              + " on the class "
              + object.getClass()
              + " threw an InvocationTargetException"
              + " so Drools will be unable to process JavaBean"
              + " PropertyChangeEvents on the asserted Object: "
              + e.getMessage());
    } catch (final SecurityException e) {
      System.err.println(
          "Warning: The SecurityManager controlling the class "
              + object.getClass()
              + " did not allow the lookup of a"
              + " addPropertyChangeListener method"
              + " so Drools will be unable to process JavaBean"
              + " PropertyChangeEvents on the asserted Object: "
              + e.getMessage());
    }
  }
Ejemplo n.º 8
0
  public void retract(
      final org.drools.FactHandle factHandle,
      final boolean removeLogical,
      final boolean updateEqualsMap,
      final Rule rule,
      final Activation activation)
      throws FactException {
    if (factHandle == null) {
      throw new IllegalArgumentException("FactHandle cannot be null ");
    }
    try {
      this.ruleBase.readLock();
      this.lock.lock();
      this.wm.startOperation();
      this.ruleBase.executeQueuedActions();

      InternalFactHandle handle = (InternalFactHandle) factHandle;
      if (handle.getId() == -1) {
        // can't retract an already retracted handle
        return;
      }

      // the handle might have been disconnected, so reconnect if it has
      if (handle.isDisconnected()) {
        handle = this.objectStore.reconnect(handle);
      }

      if (handle.getEntryPoint() != this) {
        throw new IllegalArgumentException(
            "Invalid Entry Point. You updated the FactHandle on entry point '"
                + handle.getEntryPoint().getEntryPointId()
                + "' instead of '"
                + getEntryPointId()
                + "'");
      }

      final Object object = handle.getObject();

      final ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf(this.entryPoint, object);

      if (typeConf.isSupportsPropertyChangeListeners()) {
        removePropertyChangeListener(handle, true);
      }

      if (activation != null) {
        // release resources so that they can be GC'ed
        activation.getPropagationContext().releaseResources();
      }
      final PropagationContext propagationContext =
          new PropagationContextImpl(
              this.wm.getNextPropagationIdCounter(),
              PropagationContext.RETRACTION,
              rule,
              (activation == null) ? null : activation.getTuple(),
              handle,
              this.wm.agenda.getActiveActivations(),
              this.wm.agenda.getDormantActivations(),
              this.entryPoint);

      this.entryPointNode.retractObject(handle, propagationContext, typeConf, this.wm);

      if (typeConf.isTMSEnabled()) {
        TruthMaintenanceSystem tms = wm.getTruthMaintenanceSystem();

        // Update the equality key, which maintains a list of stated
        // FactHandles
        final EqualityKey key = handle.getEqualityKey();

        // Its justified so attempt to remove any logical dependencies
        // for
        // the handle
        if (key.getStatus() == EqualityKey.JUSTIFIED) {
          tms.removeLogicalDependencies(handle);
        }

        key.removeFactHandle(handle);
        handle.setEqualityKey(null);

        // If the equality key is now empty, then remove it
        if (key.isEmpty()) {
          tms.remove(key);
        }
      }

      propagationContext.evaluateActionQueue(this.wm);

      this.wm.workingMemoryEventSupport.fireObjectRetracted(
          propagationContext, handle, object, this.wm);

      this.objectStore.removeHandle(handle);

      this.handleFactory.destroyFactHandle(handle);

      this.wm.executeQueuedActions();

      if (rule == null) {
        // This is not needed for internal WM actions as the firing rule will unstage
        this.wm.getAgenda().unstageActivations();
      }
    } finally {
      this.wm.endOperation();
      this.lock.unlock();
      this.ruleBase.readUnlock();
    }
  }
Ejemplo n.º 9
0
  public void update(
      org.drools.FactHandle factHandle,
      final Object object,
      final long mask,
      final Activation activation)
      throws FactException {
    try {
      this.ruleBase.readLock();
      this.lock.lock();
      this.wm.startOperation();
      this.ruleBase.executeQueuedActions();

      InternalFactHandle handle = (InternalFactHandle) factHandle;

      // the handle might have been disconnected, so reconnect if it has
      if (handle.isDisconnected()) {
        handle = this.objectStore.reconnect(factHandle);
      }

      final Object originalObject = handle.getObject();

      if (handle.getEntryPoint() != this) {
        throw new IllegalArgumentException(
            "Invalid Entry Point. You updated the FactHandle on entry point '"
                + handle.getEntryPoint().getEntryPointId()
                + "' instead of '"
                + getEntryPointId()
                + "'");
      }

      final ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf(this.entryPoint, object);

      // only needed if we maintain tms, but either way we must get it before we do the retract
      int status = -1;
      if (typeConf.isTMSEnabled()) {
        status = handle.getEqualityKey().getStatus();
      }

      if (handle.getId() == -1
          || object == null
          || (handle.isEvent() && ((EventFactHandle) handle).isExpired())) {
        // the handle is invalid, most likely already retracted, so return and we cannot assert a
        // null object
        return;
      }

      if (activation != null) {
        // release resources so that they can be GC'ed
        activation.getPropagationContext().releaseResources();
      }

      if (originalObject != object
          || !AssertBehaviour.IDENTITY.equals(
              this.ruleBase.getConfiguration().getAssertBehaviour())) {
        this.objectStore.removeHandle(handle);

        // set anyway, so that it updates the hashCodes
        handle.setObject(object);
        this.objectStore.addHandle(handle, object);
      }

      if (typeConf.isTMSEnabled()) {

        // the hashCode and equality has changed, so we must update the
        // EqualityKey
        EqualityKey key = handle.getEqualityKey();
        key.removeFactHandle(handle);

        TruthMaintenanceSystem tms = wm.getTruthMaintenanceSystem();

        // If the equality key is now empty, then remove it
        if (key.isEmpty()) {
          tms.remove(key);
        }

        // now use an existing EqualityKey, if it exists, else create a new one
        key = tms.get(object);
        if (key == null) {
          key = new EqualityKey(handle, status);
          tms.put(key);
        } else {
          key.addFactHandle(handle);
        }

        handle.setEqualityKey(key);
      }

      this.handleFactory.increaseFactHandleRecency(handle);

      Rule rule = activation == null ? null : activation.getRule();

      final PropagationContext propagationContext =
          new PropagationContextImpl(
              this.wm.getNextPropagationIdCounter(),
              PropagationContext.MODIFICATION,
              rule,
              (activation == null) ? null : activation.getTuple(),
              handle,
              this.wm.agenda.getActiveActivations(),
              this.wm.agenda.getDormantActivations(),
              entryPoint,
              mask);

      this.entryPointNode.modifyObject(handle, propagationContext, typeConf, this.wm);

      propagationContext.evaluateActionQueue(this.wm);

      this.wm.workingMemoryEventSupport.fireObjectUpdated(
          propagationContext, factHandle, originalObject, object, this.wm);

      this.wm.executeQueuedActions();

      if (rule == null) {
        // This is not needed for internal WM actions as the firing rule will unstage
        this.wm.getAgenda().unstageActivations();
      }
    } finally {
      this.wm.endOperation();
      this.lock.unlock();
      this.ruleBase.readUnlock();
    }
  }
Ejemplo n.º 10
0
  protected FactHandle insert(
      final Object object,
      final boolean dynamic,
      boolean logical,
      final Rule rule,
      final Activation activation)
      throws FactException {
    if (object == null) {
      // you cannot assert a null object
      return null;
    }

    try {
      this.wm.startOperation();

      ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf(this.entryPoint, object);
      if (logical && !typeConf.isTMSEnabled()) {
        enableTMS(object, typeConf);
      }

      InternalFactHandle handle = null;

      if (this.wm.isSequential()) {
        handle = createHandle(object, typeConf);
        insert(handle, object, rule, activation, typeConf);
        return handle;
      }
      try {
        this.ruleBase.readLock();
        this.lock.lock();
        // check if the object already exists in the WM
        handle = this.objectStore.getHandleForObject(object);

        if (typeConf.isTMSEnabled()) {

          EqualityKey key;

          TruthMaintenanceSystem tms = wm.getTruthMaintenanceSystem();
          if (handle == null) {
            // lets see if the object is already logical asserted
            key = tms.get(object);
          } else {
            // Object is already asserted, so check and possibly correct its
            // status and then return the handle
            key = handle.getEqualityKey();

            if (key.getStatus() == EqualityKey.STATED) {
              // return null as you cannot justify a stated object.
              return handle;
            }

            if (!logical) {
              // this object was previously justified, so we have to override it to stated
              key.setStatus(EqualityKey.STATED);
              tms.removeLogicalDependencies(handle);
            } else {
              // this was object is already justified, so just add new logical dependency
              tms.addLogicalDependency(
                  handle, activation, activation.getPropagationContext(), rule);
            }

            return handle;
          }

          // At this point we know the handle is null
          if (key == null) {

            handle = createHandle(object, typeConf);

            key = createEqualityKey(handle);

            tms.put(key);

            if (!logical) {
              key.setStatus(EqualityKey.STATED);
            } else {
              key.setStatus(EqualityKey.JUSTIFIED);
              tms.addLogicalDependency(
                  handle, activation, activation.getPropagationContext(), rule);
            }
          } else if (!logical) {
            if (key.getStatus() == EqualityKey.JUSTIFIED) {
              // Its previous justified, so switch to stated and remove logical dependencies
              final InternalFactHandle justifiedHandle = key.getFactHandle();
              tms.removeLogicalDependencies(justifiedHandle);

              if (this.wm.discardOnLogicalOverride) {
                // override, setting to new instance, and return
                // existing handle
                key.setStatus(EqualityKey.STATED);
                handle = key.getFactHandle();

                if (AssertBehaviour.IDENTITY.equals(
                    this.ruleBase.getConfiguration().getAssertBehaviour())) {
                  // as assertMap may be using an "identity"
                  // equality comparator,
                  // we need to remove the handle from the map,
                  // before replacing the object
                  // and then re-add the handle. Otherwise we may
                  // end up with a leak.
                  this.objectStore.updateHandle(handle, object);
                }
                return handle;
              } else {
                // override, then instantiate new handle for
                // assertion
                key.setStatus(EqualityKey.STATED);
                handle = createHandle(object, typeConf);
                handle.setEqualityKey(key);
                key.addFactHandle(handle);
              }

            } else {
              handle = createHandle(object, typeConf);
              key.addFactHandle(handle);
              handle.setEqualityKey(key);
            }

          } else {
            if (key.getStatus() == EqualityKey.JUSTIFIED) {
              // only add as logical dependency if this wasn't previously stated
              tms.addLogicalDependency(
                  key.getFactHandle(), activation, activation.getPropagationContext(), rule);
              return key.getFactHandle();
            } else {
              // You cannot justify a previously stated equality equal object, so return null
              return null;
            }
          }

        } else {
          if (handle != null) {
            return handle;
          }
          handle = createHandle(object, typeConf);
        }

        // if the dynamic parameter is true or if the user declared the fact type with the meta tag:
        // @propertyChangeSupport
        if (dynamic || typeConf.isDynamic()) {
          addPropertyChangeListener(handle, dynamic);
        }

        insert(handle, object, rule, activation, typeConf);

      } finally {
        this.lock.unlock();
        this.ruleBase.readUnlock();
      }
      return handle;
    } finally {
      this.wm.endOperation();
    }
  }
Ejemplo n.º 11
0
 public void destroyFactHandle(final InternalFactHandle factHandle) {
   factHandle.invalidate();
 }
Ejemplo n.º 12
0
 public final void increaseFactHandleRecency(final InternalFactHandle factHandle) {
   factHandle.setRecency(this.counter.incrementAndGet());
 }