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

devonfw / IDEasy / 9907372175

12 Jul 2024 11:49AM UTC coverage: 61.142% (-0.02%) from 61.162%
9907372175

push

github

hohwille
fixed tests

1997 of 3595 branches covered (55.55%)

Branch coverage included in aggregate %.

5296 of 8333 relevant lines covered (63.55%)

2.8 hits per line

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

60.44
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 void merge(Path setup, Path update, EnvironmentVariables variables, Path workspace) {
58

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

74
  private FileMerger getMerger(Path file) {
75

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

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

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

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

120
  private Set<String> addChildren(Path folder, Set<String> children) {
121

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

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