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
.jcr
.ArgeoJcrUtils
;
13 import org
.argeo
.jcr
.ArgeoNames
;
14 import org
.argeo
.jcr
.JcrUtils
;
15 import org
.argeo
.slc
.SlcException
;
16 import org
.argeo
.slc
.repo
.RepoConstants
;
17 import org
.argeo
.slc
.repo
.RepoUtils
;
18 import org
.argeo
.util
.security
.Keyring
;
21 * Abstract a repository. It might be persisted by a node in the current user
22 * home Node or just an URI and a label if user is anonymous
24 public class RepoElem
extends DistParentElem
{
25 // private final static Log log = LogFactory.getLog(RepoElem.class);
27 private RepositoryFactory repositoryFactory
;
28 private Keyring keyring
;
29 private Credentials credentials
;
30 private Session defaultSession
= null;
32 // Defines current repo
33 private Node repoNode
= null;
37 private Repository repository
;
40 * Creates a RepoElement for anonymous user. The {@code RepositoryFactory}
41 * is used to enable lazy initialisation
43 public RepoElem(RepositoryFactory repoFactory
, String uri
, String label
) {
45 this.repositoryFactory
= repoFactory
;
51 * Creates a RepoElement for an authenticated user. The
52 * {@code RepositoryFactory} and {@code Keyring} are used to enable lazy
56 public RepoElem(RepositoryFactory repoFactory
, Keyring keyring
,
57 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
69 .equals(repoNode
.getName()));
71 // Directly log and retrieve children for local repository
74 setReadOnly(!repoNode
.hasNode(ArgeoNames
.ARGEO_PASSWORD
));
75 uri
= JcrUtils
.get(repoNode
, ArgeoNames
.ARGEO_URI
);
76 } catch (RepositoryException e
) {
77 throw new SlcException("Unable to " + "initialize repo element", e
);
81 /** Effective login. Does nothing if the session is already there. */
86 if (repository
== null)
89 repository
= ArgeoJcrUtils
.getRepositoryByUri(
90 repositoryFactory
, uri
);
92 repository
= RepoUtils
.getRepository(repositoryFactory
,
94 credentials
= RepoUtils
.getRepositoryCredentials(keyring
,
99 defaultSession
= repository
.login(credentials
);
101 } catch (RepositoryException e
) {
102 throw new SlcException("Cannot login repository " + label
103 + " with credential " + credentials
, e
);
107 protected void refreshChildren() {
109 // TODO also remove deleted children (only adds for the time being
110 String
[] workspaceNames
= defaultSession
.getWorkspace()
111 .getAccessibleWorkspaceNames();
112 buildWksp
: for (String workspaceName
: workspaceNames
) {
113 if (!isWorkspaceVisible(workspaceName
))
116 String prefix
= getPrefix(workspaceName
);
117 if (getChildByName(prefix
) == null) {
118 WkspGroupElem wkspGpElem
= new WkspGroupElem(RepoElem
.this,
120 addChild(wkspGpElem
);
123 } catch (RepositoryException e
) {
124 throw new SlcException("Cannot list workspaces for " + repoNode
, e
);
129 public synchronized void dispose() {
130 JcrUtils
.logoutQuietly(defaultSession
);
134 private String
getPrefix(String workspaceName
) {
135 // Here is the tricks - we rely on a "hard coded" convention
136 // Workspace name should be like: name-major.minor
137 if (workspaceName
.lastIndexOf(VERSION_SEP
) > 0)
138 return workspaceName
.substring(0,
139 workspaceName
.lastIndexOf(VERSION_SEP
));
141 return workspaceName
;
144 /* Exposes this to the children workspace group */
145 protected boolean isWorkspaceVisible(String wkspName
) {
146 Boolean result
= true;
147 if (ARGEO_SYSTEM_WKSP
.contains(wkspName
))
149 // Add a supplementary check to hide workspace that are not
150 // public to anonymous user
151 if (repoNode
== null) {
152 Session tmpSession
= null;
154 tmpSession
= repository
.login(wkspName
);
156 tmpSession
.checkPermission("/", "read");
157 } catch (AccessControlException e
) {
160 } catch (RepositoryException e
) {
161 throw new SlcException(
162 "Cannot list workspaces for anonymous user", e
);
164 JcrUtils
.logoutQuietly(tmpSession
);
172 * {@link Repository#login(javax.jcr.Credentials, String)} method. To be
175 * Creates a new session with correct credentials using the information
176 * contained in the corresponding repo node. It provides all UI children
177 * elements an unique entry point to retrieve a new Session. Caller must
178 * close the session when it is not in use anymore.
181 protected Session
repositoryLogin(String workspaceName
) {
183 return repository
.login(credentials
, workspaceName
);
184 } catch (RepositoryException e
) {
185 throw new SlcException("Cannot login repository " + label
186 + " with credential " + credentials
, e
);
190 public Boolean
isConnected() {
191 if (defaultSession
!= null && defaultSession
.isLive())
197 /** Exposes URI to the current repository */
198 public String
getUri() {
202 public String
getRepoNodePath() {
203 if (repoNode
== null)
207 return repoNode
.getPath();
208 } catch (RepositoryException e
) {
209 throw new SlcException("Cannot get node path for repository "
215 * Exposes the local repoNode that completely define a connection to a
216 * repository (including a set of credentials). Might return null in case of
219 protected Node
getRepoNode() {
223 protected Repository
getRepository() {
227 protected Credentials
getCredentials() {
232 public String
getDescription() {
234 if (repoNode
!= null)
235 desc
= label
+ " (" + uri
+ ")";
239 public String
getLabel() {
243 public String
toString() {
244 return repoNode
!= null ? repoNode
.toString() : label
;