1 package org
.argeo
.cms
.acr
;
4 import java
.util
.NavigableMap
;
5 import java
.util
.Objects
;
6 import java
.util
.TreeMap
;
7 import java
.util
.function
.Function
;
9 import org
.argeo
.api
.acr
.Content
;
10 import org
.argeo
.api
.acr
.CrName
;
11 import org
.argeo
.api
.acr
.spi
.ContentProvider
;
13 /** Manages the structural and dynamic mounts within the content repository. */
15 private final NavigableMap
<String
, ContentProvider
> partitions
= new TreeMap
<>();
17 private final CmsContentSession systemSession
;
19 public MountManager(CmsContentSession systemSession
) {
20 this.systemSession
= systemSession
;
23 synchronized void addStructuralContentProvider(ContentProvider contentProvider
) {
24 String mountPath
= contentProvider
.getMountPath();
25 Objects
.requireNonNull(mountPath
);
26 if (partitions
.containsKey(mountPath
))
27 throw new IllegalStateException("A provider is already registered for " + mountPath
);
28 partitions
.put(mountPath
, contentProvider
);
29 if ("/".equals(mountPath
))// root
31 String
[] parentPath
= ContentUtils
.getParentPath(mountPath
);
32 Content parent
= systemSession
.get(parentPath
[0]);
33 Content mount
= parent
.add(parentPath
[1]);
34 mount
.put(CrName
.mount
.qName(), "true");
38 synchronized ContentProvider
getOrAddMountedProvider(String mountPath
, Function
<String
, ContentProvider
> factory
) {
39 Objects
.requireNonNull(factory
);
40 if (!partitions
.containsKey(mountPath
)) {
41 ContentProvider contentProvider
= factory
.apply(mountPath
);
42 if (!mountPath
.equals(contentProvider
.getMountPath()))
43 throw new IllegalArgumentException("Mount path " + mountPath
+ " is inconsistent with content provider "
44 + contentProvider
.getMountPath());
45 partitions
.put(mountPath
, contentProvider
);
47 return partitions
.get(mountPath
);
50 /** The content provider for this path. */
51 synchronized ContentProvider
findContentProvider(String path
) {
52 // if (ContentUtils.EMPTY.equals(path))
53 // return partitions.firstEntry().getValue();
54 Map
.Entry
<String
, ContentProvider
> entry
= partitions
.floorEntry(path
);
56 throw new IllegalArgumentException("No entry provider found for path '" + path
+ "'");
57 String mountPath
= entry
.getKey();
58 if (!path
.startsWith(mountPath
)) {
59 // FIXME make it more robust and find when there is no content provider
60 String
[] parent
= ContentUtils
.getParentPath(path
);
61 return findContentProvider(parent
[0]);
62 // throw new IllegalArgumentException("Path " + path + " doesn't have a content
65 ContentProvider contentProvider
= entry
.getValue();
66 assert mountPath
.equals(contentProvider
.getMountPath());
67 return contentProvider
;
70 /** All content provider under this path. */
71 synchronized NavigableMap
<String
, ContentProvider
> findContentProviders(String path
) {
72 NavigableMap
<String
, ContentProvider
> res
= new TreeMap
<>();
73 tail
: for (Map
.Entry
<String
, ContentProvider
> provider
: partitions
.tailMap(path
).entrySet()) {
74 if (!provider
.getKey().startsWith(path
))
76 res
.put(provider
.getKey(), provider
.getValue());