Project

General

Profile

Download (12.2 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.logging.log4j.LogManager;import org.apache.logging.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 = LogManager.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 = getTitelDetailAndYear(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(getDetailOnly(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
    private String getTitelDetailAndYear(Reference ref, String microReference) {
129
        if (ReferenceDefaultCacheStrategy.isRealInRef(ref)){
130
            return getTokenizedNomenclaturalTitelInRef(ref, microReference);
131
        }else{
132
            String result = getTitleWithoutYearAndAuthor(ref, true, true);
133
            result = isBlank(result) ? getDetailOnly(microReference): isBlank(microReference)? result : isBlank(microReference)? result : result + microReference;
134
            result = addYear(result, ref, true);
135
            return result;
136
        }
137
    }
138

    
139
    private String getDetailOnly(String microReference) {
140
        if (isBlank(microReference)){
141
            return "";
142
        }else{
143
            return EMPTY_TITLE + microReference;
144
        }
145
    }
146

    
147
    private String handleDetailAndYearForProtected(Reference nomenclaturalReference, String cache, String microRef) {
148
        if (cache == null){
149
            logger.warn("Cache is null. This should never be the case.");
150
            cache = "";
151
        }
152
        String  result = cache + (cache.contains(microRef) ? "" : microRef);
153

    
154
        String date = nomenclaturalReference.getDatePublishedString();
155
        if (isNotBlank(date) && ! result.contains(date)){
156
            result = result + ReferenceDefaultCacheStrategy.beforeYear + date;
157
        }
158
        return result;
159
    }
160

    
161
    private String getTokenizedNomenclaturalTitelInRef(Reference thisRef, String microReference) {
162
        if (thisRef == null){
163
            return null;
164
        }
165

    
166
        Reference inRef = CdmBase.deproxy(thisRef.getInReference());
167
        if (inRef != null && inRef.getInReference() != null && thisRef.getType() == ReferenceType.Section){
168
            //this is a reference of type Section which has an in-in-Ref
169
            //TODO maybe we do not need to restrict to type=Section only
170
            return this.getTokenizedNomenclaturalTitelInInRef(thisRef, microReference);
171
        }
172

    
173
        String result;
174
        //use generics's publication date if it exists
175
        if (inRef == null || (thisRef.hasDatePublished() ) ){
176
            result =  inRef == null ? "" : getTitleWithoutYearAndAuthorGeneric(inRef, true);
177
            //added //TODO unify with non-inRef references formatting
178

    
179
            if (isNotBlank(thisRef.getVolume())){
180
                result = result + " " + thisRef.getVolume();
181
            }
182
            //TODO series / edition
183

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

    
196
        result = getInRefAuthorPart(thisRef.getInReference(), afterInRefAuthor) + result;
197
        result = "in " +  result;
198
        return result;
199
    }
200

    
201

    
202
    /**
203
     * For handling in-in-Ref case.
204
     * Must only be called if a reference has inRef and inInRef
205
     * @param section
206
     * @return
207
     */
208
    private String getTokenizedNomenclaturalTitelInInRef(Reference ref, String microReference) {
209
        String result;
210

    
211
        Reference inRef = CdmBase.deproxy(ref.getInReference());
212
        Reference inInRef = CdmBase.deproxy(inRef.getInReference());
213

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

    
229
        Reference dataReference = (ref.hasDatePublished() ? ref : inRef.hasDatePublished() ? inRef : inInRef);
230

    
231
        result = addYear(result, dataReference, true);
232

    
233
        result = getInRefAuthorPart(inInRef, afterInRefAuthor) + result;
234
        if (! result.startsWith("in ")){
235
            result = "in " +  result;
236
        }
237
        return result;
238
    }
239

    
240
    /**
241
     * See https://dev.e-taxonomy.eu/redmine/issues/8881
242
     */
243
    private String getInRefAuthorPart(Reference book, String seperator){
244
        if (book == null){
245
            return "";
246
        }
247

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

    
271
        result = Nz(result);
272
        if (! result.trim().equals("")){
273
            result = result + seperator;
274
        }
275
        return result;
276
    }
277

    
278
    private String getInRefPerson(Person person) {
279
        String result;
280
        if (isNotBlank(person.getFamilyName())){
281
            result = person.getFamilyName();
282
        }else if (isNotBlank(person.getNomenclaturalTitleCache())){
283
            result = person.getNomenclaturalTitleCache();  //TODO discuss if nomTitle is really better here then titleCache
284
        }else{
285
            result = person.getTitleCache();  //maybe remove everything behind a ","
286
        }
287
        return result;
288
    }
289

    
290
    /**
291
     * @see ReferenceDefaultCacheStrategy#addYear(String, Reference, boolean)
292
     */
293
    private String addYear(String yearStr, Reference ref, boolean useFullDatePublished) {
294
        return ReferenceDefaultCacheStrategy.addYear(yearStr, ref, useFullDatePublished);
295
    }
296
    private String getTitleWithoutYearAndAuthorGeneric(Reference ref, boolean isAbbrev){
297
        return TitleWithoutYearAndAuthorHelper.getTitleWithoutYearAndAuthorGeneric(ref, isAbbrev);
298
    }
299
    private String getTitleWithoutYearAndAuthor(Reference ref, boolean isAbbrev, boolean isNomRef){
300
        return TitleWithoutYearAndAuthorHelper.getTitleWithoutYearAndAuthor(ref, isAbbrev, isNomRef);
301
    }
302
}
(1-1/3)