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
.NodeUtils
;
13 import org
.argeo
.api
.security
.Keyring
;
14 import org
.argeo
.cms
.ArgeoNames
;
15 import org
.argeo
.jcr
.JcrUtils
;
16 import org
.argeo
.slc
.SlcException
;
17 import org
.argeo
.slc
.repo
.RepoConstants
;
18 import org
.argeo
.slc
.repo
.RepoUtils
;
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
, Node repoNode
, String alias
) {
59 // label = repoNode.isNodeType(NodeType.MIX_TITLE) ? repoNode
60 // .getProperty(Property.JCR_TITLE).getString() : repoNode
62 this.repoNode
= repoNode
;
63 this.repositoryFactory
= repoFactory
;
64 this.keyring
= keyring
;
66 // Initialize this repo information
67 setInHome(RepoConstants
.DEFAULT_JAVA_REPOSITORY_ALIAS
.equals(repoNode
.getName()));
69 // Directly log and retrieve children for local repository
72 setReadOnly(!repoNode
.hasNode(ArgeoNames
.ARGEO_PASSWORD
));
73 uri
= JcrUtils
.get(repoNode
, ArgeoNames
.ARGEO_URI
);
74 } catch (RepositoryException e
) {
75 throw new SlcException("Unable to " + "initialize repo element", e
);
79 /** Effective login. Does nothing if the session is already there. */
84 if (repository
== null)
87 repository
= NodeUtils
.getRepositoryByUri(repositoryFactory
, uri
);
89 repository
= RepoUtils
.getRepository(repositoryFactory
, keyring
, repoNode
);
90 credentials
= RepoUtils
.getRepositoryCredentials(keyring
, repoNode
);
94 // FIXME make it more generic
95 String defaultWorkspace
= "main";
96 defaultSession
= repository
.login(credentials
, defaultWorkspace
);
98 } catch (RepositoryException e
) {
99 throw new SlcException("Cannot login repository " + label
+ " with credential " + credentials
, e
);
103 protected void refreshChildren() {
105 // TODO also remove deleted children (only adds for the time being
106 String
[] workspaceNames
= defaultSession
.getWorkspace().getAccessibleWorkspaceNames();
107 buildWksp
: for (String workspaceName
: workspaceNames
) {
108 if (!isWorkspaceVisible(workspaceName
))
111 String prefix
= getPrefix(workspaceName
);
112 if (getChildByName(prefix
) == null) {
113 WkspGroupElem wkspGpElem
= new WkspGroupElem(RepoElem
.this, prefix
);
114 addChild(wkspGpElem
);
117 } catch (RepositoryException e
) {
118 throw new SlcException("Cannot list workspaces for " + repoNode
, e
);
123 public synchronized void dispose() {
124 JcrUtils
.logoutQuietly(defaultSession
);
128 private String
getPrefix(String workspaceName
) {
129 // Here is the tricks - we rely on a "hard coded" convention
130 // Workspace name should be like: name-major.minor
131 if (workspaceName
.lastIndexOf(VERSION_SEP
) > 0)
132 return workspaceName
.substring(0, workspaceName
.lastIndexOf(VERSION_SEP
));
134 return workspaceName
;
137 /* Exposes this to the children workspace group */
138 protected boolean isWorkspaceVisible(String wkspName
) {
139 Boolean result
= true;
140 if (ARGEO_SYSTEM_WKSP
.contains(wkspName
))
142 // Add a supplementary check to hide workspace that are not
143 // public to anonymous user
144 if (repoNode
== null) {
145 Session tmpSession
= null;
147 tmpSession
= repository
.login(wkspName
);
149 tmpSession
.checkPermission("/", "read");
150 } catch (AccessControlException e
) {
153 } catch (RepositoryException e
) {
154 throw new SlcException("Cannot list workspaces for anonymous user", e
);
156 JcrUtils
.logoutQuietly(tmpSession
);
164 * {@link Repository#login(javax.jcr.Credentials, String)} method. To be
167 * Creates a new session with correct credentials using the information
168 * contained in the corresponding repo node. It provides all UI children
169 * elements an unique entry point to retrieve a new Session. Caller must
170 * close the session when it is not in use anymore.
173 protected Session
repositoryLogin(String workspaceName
) {
175 if (workspaceName
== null)
176 workspaceName
= "main";// FIXME make it more generic
177 return repository
.login(credentials
, workspaceName
);
178 } catch (RepositoryException e
) {
179 throw new SlcException("Cannot login repository " + label
+ " with credential " + credentials
, e
);
183 public Boolean
isConnected() {
184 if (defaultSession
!= null && defaultSession
.isLive())
190 /** Exposes URI to the current repository */
191 public String
getUri() {
195 public String
getRepoNodePath() {
196 if (repoNode
== null)
200 return repoNode
.getPath();
201 } catch (RepositoryException e
) {
202 throw new SlcException("Cannot get node path for repository " + label
, e
);
207 * Exposes the local repoNode that completely define a connection to a
208 * repository (including a set of credentials). Might return null in case of
211 protected Node
getRepoNode() {
215 protected Repository
getRepository() {
219 protected Credentials
getCredentials() {
224 public String
getDescription() {
226 if (repoNode
!= null)
227 desc
= label
+ " (" + uri
+ ")";
231 public String
getLabel() {
235 public String
toString() {
236 return repoNode
!= null ? repoNode
.toString() : label
;