]> git.argeo.org Git - lgpl/argeo-commons.git/blob - acr/CmsContentSession.java
Prepare next development cycle
[lgpl/argeo-commons.git] / acr / CmsContentSession.java
1 package org.argeo.cms.acr;
2
3 import java.util.Iterator;
4 import java.util.Locale;
5 import java.util.Map;
6 import java.util.Set;
7 import java.util.TreeSet;
8 import java.util.UUID;
9 import java.util.concurrent.CompletableFuture;
10 import java.util.concurrent.CompletionStage;
11 import java.util.function.Consumer;
12 import java.util.stream.Collectors;
13
14 import javax.security.auth.Subject;
15
16 import org.argeo.api.acr.Content;
17 import org.argeo.api.acr.ContentSession;
18 import org.argeo.api.acr.CrName;
19 import org.argeo.api.acr.NamespaceUtils;
20 import org.argeo.api.acr.spi.ContentProvider;
21 import org.argeo.api.acr.spi.ProvidedContent;
22 import org.argeo.api.acr.spi.ProvidedRepository;
23 import org.argeo.api.acr.spi.ProvidedSession;
24 import org.argeo.cms.acr.xml.DomContentProvider;
25
26 /** Implements {@link ProvidedSession}. */
27 class CmsContentSession implements ProvidedSession {
28 final private AbstractContentRepository contentRepository;
29
30 private final UUID uuid;
31 private Subject subject;
32 private Locale locale;
33
34 private CompletableFuture<ProvidedSession> closed = new CompletableFuture<>();
35
36 private CompletableFuture<ContentSession> edition;
37
38 private Set<ContentProvider> modifiedProviders = new TreeSet<>();
39
40 private Content sessionRunDir;
41
42 public CmsContentSession(AbstractContentRepository contentRepository, UUID uuid, Subject subject, Locale locale) {
43 this.contentRepository = contentRepository;
44 this.subject = subject;
45 this.locale = locale;
46 this.uuid = uuid;
47
48 }
49
50 public void close() {
51 closed.complete(this);
52
53 if (sessionRunDir != null)
54 sessionRunDir.remove();
55 }
56
57 @Override
58 public CompletionStage<ProvidedSession> onClose() {
59 return closed.minimalCompletionStage();
60 }
61
62 @Override
63 public Content get(String path) {
64 ContentProvider contentProvider = contentRepository.getMountManager().findContentProvider(path);
65 String mountPath = contentProvider.getMountPath();
66 String relativePath = extractRelativePath(mountPath, path);
67 ProvidedContent content = contentProvider.get(CmsContentSession.this, relativePath);
68 return content;
69 }
70
71 @Override
72 public boolean exists(String path) {
73 ContentProvider contentProvider = contentRepository.getMountManager().findContentProvider(path);
74 String mountPath = contentProvider.getMountPath();
75 String relativePath = extractRelativePath(mountPath, path);
76 return contentProvider.exists(this, relativePath);
77 }
78
79 private String extractRelativePath(String mountPath, String path) {
80 String relativePath = path.substring(mountPath.length());
81 if (relativePath.length() > 0 && relativePath.charAt(0) == '/')
82 relativePath = relativePath.substring(1);
83 return relativePath;
84 }
85
86 @Override
87 public Subject getSubject() {
88 return subject;
89 }
90
91 @Override
92 public Locale getLocale() {
93 return locale;
94 }
95
96 @Override
97 public ProvidedRepository getRepository() {
98 return contentRepository;
99 }
100
101 /*
102 * MOUNT MANAGEMENT
103 */
104 @Override
105 public Content getMountPoint(String path) {
106 String[] parent = ContentUtils.getParentPath(path);
107 ProvidedContent mountParent = (ProvidedContent) get(parent[0]);
108 // Content mountPoint = mountParent.getProvider().get(CmsContentSession.this, null, path);
109 return mountParent.getMountPoint(parent[1]);
110 }
111
112 /*
113 * NAMESPACE CONTEXT
114 */
115
116 @Override
117 public String getNamespaceURI(String prefix) {
118 return NamespaceUtils.getNamespaceURI((p) -> contentRepository.getTypesManager().getPrefixes().get(p), prefix);
119 }
120
121 @Override
122 public Iterator<String> getPrefixes(String namespaceURI) {
123 return NamespaceUtils.getPrefixes((ns) -> contentRepository.getTypesManager().getPrefixes().entrySet().stream()
124 .filter(e -> e.getValue().equals(ns)).map(Map.Entry::getKey).collect(Collectors.toUnmodifiableSet()),
125 namespaceURI);
126 }
127
128 @Override
129 public CompletionStage<ContentSession> edit(Consumer<ContentSession> work) {
130 edition = CompletableFuture.supplyAsync(() -> {
131 work.accept(this);
132 return this;
133 }).thenApply((s) -> {
134 // TODO optimise
135 for (ContentProvider provider : modifiedProviders) {
136 if (provider instanceof DomContentProvider) {
137 ((DomContentProvider) provider).persist(s);
138 }
139 }
140 return s;
141 });
142 return edition.minimalCompletionStage();
143 }
144
145 @Override
146 public boolean isEditing() {
147 return edition != null && !edition.isDone();
148 }
149
150 @Override
151 public void notifyModification(ProvidedContent content) {
152 ContentProvider contentProvider = content.getProvider();
153 modifiedProviders.add(contentProvider);
154 }
155
156 @Override
157 public UUID getUuid() {
158 return uuid;
159 }
160
161 @Override
162 public Content getSessionRunDir() {
163 if (sessionRunDir == null) {
164 String runDirPath = CmsContentRepository.RUN_BASE + '/' + uuid.toString();
165 if (exists(runDirPath))
166 sessionRunDir = get(runDirPath);
167 else {
168 Content runDir = get(CmsContentRepository.RUN_BASE);
169 // TODO deal with no run dir available?
170 sessionRunDir = runDir.add(uuid.toString(), CrName.COLLECTION.get());
171 }
172 }
173 return sessionRunDir;
174 }
175
176 // @Override
177 // public String findNamespace(String prefix) {
178 // return prefixes.get(prefix);
179 // }
180 //
181 // @Override
182 // public Set<String> findPrefixes(String namespaceURI) {
183 // Set<String> res = prefixes.entrySet().stream().filter(e -> e.getValue().equals(namespaceURI))
184 // .map(Map.Entry::getKey).collect(Collectors.toUnmodifiableSet());
185 //
186 // return res;
187 // }
188 //
189 // @Override
190 // public String findPrefix(String namespaceURI) {
191 // if (CrName.CR_NAMESPACE_URI.equals(namespaceURI) && prefixes.containsKey(CrName.CR_DEFAULT_PREFIX))
192 // return CrName.CR_DEFAULT_PREFIX;
193 // return ProvidedSession.super.findPrefix(namespaceURI);
194 // }
195
196 }