evaluate method

Future<bool> evaluate(
  1. Node node
)

Evaluates a provided node against this criteria.

The node is evaluated as follows. An node is equivalent if and only if...

  1. the node is the same path or a sub path of the search criteria path path
  2. if an owner regexp is set -> it must match the nodes owner
  3. if a visibility regexp is set -> it must match the visibility
  4. if a nodeValueKey and a nodeValueValue is set -> 4a. The respective key must exist (exact! no regexp) and nodeValueType and nodeValueValue must match the respective regex.
  5. if no nodeValueKey and a nodeValueValue is set -> 5a. Any key of the node must match nodeValueType and nodeValueValue the respective regex. 6a. if nodeValueLastModified is set and a nodeValue (key or value) is looked for -> the lastUpdated of the respective nodeValue has to be bigger or equal. 6b. if nodeValueLastModified is set and no nodeValue is looked for -> the lastUpdated of the respective node has to be bigger or equal.

@throws StorageException if the storage backend encounters a problem

Implementation

Future<bool> evaluate(Node node) async {
  // check for equal path start (must be a node or sub-node of path
  if (!(node.path).startsWith(path)) {
    return false;
  }

  // check owner
  if ((values[Field.owner] != null) &&
      (!_regexEvalString(values[Field.owner] ?? '', node.owner))) {
    return false;
  }

  //check visibility
  String? visibility = values[Field.visibility];
  if ((visibility != null) &&
      (!_regexEvalString(visibility, (node.visibility).toString()))) {
    return false;
  }

  // check if any of the node values matches
  Map<String, NodeValue> nodeValues = await node.getValues();
  if ((values[Field.key] == null) &&
      ((values[Field.value] != null) || (values[Field.type] != null))) {
    bool chk = false;
    for (MapEntry<String, NodeValue> e in nodeValues.entries) {
      bool r3 = nodeValueType == null ||
          !_regexEvalString(nodeValueType!, e.value.type ?? 'NoValidType');
      String? value = values[Field.value];
      bool r2 = value == null || !_regexEvalString(value, e.value.value);
      chk |= r2 && r3;
    }
    if (!chk) {
      return false;
    }
  } else {
    if (values[Field.key] != null) {
      NodeValue? nv = nodeValues[get(Field.key)];
      if (nv == null) {
        return false;
      }
      if (values[Field.type] != null &&
          !_regexEvalString(values[Field.type]!, nv.type ?? 'NoValidType')) {
        return false;
      }
      if (values[Field.value] != null &&
          !_regexEvalString(values[Field.value]!, nv.value)) {
        return false;
      }
    }
  }

  if (nodeValueLastModified != null) {
    // strip node name and convert to int
    int timestamp = int.parse(nodeValueLastModified!);

    // check sequence
    if (nodeValueKey != null) {
      // only in respective node Value
      NodeValue? nv = nodeValues[nodeValueKey];
      if (nv == null ||
          nv.lastModified < timestamp ||
          (nodeValueType != null && nv.type != nodeValueType)) {
        return false;
      }
    } else {
      // loop thru all NodeValues and see if one is at least higher or the node itself
      bool vlm = node.lastModified >= timestamp;
      for (NodeValue nv in nodeValues.values) {
        vlm |= nv.lastModified >= timestamp;
      }
      if (!vlm) {
        return false;
      }
    }
  }

  // loop thru all values
  bool vk = nodeValueKey == null;
  bool vv = nodeValueValue == null;
  bool vt = nodeValueType == null;
  for (NodeValue nv in nodeValues.values) {
    vk |= nv.key == nodeValueKey;
    vv |= nv.value == nodeValueValue;
    vt |= nv.type == nodeValueType;
  }
  return vk && vv && vt;
}