org.conqat.engine.index.shared.IndexFinding Maven / Gradle / Ivy
Show all versions of teamscale-commons Show documentation
/*
* Copyright (c) CQSE GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.conqat.engine.index.shared;
import java.util.Comparator;
import org.conqat.engine.commons.findings.DetachedFinding;
import org.conqat.engine.commons.findings.location.ElementLocation;
import org.conqat.lib.commons.test.IndexValueClass;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* A {@link DetachedFinding} with additional attributes required for index-based analysis.
*
* This class is used as DTO during communication with IDE clients via
* {@link com.teamscale.ide.commons.client.IIdeServiceClient}, special care has to be taken when
* changing its signature!
*/
@IndexValueClass(containedInBackup = true)
public class IndexFinding extends DetachedFinding {
/** Version for serialization. */
private static final long serialVersionUID = 1;
/** A comparator for stable sorting of {@link IndexFinding}s. */
public static final Comparator STABLE_INDEX_FINDING_COMPARATOR = Comparator
.comparing(IndexFinding::getLocationString).thenComparing(IndexFinding::getTypeId)
.thenComparing(IndexFinding::getMessage);
/**
* Value for {@link #analysisTimestamp} that indicates that there is no timestamp available (i.e.,
* the finding is created by a Teamscale-internal analysis).
*/
public static final long NO_TIMESTAMP = -1;
/** The separator for components of a finding type ID. */
public static final String TYPE_ID_SEPARATOR = "/";
/**
* The timestamp of the analysis creating this finding. This is {@link #NO_TIMESTAMP} if the finding
* is updated in real-time (i.e., is created by a Teamscale-internal analysis).
*
* A better field name would be "externalAnalysisTimestamp" since it is always {@link #NO_TIMESTAMP}
* for internal-analysis findings, but that rename would require a migration.
*/
@JsonProperty("analysisTimestamp")
private long analysisTimestamp = NO_TIMESTAMP;
/** A unique ID for the type of finding. */
@JsonProperty("typeId")
private final String typeId;
/** Constructor. */
public IndexFinding(DetachedFinding finding, long analysisTimestamp) {
super(finding);
this.analysisTimestamp = analysisTimestamp;
this.typeId = determineTypeId();
}
public IndexFinding(DetachedFinding finding, long analysisTimestamp, String typeId) {
super(finding);
this.analysisTimestamp = analysisTimestamp;
this.typeId = typeId;
}
/**
* Creates a {@link IndexFinding} from a {@link DetachedFinding}.
*/
public static IndexFinding asRealtimeFinding(DetachedFinding finding) {
return new IndexFinding(finding, NO_TIMESTAMP);
}
@JsonCreator
public IndexFinding(@JsonProperty(GROUP_NAME_PROPERTY) String groupName,
@JsonProperty(CATEGORY_NAME_PROPERTY) String categoryName, @JsonProperty(MESSAGE_PROPERTY) String message,
@JsonProperty(LOCATION_PROPERTY) ElementLocation location) {
super(groupName, categoryName, message, location);
this.typeId = determineTypeId();
}
/** Returns the type ID to be used during construction. */
private String determineTypeId() {
return makeFindingTypeId(getCategoryName(), getGroupName());
}
/** Creates a finding type ID for given category and group. */
public static String makeFindingTypeId(String category, String group) {
return category + TYPE_ID_SEPARATOR + group;
}
/** Copy constructor. */
public IndexFinding(IndexFinding other) {
super(other);
this.analysisTimestamp = other.analysisTimestamp;
this.typeId = other.typeId;
}
/**
* Returns the analysis timestamp. This may be {@link #NO_TIMESTAMP} to indicate that no analysis
* timestamp is available.
*/
public long getAnalysisTimestamp() {
return analysisTimestamp;
}
/** Sets the analysis timestamp. */
public void setAnalysisTimestamp(long timestamp) {
this.analysisTimestamp = timestamp;
}
/** Returns the type id of this finding. */
public String getTypeId() {
return typeId;
}
/**
* Checks whether the finding is updated in real-time (whether this is an external-upload finding).
*
* @return true
if the finding is updated in real-time (created by a Teamscale-internal
* analysis during analysis of a commit), false
if it is created for an
* explicit timestamp from an external finding upload (via one of the finding-report formats
* or {@link com.teamscale.service.external.input.SimpleExternalFindingImportService}).
*/
public boolean isRealTime() {
return analysisTimestamp == NO_TIMESTAMP;
}
}