2 * Copyright (C) 2007-2012 Mathieu Baudier
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.slc
.client
.ui
.dist
.views
;
18 import java
.util
.ArrayList
;
19 import java
.util
.HashMap
;
20 import java
.util
.List
;
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
;
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
;
74 * Browse and manipulate distributions (like merge, rename, etc.). Only support
75 * one single repository currently.
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";
82 private Repository nodeRepository
;
83 private RepositoryFactory repositoryFactory
;
84 private Keyring keyring
;
86 private TreeViewer viewer
;
88 // private List<RepositoryElem> repositories = new
89 // ArrayList<DistributionsView.RepositoryElem>();
91 // private Session nodeSession = null;
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
);
99 TreeViewerColumn col
= new TreeViewerColumn(viewer
, SWT
.NONE
);
100 col
.getColumn().setWidth(200);
101 // col.getColumn().setText("Workspace");
102 col
.setLabelProvider(new ColumnLabelProvider() {
104 public String
getText(Object element
) {
105 if (element
instanceof RepoElem
)
106 return ((RepoElem
) element
).getLabel();
107 return element
.toString();
111 final Tree table
= viewer
.getTree();
112 table
.setHeaderVisible(false);
113 table
.setLinesVisible(false);
115 viewer
.setContentProvider(new DistributionsContentProvider());
116 viewer
.addDoubleClickListener(new DistributionsDCL());
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
);
125 viewer
.getTree().setMenu(menu
);
126 getSite().registerContextMenu(menuManager
, viewer
);
128 Session nodeSession
= null;
130 nodeSession
= nodeRepository
.login();
132 // make sure base directory is available
133 Node repos
= JcrUtils
.mkdirs(nodeSession
,
134 UserJcrUtils
.getUserHome(nodeSession
).getPath()
135 + RepoConstants
.REPOSITORIES_BASE_PATH
);
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
);
152 } catch (RepositoryException e
) {
153 throw new SlcException("Cannot register repository", e
);
155 JcrUtils
.logoutQuietly(nodeSession
);
159 // nodeSession = nodeRepository.login();
160 // NodeIterator repos = JcrUtils.mkdirs(
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)
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)
178 // credentials = new SimpleCredentials(userId,
179 // "".toCharArray());
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));
189 // } catch (RepositoryException e) {
190 // throw new ArgeoException("Cannot read registered repositories", e);
194 // String uri = null;
195 // Credentials credentials = null;
196 // Repository remoteRepository = null;
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();
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));
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));
224 viewer
.setInput(nodeRepository
);
229 public void setFocus() {
230 viewer
.getTree().setFocus();
234 * Force refresh of the whole view
236 public void refresh() {
237 viewer
.setContentProvider(new DistributionsContentProvider());
240 public void setNodeRepository(Repository repository
) {
241 this.nodeRepository
= repository
;
244 public void setRepositoryFactory(RepositoryFactory repositoryFactory
) {
245 this.repositoryFactory
= repositoryFactory
;
248 public void setKeyring(Keyring keyring
) {
249 this.keyring
= keyring
;
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())
260 if (firstElement
instanceof TreeParent
) {
261 TreeParent tp
= (TreeParent
) firstElement
;
262 String wsName
= tp
.getName();
264 // Build conditions depending on element type (repo or distribution
265 // for the time being)
266 boolean isDistribElem
= false; // , isRepoElem = false;
268 // if (tp instanceof RepositoryElem){
269 // isRepoElem = true;
271 if (tp
instanceof DistributionElem
) {
272 isDistribElem
= true;
276 CommandHelpers
.refreshCommand(menuManager
, window
,
277 CreateWorkspace
.ID
, CreateWorkspace
.DEFAULT_LABEL
,
278 CreateWorkspace
.DEFAULT_ICON_PATH
, !isDistribElem
);
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
,
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
);
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
);
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
,
313 private class DistributionsContentProvider
implements ITreeContentProvider
{
315 List
<RepoElem
> repositories
= new ArrayList
<RepoElem
>();
317 public Object
[] getElements(Object input
) {
318 Repository nodeRepository
= (Repository
) input
;
320 if (nodeSession
!= null)
322 nodeSession
= nodeRepository
.login();
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
));
333 } catch (RepositoryException e
) {
334 throw new SlcException("Cannot get base elements", e
);
336 return repositories
.toArray();
339 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
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();
352 public Object
getParent(Object element
) {
353 // TODO register repo elem in distirbution elem?
357 public boolean hasChildren(Object element
) {
358 if (element
instanceof RepoElem
) {
360 } else if (element
instanceof DistributionElem
) {
366 public void dispose() {
367 for (RepoElem repoElem
: repositories
)
369 repositories
= new ArrayList
<RepoElem
>();
370 JcrUtils
.logoutQuietly(nodeSession
);
375 // private class DistributionsContentProvider extends
376 // AbstractTreeContentProvider {
378 // public Object[] getElements(Object arg0) {
379 // return repositories.toArray();
384 private class RepoElem
{
385 private Node repoNode
;
387 private Repository repository
;
388 private Credentials credentials
;
389 private Session defaultSession
= null;
391 public RepoElem(Node repoNode
) {
392 this.repoNode
= repoNode
;
395 /** Lazily connects to repository */
396 protected void connect() {
397 if (defaultSession
!= null)
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
)
407 char[] password
= keyring
.getAsChars(repoNode
408 .getPath() + '/' + ARGEO_PASSWORD
);
409 credentials
= new SimpleCredentials(userId
,
412 repository
= ArgeoJcrUtils
.getRepositoryByUri(
413 repositoryFactory
, uri
);
416 repository
= ArgeoJcrUtils
.getRepositoryByAlias(
417 repositoryFactory
, alias
);
420 defaultSession
= repository
.login(credentials
);
422 } catch (RepositoryException e
) {
423 throw new SlcException("Cannot connect to repository "
428 public String
getLabel() {
430 if (repoNode
.isNodeType(NodeType
.MIX_TITLE
)) {
431 return repoNode
.getProperty(Property
.JCR_TITLE
).getString();
433 return repoNode
.getName();
435 } catch (RepositoryException e
) {
436 throw new SlcException("Cannot read label of " + repoNode
, e
);
440 public String
toString() {
441 return repoNode
.toString();
444 public Object
[] getChildren() {
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
);
460 public void dispose() {
461 JcrUtils
.logoutQuietly(defaultSession
);
465 /** Wraps a repository **/
466 // private static class RepositoryElem extends TreeParent {
467 // // private final Repository repository;
468 // private Session defaultSession;
470 // public RepositoryElem(String name, Repository repository,
471 // Credentials credentials) {
474 // defaultSession = repository.login(credentials);
475 // String[] workspaceNames = defaultSession.getWorkspace()
476 // .getAccessibleWorkspaceNames();
477 // for (String workspace : workspaceNames)
478 // addChild(new DistributionElem(repository, workspace,
480 // } catch (RepositoryException e) {
481 // ErrorFeedback.show("Cannot log to repository", e);
486 // public synchronized void dispose() {
487 // if (log.isTraceEnabled())
488 // log.trace("Disposing RepositoryElement");
489 // JcrUtils.logoutQuietly(defaultSession);
494 private static class DistributionElem
extends TreeParent
{
495 private final String workspaceName
;
496 private final Repository repository
;
497 private final Credentials credentials
;
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
;
507 public String
getWorkspaceName() {
508 return workspaceName
;
511 public Repository
getRepository() {
515 public Credentials
getCredentials() {
521 public void dispose() {
522 // for (RepositoryElem re : repositories)
527 private class DistributionsDCL
implements IDoubleClickListener
{
529 public void doubleClick(DoubleClickEvent event
) {
530 if (event
.getSelection() == null || event
.getSelection().isEmpty())
532 Object obj
= ((IStructuredSelection
) event
.getSelection())
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());
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
);