Project

General

Profile

Download (16.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.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.Notification;
33
import com.vaadin.ui.OptionGroup;
34
import com.vaadin.ui.Panel;
35
import com.vaadin.ui.Table.ColumnHeaderMode;
36
import com.vaadin.ui.TextField;
37
import com.vaadin.ui.Tree.ExpandEvent;
38
import com.vaadin.ui.Tree.ExpandListener;
39
import com.vaadin.ui.TreeTable;
40
import com.vaadin.ui.UI;
41
import com.vaadin.ui.VerticalLayout;
42

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

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

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

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

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

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

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

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

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

    
140
    @Override
141
    protected AbstractLayout buildMainLayout() {
142

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

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

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

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

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

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

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

    
187
        // named areas
188
        namedAreaList = new OptionGroup();
189
        namedAreaList.setMultiSelect(true);
190
        namedAreaList.setSizeFull();
191
        Panel namedAreaPanel = new Panel(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_AREAS));
192
        namedAreaPanel.setContent(new VerticalLayout(namedAreaList));
193
        namedAreaPanel.setSizeFull();
194

    
195

    
196
        //taxonomy
197
        taxonTree = new TreeTable(Messages.getLocalizedString(Messages.AreaAndTaxonSettingsConfigWindow_TAXONOMY));
198
        taxonTree.setSelectable(true);
199
        taxonTree.setSizeFull();
200
        taxonTree.setImmediate(true);
201
        taxonTree.setCacheRate(20);
202
        taxonTree.setColumnHeaderMode(ColumnHeaderMode.HIDDEN);
203
        taxonTree.setMultiSelect(true);
204

    
205
        leftContainer.addComponent(distAreaBox);
206
        leftContainer.addComponent(namedAreaPanel);
207
        leftContainer.setExpandRatio(distAreaBox, 0.1f);
208
        leftContainer.setExpandRatio(namedAreaPanel, 0.9f);
209
        leftContainer.setSizeFull();
210

    
211
        rightContainer.addComponent(classificationBox);
212
        rightContainer.addComponent(taxonFilter);
213
        rightContainer.addComponent(taxonTree);
214
        rightContainer.setExpandRatio(classificationBox, 0.1f);
215
        rightContainer.setExpandRatio(taxonFilter, 0.1f);
216
        rightContainer.setExpandRatio(taxonTree, 0.8f);
217

    
218
        leftAndRightContainer.addComponent(leftContainer);
219
        leftAndRightContainer.addComponent(rightContainer);
220

    
221
        //button toolbar
222
        HorizontalLayout buttonToolBar = createOkCancelButtons();
223

    
224
        mainLayout.addComponent(leftAndRightContainer);
225
        mainLayout.addComponent(buttonToolBar);
226
        mainLayout.setExpandRatio(leftAndRightContainer, 0.9f);
227
        mainLayout.setExpandRatio(buttonToolBar, 0.1f);
228
        mainLayout.setComponentAlignment(buttonToolBar, Alignment.BOTTOM_RIGHT);
229

    
230
        return leftAndRightContainer;
231
    }
232

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

    
274
    @Override
275
    protected boolean isValid() {
276
        return classificationBox.getValue()!=null && distAreaBox.getValue()!=null;
277
    }
278

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

    
308
    @Override
309
    public void nodeExpand(ExpandEvent event) {
310
        UuidAndTitleCache<TaxonNode> parent = (UuidAndTitleCache<TaxonNode>) event.getItemId();
311
        ((TaxonNodeContainer) taxonTree.getContainerDataSource()).addChildItems(parent);
312
    }
313

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

    
322
        new TreeUpdater(children).start();
323
    }
324

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

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

    
344

    
345
    /**
346
     * {@inheritDoc}
347
     */
348
    @Override
349
    protected AreaAndTaxonSettingsPresenter getPresenter() {
350
        return new AreaAndTaxonSettingsPresenter();
351
    }
352

    
353
    private class TreeUpdater extends Thread{
354

    
355
    	private Collection<UuidAndTitleCache<TaxonNode>> children;
356

    
357

    
358
		public TreeUpdater(Collection<UuidAndTitleCache<TaxonNode>> children) {
359
			this.children = children;
360
		}
361

    
362
		@Override
363
    	public void run() {
364
			UI.getCurrent().access(new Runnable() {
365
				@Override
366
				public void run() {
367
					taxonTree.setContainerDataSource(new TaxonNodeContainer(children));
368

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

    
376
			        //disable polling when all taxa are loaded
377
			        UI.getCurrent().setPollInterval(-1);
378
				}
379
			});
380
    	}
381
    }
382

    
383
}
(1-1/6)