]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/acr/MountManager.java
Make DOM ACR more robust when used as repository root.
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / acr / MountManager.java
1 package org.argeo.cms.acr;
2
3 import java.util.Map;
4 import java.util.NavigableMap;
5 import java.util.Objects;
6 import java.util.TreeMap;
7 import java.util.function.Function;
8
9 import org.argeo.api.acr.Content;
10 import org.argeo.api.acr.CrName;
11 import org.argeo.api.acr.spi.ContentProvider;
12
13 /** Manages the structural and dynamic mounts within the content repository. */
14 class MountManager {
15 private final NavigableMap<String, ContentProvider> partitions = new TreeMap<>();
16
17 private final CmsContentSession systemSession;
18
19 public MountManager(CmsContentSession systemSession) {
20 this.systemSession = systemSession;
21 }
22
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
30 return;
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");
35
36 }
37
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);
46 }
47 return partitions.get(mountPath);
48 }
49
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);
55 if (entry == null)
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
63 // provider");
64 }
65 ContentProvider contentProvider = entry.getValue();
66 assert mountPath.equals(contentProvider.getMountPath());
67 return contentProvider;
68 }
69
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))
75 break tail;
76 res.put(provider.getKey(), provider.getValue());
77 }
78 return res;
79
80 }
81
82 }