]> 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/views/DistributionsView.java
Restructure Repo Dist UI
[gpl/argeo-slc.git] / plugins / org.argeo.slc.client.ui.dist / src / main / java / org / argeo / slc / client / ui / dist / views / DistributionsView.java
1 /*
2 * Copyright (C) 2007-2012 Mathieu Baudier
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.slc.client.ui.dist.views;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 import javax.jcr.Credentials;
24 import javax.jcr.Node;
25 import javax.jcr.NodeIterator;
26 import javax.jcr.Property;
27 import javax.jcr.Repository;
28 import javax.jcr.RepositoryException;
29 import javax.jcr.RepositoryFactory;
30 import javax.jcr.Session;
31 import javax.jcr.SimpleCredentials;
32 import javax.jcr.nodetype.NodeType;
33
34 import org.argeo.eclipse.ui.ErrorFeedback;
35 import org.argeo.eclipse.ui.TreeParent;
36 import org.argeo.jcr.ArgeoJcrUtils;
37 import org.argeo.jcr.ArgeoNames;
38 import org.argeo.jcr.ArgeoTypes;
39 import org.argeo.jcr.JcrUtils;
40 import org.argeo.jcr.UserJcrUtils;
41 import org.argeo.slc.SlcException;
42 import org.argeo.slc.client.ui.dist.DistPlugin;
43 import org.argeo.slc.client.ui.dist.commands.CopyWorkspace;
44 import org.argeo.slc.client.ui.dist.commands.CreateWorkspace;
45 import org.argeo.slc.client.ui.dist.commands.DeleteWorkspace;
46 import org.argeo.slc.client.ui.dist.commands.ManageWorkspaceAuth;
47 import org.argeo.slc.client.ui.dist.commands.NormalizeDistribution;
48 import org.argeo.slc.client.ui.dist.editors.DistributionEditor;
49 import org.argeo.slc.client.ui.dist.editors.DistributionEditorInput;
50 import org.argeo.slc.client.ui.dist.utils.CommandHelpers;
51 import org.argeo.slc.jcr.SlcNames;
52 import org.argeo.slc.repo.RepoConstants;
53 import org.argeo.util.security.Keyring;
54 import org.eclipse.jface.action.IMenuListener;
55 import org.eclipse.jface.action.IMenuManager;
56 import org.eclipse.jface.action.MenuManager;
57 import org.eclipse.jface.viewers.ColumnLabelProvider;
58 import org.eclipse.jface.viewers.DoubleClickEvent;
59 import org.eclipse.jface.viewers.IDoubleClickListener;
60 import org.eclipse.jface.viewers.IStructuredSelection;
61 import org.eclipse.jface.viewers.ITreeContentProvider;
62 import org.eclipse.jface.viewers.TreeViewer;
63 import org.eclipse.jface.viewers.TreeViewerColumn;
64 import org.eclipse.jface.viewers.Viewer;
65 import org.eclipse.swt.SWT;
66 import org.eclipse.swt.widgets.Composite;
67 import org.eclipse.swt.widgets.Menu;
68 import org.eclipse.swt.widgets.Tree;
69 import org.eclipse.ui.IWorkbenchWindow;
70 import org.eclipse.ui.PartInitException;
71 import org.eclipse.ui.part.ViewPart;
72
73 /**
74 * Browse and manipulate distributions (like merge, rename, etc.). Only support
75 * one single repository currently.
76 */
77 public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames {
78 // private final static Log log =
79 // LogFactory.getLog(DistributionsView.class);
80 public final static String ID = DistPlugin.ID + ".distributionsView";
81
82 private Repository nodeRepository;
83 private RepositoryFactory repositoryFactory;
84 private Keyring keyring;
85
86 private TreeViewer viewer;
87
88 // private List<RepositoryElem> repositories = new
89 // ArrayList<DistributionsView.RepositoryElem>();
90
91 // private Session nodeSession = null;
92
93 @Override
94 public void createPartControl(Composite parent) {
95 // Define the TableViewer
96 viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
97 | SWT.FULL_SELECTION | SWT.BORDER);
98
99 TreeViewerColumn col = new TreeViewerColumn(viewer, SWT.NONE);
100 col.getColumn().setWidth(200);
101 // col.getColumn().setText("Workspace");
102 col.setLabelProvider(new ColumnLabelProvider() {
103 @Override
104 public String getText(Object element) {
105 if (element instanceof RepoElem)
106 return ((RepoElem) element).getLabel();
107 return element.toString();
108 }
109 });
110
111 final Tree table = viewer.getTree();
112 table.setHeaderVisible(false);
113 table.setLinesVisible(false);
114
115 viewer.setContentProvider(new DistributionsContentProvider());
116 viewer.addDoubleClickListener(new DistributionsDCL());
117
118 MenuManager menuManager = new MenuManager();
119 Menu menu = menuManager.createContextMenu(viewer.getTree());
120 menuManager.addMenuListener(new IMenuListener() {
121 public void menuAboutToShow(IMenuManager manager) {
122 contextMenuAboutToShow(manager);
123 }
124 });
125 viewer.getTree().setMenu(menu);
126 getSite().registerContextMenu(menuManager, viewer);
127
128 Session nodeSession = null;
129 try {
130 nodeSession = nodeRepository.login();
131
132 // make sure base directory is available
133 Node repos = JcrUtils.mkdirs(nodeSession,
134 UserJcrUtils.getUserHome(nodeSession).getPath()
135 + RepoConstants.REPOSITORIES_BASE_PATH);
136 nodeSession.save();
137
138 // register default local java repository
139 String alias = RepoConstants.DEFAULT_JAVA_REPOSITORY_ALIAS;
140 Repository javaRepository = ArgeoJcrUtils.getRepositoryByAlias(
141 repositoryFactory, alias);
142 if (javaRepository != null) {
143 if (!repos.hasNode(alias)) {
144 Node repoNode = repos.addNode(alias,
145 ArgeoTypes.ARGEO_REMOTE_REPOSITORY);
146 repoNode.setProperty(ARGEO_URI, alias);
147 repoNode.addMixin(NodeType.MIX_TITLE);
148 repoNode.setProperty(Property.JCR_TITLE, "vm://" + alias);
149 nodeSession.save();
150 }
151 }
152 } catch (RepositoryException e) {
153 throw new SlcException("Cannot register repository", e);
154 } finally {
155 JcrUtils.logoutQuietly(nodeSession);
156 }
157 //
158 // try {
159 // nodeSession = nodeRepository.login();
160 // NodeIterator repos = JcrUtils.mkdirs(
161 // nodeSession,
162 // UserJcrUtils.getUserHome(nodeSession).getPath()
163 // + RepoConstants.REPOSITORIES_BASE_PATH).getNodes();
164 // while (repos.hasNext()) {
165 // Node repository = repos.nextNode();
166 // String label = null;
167 // if (repository.isNodeType(NodeType.MIX_TITLE)) {
168 // label = repository.getProperty(Property.JCR_TITLE)
169 // .getString();
170 // }
171 //
172 // if (repository.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY)) {
173 // String uri = repository.getProperty(ARGEO_URI).getString();
174 // Credentials credentials = null;
175 // if (repository.hasProperty(ARGEO_USER_ID)) {
176 // String userId = repository.getProperty(ARGEO_USER_ID)
177 // .getString();
178 // credentials = new SimpleCredentials(userId,
179 // "".toCharArray());
180 // }
181 // Repository remoteRepository = ArgeoJcrUtils
182 // .getRepositoryByUri(repositoryFactory, uri);
183 // if (label == null)
184 // label = repository.getName();
185 // repositories.add(new RepositoryElem(label,
186 // remoteRepository, credentials));
187 // }
188 // }
189 // } catch (RepositoryException e) {
190 // throw new ArgeoException("Cannot read registered repositories", e);
191 // }
192
193 // Remote
194 // String uri = null;
195 // Credentials credentials = null;
196 // Repository remoteRepository = null;
197
198 // try {
199 // uri = "http://dev.argeo.org/org.argeo.jcr.webapp/pub/java";
200 // credentials = new GuestCredentials();
201 // remoteRepository =
202 // ArgeoJcrUtils.getRepositoryByUri(repositoryFactory, uri);
203 // repositories.add(new RepositoryElem("anonymous@dev.argeo.org//java",
204 // remoteRepository, credentials));
205 // } catch (Exception e) {
206 // e.printStackTrace();
207 // }
208
209 // uri = "http://localhost:7070/org.argeo.jcr.webapp/pub/java";
210 // credentials = new GuestCredentials();
211 // remoteRepository =
212 // ArgeoJcrUtils.getRepositoryByUri(repositoryFactory, uri);
213 // repositories.add(new RepositoryElem("anonymous@localhost//java",
214 // remoteRepository, credentials));
215
216 // uri = "http://localhost:7070/org.argeo.jcr.webapp/remoting/java";
217 // credentials = new SimpleCredentials(System.getProperty("user.name"),
218 // "".toCharArray());
219 // remoteRepository =
220 // ArgeoJcrUtils.getRepositoryByUri(repositoryFactory, uri);
221 // repositories.add(new RepositoryElem("@localhost//java",
222 // remoteRepository, credentials));
223
224 viewer.setInput(nodeRepository);
225
226 }
227
228 @Override
229 public void setFocus() {
230 viewer.getTree().setFocus();
231 }
232
233 /**
234 * Force refresh of the whole view
235 */
236 public void refresh() {
237 viewer.setContentProvider(new DistributionsContentProvider());
238 }
239
240 public void setNodeRepository(Repository repository) {
241 this.nodeRepository = repository;
242 }
243
244 public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
245 this.repositoryFactory = repositoryFactory;
246 }
247
248 public void setKeyring(Keyring keyring) {
249 this.keyring = keyring;
250 }
251
252 /** Programatically configure the context menu */
253 protected void contextMenuAboutToShow(IMenuManager menuManager) {
254 IWorkbenchWindow window = DistPlugin.getDefault().getWorkbench()
255 .getActiveWorkbenchWindow();
256 // Get Current selected item :
257 Object firstElement = ((IStructuredSelection) viewer.getSelection())
258 .getFirstElement();
259
260 if (firstElement instanceof TreeParent) {
261 TreeParent tp = (TreeParent) firstElement;
262 String wsName = tp.getName();
263
264 // Build conditions depending on element type (repo or distribution
265 // for the time being)
266 boolean isDistribElem = false; // , isRepoElem = false;
267
268 // if (tp instanceof RepositoryElem){
269 // isRepoElem = true;
270 // } else
271 if (tp instanceof DistributionElem) {
272 isDistribElem = true;
273 }
274
275 // create workspace
276 CommandHelpers.refreshCommand(menuManager, window,
277 CreateWorkspace.ID, CreateWorkspace.DEFAULT_LABEL,
278 CreateWorkspace.DEFAULT_ICON_PATH, !isDistribElem);
279
280 // Normalize workspace
281 Map<String, String> params = new HashMap<String, String>();
282 params.put(NormalizeDistribution.PARAM_WORKSPACE, wsName);
283 CommandHelpers.refreshParameterizedCommand(menuManager, window,
284 NormalizeDistribution.ID,
285 NormalizeDistribution.DEFAULT_LABEL,
286 NormalizeDistribution.DEFAULT_ICON_PATH, isDistribElem,
287 params);
288
289 // Copy workspace
290 params = new HashMap<String, String>();
291 params.put(CopyWorkspace.PARAM_WORKSPACE_NAME, wsName);
292 CommandHelpers.refreshParameterizedCommand(menuManager, window,
293 CopyWorkspace.ID, CopyWorkspace.DEFAULT_LABEL,
294 CopyWorkspace.DEFAULT_ICON_PATH, isDistribElem, params);
295
296 // Delete Workspace
297 params = new HashMap<String, String>();
298 params.put(DeleteWorkspace.PARAM_WORKSPACE_NAME, wsName);
299 CommandHelpers.refreshParameterizedCommand(menuManager, window,
300 DeleteWorkspace.ID, DeleteWorkspace.DEFAULT_LABEL,
301 DeleteWorkspace.DEFAULT_ICON_PATH, isDistribElem, params);
302
303 // Manage workspace authorizations
304 params = new HashMap<String, String>();
305 params.put(ManageWorkspaceAuth.PARAM_WORKSPACE_NAME, wsName);
306 CommandHelpers.refreshParameterizedCommand(menuManager, window,
307 ManageWorkspaceAuth.ID, ManageWorkspaceAuth.DEFAULT_LABEL,
308 ManageWorkspaceAuth.DEFAULT_ICON_PATH, isDistribElem,
309 params);
310 }
311 }
312
313 private class DistributionsContentProvider implements ITreeContentProvider {
314 Session nodeSession;
315 List<RepoElem> repositories = new ArrayList<RepoElem>();
316
317 public Object[] getElements(Object input) {
318 Repository nodeRepository = (Repository) input;
319 try {
320 if (nodeSession != null)
321 dispose();
322 nodeSession = nodeRepository.login();
323
324 String reposPath = UserJcrUtils.getUserHome(nodeSession)
325 .getPath() + RepoConstants.REPOSITORIES_BASE_PATH;
326 NodeIterator repos = nodeSession.getNode(reposPath).getNodes();
327 while (repos.hasNext()) {
328 Node repoNode = repos.nextNode();
329 if (repoNode.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY)) {
330 repositories.add(new RepoElem(repoNode));
331 }
332 }
333 } catch (RepositoryException e) {
334 throw new SlcException("Cannot get base elements", e);
335 }
336 return repositories.toArray();
337 }
338
339 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
340
341 }
342
343 public Object[] getChildren(Object parentElement) {
344 if (parentElement instanceof RepoElem) {
345 return ((RepoElem) parentElement).getChildren();
346 } else if (parentElement instanceof DistributionElem) {
347 return ((DistributionElem) parentElement).getChildren();
348 }
349 return null;
350 }
351
352 public Object getParent(Object element) {
353 // TODO register repo elem in distirbution elem?
354 return null;
355 }
356
357 public boolean hasChildren(Object element) {
358 if (element instanceof RepoElem) {
359 return true;
360 } else if (element instanceof DistributionElem) {
361 return false;
362 }
363 return false;
364 }
365
366 public void dispose() {
367 for (RepoElem repoElem : repositories)
368 repoElem.dispose();
369 repositories = new ArrayList<RepoElem>();
370 JcrUtils.logoutQuietly(nodeSession);
371 }
372
373 }
374
375 // private class DistributionsContentProvider extends
376 // AbstractTreeContentProvider {
377 //
378 // public Object[] getElements(Object arg0) {
379 // return repositories.toArray();
380 // }
381 //
382 // }
383
384 private class RepoElem {
385 private Node repoNode;
386
387 private Repository repository;
388 private Credentials credentials;
389 private Session defaultSession = null;
390
391 public RepoElem(Node repoNode) {
392 this.repoNode = repoNode;
393 }
394
395 /** Lazily connects to repository */
396 protected void connect() {
397 if (defaultSession != null)
398 return;
399
400 try {
401 if (repoNode.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY)) {
402 String uri = repoNode.getProperty(ARGEO_URI).getString();
403 if (uri.startsWith("http")) {// http, https
404 if (repoNode.hasProperty(ARGEO_USER_ID)) {
405 String userId = repoNode.getProperty(ARGEO_USER_ID)
406 .getString();
407 char[] password = keyring.getAsChars(repoNode
408 .getPath() + '/' + ARGEO_PASSWORD);
409 credentials = new SimpleCredentials(userId,
410 password);
411 }
412 repository = ArgeoJcrUtils.getRepositoryByUri(
413 repositoryFactory, uri);
414 } else {// alias
415 String alias = uri;
416 repository = ArgeoJcrUtils.getRepositoryByAlias(
417 repositoryFactory, alias);
418 credentials = null;
419 }
420 defaultSession = repository.login(credentials);
421 }
422 } catch (RepositoryException e) {
423 throw new SlcException("Cannot connect to repository "
424 + repoNode, e);
425 }
426 }
427
428 public String getLabel() {
429 try {
430 if (repoNode.isNodeType(NodeType.MIX_TITLE)) {
431 return repoNode.getProperty(Property.JCR_TITLE).getString();
432 } else {
433 return repoNode.getName();
434 }
435 } catch (RepositoryException e) {
436 throw new SlcException("Cannot read label of " + repoNode, e);
437 }
438 }
439
440 public String toString() {
441 return repoNode.toString();
442 }
443
444 public Object[] getChildren() {
445 connect();
446 try {
447 String[] workspaceNames = defaultSession.getWorkspace()
448 .getAccessibleWorkspaceNames();
449 List<DistributionElem> distributionElems = new ArrayList<DistributionElem>();
450 for (String workspace : workspaceNames)
451 distributionElems.add(new DistributionElem(repository,
452 workspace, credentials));
453 return distributionElems.toArray();
454 } catch (RepositoryException e) {
455 throw new SlcException(
456 "Cannot list workspaces for " + repoNode, e);
457 }
458 }
459
460 public void dispose() {
461 JcrUtils.logoutQuietly(defaultSession);
462 }
463 }
464
465 /** Wraps a repository **/
466 // private static class RepositoryElem extends TreeParent {
467 // // private final Repository repository;
468 // private Session defaultSession;
469 //
470 // public RepositoryElem(String name, Repository repository,
471 // Credentials credentials) {
472 // super(name);
473 // try {
474 // defaultSession = repository.login(credentials);
475 // String[] workspaceNames = defaultSession.getWorkspace()
476 // .getAccessibleWorkspaceNames();
477 // for (String workspace : workspaceNames)
478 // addChild(new DistributionElem(repository, workspace,
479 // credentials));
480 // } catch (RepositoryException e) {
481 // ErrorFeedback.show("Cannot log to repository", e);
482 // }
483 // }
484 //
485 // @Override
486 // public synchronized void dispose() {
487 // if (log.isTraceEnabled())
488 // log.trace("Disposing RepositoryElement");
489 // JcrUtils.logoutQuietly(defaultSession);
490 // super.dispose();
491 // }
492 // }
493
494 private static class DistributionElem extends TreeParent {
495 private final String workspaceName;
496 private final Repository repository;
497 private final Credentials credentials;
498
499 public DistributionElem(Repository repository, String workspaceName,
500 Credentials credentials) {
501 super(workspaceName);
502 this.workspaceName = workspaceName;
503 this.repository = repository;
504 this.credentials = credentials;
505 }
506
507 public String getWorkspaceName() {
508 return workspaceName;
509 }
510
511 public Repository getRepository() {
512 return repository;
513 }
514
515 public Credentials getCredentials() {
516 return credentials;
517 }
518 }
519
520 @Override
521 public void dispose() {
522 // for (RepositoryElem re : repositories)
523 // re.dispose();
524 super.dispose();
525 }
526
527 private class DistributionsDCL implements IDoubleClickListener {
528
529 public void doubleClick(DoubleClickEvent event) {
530 if (event.getSelection() == null || event.getSelection().isEmpty())
531 return;
532 Object obj = ((IStructuredSelection) event.getSelection())
533 .getFirstElement();
534 if (obj instanceof DistributionElem) {
535 DistributionElem distributionElem = (DistributionElem) obj;
536 DistributionEditorInput dei = new DistributionEditorInput(
537 distributionElem.getName(),
538 distributionElem.getRepository(),
539 distributionElem.getWorkspaceName(),
540 distributionElem.getCredentials());
541 try {
542 DistPlugin.getDefault().getWorkbench()
543 .getActiveWorkbenchWindow().getActivePage()
544 .openEditor(dei, DistributionEditor.ID);
545 } catch (PartInitException e) {
546 ErrorFeedback.show("Cannot open editor for "
547 + distributionElem.getWorkspaceName(), e);
548 }
549 }
550 }
551 }
552 }