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