mirror of https://github.com/micromata/borgbackup-butler.git

Kai Reinhard
28.10.2018 34de8e3ff4872c7e48e78d1fa102aa029ac2b261
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package de.micromata.borgbutler.cache;
 
import de.micromata.borgbutler.json.borg.BorgFilesystemItem;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.io.Serializable;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
 
public class FilesystemItem extends BorgFilesystemItem implements Serializable {
    private transient static Logger log = LoggerFactory.getLogger(FilesystemItem.class);
    private static final long serialVersionUID = 6561019300264543523L;
 
    @Getter
    @Setter
    private List<FilesystemItem> childs;
    @Getter
    @Setter
    private String name;
 
    public FilesystemItem() {
 
    }
 
    public FilesystemItem(BorgFilesystemItem item) {
        this.path = item.getPath();
        this.mode = item.getMode();
        this.mtime = item.getMtime();
        this.flags = item.getFlags();
        this.size = item.getSize();
        this.type = item.getType();
        this.gid = item.getGid();
        this.group = item.getGroup();
        this.healthy = item.isHealthy();
        this.linktarget = item.getLinktarget();
        this.source = item.getSource();
        this.uid = item.getUid();
        this.user = item.getUser();
    }
 
 
    /**
     * If running in diff mode, this flag specifies the type of difference. Null represents unmodified.
     */
    public enum DiffStatus {NEW, REMOVED, MODIFIED}
 
    @Setter
    @Getter
    protected String displayPath;
 
    /**
     * If created by diff tool, this flag represents the type of difference.
     */
    @Getter
    @Setter
    private FilesystemItem.DiffStatus diffStatus;
    /**
     * If created by diff tool, this object holds the file item of the other archive (diff archive).
     */
    @Getter
    @Setter
    private FilesystemItem diffItem;
    /**
     * If created by diff tool, this String contains all differences between current and other item for {@link FilesystemItem.DiffStatus#MODIFIED}.
     * This String may used for displaying.
     */
    @Getter
    private String differences;
 
    /**
     * Compares all fields and creates human readable string with differences.
     */
    public void buildDifferencesString() {
        if (diffItem == null) {
            // Nothing to do.
            return;
        }
        if (!StringUtils.equals(this.path, diffItem.getPath())) {
            log.error("*** Internal error: Differences should only be made on same path object: current='" + path
                    + "', other='" + diffItem.getPath() + "'.");
            return;
        }
        StringBuilder sb = new StringBuilder();
        appendDiff(sb, "type", this.type, diffItem.getType());
        //appendDiff(sb, "mode", this.mode, diffItem.mode); // Done by frontend (jsx)
        appendDiff(sb, "user", this.user, diffItem.getUser());
        appendDiff(sb, "group", this.group, diffItem.getGroup());
        appendDiff(sb, "uid", this.uid, diffItem.getUid());
        appendDiff(sb, "gid", this.gid, diffItem.getGid());
        //appendDiff(sb, "mtime", this.mtime, diffItem.mtime); // Done by frontend (jsx)
        //appendDiff(sb, "size", this.size, diffItem.size); // Done by frontend (jsx)
        if (sb.length() > 0) {
            diffStatus = FilesystemItem.DiffStatus.MODIFIED;
            this.differences = sb.toString();
        }
    }
 
    private void appendDiff(StringBuilder sb, String field, String current, String other) {
        if (StringUtils.equals(current, other)) {
            // Not modified.
            return;
        }
        if (sb.length() > 0) {
            sb.append(", ");
        }
        sb.append(field + ":['" + other + "'->'" + current + "']");
    }
 
    private void appendDiff(StringBuilder sb, String field, long current, long other) {
        if (current == other) {
            // Not modified.
            return;
        }
        if (sb.length() > 0) {
            sb.append(", ");
        }
        sb.append(field + ": ['" + current + "' -> '" + other + "']");
    }
 
    @Override
    public String toString() {
        return path;
    }
 
    FilesystemItem add(Path path, int count, BorgFilesystemItem borgItem) {
        if (childs == null) {
            childs = new ArrayList<>();
        }
        if (count + 1 == path.getNameCount()) {
            FilesystemItem item = new FilesystemItem(borgItem);
            item.setName(path.getFileName().toString());
            childs.add(item);
            return item;
        }
        String name = path.getName(count).toString();
        FilesystemItem child = null;
        for (FilesystemItem ch : childs) {
            if (StringUtils.equals(ch.name, name)) {
                child = ch;
                break;
            }
        }
        if (child == null) {
            child = new FilesystemItem();
            child.setName(name);
            childs.add(child);
        }
        return child.add(path, count + 1, borgItem);
    }
 
    public FilesystemItem find(String pathString) {
        if (StringUtils.isBlank(pathString)) {
            return this;
        }
        Path path = Paths.get(pathString);
        if (path.getNameCount() == 0) {
            return this;
        }
        return find(path, 0);
    }
 
    private FilesystemItem find(Path path, int count) {
        if (childs == null) {
            return null;
        }
        for (FilesystemItem child : childs) {
            String name = path.getName(count).toString();
            if (StringUtils.equals(child.name, name)) {
                if (path.getNameCount() == count + 1)
                    return child;
                else
                    return child.find(path, count + 1);
            }
        }
        return null;
    }
 
    public int getFileNumber() {
        return path.hashCode();
    }
}