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