Project

General

Profile

Download (15.8 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.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.settings.AreaAndTaxonSettingsPresenter;
56

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

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

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

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

    
111
        classificationBox.addValueChangeListener(this);
112
        taxonFilter.addValueChangeListener(this);
113
        taxonTree.addExpandListener(this);
114

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

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

    
132
        okButton.addClickListener(this);
133
        cancelButton.addClickListener(this);
134
        updateButtons();
135
    }
136

    
137
    @Override
138
    protected AbstractLayout buildMainLayout() {
139

    
140
        mainLayout = new VerticalLayout();
141
        mainLayout.setSizeFull();
142

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

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

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

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

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

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

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

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

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

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

    
212
        leftAndRightContainer.addComponent(leftContainer);
213
        leftAndRightContainer.addComponent(rightContainer);
214

    
215
        //button toolbar
216
        HorizontalLayout buttonToolBar = createOkCancelButtons();
217

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

    
224
        return leftAndRightContainer;
225
    }
226

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

    
266
    @Override
267
    protected boolean isValid() {
268
        return classificationBox.getValue()!=null && distAreaBox.getValue()!=null;
269
    }
270

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

    
300
    @Override
301
    public void nodeExpand(ExpandEvent event) {
302
        UuidAndTitleCache<TaxonNode> parent = (UuidAndTitleCache<TaxonNode>) event.getItemId();
303
        ((TaxonNodeContainer) taxonTree.getContainerDataSource()).addChildItems(parent);
304
    }
305

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

    
314
        new TreeUpdater(children).start();
315
    }
316

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

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

    
336

    
337
    /**
338
     * {@inheritDoc}
339
     */
340
    @Override
341
    protected AreaAndTaxonSettingsPresenter getPresenter() {
342
        return new AreaAndTaxonSettingsPresenter();
343
    }
344

    
345
    private class TreeUpdater extends Thread{
346

    
347
    	private Collection<UuidAndTitleCache<TaxonNode>> children;
348

    
349

    
350
		public TreeUpdater(Collection<UuidAndTitleCache<TaxonNode>> children) {
351
			this.children = children;
352
		}
353

    
354
		@Override
355
    	public void run() {
356
			UI.getCurrent().access(new Runnable() {
357
				@Override
358
				public void run() {
359
					taxonTree.setContainerDataSource(new TaxonNodeContainer(children));
360

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

    
368
			        //disable polling when all taxa are loaded
369
			        UI.getCurrent().setPollInterval(-1);
370
				}
371
			});
372
    	}
373
    }
374

    
375
}
(1-1/7)