1 /*
2 * This file is part of dependency-check-core.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
17 */
18 package org.owasp.dependencycheck.dependency;
19
20 import org.apache.commons.lang3.ObjectUtils;
21 import org.apache.commons.lang3.StringUtils;
22 import org.apache.commons.lang3.builder.HashCodeBuilder;
23
24 import java.io.Serializable;
25
26 /**
27 * Evidence is a piece of information about a Dependency.
28 *
29 * @author Jeremy Long
30 */
31 public class Evidence implements Serializable, Comparable<Evidence> {
32
33 /**
34 * The serial version UID for serialization.
35 */
36 private static final long serialVersionUID = 1L;
37 /**
38 * Used as starting point for generating the value in {@link #hashCode()}.
39 */
40 private static final int MAGIC_HASH_INIT_VALUE = 3;
41
42 /**
43 * Used as a multiplier for generating the value in {@link #hashCode()}.
44 */
45 private static final int MAGIC_HASH_MULTIPLIER = 67;
46
47 /**
48 * Creates a new Evidence object.
49 */
50 public Evidence() {
51 }
52
53 /**
54 * Creates a new Evidence objects.
55 *
56 * @param source the source of the evidence.
57 * @param name the name of the evidence.
58 * @param value the value of the evidence.
59 * @param confidence the confidence of the evidence.
60 */
61 public Evidence(String source, String name, String value, Confidence confidence) {
62 this.source = source;
63 this.name = name;
64 this.value = value;
65 this.confidence = confidence;
66 }
67
68 /**
69 * The name of the evidence.
70 */
71 private String name;
72
73 /**
74 * Get the value of name.
75 *
76 * @return the value of name
77 */
78 public String getName() {
79 return name;
80 }
81
82 /**
83 * Set the value of name.
84 *
85 * @param name new value of name
86 */
87 public void setName(String name) {
88 this.name = name;
89 }
90
91 /**
92 * The source of the evidence.
93 */
94 private String source;
95
96 /**
97 * Get the value of source.
98 *
99 * @return the value of source
100 */
101 public String getSource() {
102 return source;
103 }
104
105 /**
106 * Set the value of source.
107 *
108 * @param source new value of source
109 */
110 public void setSource(String source) {
111 this.source = source;
112 }
113
114 /**
115 * The value of the evidence.
116 */
117 private String value;
118
119 /**
120 * Get the value of value.
121 *
122 * @return the value of value
123 */
124 public String getValue() {
125 used = true;
126 return value;
127 }
128
129 /**
130 * Get the value of value. If setUsed is set to false this call to get will
131 * not mark the evidence as used.
132 *
133 * @param setUsed whether or not this call to getValue should cause the used
134 * flag to be updated
135 * @return the value of value
136 */
137 public String getValue(Boolean setUsed) {
138 used = used || setUsed;
139 return value;
140 }
141
142 /**
143 * Set the value of value.
144 *
145 * @param value new value of value
146 */
147 public void setValue(String value) {
148 this.value = value;
149 }
150
151 /**
152 * A value indicating if the Evidence has been "used" (aka read).
153 */
154 private boolean used;
155
156 /**
157 * Get the value of used.
158 *
159 * @return the value of used
160 */
161 public boolean isUsed() {
162 return used;
163 }
164
165 /**
166 * Set the value of used.
167 *
168 * @param used new value of used
169 */
170 public void setUsed(boolean used) {
171 this.used = used;
172 }
173
174 /**
175 * The confidence level for the evidence.
176 */
177 private Confidence confidence;
178
179 /**
180 * Get the value of confidence.
181 *
182 * @return the value of confidence
183 */
184 public Confidence getConfidence() {
185 return confidence;
186 }
187
188 /**
189 * Set the value of confidence.
190 *
191 * @param confidence new value of confidence
192 */
193 public void setConfidence(Confidence confidence) {
194 this.confidence = confidence;
195 }
196
197 /**
198 * Implements the hashCode for Evidence.
199 *
200 * @return hash code.
201 */
202 @Override
203 public int hashCode() {
204 return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER)
205 .append(StringUtils.lowerCase(name))
206 .append(StringUtils.lowerCase(source))
207 .append(StringUtils.lowerCase(value))
208 .append(confidence)
209 .toHashCode();
210 }
211
212 /**
213 * Implements equals for Evidence.
214 *
215 * @param that an object to check the equality of.
216 * @return whether the two objects are equal.
217 */
218 @SuppressWarnings("deprecation")
219 @Override
220 public boolean equals(Object that) {
221 if (this == that) {
222 return true;
223 }
224 if (!(that instanceof Evidence)) {
225 return false;
226 }
227 final Evidence e = (Evidence) that;
228
229 //TODO the call to ObjectUtils.equals needs to be replaced when we
230 //stop supporting Jenkins 1.6 requirement.
231 return StringUtils.equalsIgnoreCase(name, e.name)
232 && StringUtils.equalsIgnoreCase(source, e.source)
233 && StringUtils.equalsIgnoreCase(value, e.value)
234 && ObjectUtils.equals(confidence, e.confidence);
235 }
236
237 /**
238 * Implementation of the comparable interface.
239 *
240 * @param o the evidence being compared
241 * @return an integer indicating the ordering of the two objects
242 */
243 @SuppressWarnings("deprecation")
244 @Override
245 public int compareTo(Evidence o) {
246 if (o == null) {
247 return 1;
248 }
249 if (StringUtils.equalsIgnoreCase(source, o.source)) {
250 if (StringUtils.equalsIgnoreCase(name, o.name)) {
251 if (StringUtils.equalsIgnoreCase(value, o.value)) {
252 //TODO the call to ObjectUtils.equals needs to be replaced when we
253 //stop supporting Jenkins 1.6 requirement.
254 if (ObjectUtils.equals(confidence, o.confidence)) {
255 return 0; //they are equal
256 } else {
257 return ObjectUtils.compare(confidence, o.confidence);
258 }
259 } else {
260 return compareToIgnoreCaseWithNullCheck(value, o.value);
261 }
262 } else {
263 return compareToIgnoreCaseWithNullCheck(name, o.name);
264 }
265 } else {
266 return compareToIgnoreCaseWithNullCheck(source, o.source);
267 }
268 }
269
270 /**
271 * Wrapper around
272 * {@link java.lang.String#compareToIgnoreCase(java.lang.String) String.compareToIgnoreCase}
273 * with an exhaustive, possibly duplicative, check against nulls.
274 *
275 * @param me the value to be compared
276 * @param other the other value to be compared
277 * @return true if the values are equal; otherwise false
278 */
279 private int compareToIgnoreCaseWithNullCheck(String me, String other) {
280 if (me == null && other == null) {
281 return 0;
282 } else if (me == null) {
283 return -1; //the other string is greater then me
284 } else if (other == null) {
285 return 1; //me is greater then the other string
286 }
287 return me.compareToIgnoreCase(other);
288 }
289
290 /**
291 * Standard toString() implementation.
292 *
293 * @return the string representation of the object
294 */
295 @Override
296 public String toString() {
297 return "Evidence{" + "name=" + name + ", source=" + source + ", value=" + value + ", confidence=" + confidence + '}';
298 }
299 }