Project

General

Profile

« Previous | Next » 

Revision 1d066036

Added by Cherian Mathew almost 9 years ago

StatusComposite, IStatusComposite : added font awesome refresh icon, updated checkbox generator
CdmSQLContainer : added methods to disable change ebents and possiblity to add items
LeafNodeTaxonContainer : corrected and split queris for taxon and synonyms
StatusPresenter : moving filter / query logic to container
StatusEditorUI : using new edit theme
CdmQueryFactory : new factory for sql queries
StatusPresenterTest, StatusPresenterTest : added tests for loading synonyms

View differences:

.gitattributes
30 30
src/main/java/eu/etaxonomy/cdm/vaadin/ui/CheckUI.java -text
31 31
src/main/java/eu/etaxonomy/cdm/vaadin/ui/DbStatusUI.java -text
32 32
src/main/java/eu/etaxonomy/cdm/vaadin/ui/StatusEditorUI.java -text
33
src/main/java/eu/etaxonomy/cdm/vaadin/util/CdmQueryFactory.java -text
33 34
src/main/java/eu/etaxonomy/cdm/vaadin/util/CdmSQLStringDecorator.java -text
34 35
src/main/java/eu/etaxonomy/cdm/vaadin/util/CdmSpringContextHelper.java -text
35 36
src/main/java/eu/etaxonomy/cdm/vaadin/view/AuthenticationView.java -text
src/main/java/eu/etaxonomy/cdm/vaadin/component/StatusComposite.java
24 24
import com.vaadin.data.util.sqlcontainer.RowId;
25 25
import com.vaadin.event.Action;
26 26
import com.vaadin.event.FieldEvents;
27
import com.vaadin.event.FieldEvents.FocusEvent;
28 27
import com.vaadin.event.FieldEvents.TextChangeEvent;
29
import com.vaadin.server.ThemeResource;
28
import com.vaadin.event.LayoutEvents.LayoutClickEvent;
29
import com.vaadin.event.LayoutEvents.LayoutClickListener;
30
import com.vaadin.server.FontAwesome;
30 31
import com.vaadin.ui.Alignment;
31 32
import com.vaadin.ui.Button;
32 33
import com.vaadin.ui.Button.ClickEvent;
......
42 43
import com.vaadin.ui.Table;
43 44
import com.vaadin.ui.Table.ColumnHeaderMode;
44 45
import com.vaadin.ui.TextField;
46
import com.vaadin.ui.Tree.ExpandEvent;
47
import com.vaadin.ui.Tree.ExpandListener;
48
import com.vaadin.ui.TreeTable;
45 49
import com.vaadin.ui.VerticalLayout;
46
import com.vaadin.ui.themes.Reindeer;
47 50

  
48
import eu.etaxonomy.cdm.vaadin.presenter.StatusPresenter;
51
import eu.etaxonomy.cdm.vaadin.container.LeafNodeTaxonContainer;
49 52
import eu.etaxonomy.cdm.vaadin.view.IStatusComposite;
50 53

  
51 54
/**
......
62 65
    @AutoGenerated
63 66
    private Label inViewLabel;
64 67
    @AutoGenerated
65
    private Table taxaTreeTable;
66
    @AutoGenerated
67
    private HorizontalLayout addRemovehorizontalLayout;
68
    @AutoGenerated
69
    private Button removeButton;
70
    @AutoGenerated
71
    private ComboBox addComboBox;
68
    private TreeTable taxaTreeTable;
72 69
    @AutoGenerated
73 70
    private HorizontalLayout searchHorizontalLayout;
74 71
    @AutoGenerated
......
76 73
    @AutoGenerated
77 74
    private TextField searchTextField;
78 75
    @AutoGenerated
76
    private HorizontalLayout addRemovehorizontalLayout;
77
    @AutoGenerated
78
    private Button removeButton;
79
    @AutoGenerated
80
    private ComboBox addComboBox;
81
    @AutoGenerated
79 82
    private VerticalLayout filterVerticalLayout;
80 83
    @AutoGenerated
81 84
    private Table filterTable;
......
112 115
        buildMainLayout();
113 116
        setCompositionRoot(mainLayout);
114 117

  
118
        searchHorizontalLayout.addLayoutClickListener(new LayoutClickListener() {
119

  
120
            @Override
121
            public void layoutClick(LayoutClickEvent event) {
122
                if (event.getChildComponent() == searchTextField && searchTextField.getValue().equals(FILTER_TAXA_INPUT)) {
123
                   searchTextField.setValue("");
124
                }
125
            }
126
        });
115 127
        addUIListeners();
116 128
        initAddComboBox();
117 129
        initSearchTextField();
......
130 142
        taxaTreeTable.setEnabled(enable);
131 143
        addComboBox.setEnabled(enable);
132 144
        removeButton.setEnabled(enable);
145
        searchTextField.setEnabled(enable);
146
        clearSearchButton.setEnabled(enable);
133 147
    }
134 148

  
135 149
    private void initTaxaTable(int classificationId) {
136 150

  
151
        taxaTreeTable.setSelectable(true);
152
        taxaTreeTable.setImmediate(false);
153

  
137 154
        if(listener != null) {
138 155
            List<String> columnIds = new ArrayList<String>();
139
            columnIds.add(StatusPresenter.NAME_ID);
140
            taxaTreeTable.setColumnExpandRatio(StatusPresenter.NAME_ID, 1);
141
            columnIds.add(StatusPresenter.PB_ID);
142
            taxaTreeTable.setColumnWidth(StatusPresenter.PB_ID, -1);
156
            columnIds.add(LeafNodeTaxonContainer.NAME_ID);
157
            taxaTreeTable.setColumnExpandRatio(LeafNodeTaxonContainer.NAME_ID, 1);
158
            columnIds.add(LeafNodeTaxonContainer.PB_ID);
159
            taxaTreeTable.setColumnWidth(LeafNodeTaxonContainer.PB_ID, 25);
143 160

  
144 161
            ValueChangeListener pbListener = new ValueChangeListener() {
145 162
                @Override
......
149 166
                }
150 167

  
151 168
            };
152
            taxaTreeTable.addGeneratedColumn(StatusPresenter.PB_ID, new BooleanCheckBoxGenerator(pbListener));
169
            taxaTreeTable.addGeneratedColumn(LeafNodeTaxonContainer.PB_ID, new BooleanCheckBoxGenerator(pbListener));
153 170
            try {
154 171
                taxaTreeTable.setContainerDataSource(listener.loadTaxa(classificationId), columnIds);
155 172
            } catch (SQLException e) {
156 173
              //TODO : throw up warning dialog
157 174
                e.printStackTrace();
158 175
            }
176

  
177
            taxaTreeTable.addExpandListener(new ExpandListener() {
178

  
179
                @Override
180
                public void nodeExpand(ExpandEvent event) {
181
                    //listener.addChildren(event.getItemId());
182
                }
183

  
184
            });
185

  
186
            taxaTreeTable.setCellStyleGenerator(new Table.CellStyleGenerator() {
187

  
188
                @Override
189
                public String getStyle(Table source, Object itemId, Object propertyId) {
190
                    Property hasSynProperty = source.getItem(itemId).getItemProperty(LeafNodeTaxonContainer.HAS_SYN_ID);
191
                    if(hasSynProperty == null) {
192
                        // this is a synonym
193
                        return "synonym";
194
                    }
195
                    return null;
196
                }
197
            });
198

  
199
            // NOTE : Not really sure why we need to refresh the container here.
200
            // in the case of 'Table' this is not required
201
            listener.refresh();
159 202
            updateInViewLabel();
160 203
        }
161 204

  
......
222 265

  
223 266
        filterTable.setContainerDataSource(container);
224 267
        filterTable.setColumnHeaderMode(ColumnHeaderMode.HIDDEN);
225
        filterTable.addStyleName(Reindeer.TABLE_BORDERLESS);
226

  
227 268

  
228 269

  
229 270
        ValueChangeListener selectedListener = new ValueChangeListener() {
230 271

  
272
            private static final long serialVersionUID = -5551250788805117454L;
231 273

  
232 274
            @Override
233 275
            public void valueChange(ValueChangeEvent event) {
......
256 298
        };
257 299
        filterTable.addGeneratedColumn(PROPERTY_SELECTED_ID, new BooleanCheckBoxGenerator(selectedListener));
258 300

  
259
//        filterTable.setCellStyleGenerator(new Table.CellStyleGenerator() {
260
//
261
//            private static final long serialVersionUID = -3363906932807556720L;
262
//
263
//            @Override
264
//            public String getStyle(Table source, Object itemId, Object propertyId) {
265
//                return "removable";
266
//            }
267
//        });
268 301
    }
269 302

  
270 303
    private void updateInViewLabel() {
271
        inViewLabel.setValue(IN_VIEW_PREFIX + String.valueOf(listener.getCurrentSize()) + " / " + String.valueOf(listener.getSize()) + " taxa");
304
        inViewLabel.setValue(IN_VIEW_PREFIX + String.valueOf(listener.getCurrentNoOfTaxa()) + " / " + String.valueOf(listener.getTotalNoOfTaxa()) + " taxa");
272 305
    }
273 306

  
274 307
    private void initSearchTextField() {
......
287 320
    }
288 321

  
289 322
    private void initClearSearchButton() {
290
        ThemeResource resource = new ThemeResource("icons/32/cancel.png");
291
        clearSearchButton.setIcon(resource);
323
        //ThemeResource resource = new ThemeResource("icons/32/cancel.png");
324
        clearSearchButton.setIcon(FontAwesome.REFRESH);
292 325
        clearSearchButton.setCaption("");
293 326
    }
294 327

  
......
319 352
        });
320 353
    }
321 354

  
322
//    private void addFilterComboBoxListener() {
323
//        filterComboBox.addValueChangeListener(new Property.ValueChangeListener() {
324
//
325
//            private static final long serialVersionUID = 1314542578509878256L;
326
//
327
//            @Override
328
//            public void valueChange(ValueChangeEvent event) {
329
//                if (filterComboBox.getValue() != null) {
330
//                    String selected = (String)filterComboBox.getValue();
331
//                    if(!selected.equals(SELECT_FILTER)) {
332
//                        filterTable.addItem(new Object[]{selected}, filterTable.getItemIds().size() + 1);
333
//                        filterComboBox.setValue(SELECT_FILTER);
334
//                    }
335
//                }
336
//            }
337
//        });
338
//    }
339 355

  
340 356
    private void addAddComboBoxListener() {
341 357
        addComboBox.addValueChangeListener(new Property.ValueChangeListener() {
......
363 379
            @Override
364 380
            public void textChange(TextChangeEvent event) {
365 381
               listener.setNameFilter(event.getText());
382
               updateInViewLabel();
366 383
            }
367 384

  
368 385
        });
369
        searchTextField.addFocusListener(new FieldEvents.FocusListener(){
370 386

  
371
            @Override
372
            public void focus(FocusEvent event) {
373
                searchTextField.setValue("");
374
            }
375

  
376
        });
377 387
    }
378 388

  
379 389
    private void addClearSearchButtonListener() {
......
383 393
            public void buttonClick(ClickEvent event) {
384 394
               listener.removeNameFilter();
385 395
               searchTextField.setValue(FILTER_TAXA_INPUT);
396
               updateInViewLabel();
386 397
            }
387 398

  
388 399
        });
389 400
    }
390
//    private void addFilterTableListener() {
391
//        filterTable.addItemClickListener(new ItemClickEvent.ItemClickListener() {
392
//
393
//            private static final long serialVersionUID = -4722168300711497739L;
394
//
395
//            @Override
396
//            public void itemClick(ItemClickEvent event) {
397
//                filterTable.removeItem(event.getItemId());
398
//            }}
399
//                );
400
//    }
401

  
401 402

  
402 403

  
403 404
    /* (non-Javadoc)
......
422 423
         */
423 424
        @Override
424 425
        public Component generateCell(Table source, Object itemId, Object columnId) {
425
            Property prop = source.getItem(itemId).getItemProperty(columnId);
426
            CheckBox cb = new CheckBox(null, prop);
427
            cb.addValueChangeListener(listener);
428
            cb.setData(itemId);
429
            return cb;
426
            if(source.getItem(itemId) != null) {
427
                Property prop = source.getItem(itemId).getItemProperty(columnId);
428
                if(prop == null) {
429
                    return null;
430
                }
431
                CheckBox cb = new CheckBox(null, prop);
432
                cb.addValueChangeListener(listener);
433
                cb.setData(itemId);
434
                return cb;
435
            } else {
436
                return null;
437
            }
438

  
430 439
        }
431 440
    }
432 441

  
......
458 467
        mainLayout.addComponent(filterVerticalLayout, 0, 1);
459 468
        mainLayout.setComponentAlignment(filterVerticalLayout, new Alignment(20));
460 469

  
461
        // searchHorizontalLayout
462
        searchHorizontalLayout = buildSearchHorizontalLayout();
463
        mainLayout.addComponent(searchHorizontalLayout, 0, 3);
464
        mainLayout.setComponentAlignment(searchHorizontalLayout, new Alignment(48));
465

  
466 470
        // addRemovehorizontalLayout
467 471
        addRemovehorizontalLayout = buildAddRemovehorizontalLayout();
468 472
        mainLayout.addComponent(addRemovehorizontalLayout, 0, 2);
469 473
        mainLayout.setComponentAlignment(addRemovehorizontalLayout, new Alignment(48));
470 474

  
475
        // searchHorizontalLayout
476
        searchHorizontalLayout = buildSearchHorizontalLayout();
477
        mainLayout.addComponent(searchHorizontalLayout, 0, 3);
478
        mainLayout.setComponentAlignment(searchHorizontalLayout, new Alignment(48));
479

  
471 480
        // taxaTreeTable
472
        taxaTreeTable = new Table();
481
        taxaTreeTable = new TreeTable();
473 482
        taxaTreeTable.setImmediate(false);
474 483
        taxaTreeTable.setWidth("100.0%");
475 484
        taxaTreeTable.setHeight("534px");
......
515 524
        return filterVerticalLayout;
516 525
    }
517 526

  
527
    @AutoGenerated
528
    private HorizontalLayout buildAddRemovehorizontalLayout() {
529
        // common part: create layout
530
        addRemovehorizontalLayout = new HorizontalLayout();
531
        addRemovehorizontalLayout.setImmediate(false);
532
        addRemovehorizontalLayout.setWidth("100.0%");
533
        addRemovehorizontalLayout.setHeight("-1px");
534
        addRemovehorizontalLayout.setMargin(false);
535
        addRemovehorizontalLayout.setSpacing(true);
536

  
537
        // addComboBox
538
        addComboBox = new ComboBox();
539
        addComboBox.setImmediate(false);
540
        addComboBox.setWidth("100.0%");
541
        addComboBox.setHeight("-1px");
542
        addRemovehorizontalLayout.addComponent(addComboBox);
543
        addRemovehorizontalLayout.setExpandRatio(addComboBox, 3.0f);
544

  
545
        // removeButton
546
        removeButton = new Button();
547
        removeButton.setCaption("Remove");
548
        removeButton.setImmediate(true);
549
        removeButton.setWidth("100.0%");
550
        removeButton.setHeight("-1px");
551
        addRemovehorizontalLayout.addComponent(removeButton);
552
        addRemovehorizontalLayout.setExpandRatio(removeButton, 2.0f);
553

  
554
        return addRemovehorizontalLayout;
555
    }
556

  
518 557
    @AutoGenerated
519 558
    private HorizontalLayout buildSearchHorizontalLayout() {
520 559
        // common part: create layout
......
547 586
        return searchHorizontalLayout;
548 587
    }
549 588

  
550
    @AutoGenerated
551
    private HorizontalLayout buildAddRemovehorizontalLayout() {
552
        // common part: create layout
553
        addRemovehorizontalLayout = new HorizontalLayout();
554
        addRemovehorizontalLayout.setImmediate(false);
555
        addRemovehorizontalLayout.setWidth("100.0%");
556
        addRemovehorizontalLayout.setHeight("-1px");
557
        addRemovehorizontalLayout.setMargin(false);
558
        addRemovehorizontalLayout.setSpacing(true);
559

  
560
        // addComboBox
561
        addComboBox = new ComboBox();
562
        addComboBox.setImmediate(false);
563
        addComboBox.setWidth("100.0%");
564
        addComboBox.setHeight("-1px");
565
        addRemovehorizontalLayout.addComponent(addComboBox);
566
        addRemovehorizontalLayout.setExpandRatio(addComboBox, 3.0f);
567

  
568
        // removeButton
569
        removeButton = new Button();
570
        removeButton.setCaption("Remove");
571
        removeButton.setImmediate(true);
572
        removeButton.setWidth("100.0%");
573
        removeButton.setHeight("-1px");
574
        addRemovehorizontalLayout.addComponent(removeButton);
575
        addRemovehorizontalLayout.setExpandRatio(removeButton, 2.0f);
576

  
577
        return addRemovehorizontalLayout;
578
    }
579

  
580 589
}
src/main/java/eu/etaxonomy/cdm/vaadin/container/CdmSQLContainer.java
1 1
package eu.etaxonomy.cdm.vaadin.container;
2 2

  
3 3
import java.sql.SQLException;
4
import java.util.HashMap;
5
import java.util.Map;
4 6

  
7
import org.apache.log4j.Logger;
8

  
9
import com.vaadin.data.Item;
10
import com.vaadin.data.util.sqlcontainer.RowId;
11
import com.vaadin.data.util.sqlcontainer.RowItem;
5 12
import com.vaadin.data.util.sqlcontainer.SQLContainer;
6 13
import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
7 14
import com.vaadin.data.util.sqlcontainer.query.QueryDelegate;
8 15
import com.vaadin.data.util.sqlcontainer.query.TableQuery;
9
import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator;
10 16

  
11 17
import eu.etaxonomy.cdm.vaadin.util.CdmSpringContextHelper;
12 18

  
13 19
public class CdmSQLContainer extends SQLContainer {
14 20

  
21
    private static final Logger logger = Logger.getLogger(CdmSQLContainer.class);
22

  
15 23
    JDBCConnectionPool pool;
16 24

  
25
    private int contentChangedEventsDisabledCount = 0;
26

  
27
    private boolean contentsChangedEventPending;
28

  
29
    private final Map<RowId, RowItem> addedItems = new HashMap<RowId, RowItem>();
17 30

  
18 31
    public CdmSQLContainer(QueryDelegate delegate) throws SQLException {
19 32
        super(delegate);
......
21 34

  
22 35
    public static CdmSQLContainer newInstance(String tableName) throws SQLException {
23 36
        // TODO : currently the sql generator is for h2, need to make this compatible for all flavours
24
        TableQuery tq = new TableQuery(tableName,CdmSpringContextHelper.getConnectionPool(), new DefaultSQLGenerator());
37
        TableQuery tq = new TableQuery(tableName,CdmSpringContextHelper.getConnectionPool());
25 38
        tq.setVersionColumn("updated");
26

  
27 39
        return new CdmSQLContainer(tq);
28 40

  
29 41
    }
30 42

  
43
    @Override
44
    public Item getItem(Object itemId) {
45
        RowItem rowItem = addedItems.get(itemId);
46
        if(rowItem != null) {
47
            return rowItem;
48
        } else {
49
            return super.getItem(itemId);
50
        }
51
    }
52

  
53
    public void addRowItem(RowItem rowItem) {
54
        addedItems.put(rowItem.getId(), rowItem);
55
    }
56

  
57
    @Override
58
    protected void fireContentsChange() {
59
        if (contentsChangeEventsOn()) {
60
            disableContentsChangeEvents();
61
            try {
62
                super.fireContentsChange();
63
            } finally {
64
                enableContentsChangeEvents();
65
            }
66
        } else {
67
            contentsChangedEventPending = true;
68
        }
69
    }
70

  
71
    protected boolean contentsChangeEventsOn() {
72
        return contentChangedEventsDisabledCount == 0;
73
    }
74

  
75
    protected void disableContentsChangeEvents() {
76
        contentChangedEventsDisabledCount++;
77
    }
78

  
79
    protected void enableContentsChangeEvents() {
80
        if (contentChangedEventsDisabledCount <= 0) {
81
            logger.warn("Mismatched calls to disable and enable contents change events in HierarchicalContainer");
82
            contentChangedEventsDisabledCount = 0;
83
        } else {
84
            contentChangedEventsDisabledCount--;
85
        }
86
        if (contentChangedEventsDisabledCount == 0) {
87
            if (contentsChangedEventPending) {
88
                //fireContentsChange();
89
            }
90
            contentsChangedEventPending = false;
91
        }
92
    }
93

  
31 94
}
src/main/java/eu/etaxonomy/cdm/vaadin/container/LeafNodeTaxonContainer.java
1 1
// $Id$
2 2
/**
3
* Copyright (C) 2015 EDIT
4
* European Distributed Institute of Taxonomy
5
* http://www.e-taxonomy.eu
6
*
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
3
 * Copyright (C) 2015 EDIT
4
 * European Distributed Institute of Taxonomy
5
 * http://www.e-taxonomy.eu
6
 *
7
 * The contents of this file are subject to the Mozilla Public License Version 1.1
8
 * See LICENSE.TXT at the top of this package for the full license terms.
9
 */
10 10
package eu.etaxonomy.cdm.vaadin.container;
11 11

  
12 12
import java.sql.SQLException;
13
import java.util.ArrayList;
14
import java.util.Collection;
15
import java.util.HashMap;
16
import java.util.HashSet;
17
import java.util.List;
18
import java.util.Map;
19
import java.util.Set;
20

  
21
import org.apache.log4j.Logger;
13 22

  
14
import com.vaadin.data.util.sqlcontainer.SQLContainer;
15
import com.vaadin.data.util.sqlcontainer.query.QueryDelegate;
23
import com.vaadin.data.Container;
24
import com.vaadin.data.Property;
25
import com.vaadin.data.util.filter.Compare;
26
import com.vaadin.data.util.filter.IsNull;
27
import com.vaadin.data.util.filter.Not;
28
import com.vaadin.data.util.filter.SimpleStringFilter;
29
import com.vaadin.data.util.sqlcontainer.RowItem;
30

  
31
import eu.etaxonomy.cdm.vaadin.util.CdmQueryFactory;
16 32

  
17 33
/**
18 34
 * @author cmathew
19 35
 * @date 10 Mar 2015
20 36
 *
21 37
 */
22
public class LeafNodeTaxonContainer extends SQLContainer {
38
public class LeafNodeTaxonContainer extends CdmSQLContainer implements Container.Hierarchical  {
39

  
40
    private static final Logger logger = Logger.getLogger(LeafNodeTaxonContainer.class);
41

  
42
    public static final String ID = "Id";
43
    public static final String NAME_ID = "Name";
44
    public static final String ACCTAXON_ID = "AccTaxonId";
45
    public static final String PB_ID = "Pb";
46
    public static final String FN_ID = "Fn";
47
    public static final String UNP_ID = "Unp";
48
    public static final String UNR_ID = "Unr";
49
    public static final String RANK_ID = "Rank";
50
    public static final String HAS_SYN_ID = "HasSynonyms";
51

  
52
    public Set<Filter> currentFilters;
53

  
54

  
55
    private Filter nrFilter, unpFilter, unfFilter, unpbFilter, rankFilter,  classificationFilter, synonymFilter;
56
    private SimpleStringFilter nameFilter;
57

  
58
    private int classificationId = -1;
59

  
60
    private final Map<Object,List<Object>> taxonSynonymMap;
61

  
62
    private final CdmSQLContainer synonymContainer;
63

  
23 64

  
24 65
    /**
25 66
     * @param delegate
26 67
     * @throws SQLException
27 68
     */
28
    public LeafNodeTaxonContainer(QueryDelegate delegate) throws SQLException {
29
        super(delegate);
30
        // TODO Auto-generated constructor stub
69
    public LeafNodeTaxonContainer(int classificationId) throws SQLException {
70
        super(CdmQueryFactory.generateTaxonBaseQuery(ID, NAME_ID, PB_ID, UNP_ID, RANK_ID, HAS_SYN_ID));
71
        this.synonymContainer = new CdmSQLContainer(CdmQueryFactory.generateSynonymofTaxonQuery(ID, NAME_ID));
72
        this.classificationId = classificationId;
73
        taxonSynonymMap = new HashMap<Object,List<Object>>();
74
        initFilters();
75
        addContainerFilter(classificationFilter);
76
        addContainerFilter(rankFilter);
77
    }
78

  
79
    private void initFilters() {
80
        //nrFilter = new Compare.Equal(StatusPresenter.UNR_ID, true);
81
        unpFilter = new Compare.Equal("tb.unplaced", true);
82
        //unfFilter = new Compare.Equal(StatusPresenter.FN_ID, false);
83
        unpbFilter = new Compare.Equal("tb.publish", false);
84
        classificationFilter = new Compare.Equal("tn.classification_id",classificationId);
85
        rankFilter = new Compare.Equal("dtb.titleCache","Species");
86
        synonymFilter = new Not(new IsNull("sr.relatedto_id"));
87

  
88
        currentFilters = new HashSet<Filter>();
89
    }
90

  
91

  
92

  
93
    public void setUnplacedFilter() {
94
        addContainerFilter(unpFilter);
95
    }
96

  
97

  
98
    public void removeUnplacedFilter() {
99
        removeContainerFilter(unpFilter);
100
    }
101

  
102

  
103
    public void setUnpublishedFilter() {
104
        addContainerFilter(unpbFilter);
105
    }
106

  
107

  
108
    public void removeUnpublishedFilter() {
109
        removeContainerFilter(unpbFilter);
110
    }
111

  
112

  
113
    public void setNameFilter(String filterString) {
114
        removeNameFilter();
115
        nameFilter = new SimpleStringFilter("tnb.titleCache", filterString, true, true);
116
        addContainerFilter(nameFilter);
31 117
    }
32 118

  
119

  
120
    public void removeNameFilter() {
121
        removeContainerFilter(nameFilter);
122
    }
123

  
124
    public int getTotalNoOfTaxa() {
125
        return size();
126
    }
127

  
128

  
129
    /* (non-Javadoc)
130
     * @see com.vaadin.data.Container.Hierarchical#getChildren(java.lang.Object)
131
     */
132
    @Override
133
    public Collection<?> getChildren(Object itemId) {
134
        List<Object> synList = taxonSynonymMap.get(itemId);
135
        if(synList != null) {
136
            return synList;
137
        }
138
        //synonymContainer.disableContentsChangeEvents();
139
        try {
140
            Filter synonymOfTaxonFilter = new Compare.Equal("sr.relatedto_id", Integer.valueOf(itemId.toString()));
141
            synonymContainer.addContainerFilter(synonymOfTaxonFilter);
142
            synList = new ArrayList<Object>();
143
            synList.addAll(synonymContainer.getItemIds());
144
            for(Object synItemId : synList) {
145
                addRowItem((RowItem) synonymContainer.getItem(synItemId));
146
            }
147
            synonymContainer.removeAllContainerFilters();
148
            // cache the synonyms for later
149
            taxonSynonymMap.put(itemId, synList);
150

  
151
            return synList;
152
        } finally {
153
            //synonymContainer.enableContentsChangeEvents();
154
        }
155

  
156

  
157
    }
158

  
159
    /* (non-Javadoc)
160
     * @see com.vaadin.data.Container.Hierarchical#getParent(java.lang.Object)
161
     */
162
    @Override
163
    public Object getParent(Object itemId) {
164
        return null;
165
    }
166

  
167
    /* (non-Javadoc)
168
     * @see com.vaadin.data.Container.Hierarchical#rootItemIds()
169
     */
170
    @Override
171
    public Collection<?> rootItemIds() {
172
//
173
//        disableContentsChangeEvents();
174
//        try {
175
//            Collection<?> taxontemIds = getItemIds();
176
//            return taxontemIds;
177
//        } finally {
178
//            enableContentsChangeEvents();
179
//        }
180

  
181
        return getItemIds();
182
    }
183

  
184
    /* (non-Javadoc)
185
     * @see com.vaadin.data.Container.Hierarchical#setParent(java.lang.Object, java.lang.Object)
186
     */
187
    @Override
188
    public boolean setParent(Object itemId, Object newParentId) throws UnsupportedOperationException {
189
        return true;
190
    }
191

  
192
    /* (non-Javadoc)
193
     * @see com.vaadin.data.Container.Hierarchical#areChildrenAllowed(java.lang.Object)
194
     */
195
    @Override
196
    public boolean areChildrenAllowed(Object itemId) {
197

  
198
        Property hasSynProperty = getItem(itemId).getItemProperty(HAS_SYN_ID);
199
        if(hasSynProperty == null) {
200
            return false;
201
        }
202
        return (Long)hasSynProperty.getValue() > 0;
203

  
204

  
205
    }
206

  
207
    /* (non-Javadoc)
208
     * @see com.vaadin.data.Container.Hierarchical#setChildrenAllowed(java.lang.Object, boolean)
209
     */
210
    @Override
211
    public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) throws UnsupportedOperationException {
212
        return true;
213
    }
214

  
215
    /* (non-Javadoc)
216
     * @see com.vaadin.data.Container.Hierarchical#isRoot(java.lang.Object)
217
     */
218
    @Override
219
    public boolean isRoot(Object itemId) {
220
        return true;
221
    }
222

  
223
    /* (non-Javadoc)
224
     * @see com.vaadin.data.Container.Hierarchical#hasChildren(java.lang.Object)
225
     */
226
    @Override
227
    public boolean hasChildren(Object itemId) {
228
        return true;
229
    }
230

  
231

  
232

  
33 233
}
src/main/java/eu/etaxonomy/cdm/vaadin/presenter/StatusPresenter.java
11 11

  
12 12
import java.sql.SQLException;
13 13

  
14
import com.vaadin.data.Container.Filter;
15
import com.vaadin.data.util.filter.Compare;
16
import com.vaadin.data.util.filter.Compare.Equal;
17
import com.vaadin.data.util.filter.SimpleStringFilter;
18
import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
19 14
import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
20 15

  
21 16
import eu.etaxonomy.cdm.vaadin.container.CdmSQLContainer;
22 17
import eu.etaxonomy.cdm.vaadin.container.LeafNodeTaxonContainer;
23
import eu.etaxonomy.cdm.vaadin.statement.CdmStatementDelegate;
24
import eu.etaxonomy.cdm.vaadin.util.CdmSpringContextHelper;
25 18
import eu.etaxonomy.cdm.vaadin.util.CdmSQLStringDecorator;
26 19
import eu.etaxonomy.cdm.vaadin.view.IStatusComposite;
27 20
import eu.etaxonomy.cdm.vaadin.view.IStatusComposite.StatusComponentListener;
......
33 26
 */
34 27
public class StatusPresenter implements StatusComponentListener {
35 28

  
36
    public static final String NAME_ID = "Name";
37
    public static final String PB_ID = "Pb";
38
    public static final String FN_ID = "Fn";
39
    public static final String UNP_ID = "Unp";
40
    public static final String UNR_ID = "Unr";
41

  
42
    private static final String FROM_QUERY = " FROM TaxonNode tn inner join TaxonBase tb on tn.taxon_id=tb.id inner join TaxonNameBase tnb on tb.name_id=tnb.id  inner join DefinedTermBase dtb on tnb.rank_id=dtb.id";
43
    private static final String SELECT_QUERY="SELECT tb.id as taxon_id, tnb.titleCache as " + NAME_ID + " , tb.publish as " + PB_ID + " , tb.unplaced as " +  UNP_ID + FROM_QUERY;
44
    private static final String COUNT_QUERY = "SELECT count(*) " + FROM_QUERY;
45

  
46
    private static final String CONTAINS_QUERY = "SELECT * FROM TaxonBase tb WHERE tb.id = ?";
47

  
48 29
    private final IStatusComposite composite;
49 30

  
50 31
    private LeafNodeTaxonContainer container;
51 32

  
52
    private Equal nrFilter, unpFilter, unfFilter, unpbFilter;
53
    private SimpleStringFilter nameFilter;
54 33

  
55
    private int totalNoOfItems = 0;
34

  
35
    private int totalNoOfTaxa = 0;
56 36

  
57 37
    public StatusPresenter(IStatusComposite composite) {
58 38
        this.composite = composite;
59 39
        composite.setListener(this);
60
        initFilters();
61 40
        // TODO: Need to evaluate the various sql dialects and make sure that these
62 41
        // queries are compatible with all
63 42
        QueryBuilder.setStringDecorator(new CdmSQLStringDecorator());
64 43
    }
65 44

  
66
    private void initFilters() {
67
        //nrFilter = new Compare.Equal(StatusPresenter.UNR_ID, true);
68
        unpFilter = new Compare.Equal("tb.unplaced", true);
69
        //unfFilter = new Compare.Equal(StatusPresenter.FN_ID, false);
70
        unpbFilter = new Compare.Equal("tb.publish", false);
45

  
46
    @Override
47
    public void removeFilters() {
48
        removeUnplacedFilter();
49
        removeUnpublishedFilter();
50
        removeNameFilter();
71 51
    }
72 52

  
73 53
    /* (non-Javadoc)
......
75 55
     */
76 56
    @Override
77 57
    public LeafNodeTaxonContainer loadTaxa(int classificationId) throws SQLException {
78
        FreeformQuery query = new FreeformQuery("This query is not used", CdmSpringContextHelper.getConnectionPool(), "taxon_id");
79
        CdmStatementDelegate cdmStatementDelegate = new CdmStatementDelegate(SELECT_QUERY, COUNT_QUERY, CONTAINS_QUERY);
80
        query.setDelegate(cdmStatementDelegate);
81

  
82
        Filter rankFilter = new Compare.Equal("dtb.titleCache","Species");
83
        Filter classifcationFilter = new Compare.Equal("tn.classification_id",classificationId);
84

  
85
        container = new LeafNodeTaxonContainer(query);
86
        //container.addContainerFilter(rankFilter);
87
        container.addContainerFilter(classifcationFilter);
88
        totalNoOfItems = container.size();
58
        container = new LeafNodeTaxonContainer(classificationId);
59
        totalNoOfTaxa = container.getTotalNoOfTaxa();
89 60
        return container;
90 61
    }
91 62

  
63
    @Override
64
    public void refresh() {
65
        container.refresh();
66
    }
92 67
    @Override
93 68
    public void setUnplacedFilter() {
94
        container.addContainerFilter(unpFilter);
69
        container.setUnplacedFilter();
95 70
    }
96 71

  
97 72
    @Override
98 73
    public void removeUnplacedFilter() {
99
        container.removeContainerFilter(unpFilter);
74
        container.removeUnplacedFilter();
100 75
    }
101 76

  
102 77
    @Override
103 78
    public void setUnpublishedFilter() {
104
        container.addContainerFilter(unpbFilter);
79
        container.setUnpublishedFilter();
105 80
    }
106 81

  
107 82
    @Override
108 83
    public void removeUnpublishedFilter() {
109
        container.removeContainerFilter(unpbFilter);
84
        container.removeUnpublishedFilter();
110 85
    }
111 86

  
112 87
    @Override
113 88
    public void setNameFilter(String filterString) {
114
        removeNameFilter();
115
        nameFilter = new SimpleStringFilter("tnb.titleCache", filterString, true, true);
116
        container.addContainerFilter(nameFilter);
89
        container.setNameFilter(filterString);
117 90
    }
118 91

  
119 92
    @Override
120 93
    public void removeNameFilter() {
121
        container.removeContainerFilter(nameFilter);
94
        container.removeNameFilter();
122 95
    }
123 96

  
124 97
    @Override
125
    public int getCurrentSize() {
98
    public int getCurrentNoOfTaxa() {
126 99
        return container.size();
127 100
    }
128 101

  
129 102
    @Override
130
    public int getSize() {
131
        return totalNoOfItems;
103
    public int getTotalNoOfTaxa() {
104
        return totalNoOfTaxa;
105
    }
106

  
107
    @Override
108
    public void addChildren(Object parentItemId) {
109
        //container.addChildren(parentItemId);
132 110
    }
133 111

  
134 112
    /* (non-Javadoc)
......
140 118
        return container;
141 119
    }
142 120

  
121

  
143 122
}
src/main/java/eu/etaxonomy/cdm/vaadin/ui/StatusEditorUI.java
29 29
import eu.etaxonomy.cdm.vaadin.view.StatusEditorView;
30 30

  
31 31

  
32
@Theme("mytheme")
32
@Theme("edit")
33 33
public class StatusEditorUI extends AbstractAuthenticatedUI {
34 34

  
35 35
    Navigator navigator;
......
47 47
    @Override
48 48
    protected void doInit() {
49 49
        // FIXME: remove this when testing is done
50
        setIgnoreAuthentication(true);
50
        //setIgnoreAuthentication(true);
51 51

  
52 52
        getPage().setTitle("Status Editor");
53 53
        StatusEditorView statusEditorView = new StatusEditorView();
src/main/java/eu/etaxonomy/cdm/vaadin/util/CdmQueryFactory.java
1
// $Id$
2
/**
3
* Copyright (C) 2015 EDIT
4
* European Distributed Institute of Taxonomy
5
* http://www.e-taxonomy.eu
6
*
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10
package eu.etaxonomy.cdm.vaadin.util;
11

  
12
import java.sql.SQLException;
13

  
14
import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
15
import com.vaadin.data.util.sqlcontainer.query.QueryDelegate;
16

  
17
import eu.etaxonomy.cdm.vaadin.statement.CdmStatementDelegate;
18

  
19
/**
20
 * @author cmathew
21
 * @date 1 Apr 2015
22
 *
23
 */
24
public class CdmQueryFactory {
25

  
26
    public static QueryDelegate generateTaxonBaseQuery(String id,
27
            String name_id,
28
            String pb_id,
29
            String unp_id,
30
            String rank_id,
31
            String has_syn_id) throws SQLException {
32
        String FROM_QUERY = " FROM TaxonBase tb " +
33
                "INNER JOIN TaxonNode tn on tn.taxon_id=tb.id " +
34
                "INNER JOIN TaxonNameBase tnb on tb.name_id=tnb.id " +
35
                "INNER JOIN DefinedTermBase dtb on tnb.rank_id=dtb.id  ";
36
        String SELECT_QUERY="SELECT tb.id as " + id +
37
                ", tnb.titleCache as " + name_id +
38
                ", tb.publish as " + pb_id +
39
                ", tb.unplaced as " + unp_id +
40
                ", dtb.titleCache as " + rank_id +
41
                ", (SELECT COUNT(*) FROM  SynonymRelationship sr WHERE tb.id = sr.relatedto_id) as " + has_syn_id +
42
                FROM_QUERY;
43
        String COUNT_QUERY = "SELECT count(*) " + FROM_QUERY;
44
        String CONTAINS_QUERY = "SELECT * FROM TaxonBase tb WHERE tb.id = ?";
45

  
46
        return generateQueryDelegate(SELECT_QUERY, COUNT_QUERY, CONTAINS_QUERY, id);
47
    }
48

  
49
    public static QueryDelegate generateSynonymofTaxonQuery(String id,
50
            String name_id) throws SQLException {
51
        String FROM_QUERY = " FROM TaxonBase tb " +
52
                "INNER JOIN TaxonNameBase tnb on tb.name_id=tnb.id " +
53
                "INNER JOIN SynonymRelationship sr on tb.id=sr.relatedfrom_id ";
54
        String SELECT_QUERY="SELECT tb.id as " + id +
55
                ", tnb.titleCache as " + name_id +
56
                FROM_QUERY;
57
        String COUNT_QUERY = "SELECT count(*) " + FROM_QUERY;
58
        String CONTAINS_QUERY = "SELECT * FROM SynonymRelationship sr WHERE sr.relatedfrom_id = ?";
59

  
60
        return generateQueryDelegate(SELECT_QUERY, COUNT_QUERY, CONTAINS_QUERY, id);
61
    }
62

  
63
    public static QueryDelegate generateQueryDelegate(String SELECT_QUERY, String COUNT_QUERY, String CONTAINS_QUERY, String id) throws SQLException {
64
        FreeformQuery query = new FreeformQuery("This query is not used", CdmSpringContextHelper.getConnectionPool(), id);
65
        CdmStatementDelegate delegate = new CdmStatementDelegate(SELECT_QUERY, COUNT_QUERY, CONTAINS_QUERY);
66
        query.setDelegate(delegate);
67
        return query;
68
    }
69

  
70
}
src/main/java/eu/etaxonomy/cdm/vaadin/view/IStatusComposite.java
40 40
         *
41 41
         */
42 42
        public void removeUnpublishedFilter();
43

  
44
        /**
45
         * @param filterString
46
         */
47
        public void setNameFilter(String filterString);
48
        /**
49
         *
50
         */
51
        public void removeNameFilter();
52

  
43 53
        /**
44 54
         * @return
45 55
         */
46
        public int getCurrentSize();
56
        public int getCurrentNoOfTaxa();
57

  
47 58
        /**
48 59
         * @return
49 60
         */
50
        public int getSize();
61
        public int getTotalNoOfTaxa();
51 62
        /**
52
         * @param filterString
63
         *
53 64
         */
54
        public void setNameFilter(String filterString);
65
        public void refresh();
55 66
        /**
56 67
         *
57 68
         */
58
        public void removeNameFilter();
69
        public void removeFilters();
70
        /**
71
         * @param parentItemId
72
         */
73
        public void addChildren(Object parentItemId);
59 74
    }
60 75

  
61 76
    public void setListener(StatusComponentListener listener);
src/test/java/eu/etaxonomy/cdm/vaadin/presenter/StatusPresenterTest.java
56 56
            String taxon = (String)item.getItemProperty("Name").getValue();
57 57
            logger.info("taxon : " + taxon);
58 58
        }
59
        Assert.assertEquals(4,itemIds.size());
59
        Assert.assertEquals(3,itemIds.size());
60 60

  
61 61
        sp.setUnplacedFilter();
62 62
        itemIds = container.getItemIds();
......
64 64

  
65 65
        sp.removeUnplacedFilter();
66 66
        itemIds = container.getItemIds();
67
        Assert.assertEquals(4,itemIds.size());
67
        Assert.assertEquals(3,itemIds.size());
68 68

  
69 69
        sp.setNameFilter("Taxon A");
70 70
        itemIds = container.getItemIds();
71 71
        Assert.assertEquals(1,itemIds.size());
72

  
73

  
74
    }
75

  
76
    @Test
77
    public void testLoadSynonyms() throws SQLException {
78
        LeafNodeTaxonContainer container = sp.loadTaxa(11);
79
        container.refresh();
80
        Collection<?> rootItemIds = container.rootItemIds();
81
        Assert.assertEquals(3,rootItemIds.size());
82

  
83
        Collection<?> childIds = container.getChildren(10);
84
        Assert.assertEquals(2, childIds.size());
85

  
86
        // FIXME : Need to check why these calls thorw a NPE
87
        // in the case of h2
88
        //Assert.assertEquals(true, container.areChildrenAllowed(10));
89
        //Assert.assertEquals(false, container.areChildrenAllowed(11));
72 90
    }
73 91

  
74 92
    @Ignore
src/test/resources/eu/etaxonomy/cdm/vaadin/presenter/StatusPresenterTest.xml
1 1
<?xml version="1.0" encoding="UTF-8"?><!--
2
  generated by Jailer 4.3, Tue Mar 10 14:42:57 CET 2015 from cmathew@cmbgbm-t530
2
  generated by Jailer 4.3, Wed Apr 01 11:37:10 CEST 2015 from cmathew@cmbgbm-t530
3 3
  
4
  Extraction Model:  all rows from Classification (extractionmodel/by-example/SbE-Classification-14-42-42-331.csv)
4
  Extraction Model:  all rows from Classification (extractionmodel/by-example/SbE-Classification-11-36-57-404.csv)
5 5
  Database URL:      jdbc:mysql://127.0.0.1:3306/local-redlist
6 6
  Database User:     root
7 7
  
8
  Exported Rows:     27
8
  Exported Rows:     45
9 9
      Classification                 2
10 10
      DefinedTermBase                2
11
      TaxonBase                      7
12
      TaxonNameBase                  7
11
      SynonymRelationship            6
12
      TaxonBase                      13
13
      TaxonNameBase                  13
13 14
      TaxonNode                      9
14 15
  
15 16
--><dataset>
......
24 25
  <TaxonNode id="20" created="2015-03-10 13:40:31.0" uuid="6a6ee4dd-5727-47ba-a53d-3a985623dd93" updated="2015-03-10 13:40:31.0" countchildren="0" sortindex="3" treeindex="#t11#11#20#" createdby_id="10" updatedby_id="10" classification_id="11" parent_id="11" taxon_id="30"/>
25 26

  
26 27
  <TaxonNameBase DTYPE="BotanicalName" id="10" created="2015-03-09 15:49:22.0" uuid="9c0b6c13-562e-4642-9494-58dbcedf45f4" updated="2015-03-09 15:49:25.0" protectedtitlecache="false" titleCache="Taxon A" parsingproblem="0" problemends="5" problemstarts="0" protectedfulltitlecache="false" authorshipcache="A" binomhybrid="false" genusoruninomial="Taxon" hybridformula="false" monomhybrid="false" namecache="Taxon" protectedauthorshipcache="false" protectednamecache="false" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="10" rank_id="790" combinationauthorteam_id="10"/>
28
  <TaxonNameBase DTYPE="BotanicalName" id="11" created="2015-03-09 15:49:30.0" uuid="82de3687-f90d-4968-951b-456a21659666" updated="2015-03-09 15:50:21.0" protectedtitlecache="true" titleCache="HTSynonym A1" fullTitleCache="HTSynonym A1" parsingproblem="4" problemends="12" problemstarts="0" protectedfulltitlecache="true" authorshipcache="" binomhybrid="false" hybridformula="false" monomhybrid="false" namecache="HTSynonym A1" protectedauthorshipcache="false" protectednamecache="true" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="11"/>
29
  <TaxonNameBase DTYPE="BotanicalName" id="12" created="2015-03-09 15:50:25.0" uuid="bd86d4f9-8427-4ac5-a8c2-48add63da449" updated="2015-03-09 15:50:54.0" protectedtitlecache="true" titleCache="HMSynonym A1" fullTitleCache="HMSynonym A1" parsingproblem="4" problemends="12" problemstarts="0" protectedfulltitlecache="true" authorshipcache="" binomhybrid="false" hybridformula="false" monomhybrid="false" namecache="HMSynonym A1" protectedauthorshipcache="false" protectednamecache="true" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="10"/>
27 30
  <TaxonNameBase DTYPE="BotanicalName" id="13" created="2015-03-09 15:51:11.0" uuid="fb76b9cb-29d2-4986-a327-19d1d003159a" updated="2015-03-09 15:51:14.0" protectedtitlecache="false" titleCache="Taxon B" fullTitleCache="Taxon B" parsingproblem="0" problemends="5" problemstarts="0" protectedfulltitlecache="false" authorshipcache="B" binomhybrid="false" genusoruninomial="Taxon" hybridformula="false" monomhybrid="false" namecache="Taxon" protectedauthorshipcache="false" protectednamecache="false" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="12" rank_id="790" combinationauthorteam_id="11"/>
28 31
  <TaxonNameBase DTYPE="BotanicalName" id="14" created="2015-03-09 15:51:24.0" uuid="a21d5e7c-e8b5-4395-b83b-a219877e80eb" updated="2015-03-09 15:51:25.0" protectedtitlecache="false" titleCache="Taxon C" parsingproblem="0" problemends="5" problemstarts="0" protectedfulltitlecache="false" authorshipcache="C" binomhybrid="false" genusoruninomial="Taxon" hybridformula="false" monomhybrid="false" namecache="Taxon" protectedauthorshipcache="false" protectednamecache="false" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="13" rank_id="790" combinationauthorteam_id="12"/>
32
  <TaxonNameBase DTYPE="BotanicalName" id="15" created="2015-03-09 15:51:31.0" uuid="7dd4eaa3-b65f-4d1e-8d2c-26a31ea3ae0b" updated="2015-03-09 15:51:44.0" protectedtitlecache="true" titleCache="HTSynonym C1" fullTitleCache="HTSynonym C1" parsingproblem="4" problemends="12" problemstarts="0" protectedfulltitlecache="true" authorshipcache="" binomhybrid="false" hybridformula="false" monomhybrid="false" namecache="HTSynonym C1" protectedauthorshipcache="false" protectednamecache="true" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="13"/>
29 33
  <TaxonNameBase DTYPE="BotanicalName" id="16" created="2015-03-09 15:52:34.0" uuid="81444d5e-122f-46aa-9bee-d7c0ba52f8d6" updated="2015-03-09 15:52:42.0" protectedtitlecache="false" titleCache="Taxon A" parsingproblem="0" problemends="5" problemstarts="0" protectedfulltitlecache="false" authorshipcache="A" binomhybrid="false" genusoruninomial="Taxon" hybridformula="false" monomhybrid="false" namecache="Taxon" protectedauthorshipcache="false" protectednamecache="false" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="14" rank_id="790" combinationauthorteam_id="13"/>
34
  <TaxonNameBase DTYPE="BotanicalName" id="17" created="2015-03-09 15:52:53.0" uuid="dcdfbc9f-5596-4ae2-85e0-b9c738d8bcec" updated="2015-03-09 15:52:57.0" protectedtitlecache="true" titleCache="HMSynonym A1" fullTitleCache="HMSynonym A1" parsingproblem="4" problemends="12" problemstarts="0" protectedfulltitlecache="true" authorshipcache="" binomhybrid="false" hybridformula="false" monomhybrid="false" namecache="HMSynonym A1" protectedauthorshipcache="false" protectednamecache="true" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="14"/>
35
  <TaxonNameBase DTYPE="BotanicalName" id="18" created="2015-03-09 15:53:06.0" uuid="fa186915-0bb5-4047-a5c5-404d75851f1c" updated="2015-03-09 15:53:07.0" protectedtitlecache="true" titleCache="HTSynonym A1" fullTitleCache="HTSynonym A1" parsingproblem="4" problemends="12" problemstarts="0" protectedfulltitlecache="true" authorshipcache="" binomhybrid="false" hybridformula="false" monomhybrid="false" namecache="HTSynonym A1" protectedauthorshipcache="false" protectednamecache="true" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="15"/>
30 36
  <TaxonNameBase DTYPE="BotanicalName" id="19" created="2015-03-09 15:53:21.0" uuid="fddf69fa-4f25-4d10-b693-1a9d5d7bbd5c" updated="2015-03-09 15:53:23.0" protectedtitlecache="false" titleCache="Taxon B" fullTitleCache="Taxon B" parsingproblem="0" problemends="5" problemstarts="0" protectedfulltitlecache="false" authorshipcache="B" binomhybrid="false" genusoruninomial="Taxon" hybridformula="false" monomhybrid="false" namecache="Taxon" protectedauthorshipcache="false" protectednamecache="false" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="16" rank_id="790" combinationauthorteam_id="14"/>
31 37
  <TaxonNameBase DTYPE="BotanicalName" id="20" created="2015-03-09 15:53:30.0" uuid="9e644031-9190-4a4f-94bb-fc1f6066bbab" updated="2015-03-09 15:53:32.0" protectedtitlecache="false" titleCache="Taxon C" parsingproblem="0" problemends="5" problemstarts="0" protectedfulltitlecache="false" authorshipcache="C" binomhybrid="false" genusoruninomial="Taxon" hybridformula="false" monomhybrid="false" namecache="Taxon" protectedauthorshipcache="false" protectednamecache="false" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="17" rank_id="790" combinationauthorteam_id="15"/>
38
  <TaxonNameBase DTYPE="BotanicalName" id="21" created="2015-03-09 15:53:49.0" uuid="0755d9d7-007a-4d81-a2f8-2ba1b7020cf4" updated="2015-03-09 15:53:52.0" protectedtitlecache="true" titleCache="HTSynonym C1" fullTitleCache="HTSynonym C1" parsingproblem="4" problemends="12" problemstarts="0" protectedfulltitlecache="true" authorshipcache="" binomhybrid="false" hybridformula="false" monomhybrid="false" namecache="HTSynonym C1" protectedauthorshipcache="false" protectednamecache="true" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="17"/>
32 39
  <TaxonNameBase DTYPE="BotanicalName" id="30" created="2015-03-10 13:40:30.0" uuid="b1b9abf0-72a6-4a2e-8bd1-3ef189f5b3e9" updated="2015-03-10 13:40:31.0" protectedtitlecache="false" titleCache="Taxon D" fullTitleCache="Taxon D" parsingproblem="1" problemends="5" problemstarts="0" protectedfulltitlecache="false" authorshipcache="D" binomhybrid="false" genusoruninomial="Taxon" hybridformula="false" monomhybrid="false" namecache="Taxon" protectedauthorshipcache="false" protectednamecache="false" trinomhybrid="false" anamorphic="false" createdby_id="10" updatedby_id="10" homotypicalgroup_id="20" rank_id="800" combinationauthorteam_id="20"/>
33 40

  
34 41
  <Classification id="11" created="2015-03-09 15:48:30.0" uuid="6595638e-4993-421a-9fe5-76b09d94f36a" updated="2015-03-09 15:48:42.0" protectedtitlecache="false" titleCache="Classification1" createdby_id="10" updatedby_id="10" name_id="11" rootnode_id="11"/>
35 42
  <Classification id="12" created="2015-03-09 15:52:08.0" uuid="1ef8aada-de72-4023-bbe1-14465b6bc60d" updated="2015-03-09 15:52:24.0" protectedtitlecache="false" titleCache="Classification2" createdby_id="10" updatedby_id="10" name_id="12" rootnode_id="15"/>
36 43

  
37 44
  <TaxonBase DTYPE="Taxon" id="10" created="2015-03-09 15:49:22.0" uuid="666b484f-dc1e-4578-b404-86bc6d2e47fa" updated="2015-03-09 15:49:25.0" protectedtitlecache="false" titleCache="Taxon A sec. ???" doubtful="false" publish="true" usenamecache="false" excluded="false" taxonstatusunknown="false" taxonomicchildrencount="0" unplaced="true" createdby_id="10" updatedby_id="10" name_id="10"/>
45
  <TaxonBase DTYPE="Synonym" id="11" created="2015-03-09 15:49:30.0" uuid="f45a4860-451d-493c-ad42-bbe68325a883" updated="2015-03-09 15:50:21.0" protectedtitlecache="false" titleCache="HTSynonym A1 sec. ???" doubtful="false" publish="true" usenamecache="false" createdby_id="10" updatedby_id="10" name_id="11"/>
46
  <TaxonBase DTYPE="Synonym" id="12" created="2015-03-09 15:50:25.0" uuid="cdd8945e-d538-4141-8c1b-78c93a8e3a8b" updated="2015-03-09 15:50:54.0" protectedtitlecache="false" titleCache="HMSynonym A1 sec. ???" doubtful="false" publish="true" usenamecache="false" createdby_id="10" updatedby_id="10" name_id="12"/>
38 47
  <TaxonBase DTYPE="Taxon" id="13" created="2015-03-09 15:51:11.0" uuid="77e7d93e-75c6-4dd4-850d-7b5809654378" updated="2015-03-09 15:51:14.0" protectedtitlecache="false" titleCache="Taxon B sec. ???" doubtful="false" publish="true" usenamecache="false" excluded="false" taxonstatusunknown="false" taxonomicchildrencount="0" unplaced="false" createdby_id="10" updatedby_id="10" name_id="13"/>
39 48
  <TaxonBase DTYPE="Taxon" id="14" created="2015-03-09 15:51:24.0" uuid="b38d0d73-9a20-4894-99bb-2148ee6b10d0" updated="2015-03-09 15:51:25.0" protectedtitlecache="false" titleCache="Taxon C sec. ???" doubtful="false" publish="true" usenamecache="false" excluded="false" taxonstatusunknown="false" taxonomicchildrencount="0" unplaced="false" createdby_id="10" updatedby_id="10" name_id="14"/>
49
  <TaxonBase DTYPE="Synonym" id="15" created="2015-03-09 15:51:31.0" uuid="1e240011-aec1-4f94-a934-f3bd0e9df9a5" updated="2015-03-09 15:51:44.0" protectedtitlecache="false" titleCache="HTSynonym C1 sec. ???" doubtful="false" publish="true" usenamecache="false" createdby_id="10" updatedby_id="10" name_id="15"/>
40 50
  <TaxonBase DTYPE="Taxon" id="16" created="2015-03-09 15:52:34.0" uuid="eaac797e-cac7-4649-97cf-c7b580076895" updated="2015-03-09 15:52:42.0" protectedtitlecache="false" titleCache="Taxon A sec. ???" doubtful="false" publish="true" usenamecache="false" excluded="false" taxonstatusunknown="false" taxonomicchildrencount="0" unplaced="true" createdby_id="10" updatedby_id="10" name_id="16"/>
51
  <TaxonBase DTYPE="Synonym" id="17" created="2015-03-09 15:52:53.0" uuid="5b6219d0-ae66-4a09-9b5f-af9fc418a085" updated="2015-03-09 15:52:57.0" protectedtitlecache="false" titleCache="HMSynonym A1 sec. ???" doubtful="false" publish="true" usenamecache="false" createdby_id="10" updatedby_id="10" name_id="17"/>
52
  <TaxonBase DTYPE="Synonym" id="18" created="2015-03-09 15:53:06.0" uuid="4a85597d-b116-41d1-805c-be8168f5715b" updated="2015-03-09 15:53:07.0" protectedtitlecache="false" titleCache="HTSynonym A1 sec. ???" doubtful="false" publish="true" usenamecache="false" createdby_id="10" updatedby_id="10" name_id="18"/>
41 53
  <TaxonBase DTYPE="Taxon" id="19" created="2015-03-09 15:53:21.0" uuid="5004a8e7-b907-4744-b67e-44ccb057ab3b" updated="2015-03-09 15:53:23.0" protectedtitlecache="false" titleCache="Taxon B sec. ???" doubtful="false" publish="true" usenamecache="false" excluded="false" taxonstatusunknown="false" taxonomicchildrencount="0" unplaced="false" createdby_id="10" updatedby_id="10" name_id="19"/>
42 54
  <TaxonBase DTYPE="Taxon" id="20" created="2015-03-09 15:53:30.0" uuid="3d71c8b8-3bec-4f5f-ba23-6f9d55ef84e9" updated="2015-03-09 15:53:32.0" protectedtitlecache="false" titleCache="Taxon C sec. ???" doubtful="false" publish="true" usenamecache="false" excluded="false" taxonstatusunknown="false" taxonomicchildrencount="0" unplaced="false" createdby_id="10" updatedby_id="10" name_id="20"/>
55
  <TaxonBase DTYPE="Synonym" id="21" created="2015-03-09 15:53:49.0" uuid="cdd27491-1b41-4119-86f5-0ffd33475769" updated="2015-03-09 15:53:52.0" protectedtitlecache="false" titleCache="HTSynonym C1 sec. ???" doubtful="false" publish="true" usenamecache="false" createdby_id="10" updatedby_id="10" name_id="21"/>
43 56
  <TaxonBase DTYPE="Taxon" id="30" created="2015-03-10 13:40:30.0" uuid="5f713f69-e03e-4a11-8a55-700fbbf44805" updated="2015-03-10 13:40:31.0" protectedtitlecache="false" titleCache="Taxon D sec. ???" doubtful="false" publish="true" usenamecache="false" excluded="false" taxonstatusunknown="false" taxonomicchildrencount="0" unplaced="false" createdby_id="10" updatedby_id="10" name_id="30"/>
44 57

  
58
  <SynonymRelationship id="10" created="2015-03-09 15:49:30.0" uuid="f3b087a0-ff03-4a8c-97c1-c06a23d77ac0" updated="2015-03-09 15:50:21.0" doubtful="false" partial="false" proparte="false" createdby_id="10" updatedby_id="10" relatedfrom_id="11" relatedto_id="10" type_id="888"/>
59
  <SynonymRelationship id="11" created="2015-03-09 15:50:25.0" uuid="3d0d79b6-37b1-4541-a01d-35f88721a39b" updated="2015-03-09 15:50:54.0" doubtful="false" partial="false" proparte="false" createdby_id="10" updatedby_id="10" relatedfrom_id="12" relatedto_id="10" type_id="889"/>
60
  <SynonymRelationship id="12" created="2015-03-09 15:51:31.0" uuid="21e7c6f4-c029-49ad-9cf9-0b14186cd76a" updated="2015-03-09 15:51:44.0" doubtful="false" partial="false" proparte="false" createdby_id="10" updatedby_id="10" relatedfrom_id="15" relatedto_id="14" type_id="889"/>
61
  <SynonymRelationship id="13" created="2015-03-09 15:52:53.0" uuid="4bdc85a7-5af4-4744-b372-869bfbdc30e2" updated="2015-03-09 15:52:57.0" doubtful="false" partial="false" proparte="false" createdby_id="10" updatedby_id="10" relatedfrom_id="17" relatedto_id="16" type_id="889"/>
62
  <SynonymRelationship id="14" created="2015-03-09 15:53:06.0" uuid="3d2e320c-28cf-4925-b68d-249f95ba684a" updated="2015-03-09 15:53:07.0" doubtful="false" partial="false" proparte="false" createdby_id="10" updatedby_id="10" relatedfrom_id="18" relatedto_id="16" type_id="888"/>
63
  <SynonymRelationship id="15" created="2015-03-09 15:53:49.0" uuid="f0e2e376-91a2-459c-b460-1442a0be293a" updated="2015-03-09 15:53:52.0" doubtful="false" partial="false" proparte="false" createdby_id="10" updatedby_id="10" relatedfrom_id="21" relatedto_id="20" type_id="889"/>
64

  
45 65
  <DefinedTermBase DTYPE="Rank" id="790" created="2015-03-09 15:44:33.0" uuid="b301f787-f319-4ccc-a10f-b4ed3b99a86d" updated="2015-03-09 15:44:33.0" protectedtitlecache="false" titleCache="Species" termType="RK" uri="" idinvocabulary="sp." orderindex="44" rankclass="SP" vocabulary_id="15"/>
46 66
  <DefinedTermBase DTYPE="Rank" id="800" created="2015-03-09 15:44:33.0" uuid="1b11c34c-48a8-4efa-98d5-84f7f66ef43a" updated="2015-03-09 15:44:33.0" protectedtitlecache="false" titleCache="Genus" termType="RK" uri="" idinvocabulary="gen." orderindex="34" rankclass="GE" vocabulary_id="15"/>
47 67

  

Also available in: Unified diff