Beispiel #1
0
 /**
  * Tests if a specific relation type is defined.
  *
  * <p>Note that this routine returns false both when a snumber/dnumber are swapped, and when a
  * typecombo does not exist - it is not possible to derive whether one or the other has occurred.
  *
  * <p>
  *
  * @param n1 The source type number.
  * @param n2 The destination type number.
  * @param r The relation definition (role) number, or -1 if the role does not matter r can only be
  *     -1 if virtual is <code>true</code>
  * @param restriction if {@link #STRICT}, contains only returns true if the typerel occurs as-is
  *     in the database. if {@link #INCLUDE_DESCENDANTS}, contains returns true if the typerel
  *     occurs as a virtual (derived) node, where source or destination may also be descendants of
  *     the specified type. if {@link #INCLUDE_PARENTS}, contains returns true if the typerel
  *     occurs as a virtual (derived) node, where source or destination may also be parents of the
  *     specified type. if {@link #INCLUDE_PARENTS_AND_DESCENDANTS}, contains returns true if the
  *     typerel occurs as a virtual (derived) node, where source or destination may also be
  *     descendants or parents of the specified type.
  * @return <code>true</code> when the relation exists, false otherwise.
  * @since MMBase-1.6.2
  */
 public boolean contains(int n1, int n2, int r, int restriction) {
   switch (restriction) {
     case INCLUDE_DESCENDANTS:
       return typeRelNodes.contains(new VirtualTypeRelNode(n1, n2, r));
     case INCLUDE_PARENTS:
       return parentTypeRelNodes.contains(new VirtualTypeRelNode(n1, n2, r));
     case INCLUDE_PARENTS_AND_DESCENDANTS:
       return typeRelNodes.contains(new VirtualTypeRelNode(n1, n2, r))
           || parentTypeRelNodes.contains(new VirtualTypeRelNode(n1, n2, r));
     case STRICT:
       SortedSet<MMObjectNode> existingNodes = typeRelNodes.getBySourceDestinationRole(n1, n2, r);
       return (existingNodes.size() > 0 && !existingNodes.first().isVirtual());
     default:
       log.error("Unknown restriction " + restriction);
       return false;
   }
 }
Beispiel #2
0
 /**
  * A Set of all allowed relations of a certain role between two builders. Distinction is made
  * between source and destination depending on passed directionality.
  *
  * @since MMBase-1.6.2
  */
 public Set<MMObjectNode> getAllowedRelations(
     int builder1, int builder2, int role, int directionality) {
   Set<MMObjectNode> res = new HashSet<MMObjectNode>();
   if (directionality != RelationStep.DIRECTIONS_SOURCE) {
     res.addAll(typeRelNodes.getBySourceDestinationRole(builder1, builder2, role));
   }
   if (directionality != RelationStep.DIRECTIONS_DESTINATION
       && (directionality != RelationStep.DIRECTIONS_EITHER || res.isEmpty())) {
     res.addAll(inverseTypeRelNodes.getByDestinationSourceRole(builder2, builder1, role));
   }
   return res;
 }
Beispiel #3
0
  /**
   * Retrieves the identifying number of the relation definition that is 'allowed' between two
   * specified node types. The results are dependent on there being only one type of relation
   * between two node types (not enforced, thus unpredictable). Makes use of a typeRelNodes.
   *
   * @param snum The first objectnode type (the source)
   * @param dnum The second objectnode type (the destination)
   * @return the number of the found relation, or -1 if either no relation was found, or more than
   *     one was found.
   */
  public int getAllowedRelationType(int snum, int dnum) {
    Set<MMObjectNode> set =
        new HashSet<MMObjectNode>(typeRelNodes.getBySourceDestination(snum, dnum));
    set.addAll(inverseTypeRelNodes.getByDestinationSource(dnum, snum));

    if (set.size() != 1) {
      return -1;
    } else {
      MMObjectNode n = set.iterator().next();
      return n.getIntValue("rnumber");
    }
  }
Beispiel #4
0
  /**
   * Addes one typerel cache entries, plus inherited relations (if builder are initialized)
   *
   * @return A Set with the added entries, which can be used for logging or so, or can be
   *     disregarded
   * @since MMBase-1.6.2
   */
  protected TypeRelSet addCacheEntry(
      final MMObjectNode typeRel, final boolean buildersInitialized) {

    if (typeRel == null) {
      throw new IllegalArgumentException("typeRel cannot be null");
    }

    final TypeRelSet added =
        new TypeRelSet(); // store temporary, which will enable nice logging of what happened

    // Start to add the actual definition, this is then afterwards again,
    // except if one of the builders could not be found
    added.add(typeRel);

    if (mmb == null) {
      throw new IllegalStateException("mmb is null");
    }

    final RelDef reldef = mmb.getRelDef();
    if (reldef == null) {
      throw new IllegalStateException("No reldef found");
    }

    final MMObjectNode reldefNode = reldef.getNode(typeRel.getIntValue("rnumber"));
    if (reldefNode == null) {
      throw new RuntimeException(
          "Could not find reldef-node for rnumber= " + typeRel.getIntValue("rnumber"));
    }

    final boolean bidirectional = (!InsRel.usesdir) || (reldefNode.getIntValue("dir") > 1);

    INHERITANCE:
    if (buildersInitialized) { // handle inheritance, which is
      // not possible during
      // initialization of MMBase.

      final TypeDef typeDef = mmb.getTypeDef();

      final String sourceBuilderName = typeDef.getValue(typeRel.getIntValue("snumber"));
      final MMObjectBuilder sourceBuilder =
          sourceBuilderName != null ? mmb.getBuilder(sourceBuilderName) : null;

      final String destinationBuilderName = typeDef.getValue(typeRel.getIntValue("dnumber"));
      final MMObjectBuilder destinationBuilder =
          destinationBuilderName != null ? mmb.getBuilder(destinationBuilderName) : null;

      if (sourceBuilder == null) {
        if (destinationBuilder == null) {
          log.info(
              "Both source and destination of "
                  + typeRel
                  + " are not active builders. Cannot follow descendants.");
        } else {
          log.info(
              "The source of relation type "
                  + typeRel
                  + " is not an active builder. Cannot follow descendants.");
        }
        break INHERITANCE;
      }

      if (destinationBuilder == null) {
        log.warn(
            "The destination of relation type "
                + typeRel
                + " is not an active builder. Cannot follow descendants.");
        break INHERITANCE;
      }

      final int rnumber = typeRel.getIntValue("rnumber");

      final List<MMObjectBuilder> sources =
          new ArrayList<MMObjectBuilder>(sourceBuilder.getDescendants());
      sources.add(sourceBuilder);

      final List<MMObjectBuilder> destinations =
          new ArrayList<MMObjectBuilder>(destinationBuilder.getDescendants());
      destinations.add(destinationBuilder);

      for (MMObjectBuilder s : sources) {
        for (MMObjectBuilder d : destinations) {
          MMObjectNode vnode = new VirtualTypeRelNode(s.getNumber(), d.getNumber(), rnumber);
          added.add(vnode);
        }
      }

      // seek all parents and store typerels for them
      // this cache is used by contains(INCLUDE_PARENTS /
      // INCLUDE_PARENTS_AND_DESCENDANTS));
      MMObjectBuilder sourceParent = sourceBuilder;
      while (sourceParent != null) {
        MMObjectBuilder destinationParent = destinationBuilder;
        while (destinationParent != null) {
          MMObjectNode vnode =
              new VirtualTypeRelNode(
                  sourceParent.getNumber(), destinationParent.getNumber(), rnumber);
          parentTypeRelNodes.add(vnode);
          destinationParent = destinationParent.getParentBuilder();
        }
        sourceParent = sourceParent.getParentBuilder();
      }
      added.add(typeRel); // replaces the ones added in the 'inheritance'
      // loop (so now not any more Virtual)
    }

    for (MMObjectNode node : added) {
      if (!node.isVirtual()) {
        // make sure 'real' nodes replace virtual nodes. (real and virtual nodes are equal, so will
        // not be added to set otherwise)
        // This is especially essential whey you use STRICT in contains
        typeRelNodes.remove(node);
        if (bidirectional) inverseTypeRelNodes.remove(node);
      }
      typeRelNodes.add(node);
      if (bidirectional) inverseTypeRelNodes.add(node);
    }
    if (log.isDebugEnabled()) {
      log.debug("Added to typerelcache: " + added);
    }
    return added;
  }