001package org.hl7.fhir.r5.utils;
002
003import org.hl7.fhir.r5.model.Base;
004import org.hl7.fhir.r5.model.DataType;
005import org.hl7.fhir.r5.model.Property;
006import org.hl7.fhir.r5.model.Resource;
007
008public class DataTypeVisitor {
009
010  public interface IDatatypeVisitor<T extends DataType> {
011    Class<T> classT();
012    boolean visit(String path, T node);
013  }
014
015  private boolean anyFalse;
016  private boolean anyTrue;
017  private int nodeCount;
018  private int selectedCount;
019  
020  public <T extends DataType> void visit(Resource resource, IDatatypeVisitor<T> visitor) {
021    visitNode(resource.fhirType(), resource, visitor);
022  }
023
024  @SuppressWarnings("unchecked")
025  private <T extends DataType> void visitNode(String path, Base node, IDatatypeVisitor<T> visitor) {
026    nodeCount++;
027    if (node instanceof DataType && visitor.classT().isInstance(node)) {
028      selectedCount++;
029      boolean ok = visitor.visit(path, (T) node);
030      if (ok) {
031        anyTrue = true;
032      } else {
033        anyFalse = true;
034      }
035    }
036    for (Property p : node.children()) {
037      if (p.isList()) {
038        int i = 0;
039        for (Base b : p.getValues()) {
040          visitNode(path+"."+p.getName()+"["+i+"]", b, visitor);
041          i++;
042        }
043      } else {
044        for (Base b : p.getValues()) {
045          visitNode(path+"."+p.getName(), b, visitor);
046        }
047      }
048    }
049  }
050
051  public boolean isAnyFalse() {
052    return anyFalse;
053  }
054
055  public boolean isAnyTrue() {
056    return anyTrue;
057  }
058
059  public int getNodeCount() {
060    return nodeCount;
061  }
062
063  public int getSelectedCount() {
064    return selectedCount;
065  }
066  
067  
068}