Merge branch 'hotfix/5.18.2'
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / featuretree / e4 / FeatureTreeDtoDropAdapter.java
1 /**
2 * Copyright (C) 2017 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.featuretree.e4;
10
11 import java.util.Arrays;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.UUID;
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.TreeViewer;
20 import org.eclipse.jface.viewers.Viewer;
21 import org.eclipse.jface.viewers.ViewerDropAdapter;
22 import org.eclipse.swt.dnd.TransferData;
23
24 import eu.etaxonomy.cdm.model.description.Feature;
25 import eu.etaxonomy.cdm.model.term.IHasTermType;
26 import eu.etaxonomy.cdm.model.term.OrderedTermVocabulary;
27 import eu.etaxonomy.cdm.model.term.TermType;
28 import eu.etaxonomy.cdm.model.term.TermVocabulary;
29 import eu.etaxonomy.cdm.persistence.dto.TermDto;
30 import eu.etaxonomy.cdm.persistence.dto.TermNodeDto;
31 import eu.etaxonomy.cdm.persistence.dto.TermTreeDto;
32 import eu.etaxonomy.taxeditor.editor.definedterm.TermTransfer;
33 import eu.etaxonomy.taxeditor.editor.definedterm.e4.DefinedTermDropAdapterE4;
34 import eu.etaxonomy.taxeditor.featuretree.FeatureNodeDtoTransfer;
35 import eu.etaxonomy.taxeditor.featuretree.e4.operation.AddFeatureOperation;
36 import eu.etaxonomy.taxeditor.featuretree.e4.operation.AddOntologyTermOperation;
37 import eu.etaxonomy.taxeditor.featuretree.e4.operation.MoveFeatureOperation;
38 import eu.etaxonomy.taxeditor.l10n.Messages;
39 import eu.etaxonomy.taxeditor.model.MessagingUtils;
40 import eu.etaxonomy.taxeditor.ui.dialog.selection.TermVocabularySelectionDialog;
41 import eu.etaxonomy.taxeditor.view.webimport.termimport.wrapper.OntologyTermWrapper;
42
43 public class FeatureTreeDtoDropAdapter extends ViewerDropAdapter {
44
45 protected IFeatureTreeEditor editor;
46 private UISynchronize sync;
47
48 public FeatureTreeDtoDropAdapter(IFeatureTreeEditor editor, Viewer viewer, UISynchronize sync) {
49 super(viewer);
50 this.editor = editor;
51 this.sync = sync;
52 }
53
54 @Override
55 public boolean performDrop(Object data) {
56 // if(StoreUtil.promptCheckIsDirty(editor)){
57 // return false;
58 // }
59 Object currentTarget = getCurrentTarget();
60 TermNodeDto target = null;
61 if(currentTarget instanceof TermTreeDto){
62 target = ((TermTreeDto) currentTarget).getRoot();
63 }
64 else if(currentTarget instanceof TermNodeDto){
65 target = (TermNodeDto) currentTarget;
66 }
67
68 // if (target != null && target.getUuid() == null){
69 // if(StoreUtil.promptCheckIsDirty(editor)){
70 // return false;
71 // }
72 // }
73 int position = 0;
74 int location = getCurrentLocation();
75 UUID parentUuid = target.getParentUuid();
76 if(parentUuid!=null){
77 TermNodeDto parent = editor.getNodeDtoForUuid(parentUuid);
78 if (location == LOCATION_BEFORE) {
79 position = Math.max(0, parent.getIndex(target));
80 target = parent;
81 }
82
83 if (location == LOCATION_AFTER) {
84 position = parent.getIndex(target)+1;
85 target = parent;
86 }
87 }
88
89
90 if(target==null){
91 MessagingUtils.warningDialog("", this, ""); //$NON-NLS-1$ //$NON-NLS-1$
92 return false;
93 }
94 Collection<Object> droppedObjects = Collections.emptyList();
95 if(data instanceof Object[]){
96 droppedObjects = Arrays.asList((Object[])data);
97 }
98 else if(data instanceof IStructuredSelection){
99 droppedObjects = ((IStructuredSelection) data).toList();
100 }
101 TreeViewer viewer = (TreeViewer) getViewer();
102
103 // cannot drop a feature node onto itself
104 for (Object droppedObject : droppedObjects) {
105 if(droppedObject==null){
106 MessagingUtils.warningDialog(DefinedTermDropAdapterE4.MOVE_FAILED, this.getClass(),
107 Messages.FeatureTreeDropAdapter_MOVE_FAILED_SAVE_MESSAGE);
108 return false;
109 }
110 if (droppedObject.equals(target)) {
111 return false;
112 }
113
114 }
115 for (Object droppedObject : droppedObjects) {
116 //check term type compatibility
117 TermType targetType = target.getType();
118
119 TermType droppedType = null;
120 if(droppedObject instanceof IHasTermType){
121 droppedType = ((IHasTermType)droppedObject).getTermType();
122 if(droppedType!=null && !droppedType.equals(targetType) && !droppedType.isKindOf(targetType)){
123 MessagingUtils.warningDialog(DefinedTermDropAdapterE4.TERM_TYPE_ERROR_TITLE, this, DefinedTermDropAdapterE4.TERM_TYPE_ERROR_MESSAGE);
124 continue;
125 }
126 }
127 else if(droppedObject instanceof TermDto){
128 droppedType = ((TermDto)droppedObject).getTermType();
129 if(droppedType!=null && !droppedType.equals(targetType) && !droppedType.isKindOf(targetType)){
130 MessagingUtils.warningDialog(DefinedTermDropAdapterE4.TERM_TYPE_ERROR_TITLE, this, DefinedTermDropAdapterE4.TERM_TYPE_ERROR_MESSAGE);
131 continue;
132 }
133 }
134 if(droppedObject instanceof TermNodeDto){
135 if (((TermNodeDto)droppedObject).getUuid() == null || target.getUuid() == null){
136 MessagingUtils.warningDialog("The new imported node needs to be saved first", this, "Newly created nodes can not be moved or used as parent without saving");
137 return false;
138 }
139 TermNodeDto droppedNode = editor.getNodeDtoForUuid(((TermNodeDto) droppedObject).getUuid());
140 TermNodeDto oldParent = editor.getNodeDtoForUuid(droppedNode.getParentUuid());
141 boolean isCircle = checkCircle(droppedNode, target);
142 if (isCircle || droppedNode.equals(target)){
143 return false;
144 }
145 int currentPosition = oldParent.getIndex(droppedNode);
146
147 if(currentPosition<position && target.equals(oldParent)){
148 position -= 1;
149 }
150 MoveFeatureOperation operation = new MoveFeatureOperation(droppedNode.getUuid(), droppedNode.getTerm().getUuid(), target.getUuid(), position, getCurrentOperation(), editor, editor);
151
152 Object o = oldParent.getChildren().remove(currentPosition);
153
154 target.getChildren().add(position, droppedNode);
155 droppedNode.setParentUuid(target.getUuid());
156 editor.setNodeDtoForUuid(droppedNode);
157 editor.setNodeDtoForUuid(target);
158 editor.setNodeDtoForUuid(oldParent);
159 editor.setDirty();
160 editor.addOperation(operation);
161 }
162 else if(droppedObject instanceof Feature){
163 Feature droppedFeature = (Feature) droppedObject;
164 AddFeatureOperation operation = new AddFeatureOperation(
165 droppedFeature.getUuid(),
166 target.getUuid(), position, editor, editor);
167 // AbstractUtility.executeOperation(operation, sync);
168 editor.setDirty();
169 editor.addOperation(operation);
170 }
171 else if(droppedObject instanceof TermDto){
172 TermDto termDto = (TermDto) droppedObject;
173 // check if target feature tree has the same type as the dropped term
174 if(!termDto.getTermType().equals(targetType)){
175 MessagingUtils.warningDialog(DefinedTermDropAdapterE4.TERM_TYPE_ERROR_TITLE, this, DefinedTermDropAdapterE4.TERM_TYPE_ERROR_MESSAGE);
176 continue;
177 }
178 AddFeatureOperation operation = new AddFeatureOperation(
179 termDto.getUuid(),
180 target.getUuid(), position, editor, editor);
181 // AbstractUtility.executeOperation(operation, sync);
182 TermNodeDto newDto = new TermNodeDto(termDto, target, position, target.getTree(), null, null, null);
183 // target.getChildren().add(position, newDto);
184
185 editor.setDirty();
186 editor.addOperation(operation);
187 }
188 else if(droppedObject instanceof OntologyTermWrapper){
189 OntologyTermWrapper wrapper = (OntologyTermWrapper)droppedObject;
190 TermVocabulary vocabulary = wrapper.getTermVocabulary();
191 if(vocabulary==null){
192 vocabulary = TermVocabularySelectionDialog.select(
193 Messages.FeatureTreeDropAdapter_CHOOSE_VOC, viewer.getControl().getShell(), null);
194
195 if(vocabulary instanceof OrderedTermVocabulary){
196 MessagingUtils.warningDialog(Messages.FeatureTreeDropAdapter_IMPORT_NOT_POSSIBLE, this,
197 Messages.FeatureTreeDropAdapter_ORDER_VOC_NOT_POSSIBLE);
198 return false;
199 }
200 if(vocabulary == null){
201 return false;
202 }
203 // vocabulary = new TermVocabularyDto(voc.getUuid(), voc.getRepresentations(), voc.getTermType(), voc.getTitleCache(), voc.isAllowDuplicates(), voc.isOrderRelevant(), voc.isFlat());
204
205 }
206
207
208 AddOntologyTermOperation operation = new AddOntologyTermOperation(wrapper, target.getUuid(), vocabulary, editor, editor);
209 // AbstractUtility.executeOperation(operation, sync);
210 editor.setDirty();
211 editor.addOperation(operation);
212
213 }
214 }
215 editor.getViewer().refresh();
216 // viewer.refresh();
217 return true;
218 }
219
220 /**
221 * @param droppedNode
222 * @param target
223 */
224 private boolean checkCircle(TermNodeDto droppedNode, TermNodeDto newParent) {
225 boolean result = false;
226 if (droppedNode.getChildren().contains(newParent) ){
227 return true;
228 }
229
230
231 if (newParent.getParentUuid() != null){
232 result = checkCircle(droppedNode, editor.getNodeDtoForUuid(newParent.getParentUuid()));
233
234 }
235 return result;
236
237 }
238
239 @Override
240 public boolean validateDrop(Object target, int operation, TransferData transferData) {
241 boolean
242 isSupported = FeatureNodeDtoTransfer.getInstance().isSupportedType(transferData);
243 isSupported |= TermTransfer.getInstance().isSupportedType(transferData);
244 isSupported |= LocalSelectionTransfer.getTransfer().isSupportedType(transferData);
245 isSupported &= getViewer().getInput()!=null;
246
247 if(target instanceof TermTreeDto && getCurrentLocation()!=ViewerDropAdapter.LOCATION_ON){
248 isSupported = false;
249 }
250 if (target == null){
251 isSupported = false;
252 }
253 return isSupported;
254 }
255
256
257
258 }