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