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