Project

General

Profile

Download (11.9 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2021 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.reference;
10

    
11
import java.io.Serializable;
12

    
13
import org.apache.log4j.Logger;
14

    
15
import eu.etaxonomy.cdm.format.CdmFormatterBase;
16
import eu.etaxonomy.cdm.model.agent.Person;
17
import eu.etaxonomy.cdm.model.agent.Team;
18
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
19
import eu.etaxonomy.cdm.model.common.CdmBase;
20
import eu.etaxonomy.cdm.model.name.NomenclaturalSource;
21
import eu.etaxonomy.cdm.model.name.TaxonName;
22
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
23
import eu.etaxonomy.cdm.model.reference.Reference;
24
import eu.etaxonomy.cdm.model.reference.ReferenceType;
25
import eu.etaxonomy.cdm.strategy.cache.agent.TeamDefaultCacheStrategy;
26
import eu.etaxonomy.cdm.strategy.cache.reference.ReferenceDefaultCacheStrategy;
27
import eu.etaxonomy.cdm.strategy.cache.reference.TitleWithoutYearAndAuthorHelper;
28

    
29
/**
30
 * @author a.mueller
31
 * @since 03.05.2021
32
 */
33
public class NomenclaturalSourceFormatter
34
        extends CdmFormatterBase<NomenclaturalSource>
35
        implements Serializable {
36

    
37
    private static final long serialVersionUID = -6263443499465634548L;
38

    
39
    private static final Logger logger = Logger.getLogger(NomenclaturalSourceFormatter.class);
40

    
41
    private static final String EMPTY_TITLE = "-";
42
    private static final String beforeMicroReference = ": ";
43
    private static final String afterInRefAuthor = ", ";
44

    
45
    private static NomenclaturalSourceFormatter instance;
46

    
47
    public static final NomenclaturalSourceFormatter INSTANCE() {
48
            if (instance == null){
49
                instance = new NomenclaturalSourceFormatter();
50
            }
51
            return instance;
52
    }
53

    
54
    @Override
55
    public String format(NomenclaturalSource source){
56
        if (source == null){
57
            return null;
58
        }
59
        Reference reference = source.getCitation();
60
        String microReference = source.getCitationMicroReference();
61
        if (reference == null && isBlank(microReference)){
62
            return null;
63
        }
64
        return format(reference, microReference);
65
    }
66

    
67
    /**
68
    * Returns a formatted string containing the entire citation used for
69
    * nomenclatural purposes based on the {@link Reference reference} supplied - including
70
    * (abbreviated) title  but not authors - and on the given details.<BR>
71
    *
72
    * @param  reference
73
    *                         the nomenclatural reference
74
    * @param  microReference  the string with the details (generally pages)
75
    *                         corresponding to the nomenclatural reference supplied
76
    *                         as the first argument
77
    * @return                 the formatted string representing the
78
    *                         nomenclatural citation
79
    * @see                    INomenclaturalReference#getNomenclaturalCitation(String)
80
    * @see                    TaxonName#getNomenclaturalReference()
81
    */
82
    public String format(Reference reference, String microReference){
83
        if (isNotBlank(microReference)){
84
            microReference = microReference.startsWith(":") ? microReference : getBeforeMicroReference() + microReference;
85
        }else{
86
            microReference = "";
87
        }
88

    
89
        if (reference == null){
90
            return EMPTY_TITLE + microReference;
91
        }
92

    
93
        if (reference.isProtectedAbbrevTitleCache()){
94
            String cache = reference.getAbbrevTitleCache();
95
            return handleDetailAndYearForProtected(reference, cache, microReference);
96
        }
97

    
98
        String result = getTokenizedNomenclaturalTitel(reference, microReference);
99
        //if no data is available and only titleCache is protected take the protected title
100
        //this is to avoid empty cache if someone forgets to set also the abbrevTitleCache
101
        //we need to think about handling protected not separate for abbrevTitleCache and titleCache
102
        if (result.equals(microReference) && reference.isProtectedTitleCache() ){
103
            String cache = reference.getTitleCache();
104
            return handleDetailAndYearForProtected(reference, cache, microReference);
105
        }
106

    
107
        if (isNotBlank(microReference)){
108
            microReference = getBeforeMicroReference() + microReference;
109
            if (microReference.endsWith(".")){
110
                microReference = microReference.substring(0, microReference.length() - 1);
111
            }
112
        }
113
        if (result.startsWith(". ")){  //only year available, remove '. '
114
            result = result.substring(2);
115
        }
116
        return result;
117
    }
118

    
119
    private String getBeforeMicroReference(){
120
        return beforeMicroReference;
121
    }
122

    
123
    /**
124
     * Returns the nomenclatural title with micro reference represented as token
125
     * which can later be replaced by the real data.
126
     * @param microReference
127
     *
128
     * @see INomenclaturalReference#MICRO_REFERENCE_TOKEN
129
     */
130
    private String getTokenizedNomenclaturalTitel(Reference ref, String microReference) {
131
        if (ReferenceDefaultCacheStrategy.isRealInRef(ref)){
132
            return getTokenizedNomenclaturalTitelInRef(ref, microReference);
133
        }else{
134
            String result = getTitleWithoutYearAndAuthor(ref, true, true);
135
            result = isNotBlank(microReference)? (isBlank(result)? EMPTY_TITLE: result) + microReference : result;
136
            result = addYear(result, ref, true);
137
            return result;
138
        }
139
    }
140

    
141
    private String handleDetailAndYearForProtected(Reference nomenclaturalReference, String cache, String microRef) {
142
        if (cache == null){
143
            logger.warn("Cache is null. This should never be the case.");
144
            cache = "";
145
        }
146
        String  result = cache + (cache.contains(microRef) ? "" : microRef);
147

    
148
        String date = nomenclaturalReference.getDatePublishedString();
149
        if (isNotBlank(date) && ! result.contains(date)){
150
            result = result + ReferenceDefaultCacheStrategy.beforeYear + date;
151
        }
152
        return result;
153
    }
154

    
155
    private String getTokenizedNomenclaturalTitelInRef(Reference thisRef, String microReference) {
156
        if (thisRef == null){
157
            return null;
158
        }
159

    
160
        Reference inRef = CdmBase.deproxy(thisRef.getInReference());
161
        if (inRef != null && inRef.getInReference() != null && thisRef.getType() == ReferenceType.Section){
162
            //this is a reference of type Section which has an in-in-Ref
163
            //TODO maybe we do not need to restrict to type=Section only
164
            return this.getTokenizedNomenclaturalTitelInInRef(thisRef, microReference);
165
        }
166

    
167
        String result;
168
        //use generics's publication date if it exists
169
        if (inRef == null || (thisRef.hasDatePublished() ) ){
170
            result =  inRef == null ? "" : getTitleWithoutYearAndAuthorGeneric(inRef, true);
171
            //added //TODO unify with non-inRef references formatting
172

    
173
            if (isNotBlank(thisRef.getVolume())){
174
                result = result + " " + thisRef.getVolume();
175
            }
176
            //TODO series / edition
177

    
178
            //end added
179
            result += microReference;
180
            result = addYear(result, thisRef, true);
181
        }else{
182
            //else use inRefs's publication date
183
            result = format(inRef, microReference); // inRef.getNomenclaturalCitation(INomenclaturalReference.MICRO_REFERENCE_TOKEN);
184
//            if (result != null){
185
//                result = result.replace(beforeMicroReference + INomenclaturalReference.MICRO_REFERENCE_TOKEN, INomenclaturalReference.MICRO_REFERENCE_TOKEN);
186
//            }
187
        }
188
        //FIXME: vol. etc., https://dev.e-taxonomy.eu/redmine/issues/2862
189

    
190
        result = getInRefAuthorPart(thisRef.getInReference(), afterInRefAuthor) + result;
191
        result = "in " +  result;
192
        return result;
193
    }
194

    
195

    
196
    /**
197
     * For handling in-in-Ref case.
198
     * Must only be called if a reference has inRef and inInRef
199
     * @param section
200
     * @return
201
     */
202
    private String getTokenizedNomenclaturalTitelInInRef(Reference ref, String microReference) {
203
        String result;
204

    
205
        Reference inRef = CdmBase.deproxy(ref.getInReference());
206
        Reference inInRef = CdmBase.deproxy(inRef.getInReference());
207

    
208
        if (! ReferenceDefaultCacheStrategy.isNomRef(inInRef.getType())){
209
            if (! ReferenceDefaultCacheStrategy.isNomRef(inRef.getType())){
210
                logger.warn("Neither inReference nor inInReference is a "
211
                        + " nomenclatural reference. This is not correct or not handled yet."
212
                        + " Generic titleWithoutYearAndAuthor used instead");
213
                result = getTitleWithoutYearAndAuthorGeneric(inInRef, true);
214
                //FIXME: vol. etc., https://dev.e-taxonomy.eu/redmine/issues/2862  (comment taken from super.getTokenizedNomenclaturalTitel())
215
            }else{
216
                result = getTitleWithoutYearAndAuthor(inRef, true, true);
217
            }
218
        }else{
219
            result = getTitleWithoutYearAndAuthor(inInRef, true, true);
220
        }
221
        result += microReference;
222

    
223
        Reference dataReference = (ref.hasDatePublished() ? ref : inRef.hasDatePublished() ? inRef : inInRef);
224

    
225
        result = addYear(result, dataReference, true);
226

    
227
        result = getInRefAuthorPart(inInRef, afterInRefAuthor) + result;
228
        if (! result.startsWith("in ")){
229
            result = "in " +  result;
230
        }
231
        return result;
232
    }
233

    
234
    /**
235
     * See https://dev.e-taxonomy.eu/redmine/issues/8881
236
     */
237
    private String getInRefAuthorPart(Reference book, String seperator){
238
        if (book == null){
239
            return "";
240
        }
241

    
242
        TeamOrPersonBase<?> author = book.getAuthorship();
243
        String result;
244
        if (author == null){
245
            result = "";
246
        }else if(author.isInstanceOf(Person.class)){
247
            Person person = CdmBase.deproxy(author, Person.class);
248
            result = getInRefPerson(person);
249
        }else{
250
            Team team = CdmBase.deproxy(author, Team.class);
251
            if (team.isProtectedNomenclaturalTitleCache()){
252
                //not yet finally discussed may change in future
253
                result = team.getNomenclaturalTitleCache();
254
            }else if (team.isProtectedTitleCache()){
255
                //not yet finally discussed may change in future
256
                result = team.getTitleCache();
257
            }else if (team.getTeamMembers().isEmpty()){
258
                //not yet finally discussed may change in future
259
                result = team.getTitleCache();
260
            }else{
261
                result = TeamDefaultCacheStrategy.INSTANCE_ET_AL_3().getFamilyTitle(team);
262
            }
263
        }
264

    
265
        result = Nz(result);
266
        if (! result.trim().equals("")){
267
            result = result + seperator;
268
        }
269
        return result;
270
    }
271

    
272
    private String getInRefPerson(Person person) {
273
        String result;
274
        if (isNotBlank(person.getFamilyName())){
275
            result = person.getFamilyName();
276
        }else if (isNotBlank(person.getNomenclaturalTitleCache())){
277
            result = person.getNomenclaturalTitleCache();  //TODO discuss if nomTitle is really better here then titleCache
278
        }else{
279
            result = person.getTitleCache();  //maybe remove everything behind a ","
280
        }
281
        return result;
282
    }
283

    
284
    /**
285
     * @see ReferenceDefaultCacheStrategy#addYear(String, Reference, boolean)
286
     */
287
    private String addYear(String yearStr, Reference ref, boolean useFullDatePublished) {
288
        return ReferenceDefaultCacheStrategy.addYear(yearStr, ref, useFullDatePublished);
289
    }
290
    private String getTitleWithoutYearAndAuthorGeneric(Reference ref, boolean isAbbrev){
291
        return TitleWithoutYearAndAuthorHelper.getTitleWithoutYearAndAuthorGeneric(ref, isAbbrev);
292
    }
293
    private String getTitleWithoutYearAndAuthor(Reference ref, boolean isAbbrev, boolean isNomRef){
294
        return TitleWithoutYearAndAuthorHelper.getTitleWithoutYearAndAuthor(ref, isAbbrev, isNomRef);
295
    }
296
}
(1-1/3)