1 package org
.argeo
.slc
.client
.ui
.dist
.model
;
3 import java
.security
.AccessControlException
;
5 import javax
.jcr
.Credentials
;
7 import javax
.jcr
.Repository
;
8 import javax
.jcr
.RepositoryException
;
9 import javax
.jcr
.RepositoryFactory
;
10 import javax
.jcr
.Session
;
12 import org
.argeo
.api
.NodeConstants
;
13 import org
.argeo
.api
.NodeUtils
;
14 import org
.argeo
.api
.security
.Keyring
;
15 import org
.argeo
.cms
.ArgeoNames
;
16 import org
.argeo
.jcr
.JcrUtils
;
17 import org
.argeo
.slc
.SlcException
;
18 import org
.argeo
.slc
.repo
.RepoConstants
;
19 import org
.argeo
.slc
.repo
.RepoUtils
;
22 * Abstract a repository. It might be persisted by a node in the current user
23 * home Node or just an URI and a label if user is anonymous
25 public class RepoElem
extends DistParentElem
{
26 // private final static Log log = LogFactory.getLog(RepoElem.class);
28 private RepositoryFactory repositoryFactory
;
29 private Keyring keyring
;
30 private Credentials credentials
;
31 private Session defaultSession
= null;
33 // Defines current repo
34 private Node repoNode
= null;
38 private Repository repository
;
41 * Creates a RepoElement for anonymous user. The {@code RepositoryFactory}
42 * is used to enable lazy initialisation
44 public RepoElem(RepositoryFactory repoFactory
, String uri
, String label
) {
46 this.repositoryFactory
= repoFactory
;
52 * Creates a RepoElement for an authenticated user. The
53 * {@code RepositoryFactory} and {@code Keyring} are used to enable lazy
57 public RepoElem(RepositoryFactory repoFactory
, Keyring keyring
, Node repoNode
, String alias
) {
60 // label = repoNode.isNodeType(NodeType.MIX_TITLE) ? repoNode
61 // .getProperty(Property.JCR_TITLE).getString() : repoNode
63 this.repoNode
= repoNode
;
64 this.repositoryFactory
= repoFactory
;
65 this.keyring
= keyring
;
67 // Initialize this repo information
68 setInHome(RepoConstants
.DEFAULT_JAVA_REPOSITORY_ALIAS
.equals(repoNode
.getName()));
70 // Directly log and retrieve children for local repository
73 setReadOnly(!repoNode
.hasNode(ArgeoNames
.ARGEO_PASSWORD
));
74 uri
= JcrUtils
.get(repoNode
, ArgeoNames
.ARGEO_URI
);
75 } catch (RepositoryException e
) {
76 throw new SlcException("Unable to " + "initialize repo element", e
);
80 /** Effective login. Does nothing if the session is already there. */
85 if (repository
== null)
88 repository
= NodeUtils
.getRepositoryByUri(repositoryFactory
, uri
);
90 repository
= RepoUtils
.getRepository(repositoryFactory
, keyring
, repoNode
);
91 credentials
= RepoUtils
.getRepositoryCredentials(keyring
, repoNode
);
95 // FIXME make it more generic
96 String defaultWorkspace
= NodeConstants
.SYS_WORKSPACE
;
97 defaultSession
= repository
.login(credentials
, defaultWorkspace
);
99 } catch (RepositoryException e
) {
100 throw new SlcException("Cannot login repository " + label
+ " with credential " + credentials
, e
);
104 protected void refreshChildren() {
106 // TODO also remove deleted children (only adds for the time being
107 String
[] workspaceNames
= defaultSession
.getWorkspace().getAccessibleWorkspaceNames();
108 buildWksp
: for (String workspaceName
: workspaceNames
) {
109 if (!isWorkspaceVisible(workspaceName
))
112 String prefix
= getPrefix(workspaceName
);
113 if (getChildByName(prefix
) == null) {
114 WkspGroupElem wkspGpElem
= new WkspGroupElem(RepoElem
.this, prefix
);
115 addChild(wkspGpElem
);
118 } catch (RepositoryException e
) {
119 throw new SlcException("Cannot list workspaces for " + repoNode
, e
);
124 public synchronized void dispose() {
125 JcrUtils
.logoutQuietly(defaultSession
);
129 private String
getPrefix(String workspaceName
) {
130 // Here is the tricks - we rely on a "hard coded" convention
131 // Workspace name should be like: name-major.minor
132 if (workspaceName
.lastIndexOf(VERSION_SEP
) > 0)
133 return workspaceName
.substring(0, workspaceName
.lastIndexOf(VERSION_SEP
));
135 return workspaceName
;
138 /* Exposes this to the children workspace group */
139 protected boolean isWorkspaceVisible(String wkspName
) {
140 Boolean result
= true;
141 if (ARGEO_SYSTEM_WKSP
.contains(wkspName
))
143 // Add a supplementary check to hide workspace that are not
144 // public to anonymous user
145 if (repoNode
== null) {
146 Session tmpSession
= null;
148 tmpSession
= repository
.login(wkspName
);
150 tmpSession
.checkPermission("/", "read");
151 } catch (AccessControlException e
) {
154 } catch (RepositoryException e
) {
155 throw new SlcException("Cannot list workspaces for anonymous user", e
);
157 JcrUtils
.logoutQuietly(tmpSession
);
165 * {@link Repository#login(javax.jcr.Credentials, String)} method. To be
168 * Creates a new session with correct credentials using the information
169 * contained in the corresponding repo node. It provides all UI children
170 * elements an unique entry point to retrieve a new Session. Caller must
171 * close the session when it is not in use anymore.
174 protected Session
repositoryLogin(String workspaceName
) {
176 if (workspaceName
== null)
177 workspaceName
= NodeConstants
.SYS_WORKSPACE
;// FIXME make it more generic
178 return repository
.login(credentials
, workspaceName
);
179 } catch (RepositoryException e
) {
180 throw new SlcException("Cannot login repository " + label
+ " with credential " + credentials
, e
);
184 public Boolean
isConnected() {
185 if (defaultSession
!= null && defaultSession
.isLive())
191 /** Exposes URI to the current repository */
192 public String
getUri() {
196 public String
getRepoNodePath() {
197 if (repoNode
== null)
201 return repoNode
.getPath();
202 } catch (RepositoryException e
) {
203 throw new SlcException("Cannot get node path for repository " + label
, e
);
208 * Exposes the local repoNode that completely define a connection to a
209 * repository (including a set of credentials). Might return null in case of
212 protected Node
getRepoNode() {
216 protected Repository
getRepository() {
220 protected Credentials
getCredentials() {
225 public String
getDescription() {
227 if (repoNode
!= null)
228 desc
= label
+ " (" + uri
+ ")";
232 public String
getLabel() {
236 public String
toString() {
237 return repoNode
!= null ? repoNode
.toString() : label
;