Project

General

Profile

« Previous | Next » 

Revision bf643f22

Added by Andreas Kohlbecker over 5 years ago

fix #7951 ReferenceLabelProvider to ellipsis the reference labels

View differences:

src/main/java/eu/etaxonomy/cdm/service/CdmFilterablePagingProviderFactory.java
39 39
        referenceOrderHints.add(OrderHint.ORDER_BY_TITLE_CACHE);
40 40
        referenceOrderHints.add(new OrderHint("issn", SortOrder.ASCENDING));
41 41
        referenceOrderHints.add(new OrderHint("isbn", SortOrder.ASCENDING));
42
        CdmFilterablePagingProvider<Reference,Reference> referencePagingProvider = new CdmFilterablePagingProvider<Reference, Reference>(repo.getReferenceService(), MatchMode.ANYWHERE, referenceOrderHints);
42
        CdmFilterablePagingProvider<Reference,Reference> pagingProvider = new CdmFilterablePagingProvider<Reference, Reference>(
43
                repo.getReferenceService(), MatchMode.ANYWHERE, referenceOrderHints);
43 44

  
44
        return referencePagingProvider;
45
        return pagingProvider;
46
    }
47

  
48
    public TypifiedEntityFilterablePagingProvider<Reference> referenceEntityReferencePagingProvider(ReferenceLabelProvider labelProvider, List<String> initStrategy){
49
        List<OrderHint> referenceOrderHints = new ArrayList<OrderHint>();
50
        referenceOrderHints.add(OrderHint.ORDER_BY_TITLE_CACHE);
51
        referenceOrderHints.add(new OrderHint("issn", SortOrder.ASCENDING));
52
        referenceOrderHints.add(new OrderHint("isbn", SortOrder.ASCENDING));
53
        TypifiedEntityFilterablePagingProvider<Reference> pagingProvider = new TypifiedEntityFilterablePagingProvider<Reference>(
54
                repo.getReferenceService(), MatchMode.ANYWHERE, referenceOrderHints, labelProvider);
55
        pagingProvider.setInitStrategy(initStrategy);
56

  
57
        return pagingProvider;
45 58
    }
46 59

  
47 60

  
src/main/java/eu/etaxonomy/cdm/service/ComboboxLabelProvider.java
1
/**
2
* Copyright (C) 2018 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.service;
10

  
11
import eu.etaxonomy.cdm.model.common.CdmBase;
12

  
13
/**
14
 * @author a.kohlbecker
15
 * @since Dec 12, 2018
16
 *
17
 */
18
public interface ComboboxLabelProvider<T extends CdmBase> {
19

  
20
    public String composeLabel(T entity, String filterString);
21

  
22
}
src/main/java/eu/etaxonomy/cdm/service/ReferenceLabelProvider.java
1
/**
2
* Copyright (C) 2018 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.service;
10

  
11
import java.util.Arrays;
12
import java.util.List;
13
import java.util.StringTokenizer;
14
import java.util.regex.Matcher;
15
import java.util.regex.Pattern;
16

  
17
import eu.etaxonomy.cdm.model.reference.Reference;
18

  
19
/**
20
 * Creates truncated labels for references by applying ellypsis on the reference authors and title for inReferences an
21
 * ellypsis is also being created.
22
 * <p>
23
 * Here are some examples:
24
 * <table>
25
 * <th>
26
 *  <td>original</td>
27
 *  <td>ellypsis</td></th>
28
 * <tr>
29
 * </tr>
30
 * <td>
31
 *   <td>Gottschling, M., Tillmann, U., Kusber, W.-H. & al., A Gordian knot: Nomenclature and taxonomy of Heterocapsa triquetra (Peridiniales: Heterocapsaceae) in Taxon 67(1): 179–185. 2018<td>
32
 *   </td>Gottschling, M.,…Kusber…, A Gordian knot:… in Taxon 67(1): 179–185. 2018</td>
33
 *   </tr>
34
 * <td>
35
 *   <td>Hamilton, P.B., Stachura-Suchoples, K., Kusber, W.-H. & al., Typification of the puzzling large diatom species Neidium iridis Ehrenb. in Cryptog. Algol.<td>
36
 *   </td>Hamilton, P.B.,…Kusber…, Typification of the… in Cryptog. Algol.</td>
37
 * </tr>
38
 * <td>
39
 * <td>Jahn , R., Kusber, W.-H. & Cocquyt, C., Differentiating Iconella from Surirella (Bacillariophyceae): typifying four Ehrenberg names and a preliminary checklist of the African taxa in PhytoKeys 82: 73-112<td>
40
 * </td>Jahn , R., Kusber, W.-H. & Cocquyt, C., Differentiating… in PhytoKeys 82: 73-112</td>
41
 * </tr>
42
 * <td>
43
 * <td>Jahn, R., Kusber, W.-H., Skibbe, O. & al., Gomphonella olivacea (Hornemann) Rabenhorst – a new phylogenetic position for a well-known taxon, its typification, new species and combinations in Cryptog. Algol.<td>
44
 * </td>Jahn, R., Kusber,…, Gomphonella olivacea… in Cryptog. Algol.</td>
45
 * </td>
46
 * </table>
47
 * @author a.kohlbecker
48
 * @since Dec 12, 2018
49
 *
50
 */
51
public class ReferenceLabelProvider implements ComboboxLabelProvider<Reference> {
52

  
53
    private static final String DELIM = " ";
54

  
55
    /**
56
     * This init strategy should be used when the ReferenceLabelProvider is being used
57
     * outside of a hibernate session
58
     */
59
    public static List<String> INIT_STRATEGY = Arrays.asList(
60
            "authorship",
61
            "inReference.authorship",
62
            "inReference.inReference.authorship",
63
            "inReference.inReference.inReference");
64

  
65
    public enum LabelType {
66
        NOMENCLATURAL,
67
        BIBLIOGRAPHIC;
68
    }
69

  
70
    private LabelType labelType;
71
    private int maxAuthorCharsVisible = 20;
72
    private int maxTitleCharsVisible = 20;
73

  
74
    private String MORE = "\u2026"; // 'HORIZONTAL ELLIPSIS' (U+2026)
75

  
76
    public ReferenceLabelProvider(LabelType labelType){
77
        this.labelType = labelType;
78
    }
79

  
80
    /**
81
     * {@inheritDoc}
82
     */
83
    @Override
84
    public String composeLabel(Reference entity, String filterString) {
85

  
86

  
87
        EllipsisData ed = ellypsis(entity, filterString);
88
        String label = ed.truncated;
89

  
90
        return label;
91
    }
92

  
93
    /**
94
     * @param entity
95
     * @param filterString
96
     * @return
97
     */
98
    public EllipsisData ellypsis(Reference entity, String filterString) {
99

  
100
        String label = "";
101
        String authors = entity.getAuthorship() != null ? entity.getAuthorship().getTitleCache() : "";
102
        String title = null;
103
        String titleCache;
104

  
105
        switch(labelType){
106
            case NOMENCLATURAL:
107
                if(!entity.isProtectedAbbrevTitleCache()){
108
                    title = entity.getAbbrevTitle();
109
                    if(title == null) {
110
                        // fallback to use the title
111
                        title = entity.getTitle();
112
                    }
113
                }
114
                titleCache = entity.getAbbrevTitleCache();
115
                break;
116
            case BIBLIOGRAPHIC:
117
            default:
118
                if(!entity.isProtectedTitleCache()){
119
                    title = entity.getTitle();
120
                    if(title == null) {
121
                        // fallback to use the abbreviated title
122
                        title = entity.getAbbrevTitle();
123
                    }
124
                }
125
                titleCache = entity.getTitleCache();
126
                break;
127
        }
128

  
129
        Pattern pattern = Pattern.compile("(" + filterString +")", Pattern.CASE_INSENSITIVE);
130

  
131
        if(authors != null){
132
            String authorsEllipsed = authors;
133
            if(authorsEllipsed.length() > maxAuthorCharsVisible) {
134
                authorsEllipsed = applyEllipsis(authors, maxAuthorCharsVisible);
135
                authorsEllipsed = preserveFilterstring(filterString, authors, pattern, authorsEllipsed);
136
            }
137
            label = titleCache.replace(authors, authorsEllipsed);
138
        }
139

  
140

  
141
        if(title != null){
142
            String titleEllipsed = title;
143
            if(titleEllipsed.length() > maxTitleCharsVisible) {
144
                titleEllipsed = applyEllipsis(title, maxTitleCharsVisible);
145
                titleEllipsed = preserveFilterstring(filterString, title, pattern, titleEllipsed);
146
            }
147
            label = label.replace(title, titleEllipsed);
148
        }
149

  
150
        if(entity.getInReference() != null){
151
            EllipsisData inRefEd = ellypsis(entity.getInReference(), filterString);
152
            label = label.replaceFirst(inRefEd.original, inRefEd.truncated);
153
        }
154

  
155
        EllipsisData ed = new EllipsisData(titleCache, label);
156

  
157

  
158
        return ed;
159
    }
160

  
161
    /**
162
     * @param authors
163
     * @return
164
     */
165
    public String applyEllipsis(String text, int maxCharsVisible) {
166
        String ellipsedText = "";
167
        StringTokenizer tokenizer = new StringTokenizer(text, DELIM);
168
        while(tokenizer.hasMoreElements()){
169
            String token = tokenizer.nextToken();
170
            if(ellipsedText.length() + token.length() + DELIM.length() <= maxCharsVisible){
171
                ellipsedText = ellipsedText + (ellipsedText.isEmpty() ? "" : DELIM) + token;
172
            } else {
173
                break;
174
            }
175
        }
176
        return ellipsedText + MORE;
177
    }
178

  
179
    /**
180
     * @param filterString
181
     * @param authors
182
     * @param pattern
183
     * @param authorsEllipsed
184
     * @return
185
     */
186
    public String preserveFilterstring(String filterString, String text, Pattern pattern, String textEllipsed) {
187
        String matchingSubstring = null;
188
        if(!filterString.isEmpty()){
189
            Matcher m = pattern.matcher(text);
190
            if(m.find()){
191
                matchingSubstring = m.group(1);
192
            }
193
        }
194
        if(matchingSubstring != null && !textEllipsed.toLowerCase().contains(filterString)){
195
            textEllipsed += matchingSubstring + MORE;
196
        }
197
        return textEllipsed;
198
    }
199

  
200
    class EllipsisData {
201
        String original;
202
        String truncated;
203
        /**
204
         * @param original
205
         * @param truncated
206
         */
207
        public EllipsisData(String original, String truncated) {
208
            super();
209
            this.original = original;
210
            this.truncated = truncated;
211
        }
212
    }
213

  
214
}
src/main/java/eu/etaxonomy/cdm/service/TypifiedEntityFilterablePagingProvider.java
1
/**
2
* Copyright (C) 2018 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.service;
10

  
11
import java.util.ArrayList;
12
import java.util.List;
13

  
14
import org.vaadin.viritin.fields.LazyComboBox.FilterableCountProvider;
15
import org.vaadin.viritin.fields.LazyComboBox.FilterablePagingProvider;
16

  
17
import eu.etaxonomy.cdm.api.service.IIdentifiableEntityService;
18
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
19
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
20
import eu.etaxonomy.cdm.persistence.query.MatchMode;
21
import eu.etaxonomy.cdm.persistence.query.OrderHint;
22
import eu.etaxonomy.cdm.ref.TypedEntityReference;
23

  
24
/**
25
 * @author a.kohlbecker
26
 * @since Dec 11, 2018
27
 *
28
 */
29
public class TypifiedEntityFilterablePagingProvider<T extends IdentifiableEntity> implements FilterablePagingProvider<TypedEntityReference<T>>, FilterableCountProvider{
30

  
31
    private CdmFilterablePagingProvider<T, T> entityPagingProvider;
32

  
33
    private ComboboxLabelProvider<T> labelProvider;
34

  
35
    public TypifiedEntityFilterablePagingProvider(IIdentifiableEntityService<T> service, MatchMode matchMode, List<OrderHint> orderHints, ComboboxLabelProvider<T> labelProvider){
36
        this.labelProvider = labelProvider;
37
        entityPagingProvider = new CdmFilterablePagingProvider<T, T>(service, matchMode, orderHints);
38
    }
39

  
40
    /**
41
     * {@inheritDoc}
42
     */
43
    @Override
44
    public int size(String filter) {
45
        return entityPagingProvider.size(filter);
46
    }
47

  
48
    /**
49
     * {@inheritDoc}
50
     */
51
    @Override
52
    public List<TypedEntityReference<T>> findEntities(int firstRow, String filter) {
53
        List<T> entities = entityPagingProvider.findEntities(firstRow, filter);
54
        List<TypedEntityReference<T>> ters = new ArrayList<>(entities.size());
55
        for(T e : entities){
56
            Class<T> type = (Class<T>)e.getClass();
57
            String label = labelProvider.composeLabel(e, filter);
58
            TypedEntityReference<T> ter = new TypedEntityReference<T>(type, e.getUuid(), label);
59
            ters.add(ter);
60
        }
61
        return ters;
62
    }
63

  
64
    /**
65
     * @param restriction
66
     */
67
    public void addRestriction(Restriction restriction) {
68
        entityPagingProvider.addRestriction(restriction);
69
    }
70

  
71
    /**
72
     * @return
73
     */
74
    public int getPageSize() {
75
        return entityPagingProvider.getPageSize();
76
    }
77

  
78
    /**
79
     * @param asList
80
     */
81
    public void setInitStrategy(List<String> initStrategy) {
82
        entityPagingProvider.setInitStrategy(initStrategy);
83
    }
84

  
85
}
src/main/java/eu/etaxonomy/cdm/vaadin/util/ReferenceCaptionGenerator.java
1
/**
2
* Copyright (C) 2018 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.util;
10

  
11
import org.vaadin.viritin.fields.CaptionGenerator;
12

  
13
import eu.etaxonomy.cdm.model.reference.Reference;
14

  
15
/**
16
 * @author a.kohlbecker
17
 * @since Dec 12, 2018
18
 *
19
 */
20
public class ReferenceCaptionGenerator implements CaptionGenerator<Reference> {
21

  
22
    private int authorsCharsVisible = 20;
23

  
24
    private int titleCharsVisible = 20;
25

  
26
    /**
27
     * {@inheritDoc}
28
     */
29
    @Override
30
    public String getCaption(Reference reference) {
31
        String title = "";
32

  
33
        return null;
34
    }
35

  
36
}
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/StartRegistrationPresenter.java
28 28
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
29 29
import eu.etaxonomy.cdm.persistence.dao.common.Restriction.Operator;
30 30
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
31
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
31
import eu.etaxonomy.cdm.ref.TypedEntityReference;
32 32
import eu.etaxonomy.cdm.service.CdmFilterablePagingProviderFactory;
33
import eu.etaxonomy.cdm.service.ReferenceLabelProvider;
34
import eu.etaxonomy.cdm.service.TypifiedEntityFilterablePagingProvider;
33 35
import eu.etaxonomy.cdm.vaadin.event.EditorActionTypeFilter;
34 36
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
35 37
import eu.etaxonomy.cdm.vaadin.event.RegistrationEditorAction;
36 38
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
37
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
38 39
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
39 40
import eu.etaxonomy.vaadin.mvp.AbstractEditorPresenter;
40 41
import eu.etaxonomy.vaadin.ui.navigation.NavigationEvent;
......
74 75

  
75 76
        super.handleViewEntered();
76 77

  
77
        CdmFilterablePagingProvider<Reference, Reference> pagingProvider = pagingProviderFactory.referencePagingProvider();
78
        CdmTitleCacheCaptionGenerator<Reference> titleCacheGenrator = new CdmTitleCacheCaptionGenerator<Reference>();
78
        TypifiedEntityFilterablePagingProvider<Reference> pagingProvider =
79
                pagingProviderFactory.referenceEntityReferencePagingProvider(
80
                        new ReferenceLabelProvider(ReferenceLabelProvider.LabelType.BIBLIOGRAPHIC),
81
                        ReferenceLabelProvider.INIT_STRATEGY
82
                        );
83
        TypedEntityCaptionGenerator<Reference> titleCacheGenrator = new TypedEntityCaptionGenerator<Reference>();
79 84
        pagingProvider.addRestriction(new Restriction("type", Operator.AND_NOT, null, ReferenceType.Section, ReferenceType.Journal, ReferenceType.PrintSeries));
80 85
        getView().getReferenceCombobox().setCaptionGenerator(titleCacheGenrator);
81 86
        getView().getReferenceCombobox().loadFrom(pagingProvider, pagingProvider, pagingProvider.getPageSize());
......
173 178
        }
174 179

  
175 180
        UUID referenceUuid = null;
176
        LazyComboBox<Reference> referenceCombobox = getView().getReferenceCombobox();
181
        LazyComboBox<TypedEntityReference<Reference>> referenceCombobox = getView().getReferenceCombobox();
177 182
        referenceCombobox.commit();
178 183
        if(newReference != null){
179 184
            referenceUuid = newReference.getUuid();
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/StartRegistrationView.java
14 14
import com.vaadin.ui.Label;
15 15

  
16 16
import eu.etaxonomy.cdm.model.reference.Reference;
17
import eu.etaxonomy.cdm.ref.TypedEntityReference;
17 18
import eu.etaxonomy.vaadin.mvp.ApplicationView;
18 19

  
19 20
/**
......
25 26

  
26 27
    Button getNewPublicationButton();
27 28

  
28
    LazyComboBox<Reference> getReferenceCombobox();
29
    LazyComboBox<TypedEntityReference<Reference>> getReferenceCombobox();
29 30

  
30 31
    /**
31 32
     * @return
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/StartRegistrationViewBean.java
17 17
import com.vaadin.navigator.View;
18 18
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
19 19
import com.vaadin.spring.annotation.SpringView;
20
import com.vaadin.ui.AbstractSelect;
20 21
import com.vaadin.ui.Alignment;
21 22
import com.vaadin.ui.Button;
23
import com.vaadin.ui.ComboBox;
22 24
import com.vaadin.ui.CssLayout;
23 25
import com.vaadin.ui.HorizontalLayout;
24 26
import com.vaadin.ui.Label;
......
26 28
import com.vaadin.ui.themes.ValoTheme;
27 29

  
28 30
import eu.etaxonomy.cdm.model.reference.Reference;
31
import eu.etaxonomy.cdm.ref.TypedEntityReference;
29 32
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
30 33
import eu.etaxonomy.cdm.vaadin.event.RegistrationEditorAction;
31 34
import eu.etaxonomy.cdm.vaadin.permission.AccessRestrictedView;
......
48 51
    public static final String SUBHEADER_DEEFAULT = "Any valid nomenclatural act can only be etablished in a publication. "
49 52
            + "To start a new registration process, please choose an existing one or create a new publication.";
50 53

  
51
    private LazyComboBox<Reference> referenceCombobox;
54
    private LazyComboBox<TypedEntityReference<Reference>> referenceCombobox;
52 55

  
53 56
    private Button newPublicationButton;
54 57

  
......
80 83
        HorizontalLayout publicationLayout = new HorizontalLayout();
81 84
        publicationLayout.setSpacing(true);
82 85

  
83
        referenceCombobox = new LazyComboBox<Reference>(Reference.class);
86
        Class<TypedEntityReference<Reference>> type = (Class<TypedEntityReference<Reference>>) new TypedEntityReference<Reference>(Reference.class, null).getClass();
87
        referenceCombobox = new LazyComboBox<TypedEntityReference<Reference>>(type) {
88

  
89
            @Override
90
            protected void setSelectInstance(AbstractSelect select) {
91
                if(select instanceof ComboBox){
92
                    ComboBox combobox = (ComboBox)select;
93
                    // uncomment the below line to set a defined width for the ComboBox popup
94
                    // combobox.setPopupWidth("200%");
95
                }
96
                super.setSelectInstance(select);
97
            }
98

  
99
        };
84 100
        referenceCombobox.setWidth(ELEMENT_WIDTH);
85 101
        referenceCombobox.setBuffered(false);
86 102
        referenceCombobox.addValueChangeListener( e -> {
......
102 118
        removeNewPublicationButton.setStyleName(ValoTheme.BUTTON_DANGER);
103 119
        removeNewPublicationButton.setWidth(ELEMENT_WIDTH);
104 120
        removeNewPublicationButton.addClickListener( e -> getViewEventBus().publish(this,
105
                new ReferenceEditorAction(EditorActionType.REMOVE, removeNewPublicationButton, referenceCombobox, this)
121
                new ReferenceEditorAction(EditorActionType.REMOVE, removeNewPublicationButton, null, this)
106 122
                ));
107 123

  
108 124
        removeNewPublicationButton.setVisible(false);
......
200 216
     * @return the referenceCombobox
201 217
     */
202 218
    @Override
203
    public LazyComboBox<Reference> getReferenceCombobox() {
219
    public LazyComboBox<TypedEntityReference<Reference>> getReferenceCombobox() {
204 220
        return referenceCombobox;
205 221
    }
206 222

  
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/TypedEntityCaptionGenerator.java
1
/**
2
* Copyright (C) 2018 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.registration;
10

  
11
import org.vaadin.viritin.fields.CaptionGenerator;
12

  
13
import eu.etaxonomy.cdm.model.common.CdmBase;
14
import eu.etaxonomy.cdm.ref.TypedEntityReference;
15

  
16
/**
17
 * @author a.kohlbecker
18
 * @since Dec 12, 2018
19
 *
20
 */
21
public class TypedEntityCaptionGenerator<T extends CdmBase> implements CaptionGenerator<TypedEntityReference<T>> {
22

  
23
    private static final long serialVersionUID = 1312587195614966511L;
24

  
25
    @Override
26
    public String getCaption(TypedEntityReference<T> option) {
27
        return option.getLabel();
28
    }
29

  
30
}

Also available in: Unified diff