Project

General

Profile

Download (12.7 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2018 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.view.webimport.termimport;
10

    
11
import java.util.ArrayList;
12
import java.util.Collection;
13
import java.util.Collections;
14
import java.util.Comparator;
15
import java.util.HashSet;
16
import java.util.Iterator;
17
import java.util.List;
18
import java.util.stream.Collectors;
19

    
20
import org.eclipse.core.runtime.IProgressMonitor;
21
import org.eclipse.core.runtime.IStatus;
22
import org.eclipse.core.runtime.Status;
23
import org.eclipse.core.runtime.jobs.Job;
24
import org.eclipse.e4.ui.di.UISynchronize;
25
import org.eclipse.jface.util.LocalSelectionTransfer;
26
import org.eclipse.jface.viewers.ISelection;
27
import org.eclipse.jface.viewers.IStructuredSelection;
28
import org.eclipse.jface.viewers.StructuredSelection;
29
import org.eclipse.jface.window.Window;
30
import org.eclipse.swt.SWT;
31
import org.eclipse.swt.dnd.DND;
32
import org.eclipse.swt.dnd.DragSourceAdapter;
33
import org.eclipse.swt.dnd.DragSourceEvent;
34
import org.eclipse.swt.dnd.Transfer;
35
import org.eclipse.swt.events.FocusEvent;
36
import org.eclipse.swt.events.FocusListener;
37
import org.eclipse.swt.events.KeyAdapter;
38
import org.eclipse.swt.events.KeyEvent;
39
import org.eclipse.swt.events.SelectionAdapter;
40
import org.eclipse.swt.events.SelectionEvent;
41
import org.json.JSONException;
42

    
43
import eu.etaxonomy.cdm.common.CdmUtils;
44
import eu.etaxonomy.taxeditor.l10n.Messages;
45
import eu.etaxonomy.taxeditor.model.ColorResources;
46
import eu.etaxonomy.taxeditor.model.MessagingUtils;
47
import eu.etaxonomy.taxeditor.preference.Resources;
48
import eu.etaxonomy.taxeditor.store.StoreUtil;
49
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
50
import eu.etaxonomy.taxeditor.view.webimport.termimport.parser.TermParser;
51
import eu.etaxonomy.taxeditor.view.webimport.termimport.parser.TerminologyParser;
52
import eu.etaxonomy.taxeditor.view.webimport.termimport.requests.RequestSearch;
53
import eu.etaxonomy.taxeditor.view.webimport.termimport.requests.RequestTerminologies;
54
import eu.etaxonomy.taxeditor.view.webimport.termimport.wrapper.OntologyTermWrapper;
55
import eu.etaxonomy.taxeditor.view.webimport.termimport.wrapper.TerminologyWrapper;
56

    
57
/**
58
 * @author pplitzner
59
 * @since Apr 23, 2018
60
 *
61
 */
62
public class GfBioTerminologyImportPresenter {
63

    
64
    public static final String NO_CONNECTION_TITLE = Messages.GfBioTerminologyImportPresenter_NO_CONNECTION_TITLE;
65
    public static final String NO_CONNECTION_MESSAGE = Messages.GfBioTerminologyImportPresenter_NO_CONNECTION_MESSAGE;
66
    private static final String TXT_SEARCH_DEFAULT = Messages.GfBioTerminologyImportPresenter_TEXT_SEARCH_DEFAULT;
67

    
68
    private GfBioTerminologyImportComposite composite;
69
    private Collection<TerminologyWrapper> selectedOntologies = new ArrayList<>();
70
    private UISynchronize sync;
71
    private volatile Collection<TerminologyWrapper> availableOntologies = new HashSet<>();
72

    
73
    public GfBioTerminologyImportPresenter(GfBioTerminologyImportComposite composite, UISynchronize sync) {
74
        super();
75
        this.composite = composite;
76
        this.sync = sync;
77

    
78
        requestAvailableOntologies();
79

    
80
        composite.getBtnSearch().addSelectionListener(new SelectionAdapter() {
81
            @Override
82
            public void widgetSelected(SelectionEvent e) {
83
                if(e.widget==composite.getBtnSearch()){
84
                    search();
85
                }
86
            }
87
        });
88

    
89
        //text search
90
        composite.getTxtSearch().addKeyListener(new KeyAdapter() {
91
            @Override
92
            public void keyPressed(KeyEvent e) {
93
                if(e.keyCode==SWT.CR){
94
                    search();
95
                }
96
            }
97
        });
98
        composite.getTxtSearch().setText(TXT_SEARCH_DEFAULT);
99
        composite.getTxtSearch().setForeground(ColorResources.getColor(Resources.SEARCH_VIEW_FOREGROUND));
100
        composite.getTxtSearch().addFocusListener(new FocusListener() {
101

    
102
            @Override
103
            public void focusGained(FocusEvent e) {
104
                composite.getTxtSearch().setForeground(ColorResources.getColor(Resources.SEARCH_VIEW_FOCUS));
105
                if (TXT_SEARCH_DEFAULT.equals(composite.getTxtSearch().getText())) {
106
                    composite.getTxtSearch().setText(""); //$NON-NLS-1$
107
                }
108
            }
109

    
110
            @Override
111
            public void focusLost(FocusEvent e) {
112
                if (CdmUtils.isBlank(composite.getTxtSearch().getText())) {
113
                    composite.getTxtSearch().setForeground(ColorResources.getColor(Resources.SEARCH_VIEW_FOREGROUND));
114
                    composite.getTxtSearch().setText(TXT_SEARCH_DEFAULT);
115
                }
116
            }
117
        });
118

    
119

    
120
        composite.getBtnChooseOntology().addSelectionListener(new SelectionAdapter() {
121
            @Override
122
            public void widgetSelected(SelectionEvent e) {
123
                if(availableOntologies.isEmpty()
124
                        && MessagingUtils.confirmDialog("No Ontologies available", "There are no ontologies available. They have either not been loaded yet or the terminology service can not be reached.\nDo you want to retry loading the ontologies?")){
125
                    //re-check if ontologies have been loaded in the meantime
126
                    if(availableOntologies.isEmpty()){
127
                        requestAvailableOntologies();
128
                    }
129
                    else{
130
                        openOntologySelectionDialog(composite);
131
                    }
132
                }
133
                else{
134
                    openOntologySelectionDialog(composite);
135
                }
136
            }
137

    
138
            private void openOntologySelectionDialog(GfBioTerminologyImportComposite composite) {
139
                OntologySelectionDialog dialog = new OntologySelectionDialog(composite.getShell(), selectedOntologies, availableOntologies);
140
                if(dialog.open()==Window.OK){
141
                    selectedOntologies = dialog.getSelectedOntologies();
142
                    composite.getTextOntologies().setText(selectedOntologies.stream()
143
                            .map(wrapper->wrapper.getAcronym())
144
                            .collect(Collectors.joining(", ")));
145
                }
146
            }
147
        });
148

    
149
        //vocabulary combo
150
        composite.getBtnRemoveVocabulary().addSelectionListener(new SelectionAdapter() {
151
            @Override
152
            public void widgetSelected(SelectionEvent e) {
153
                composite.getTermVocabularyComboViewer().setElement(null);
154
            }
155
        });
156

    
157
        composite.getTreeTermHierarchy().setContentProvider(new OntologyTermContentProvider());
158
        composite.getTreeTermHierarchy().setLabelProvider(new OntologyTermLabelProvider());
159

    
160
        //tree results
161
        composite.getTreeTermHierarchy().addSelectionChangedListener(e->updateDetails(e.getSelection()));
162
        composite.getTreeTermHierarchy().setContentProvider(new OntologyTermContentProvider());
163
        composite.getTreeTermHierarchy().setLabelProvider(new OntologyTermLabelProvider());
164
        Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer(),};
165
        composite.getTreeTermHierarchy().addDragSupport(DND.DROP_MOVE,
166
                transfers, new DragSourceAdapter() {
167

    
168
            @Override
169
            public void dragSetData(DragSourceEvent event) {
170
                if (LocalSelectionTransfer.getTransfer().isSupportedType(event.dataType)) {
171
                    IStructuredSelection selection = (IStructuredSelection) composite.getTreeTermHierarchy().getSelection();
172
                    selection.toList().stream()
173
                    .filter(item->item instanceof OntologyTermWrapper)
174
                    .forEach(wrapper->((OntologyTermWrapper)wrapper).setTermVocabulary(composite.getTermVocabularyComboViewer().getSelection()));
175
                    LocalSelectionTransfer.getTransfer().setSelection(selection);
176
                }
177
            }
178
            @Override
179
            public void dragStart(DragSourceEvent event) {
180
                event.doit = !composite.getTreeTermHierarchy().getSelection().isEmpty();
181
            }
182
        });
183
    }
184

    
185
    private void requestAvailableOntologies() {
186
        Job requestOntologiesJob = new Job("Request available ontologies") {
187

    
188
            @Override
189
            protected IStatus run(IProgressMonitor monitor) {
190
                String response = new RequestTerminologies().request();
191
                try {
192
                    availableOntologies = TerminologyParser.parse(response);
193
                } catch (JSONException e) {
194
                    MessagingUtils.errorDialog("Loading ontologies failed", this, "Ontologies could not be found", TaxeditorStorePlugin.PLUGIN_ID, e, false);
195
                    e.printStackTrace();
196
                }
197
                return Status.OK_STATUS;
198
            }
199
        };
200
        requestOntologiesJob.schedule();
201
    }
202

    
203
    private OntologyTermWrapper getSelectedTerm(IStructuredSelection selection){
204
        Iterator iterator = selection.iterator();
205
        if(iterator.hasNext()){
206
            Object next = iterator.next();
207
            if(next instanceof OntologyTermWrapper){
208
                return (OntologyTermWrapper) next;
209
            }
210
        }
211
        return null;
212
    }
213

    
214
    private void clearDetails(){
215
        composite.getLblLabel().setText(""); //$NON-NLS-1$
216
        composite.getLblUri().setText(""); //$NON-NLS-1$
217
        composite.getLblDescription().setText(""); //$NON-NLS-1$
218
        composite.getListSynonyms().getList().removeAll();
219
    }
220

    
221
    private void updateDetails(ISelection s) {
222
        StructuredSelection selection = (StructuredSelection)s;
223
        if(selection.isEmpty()){
224
            clearDetails();
225
        }
226
        OntologyTermWrapper wrapper = getSelectedTerm(selection);
227
        if(wrapper!=null){
228
            String label = wrapper.getLabel();
229
            String uri = wrapper.getUri();
230
            String description = wrapper.getDescription();
231
            composite.getLblLabel().setText(label!=null?label:""); //$NON-NLS-1$
232
            composite.getLblUri().setText(uri!=null?uri:""); //$NON-NLS-1$
233
            composite.getLblDescription().setText(description!=null?description:""); //$NON-NLS-1$
234
            composite.getListSynonyms().getList().removeAll();
235
            if(wrapper.getSynonyms()!=null){
236
                wrapper.getSynonyms().forEach(syn->composite.getListSynonyms().add(syn));
237
            }
238
        }
239
    }
240

    
241
    private void search(){
242
        //clear result count
243
        composite.getLblResultCount().setText("Searching...");
244

    
245
        String searchString = composite.getTxtSearch().getText();
246
        if(searchString.equals(TXT_SEARCH_DEFAULT)){
247
            return;
248
        }
249
        if(selectedOntologies.isEmpty() && !MessagingUtils.confirmDialog("Long running operation", "You have not selected any specific ontology. This search may take a long time.\n\nDo you want to continue?")){
250
            return;
251
        }
252
        Job searchJob = new Job("Search Ontologies") {
253

    
254
            @Override
255
            protected IStatus run(IProgressMonitor monitor) {
256
                String response = new RequestSearch(searchString, selectedOntologies).request();
257
                if(response==null){
258
                    MessagingUtils.informationDialog(NO_CONNECTION_TITLE, NO_CONNECTION_MESSAGE);
259
                    return Status.CANCEL_STATUS;
260
                }
261
                final List<OntologyTermWrapper> wrapperList = new ArrayList<>();
262
                wrapperList.addAll(TermParser.parse(response));
263
                if(wrapperList.isEmpty()){
264
                    MessagingUtils.informationDialog(Messages.GfBioTerminologyImportPresenter_NO_RESULTS_TITLE, Messages.GfBioTerminologyImportPresenter_NO_RESULTS_MESSAGE);
265
                }
266
                //sort list
267
                Collections.sort(wrapperList, new TermWrapperComparator(searchString));
268
                sync.syncExec(() -> {
269
                    composite.getTreeTermHierarchy().setInput(wrapperList);
270
                    composite.getLblResultCount().setText(Integer.toString(wrapperList.size()));
271
                });
272
                return Status.OK_STATUS;
273
            }
274
        };
275
       searchJob.schedule();
276
    }
277

    
278
    private final class TermWrapperComparator implements Comparator<OntologyTermWrapper> {
279
        private final String searchString;
280

    
281
        public TermWrapperComparator(String searchString) {
282
            super();
283
            this.searchString = searchString;
284
        }
285

    
286
        @Override
287
        public int compare(OntologyTermWrapper o1, OntologyTermWrapper o2) {
288
            //remove wildcards from search string
289
            String trimmedSearch = searchString.replace("*", "");
290
            String label1 = o1.getLabel();
291
            String label2 = o2.getLabel();
292
            return StoreUtil.compareBySearchString(trimmedSearch, label1, label2);
293
        }
294
    }
295

    
296
}
(3-3/7)