Example #1
0
 public void dispose() {
   if (dynamicFacts != null) {
     // first we check for facts that were inserted into the working memory
     // using the old API and setting a per instance dynamic flag and remove the
     // session from the listeners list in the bean
     for (InternalFactHandle handle : dynamicFacts) {
       removePropertyChangeListener(handle, false);
     }
     dynamicFacts = null;
   }
   for (ObjectTypeConf conf : this.typeConfReg.values()) {
     // then, we check if any of the object types were configured using the
     // @propertyChangeSupport annotation, and clean them up
     if (conf.isDynamic() && conf.isSupportsPropertyChangeListeners()) {
       // it is enough to iterate the facts on the concrete object type nodes
       // only, as the facts will always be in their concrete object type nodes
       // even if they were also asserted into higher level OTNs as well
       ObjectTypeNode otn = conf.getConcreteObjectTypeNode();
       final ObjectHashSet memory =
           ((ObjectTypeNodeMemory) this.getInternalWorkingMemory().getNodeMemory(otn)).memory;
       Iterator it = memory.iterator();
       for (ObjectEntry entry = (ObjectEntry) it.next();
           entry != null;
           entry = (ObjectEntry) it.next()) {
         InternalFactHandle handle = (InternalFactHandle) entry.getValue();
         removePropertyChangeListener(handle, false);
       }
     }
   }
 }
Example #2
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();
    }
  }