001package org.gbif.api.model.crawler;
002
003import java.util.List;
004
005import com.google.common.base.Objects;
006import com.google.common.base.Preconditions;
007import org.codehaus.jackson.annotate.JsonCreator;
008import org.codehaus.jackson.annotate.JsonProperty;
009
010/**
011 * A container class used to capture the information necessary for a generic validation report.
012 * <p/>
013 * This is written with the intention to capture the information about e.g. the sample core or the taxon core of a
014 * DwC-A.
015 * <p/>
016 * Generic validation includes information about the number of records checked, whether all records where checked
017 * (implementations often cannot check everything) and information about the validity of primary keys.
018 */
019public class GenericValidationReport {
020  // the number of records checked in the validation
021  private final int checkedRecords;
022
023  // false if we had to stop at an implementation imposed limit (e.g. due to memory restrictions)
024  private final boolean allRecordsChecked;
025
026  // a sample of duplicate ids which are expected to be unique (i.e. primary keys)
027  private final List<String> duplicateIds;
028
029  // a sample of data file line numbers with records missing a core identifier
030  private final List<Integer> rowNumbersMissingId;
031
032  // if the archive is not valid this will hold a readable reason
033  private String invalidationReason;
034
035  // is this archive valid
036  private final boolean valid;
037
038  @JsonCreator
039  public GenericValidationReport(
040    @JsonProperty("checkedRecords") int checkedRecords,
041    @JsonProperty("allRecordsChecked") boolean allRecordsChecked,
042    @JsonProperty("duplicateIds") List<String> duplicateIds,
043    @JsonProperty("rowNumbersMissingId") List<Integer> rowNumbersMissingId
044  ) {
045    this.checkedRecords = checkedRecords;
046    this.allRecordsChecked = allRecordsChecked;
047    this.duplicateIds = Preconditions.checkNotNull(duplicateIds, "duplicateIds cannot be null");
048    this.rowNumbersMissingId = Preconditions.checkNotNull(rowNumbersMissingId, "rowNumbersMissingId cannot be null");
049    this.valid = validate();
050  }
051
052  private boolean validate() {
053    if (!duplicateIds.isEmpty()) {
054      invalidationReason = "Non unique core ids";
055      return false;
056    }
057    if (!rowNumbersMissingId.isEmpty()) {
058      invalidationReason = "Missing core ids";
059      return false;
060    }
061    return true;
062  }
063
064  public int getCheckedRecords() {
065    return checkedRecords;
066  }
067
068  public boolean isAllRecordsChecked() {
069    return allRecordsChecked;
070  }
071
072  public List<String> getDuplicateIds() {
073    return duplicateIds;
074  }
075
076  public List<Integer> getRowNumbersMissingId() {
077    return rowNumbersMissingId;
078  }
079
080  public String getInvalidationReason() {
081    return invalidationReason;
082  }
083
084  public boolean isValid() {
085    return valid;
086  }
087
088  @Override
089  public int hashCode() {
090    return Objects.hashCode(checkedRecords, allRecordsChecked, duplicateIds,
091                            rowNumbersMissingId, invalidationReason,valid);
092  }
093
094  @Override
095  public boolean equals(Object obj) {
096    if (this == obj) {
097      return true;
098    }
099    if (obj == null || getClass() != obj.getClass()) {
100      return false;
101    }
102    final GenericValidationReport other = (GenericValidationReport) obj;
103    return Objects.equal(this.checkedRecords, other.checkedRecords)
104           && Objects.equal(this.allRecordsChecked, other.allRecordsChecked)
105           && Objects.equal(this.duplicateIds, other.duplicateIds)
106           && Objects.equal(this.rowNumbersMissingId, other.rowNumbersMissingId)
107           && Objects.equal(this.invalidationReason, other.invalidationReason)
108           && Objects.equal(this.valid, other.valid);
109  }
110
111  @Override
112  public String toString() {
113    return Objects.toStringHelper(this)
114      .add("checkedRecords", checkedRecords)
115      .add("duplicateIds", duplicateIds)
116      .add("rowNumbersMissingId", rowNumbersMissingId)
117      .add("allRecordsChecked", allRecordsChecked)
118      .add("invalidationReason", invalidationReason)
119      .add("valid", valid)
120      .toString();
121  }
122}