Fix infinite loop when moving terms with parent terms
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / editor / definedterm / e4 / DefinedTermDropAdapterE4.java
1 /**
2 * Copyright (C) 2009 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 package eu.etaxonomy.taxeditor.editor.definedterm.e4;
10
11 import java.util.ArrayList;
12 import java.util.Collection;
13
14 import javax.inject.Inject;
15
16 import org.eclipse.e4.ui.di.UISynchronize;
17 import org.eclipse.jface.util.LocalSelectionTransfer;
18 import org.eclipse.jface.viewers.IStructuredSelection;
19 import org.eclipse.jface.viewers.StructuredSelection;
20 import org.eclipse.jface.viewers.ViewerDropAdapter;
21 import org.eclipse.swt.dnd.TransferData;
22
23 import eu.etaxonomy.cdm.persistence.dto.AbstractTermDto;
24 import eu.etaxonomy.cdm.persistence.dto.TermDto;
25 import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
26 import eu.etaxonomy.taxeditor.editor.definedterm.operation.MoveDefinedTermOperation;
27 import eu.etaxonomy.taxeditor.l10n.Messages;
28 import eu.etaxonomy.taxeditor.model.AbstractUtility;
29 import eu.etaxonomy.taxeditor.model.MessagingUtils;
30 import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
31 import eu.etaxonomy.taxeditor.store.StoreUtil;
32 import eu.etaxonomy.taxeditor.ui.EditViewerDropAdapter;
33
34 /**
35 *
36 * @author pplitzner
37 * @since Aug 22, 2017
38 *
39 */
40 public class DefinedTermDropAdapterE4 extends EditViewerDropAdapter {
41
42
43 public static final String TERM_TYPE_ERROR_TITLE = Messages.DefinedTermDropAdapterE4_TERM_TYPE_ERROR_TITLE;
44 public static final String TERM_TYPE_ERROR_MESSAGE = Messages.DefinedTermDropAdapterE4_TERM_TYPE_ERROR_MESSAGE;
45
46 public static final String MOVE_FAILED = Messages.DefinedTermDropAdapterE4_MOVE_FAILED;
47
48 private static final String MOVE_FAILED_MESSAGE = Messages.DefinedTermDropAdapterE4_MOVE_FAILED_MESSAGE;
49
50 private final DefinedTermEditorE4 editor;
51
52 @Inject
53 private UISynchronize sync;
54
55 @Inject
56 protected DefinedTermDropAdapterE4(DefinedTermEditorE4 editor) {
57 super(editor.getViewer());
58 this.editor = editor;
59 }
60
61 @Override
62 public boolean performDrop(Object data) {
63 if(StoreUtil.promptCheckIsDirty(editor) || data == null){
64 return false;
65 }
66 AbstractTermDto target = (AbstractTermDto) getCurrentTarget();//can be vocab
67 int currentLocation = getCurrentLocation();
68 IStructuredSelection droppedTerms = (IStructuredSelection) data;
69 Collection<TermDto> sourceTerms = new ArrayList<>(); //Arrays.asList(droppedElements)
70
71 for (Object droppedTerm : droppedTerms.toList()) {
72 TermDto term = (TermDto) droppedTerm;
73 sourceTerms.add(term);
74 }
75 // cannot drop a term onto itself or at its own children
76 for (Object droppedObject : sourceTerms) {
77 if(droppedObject==null){
78 MessagingUtils.warningDialog(MOVE_FAILED, this.getClass(),
79 Messages.DefinedTermDropAdapterE4_MOVE_FAILED_SAVE_MESSAGE);
80 return false;
81 }
82 if (droppedObject.equals(target)) {
83 MessagingUtils.warningDialog(MOVE_FAILED, this.getClass(),
84 MOVE_FAILED_MESSAGE);
85 return false;
86 }
87 if(target instanceof TermDto){
88 TermDto parentTerm = (TermDto)target;
89 //check term type compatibility
90 if(droppedObject instanceof TermDto && !((TermDto) droppedObject).getTermType().equals(parentTerm.getTermType())){
91 MessagingUtils.warningDialog(TERM_TYPE_ERROR_TITLE, this, TERM_TYPE_ERROR_MESSAGE);
92 return false;
93 }
94
95 TermDto partOfDto = parentTerm.getPartOfDto();
96 if(partOfDto!=null && partOfDto.equals(droppedObject)){
97 MessagingUtils.warningDialog(MOVE_FAILED, this.getClass(),
98 MOVE_FAILED_MESSAGE);
99 return false;
100 }
101 TermDto kindOfDto = parentTerm.getKindOfDto();
102 if(kindOfDto!=null && kindOfDto.equals(droppedObject)){
103 MessagingUtils.warningDialog(MOVE_FAILED, this.getClass(),
104 MOVE_FAILED_MESSAGE);
105 return false;
106 }
107 }
108 else if(target instanceof TermVocabularyDto){
109 TermVocabularyDto vocDto = (TermVocabularyDto)target;
110 //check term type compatibility
111 if(droppedObject instanceof TermDto && !((TermDto) droppedObject).getTermType().equals(vocDto.getTermType())){
112 MessagingUtils.warningDialog(TERM_TYPE_ERROR_TITLE, this, TERM_TYPE_ERROR_MESSAGE);
113 return false;
114 }
115 }
116 }
117 AbstractPostOperation operation = new MoveDefinedTermOperation(Messages.DefinedTermDropAdapterE4_MOVE_DESCRIPTIONS,
118 StoreUtil.getUndoContext(),
119 target,
120 sourceTerms,
121 editor,
122 currentLocation);
123 AbstractUtility.executeOperation(operation, sync);
124 // select the moved objects
125 editor.getViewer().setSelection(new StructuredSelection(sourceTerms));
126
127 return true;
128 }
129
130 @Override
131 public boolean validateDrop(Object target, int operation,
132 TransferData transferType) {
133 boolean valid = LocalSelectionTransfer.getTransfer().isSupportedType(transferType)
134 && target instanceof AbstractTermDto;
135 if(target instanceof TermVocabularyDto && getCurrentLocation()!=ViewerDropAdapter.LOCATION_ON){
136 valid = false;
137 }
138 return valid;
139 }
140
141 }