]> 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
09119524f5dea4aa817c6c6ef0f73d2929b56428
[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 Argeo GmbH
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.HashMap;
19 import java.util.Map;
20
21 import javax.jcr.Repository;
22 import javax.jcr.RepositoryException;
23
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.UnregisterRemoteRepo;
41 import org.argeo.slc.client.ui.dist.controllers.DistTreeComparator;
42 import org.argeo.slc.client.ui.dist.controllers.DistTreeComparer;
43 import org.argeo.slc.client.ui.dist.controllers.DistTreeContentProvider;
44 import org.argeo.slc.client.ui.dist.controllers.DistTreeDoubleClickListener;
45 import org.argeo.slc.client.ui.dist.controllers.DistTreeLabelProvider;
46 import org.argeo.slc.client.ui.dist.model.DistParentElem;
47 import org.argeo.slc.client.ui.dist.model.RepoElem;
48 import org.argeo.slc.client.ui.dist.model.WkspGroupElem;
49 import org.argeo.slc.client.ui.dist.model.WorkspaceElem;
50 import org.argeo.slc.client.ui.dist.utils.CommandHelpers;
51 import org.argeo.slc.jcr.SlcNames;
52 import org.eclipse.jface.action.IContributionItem;
53 import org.eclipse.jface.action.IMenuListener;
54 import org.eclipse.jface.action.IMenuManager;
55 import org.eclipse.jface.action.MenuManager;
56 import org.eclipse.jface.dialogs.MessageDialog;
57 import org.eclipse.jface.viewers.IStructuredSelection;
58 import org.eclipse.jface.viewers.TreeViewer;
59 import org.eclipse.jface.viewers.TreeViewerColumn;
60 import org.eclipse.jface.viewers.Viewer;
61 import org.eclipse.jface.viewers.ViewerComparator;
62 import org.eclipse.jface.viewers.ViewerDropAdapter;
63 import org.eclipse.swt.SWT;
64 import org.eclipse.swt.dnd.DND;
65 import org.eclipse.swt.dnd.DragSourceAdapter;
66 import org.eclipse.swt.dnd.DragSourceEvent;
67 import org.eclipse.swt.dnd.TextTransfer;
68 import org.eclipse.swt.dnd.Transfer;
69 import org.eclipse.swt.dnd.TransferData;
70 import org.eclipse.swt.widgets.Composite;
71 import org.eclipse.swt.widgets.Menu;
72 import org.eclipse.swt.widgets.Tree;
73 import org.eclipse.ui.IWorkbenchWindow;
74 import org.eclipse.ui.part.ViewPart;
75
76 /**
77 * Browse, manipulate and manage distributions across multiple repositories
78 * (like fetch, merge, publish, etc.).
79 */
80 public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames {
81 // private final static Log log =
82 // LogFactory.getLog(DistributionsView.class);
83
84 public final static String ID = DistPlugin.ID + ".distributionsView";
85
86 /* DEPENDENCY INJECTION */
87 private Repository nodeRepository;
88 private DistTreeContentProvider treeContentProvider;
89
90 private TreeViewer viewer;
91
92 @Override
93 public void createPartControl(Composite parent) {
94 // Define the TableViewer
95 viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
96 | SWT.FULL_SELECTION | SWT.BORDER);
97
98 TreeViewerColumn col = new TreeViewerColumn(viewer, SWT.NONE);
99 col.getColumn().setWidth(400);
100 col.setLabelProvider(new DistTreeLabelProvider());
101
102 final Tree tree = viewer.getTree();
103 tree.setHeaderVisible(false);
104 tree.setLinesVisible(false);
105
106 // viewer.setContentProvider(new DistTreeContentProvider());
107 viewer.setContentProvider(treeContentProvider);
108 viewer.addDoubleClickListener(new DistTreeDoubleClickListener(viewer));
109 viewer.setComparer(new DistTreeComparer());
110
111 viewer.setComparator(new DistTreeComparator());
112
113 @SuppressWarnings("unused")
114 ViewerComparator vc = viewer.getComparator();
115
116 // Enable retrieving current tree selected items from outside the view
117 getSite().setSelectionProvider(viewer);
118
119 // Drag and drop
120 Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
121 int operations = DND.DROP_COPY | DND.DROP_MOVE;
122 viewer.addDragSupport(operations, tt, new ViewDragListener());
123 viewer.addDropSupport(operations, tt, new ViewDropListener(viewer));
124
125 MenuManager menuManager = new MenuManager();
126 Menu menu = menuManager.createContextMenu(viewer.getTree());
127 menuManager.addMenuListener(new IMenuListener() {
128 public void menuAboutToShow(IMenuManager manager) {
129 contextMenuAboutToShow(manager);
130 }
131 });
132 viewer.getTree().setMenu(menu);
133 getSite().registerContextMenu(menuManager, viewer);
134
135 // Initialize
136 refresh();
137 }
138
139 /** Programatically configure the context menu */
140 protected void contextMenuAboutToShow(IMenuManager menuManager) {
141 IWorkbenchWindow window = DistPlugin.getDefault().getWorkbench()
142 .getActiveWorkbenchWindow();
143
144 try {
145 // Most of the implemented commands support only one selected
146 // element
147 boolean singleElement = ((IStructuredSelection) viewer
148 .getSelection()).size() == 1;
149 // Get Current selected item :
150 Object firstElement = ((IStructuredSelection) viewer.getSelection())
151 .getFirstElement();
152
153 if (firstElement instanceof TreeParent
154 || firstElement instanceof DistParentElem) {
155
156 String targetRepoPath = null, workspaceName = null, workspacePrefix = null;
157 // String targetRepoUri = null;
158 // Build conditions depending on element type
159 boolean isDistribElem = false, isRepoElem = false, isDistribGroupElem = false;
160 boolean isHomeRepo = false, isReadOnly = true;
161
162 RepoElem re = null;
163
164 if (firstElement instanceof WorkspaceElem) {
165 WorkspaceElem de = (WorkspaceElem) firstElement;
166 re = (RepoElem) de.getParent().getParent();
167 isDistribElem = true;
168 isReadOnly = de.isReadOnly();
169 workspaceName = de.getWorkspaceName();
170 } else if (firstElement instanceof RepoElem) {
171 re = (RepoElem) firstElement;
172 isRepoElem = true;
173 isHomeRepo = re.inHome();
174 isReadOnly = re.isReadOnly();
175 } else if (firstElement instanceof WkspGroupElem) {
176 WkspGroupElem wge = (WkspGroupElem) firstElement;
177 isReadOnly = wge.isReadOnly();
178 isDistribGroupElem = true;
179 re = (RepoElem) wge.getParent();
180 workspacePrefix = wge.getName();
181 }
182
183 // TODO add case for goups
184
185 if (re != null) {
186 // targetRepoUri = re.getUri();
187 targetRepoPath = re.getRepoNode().getPath();
188 }
189
190 // Display repo info
191 CommandUtils.refreshCommand(menuManager, window,
192 DisplayRepoInformation.ID,
193 DisplayRepoInformation.DEFAULT_LABEL,
194 DisplayRepoInformation.DEFAULT_ICON, isRepoElem
195 && singleElement);
196
197 // create workspace
198 Map<String, String> params = new HashMap<String, String>();
199 params.put(CreateWorkspace.PARAM_TARGET_REPO_PATH,
200 targetRepoPath);
201 params.put(CreateWorkspace.PARAM_WORKSPACE_PREFIX,
202 workspacePrefix);
203 CommandUtils.refreshParametrizedCommand(menuManager, window,
204 CreateWorkspace.ID, CreateWorkspace.DEFAULT_LABEL,
205 CreateWorkspace.DEFAULT_ICON,
206 (isRepoElem || isDistribGroupElem) && singleElement
207 && !isReadOnly, params);
208
209 // Register a remote repository
210 CommandUtils.refreshCommand(menuManager, window,
211 RegisterRepository.ID,
212 RegisterRepository.DEFAULT_LABEL,
213 RegisterRepository.DEFAULT_ICON, isRepoElem
214 && singleElement);
215
216 // Unregister a remote repository
217 params = new HashMap<String, String>();
218 params.put(UnregisterRemoteRepo.PARAM_REPO_PATH, targetRepoPath);
219 CommandUtils.refreshParametrizedCommand(menuManager, window,
220 UnregisterRemoteRepo.ID,
221 UnregisterRemoteRepo.DEFAULT_LABEL,
222 UnregisterRemoteRepo.DEFAULT_ICON, isRepoElem
223 && !isHomeRepo && singleElement, params);
224
225 // Fetch repository
226 params = new HashMap<String, String>();
227 params.put(Fetch.PARAM_TARGET_REPO_PATH, targetRepoPath);
228 CommandUtils.refreshParametrizedCommand(menuManager, window,
229 Fetch.ID, Fetch.DEFAULT_LABEL, Fetch.DEFAULT_ICON,
230 isRepoElem && isHomeRepo && singleElement
231 && !isReadOnly, params);
232
233 // Normalize workspace
234 params = new HashMap<String, String>();
235 params.put(NormalizeWorkspace.PARAM_TARGET_REPO_PATH,
236 targetRepoPath);
237 params.put(NormalizeWorkspace.PARAM_WORKSPACE_NAME,
238 workspaceName);
239
240 CommandUtils.refreshParametrizedCommand(menuManager, window,
241 NormalizeWorkspace.ID, "Normalize...",
242 NormalizeWorkspace.DEFAULT_ICON, isDistribElem
243 && singleElement && !isReadOnly, params);
244
245 // Copy workspace
246 params = new HashMap<String, String>();
247 params.put(CopyWorkspace.PARAM_TARGET_REPO_PATH, targetRepoPath);
248 params.put(CopyWorkspace.PARAM_SOURCE_WORKSPACE_NAME,
249 workspaceName);
250 CommandUtils.refreshParametrizedCommand(menuManager, window,
251 CopyWorkspace.ID, CopyWorkspace.DEFAULT_LABEL,
252 CopyWorkspace.DEFAULT_ICON, isDistribElem
253 && singleElement, params);
254
255 // Clear Workspace
256 params = new HashMap<String, String>();
257 params.put(DeleteWorkspace.PARAM_TARGET_REPO_PATH,
258 targetRepoPath);
259 params.put(DeleteWorkspace.PARAM_WORKSPACE_NAME, workspaceName);
260 CommandUtils.refreshParametrizedCommand(menuManager, window,
261 DeleteWorkspace.ID, DeleteWorkspace.DEFAULT_LABEL,
262 DeleteWorkspace.DEFAULT_ICON, isDistribElem
263 && singleElement && !isReadOnly, params);
264
265 // Advanced submenu
266 MenuManager submenu = new MenuManager("Advanced", DistPlugin.ID
267 + ".advancedSubmenu");
268 IContributionItem ici = menuManager.find(DistPlugin.ID
269 + ".advancedSubmenu");
270 if (ici != null)
271 menuManager.remove(ici);
272
273 // Publish workspace
274 params = new HashMap<String, String>();
275 params.put(PublishWorkspace.PARAM_TARGET_REPO_PATH,
276 targetRepoPath);
277 params.put(PublishWorkspace.PARAM_WORKSPACE_NAME, workspaceName);
278 CommandUtils.refreshParametrizedCommand(submenu, window,
279 PublishWorkspace.ID, PublishWorkspace.DEFAULT_LABEL,
280 PublishWorkspace.DEFAULT_ICON, isDistribElem
281 && singleElement && !isReadOnly, params);
282
283 // Normalize distribution (Legacy)
284 params = new HashMap<String, String>();
285 params.put(NormalizeDistribution.PARAM_TARGET_REPO_PATH,
286 targetRepoPath);
287 params.put(NormalizeDistribution.PARAM_WORKSPACE_NAME,
288 workspaceName);
289 CommandUtils.refreshParametrizedCommand(submenu, window,
290 NormalizeDistribution.ID,
291 NormalizeDistribution.DEFAULT_LABEL,
292 NormalizeDistribution.DEFAULT_ICON, isDistribElem
293 && singleElement && !isReadOnly, params);
294
295 if (submenu.getSize() > 0)
296 menuManager.add(submenu);
297
298 // // Manage workspace authorizations
299 // params = new HashMap<String, String>();
300 // params.put(ManageWorkspaceAuth.PARAM_WORKSPACE_NAME, wsName);
301 // CommandHelpers.refreshParameterizedCommand(menuManager,
302 // window,
303 // ManageWorkspaceAuth.ID, ManageWorkspaceAuth.DEFAULT_LABEL,
304 // ManageWorkspaceAuth.DEFAULT_ICON_PATH, isDistribElem
305 // && singleElement && !isReadOnly, params);
306 }
307 } catch (RepositoryException e) {
308 throw new SlcException("unexpected errror while "
309 + "building context menu", e);
310 }
311 }
312
313 @Override
314 public void setFocus() {
315 viewer.getTree().setFocus();
316 }
317
318 /**
319 * Force refresh of the whole view
320 */
321 public void refresh() {
322 viewer.setInput(nodeRepository);
323 viewer.expandToLevel(2);
324 }
325
326 /** Listens to drag */
327 class ViewDragListener extends DragSourceAdapter {
328 public void dragSetData(DragSourceEvent event) {
329 IStructuredSelection selection = (IStructuredSelection) viewer
330 .getSelection();
331 if (selection.getFirstElement() instanceof WorkspaceElem) {
332 WorkspaceElem de = (WorkspaceElem) selection.getFirstElement();
333 if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
334 event.data = ((RepoElem) de.getParent().getParent())
335 .getUri() + "/" + de.getWorkspaceName();
336 }
337 }
338 }
339 }
340
341 /** Listens to drop */
342 class ViewDropListener extends ViewerDropAdapter {
343
344 public ViewDropListener(Viewer viewer) {
345 super(viewer);
346 }
347
348 @Override
349 public boolean performDrop(Object data) {
350 WorkspaceElem sourceWksp = (WorkspaceElem) getSelectedObject();
351 RepoElem targetRepo = (RepoElem) getCurrentTarget();
352
353 Boolean ok = MessageDialog.openConfirm(
354 getSite().getShell(),
355 "Confirm distribution merge",
356 "Do you want to merge "
357 + sourceWksp.getWorkspaceName()
358 + " (from repo "
359 + ((RepoElem) sourceWksp.getParent().getParent())
360 .getLabel() + ") to repo "
361 + targetRepo.getLabel() + "?");
362 if (!ok)
363 return false;
364
365 try {
366 Map<String, String> params = new HashMap<String, String>();
367 params.put(MergeWorkspaces.PARAM_TARGET_REPO_PATH, targetRepo
368 .getRepoNode().getPath());
369 params.put(MergeWorkspaces.PARAM_SOURCE_REPO_PATH,
370 ((RepoElem) sourceWksp.getParent().getParent())
371 .getRepoNode().getPath());
372 params.put(MergeWorkspaces.PARAM_SOURCE_WORKSPACE_NAME,
373 sourceWksp.getWorkspaceName());
374 CommandHelpers.callCommand(RefreshDistributionsView.ID, params);
375 return true;
376 } catch (RepositoryException e) {
377 throw new SlcException("Cannot process drop from " + sourceWksp
378 + " to " + targetRepo, e);
379 }
380 }
381
382 @Override
383 public boolean validateDrop(Object target, int operation,
384 TransferData transferType) {
385 if (target instanceof RepoElem) {
386 if (getSelectedObject() instanceof WorkspaceElem) {
387 // check if not same repository
388 String srcRepoUri = ((RepoElem) ((WorkspaceElem) getSelectedObject())
389 .getParent().getParent()).getUri();
390 String targetRepoUri = ((RepoElem) target).getUri();
391 return !targetRepoUri.equals(srcRepoUri);
392 }
393 }
394 return false;
395 }
396 }
397
398 /*
399 * DEPENDENCY INJECTION
400 */
401 public void setNodeRepository(Repository repository) {
402 this.nodeRepository = repository;
403 }
404
405 public void setTreeContentProvider(
406 DistTreeContentProvider treeContentProvider) {
407 this.treeContentProvider = treeContentProvider;
408 }
409 }