1 package org
.argeo
.cms
.acr
;
3 import java
.util
.Iterator
;
4 import java
.util
.Locale
;
7 import java
.util
.TreeSet
;
9 import java
.util
.concurrent
.CompletableFuture
;
10 import java
.util
.concurrent
.CompletionStage
;
11 import java
.util
.function
.Consumer
;
12 import java
.util
.stream
.Collectors
;
14 import javax
.security
.auth
.Subject
;
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
;
26 /** Implements {@link ProvidedSession}. */
27 class CmsContentSession
implements ProvidedSession
{
28 final private AbstractContentRepository contentRepository
;
30 private final UUID uuid
;
31 private Subject subject
;
32 private Locale locale
;
34 private CompletableFuture
<ProvidedSession
> closed
= new CompletableFuture
<>();
36 private CompletableFuture
<ContentSession
> edition
;
38 private Set
<ContentProvider
> modifiedProviders
= new TreeSet
<>();
40 private Content sessionRunDir
;
42 public CmsContentSession(AbstractContentRepository contentRepository
, UUID uuid
, Subject subject
, Locale locale
) {
43 this.contentRepository
= contentRepository
;
44 this.subject
= subject
;
51 closed
.complete(this);
53 if (sessionRunDir
!= null)
54 sessionRunDir
.remove();
58 public CompletionStage
<ProvidedSession
> onClose() {
59 return closed
.minimalCompletionStage();
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
);
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
);
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);
87 public Subject
getSubject() {
92 public Locale
getLocale() {
97 public ProvidedRepository
getRepository() {
98 return contentRepository
;
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]);
117 public String
getNamespaceURI(String prefix
) {
118 return NamespaceUtils
.getNamespaceURI((p
) -> contentRepository
.getTypesManager().getPrefixes().get(p
), prefix
);
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()),
129 public CompletionStage
<ContentSession
> edit(Consumer
<ContentSession
> work
) {
130 edition
= CompletableFuture
.supplyAsync(() -> {
133 }).thenApply((s
) -> {
135 for (ContentProvider provider
: modifiedProviders
) {
136 if (provider
instanceof DomContentProvider
) {
137 ((DomContentProvider
) provider
).persist(s
);
142 return edition
.minimalCompletionStage();
146 public boolean isEditing() {
147 return edition
!= null && !edition
.isDone();
151 public void notifyModification(ProvidedContent content
) {
152 ContentProvider contentProvider
= content
.getProvider();
153 modifiedProviders
.add(contentProvider
);
157 public UUID
getUuid() {
162 public Content
getSessionRunDir() {
163 if (sessionRunDir
== null) {
164 String runDirPath
= CmsContentRepository
.RUN_BASE
+ '/' + uuid
.toString();
165 if (exists(runDirPath
))
166 sessionRunDir
= get(runDirPath
);
168 Content runDir
= get(CmsContentRepository
.RUN_BASE
);
169 // TODO deal with no run dir available?
170 sessionRunDir
= runDir
.add(uuid
.toString(), CrName
.COLLECTION
.get());
173 return sessionRunDir
;
177 // public String findNamespace(String prefix) {
178 // return prefixes.get(prefix);
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());
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);