示例#1
0
  public static ObjectTypeNode attachObjectTypeNode(BuildContext context, ObjectType objectType) {
    final InternalRuleBase ruleBase = context.getRuleBase();
    ruleBase.readLock();
    try {
      InternalWorkingMemory[] wms = context.getWorkingMemories();

      EntryPointNode epn = ruleBase.getRete().getEntryPointNode(context.getCurrentEntryPoint());
      if (epn == null) {
        epn = new EntryPointNode(context.getNextId(), ruleBase.getRete(), context);
        if (wms.length > 0) {
          epn.attach(wms);
        } else {
          epn.attach();
        }
      }

      ObjectTypeNode otn = new ObjectTypeNode(context.getNextId(), epn, objectType, context);

      long expirationOffset = getExpiratioOffsetForType(context, objectType);
      otn.setExpirationOffset(expirationOffset);

      if (wms.length > 0) {
        otn.attach(wms);
      } else {
        otn.attach();
      }

      return otn;
    } finally {
      ruleBase.readUnlock();
    }
  }
示例#2
0
  public void attach(final InternalWorkingMemory[] workingMemories) {
    attach();

    // we need to call updateSink on Rete, because someone
    // might have already added facts matching this ObjectTypeNode
    // to working memories
    for (int i = 0, length = workingMemories.length; i < length; i++) {
      final InternalWorkingMemory workingMemory = workingMemories[i];
      final PropagationContextImpl propagationContext =
          new PropagationContextImpl(
              workingMemory.getNextPropagationIdCounter(),
              PropagationContext.RULE_ADDITION,
              null,
              null,
              null);
      propagationContext.setEntryPoint(((EntryPointNode) this.source).getEntryPoint());
      this.source.updateSink(this, propagationContext, workingMemory);
    }
  }
  public void testQueryTerminalNode() {
    final ClassObjectType queryObjectType = new ClassObjectType(DroolsQuery.class);
    final ObjectTypeNode queryObjectTypeNode =
        new ObjectTypeNode(this.buildContext.getNextId(), queryObjectType, buildContext);
    queryObjectTypeNode.attach();

    ClassFieldExtractor extractor =
        cache.getExtractor(DroolsQuery.class, "name", DroolsQuery.class.getClassLoader());

    FieldValue field = FieldFactory.getFieldValue("query-1");

    final Evaluator evaluator = ValueType.STRING_TYPE.getEvaluator(Operator.EQUAL);
    LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field);

    AlphaNode alphaNode =
        new AlphaNode(this.buildContext.getNextId(), constraint, queryObjectTypeNode, buildContext);
    alphaNode.attach();

    final LeftInputAdapterNode liaNode =
        new LeftInputAdapterNode(this.buildContext.getNextId(), alphaNode, this.buildContext);
    liaNode.attach();

    final ClassObjectType cheeseObjectType = new ClassObjectType(Cheese.class);
    final ObjectTypeNode cheeseObjectTypeNode =
        new ObjectTypeNode(this.buildContext.getNextId(), cheeseObjectType, buildContext);
    cheeseObjectTypeNode.attach();

    extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader());

    field = FieldFactory.getFieldValue("stilton");

    constraint = new LiteralConstraint(extractor, evaluator, field);

    alphaNode =
        new AlphaNode(
            this.buildContext.getNextId(), constraint, cheeseObjectTypeNode, buildContext);
    alphaNode.attach();

    BuildContext buildContext =
        new BuildContext(ruleBase, ruleBase.getReteooBuilder().getIdGenerator());
    buildContext.setTupleMemoryEnabled(false);

    final JoinNode joinNode =
        new JoinNode(
            this.buildContext.getNextId(),
            liaNode,
            alphaNode,
            EmptyBetaConstraints.getInstance(),
            buildContext);
    joinNode.attach();

    final Query query = new Query("query-1");

    final QueryTerminalNode queryNode =
        new QueryTerminalNode(this.buildContext.getNextId(), joinNode, query, query.getLhs());

    queryNode.attach();

    final org.drools.rule.Package pkg = new org.drools.rule.Package("com.drools.test");
    pkg.addRule(query);

    try {
      final Field pkgField = ruleBase.getClass().getSuperclass().getDeclaredField("pkgs");
      pkgField.setAccessible(true);
      final Map pkgs = (Map) pkgField.get(ruleBase);
      pkgs.put(pkg.getName(), pkg);
    } catch (final Exception e) {
      Assert.fail("Should not throw any exception: " + e.getMessage());
    }

    final WorkingMemory workingMemory = ruleBase.newStatefulSession();
    QueryResults results = workingMemory.getQueryResults("query-1");

    assertEquals(0, results.size());

    final Cheese stilton1 = new Cheese("stilton", 100);
    final FactHandle handle1 = workingMemory.insert(stilton1);

    results = workingMemory.getQueryResults("query-1");

    assertEquals(1, results.size());

    final Cheese cheddar = new Cheese("cheddar", 55);
    workingMemory.insert(cheddar);

    results = workingMemory.getQueryResults("query-1");

    assertEquals(1, results.size());

    final Cheese stilton2 = new Cheese("stilton", 5);

    final FactHandle handle2 = workingMemory.insert(stilton2);

    results = workingMemory.getQueryResults("query-1");

    assertEquals(2, results.size());

    QueryResult result = results.get(0);
    assertEquals(1, result.size());
    assertEquals(stilton2, result.get(0));

    result = results.get(1);
    assertEquals(1, result.size());
    assertEquals(stilton1, result.get(0));

    int i = 0;
    for (final Iterator it = results.iterator(); it.hasNext(); ) {
      result = (QueryResult) it.next();
      assertEquals(1, result.size());
      if (i == 1) {
        assertSame(stilton1, result.get(0));
      } else {
        assertSame(stilton2, result.get(0));
      }
      i++;
    }

    workingMemory.retract(handle1);
    results = workingMemory.getQueryResults("query-1");

    assertEquals(1, results.size());

    workingMemory.retract(handle2);
    results = workingMemory.getQueryResults("query-1");

    assertEquals(0, results.size());
  }
  public static ReteooStatefulSession readSession(
      ReteooStatefulSession session,
      DefaultAgenda agenda,
      long time,
      boolean multithread,
      MarshallerReaderContext context)
      throws IOException, ClassNotFoundException {
    if (session.getTimerService() instanceof PseudoClockScheduler) {
      PseudoClockScheduler clock = (PseudoClockScheduler) session.getTimerService();
      clock.advanceTime(time, TimeUnit.MILLISECONDS);
    }

    // RuleFlowGroups need to reference the session
    for (RuleFlowGroup group : agenda.getRuleFlowGroupsMap().values()) {
      ((RuleFlowGroupImpl) group).setWorkingMemory(session);
    }

    context.wm = session;

    context.handles.put(
        context.wm.getInitialFactHandle().getId(), context.wm.getInitialFactHandle());

    if (context.stream.readBoolean()) {
      InternalFactHandle initialFactHandle = context.wm.getInitialFactHandle();
      int sinkId = context.stream.readInt();
      ObjectTypeNode initialFactNode = (ObjectTypeNode) context.sinks.get(sinkId);
      if (initialFactNode == null) {
        // ------ START RANT ------
        // The following code is as bad as it looks, but since I was so far
        // unable to convince Mark that creating OTNs on demand is really bad,
        // I have to continue doing it :)
        EntryPointNode defaultEPNode =
            context.ruleBase.getRete().getEntryPointNode(EntryPoint.DEFAULT);
        BuildContext buildContext =
            new BuildContext(
                context.ruleBase, context.ruleBase.getReteooBuilder().getIdGenerator());
        buildContext.setPartitionId(RuleBasePartitionId.MAIN_PARTITION);
        buildContext.setObjectTypeNodeMemoryEnabled(true);
        initialFactNode =
            new ObjectTypeNode(
                sinkId, defaultEPNode, ClassObjectType.InitialFact_ObjectType, buildContext);
        // isn't contention something everybody loves?
        context.ruleBase.lock();
        try {
          // Yeah, I know, because one session is being deserialized, we go and lock all of them...
          initialFactNode.attach(buildContext);
        } finally {
          context.ruleBase.unlock();
        }
        // ------- END RANT -----
      }
      ObjectHashSet initialFactMemory = (ObjectHashSet) context.wm.getNodeMemory(initialFactNode);

      initialFactMemory.add(initialFactHandle);
      readRightTuples(initialFactHandle, context);
    }
    while (context.readShort() == PersisterEnums.ENTRY_POINT) {
      String entryPointId = context.stream.readUTF();
      WorkingMemoryEntryPoint wmep = context.wm.getEntryPoints().get(entryPointId);
      readFactHandles(context, ((NamedEntryPoint) wmep).getObjectStore());
    }
    InternalFactHandle handle = context.wm.getInitialFactHandle();
    while (context.stream.readShort() == PersisterEnums.LEFT_TUPLE) {
      LeftTupleSink sink = (LeftTupleSink) context.sinks.get(context.stream.readInt());
      LeftTuple leftTuple = sink.createLeftTuple(handle, sink, true);
      readLeftTuple(leftTuple, context);
    }

    readPropagationContexts(context);

    readActivations(context);

    readActionQueue(context);

    readTruthMaintenanceSystem(context);

    if (processMarshaller != null) {
      processMarshaller.readProcessInstances(context);
    } else {
      short type = context.stream.readShort();
      if (PersisterEnums.END != type) {
        throw new IllegalStateException(
            "No process marshaller, unable to unmarshall type: " + type);
      }
    }

    if (processMarshaller != null) {
      processMarshaller.readWorkItems(context);
    } else {
      short type = context.stream.readShort();
      if (PersisterEnums.END != type) {
        throw new IllegalStateException(
            "No process marshaller, unable to unmarshall type: " + type);
      }
    }

    if (processMarshaller != null) {
      // This actually does ALL timers, due to backwards compatability issues
      // It will read in old JBPM binaries, but always write to the new binary format.
      processMarshaller.readProcessTimers(context);
    } else {
      short type = context.stream.readShort();
      if (PersisterEnums.END != type) {
        throw new IllegalStateException(
            "No process marshaller, unable to unmarshall type: " + type);
      }
    }

    // no legacy jBPM timers, so handle locally
    while (context.readShort() == PersisterEnums.DEFAULT_TIMER) {
      InputMarshaller.readTimer(context);
    }

    if (multithread) {
      session.startPartitionManagers();
    }

    return session;
  }