2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.taxeditor
.termtree
.e4
;
11 import java
.util
.Arrays
;
12 import java
.util
.Collection
;
13 import java
.util
.Collections
;
14 import java
.util
.UUID
;
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
.DropTargetEvent
;
23 import org
.eclipse
.swt
.dnd
.TransferData
;
25 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
26 import eu
.etaxonomy
.cdm
.model
.term
.IHasTermType
;
27 import eu
.etaxonomy
.cdm
.model
.term
.OrderedTermVocabulary
;
28 import eu
.etaxonomy
.cdm
.model
.term
.TermType
;
29 import eu
.etaxonomy
.cdm
.model
.term
.TermVocabulary
;
30 import eu
.etaxonomy
.cdm
.persistence
.dto
.TermDto
;
31 import eu
.etaxonomy
.cdm
.persistence
.dto
.TermNodeDto
;
32 import eu
.etaxonomy
.cdm
.persistence
.dto
.TermTreeDto
;
33 import eu
.etaxonomy
.taxeditor
.editor
.definedterm
.TermTransfer
;
34 import eu
.etaxonomy
.taxeditor
.editor
.definedterm
.e4
.DefinedTermDropAdapterE4
;
35 import eu
.etaxonomy
.taxeditor
.l10n
.Messages
;
36 import eu
.etaxonomy
.taxeditor
.model
.MessagingUtils
;
37 import eu
.etaxonomy
.taxeditor
.termtree
.TermNodeDtoTransfer
;
38 import eu
.etaxonomy
.taxeditor
.termtree
.e4
.operation
.AddFeatureOperation
;
39 import eu
.etaxonomy
.taxeditor
.termtree
.e4
.operation
.AddOntologyTermOperation
;
40 import eu
.etaxonomy
.taxeditor
.termtree
.e4
.operation
.MoveFeatureOperation
;
41 import eu
.etaxonomy
.taxeditor
.ui
.dialog
.selection
.TermVocabularySelectionDialog
;
42 import eu
.etaxonomy
.taxeditor
.view
.webimport
.termimport
.wrapper
.OntologyTermWrapper
;
44 public class TermTreeDtoDropAdapter
extends ViewerDropAdapter
{
46 protected ITermTreeEditor editor
;
47 private UISynchronize sync
;
49 public TermTreeDtoDropAdapter(ITermTreeEditor editor
, Viewer viewer
, UISynchronize sync
) {
56 public boolean performDrop(Object data
) {
57 Object currentTarget
= getCurrentTarget();
58 TermNodeDto target
= null;
59 if(currentTarget
instanceof TermTreeDto
){
60 target
= ((TermTreeDto
) currentTarget
).getRoot();
62 else if(currentTarget
instanceof TermNodeDto
){
63 target
= (TermNodeDto
) currentTarget
;
67 int location
= getCurrentLocation();
68 UUID parentUuid
= target
.getParentUuid();
70 TermNodeDto parent
= editor
.getNodeDtoForUuid(parentUuid
);
71 if (location
== LOCATION_BEFORE
) {
72 position
= Math
.max(0, parent
.getIndex(target
));
76 if (location
== LOCATION_AFTER
) {
77 position
= parent
.getIndex(target
)+1;
82 Collection
<Object
> droppedObjects
= Collections
.emptyList();
83 if(data
instanceof Object
[]){
84 droppedObjects
= Arrays
.asList((Object
[])data
);
86 else if(data
instanceof IStructuredSelection
){
87 droppedObjects
= ((IStructuredSelection
) data
).toList();
89 TreeViewer viewer
= (TreeViewer
) getViewer();
91 // cannot drop a feature node onto itself
92 for (Object droppedObject
: droppedObjects
) {
93 if(droppedObject
==null){
94 MessagingUtils
.warningDialog(DefinedTermDropAdapterE4
.MOVE_FAILED
, this.getClass(),
95 Messages
.FeatureTreeDropAdapter_MOVE_FAILED_SAVE_MESSAGE
);
98 if (droppedObject
.equals(target
)) {
103 for (Object droppedObject
: droppedObjects
) {
104 //check term type compatibility
105 TermType targetType
= target
.getType();
107 TermType droppedType
= null;
108 if(droppedObject
instanceof IHasTermType
){
109 droppedType
= ((IHasTermType
)droppedObject
).getTermType();
110 if(droppedType
!=null && !droppedType
.equals(targetType
) && !droppedType
.isKindOf(targetType
)){
111 MessagingUtils
.warningDialog(DefinedTermDropAdapterE4
.TERM_TYPE_ERROR_TITLE
, this, DefinedTermDropAdapterE4
.TERM_TYPE_ERROR_MESSAGE
);
115 else if(droppedObject
instanceof TermDto
){
116 droppedType
= ((TermDto
)droppedObject
).getTermType();
117 if(droppedType
!=null && !droppedType
.equals(targetType
) && !droppedType
.isKindOf(targetType
)){
118 MessagingUtils
.warningDialog(DefinedTermDropAdapterE4
.TERM_TYPE_ERROR_TITLE
, this, DefinedTermDropAdapterE4
.TERM_TYPE_ERROR_MESSAGE
);
122 if(droppedObject
instanceof TermNodeDto
){
123 if (((TermNodeDto
)droppedObject
).getUuid() == null || target
.getUuid() == null){
124 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");
127 TermNodeDto droppedNode
= editor
.getNodeDtoForUuid(((TermNodeDto
) droppedObject
).getUuid());
128 TermNodeDto oldParent
= editor
.getNodeDtoForUuid(droppedNode
.getParentUuid());
129 boolean isCircle
= checkCircle(droppedNode
, target
);
130 if (isCircle
|| droppedNode
.equals(target
)){
133 int currentPosition
= oldParent
.getIndex(droppedNode
);
135 if(currentPosition
<position
&& target
.equals(oldParent
)){
138 MoveFeatureOperation operation
= new MoveFeatureOperation(droppedNode
.getUuid(), droppedNode
.getTerm().getUuid(), target
.getUuid(), position
, getCurrentOperation(), editor
, editor
);
140 Object o
= oldParent
.getChildren().remove(currentPosition
);
142 target
.getChildren().add(position
, droppedNode
);
143 droppedNode
.setParentUuid(target
.getUuid());
144 editor
.setNodeDtoForUuid(droppedNode
);
145 editor
.setNodeDtoForUuid(target
);
146 editor
.setNodeDtoForUuid(oldParent
);
148 editor
.addOperation(operation
);
150 else if(droppedObject
instanceof Feature
){
151 Feature droppedFeature
= (Feature
) droppedObject
;
152 AddFeatureOperation operation
= new AddFeatureOperation(
153 droppedFeature
.getUuid(),
154 target
.getUuid(), position
, editor
, editor
);
156 editor
.addOperation(operation
);
158 else if(droppedObject
instanceof TermDto
){
159 TermDto termDto
= (TermDto
) droppedObject
;
160 // check if target feature tree has the same type as the dropped term
161 if(!termDto
.getTermType().equals(targetType
)){
162 MessagingUtils
.warningDialog(DefinedTermDropAdapterE4
.TERM_TYPE_ERROR_TITLE
, this, DefinedTermDropAdapterE4
.TERM_TYPE_ERROR_MESSAGE
);
165 AddFeatureOperation operation
= new AddFeatureOperation(
167 target
.getUuid(), position
, editor
, editor
);
168 TermNodeDto newDto
= new TermNodeDto(termDto
, target
, position
, target
.getTree(), null, null, null);
171 editor
.addOperation(operation
);
173 else if(droppedObject
instanceof OntologyTermWrapper
){
174 OntologyTermWrapper wrapper
= (OntologyTermWrapper
)droppedObject
;
175 TermVocabulary vocabulary
= wrapper
.getTermVocabulary();
176 if(vocabulary
==null){
177 vocabulary
= TermVocabularySelectionDialog
.select(
178 Messages
.FeatureTreeDropAdapter_CHOOSE_VOC
, viewer
.getControl().getShell(), null);
180 if(vocabulary
instanceof OrderedTermVocabulary
){
181 MessagingUtils
.warningDialog(Messages
.FeatureTreeDropAdapter_IMPORT_NOT_POSSIBLE
, this,
182 Messages
.FeatureTreeDropAdapter_ORDER_VOC_NOT_POSSIBLE
);
185 if(vocabulary
== null){
191 AddOntologyTermOperation operation
= new AddOntologyTermOperation(wrapper
, target
.getUuid(), vocabulary
, editor
, editor
);
194 editor
.addOperation(operation
);
198 editor
.getViewer().refresh();
206 private boolean checkCircle(TermNodeDto droppedNode
, TermNodeDto newParent
) {
207 boolean result
= false;
208 if (droppedNode
.getChildren().contains(newParent
) ){
211 if (newParent
.getParentUuid() != null){
212 result
= checkCircle(droppedNode
, editor
.getNodeDtoForUuid(newParent
.getParentUuid()));
220 public boolean validateDrop(Object target
, int operation
, TransferData transferData
) {
222 isSupported
= TermNodeDtoTransfer
.getInstance().isSupportedType(transferData
);
223 isSupported
|= TermTransfer
.getInstance().isSupportedType(transferData
);
224 isSupported
|= LocalSelectionTransfer
.getTransfer().isSupportedType(transferData
);
225 isSupported
&= getViewer().getInput()!=null;
226 DropTargetEvent event
= this.getCurrentEvent();
228 TermTreeDto rootTree
= null;
229 if (getSelectedObject() instanceof TermNodeDto
){
230 TermNodeDto selectedNode
= (TermNodeDto
)getSelectedObject();
231 rootTree
= selectedNode
.getTree();
233 if(target
instanceof TermTreeDto
&& getCurrentLocation()!=ViewerDropAdapter
.LOCATION_ON
){
239 if (target
instanceof TermNodeDto
&& ((TermNodeDto
)target
).getTree().isFlat() && getCurrentLocation() == LOCATION_ON
){
243 if (getSelectedObject() instanceof TermNodeDto
){
244 term
= ((TermNodeDto
)getSelectedObject()).getTerm();
245 isSupported
= checkDuplication(target
, rootTree
, term
);
249 TermTransfer transfer
= TermTransfer
.getInstance();
250 if (transfer
.getSelection() != null){
251 TermDto dto
= transfer
.getSelection();
252 isSupported
= checkDuplication(target
, rootTree
, dto
);
259 private boolean checkDuplication(Object target
, TermTreeDto rootTree
, TermDto term
) {
260 boolean isSupported
= true;
261 TermTreeDto targetTree
= null;
262 if (target
instanceof TermNodeDto
){
263 targetTree
= ((TermNodeDto
)target
).getTree();
264 }else if (target
instanceof TermTreeDto
){
265 targetTree
= (TermTreeDto
)target
;
267 if (targetTree
!= null && !targetTree
.isAllowDuplicate()){
268 for (TermDto dto
: targetTree
.getTerms()){
269 if (dto
!= null && dto
.getUuid().equals(term
.getUuid()) && !(rootTree
!= null && targetTree
.equals(rootTree
))){