smaller changes to fix moving of taxonnodes
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / navigator / TreeNodeDropAdapterAssistant.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.navigation.navigator;
12
13 import java.util.EnumSet;
14 import java.util.HashSet;
15 import java.util.Iterator;
16 import java.util.Set;
17 import java.util.UUID;
18
19 import org.apache.log4j.Logger;
20 import org.eclipse.core.commands.operations.AbstractOperation;
21 import org.eclipse.core.commands.operations.IUndoContext;
22 import org.eclipse.core.runtime.IStatus;
23 import org.eclipse.core.runtime.Status;
24 import org.eclipse.jface.dialogs.MessageDialog;
25 import org.eclipse.jface.util.LocalSelectionTransfer;
26 import org.eclipse.jface.viewers.ISelection;
27 import org.eclipse.jface.viewers.TreeSelection;
28 import org.eclipse.swt.dnd.DropTargetEvent;
29 import org.eclipse.swt.dnd.TransferData;
30 import org.eclipse.ui.navigator.CommonDropAdapter;
31 import org.eclipse.ui.navigator.CommonDropAdapterAssistant;
32
33 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
34 import eu.etaxonomy.cdm.model.common.CdmBase;
35 import eu.etaxonomy.cdm.model.taxon.Classification;
36 import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
37 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
38 import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
39 import eu.etaxonomy.taxeditor.navigation.NavigationUtil;
40 import eu.etaxonomy.taxeditor.navigation.navigator.operation.MoveTaxonOperation;
41 import eu.etaxonomy.taxeditor.navigation.navigator.operation.RemotingMoveTaxonOperation;
42 import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
43 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
44 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
45 import eu.etaxonomy.taxeditor.store.CdmStore;
46
47 /**
48 * <p>TaxonNodeDropAdapterAssistant class.</p>
49 *
50 * @author p.ciardelli
51 * @created 03.06.2009
52 * @version 1.0
53 */
54 public class TreeNodeDropAdapterAssistant extends CommonDropAdapterAssistant implements IPostOperationEnabled {
55
56 private static final Logger logger = Logger.getLogger(TreeNodeDropAdapterAssistant.class);
57
58 /** Constant <code>ID="eu.etaxonomy.taxeditor.navigation.navig"{trunked}</code> */
59 public static final String ID = "eu.etaxonomy.taxeditor.navigation.navigator.dropassistant"; //$NON-NLS-1$
60
61 private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
62
63 /* (non-Javadoc)
64 * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#handleDrop(org.eclipse.ui.navigator.CommonDropAdapter, org.eclipse.swt.dnd.DropTargetEvent, java.lang.Object)
65 */
66 /** {@inheritDoc} */
67 @Override
68 public IStatus handleDrop(CommonDropAdapter dropAdapter,
69 DropTargetEvent dropTargetEvent, Object target) {
70
71
72 if (target instanceof ITaxonTreeNode) {
73 Set<TaxonNode> taxonNodes = getSelectedTaxa();
74 ITaxonTreeNode targetTreeNode = (ITaxonTreeNode) target;
75 if (targetTreeNode instanceof Classification){
76 targetTreeNode = ((Classification)targetTreeNode).getRootNode();
77 targetTreeNode = HibernateProxyHelper.deproxy(targetTreeNode, TaxonNode.class);
78 }
79 //if(taxonNodes != null) {
80 if (taxonNodes.size() >= 1){
81 return moveTaxon(taxonNodes, targetTreeNode);
82 /*} else{
83 if( MessageDialog.openConfirm(null, "Moving taxon", "The operation move accepted taxon to other parent is available only for a single taxon.")){
84 return null;
85 }
86 }*/
87 }
88 }
89
90 return Status.CANCEL_STATUS;
91 }
92
93 private Set<TaxonNode> getSelectedTaxa(){
94 HashSet<TaxonNode> taxonNodes = new HashSet<TaxonNode>();
95
96 ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
97 if (selection instanceof TreeSelection) {
98
99 Iterator selectionIterator = ((TreeSelection) selection).iterator();
100
101 while (selectionIterator.hasNext()){
102 Object object = selectionIterator.next();
103 if(object instanceof TaxonNode){
104 TaxonNode taxonNode = (TaxonNode) object;
105 taxonNodes.add(taxonNode);
106 }
107 }
108 }
109 return taxonNodes.size() > 0 ? taxonNodes : null;
110 }
111
112 /* (non-Javadoc)
113 * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#validateDrop(java.lang.Object, int, org.eclipse.swt.dnd.TransferData)
114 */
115 /** {@inheritDoc} */
116 @Override
117 public IStatus validateDrop(Object target, int operation,
118 TransferData transferType) {
119 if (target instanceof ITaxonTreeNode) {
120
121 // check users permissions with target taxonnode and taxon
122 if (target instanceof TaxonNode) {
123 TaxonNode targetNode = (TaxonNode)target;
124 Boolean hasTargetNodePermission = CdmStore.currentAuthentiationHasPermission(targetNode, UPDATE);
125 Boolean hasTargetTaxonPermission = CdmStore.currentAuthentiationHasPermission(targetNode.getTaxon(), UPDATE);
126
127 if(logger.isDebugEnabled()){
128 logger.debug("target: " + targetNode.getTaxon().getTitleCache());
129 }
130
131 if(!hasTargetNodePermission || ! hasTargetNodePermission){
132 if(logger.isDebugEnabled()){
133 logger.debug("CANCEL_STATUS for target node: " + hasTargetNodePermission.toString() + " " + hasTargetTaxonPermission.toString() + " ");
134 }
135 return Status.CANCEL_STATUS;
136 }
137 }
138
139 // do not allow to drop onto itself and
140 // check users permissions with all selected taxon nodes and taxa
141 for(TaxonNode taxonNode : getSelectedTaxa()){
142 logger.debug("selectedTaxa: " + taxonNode.getTaxon().getTitleCache());
143 Boolean isSameTaxonNode = taxonNode.equals(target);
144 Boolean hasTaxonNodePermission = CdmStore.currentAuthentiationHasPermission(taxonNode, UPDATE);
145 Boolean hasTaxonPermission = CdmStore.currentAuthentiationHasPermission(taxonNode.getTaxon(), UPDATE);
146 if (
147 isSameTaxonNode
148 || !hasTaxonNodePermission
149 || !hasTaxonPermission
150 ) {
151 if(logger.isDebugEnabled()){
152 logger.debug("CANCEL_STATUS for selected " + isSameTaxonNode.toString() + " " + hasTaxonNodePermission.toString() + " " + hasTaxonPermission.toString() + " ");
153 }
154 return Status.CANCEL_STATUS;
155 }
156 }
157 logger.debug("OK_STATUS");
158 return Status.OK_STATUS;
159 }
160 logger.debug("CANCEL_STATUS");
161 return Status.CANCEL_STATUS;
162 }
163
164
165 /**
166 * @param childTaxonNode
167 * @param parentTaxon
168 * @return
169 */
170 private IStatus moveTaxon(Set<TaxonNode> taxonNodes, ITaxonTreeNode targetITaxonTreeNode) {
171
172 TaxonNavigator taxonNavigator;
173 taxonNavigator = (TaxonNavigator) NavigationUtil.showView(TaxonNavigator.ID);
174
175 if(targetITaxonTreeNode instanceof TaxonNode){
176
177 TaxonNode targetTaxonNode = (TaxonNode) targetITaxonTreeNode;
178 // Make sure parent taxon does not have unsaved changes
179 if (NavigationUtil.isDirty(targetTaxonNode)){
180 MessageDialog.openWarning(NavigationUtil.getShell(), "Unsaved Parent Taxon", "There are unsaved " +
181 "changes in the parent taxon. Pleas save first.");
182 return Status.CANCEL_STATUS;
183 }
184
185 }
186 Iterator<TaxonNode> taxIterator = taxonNodes.iterator();
187 Set<UUID> uuids = new HashSet<UUID>();
188 TaxonNode node = null;
189 while(taxIterator.hasNext()){
190 node = taxIterator.next();
191 uuids.add(node.getUuid());
192 }
193 if (!PreferencesUtil.getSortNodesNaturally()){
194 IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
195 if (workspaceUndoContext == null) {
196 logger.error("Workspace undo context is null. DND operation cancelled");
197 return Status.CANCEL_STATUS;
198 }
199
200 if(CdmStore.getCurrentSessionManager().isRemoting()) {
201 AbstractOperation operation = new RemotingMoveTaxonOperation(taxonNavigator, false, uuids, (TaxonNode)targetITaxonTreeNode, true);
202 NavigationUtil.executeOperation(operation, null);
203 } else {
204 AbstractPostOperation operation = new MoveTaxonOperation
205 ("Move Taxon", workspaceUndoContext, uuids, targetITaxonTreeNode, this, taxonNavigator, true);
206 NavigationUtil.executeOperation(operation);
207 }
208
209 logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
210 return Status.OK_STATUS;
211 }else{
212 String[] buttonLables = {"Parent", "Predecessor", "Cancel"};
213 MessageDialog dialog = new MessageDialog(null, "Target node", null, "Do you want to use the target node as parent or do you want to move the taxon below the target.", MessageDialog.QUESTION_WITH_CANCEL, buttonLables, 0);
214 dialog.open();
215 int returnCode = dialog.getReturnCode();
216 if (returnCode == 0){
217 IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
218 if (workspaceUndoContext == null) {
219 logger.error("Workspace undo context is null. DND operation cancelled");
220 return Status.CANCEL_STATUS;
221 }
222
223 if(CdmStore.getCurrentSessionManager().isRemoting()) {
224 AbstractOperation operation = new RemotingMoveTaxonOperation(taxonNavigator, false, uuids, (TaxonNode)targetITaxonTreeNode, true);
225 NavigationUtil.executeOperation(operation, null);
226 } else {
227 AbstractPostOperation operation = new MoveTaxonOperation
228 ("Move Taxon", workspaceUndoContext, uuids, targetITaxonTreeNode, this, taxonNavigator, true);
229 NavigationUtil.executeOperation(operation);
230 }
231
232 logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
233 return Status.OK_STATUS;
234 }else if (returnCode == 1){
235 IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
236 if (workspaceUndoContext == null) {
237 logger.error("Workspace undo context is null. DND operation cancelled");
238 return Status.CANCEL_STATUS;
239 }
240 TaxonNode targetNode = (TaxonNode) targetITaxonTreeNode;
241
242 if(CdmStore.getCurrentSessionManager().isRemoting()) {
243 AbstractOperation operation = new RemotingMoveTaxonOperation(taxonNavigator, false, uuids, targetNode, false);
244 NavigationUtil.executeOperation(operation, null);
245 } else {
246 AbstractPostOperation operation = new MoveTaxonOperation
247 ("Move Taxon", workspaceUndoContext, uuids, targetNode, this, taxonNavigator, false);
248 NavigationUtil.executeOperation(operation);
249 }
250 logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
251 return Status.OK_STATUS;
252 } else{
253 return Status.CANCEL_STATUS;
254 }
255
256
257 }
258 }
259
260 /* (non-Javadoc)
261 * @see eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation(eu.etaxonomy.cdm.model.common.CdmBase)
262 */
263 /** {@inheritDoc} */
264 @Override
265 public boolean postOperation(CdmBase objectAffectedByOperation) {
266 return true;
267 }
268
269 /**
270 * <p>onComplete</p>
271 *
272 * @return a boolean.
273 */
274 @Override
275 public boolean onComplete() {
276 // TODO Auto-generated method stub
277 return false;
278 }
279
280 }