2 * Copyright (C) 2007-2012 Argeo GmbH
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
.HashMap
;
21 import javax
.jcr
.Repository
;
22 import javax
.jcr
.RepositoryException
;
24 import org
.argeo
.eclipse
.ui
.TreeParent
;
25 import org
.argeo
.eclipse
.ui
.utils
.CommandUtils
;
26 import org
.argeo
.jcr
.ArgeoNames
;
27 import org
.argeo
.slc
.SlcException
;
28 import org
.argeo
.slc
.client
.ui
.dist
.DistPlugin
;
29 import org
.argeo
.slc
.client
.ui
.dist
.commands
.CopyWorkspace
;
30 import org
.argeo
.slc
.client
.ui
.dist
.commands
.CreateWorkspace
;
31 import org
.argeo
.slc
.client
.ui
.dist
.commands
.DeleteWorkspace
;
32 import org
.argeo
.slc
.client
.ui
.dist
.commands
.DisplayRepoInformation
;
33 import org
.argeo
.slc
.client
.ui
.dist
.commands
.Fetch
;
34 import org
.argeo
.slc
.client
.ui
.dist
.commands
.MergeWorkspaces
;
35 import org
.argeo
.slc
.client
.ui
.dist
.commands
.NormalizeDistribution
;
36 import org
.argeo
.slc
.client
.ui
.dist
.commands
.NormalizeWorkspace
;
37 import org
.argeo
.slc
.client
.ui
.dist
.commands
.PublishWorkspace
;
38 import org
.argeo
.slc
.client
.ui
.dist
.commands
.RefreshDistributionsView
;
39 import org
.argeo
.slc
.client
.ui
.dist
.commands
.RegisterRepository
;
40 import org
.argeo
.slc
.client
.ui
.dist
.commands
.RunInOsgi
;
41 import org
.argeo
.slc
.client
.ui
.dist
.commands
.UnregisterRemoteRepo
;
42 import org
.argeo
.slc
.client
.ui
.dist
.controllers
.DistTreeComparator
;
43 import org
.argeo
.slc
.client
.ui
.dist
.controllers
.DistTreeComparer
;
44 import org
.argeo
.slc
.client
.ui
.dist
.controllers
.DistTreeContentProvider
;
45 import org
.argeo
.slc
.client
.ui
.dist
.controllers
.DistTreeDoubleClickListener
;
46 import org
.argeo
.slc
.client
.ui
.dist
.controllers
.DistTreeLabelProvider
;
47 import org
.argeo
.slc
.client
.ui
.dist
.model
.DistParentElem
;
48 import org
.argeo
.slc
.client
.ui
.dist
.model
.RepoElem
;
49 import org
.argeo
.slc
.client
.ui
.dist
.model
.WkspGroupElem
;
50 import org
.argeo
.slc
.client
.ui
.dist
.model
.WorkspaceElem
;
51 import org
.argeo
.slc
.client
.ui
.dist
.utils
.CommandHelpers
;
52 import org
.argeo
.slc
.jcr
.SlcNames
;
53 import org
.eclipse
.jface
.action
.IContributionItem
;
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
.dialogs
.MessageDialog
;
58 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
59 import org
.eclipse
.jface
.viewers
.TreeViewer
;
60 import org
.eclipse
.jface
.viewers
.TreeViewerColumn
;
61 import org
.eclipse
.jface
.viewers
.Viewer
;
62 import org
.eclipse
.jface
.viewers
.ViewerComparator
;
63 import org
.eclipse
.jface
.viewers
.ViewerDropAdapter
;
64 import org
.eclipse
.swt
.SWT
;
65 import org
.eclipse
.swt
.dnd
.DND
;
66 import org
.eclipse
.swt
.dnd
.DragSourceAdapter
;
67 import org
.eclipse
.swt
.dnd
.DragSourceEvent
;
68 import org
.eclipse
.swt
.dnd
.TextTransfer
;
69 import org
.eclipse
.swt
.dnd
.Transfer
;
70 import org
.eclipse
.swt
.dnd
.TransferData
;
71 import org
.eclipse
.swt
.widgets
.Composite
;
72 import org
.eclipse
.swt
.widgets
.Menu
;
73 import org
.eclipse
.swt
.widgets
.Tree
;
74 import org
.eclipse
.ui
.IWorkbenchWindow
;
75 import org
.eclipse
.ui
.part
.ViewPart
;
78 * Browse, manipulate and manage distributions across multiple repositories
79 * (like fetch, merge, publish, etc.).
81 public class DistributionsView
extends ViewPart
implements SlcNames
, ArgeoNames
{
82 // private final static Log log =
83 // LogFactory.getLog(DistributionsView.class);
85 public final static String ID
= DistPlugin
.ID
+ ".distributionsView";
87 /* DEPENDENCY INJECTION */
88 private Repository nodeRepository
;
89 private DistTreeContentProvider treeContentProvider
;
91 private TreeViewer viewer
;
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(400);
101 col
.setLabelProvider(new DistTreeLabelProvider());
103 final Tree tree
= viewer
.getTree();
104 tree
.setHeaderVisible(false);
105 tree
.setLinesVisible(false);
107 // viewer.setContentProvider(new DistTreeContentProvider());
108 viewer
.setContentProvider(treeContentProvider
);
109 viewer
.addDoubleClickListener(new DistTreeDoubleClickListener(viewer
));
110 viewer
.setComparer(new DistTreeComparer());
112 viewer
.setComparator(new DistTreeComparator());
114 @SuppressWarnings("unused")
115 ViewerComparator vc
= viewer
.getComparator();
117 // Enable retrieving current tree selected items from outside the view
118 getSite().setSelectionProvider(viewer
);
121 Transfer
[] tt
= new Transfer
[] { TextTransfer
.getInstance() };
122 int operations
= DND
.DROP_COPY
| DND
.DROP_MOVE
;
123 viewer
.addDragSupport(operations
, tt
, new ViewDragListener());
124 viewer
.addDropSupport(operations
, tt
, new ViewDropListener(viewer
));
126 MenuManager menuManager
= new MenuManager();
127 Menu menu
= menuManager
.createContextMenu(viewer
.getTree());
128 menuManager
.addMenuListener(new IMenuListener() {
129 public void menuAboutToShow(IMenuManager manager
) {
130 contextMenuAboutToShow(manager
);
133 viewer
.getTree().setMenu(menu
);
134 getSite().registerContextMenu(menuManager
, viewer
);
140 /** Programatically configure the context menu */
141 protected void contextMenuAboutToShow(IMenuManager menuManager
) {
142 IWorkbenchWindow window
= DistPlugin
.getDefault().getWorkbench()
143 .getActiveWorkbenchWindow();
146 // Most of the implemented commands support only one selected
148 boolean singleElement
= ((IStructuredSelection
) viewer
149 .getSelection()).size() == 1;
150 // Get Current selected item :
151 Object firstElement
= ((IStructuredSelection
) viewer
.getSelection())
154 if (firstElement
instanceof TreeParent
155 || firstElement
instanceof DistParentElem
) {
157 String targetRepoPath
= null, workspaceName
= null, workspacePrefix
= null;
158 // String targetRepoUri = null;
159 // Build conditions depending on element type
160 boolean isDistribElem
= false, isRepoElem
= false, isDistribGroupElem
= false;
161 boolean isLocal
= false, isReadOnly
= true;
165 if (firstElement
instanceof WorkspaceElem
) {
166 WorkspaceElem de
= (WorkspaceElem
) firstElement
;
167 re
= (RepoElem
) de
.getParent().getParent();
168 isDistribElem
= true;
169 isReadOnly
= de
.isReadOnly();
170 workspaceName
= de
.getWorkspaceName();
171 isLocal
= de
.inHome();
172 } else if (firstElement
instanceof RepoElem
) {
173 re
= (RepoElem
) firstElement
;
175 isLocal
= re
.inHome();
176 isReadOnly
= re
.isReadOnly();
177 } else if (firstElement
instanceof WkspGroupElem
) {
178 WkspGroupElem wge
= (WkspGroupElem
) firstElement
;
179 isReadOnly
= wge
.isReadOnly();
180 isDistribGroupElem
= true;
181 re
= (RepoElem
) wge
.getParent();
182 workspacePrefix
= wge
.getName();
185 // TODO add case for goups
188 // targetRepoUri = re.getUri();
189 targetRepoPath
= re
.getRepoNode().getPath();
193 CommandUtils
.refreshCommand(menuManager
, window
,
194 DisplayRepoInformation
.ID
,
195 DisplayRepoInformation
.DEFAULT_LABEL
,
196 DisplayRepoInformation
.DEFAULT_ICON
, isRepoElem
200 Map
<String
, String
> params
= new HashMap
<String
, String
>();
201 params
.put(CreateWorkspace
.PARAM_TARGET_REPO_PATH
,
203 params
.put(CreateWorkspace
.PARAM_WORKSPACE_PREFIX
,
205 CommandUtils
.refreshParametrizedCommand(menuManager
, window
,
206 CreateWorkspace
.ID
, CreateWorkspace
.DEFAULT_LABEL
,
207 CreateWorkspace
.DEFAULT_ICON
,
208 (isRepoElem
|| isDistribGroupElem
) && singleElement
209 && !isReadOnly
, params
);
211 // Register a remote repository
212 CommandUtils
.refreshCommand(menuManager
, window
,
213 RegisterRepository
.ID
,
214 RegisterRepository
.DEFAULT_LABEL
,
215 RegisterRepository
.DEFAULT_ICON
, isRepoElem
218 // Unregister a remote repository
219 params
= new HashMap
<String
, String
>();
220 params
.put(UnregisterRemoteRepo
.PARAM_REPO_PATH
, targetRepoPath
);
221 CommandUtils
.refreshParametrizedCommand(menuManager
, window
,
222 UnregisterRemoteRepo
.ID
,
223 UnregisterRemoteRepo
.DEFAULT_LABEL
,
224 UnregisterRemoteRepo
.DEFAULT_ICON
, isRepoElem
225 && !isLocal
&& singleElement
, params
);
228 params
= new HashMap
<String
, String
>();
229 params
.put(Fetch
.PARAM_TARGET_REPO_PATH
, targetRepoPath
);
230 CommandUtils
.refreshParametrizedCommand(menuManager
, window
,
231 Fetch
.ID
, Fetch
.DEFAULT_LABEL
, Fetch
.DEFAULT_ICON
,
232 isRepoElem
&& isLocal
&& singleElement
233 && !isReadOnly
, params
);
235 // Normalize workspace
236 params
= new HashMap
<String
, String
>();
237 params
.put(NormalizeWorkspace
.PARAM_TARGET_REPO_PATH
,
239 params
.put(NormalizeWorkspace
.PARAM_WORKSPACE_NAME
,
242 CommandUtils
.refreshParametrizedCommand(menuManager
, window
,
243 NormalizeWorkspace
.ID
, "Normalize...",
244 NormalizeWorkspace
.DEFAULT_ICON
, isDistribElem
245 && singleElement
&& !isReadOnly
, params
);
248 params
= new HashMap
<String
, String
>();
249 params
.put(CopyWorkspace
.PARAM_TARGET_REPO_PATH
, targetRepoPath
);
250 params
.put(CopyWorkspace
.PARAM_SOURCE_WORKSPACE_NAME
,
252 CommandUtils
.refreshParametrizedCommand(menuManager
, window
,
253 CopyWorkspace
.ID
, CopyWorkspace
.DEFAULT_LABEL
,
254 CopyWorkspace
.DEFAULT_ICON
, isDistribElem
255 && singleElement
, params
);
258 params
= new HashMap
<String
, String
>();
259 params
.put(DeleteWorkspace
.PARAM_TARGET_REPO_PATH
,
261 params
.put(DeleteWorkspace
.PARAM_WORKSPACE_NAME
, workspaceName
);
262 CommandUtils
.refreshParametrizedCommand(menuManager
, window
,
263 DeleteWorkspace
.ID
, DeleteWorkspace
.DEFAULT_LABEL
,
264 DeleteWorkspace
.DEFAULT_ICON
, isDistribElem
265 && singleElement
&& !isReadOnly
, params
);
268 MenuManager submenu
= new MenuManager("Advanced", DistPlugin
.ID
269 + ".advancedSubmenu");
270 IContributionItem ici
= menuManager
.find(DistPlugin
.ID
271 + ".advancedSubmenu");
273 menuManager
.remove(ici
);
276 params
= new HashMap
<String
, String
>();
277 params
.put(PublishWorkspace
.PARAM_TARGET_REPO_PATH
,
279 params
.put(PublishWorkspace
.PARAM_WORKSPACE_NAME
, workspaceName
);
280 CommandUtils
.refreshParametrizedCommand(submenu
, window
,
281 PublishWorkspace
.ID
, PublishWorkspace
.DEFAULT_LABEL
,
282 PublishWorkspace
.DEFAULT_ICON
, isDistribElem
283 && singleElement
&& !isReadOnly
, params
);
285 // Normalize distribution (Legacy)
286 params
= new HashMap
<String
, String
>();
287 params
.put(NormalizeDistribution
.PARAM_TARGET_REPO_PATH
,
289 params
.put(NormalizeDistribution
.PARAM_WORKSPACE_NAME
,
291 CommandUtils
.refreshParametrizedCommand(submenu
, window
,
292 NormalizeDistribution
.ID
,
293 NormalizeDistribution
.DEFAULT_LABEL
,
294 NormalizeDistribution
.DEFAULT_ICON
, isDistribElem
295 && singleElement
&& !isReadOnly
, params
);
298 params
= new HashMap
<String
, String
>();
299 params
.put(RunInOsgi
.PARAM_WORKSPACE_NAME
, workspaceName
);
300 CommandUtils
.refreshParametrizedCommand(submenu
, window
,
301 RunInOsgi
.ID
, RunInOsgi
.DEFAULT_LABEL
,
302 RunInOsgi
.DEFAULT_ICON
, isDistribElem
&& singleElement
305 if (submenu
.getSize() > 0)
306 menuManager
.add(submenu
);
308 // // Manage workspace authorizations
309 // params = new HashMap<String, String>();
310 // params.put(ManageWorkspaceAuth.PARAM_WORKSPACE_NAME, wsName);
311 // CommandHelpers.refreshParameterizedCommand(menuManager,
313 // ManageWorkspaceAuth.ID, ManageWorkspaceAuth.DEFAULT_LABEL,
314 // ManageWorkspaceAuth.DEFAULT_ICON_PATH, isDistribElem
315 // && singleElement && !isReadOnly, params);
317 } catch (RepositoryException e
) {
318 throw new SlcException("unexpected errror while "
319 + "building context menu", e
);
324 public void setFocus() {
325 viewer
.getTree().setFocus();
329 * Force refresh of the whole view
331 public void refresh() {
332 viewer
.setInput(nodeRepository
);
333 viewer
.expandToLevel(2);
336 /** Listens to drag */
337 class ViewDragListener
extends DragSourceAdapter
{
338 public void dragSetData(DragSourceEvent event
) {
339 IStructuredSelection selection
= (IStructuredSelection
) viewer
341 if (selection
.getFirstElement() instanceof WorkspaceElem
) {
342 WorkspaceElem de
= (WorkspaceElem
) selection
.getFirstElement();
343 if (TextTransfer
.getInstance().isSupportedType(event
.dataType
)) {
344 event
.data
= ((RepoElem
) de
.getParent().getParent())
345 .getUri() + "/" + de
.getWorkspaceName();
351 /** Listens to drop */
352 class ViewDropListener
extends ViewerDropAdapter
{
354 public ViewDropListener(Viewer viewer
) {
359 public boolean performDrop(Object data
) {
360 WorkspaceElem sourceWksp
= (WorkspaceElem
) getSelectedObject();
361 RepoElem targetRepo
= (RepoElem
) getCurrentTarget();
363 Boolean ok
= MessageDialog
.openConfirm(
364 getSite().getShell(),
365 "Confirm distribution merge",
366 "Do you want to merge "
367 + sourceWksp
.getWorkspaceName()
369 + ((RepoElem
) sourceWksp
.getParent().getParent())
370 .getLabel() + ") to repo "
371 + targetRepo
.getLabel() + "?");
376 Map
<String
, String
> params
= new HashMap
<String
, String
>();
377 params
.put(MergeWorkspaces
.PARAM_TARGET_REPO_PATH
, targetRepo
378 .getRepoNode().getPath());
379 params
.put(MergeWorkspaces
.PARAM_SOURCE_REPO_PATH
,
380 ((RepoElem
) sourceWksp
.getParent().getParent())
381 .getRepoNode().getPath());
382 params
.put(MergeWorkspaces
.PARAM_SOURCE_WORKSPACE_NAME
,
383 sourceWksp
.getWorkspaceName());
384 CommandHelpers
.callCommand(RefreshDistributionsView
.ID
, params
);
386 } catch (RepositoryException e
) {
387 throw new SlcException("Cannot process drop from " + sourceWksp
388 + " to " + targetRepo
, e
);
393 public boolean validateDrop(Object target
, int operation
,
394 TransferData transferType
) {
395 if (target
instanceof RepoElem
) {
396 if (getSelectedObject() instanceof WorkspaceElem
) {
397 // check if not same repository
398 String srcRepoUri
= ((RepoElem
) ((WorkspaceElem
) getSelectedObject())
399 .getParent().getParent()).getUri();
400 String targetRepoUri
= ((RepoElem
) target
).getUri();
401 return !targetRepoUri
.equals(srcRepoUri
);
409 * DEPENDENCY INJECTION
411 public void setNodeRepository(Repository repository
) {
412 this.nodeRepository
= repository
;
415 public void setTreeContentProvider(
416 DistTreeContentProvider treeContentProvider
) {
417 this.treeContentProvider
= treeContentProvider
;