1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.datamodel.ifs2;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.nio.file.Files;
24 import java.nio.file.Path;
25 import java.nio.file.attribute.BasicFileAttributes;
26 import java.nio.file.attribute.FileTime;
27 import java.time.Instant;
28 import java.util.Date;
29 import java.util.Map;
30 import java.util.TreeMap;
31 import java.util.function.Consumer;
32 import java.util.function.Function;
33
34 import org.jdom2.Element;
35 import org.jdom2.Namespace;
36 import org.mycore.common.MCRConstants;
37 import org.mycore.common.MCRSessionMgr;
38 import org.mycore.common.config.MCRConfiguration2;
39 import org.mycore.datamodel.niofs.MCRFileAttributes;
40 import org.mycore.datamodel.niofs.utils.MCRRecursiveDeleter;
41
42
43
44
45
46
47
48 public abstract class MCRStoredNode extends MCRNode {
49
50 private static final String LANG_ATT = "lang";
51
52 private static final String LABEL_ELEMENT = "label";
53
54 private static final String NAME_ATT = "name";
55
56
57
58
59 private Element additionalData;
60
61
62
63
64
65
66
67
68
69
70
71
72 protected MCRStoredNode(MCRDirectory parent, Path fo, Element data) {
73 super(parent, fo);
74 this.additionalData = data;
75 }
76
77
78
79
80
81
82
83
84
85
86
87 protected MCRStoredNode(MCRDirectory parent, String name, String type) {
88 super(parent, parent.path.resolve(name));
89 additionalData = new Element(type);
90 additionalData.setAttribute(NAME_ATT, name);
91 parent.writeData(e -> e.addContent(additionalData));
92 }
93
94
95
96
97
98
99
100
101 @Deprecated
102 public File getLocalFile() {
103 return path.toFile();
104 }
105
106
107
108
109
110
111
112 public Path getLocalPath() {
113 return path;
114 }
115
116
117
118
119 public void delete() throws IOException {
120 writeData(Element::detach);
121 if (Files.isDirectory(path)) {
122 Files.walkFileTree(path, MCRRecursiveDeleter.instance());
123 } else {
124 Files.deleteIfExists(path);
125 }
126 getRoot().saveAdditionalData();
127 }
128
129
130
131
132
133
134
135 public void renameTo(String name) throws IOException {
136 Path oldPath = path;
137 Path newPath = path.resolveSibling(name);
138 Files.move(oldPath, newPath);
139 Files.setLastModifiedTime(newPath, FileTime.from(Instant.now()));
140 path = newPath;
141 writeData(e -> e.setAttribute(NAME_ATT, name));
142 getRoot().saveAdditionalData();
143 }
144
145
146
147
148
149
150
151 public void setLastModified(Date time) throws IOException {
152 Files.setLastModifiedTime(path, FileTime.from(time.toInstant()));
153 }
154
155
156
157
158
159
160
161
162
163 public void setLabel(String lang, String label) throws IOException {
164 writeData(e -> {
165 e.getChildren(LABEL_ELEMENT)
166 .stream()
167 .filter(child -> lang.equals(
168 child.getAttributeValue(LANG_ATT,
169 Namespace.XML_NAMESPACE)))
170 .findAny()
171 .orElseGet(() -> {
172 Element newLabel = new Element(LABEL_ELEMENT).setAttribute(LANG_ATT, lang, Namespace.XML_NAMESPACE);
173 e.addContent(newLabel);
174 return newLabel;
175 })
176 .setText(label);
177 });
178 getRoot().saveAdditionalData();
179 }
180
181
182
183
184 public void clearLabels() throws IOException {
185 writeData(e -> e.removeChildren(LABEL_ELEMENT));
186 getRoot().saveAdditionalData();
187 }
188
189
190
191
192
193 public Map<String, String> getLabels() {
194 Map<String, String> labels = new TreeMap<>();
195 for (Element label : readData(e -> e.getChildren(LABEL_ELEMENT))) {
196 labels.put(label.getAttributeValue(LANG_ATT, Namespace.XML_NAMESPACE), label.getText());
197 }
198 return labels;
199 }
200
201
202
203
204
205
206
207
208 public String getLabel(String lang) {
209 return readData(e -> e.getChildren(LABEL_ELEMENT)
210 .stream()
211 .filter(label -> lang.equals(
212 label.getAttributeValue(LANG_ATT, Namespace.XML_NAMESPACE)))
213 .findAny()
214 .map(Element::getText)
215 .orElse(null));
216 }
217
218
219
220
221
222
223
224 public String getCurrentLabel() {
225 String currentLang = MCRSessionMgr.getCurrentSession().getCurrentLanguage();
226 String label = getLabel(currentLang);
227 if (label != null) {
228 return label;
229 }
230
231 String defaultLang = MCRConfiguration2.getString("MCR.Metadata.DefaultLang").orElse(MCRConstants.DEFAULT_LANG);
232 label = getLabel(defaultLang);
233 if (label != null) {
234 return label;
235 }
236
237 return readData(e -> e.getChildText(LABEL_ELEMENT));
238 }
239
240
241
242
243 abstract void repairMetadata() throws IOException;
244
245 protected <T> T readData(Function<Element, T> readOperation) {
246 return getRoot().getDataGuard().read(() -> readOperation.apply(additionalData));
247 }
248
249 protected <T> void writeData(Consumer<Element> writeOperation) {
250 getRoot().getDataGuard().write(() -> writeOperation.accept(additionalData));
251 }
252
253 public MCRFileAttributes<String> getBasicFileAttributes() throws IOException {
254 BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
255 return MCRFileAttributes.fromAttributes(attrs, null);
256 }
257
258 }