Version.java

1
package org.europa.together.domain;
2
3
import java.util.Objects;
4
import org.europa.together.application.LogbackLogger;
5
import org.europa.together.business.Logger;
6
import org.europa.together.exceptions.MisconfigurationException;
7
import org.europa.together.utils.StringUtils;
8
import org.europa.together.utils.Validator;
9
10
/**
11
 * Data class for program version numbers, based on semantic versioning. This
12
 * implementation allwos to compare and sort version numbers.<br>
13
 * Pattern: Major.Minor.Patch-Label (Patch and Label are optional)<br>
14
 * <code>
15
 *  true:  equals(1.2.3-SNAPSHOT : 1.2.3-SNAPSHOT);
16
 *  true:  equals(1.2.3-LABLE : 1.2.3-SNAPSHOT);
17
 *  true:  equals(1.0 : 1.0.0);
18
 *  false: equals(1.0 : 1.0.1);
19
 *  false: equals(1.0-LABEL : 1.0);
20
 *  A greater B: compareTo(2.0 : 1.0);
21
 *  A greater B: compareTo(1.1 : 1.0);
22
 *  A greater B: compareTo(1.0.1 : 1.0.0);
23
 *  A greater B: compareTo(2.1 : 1.1);
24
 *  A equal B:   compareTo(2.1.1 : 2.1.1-SNAPSHOT);
25
 * </code> The only recomennded label is SNAPSHOT, because labels are not part
26
 * of comparing.
27
 *
28
 * <b>Definition:</b><br>
29
 * A version of a software artifact is always uniqe. Artifacts can have
30
 * different versions (1:n relation). That means when an artifact a exist two
31
 * times and both are not identical, the first artifact has a different version
32
 * than the second artifact. Both artifacts can not have the same version. If
33
 * both artifacts with the same name have the same version it is impossible to
34
 * distinguish them.
35
 */
36
public final class Version implements Comparable<Version> {
37
38
    private static final Logger LOGGER = new LogbackLogger(Version.class);
39
40
    private int major = -1;
41
    private int minor = -1;
42
    private int patch = -1;
43
    private String label = "";
44
45
    /**
46
     * Constructor.
47
     *
48
     * @param version as String
49
     * @throws org.europa.together.exceptions.MisconfigurationException
50
     */
51
    public Version(final String version)
52
            throws MisconfigurationException {
53
54 1 1. <init> : negated conditional → KILLED
        if (!Validator.validate(version, Validator.SEMANTIC_VERSION_NUMBER)) {
55
            String msg = "The version number " + version
56
                    + " do not match the Pattern: [1].[2].[3]-[LABEL].";
57
            throw new MisconfigurationException(msg);
58
        } else {
59
            String[] fragments = version.split("\\.");
60
            LOGGER.log("Fragments: " + fragments.length, LogLevel.DEBUG);
61
62
            major = Integer.parseInt(fragments[0]);
63 2 1. <init> : changed conditional boundary → KILLED
2. <init> : negated conditional → KILLED
            if (fragments.length > 1) {
64 1 1. <init> : negated conditional → KILLED
                if (!fragments[1].contains("-")) {
65
                    minor = Integer.parseInt(fragments[1]);
66
                } else {
67
                    LOGGER.log("Lable after minor.", LogLevel.DEBUG);
68
                    String[] optional = fragments[1].split("-");
69
                    minor = Integer.parseInt(optional[0]);
70
                    label = optional[1];
71
                }
72
            }
73 2 1. <init> : changed conditional boundary → KILLED
2. <init> : negated conditional → KILLED
            if (fragments.length > 2) {
74
                String[] optional = fragments[2].split("-");
75
76
                patch = Integer.parseInt(optional[0]);
77 1 1. <init> : negated conditional → KILLED
                if (optional.length == 2) { //prevent index out of bound exception
78
                    label = optional[1];
79
                }
80
            }
81
            LOGGER.log("Version: " + toString(), LogLevel.DEBUG);
82
        }
83
    }
84
85
    //<editor-fold defaultstate="collapsed" desc="Getter / Setter">
86
    /**
87
     * Return the Major section of a version number as int. MANDANTORY.
88
     *
89
     * @return Major as int
90
     */
91
    public int getMajor() {
92 1 1. getMajor : replaced int return with 0 for org/europa/together/domain/Version::getMajor → KILLED
        return major;
93
    }
94
95
    /**
96
     * Return the Minor section of a version number as int. MANDANTORY.
97
     *
98
     * @return Minor as int
99
     */
100
    public int getMinor() {
101 1 1. getMinor : replaced int return with 0 for org/europa/together/domain/Version::getMinor → KILLED
        return minor;
102
    }
103
104
    /**
105
     * Return the Patch level section of a version number as int. OPTIONAL. If
106
     * the patch level not exist the method return -1.
107
     *
108
     * @return Patch as int
109
     */
110
    public int getPatch() {
111 1 1. getPatch : replaced int return with 0 for org/europa/together/domain/Version::getPatch → KILLED
        return patch;
112
    }
113
114
    /**
115
     * Return the Label section of a version number as String. OPTIONAL. If the
116
     * label not exist the method return an empty String.
117
     *
118
     * @return Label as String
119
     */
120
    public String getLabel() {
121 1 1. getLabel : replaced return value with "" for org/europa/together/domain/Version::getLabel → KILLED
        return label;
122
    }
123
124
    /**
125
     * Return the whole version number as String.
126
     *
127
     * @return version as String
128
     */
129
    public String getVersion() {
130
        String version = Integer.toString(major);
131 1 1. getVersion : negated conditional → KILLED
        if (minor != -1) {
132
            version = version + "." + minor;
133
        }
134 1 1. getVersion : negated conditional → KILLED
        if (patch != -1) {
135
            version = version + "." + patch;
136
        }
137 1 1. getVersion : negated conditional → KILLED
        if (!StringUtils.isEmpty(label)) {
138
            version = version + "-" + label;
139
        }
140 1 1. getVersion : replaced return value with "" for org/europa/together/domain/Version::getVersion → KILLED
        return version;
141
    }
142
    //</editor-fold>
143
144
    @Override
145
    public int compareTo(final Version o) {
146
        // -1:smaller | 0:equal | 1:greater
147
        int compare;
148 2 1. compareTo : negated conditional → KILLED
2. compareTo : changed conditional boundary → KILLED
        if (this.major > o.major) {
149
            compare = 1;
150 2 1. compareTo : negated conditional → KILLED
2. compareTo : changed conditional boundary → KILLED
        } else if (this.major < o.major) {
151
            compare = -1;
152
        } else {
153 2 1. compareTo : changed conditional boundary → KILLED
2. compareTo : negated conditional → KILLED
            if (this.minor > o.minor) {
154
                compare = 1;
155 2 1. compareTo : changed conditional boundary → KILLED
2. compareTo : negated conditional → KILLED
            } else if (this.minor < o.minor) {
156
                compare = -1;
157
            } else {
158
159 2 1. compareTo : negated conditional → KILLED
2. compareTo : changed conditional boundary → KILLED
                if (this.patch > o.patch) {
160
                    compare = 1;
161 2 1. compareTo : changed conditional boundary → KILLED
2. compareTo : negated conditional → KILLED
                } else if (this.patch < o.patch) {
162
                    compare = -1;
163
                } else {
164
                    compare = 0;
165
                }
166
            }
167
        }
168 1 1. compareTo : replaced int return with 0 for org/europa/together/domain/Version::compareTo → KILLED
        return compare;
169
    }
170
171
    @Override
172
    public boolean equals(final Object object) {
173
        boolean success = false;
174 2 1. equals : negated conditional → KILLED
2. equals : negated conditional → KILLED
        if (object != null && object instanceof Version) {
175 1 1. equals : negated conditional → KILLED
            if (this == object) {
176
                success = true;
177
            } else {
178
                final Version other = (Version) object;
179 1 1. equals : negated conditional → KILLED
                if (Objects.equals(this.major, other.major)
180 5 1. equals : negated conditional → KILLED
2. equals : negated conditional → KILLED
3. equals : negated conditional → KILLED
4. equals : negated conditional → KILLED
5. equals : negated conditional → KILLED
                        && Objects.equals(this.minor, other.minor)
181
                        && ((this.patch == -1 || this.patch == 0)
182
                        && (other.patch == -1 || other.patch == 0)
183 1 1. equals : negated conditional → KILLED
                        || Objects.equals(this.patch, other.patch))) {
184
                    success = true;
185
                }
186
            }
187
        }
188 2 1. equals : replaced boolean return with true for org/europa/together/domain/Version::equals → KILLED
2. equals : replaced boolean return with false for org/europa/together/domain/Version::equals → KILLED
        return success;
189
    }
190
191
    @Override
192
    public int hashCode() {
193
        int hash = Objects.hashCode(this.major);
194 1 1. hashCode : Replaced integer addition with subtraction → KILLED
        hash += Objects.hashCode(this.minor);
195 1 1. hashCode : Replaced integer addition with subtraction → KILLED
        hash += Objects.hashCode(this.patch);
196 1 1. hashCode : replaced int return with 0 for org/europa/together/domain/Version::hashCode → KILLED
        return hash;
197
    }
198
199
    @Override
200
    public String toString() {
201 1 1. toString : replaced return value with "" for org/europa/together/domain/Version::toString → KILLED
        return "Version{" + getVersion() + "}";
202
    }
203
}

Mutations

54

1.1
Location : <init>
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:failGetVersion_Majorl()]
negated conditional → KILLED

63

1.1
Location : <init>
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:getVersion_Major()]
changed conditional boundary → KILLED

2.2
Location : <init>
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:getVersion_Major()]
negated conditional → KILLED

64

1.1
Location : <init>
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isEqualByMinor()]
negated conditional → KILLED

73

1.1
Location : <init>
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isEqualByMinor()]
changed conditional boundary → KILLED

2.2
Location : <init>
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:getVersion_Major()]
negated conditional → KILLED

77

1.1
Location : <init>
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isNotEqualByMajor()]
negated conditional → KILLED

92

1.1
Location : getMajor
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:getVersion_Major()]
replaced int return with 0 for org/europa/together/domain/Version::getMajor → KILLED

101

1.1
Location : getMinor
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:getVersion_Major()]
replaced int return with 0 for org/europa/together/domain/Version::getMinor → KILLED

111

1.1
Location : getPatch
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:getVersion_Major()]
replaced int return with 0 for org/europa/together/domain/Version::getPatch → KILLED

121

1.1
Location : getLabel
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:getVersion_MinorWithLabel()]
replaced return value with "" for org/europa/together/domain/Version::getLabel → KILLED

131

1.1
Location : getVersion
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:getVersion_Major()]
negated conditional → KILLED

134

1.1
Location : getVersion
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:getVersion_Major()]
negated conditional → KILLED

137

1.1
Location : getVersion
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:getVersion_Major()]
negated conditional → KILLED

140

1.1
Location : getVersion
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:getVersion_Major()]
replaced return value with "" for org/europa/together/domain/Version::getVersion → KILLED

148

1.1
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:sort()]
negated conditional → KILLED

2.2
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:sort()]
changed conditional boundary → KILLED

150

1.1
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:sort()]
negated conditional → KILLED

2.2
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:sort()]
changed conditional boundary → KILLED

153

1.1
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:compare()]
changed conditional boundary → KILLED

2.2
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:sort()]
negated conditional → KILLED

155

1.1
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:sort()]
changed conditional boundary → KILLED

2.2
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:sort()]
negated conditional → KILLED

159

1.1
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:compare()]
negated conditional → KILLED

2.2
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:compare()]
changed conditional boundary → KILLED

161

1.1
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:compare()]
changed conditional boundary → KILLED

2.2
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:compare()]
negated conditional → KILLED

168

1.1
Location : compareTo
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:sort()]
replaced int return with 0 for org/europa/together/domain/Version::compareTo → KILLED

174

1.1
Location : equals
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isEqualByMinor()]
negated conditional → KILLED

2.2
Location : equals
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isEqualByMinor()]
negated conditional → KILLED

175

1.1
Location : equals
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isNotEqualByMajor()]
negated conditional → KILLED

179

1.1
Location : equals
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isEqualByMinor()]
negated conditional → KILLED

180

1.1
Location : equals
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isEqualByMajor()]
negated conditional → KILLED

2.2
Location : equals
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isEqualByMinor()]
negated conditional → KILLED

3.3
Location : equals
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isEqualByMajor()]
negated conditional → KILLED

4.4
Location : equals
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isEqualByMajor()]
negated conditional → KILLED

5.5
Location : equals
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isEqualByMajor()]
negated conditional → KILLED

183

1.1
Location : equals
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isEqualByPatch()]
negated conditional → KILLED

188

1.1
Location : equals
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isNotEqualByMajor()]
replaced boolean return with true for org/europa/together/domain/Version::equals → KILLED

2.2
Location : equals
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:isEqualByMinor()]
replaced boolean return with false for org/europa/together/domain/Version::equals → KILLED

194

1.1
Location : hashCode
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:processHashCode()]
Replaced integer addition with subtraction → KILLED

195

1.1
Location : hashCode
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:processHashCode()]
Replaced integer addition with subtraction → KILLED

196

1.1
Location : hashCode
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:processHashCode()]
replaced int return with 0 for org/europa/together/domain/Version::hashCode → KILLED

201

1.1
Location : toString
Killed by : org.europa.together.domain.VersionTest.[engine:junit-jupiter]/[class:org.europa.together.domain.VersionTest]/[method:sort()]
replaced return value with "" for org/europa/together/domain/Version::toString → KILLED

Active mutators

Tests examined


Report generated by PIT 1.22.0