Project

General

Profile

Download (14.3 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2015 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.cdm.vaadin.view.distributionStatus;
10

    
11
import java.sql.SQLException;
12
import java.util.ArrayList;
13
import java.util.Collection;
14
import java.util.List;
15
import java.util.Set;
16
import java.util.UUID;
17

    
18
import com.vaadin.data.Container;
19
import com.vaadin.data.Property;
20
import com.vaadin.data.Property.ValueChangeEvent;
21
import com.vaadin.data.Property.ValueChangeListener;
22
import com.vaadin.data.util.BeanItemContainer;
23
import com.vaadin.data.util.sqlcontainer.RowId;
24
import com.vaadin.server.Page;
25
import com.vaadin.server.VaadinSession;
26
import com.vaadin.ui.AbstractLayout;
27
import com.vaadin.ui.Alignment;
28
import com.vaadin.ui.Button.ClickEvent;
29
import com.vaadin.ui.Button.ClickListener;
30
import com.vaadin.ui.ComboBox;
31
import com.vaadin.ui.HorizontalLayout;
32
import com.vaadin.ui.ListSelect;
33
import com.vaadin.ui.Notification;
34
import com.vaadin.ui.Table.ColumnHeaderMode;
35
import com.vaadin.ui.TextField;
36
import com.vaadin.ui.Tree.ExpandEvent;
37
import com.vaadin.ui.Tree.ExpandListener;
38
import com.vaadin.ui.TreeTable;
39
import com.vaadin.ui.UI;
40
import com.vaadin.ui.VerticalLayout;
41

    
42
import eu.etaxonomy.cdm.common.CdmUtils;
43
import eu.etaxonomy.cdm.model.common.TermVocabulary;
44
import eu.etaxonomy.cdm.model.location.NamedArea;
45
import eu.etaxonomy.cdm.model.taxon.Classification;
46
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
47
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
48
import eu.etaxonomy.cdm.vaadin.container.CdmSQLContainer;
49
import eu.etaxonomy.cdm.vaadin.container.NamedAreaContainer;
50
import eu.etaxonomy.cdm.vaadin.container.TaxonNodeContainer;
51
import eu.etaxonomy.cdm.vaadin.util.CdmQueryFactory;
52
import eu.etaxonomy.cdm.vaadin.util.CdmSpringContextHelper;
53
import eu.etaxonomy.cdm.vaadin.util.DistributionEditorUtil;
54
import eu.etaxonomy.cdm.vaadin.view.distributionStatus.settings.AreaAndTaxonSettingsPresenter;
55

    
56
/**
57
 *
58
 * @author pplitzner
59
 *
60
 */
61
public class AreaAndTaxonSettingsConfigWindow
62
            extends SettingsDialogWindowBase<AreaAndTaxonSettingsPresenter>
63
            implements ValueChangeListener, ClickListener, ExpandListener{
64

    
65
    private static final long serialVersionUID = 1439411115014088780L;
66
    private ComboBox classificationBox;
67
    private TextField taxonFilter;
68
    private ComboBox distAreaBox;
69
    private ListSelect namedAreaList;
70
    private TreeTable taxonTree;
71
    private IDistributionTableView distributionTableView;
72

    
73
    /**
74
     * The constructor should first build the main layout, set the
75
     * composition root and then do any custom initialization.
76
     *
77
     * The constructor will not be automatically regenerated by the
78
     * visual editor.
79
     * @param distributionTableView
80
     */
81
    public AreaAndTaxonSettingsConfigWindow(IDistributionTableView distributionTableView) {
82
        super();
83
        this.distributionTableView = distributionTableView;
84
    }
85

    
86
    @Override
87
    protected void init() {
88
        //init classification
89
        Classification classification = presenter.getChosenClassification();
90
        try {
91
            classificationBox.setContainerDataSource(new CdmSQLContainer(CdmQueryFactory.generateTableQuery("Classification")));
92
        } catch (SQLException e) {
93
            DistributionEditorUtil.showSqlError(e);
94
        }
95
        RowId parent = null;
96
        if(classification!=null){
97
        	parent = new RowId(classification.getRootNode().getId());
98
        }
99
        else if(classificationBox.getItemIds().size()==1){
100
            //only one classification exists
101
            parent = (RowId) classificationBox.getItemIds().iterator().next();
102
        }
103
        if(parent!=null){
104
            classificationBox.setValue(new RowId(parent.getId()));
105
            showClassificationTaxa(getUuidAndTitleCacheFromRowId(parent));
106
        }
107

    
108
        classificationBox.addValueChangeListener(this);
109
        taxonFilter.addValueChangeListener(this);
110
        taxonTree.addExpandListener(this);
111

    
112
        //init areas
113
        TermVocabulary<NamedArea> chosenAreaVoc = presenter.getChosenAreaVoc();
114
        Container areaVocContainer = presenter.getAreaContainer();
115
        if (areaVocContainer.size() == 1){
116
            chosenAreaVoc = (TermVocabulary<NamedArea>)areaVocContainer.getItemIds().iterator().next();
117
        }
118
        distAreaBox.setContainerDataSource(areaVocContainer);
119
        distAreaBox.setValue(chosenAreaVoc);
120
        distAreaBox.addValueChangeListener(this);
121

    
122
        if(chosenAreaVoc!=null){
123
            NamedAreaContainer areaContainer = new NamedAreaContainer(chosenAreaVoc);
124
            namedAreaList.setContainerDataSource(areaContainer);
125
        }
126
        Object selectedAreas = VaadinSession.getCurrent().getAttribute(DistributionEditorUtil.SATTR_SELECTED_AREAS);
127
        namedAreaList.setValue(selectedAreas);
128

    
129
        okButton.addClickListener(this);
130
        cancelButton.addClickListener(this);
131
        updateButtons();
132
    }
133

    
134
    @Override
135
    protected AbstractLayout buildMainLayout() {
136

    
137
        mainLayout = new VerticalLayout();
138
        mainLayout.setSizeFull();
139

    
140
        HorizontalLayout leftAndRightContainer = new HorizontalLayout();
141
        leftAndRightContainer.setImmediate(false);
142
        leftAndRightContainer.setSizeFull();
143
        leftAndRightContainer.setMargin(true);
144
        leftAndRightContainer.setSpacing(true);
145

    
146
        VerticalLayout leftContainer = new VerticalLayout();
147
        leftContainer.setImmediate(false);
148
        leftContainer.setSpacing(true);
149
        leftContainer.setSizeFull();
150

    
151
        VerticalLayout rightContainer = new VerticalLayout();
152
        rightContainer.setImmediate(false);
153
        rightContainer.setSpacing(true);
154
        rightContainer.setSizeFull();
155

    
156
        //classification
157
        classificationBox = new ComboBox("Classification");
158
        classificationBox.setItemCaptionPropertyId(TaxonNodeContainer.LABEL);
159
        classificationBox.setInputPrompt("Please select a classification...");
160
        classificationBox.setImmediate(true);
161
        classificationBox.setNewItemsAllowed(false);
162
        classificationBox.setNullSelectionAllowed(false);
163
        classificationBox.setSizeFull();
164
        classificationBox.setWidth("100%");
165

    
166
        //taxonFilter
167
        taxonFilter = new TextField("Filter");
168
        taxonFilter.setInputPrompt("Filter taxa by name...");
169
        taxonFilter.setSizeFull();
170
        taxonFilter.setImmediate(true);
171

    
172
        //distribution area box
173
        distAreaBox = new ComboBox("Distribution Area:");
174
        distAreaBox.setInputPrompt("Please select a distribution area...");
175
        distAreaBox.setImmediate(true);
176
        distAreaBox.setNullSelectionAllowed(false);
177
        distAreaBox.setNewItemsAllowed(false);
178
        distAreaBox.setSizeFull();
179
        distAreaBox.setWidth("100%");
180

    
181
        // named areas
182
        namedAreaList = new ListSelect();
183
        namedAreaList.setCaption("Areas");
184
        namedAreaList.setSizeFull();
185
        namedAreaList.setMultiSelect(true);
186

    
187
        //taxonomy
188
        taxonTree = new TreeTable("Taxonomy");
189
        taxonTree.setSelectable(true);
190
        taxonTree.setSizeFull();
191
        taxonTree.setImmediate(true);
192
        taxonTree.setCacheRate(20);
193
        taxonTree.setColumnHeaderMode(ColumnHeaderMode.HIDDEN);
194
        taxonTree.setMultiSelect(true);
195

    
196
        leftContainer.addComponent(distAreaBox);
197
        leftContainer.addComponent(namedAreaList);
198
        leftContainer.setExpandRatio(distAreaBox, 0.1f);
199
        leftContainer.setExpandRatio(namedAreaList, 0.9f);
200
        leftContainer.setSizeFull();
201

    
202
        rightContainer.addComponent(classificationBox);
203
        rightContainer.addComponent(taxonFilter);
204
        rightContainer.addComponent(taxonTree);
205
        rightContainer.setExpandRatio(classificationBox, 0.1f);
206
        rightContainer.setExpandRatio(taxonFilter, 0.1f);
207
        rightContainer.setExpandRatio(taxonTree, 0.8f);
208

    
209
        leftAndRightContainer.addComponent(leftContainer);
210
        leftAndRightContainer.addComponent(rightContainer);
211

    
212
        //button toolbar
213
        HorizontalLayout buttonToolBar = createOkCancelButtons();
214

    
215
        mainLayout.addComponent(leftAndRightContainer);
216
        mainLayout.addComponent(buttonToolBar);
217
        mainLayout.setExpandRatio(leftAndRightContainer, 0.9f);
218
        mainLayout.setExpandRatio(buttonToolBar, 0.1f);
219
        mainLayout.setComponentAlignment(buttonToolBar, Alignment.BOTTOM_RIGHT);
220

    
221
        return leftAndRightContainer;
222
    }
223

    
224
    @Override
225
    public void valueChange(ValueChangeEvent event) {
226
        Property<?> property = event.getProperty();
227
        if(property==classificationBox){
228
        	UuidAndTitleCache<TaxonNode> parent = getUuidAndTitleCacheFromRowId(classificationBox.getValue());
229
            showClassificationTaxa(parent);
230
        }
231
        else if(property==taxonFilter){
232
            String filterText = taxonFilter.getValue();
233
            Property<?> uuidProperty = classificationBox.getContainerProperty(classificationBox.getValue(),"uuid");
234
            if(uuidProperty==null){
235
            	Notification.show("Please select a classification");
236
            }
237
            else{
238
            	if(CdmUtils.isNotBlank(filterText)){
239
            		UUID classificationUuid = UUID.fromString((String) uuidProperty.getValue());
240
            		List<UuidAndTitleCache<TaxonNode>> taxa = CdmSpringContextHelper.getTaxonNodeService().getUuidAndTitleCache(null, filterText, classificationUuid);
241
            		BeanItemContainer<UuidAndTitleCache<TaxonNode>> container = new BeanItemContainer<>(UuidAndTitleCache.class);
242
            		taxonTree.setContainerDataSource(container);
243
            		for (UuidAndTitleCache<TaxonNode> taxon : taxa) {
244
            			container.addItem(taxon);
245
            			taxonTree.setChildrenAllowed(taxon, false);
246
            		}
247
            		taxonTree.setVisibleColumns("titleCache");
248
            	}
249
            	else{
250
            		UuidAndTitleCache<TaxonNode> parent = getUuidAndTitleCacheFromRowId(classificationBox.getValue());
251
            		showClassificationTaxa(parent);
252
            	}
253
            }
254
        }
255
        else if(property==distAreaBox){
256
            TermVocabulary<NamedArea> vocabulary = (TermVocabulary<NamedArea>) event.getProperty().getValue();
257
            NamedAreaContainer container = new NamedAreaContainer(vocabulary);
258
            namedAreaList.setContainerDataSource(container);
259
        }
260
        updateButtons();
261
    }
262

    
263
    @Override
264
    protected boolean isValid() {
265
        return classificationBox.getValue()!=null && distAreaBox.getValue()!=null;
266
    }
267

    
268
    @Override
269
    public void buttonClick(ClickEvent event) {
270
        Object source = event.getSource();
271
        if(source==okButton){
272
            List<UUID> taxonNodes = new ArrayList<>();
273
            TermVocabulary<NamedArea> areaVoc = null;
274
            String uuidString = (String) classificationBox.getContainerProperty(classificationBox.getValue(),"uuid").getValue();
275
            UUID classificationUuid = UUID.fromString(uuidString);
276
            Set<UuidAndTitleCache<TaxonNode>> treeSelection = (Set<UuidAndTitleCache<TaxonNode>>) taxonTree.getValue();
277
			if(!treeSelection.isEmpty()){
278
				for (UuidAndTitleCache<TaxonNode> uuidAndTitleCache : treeSelection) {
279
					taxonNodes.add(uuidAndTitleCache.getUuid());
280
				}
281
            }
282
            areaVoc = (TermVocabulary<NamedArea>) distAreaBox.getValue();
283
            Set<NamedArea> selectedAreas = (Set<NamedArea>) namedAreaList.getValue();
284
            DistributionEditorUtil.updateDistributionView(distributionTableView, taxonNodes, areaVoc, selectedAreas, classificationUuid);
285
            window.close();
286
        }
287
        else if(source==cancelButton){
288
            window.close();
289
        }
290
    }
291

    
292
    @Override
293
    public void nodeExpand(ExpandEvent event) {
294
        UuidAndTitleCache<TaxonNode> parent = (UuidAndTitleCache<TaxonNode>) event.getItemId();
295
        ((TaxonNodeContainer) taxonTree.getContainerDataSource()).addChildItems(parent);
296
    }
297

    
298
    private void showClassificationTaxa(UuidAndTitleCache<TaxonNode> parent) {
299
        final Collection<UuidAndTitleCache<TaxonNode>> children = CdmSpringContextHelper.getTaxonNodeService().listChildNodesAsUuidAndTitleCache(parent);
300
        // Enable polling and set frequency to 0.5 seconds
301
        UI.getCurrent().setPollInterval(500);
302
        taxonTree.setEnabled(false);
303
        taxonTree.removeAllItems();
304
        Notification.show("Loading taxa...");
305

    
306
        new TreeUpdater(children).start();
307
    }
308

    
309
    private UuidAndTitleCache<TaxonNode> getUuidAndTitleCacheFromRowId(Object classificationSelection) {
310
        String uuidString = (String) classificationBox.getContainerProperty(classificationSelection, "uuid").getValue();
311
        Property<Integer> rootNodeContainerProperty = null;
312

    
313
        Collection<?> ids = classificationBox.getContainerPropertyIds();
314
        //use for loop here because the case of the root node id columns differs between some DBs
315
        for (Object id : ids) {
316
			if(id instanceof String && ((String) id).toLowerCase().equals("rootnode_id")){
317
				rootNodeContainerProperty = classificationBox.getContainerProperty(classificationSelection, id);
318
				break;
319
			}
320
		}
321
		int id = rootNodeContainerProperty.getValue();
322
        String titleCache = (String) classificationBox.getContainerProperty(classificationSelection, "titleCache").getValue();
323
        UUID uuid = UUID.fromString(uuidString);
324
        UuidAndTitleCache<TaxonNode> parent = new UuidAndTitleCache<>(uuid, id, titleCache);
325
        return parent;
326
    }
327

    
328

    
329
    /**
330
     * {@inheritDoc}
331
     */
332
    @Override
333
    protected AreaAndTaxonSettingsPresenter getPresenter() {
334
        return new AreaAndTaxonSettingsPresenter();
335
    }
336

    
337
    private class TreeUpdater extends Thread{
338

    
339
    	private Collection<UuidAndTitleCache<TaxonNode>> children;
340

    
341

    
342
		public TreeUpdater(Collection<UuidAndTitleCache<TaxonNode>> children) {
343
			this.children = children;
344
		}
345

    
346
		@Override
347
    	public void run() {
348
			UI.getCurrent().access(new Runnable() {
349
				@Override
350
				public void run() {
351
					taxonTree.setContainerDataSource(new TaxonNodeContainer(children));
352

    
353
			        Notification notification = new Notification("Loading complete");
354
			        notification.setDelayMsec(500);
355
			        notification.show(Page.getCurrent());
356
			        taxonTree.setEnabled(true);
357

    
358
			        //disable polling when all taxa are loaded
359
			        UI.getCurrent().setPollInterval(-1);
360
				}
361
			});
362
    	}
363
    }
364

    
365
}
(1-1/7)