]> git.argeo.org Git - gpl/argeo-slc.git/blob - model/RepoElem.java
Prepare next development cycle
[gpl/argeo-slc.git] / model / RepoElem.java
1 package org.argeo.slc.client.ui.dist.model;
2
3 import java.security.AccessControlException;
4
5 import javax.jcr.Credentials;
6 import javax.jcr.Node;
7 import javax.jcr.Repository;
8 import javax.jcr.RepositoryException;
9 import javax.jcr.RepositoryFactory;
10 import javax.jcr.Session;
11
12 import org.argeo.api.cms.CmsConstants;
13 import org.argeo.cms.ArgeoNames;
14 import org.argeo.cms.jcr.CmsJcrUtils;
15 import org.argeo.cms.security.Keyring;
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;
20
21 /**
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
24 */
25 public class RepoElem extends DistParentElem {
26 // private final static CmsLog log = CmsLog.getLog(RepoElem.class);
27
28 private RepositoryFactory repositoryFactory;
29 private Keyring keyring;
30 private Credentials credentials;
31 private Session defaultSession = null;
32
33 // Defines current repo
34 private Node repoNode = null;
35 private String label;
36 private String uri;
37
38 private Repository repository;
39
40 /**
41 * Creates a RepoElement for anonymous user. The {@code RepositoryFactory}
42 * is used to enable lazy initialisation
43 */
44 public RepoElem(RepositoryFactory repoFactory, String uri, String label) {
45 super(label);
46 this.repositoryFactory = repoFactory;
47 this.uri = uri;
48 this.label = label;
49 }
50
51 /**
52 * Creates a RepoElement for an authenticated user. The
53 * {@code RepositoryFactory} and {@code Keyring} are used to enable lazy
54 * initialisation
55 *
56 */
57 public RepoElem(RepositoryFactory repoFactory, Keyring keyring, Node repoNode, String alias) {
58 super(alias);
59 this.label = alias;
60 // label = repoNode.isNodeType(NodeType.MIX_TITLE) ? repoNode
61 // .getProperty(Property.JCR_TITLE).getString() : repoNode
62 // .getName();
63 this.repoNode = repoNode;
64 this.repositoryFactory = repoFactory;
65 this.keyring = keyring;
66 try {
67 // Initialize this repo information
68 setInHome(RepoConstants.DEFAULT_JAVA_REPOSITORY_ALIAS.equals(repoNode.getName()));
69 if (inHome())
70 // Directly log and retrieve children for local repository
71 login();
72 else
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);
77 }
78 }
79
80 /** Effective login. Does nothing if the session is already there. */
81 public void login() {
82 if (isConnected())
83 return;
84
85 if (repository == null)
86 if (repoNode == null)
87 // Anonymous
88 repository = CmsJcrUtils.getRepositoryByUri(repositoryFactory, uri);
89 else {
90 repository = RepoUtils.getRepository(repositoryFactory, keyring, repoNode);
91 credentials = RepoUtils.getRepositoryCredentials(keyring, repoNode);
92 }
93
94 try {
95 // FIXME make it more generic
96 String defaultWorkspace = CmsConstants.SYS_WORKSPACE;
97 defaultSession = repository.login(credentials, defaultWorkspace);
98 refreshChildren();
99 } catch (RepositoryException e) {
100 throw new SlcException("Cannot login repository " + label + " with credential " + credentials, e);
101 }
102 }
103
104 protected void refreshChildren() {
105 try {
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))
110 continue buildWksp;
111
112 String prefix = getPrefix(workspaceName);
113 if (getChildByName(prefix) == null) {
114 WkspGroupElem wkspGpElem = new WkspGroupElem(RepoElem.this, prefix);
115 addChild(wkspGpElem);
116 }
117 }
118 } catch (RepositoryException e) {
119 throw new SlcException("Cannot list workspaces for " + repoNode, e);
120 }
121 }
122
123 @Override
124 public synchronized void dispose() {
125 JcrUtils.logoutQuietly(defaultSession);
126 super.dispose();
127 }
128
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));
134 else
135 return workspaceName;
136 }
137
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))
142 return false;
143 // Add a supplementary check to hide workspace that are not
144 // public to anonymous user
145 if (repoNode == null) {
146 Session tmpSession = null;
147 try {
148 tmpSession = repository.login(wkspName);
149 try {
150 tmpSession.checkPermission("/", "read");
151 } catch (AccessControlException e) {
152 result = false;
153 }
154 } catch (RepositoryException e) {
155 throw new SlcException("Cannot list workspaces for anonymous user", e);
156 } finally {
157 JcrUtils.logoutQuietly(tmpSession);
158 }
159 }
160 return result;
161 }
162
163 /**
164 * Actual call to the
165 * {@link Repository#login(javax.jcr.Credentials, String)} method. To be
166 * overridden.
167 *
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.
172 *
173 */
174 protected Session repositoryLogin(String workspaceName) {
175 try {
176 if (workspaceName == null)
177 workspaceName = CmsConstants.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);
181 }
182 }
183
184 public Boolean isConnected() {
185 if (defaultSession != null && defaultSession.isLive())
186 return true;
187 else
188 return false;
189 }
190
191 /** Exposes URI to the current repository */
192 public String getUri() {
193 return uri;
194 }
195
196 public String getRepoNodePath() {
197 if (repoNode == null)
198 return null;
199 else
200 try {
201 return repoNode.getPath();
202 } catch (RepositoryException e) {
203 throw new SlcException("Cannot get node path for repository " + label, e);
204 }
205 }
206
207 /**
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
210 * an anonymous user
211 */
212 protected Node getRepoNode() {
213 return repoNode;
214 }
215
216 protected Repository getRepository() {
217 return repository;
218 }
219
220 protected Credentials getCredentials() {
221 return credentials;
222 }
223
224 // META INFO
225 public String getDescription() {
226 String desc = label;
227 if (repoNode != null)
228 desc = label + " (" + uri + ")";
229 return desc;
230 }
231
232 public String getLabel() {
233 return label;
234 }
235
236 public String toString() {
237 return repoNode != null ? repoNode.toString() : label;
238 }
239 }