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

devonfw / IDEasy / 14124338799

28 Mar 2025 07:48AM UTC coverage: 67.594% (-0.008%) from 67.602%
14124338799

Pull #1182

github

web-flow
Merge 056e15b6a into 8bcbfb54c
Pull Request #1182: #692 : "Latest" version of docker is now accepted

3044 of 4934 branches covered (61.69%)

Branch coverage included in aggregate %.

7846 of 11177 relevant lines covered (70.2%)

3.07 hits per line

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

46.43
cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java
1
package com.devonfw.tools.ide.url.model.folder;
2

3
import java.io.IOException;
4
import java.nio.file.Files;
5
import java.nio.file.Path;
6
import java.util.Collection;
7
import java.util.Collections;
8
import java.util.HashMap;
9
import java.util.Iterator;
10
import java.util.Map;
11
import java.util.Set;
12
import java.util.stream.Stream;
13

14
import org.slf4j.Logger;
15
import org.slf4j.LoggerFactory;
16

17
import com.devonfw.tools.ide.url.model.AbstractUrlArtifact;
18
import com.devonfw.tools.ide.url.model.UrlArtifactWithParent;
19

20
/**
21
 * Class from which UrlRepository inherits, as its objects don't have a parent, but possibly child objects of the class UrlTool.
22
 *
23
 * @param <C> Type of the child object.
24
 */
25
public abstract class AbstractUrlFolder<C extends UrlArtifactWithParent<?>> extends AbstractUrlArtifact
26
    implements UrlFolder<C> {
27

28
  private static final Logger LOG = LoggerFactory.getLogger(AbstractUrlFolder.class);
4✔
29

30
  private final Map<String, C> childMap;
31

32
  private final Set<String> childNames;
33

34
  private final Collection<C> children;
35

36
  /**
37
   * The constructor.
38
   *
39
   * @param path the {@link #getPath() path}.
40
   * @param name the {@link #getName() filename}.
41
   */
42
  public AbstractUrlFolder(Path path, String name) {
43

44
    super(path, name);
4✔
45
    this.childMap = new HashMap<>();
5✔
46
    this.childNames = Collections.unmodifiableSet(this.childMap.keySet());
6✔
47
    this.children = Collections.unmodifiableCollection(this.childMap.values());
6✔
48
  }
1✔
49

50
  @Override
51
  public int getChildCount() {
52

53
    load(false);
×
54
    return this.childMap.size();
×
55
  }
56

57
  @Override
58
  public C getChild(String name) {
59

60
    load(false);
3✔
61
    if ("*".equals(name)) {
4!
62
      return this.childMap.get("latest");
×
63
    }
64
    return this.childMap.get(name);
6✔
65
  }
66

67
  @Override
68
  public C getOrCreateChild(String name) {
69

70
    return this.childMap.computeIfAbsent(name, p -> newChild(name));
13✔
71
  }
72

73
  @Override
74
  public void deleteChild(String name) {
75

76
    C child = this.childMap.remove(name);
×
77
    if (child != null) {
×
78
      delete(child.getPath());
×
79
    }
80
  }
×
81

82
  private static void delete(Path path) {
83

84
    LOG.debug("Deleting {}", path);
×
85
    if (Files.exists(path)) {
×
86
      try {
87
        deleteRecursive(path);
×
88
      } catch (IOException e) {
×
89
        throw new RuntimeException("Failed to delete " + path);
×
90
      }
×
91
    } else {
92
      LOG.warn("Could not delete file {} because it does not exist.", path);
×
93
    }
94
  }
×
95

96
  private static void deleteRecursive(Path path) throws IOException {
97

98
    if (Files.isDirectory(path)) {
×
99
      try (Stream<Path> childStream = Files.list(path)) {
×
100
        Iterator<Path> iterator = childStream.iterator();
×
101
        while (iterator.hasNext()) {
×
102
          Path child = iterator.next();
×
103
          deleteRecursive(child);
×
104
        }
×
105
      }
106
    }
107
    LOG.trace("Deleting {}", path);
×
108
    Files.delete(path);
×
109

110
  }
×
111

112
  @Override
113
  public Collection<C> getChildren() {
114

115
    load(false);
3✔
116
    return this.children;
3✔
117
  }
118

119
  /**
120
   * @param name the plain filename (excluding any path).
121
   * @param folder - {@code true} in case of a folder, {@code false} otherwise (plain data file).
122
   * @return {@code true} if the existing file from the file-system should be {@link #getOrCreateChild(String) created as child}, {@code false} otherwise
123
   *     (ignore the file).
124
   */
125
  protected boolean isAllowedChild(String name, boolean folder) {
126

127
    return folder;
2✔
128
  }
129

130
  /**
131
   * @return the {@link Set} with all {@link #getName() names} of the children.
132
   */
133
  public Set<String> getChildNames() {
134

135
    return this.childNames;
×
136
  }
137

138
  @Override
139
  public void load(boolean recursive) {
140

141
    if (!this.loaded) {
3✔
142
      Path path = getPath();
3✔
143
      if (Files.isDirectory(path)) {
5✔
144
        try (Stream<Path> childStream = Files.list(path)) {
3✔
145
          childStream.forEach(c -> loadChild(c, recursive));
10✔
146
        } catch (IOException e) {
×
147
          throw new IllegalStateException("Failed to list children of directory " + path, e);
×
148
        }
1✔
149
      }
150
      this.loaded = true;
3✔
151
    }
152
  }
1✔
153

154
  private void loadChild(Path childPath, boolean recursive) {
155

156
    String name = childPath.getFileName().toString();
4✔
157
    if (name.startsWith(".")) {
4!
158
      return; // ignore hidden files and folders (e.g. ".git")
×
159
    }
160
    boolean folder = Files.isDirectory(childPath);
5✔
161
    if (isAllowedChild(name, folder)) {
5✔
162
      C child = getOrCreateChild(name);
4✔
163
      if (recursive) {
2✔
164
        child.load(recursive);
3✔
165
      }
166
    }
167
  }
1✔
168

169
  /**
170
   * @param name the {@link #getName() name} of the requested child.
171
   * @return the new child object.
172
   */
173
  protected abstract C newChild(String name);
174

175
  @Override
176
  public void save() {
177

178
    for (C child : this.childMap.values()) {
×
179
      child.save();
×
180
    }
×
181
  }
×
182
}
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

© 2025 Coveralls, Inc