]> git.argeo.org Git - lgpl/argeo-commons.git/blob - fs/FsContentProvider.java
Prepare next development cycle
[lgpl/argeo-commons.git] / 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.ContentResourceException;
16 import org.argeo.api.acr.CrName;
17 import org.argeo.api.acr.NamespaceUtils;
18 import org.argeo.api.acr.spi.ContentProvider;
19 import org.argeo.api.acr.spi.ProvidedContent;
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 String mountPath;
27 private final Path rootPath;
28 private final boolean isRoot;
29
30 private NavigableMap<String, String> prefixes = new TreeMap<>();
31
32 public FsContentProvider(String mountPath, Path rootPath, boolean isRoot) {
33 this.mountPath = mountPath;
34 this.rootPath = rootPath;
35 this.isRoot = isRoot;
36 initNamespaces();
37 }
38
39 protected void initNamespaces() {
40 try {
41 UserDefinedFileAttributeView udfav = Files.getFileAttributeView(rootPath,
42 UserDefinedFileAttributeView.class);
43 if(udfav==null)
44 return;
45 for (String name : udfav.list()) {
46 if (name.startsWith(XMLNS_)) {
47 ByteBuffer buf = ByteBuffer.allocate(udfav.size(name));
48 udfav.read(name, buf);
49 buf.flip();
50 String namespace = StandardCharsets.UTF_8.decode(buf).toString();
51 String prefix = name.substring(XMLNS_.length());
52 prefixes.put(prefix, namespace);
53 }
54 }
55
56 // defaults
57 addDefaultNamespace(udfav, CrName.CR_DEFAULT_PREFIX, CrName.CR_NAMESPACE_URI);
58 addDefaultNamespace(udfav, "basic", CrName.CR_NAMESPACE_URI);
59 addDefaultNamespace(udfav, "owner", CrName.CR_NAMESPACE_URI);
60 addDefaultNamespace(udfav, "posix", CrName.CR_NAMESPACE_URI);
61 } catch (IOException e) {
62 throw new RuntimeException("Cannot read namespaces from " + rootPath, e);
63 }
64
65 }
66
67 protected void addDefaultNamespace(UserDefinedFileAttributeView udfav, String prefix, String namespace)
68 throws IOException {
69 if (!prefixes.containsKey(prefix)) {
70 ByteBuffer bb = ByteBuffer.wrap(namespace.getBytes(StandardCharsets.UTF_8));
71 udfav.write(XMLNS_ + prefix, bb);
72 prefixes.put(prefix, namespace);
73 }
74 }
75
76 public void registerPrefix(String prefix, String namespace) {
77 if (prefixes.containsKey(prefix))
78 prefixes.remove(prefix);
79 try {
80 UserDefinedFileAttributeView udfav = Files.getFileAttributeView(rootPath,
81 UserDefinedFileAttributeView.class);
82 addDefaultNamespace(udfav, prefix, namespace);
83 } catch (IOException e) {
84 throw new RuntimeException("Cannot register namespace " + prefix + " " + namespace + " on " + rootPath, e);
85 }
86
87 }
88
89
90 @Override
91 public String getMountPath() {
92 return mountPath;
93 }
94
95 boolean isRoot(Path path) {
96 try {
97 return isRoot && Files.isSameFile(rootPath, path);
98 } catch (IOException e) {
99 throw new ContentResourceException(e);
100 }
101 }
102
103 @Override
104 public ProvidedContent get(ProvidedSession session, String mountPath, String relativePath) {
105 return new FsContent(session, this, rootPath.resolve(relativePath));
106 }
107
108 /*
109 * NAMESPACE CONTEXT
110 */
111
112 @Override
113 public String getNamespaceURI(String prefix) {
114 return NamespaceUtils.getNamespaceURI((p) -> prefixes.get(p), prefix);
115 }
116
117 @Override
118 public Iterator<String> getPrefixes(String namespaceURI) {
119 return NamespaceUtils.getPrefixes((ns) -> prefixes.entrySet().stream().filter(e -> e.getValue().equals(ns))
120 .map(Map.Entry::getKey).collect(Collectors.toUnmodifiableSet()), namespaceURI);
121 }
122
123 }