1 package org
.argeo
.cms
.acr
.fs
;
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
;
11 import java
.util
.NavigableMap
;
12 import java
.util
.Objects
;
13 import java
.util
.TreeMap
;
14 import java
.util
.stream
.Collectors
;
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
;
23 /** Access a file system as a {@link ContentProvider}. */
24 public class FsContentProvider
implements ContentProvider
{
25 final static String XMLNS_
= "xmlns:";
27 private final String mountPath
;
28 private final Path rootPath
;
29 // private final boolean isRoot;
31 private NavigableMap
<String
, String
> prefixes
= new TreeMap
<>();
33 public FsContentProvider(String mountPath
, Path rootPath
) {
34 Objects
.requireNonNull(mountPath
);
35 Objects
.requireNonNull(rootPath
);
37 this.mountPath
= mountPath
;
38 this.rootPath
= rootPath
;
39 // FIXME make it more robust
44 // public FsContentProvider(String mountPath, Path rootPath, boolean isRoot) {
45 // this.mountPath = mountPath;
46 // this.rootPath = rootPath;
47 //// this.isRoot = isRoot;
48 //// initNamespaces();
51 private void initNamespaces() {
53 UserDefinedFileAttributeView udfav
= Files
.getFileAttributeView(rootPath
,
54 UserDefinedFileAttributeView
.class);
57 for (String name
: udfav
.list()) {
58 if (name
.startsWith(XMLNS_
)) {
59 ByteBuffer buf
= ByteBuffer
.allocate(udfav
.size(name
));
60 udfav
.read(name
, buf
);
62 String namespace
= StandardCharsets
.UTF_8
.decode(buf
).toString();
63 String prefix
= name
.substring(XMLNS_
.length());
64 prefixes
.put(prefix
, namespace
);
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
);
79 protected void addDefaultNamespace(UserDefinedFileAttributeView udfav
, String prefix
, String namespace
)
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
);
88 public void registerPrefix(String prefix
, String namespace
) {
89 if (prefixes
.containsKey(prefix
))
90 prefixes
.remove(prefix
);
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
);
102 public String
getMountPath() {
106 boolean isMountRoot(Path path
) {
108 return Files
.isSameFile(rootPath
, path
);
109 } catch (IOException e
) {
110 throw new ContentResourceException(e
);
115 public ProvidedContent
get(ProvidedSession session
, String relativePath
) {
116 return new FsContent(session
, this, rootPath
.resolve(relativePath
));
124 public boolean exists(ProvidedSession session
, String relativePath
) {
125 return Files
.exists(rootPath
.resolve(relativePath
));
129 public String
getNamespaceURI(String prefix
) {
130 return NamespaceUtils
.getNamespaceURI((p
) -> prefixes
.get(p
), prefix
);
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
);