Project

General

Profile

Download (16.2 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.component.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.i18n.Messages;
44
import eu.etaxonomy.cdm.model.common.TermVocabulary;
45
import eu.etaxonomy.cdm.model.location.NamedArea;
46
import eu.etaxonomy.cdm.model.taxon.Classification;
47
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
48
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
49
import eu.etaxonomy.cdm.vaadin.container.CdmSQLContainer;
50
import eu.etaxonomy.cdm.vaadin.container.NamedAreaContainer;
51
import eu.etaxonomy.cdm.vaadin.container.TaxonNodeContainer;
52
import eu.etaxonomy.cdm.vaadin.util.CdmQueryFactory;
53
import eu.etaxonomy.cdm.vaadin.util.CdmSpringContextHelper;
54
import eu.etaxonomy.cdm.vaadin.util.DistributionEditorUtil;
55
import eu.etaxonomy.cdm.vaadin.view.distributionStatus.IDistributionTableView;
56
import eu.etaxonomy.cdm.vaadin.view.distributionStatus.settings.AreaAndTaxonSettingsPresenter;
57

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

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

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

    
88
    @Override
89
    protected void init() {
90
        //init classification
91
        Classification classification = presenter.getChosenClassification();
92
        try {
93
            CdmSQLContainer classificationContainer = new CdmSQLContainer(CdmQueryFactory.generateTableQuery("Classification")); //$NON-NLS-1$
94
            classificationContainer.sort(new Object[] {"titleCache"}, new boolean[] {true}); //$NON-NLS-1$
95
            classificationBox.setContainerDataSource(classificationContainer);
96
        } catch (SQLException e) {
97
            DistributionEditorUtil.showSqlError(e);
98
        }
99
        RowId classificationRow = null;
100
        if(classification!=null){
101
            classificationRow = new RowId(classification.getId());
102
            TaxonNode root = CdmSpringContextHelper.getClassificationService().getRootNode(classification.getUuid());
103
            showClassificationTaxa(root);
104
        }
105
        else if(classificationBox.getItemIds().size()==1){
106
            //only one classification exists
107
            classificationRow = (RowId) classificationBox.getItemIds().iterator().next();
108
        }
109
        if(classificationRow!=null){
110
            classificationBox.setValue(classificationRow);
111
        }
112

    
113
        classificationBox.addValueChangeListener(this);
114
        taxonFilter.addValueChangeListener(this);
115
        taxonTree.addExpandListener(this);
116

    
117
        //init areas
118
        TermVocabulary<NamedArea> chosenAreaVoc = presenter.getChosenAreaVoc();
119
        Container areaVocContainer = presenter.getAreaContainer();
120
        if (areaVocContainer.size() == 1){
121
            chosenAreaVoc = (TermVocabulary<NamedArea>)areaVocContainer.getItemIds().iterator().next();
122
        }
123
        distAreaBox.setContainerDataSource(areaVocContainer);
124
        distAreaBox.setValue(chosenAreaVoc);
125
        distAreaBox.addValueChangeListener(this);
126

    
127
        if(chosenAreaVoc!=null){
128
            NamedAreaContainer areaContainer = new NamedAreaContainer(chosenAreaVoc);
129
            namedAreaList.setContainerDataSource(areaContainer);
130
        }
131
        Object selectedAreas = VaadinSession.getCurrent().getAttribute(DistributionEditorUtil.SATTR_SELECTED_AREAS);
132
        namedAreaList.setValue(selectedAreas);
133

    
134
        okButton.addClickListener(this);
135
        cancelButton.addClickListener(this);
136
        updateButtons();
137
    }
138

    
139
    @Override
140
    protected AbstractLayout buildMainLayout() {
141

    
142
        mainLayout = new VerticalLayout();
143
        mainLayout.setSizeFull();
144

    
145
        HorizontalLayout leftAndRightContainer = new HorizontalLayout();
146
        leftAndRightContainer.setImmediate(false);
147
        leftAndRightContainer.setSizeFull();
148
        leftAndRightContainer.setMargin(true);
149
        leftAndRightContainer.setSpacing(true);
150

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

    
156
        VerticalLayout rightContainer = new VerticalLayout();
157
        rightContainer.setImmediate(false);
158
        rightContainer.setSpacing(true);
159
        rightContainer.setSizeFull();
160

    
161
        //classification
162
        classificationBox = new ComboBox(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_CLASSIFICATION));
163
        classificationBox.setItemCaptionPropertyId(TaxonNodeContainer.LABEL);
164
        classificationBox.setInputPrompt(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_SELECT_CLASSIFICATION));
165
        classificationBox.setImmediate(true);
166
        classificationBox.setNewItemsAllowed(false);
167
        classificationBox.setNullSelectionAllowed(false);
168
        classificationBox.setSizeFull();
169
        classificationBox.setWidth("100%"); //$NON-NLS-1$
170

    
171
        //taxonFilter
172
        taxonFilter = new TextField(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_FILTER));
173
        taxonFilter.setInputPrompt(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_FILTER_TAXA_BY_NAME));
174
        taxonFilter.setSizeFull();
175
        taxonFilter.setImmediate(true);
176

    
177
        //distribution area box
178
        distAreaBox = new ComboBox(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_DISTRIBUTION_AREA));
179
        distAreaBox.setInputPrompt(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_SELECT_DISTRIBUTION_AREA));
180
        distAreaBox.setImmediate(true);
181
        distAreaBox.setNullSelectionAllowed(false);
182
        distAreaBox.setNewItemsAllowed(false);
183
        distAreaBox.setSizeFull();
184
        distAreaBox.setWidth("100%"); //$NON-NLS-1$
185

    
186
        // named areas
187
        namedAreaList = new ListSelect();
188
        namedAreaList.setCaption(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_AREAS));
189
        namedAreaList.setSizeFull();
190
        namedAreaList.setMultiSelect(true);
191

    
192
        //taxonomy
193
        taxonTree = new TreeTable(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_TAXONOMY));
194
        taxonTree.setSelectable(true);
195
        taxonTree.setSizeFull();
196
        taxonTree.setImmediate(true);
197
        taxonTree.setCacheRate(20);
198
        taxonTree.setColumnHeaderMode(ColumnHeaderMode.HIDDEN);
199
        taxonTree.setMultiSelect(true);
200

    
201
        leftContainer.addComponent(distAreaBox);
202
        leftContainer.addComponent(namedAreaList);
203
        leftContainer.setExpandRatio(distAreaBox, 0.1f);
204
        leftContainer.setExpandRatio(namedAreaList, 0.9f);
205
        leftContainer.setSizeFull();
206

    
207
        rightContainer.addComponent(classificationBox);
208
        rightContainer.addComponent(taxonFilter);
209
        rightContainer.addComponent(taxonTree);
210
        rightContainer.setExpandRatio(classificationBox, 0.1f);
211
        rightContainer.setExpandRatio(taxonFilter, 0.1f);
212
        rightContainer.setExpandRatio(taxonTree, 0.8f);
213

    
214
        leftAndRightContainer.addComponent(leftContainer);
215
        leftAndRightContainer.addComponent(rightContainer);
216

    
217
        //button toolbar
218
        HorizontalLayout buttonToolBar = createOkCancelButtons();
219

    
220
        mainLayout.addComponent(leftAndRightContainer);
221
        mainLayout.addComponent(buttonToolBar);
222
        mainLayout.setExpandRatio(leftAndRightContainer, 0.9f);
223
        mainLayout.setExpandRatio(buttonToolBar, 0.1f);
224
        mainLayout.setComponentAlignment(buttonToolBar, Alignment.BOTTOM_RIGHT);
225

    
226
        return leftAndRightContainer;
227
    }
228

    
229
    @Override
230
    public void valueChange(ValueChangeEvent event) {
231
        Property<?> property = event.getProperty();
232
        if(property==classificationBox){
233
        	UuidAndTitleCache<TaxonNode> parent = getUuidAndTitleCacheFromRowId(classificationBox.getValue());
234
        	TaxonNode root = CdmSpringContextHelper.getClassificationService().getRootNode(parent.getUuid());
235
        	showClassificationTaxa(root);
236
        }
237
        else if(property==taxonFilter){
238
            String filterText = taxonFilter.getValue();
239
            Property<?> uuidProperty = classificationBox.getContainerProperty(classificationBox.getValue(),"uuid"); //$NON-NLS-1$
240
            if(uuidProperty==null){
241
            	Notification.show(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_SELECT_CLASSIFICATION));
242
            }
243
            else{
244
            	if(CdmUtils.isNotBlank(filterText)){
245
            		UUID classificationUuid = UUID.fromString((String) uuidProperty.getValue());
246
            		List<UuidAndTitleCache<TaxonNode>> taxa = CdmSpringContextHelper.getTaxonNodeService().getUuidAndTitleCache(null, filterText, classificationUuid);
247
            		BeanItemContainer<UuidAndTitleCache<TaxonNode>> container = new BeanItemContainer<>(UuidAndTitleCache.class);
248
            		taxonTree.setContainerDataSource(container);
249
            		for (UuidAndTitleCache<TaxonNode> taxon : taxa) {
250
            			container.addItem(taxon);
251
            			taxonTree.setChildrenAllowed(taxon, false);
252
            		}
253
            		taxonTree.setVisibleColumns("titleCache"); //$NON-NLS-1$
254
            	}
255
            	else{
256
            		UuidAndTitleCache<TaxonNode> parent = getUuidAndTitleCacheFromRowId(classificationBox.getValue());
257
            		TaxonNode root = CdmSpringContextHelper.getClassificationService().getRootNode(parent.getUuid());
258
            		showClassificationTaxa(root);
259
            	}
260
            }
261
        }
262
        else if(property==distAreaBox){
263
            TermVocabulary<NamedArea> vocabulary = (TermVocabulary<NamedArea>) event.getProperty().getValue();
264
            NamedAreaContainer container = new NamedAreaContainer(vocabulary);
265
            namedAreaList.setContainerDataSource(container);
266
        }
267
        updateButtons();
268
    }
269

    
270
    @Override
271
    protected boolean isValid() {
272
        return classificationBox.getValue()!=null && distAreaBox.getValue()!=null;
273
    }
274

    
275
    @Override
276
    public void buttonClick(ClickEvent event) {
277
        Object source = event.getSource();
278
        if(source==okButton){
279
            List<UUID> taxonNodes = new ArrayList<>();
280
            TermVocabulary<NamedArea> areaVoc = null;
281
            String uuidString = (String) classificationBox.getContainerProperty(classificationBox.getValue(),"uuid").getValue(); //$NON-NLS-1$
282
            UUID classificationUuid = UUID.fromString(uuidString);
283
            Set<UuidAndTitleCache<TaxonNode>> treeSelection = (Set<UuidAndTitleCache<TaxonNode>>) taxonTree.getValue();
284
			if(!treeSelection.isEmpty()){
285
				for (UuidAndTitleCache<TaxonNode> uuidAndTitleCache : treeSelection) {
286
					taxonNodes.add(uuidAndTitleCache.getUuid());
287
				}
288
            }
289
			if(treeSelection.isEmpty() && CdmUtils.isNotBlank(taxonFilter.getValue())) {
290
                for (UuidAndTitleCache<TaxonNode> uuidAndTitleCache : (Collection<UuidAndTitleCache<TaxonNode>>) taxonTree.getItemIds()) {
291
                    taxonNodes.add(uuidAndTitleCache.getUuid());
292
                }
293
			}
294
            areaVoc = (TermVocabulary<NamedArea>) distAreaBox.getValue();
295
            List<NamedArea> selectedAreas = new ArrayList<>((Set<NamedArea>)namedAreaList.getValue()); //getValue is LinkedHashSet and therefore sorted
296
            DistributionEditorUtil.updateDistributionView(distributionTableView, taxonNodes, areaVoc, selectedAreas, classificationUuid);
297
            window.close();
298
        }
299
        else if(source==cancelButton){
300
            window.close();
301
        }
302
    }
303

    
304
    @Override
305
    public void nodeExpand(ExpandEvent event) {
306
        UuidAndTitleCache<TaxonNode> parent = (UuidAndTitleCache<TaxonNode>) event.getItemId();
307
        ((TaxonNodeContainer) taxonTree.getContainerDataSource()).addChildItems(parent);
308
    }
309

    
310
    private void showClassificationTaxa(TaxonNode rootNode) {
311
        final Collection<UuidAndTitleCache<TaxonNode>> children = CdmSpringContextHelper.getTaxonNodeService().listChildNodesAsUuidAndTitleCache(rootNode);
312
        // Enable polling and set frequency to 0.5 seconds
313
        UI.getCurrent().setPollInterval(500);
314
        taxonTree.setEnabled(false);
315
        taxonTree.removeAllItems();
316
        Notification.show(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_LOADING_TAXA));
317

    
318
        new TreeUpdater(children).start();
319
    }
320

    
321
    private UuidAndTitleCache<TaxonNode> getUuidAndTitleCacheFromRowId(Object classificationSelection) {
322
        String uuidString = (String) classificationBox.getContainerProperty(classificationSelection, "uuid").getValue(); //$NON-NLS-1$
323
        Property<Integer> rootNodeContainerProperty = null;
324

    
325
        Collection<?> ids = classificationBox.getContainerPropertyIds();
326
        //use for loop here because the case of the root node id columns differs between some DBs
327
        for (Object id : ids) {
328
			if(id instanceof String && ((String) id).toLowerCase().equals("rootnode_id")){ //$NON-NLS-1$
329
				rootNodeContainerProperty = classificationBox.getContainerProperty(classificationSelection, id);
330
				break;
331
			}
332
		}
333
		int id = rootNodeContainerProperty.getValue();
334
        String titleCache = (String) classificationBox.getContainerProperty(classificationSelection, "titleCache").getValue(); //$NON-NLS-1$
335
        UUID uuid = UUID.fromString(uuidString);
336
        UuidAndTitleCache<TaxonNode> parent = new UuidAndTitleCache<>(uuid, id, titleCache);
337
        return parent;
338
    }
339

    
340

    
341
    /**
342
     * {@inheritDoc}
343
     */
344
    @Override
345
    protected AreaAndTaxonSettingsPresenter getPresenter() {
346
        return new AreaAndTaxonSettingsPresenter();
347
    }
348

    
349
    private class TreeUpdater extends Thread{
350

    
351
    	private Collection<UuidAndTitleCache<TaxonNode>> children;
352

    
353

    
354
		public TreeUpdater(Collection<UuidAndTitleCache<TaxonNode>> children) {
355
			this.children = children;
356
		}
357

    
358
		@Override
359
    	public void run() {
360
			UI.getCurrent().access(new Runnable() {
361
				@Override
362
				public void run() {
363
					taxonTree.setContainerDataSource(new TaxonNodeContainer(children));
364

    
365
			        Notification notification = new Notification(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_LOADING_COMPLETE));
366
			        notification.setDelayMsec(500);
367
			        notification.show(Page.getCurrent());
368
			        taxonTree.setEnabled(true);
369
			        taxonTree.setSortContainerPropertyId("titleCache"); //$NON-NLS-1$
370
			        taxonTree.sort();
371

    
372
			        //disable polling when all taxa are loaded
373
			        UI.getCurrent().setPollInterval(-1);
374
				}
375
			});
376
    	}
377
    }
378

    
379
}
(1-1/6)