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

devonfw / IDEasy / 11560364436

28 Oct 2024 06:31PM UTC coverage: 66.705% (-0.04%) from 66.746%
11560364436

push

github

web-flow
#710: make workspace configuration robust (#719)

2406 of 3950 branches covered (60.91%)

Branch coverage included in aggregate %.

6275 of 9064 relevant lines covered (69.23%)

3.05 hits per line

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

60.87
cli/src/main/java/com/devonfw/tools/ide/merge/DirectoryMerger.java
1
package com.devonfw.tools.ide.merge;
2

3
import java.io.IOException;
4
import java.nio.file.Files;
5
import java.nio.file.Path;
6
import java.util.HashMap;
7
import java.util.HashSet;
8
import java.util.Iterator;
9
import java.util.Map;
10
import java.util.Set;
11

12
import org.jline.utils.Log;
13

14
import com.devonfw.tools.ide.context.IdeContext;
15
import com.devonfw.tools.ide.environment.EnvironmentVariables;
16
import com.devonfw.tools.ide.merge.xmlmerger.XmlMerger;
17
import com.devonfw.tools.ide.util.FilenameUtil;
18

19
/**
20
 * Implementation of {@link WorkspaceMerger} that does the whole thing:
21
 * <ul>
22
 * <li>It will recursively traverse directories.</li>
23
 * <li>For each setup or update file if will delegate to the according {@link FileMerger} based on the file
24
 * extension.</li>
25
 * </ul>
26
 */
27
public class DirectoryMerger extends AbstractWorkspaceMerger {
28

29
  private final Map<String, FileMerger> extension2mergerMap;
30

31
  private final FallbackMerger fallbackMerger;
32

33
  /**
34
   * The constructor.
35
   *
36
   * @param context the {@link #context}.
37
   */
38
  public DirectoryMerger(IdeContext context) {
39

40
    super(context);
3✔
41
    this.extension2mergerMap = new HashMap<>();
5✔
42
    PropertiesMerger propertiesMerger = new PropertiesMerger(context);
5✔
43
    this.extension2mergerMap.put("properties", propertiesMerger);
6✔
44
    this.extension2mergerMap.put("prefs", propertiesMerger); // Eclipse specific
6✔
45
    XmlMerger xmlMerger = new XmlMerger(context);
5✔
46
    this.extension2mergerMap.put("xml", xmlMerger);
6✔
47
    this.extension2mergerMap.put("xmi", xmlMerger);
6✔
48
    this.extension2mergerMap.put("launch", xmlMerger); // Eclipse specific
6✔
49
    JsonMerger jsonMerger = new JsonMerger(context);
5✔
50
    this.extension2mergerMap.put("json", jsonMerger);
6✔
51
    TextMerger textMerger = new TextMerger(context);
5✔
52
    this.extension2mergerMap.put("name", textMerger); // intellij specific
6✔
53
    this.fallbackMerger = new FallbackMerger(context);
6✔
54
  }
1✔
55

56
  @Override
57
  public int merge(Path setup, Path update, EnvironmentVariables variables, Path workspace) {
58

59
    int errors = 0;
2✔
60
    Set<String> children = null;
2✔
61
    children = addChildren(setup, children);
5✔
62
    children = addChildren(update, children);
5✔
63
    if (children == null) {
2✔
64
      // file merge
65
      FileMerger merger = getMerger(workspace);
4✔
66
      errors += merger.merge(setup, update, variables, workspace);
9✔
67
    } else {
1✔
68
      // directory scan
69
      for (String filename : children) {
10✔
70
        errors += merge(setup.resolve(filename), update.resolve(filename), variables, workspace.resolve(filename));
15✔
71
      }
1✔
72
    }
73
    return errors;
2✔
74
  }
75

76
  private FileMerger getMerger(Path file) {
77

78
    String filename = file.getFileName().toString();
4✔
79
    String extension = FilenameUtil.getExtension(filename);
3✔
80
    if (extension == null) {
2!
81
      this.context.debug("No extension for {}", file);
×
82
    } else {
83
      this.context.trace("Extension is {}", extension);
10✔
84
      FileMerger merger = this.extension2mergerMap.get(extension);
6✔
85
      if (merger != null) {
2!
86
        return merger;
2✔
87
      }
88
    }
89
    return this.fallbackMerger;
×
90
  }
91

92
  @Override
93
  public void inverseMerge(Path workspace, EnvironmentVariables variables, boolean addNewProperties, Path update) {
94

95
    if (Files.isDirectory(update)) {
×
96
      if (!Files.isDirectory(workspace)) {
×
97
        Log.warn("Workspace is missing directory: {}", workspace);
×
98
        return;
×
99
      }
100
      Log.trace("Traversing directory: {}", update);
×
101
      try {
102
        Iterator<Path> iterator = Files.list(update).iterator();
×
103
        while (iterator.hasNext()) {
×
104
          Path updateChild = iterator.next();
×
105
          Path fileName = updateChild.getFileName();
×
106
          inverseMerge(workspace.resolve(fileName), variables, addNewProperties, update.resolve(fileName));
×
107
        }
×
108
      } catch (IOException e) {
×
109
        throw new IllegalStateException("Failed to list children of folder " + update, e);
×
110
      }
×
111

112
    } else if (Files.exists(workspace)) {
×
113
      Log.debug("Start merging of changes from workspace back to file: {}", update);
×
114
      FileMerger merger = getMerger(workspace);
×
115
      Log.trace("Using merger {}", merger.getClass().getSimpleName());
×
116
      merger.inverseMerge(workspace, variables, addNewProperties, update);
×
117
    } else {
×
118
      Log.warn("No such file or directory: {}", update);
×
119
    }
120
  }
×
121

122
  private Set<String> addChildren(Path folder, Set<String> children) {
123

124
    if (!Files.isDirectory(folder)) {
5✔
125
      return children;
2✔
126
    }
127
    try {
128
      Iterator<Path> iterator = Files.list(folder).iterator();
4✔
129
      while (iterator.hasNext()) {
3✔
130
        Path child = iterator.next();
4✔
131
        if (children == null) {
2✔
132
          children = new HashSet<>();
4✔
133
        }
134
        children.add(child.getFileName().toString());
6✔
135
      }
1✔
136
      return children;
2✔
137
    } catch (IOException e) {
×
138
      throw new IllegalStateException("Failed to list children of folder " + folder, e);
×
139
    }
140
  }
141

142
}
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