001package org.hl7.fhir.r5.comparison;
002
003import java.util.ArrayList;
004import java.util.List;
005
006import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
007import org.hl7.fhir.utilities.validation.ValidationMessage;
008import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
009
010public class StructuralMatch<T> {
011
012  private String name; // this is used in some contexts to carry name when T is a pretty abstract type
013  private T left;
014  private T right;
015  private List<ValidationMessage> messages = new ArrayList<>();
016  private List<StructuralMatch<T>> children = new ArrayList<>();
017 
018  public StructuralMatch() {
019    // root, just a place holder...
020  }
021 
022  public StructuralMatch(T left, T right) {
023    super();
024    this.left = left;
025    this.right = right;
026  }
027 
028  public StructuralMatch(T left, T right, ValidationMessage msg) {
029    super();
030    this.left = left;
031    this.right = right;
032    if (msg != null) {
033      this.messages.add(msg);
034    }
035  }
036 
037  public StructuralMatch(ValidationMessage msg, T right) {
038    super();
039    this.messages.add(msg);
040    this.right = right;
041  }
042
043  public StructuralMatch(T left, ValidationMessage msg) {
044    super();
045    this.left = left;
046    this.messages.add(msg);
047  }
048   
049  public T getLeft() {
050    return left;
051  }
052  public T getRight() {
053    return right;
054  }
055
056  public List<StructuralMatch<T>> getChildren() {
057    return children;
058  }
059
060  /**
061   * return left if it exists, or return right (which might be null)
062   *
063   * This is used when accessing whatever makes the items common
064   *
065   * @return
066   */
067  public T either() {
068    return left != null ? left : right;
069  }
070
071  public boolean hasLeft() {
072    return left != null;
073  }
074 
075  public boolean hasRight() {
076    return right != null;
077  }
078
079  public List<ValidationMessage> getMessages() {
080    return messages;
081  }
082
083  public boolean hasErrors() {
084    for (ValidationMessage vm : messages) {
085      if (vm.getLevel() == IssueSeverity.ERROR) {
086        return true;
087      }
088    }
089    return false;
090  }
091
092  public void countMessages(MessageCounts cnts) {
093    for (ValidationMessage vm : getMessages()) {
094      if (vm.getLevel() == IssueSeverity.ERROR) {
095        cnts.error();
096      } else if (vm.getLevel() == IssueSeverity.WARNING) {
097        cnts.warning();
098      } else if (vm.getLevel() == IssueSeverity.INFORMATION) {
099        cnts.hint();
100      } 
101    }
102    for (StructuralMatch<T> c : children) {
103      c.countMessages(cnts);
104    }
105  }
106
107  public String getName() {
108    return name;
109  }
110
111  public StructuralMatch<T> setName(String name) {
112    this.name = name;
113    return this;
114  }
115
116  public boolean isDifferent() {
117    return (left == null) != (right == null) || !messages.isEmpty();
118  }
119  
120}