1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2011-2026 Yegor Bugayenko
3 * SPDX-License-Identifier: MIT
4 */
5 package com.qulice.spi;
6
7 import java.util.Comparator;
8 import lombok.EqualsAndHashCode;
9 import lombok.ToString;
10
11 /**
12 * Validation result.
13 * @since 0.17
14 */
15 public interface Violation extends Comparable<Violation> {
16
17 /**
18 * Name of the validator that generated this violation information.
19 * @return Name of the validator
20 */
21 String validator();
22
23 /**
24 * Name of the failed check.
25 * @return Name of the failed check
26 */
27 String name();
28
29 /**
30 * Validated file.
31 * @return Validated file
32 */
33 String file();
34
35 /**
36 * Lines with the problem.
37 * @return Lines with the problem
38 */
39 String lines();
40
41 /**
42 * Validation message.
43 * @return Validation message
44 */
45 String message();
46
47 /**
48 * Default validation result.
49 * @since 0.1
50 */
51 @EqualsAndHashCode
52 @ToString
53 final class Default implements Violation {
54
55 /**
56 * Total ordering across all observable fields, so that two
57 * violations only tie when they are fully equal.
58 */
59 private static final Comparator<Violation> ORDER =
60 Comparator.comparing(Violation::validator, String.CASE_INSENSITIVE_ORDER)
61 .thenComparing(Violation::file, String.CASE_INSENSITIVE_ORDER)
62 .thenComparing(Default::lineNumber)
63 .thenComparing(Violation::lines)
64 .thenComparing(Violation::name)
65 .thenComparing(Violation::message);
66
67 /**
68 * Name of the validator that generated this violation information.
69 */
70 private final String vldtr;
71
72 /**
73 * Name of the failed check.
74 */
75 private final String chk;
76
77 /**
78 * Lines with the problem.
79 */
80 private final String lns;
81
82 /**
83 * Validated file.
84 */
85 private final String path;
86
87 /**
88 * Validation message.
89 */
90 private final String msg;
91
92 /**
93 * Constructor.
94 * @param vldtr Name of the validator
95 * @param name Name of the failed check
96 * @param file Validated file
97 * @param lns Lines with the problem
98 * @param msg Validation message
99 */
100 public Default(final String vldtr, final String name,
101 final String file, final String lns, final String msg) {
102 this.vldtr = vldtr;
103 this.chk = name;
104 this.path = file;
105 this.lns = lns;
106 this.msg = msg;
107 }
108
109 @Override
110 public String validator() {
111 return this.vldtr;
112 }
113
114 @Override
115 public String name() {
116 return this.chk;
117 }
118
119 @Override
120 public String file() {
121 return this.path;
122 }
123
124 @Override
125 public String lines() {
126 return this.lns;
127 }
128
129 @Override
130 public String message() {
131 return this.msg;
132 }
133
134 @Override
135 public int compareTo(final Violation other) {
136 return Default.ORDER.compare(this, other);
137 }
138
139 /**
140 * Numeric line number, or {@link Integer#MAX_VALUE} when the
141 * field cannot be parsed as a single integer (e.g. a range like
142 * {@code "10-12"}). Numeric ordering keeps line 9 before line 42.
143 * @param violation The violation to inspect
144 * @return Parsed line number, or {@code MAX_VALUE} as a fallback
145 */
146 private static int lineNumber(final Violation violation) {
147 int parsed;
148 try {
149 parsed = Integer.parseInt(violation.lines());
150 } catch (final NumberFormatException ignored) {
151 parsed = Integer.MAX_VALUE;
152 }
153 return parsed;
154 }
155 }
156 }