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