• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

devonfw / IDEasy / 19803018800

30 Nov 2025 06:23PM UTC coverage: 69.793% (+0.09%) from 69.705%
19803018800

Pull #1623

github

web-flow
Merge ec04329ee into ed1896f7f
Pull Request #1623: #1621: fix build security.json

3811 of 5993 branches covered (63.59%)

Branch coverage included in aggregate %.

9793 of 13499 relevant lines covered (72.55%)

3.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.41
cli/src/main/java/com/devonfw/tools/ide/url/model/file/json/ToolSecurity.java
1
package com.devonfw.tools.ide.url.model.file.json;
2

3
import java.io.BufferedReader;
4
import java.nio.file.Files;
5
import java.nio.file.Path;
6
import java.util.ArrayList;
7
import java.util.Collection;
8
import java.util.Collections;
9
import java.util.List;
10
import java.util.Map;
11
import java.util.TreeMap;
12
import java.util.function.Predicate;
13

14
import com.devonfw.tools.ide.json.JsonMapping;
15
import com.devonfw.tools.ide.log.IdeLogger;
16
import com.devonfw.tools.ide.variable.IdeVariables;
17
import com.devonfw.tools.ide.version.VersionIdentifier;
18
import com.devonfw.tools.ide.version.VersionRange;
19
import com.fasterxml.jackson.databind.ObjectMapper;
20

21
/**
22
 * Container representing data from the "security.json" file with all {@link Cve CVE}s of a specific tool.
23
 *
24
 * @see com.devonfw.tools.ide.url.model.file.UrlSecurityFile
25
 */
26
public class ToolSecurity {
27

28
  static final String PROPERTY_ISSUES = "issues";
29

30
  private static final ObjectMapper MAPPER = JsonMapping.create();
2✔
31

32
  private static final ToolSecurity EMPTY = new ToolSecurity(Map.of());
6✔
33

34
  private final Map<String, Cve> cveMap;
35

36
  private final Collection<Cve> issues;
37

38
  /**
39
   * The constructor.
40
   */
41
  public ToolSecurity() {
42
    this(new TreeMap<>());
5✔
43
  }
1✔
44

45
  private ToolSecurity(Map<String, Cve> cveMap) {
46
    super();
2✔
47
    this.cveMap = cveMap;
3✔
48
    this.issues = Collections.unmodifiableCollection(this.cveMap.values());
6✔
49
  }
1✔
50

51
  /**
52
   * @return the {@link Collection} of {@link Cve}s.
53
   */
54
  public Collection<Cve> getIssues() {
55
    return this.issues;
3✔
56
  }
57

58
  /**
59
   * @param issues the list of CVEs
60
   */
61
  public void setIssues(List<Cve> issues) {
62

63
    this.cveMap.clear();
3✔
64
    for (Cve issue : issues) {
10✔
65
      addIssue(issue);
4✔
66
    }
1✔
67
  }
1✔
68

69
  /**
70
   * @param issue the {@link Cve} to add.
71
   * @return {@code true} if this {@link ToolSecurity} was modified (issue added or merged), {@code false} otherwise ({@link Cve} was already contained).
72
   */
73
  public boolean addIssue(Cve issue) {
74

75
    Cve newIssue = issue;
2✔
76
    String id = issue.id();
3✔
77
    Cve existingIssue = this.cveMap.get(id);
6✔
78
    if (existingIssue != null) {
2!
79
      newIssue = existingIssue.merge(issue);
×
80
      if (newIssue.equals(existingIssue)) {
×
81
        return false;
×
82
      }
83
    }
84
    this.cveMap.put(id, newIssue);
6✔
85
    return true;
2✔
86
  }
87

88
  /**
89
   * Clears all issues.
90
   */
91
  public void clearIssues() {
92
    this.cveMap.clear();
×
93
  }
×
94

95
  /**
96
   * Finds all {@link Cve}s for the given {@link VersionIdentifier} that also match the given {@link Predicate}.
97
   *
98
   * @param version the {@link VersionIdentifier} to check.
99
   * @param logger the {@link IdeLogger}.
100
   * @param predicate the {@link Predicate} deciding which matching {@link Cve}s are {@link Predicate#test(Object) accepted}.
101
   * @return all {@link Cve}s for the given {@link VersionIdentifier}.
102
   */
103
  public Collection<Cve> findCves(VersionIdentifier version, IdeLogger logger, Predicate<Cve> predicate) {
104
    List<Cve> cvesOfVersion = new ArrayList<>();
4✔
105
    for (Cve cve : this.issues) {
11✔
106
      for (VersionRange range : cve.versions()) {
11✔
107
        if (range.contains(version)) {
4✔
108
          if (predicate.test(cve)) {
4!
109
            cvesOfVersion.add(cve);
5✔
110
          } else {
111
            logger.info("Ignoring CVE {} with severity {}", cve.id(), cve.severity());
×
112
          }
113
        }
114
      }
1✔
115
    }
1✔
116
    return cvesOfVersion;
2✔
117
  }
118

119
  /**
120
   * Finds all {@link Cve}s for the given {@link VersionIdentifier} and {@code minSeverity}.
121
   *
122
   * @param version the {@link VersionIdentifier} to check.
123
   * @param logger the {@link IdeLogger}.
124
   * @param minSeverity the {@link IdeVariables#CVE_MIN_SEVERITY minimum severity}.
125
   * @return all {@link Cve}s for the given {@link VersionIdentifier}.
126
   */
127
  public Collection<Cve> findCves(VersionIdentifier version, IdeLogger logger, double minSeverity) {
128
    return findCves(version, logger, cve -> cve.severity() >= minSeverity);
15!
129
  }
130

131
  /**
132
   * @param file the {@link Path} to the JSON file to load.
133
   * @return the loaded {@link ToolSecurity} or the {@link #getEmpty() empty instance} if given {@link Path} does not exist.
134
   */
135
  public static ToolSecurity of(Path file) {
136

137
    if (Files.exists(file)) {
5!
138
      try (BufferedReader reader = Files.newBufferedReader(file)) {
3✔
139
        return MAPPER.readValue(reader, ToolSecurity.class);
8✔
140
      } catch (Exception e) {
×
141
        throw new IllegalStateException("Failed to load " + file, e);
×
142
      }
143
    } else {
144
      return EMPTY;
×
145
    }
146
  }
147

148
  /**
149
   * @return the empty instance of {@link ToolSecurity}.
150
   */
151
  public static ToolSecurity getEmpty() {
152

153
    return EMPTY;
2✔
154
  }
155
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc