]> git.argeo.org Git - lgpl/argeo-commons.git/blob - cms/acr/fs/FsContentProvider.java
Prepare next development cycle
[lgpl/argeo-commons.git] / cms / acr / fs / FsContentProvider.java
1 package org.argeo.cms.acr.fs;
2
3 import java.io.IOException;
4 import java.nio.ByteBuffer;
5 import java.nio.charset.StandardCharsets;
6 import java.nio.file.Files;
7 import java.nio.file.Path;
8 import java.nio.file.attribute.UserDefinedFileAttributeView;
9 import java.util.Iterator;
10 import java.util.Map;
11 import java.util.NavigableMap;
12 import java.util.TreeMap;
13 import java.util.stream.Collectors;
14
15 import org.argeo.api.acr.Content;
16 import org.argeo.api.acr.ContentResourceException;
17 import org.argeo.api.acr.CrName;
18 import org.argeo.api.acr.NamespaceUtils;
19 import org.argeo.api.acr.spi.ContentProvider;
20 import org.argeo.api.acr.spi.ProvidedSession;
21
22 /** Access a file system as a {@link ContentProvider}. */
23 public class FsContentProvider implements ContentProvider {
24 final static String XMLNS_ = "xmlns:";
25
26 private final Path rootPath;
27 private final boolean isRoot;
28
29 private NavigableMap<String, String> prefixes = new TreeMap<>();
30
31 public FsContentProvider(Path rootPath, boolean isRoot) {
32 this.rootPath = rootPath;
33 this.isRoot = isRoot;
34 initNamespaces();
35 }
36
37 protected void initNamespaces() {
38 try {
39 UserDefinedFileAttributeView udfav = Files.getFileAttributeView(rootPath,
40 UserDefinedFileAttributeView.class);
41 for (String name : udfav.list()) {
42 if (name.startsWith(XMLNS_)) {
43 ByteBuffer buf = ByteBuffer.allocate(udfav.size(name));
44 udfav.read(name, buf);
45 buf.flip();
46 String namespace = StandardCharsets.UTF_8.decode(buf).toString();
47 String prefix = name.substring(XMLNS_.length());
48 prefixes.put(prefix, namespace);
49 }
50 }
51
52 // defaults
53 addDefaultNamespace(udfav, CrName.CR_DEFAULT_PREFIX, CrName.CR_NAMESPACE_URI);
54 addDefaultNamespace(udfav, "basic", CrName.CR_NAMESPACE_URI);
55 addDefaultNamespace(udfav, "owner", CrName.CR_NAMESPACE_URI);
56 addDefaultNamespace(udfav, "posix", CrName.CR_NAMESPACE_URI);
57 } catch (IOException e) {
58 throw new RuntimeException("Cannot read namespaces from " + rootPath, e);
59 }
60
61 }
62
63 protected void addDefaultNamespace(UserDefinedFileAttributeView udfav, String prefix, String namespace)
64 throws IOException {
65 if (!prefixes.containsKey(prefix)) {
66 ByteBuffer bb = ByteBuffer.wrap(namespace.getBytes(StandardCharsets.UTF_8));
67 int size = udfav.write(XMLNS_ + prefix, bb);
68 prefixes.put(prefix, namespace);
69 }
70 }
71
72 boolean isRoot(Path path) {
73 try {
74 return isRoot && Files.isSameFile(rootPath, path);
75 } catch (IOException e) {
76 throw new ContentResourceException(e);
77 }
78 }
79
80 @Override
81 public Content get(ProvidedSession session, String mountPath, String relativePath) {
82 return new FsContent(session, this, rootPath.resolve(relativePath));
83 }
84
85 /*
86 * NAMESPACE CONTEXT
87 */
88
89 @Override
90 public String getNamespaceURI(String prefix) {
91 return NamespaceUtils.getNamespaceURI((p) -> prefixes.get(p), prefix);
92 }
93
94 @Override
95 public Iterator<String> getPrefixes(String namespaceURI) {
96 return NamespaceUtils.getPrefixes((ns) -> prefixes.entrySet().stream().filter(e -> e.getValue().equals(ns))
97 .map(Map.Entry::getKey).collect(Collectors.toUnmodifiableSet()), namespaceURI);
98 }
99
100 }