Project

General

Profile

« Previous | Next » 

Revision 569b2942

Added by Andreas Kohlbecker over 5 years ago

ref #7951 moving EllypsisFormatter to cdmlib/model/eu.etaxonomy.cdm.format

View differences:

cdmlib-model/src/main/java/eu/etaxonomy/cdm/format/AbstractEllypsisFormatter.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.format;
10

  
11
import java.util.StringTokenizer;
12
import java.util.regex.Matcher;
13
import java.util.regex.Pattern;
14

  
15
import eu.etaxonomy.cdm.model.common.CdmBase;
16

  
17
/**
18
 * @author a.kohlbecker
19
 * @since Dec 14, 2018
20
 *
21
 */
22
public abstract class AbstractEllypsisFormatter<T extends CdmBase> implements EllypsisFormatter<T> {
23

  
24
    private static final String DELIM = " ";
25
    private String MORE = " \u2026";
26

  
27
    @Override
28
    public String ellypsis(T entity, String preserveString) {
29

  
30

  
31
        EllipsisData ed = entityEllypsis(entity, preserveString);
32
        String label = ed.truncated;
33

  
34
        return label;
35
    }
36

  
37
    protected abstract EllipsisData entityEllypsis(T entity, String filterString);
38

  
39
    public String stringEllypsis(String text, int maxCharsVisible, int minNumOfWords) {
40
        String ellipsedText = "";
41
        StringTokenizer tokenizer = new StringTokenizer(text, DELIM);
42
        int wordCount = 0;
43
        while(tokenizer.hasMoreElements()){
44
            String token = tokenizer.nextToken();
45
            if(ellipsedText.length() + token.length() + DELIM.length() <= maxCharsVisible || wordCount < minNumOfWords){
46
                ellipsedText = ellipsedText + (ellipsedText.isEmpty() ? "" : DELIM) + token;
47
            } else {
48
                break;
49
            }
50
            wordCount++;
51
        }
52
        return ellipsedText + MORE;
53
    }
54

  
55
    public String preserveString(String preserveString, String text, Pattern pattern, String textEllipsed) {
56
        String matchingSubstring = null;
57
        if(!preserveString.isEmpty()){
58
            Matcher m = pattern.matcher(text);
59
            if(m.find()){
60
                matchingSubstring = m.group(1);
61
            }
62
        }
63
        if(matchingSubstring != null && !textEllipsed.toLowerCase().contains(preserveString)){
64
            textEllipsed += matchingSubstring + MORE;
65
        }
66
        return textEllipsed;
67
    }
68

  
69
    static class EllipsisData {
70
        String original;
71
        String truncated;
72
        /**
73
         * @param original
74
         * @param truncated
75
         */
76
        public EllipsisData(String original, String truncated) {
77
            super();
78
            this.original = original;
79
            this.truncated = truncated;
80
        }
81
    }
82

  
83
}
cdmlib-model/src/main/java/eu/etaxonomy/cdm/format/EllypsisFormatter.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.format;
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 EllypsisFormatter<T extends CdmBase> {
19

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

  
22
}
cdmlib-model/src/main/java/eu/etaxonomy/cdm/format/ReferenceEllypsisFormatter.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.format;
10

  
11
import java.util.Arrays;
12
import java.util.List;
13
import java.util.regex.Pattern;
14

  
15
import eu.etaxonomy.cdm.model.reference.Reference;
16

  
17
/**
18
 * Creates truncated labels for references by applying ellypsis on the reference authors and title for inReferences an
19
 * ellypsis is also being created.
20
 * <p>
21
 * Here are some examples:
22
 * <table>
23
 * <th>
24
 *  <td>original</td>
25
 *  <td>ellypsis</td></th>
26
 * <tr>
27
 * </tr>
28
 * <td>
29
 *   <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>
30
 *   </td>Gottschling, M.,…Kusber…, A Gordian knot:… in Taxon 67(1): 179–185. 2018</td>
31
 *   </tr>
32
 * <td>
33
 *   <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>
34
 *   </td>Hamilton, P.B.,…Kusber…, Typification of the… in Cryptog. Algol.</td>
35
 * </tr>
36
 * <td>
37
 * <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>
38
 * </td>Jahn , R., Kusber, W.-H. & Cocquyt, C., Differentiating… in PhytoKeys 82: 73-112</td>
39
 * </tr>
40
 * <td>
41
 * <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>
42
 * </td>Jahn, R., Kusber,…, Gomphonella olivacea… in Cryptog. Algol.</td>
43
 * </td>
44
 * </table>
45
 * @author a.kohlbecker
46
 * @since Dec 12, 2018
47
 *
48
 */
49
public class ReferenceEllypsisFormatter extends AbstractEllypsisFormatter<Reference> {
50

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

  
61
    public enum LabelType {
62
        NOMENCLATURAL,
63
        BIBLIOGRAPHIC;
64
    }
65

  
66
    private LabelType labelType;
67
    private int maxAuthorCharsVisible = 20;
68
    private int maxTitleCharsVisible = 20;
69
    private int minNumOfWords = 1;
70

  
71
    public ReferenceEllypsisFormatter(LabelType labelType){
72
        this.labelType = labelType;
73
    }
74

  
75
    /**
76
     * @param entity
77
     * @param filterString
78
     * @return
79
     */
80
    @Override
81
    protected EllipsisData entityEllypsis(Reference entity, String filterString) {
82

  
83
        String label = "";
84
        String authors = entity.getAuthorship() != null ? entity.getAuthorship().getTitleCache() : "";
85
        String title = null;
86
        String titleCache;
87

  
88
        switch(labelType){
89
            case NOMENCLATURAL:
90
                if(!entity.isProtectedAbbrevTitleCache()){
91
                    title = entity.getAbbrevTitle();
92
                    if(title == null) {
93
                        // fallback to use the title
94
                        title = entity.getTitle();
95
                    }
96
                }
97
                titleCache = entity.getAbbrevTitleCache();
98
                break;
99
            case BIBLIOGRAPHIC:
100
            default:
101
                if(!entity.isProtectedTitleCache()){
102
                    title = entity.getTitle();
103
                    if(title == null) {
104
                        // fallback to use the abbreviated title
105
                        title = entity.getAbbrevTitle();
106
                    }
107
                }
108
                titleCache = entity.getTitleCache();
109
                break;
110
        }
111

  
112
        Pattern pattern = Pattern.compile("(" + filterString +")", Pattern.CASE_INSENSITIVE);
113

  
114
        if(authors != null){
115
            String authorsEllipsed = authors;
116
            if(authorsEllipsed.length() > maxAuthorCharsVisible) {
117
                authorsEllipsed = stringEllypsis(authors, maxAuthorCharsVisible, minNumOfWords);
118
                authorsEllipsed = preserveString(filterString, authors, pattern, authorsEllipsed);
119
            }
120
            label = titleCache.replace(authors, authorsEllipsed);
121
        }
122

  
123
        if(title != null){
124
            String titleEllipsed = title;
125
            if(titleEllipsed.length() > maxTitleCharsVisible) {
126
                titleEllipsed = stringEllypsis(title, maxTitleCharsVisible, minNumOfWords);
127
                titleEllipsed = preserveString(filterString, title, pattern, titleEllipsed);
128
            }
129
            label = label.replace(title, titleEllipsed);
130
        }
131

  
132

  
133
        if(entity.getInReference() != null){
134
            EllipsisData inRefEd = entityEllypsis(entity.getInReference(), filterString);
135
            label = label.replace(inRefEd.original, inRefEd.truncated);
136
        }
137

  
138
        EllipsisData ed = new EllipsisData(titleCache, label);
139

  
140
        return ed;
141
    }
142

  
143
    public int getMaxAuthorCharsVisible() {
144
        return maxAuthorCharsVisible;
145
    }
146

  
147
    public void setMaxAuthorCharsVisible(int maxAuthorCharsVisible) {
148
        this.maxAuthorCharsVisible = maxAuthorCharsVisible;
149
    }
150

  
151
    public int getMaxTitleCharsVisible() {
152
        return maxTitleCharsVisible;
153
    }
154

  
155
    public void setMaxTitleCharsVisible(int maxTitleCharsVisible) {
156
        this.maxTitleCharsVisible = maxTitleCharsVisible;
157
    }
158

  
159
    public int getMinNumOfWords() {
160
        return minNumOfWords;
161
    }
162

  
163
    public void setMinNumOfWords(int minNumOfWords) {
164
        this.minNumOfWords = minNumOfWords;
165
    }
166

  
167

  
168
}

Also available in: Unified diff