ConstraintValidationFinding.java

  1. /*
  2.  * Portions of this software was developed by employees of the National Institute
  3.  * of Standards and Technology (NIST), an agency of the Federal Government and is
  4.  * being made available as a public service. Pursuant to title 17 United States
  5.  * Code Section 105, works of NIST employees are not subject to copyright
  6.  * protection in the United States. This software may be subject to foreign
  7.  * copyright. Permission in the United States and in foreign countries, to the
  8.  * extent that NIST may hold copyright, to use, copy, modify, create derivative
  9.  * works, and distribute this software and its documentation without fee is hereby
  10.  * granted on a non-exclusive basis, provided that this notice and disclaimer
  11.  * of warranty appears in all copies.
  12.  *
  13.  * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
  14.  * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
  15.  * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
  16.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
  17.  * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
  18.  * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE.  IN NO EVENT
  19.  * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
  20.  * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
  21.  * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
  22.  * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
  23.  * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
  24.  * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
  25.  */

  26. package gov.nist.secauto.metaschema.core.model.constraint;

  27. import gov.nist.secauto.metaschema.core.metapath.item.node.INodeItem;
  28. import gov.nist.secauto.metaschema.core.model.constraint.IConstraint.Level;
  29. import gov.nist.secauto.metaschema.core.model.validation.IValidationFinding;
  30. import gov.nist.secauto.metaschema.core.util.CollectionUtil;

  31. import java.net.URI;
  32. import java.util.Collections;
  33. import java.util.Comparator;
  34. import java.util.List;

  35. import edu.umd.cs.findbugs.annotations.NonNull;
  36. import edu.umd.cs.findbugs.annotations.Nullable;

  37. /**
  38.  * Represents an individual constraint validation issue.
  39.  */
  40. public class ConstraintValidationFinding implements IValidationFinding { // NOPMD - intentional
  41.   @NonNull
  42.   private final List<? extends IConstraint> constraints;
  43.   @NonNull
  44.   private final CharSequence message;
  45.   @NonNull
  46.   private final INodeItem node;
  47.   @NonNull
  48.   private final List<? extends INodeItem> targets;
  49.   private final Throwable cause;
  50.   private final Level severity;

  51.   private ConstraintValidationFinding(
  52.       @NonNull List<? extends IConstraint> constraints,
  53.       @NonNull INodeItem node,
  54.       @NonNull CharSequence message,
  55.       @NonNull List<? extends INodeItem> targets,
  56.       @NonNull Level severity,
  57.       @Nullable Throwable cause) {
  58.     this.constraints = constraints;
  59.     this.node = node;
  60.     this.message = message;
  61.     this.targets = targets;
  62.     this.severity = severity;
  63.     this.cause = cause;
  64.   }

  65.   public List<? extends IConstraint> getConstraints() {
  66.     return constraints;
  67.   }

  68.   @Override
  69.   public CharSequence getMessage() {
  70.     return message;
  71.   }

  72.   public INodeItem getNode() {
  73.     return node;
  74.   }

  75.   public List<? extends INodeItem> getTargets() {
  76.     return targets;
  77.   }

  78.   @Override
  79.   public Throwable getCause() {
  80.     return cause;
  81.   }

  82.   @SuppressWarnings("null")
  83.   @Override
  84.   public Level getSeverity() {
  85.     return severity;
  86.   }

  87.   @SuppressWarnings("null")
  88.   @Override
  89.   public @NonNull URI getDocumentUri() {
  90.     return getNode().getBaseUri();
  91.   }

  92.   @NonNull
  93.   public static Builder builder(@NonNull List<? extends IConstraint> constraints, @NonNull INodeItem node) {
  94.     return new Builder(constraints, node);
  95.   }

  96.   @NonNull
  97.   public static Builder builder(@NonNull IConstraint constraint, @NonNull INodeItem node) {
  98.     return new Builder(CollectionUtil.singletonList(constraint), node);
  99.   }

  100.   public static final class Builder {
  101.     @NonNull
  102.     private final List<? extends IConstraint> constraints;
  103.     @NonNull
  104.     private final INodeItem node;
  105.     private CharSequence message;
  106.     private List<? extends INodeItem> targets;
  107.     private Throwable cause;
  108.     private Level severity;

  109.     private Builder(@NonNull List<? extends IConstraint> constraints, @NonNull INodeItem node) {
  110.       this.constraints = constraints;
  111.       this.node = node;
  112.     }

  113.     @NonNull
  114.     public Builder message(@NonNull CharSequence message) {
  115.       this.message = message;
  116.       return this;
  117.     }

  118.     @NonNull
  119.     public Builder target(@NonNull INodeItem target) {
  120.       this.targets = Collections.singletonList(target);
  121.       return this;
  122.     }

  123.     @NonNull
  124.     public Builder targets(@NonNull List<? extends INodeItem> targets) {
  125.       this.targets = CollectionUtil.unmodifiableList(targets);
  126.       return this;
  127.     }

  128.     @NonNull
  129.     public Builder cause(@NonNull Throwable cause) {
  130.       this.cause = cause;
  131.       return this;
  132.     }

  133.     @NonNull
  134.     public Builder severity(@NonNull Level severity) {
  135.       this.severity = severity;
  136.       return this;
  137.     }

  138.     @NonNull
  139.     public ConstraintValidationFinding build() {
  140.       if (message == null) {
  141.         throw new IllegalStateException("Missing message");
  142.       }

  143.       Level severity = this.severity == null ? constraints.stream()
  144.           .map(IConstraint::getLevel)
  145.           .max(Comparator.comparing(Level::ordinal))
  146.           .get() : this.severity;

  147.       List<? extends INodeItem> targets = this.targets == null ? CollectionUtil.emptyList() : this.targets;

  148.       assert message != null;
  149.       assert targets != null;
  150.       assert severity != null;

  151.       return new ConstraintValidationFinding(
  152.           constraints,
  153.           node,
  154.           message,
  155.           targets,
  156.           severity,
  157.           cause);
  158.     }
  159.   }
  160. }