]> git.argeo.org Git - gpl/argeo-slc.git/blob - plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/RepoElem.java
Fix licence management
[gpl/argeo-slc.git] / plugins / org.argeo.slc.client.ui.dist / src / main / java / 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.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;
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,
57 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
69 .equals(repoNode.getName()));
70 if (inHome())
71 // Directly log and retrieve children for local repository
72 login();
73 else
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);
78 }
79 }
80
81 /** Effective login. Does nothing if the session is already there. */
82 public void login() {
83 if (isConnected())
84 return;
85
86 if (repository == null)
87 if (repoNode == null)
88 // Anonymous
89 repository = ArgeoJcrUtils.getRepositoryByUri(
90 repositoryFactory, uri);
91 else {
92 repository = RepoUtils.getRepository(repositoryFactory,
93 keyring, repoNode);
94 credentials = RepoUtils.getRepositoryCredentials(keyring,
95 repoNode);
96 }
97
98 try {
99 defaultSession = repository.login(credentials);
100 refreshChildren();
101 } catch (RepositoryException e) {
102 throw new SlcException("Cannot login repository " + label
103 + " with credential " + credentials, e);
104 }
105 }
106
107 protected void refreshChildren() {
108 try {
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))
114 continue buildWksp;
115
116 String prefix = getPrefix(workspaceName);
117 if (getChildByName(prefix) == null) {
118 WkspGroupElem wkspGpElem = new WkspGroupElem(RepoElem.this,
119 prefix);
120 addChild(wkspGpElem);
121 }
122 }
123 } catch (RepositoryException e) {
124 throw new SlcException("Cannot list workspaces for " + repoNode, e);
125 }
126 }
127
128 @Override
129 public synchronized void dispose() {
130 JcrUtils.logoutQuietly(defaultSession);
131 super.dispose();
132 }
133
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));
140 else
141 return workspaceName;
142 }
143
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))
148 return false;
149 // Add a supplementary check to hide workspace that are not
150 // public to anonymous user
151 if (repoNode == null) {
152 Session tmpSession = null;
153 try {
154 tmpSession = repository.login(wkspName);
155 try {
156 tmpSession.checkPermission("/", "read");
157 } catch (AccessControlException e) {
158 result = false;
159 }
160 } catch (RepositoryException e) {
161 throw new SlcException(
162 "Cannot list workspaces for anonymous user", e);
163 } finally {
164 JcrUtils.logoutQuietly(tmpSession);
165 }
166 }
167 return result;
168 }
169
170 /**
171 * Actual call to the
172 * {@link Repository#login(javax.jcr.Credentials, String)} method. To be
173 * overridden.
174 *
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.
179 *
180 */
181 protected Session repositoryLogin(String workspaceName) {
182 try {
183 return repository.login(credentials, workspaceName);
184 } catch (RepositoryException e) {
185 throw new SlcException("Cannot login repository " + label
186 + " with credential " + credentials, e);
187 }
188 }
189
190 public Boolean isConnected() {
191 if (defaultSession != null && defaultSession.isLive())
192 return true;
193 else
194 return false;
195 }
196
197 /** Exposes URI to the current repository */
198 public String getUri() {
199 return uri;
200 }
201
202 public String getRepoNodePath() {
203 if (repoNode == null)
204 return null;
205 else
206 try {
207 return repoNode.getPath();
208 } catch (RepositoryException e) {
209 throw new SlcException("Cannot get node path for repository "
210 + label, e);
211 }
212 }
213
214 /**
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
217 * an anonymous user
218 */
219 protected Node getRepoNode() {
220 return repoNode;
221 }
222
223 protected Repository getRepository() {
224 return repository;
225 }
226
227 protected Credentials getCredentials() {
228 return credentials;
229 }
230
231 // META INFO
232 public String getDescription() {
233 String desc = label;
234 if (repoNode != null)
235 desc = label + " (" + uri + ")";
236 return desc;
237 }
238
239 public String getLabel() {
240 return label;
241 }
242
243 public String toString() {
244 return repoNode != null ? repoNode.toString() : label;
245 }
246 }