Project

General

Profile

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

    
11
import java.util.UUID;
12

    
13
import org.apache.log4j.Logger;
14
import org.joda.time.DateTime;
15
import org.joda.time.format.DateTimeFormat;
16
import org.joda.time.format.DateTimeFormatter;
17

    
18
import eu.etaxonomy.cdm.common.CdmUtils;
19
import eu.etaxonomy.cdm.common.UTF8;
20
import eu.etaxonomy.cdm.format.reference.NomenclaturalSourceFormatter;
21
import eu.etaxonomy.cdm.format.reference.OriginalSourceFormatter;
22
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
23
import eu.etaxonomy.cdm.model.common.VerbatimTimePeriod;
24
import eu.etaxonomy.cdm.model.reference.Reference;
25
import eu.etaxonomy.cdm.model.reference.ReferenceType;
26
import eu.etaxonomy.cdm.strategy.StrategyBase;
27

    
28
/**
29
 * #5833
30
 * The new single default cache strategy for {@link Reference references}.
31
 * As we do have only one {@link Reference} class left which implements multiple interfaces,
32
 * we may also only need 1 single cache strategy. However, care must be taken as the formatting
33
 * differs dependent on the type an the in-reference structure.
34
 *
35
 * Generally the cache strategy allows to compute 2 formats:<BR><BR>
36
 *
37
 *  1.) for bibliographic references (stored in {@link Reference#getTitleCache() titleCache}).<BR>
38
 *
39
 *  2.) for nomenclatural references (stored in {@link Reference#getAbbrevTitleCache() abbrevTitleCache}),
40
 *      but without micro reference (detail).<BR>
41
 * <BR>
42
 * The formatting of nomenclatural references with micro references has been moved to {@link NomenclaturalSourceFormatter}
43
 * and the formatting of short citations has been moved to {@link OriginalSourceFormatter}.
44
 *
45
 * @author a.mueller
46
 * @since 25.05.2016
47
 */
48
public class ReferenceDefaultCacheStrategy
49
        extends StrategyBase
50
        implements IReferenceCacheStrategy {
51

    
52
    private static final long serialVersionUID = 6773742298840407263L;
53
    private static final Logger logger = Logger.getLogger(ReferenceDefaultCacheStrategy.class);
54

    
55
    private final static UUID uuid = UUID.fromString("63e669ca-c6be-4a8a-b157-e391c22580f9");
56

    
57
    //article
58
    public static final String UNDEFINED_JOURNAL = "undefined journal " + UTF8.EN_DASH;
59
    private static final String afterAuthor = ": ";
60

    
61
    //book
62

    
63
    //(book?) section
64
    private static final String afterSectionAuthor = ": ";
65
    private static final String afterInRefAuthor = ", ";  //TODO needs discussion
66

    
67

    
68
    //in reference
69
    private String biblioInSeparator = UTF8.EN_DASH + " In: "; //#9529
70
    private String biblioArticleInSeparator = UTF8.EN_DASH + " "; //#9529
71

    
72
    //common
73
    private static final String blank = " ";
74
    public static final String beforeYear = ". ";
75
    private static final String afterYear = "";
76

    
77
    private static final boolean trim = true;
78

    
79
// ************************ FACTORY ****************************/
80

    
81
    public static ReferenceDefaultCacheStrategy NewInstance(){
82
        return new ReferenceDefaultCacheStrategy();
83
    }
84

    
85
// ******************************* Main methods ******************************/
86

    
87
    @Override
88
    protected UUID getUuid() {
89
        return uuid;
90
    }
91

    
92
    @Override
93
    public String getTitleCache(Reference reference) {
94
        if (reference == null){
95
            return null;
96
        }
97
        if (reference.isProtectedTitleCache()){
98
            return reference.getTitleCache();
99
        }
100
        boolean isNotAbbrev = false;
101

    
102
        String result;
103
        ReferenceType type = reference.getType();
104
        String authorAndYear = getAuthorAndYear(reference, isNotAbbrev, false);
105

    
106
        if (isRealInRef(reference)){
107
            //Section, Book-Section or Generic with inRef
108
            result = titleCacheRealInRef(reference, isNotAbbrev);
109
        }else if(isNomRef(type)){
110
            //all Non-InRef NomRefs
111
            //Article, CdDvd, Generic, Section, Thesis, WebPage (+Book, BookSection but not here)
112
            String title = getTitleWithoutYearAndAuthor(reference, isNotAbbrev, false);
113
            result = addPages(title, reference);
114

    
115
            if (type == ReferenceType.Article){
116
                String artTitle = CdmUtils.addTrailingDotIfNotExists(reference.getTitle());
117
                result = CdmUtils.concat(" ", artTitle, result);
118
                if (isNotBlank(authorAndYear)){
119
//                    String authorSeparator = isNotBlank(artTitle)? afterAuthor : " ";
120
                    String authorSeparator = afterAuthor;
121
                    authorAndYear += authorSeparator;
122
                }
123
                result = authorAndYear + result;
124
            }else{  //if Book, CdDvd, flat Generic, Thesis, WebPage
125
                if (isNotBlank(authorAndYear)){
126
                    String authorSeparator = isNotBlank(title)? afterAuthor : "";
127
                    authorAndYear += authorSeparator;
128
                }
129
                result = authorAndYear + result;
130
            }
131
            if (!type.isWebPage()){
132
                result = CdmUtils.addTrailingDotIfNotExists(result);
133
            }
134
        }else if (type == ReferenceType.Journal){
135
            result = titleCacheJournal(reference, isNotAbbrev);
136
        }else{
137
            result = titleCacheDefaultReference(reference, isNotAbbrev);
138
        }
139
        if (reference.getType() == ReferenceType.WebPage && reference.getUri() != null && !result.contains(reference.getUri().toString())){
140
            result = CdmUtils.concat(" "+UTF8.EN_DASH+" ", result, reference.getUri().toString());
141
        }
142
        if(reference.getAccessed() != null){
143
            //TODO still a bit preliminary, also brackets may change in future
144
            result = result + " [accessed " + getAccessedString(reference.getAccessed()) +"]";
145
        }
146
        return result == null ? null : result.trim();
147
    }
148

    
149
    private String getAuthorAndYear(Reference reference, boolean isAbbrev, boolean useFullDatePublished) {
150
        TeamOrPersonBase<?> author = reference.getAuthorship();
151
        String authorStr = (author == null)? "" : CdmUtils.getPreferredNonEmptyString(author.getTitleCache(),
152
                author.getNomenclaturalTitle(), isAbbrev, trim);
153
        String result = addAuthorYear(authorStr, reference, useFullDatePublished);
154
        return result;
155
    }
156

    
157
    private String getAccessedString(DateTime accessed) {
158
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
159
        String result = formatter.print(accessed);
160
        if (result.endsWith(" 00:00")){
161
            result = result.replace(" 00:00", "");
162
        }
163
        return result;
164
    }
165

    
166
    private String addPages(String result, Reference reference) {
167
        //pages
168
        if (isNotBlank(reference.getPages())){
169
            //Removing trailing added just in case, maybe not necessary
170
            result = removeTrailingDots(result).trim() + ": " + reference.getPages();
171
        }
172
        return result;
173
    }
174

    
175
    @Override
176
    public String getFullAbbrevTitleString(Reference reference) {
177
        if (reference == null){
178
            return null;
179
        }
180
        String result;
181
        ReferenceType type = reference.getType();
182
        boolean isAbbrev = true;
183

    
184
        if (reference.isProtectedAbbrevTitleCache()){
185
            return reference.getAbbrevTitleCache();
186
        }
187

    
188
        if (type == ReferenceType.Article){
189
            result = getTitleWithoutYearAndAuthor(reference, isAbbrev, false);
190
            boolean useFullDatePublished = false;
191
            String articleTitle = CdmUtils.getPreferredNonEmptyString(reference.getTitle(),
192
                    reference.getAbbrevTitle(), isAbbrev, trim);
193
            result = CdmUtils.concat(" ", articleTitle, result);  //Article should maybe left out for nomenclatural references (?)
194
            String authorAndYear = getAuthorAndYear(reference, isAbbrev, useFullDatePublished);
195
            if (isNotBlank(authorAndYear)){
196
//                String authorSeparator = isNotBlank(reference.getTitle())? afterAuthor : " ";
197
                String authorSeparator = afterAuthor;
198
                authorAndYear += authorSeparator;
199
            }
200
            result = authorAndYear + result;
201
            result = CdmUtils.addTrailingDotIfNotExists(result);
202
        }else if (isRealInRef(reference)){
203
            result = titleCacheRealInRef(reference, isAbbrev);
204
        }else if (isNomRef(type)){
205
            String authorAndYear = getAuthorAndYear(reference, isAbbrev, false);
206
            String title = getTitleWithoutYearAndAuthor(reference, isAbbrev, false);
207
            result = addPages(title, reference);
208
            //if Book, CdDvd, flat Generic, Thesis, WebPage
209
            if (isNotBlank(authorAndYear)){
210
                String authorSeparator = isNotBlank(title)? afterAuthor : "";
211
                authorAndYear += authorSeparator;
212
            }
213
            result = authorAndYear + result;
214

    
215
            if (!type.isWebPage()){
216
                result = CdmUtils.addTrailingDotIfNotExists(result);
217
            }
218
        }else if(type == ReferenceType.Journal){
219
            result = titleCacheJournal(reference, isAbbrev);
220
        }else{
221
            result = titleCacheDefaultReference(reference, isAbbrev);
222
        }
223

    
224
        return result;
225
    }
226

    
227
// ************************ TITLE CACHE SUBS ********************************************/
228

    
229
    //section, book section or generic with inRef
230
    private String titleCacheRealInRef(Reference reference, boolean isAbbrev) {
231
        ReferenceType type = reference.getType();
232
        Reference inRef = reference.getInReference();
233
        boolean hasInRef = (inRef != null);
234

    
235
        String inRefAuthorAndTitle;
236
        //copy from InRefDefaultCacheStrategyBase
237
        if (inRef != null){
238
            String inRefTitle = TitleWithoutYearAndAuthorHelper.getTitleWithoutYearAndAuthor(inRef, isAbbrev, false);
239
            TeamOrPersonBase<?> inRefAuthor = inRef.getAuthorship();
240
            String authorStr = (inRefAuthor == null)? "" : CdmUtils.getPreferredNonEmptyString(inRefAuthor.getTitleCache(),
241
                    inRefAuthor.getNomenclaturalTitle(), isAbbrev, trim);
242
            inRefAuthorAndTitle = CdmUtils.concat(afterInRefAuthor, authorStr, inRefTitle);
243
        }else{
244
            inRefAuthorAndTitle = String.format("- undefined %s -", getUndefinedLabel(type));
245
        }
246
        inRefAuthorAndTitle = CdmUtils.addTrailingDotIfNotExists(inRefAuthorAndTitle);
247

    
248
        //in
249
        String result = biblioInSeparator + inRefAuthorAndTitle;
250

    
251
        //section title
252
        String title = CdmUtils.getPreferredNonEmptyString(
253
                reference.getTitle(), reference.getAbbrevTitle(), isAbbrev, trim);
254
        if (title.matches(".*[.!\\?]")){
255
            title = title.substring(0, title.length() - 1);
256
        }
257
        //pages
258
        String pages = getPages(reference);
259
        if (isNotBlank(pages)){
260
            title = CdmUtils.concat(", ", title, pages);
261
        }
262
        if (title.length() > 0){
263
            result = title.trim() + "." + blank + result;
264
        }
265

    
266
        //section author
267
        TeamOrPersonBase<?> author = reference.getAuthorship();
268
        String authorStr = (author == null)? "" : CdmUtils.getPreferredNonEmptyString(author.getTitleCache(),
269
                author.getNomenclaturalTitle(), isAbbrev, trim);
270

    
271
        //date
272
        String dateStr = null;
273
        VerbatimTimePeriod date = (reference.getDatePublished() != null && ! reference.getDatePublished().isEmpty())? reference.getDatePublished() : null;
274
        if (date == null && hasInRef && reference.getInReference().getDatePublished() != null && !reference.getInReference().getDatePublished().isEmpty()){
275
            date = reference.getInReference().getDatePublished();
276
        }
277
        if (date != null){
278
            dateStr = date.getYear();
279
        }
280

    
281
        String authorAndYear = CdmUtils.concat(" ", authorStr, dateStr);
282

    
283
        String sep = result.startsWith(biblioInSeparator)? " ": afterSectionAuthor;
284
        result = CdmUtils.concat(sep, authorAndYear, result);
285

    
286
        return result;
287
    }
288

    
289
    private static final String pageNoRe = "[0-9iIvVxXlLcCdDmM]+";
290
    private String getPages(Reference reference) {
291

    
292
        if (isBlank(reference.getPages())){
293
            return null;
294
        }else if (reference.getPages().matches(pageNoRe + "\\s*[-"+UTF8.EN_DASH+"]\\s*"+ pageNoRe)){
295
            return "pp. " + reference.getPages();
296
        }else if (reference.getPages().matches(pageNoRe)){
297
            return "p. " + reference.getPages();
298
        }else{
299
            return reference.getPages();
300
        }
301
    }
302

    
303
    private String titleCacheJournal(Reference reference, boolean isAbbrev) {
304
        String result;
305
        //copied from Journal
306

    
307
        //title
308
        result = CdmUtils.getPreferredNonEmptyString(reference.getTitle(),
309
                reference.getAbbrevTitle(), isAbbrev, trim);
310

    
311
//          //delete .
312
//          while (result.endsWith(".")){
313
//              result = result.substring(0, result.length()-1);
314
//          }
315
//          result = addYear(result, journal);
316

    
317
        TeamOrPersonBase<?> team = reference.getAuthorship();
318
        if (team != null){
319
            String author = CdmUtils.getPreferredNonEmptyString(team.getTitleCache(),
320
                    team.getNomenclaturalTitle(), isAbbrev, trim);
321
            if (isNotBlank(author)){
322
                result = author + afterAuthor + result;
323
            }
324
        }
325
        return result;
326
    }
327

    
328
    private String titleCacheDefaultReference(Reference reference, boolean isAbbrev) {
329
        String result;
330
        //copied from ReferenceDefaultCacheStrategy
331
        result = "";
332
        String titel = CdmUtils.getPreferredNonEmptyString(reference.getTitle(),
333
                reference.getAbbrevTitle(), isAbbrev, trim);
334
        if (isNotBlank(titel)){
335
            result = titel + blank;
336
        }
337
        //delete .
338
        while (result.endsWith(".")){
339
            result = result.substring(0, result.length()-1);
340
        }
341

    
342
        result = addYearReferenceDefault(result, reference);
343
        TeamOrPersonBase<?> team = reference.getAuthorship();
344
        if (team != null){
345
            String author = CdmUtils.getPreferredNonEmptyString(team.getTitleCache(),
346
                    team.getNomenclaturalTitle(), isAbbrev, trim);
347
            if (isNotBlank(author)){
348
                result = author + afterAuthor + result;
349
            }
350
        }
351
        return result;
352
    }
353

    
354
// ******************************* HELPER *****************************************/
355

    
356
    /**
357
     * Adds the year or full date of a reference to a given string
358
     * @param currentStr the given string
359
     * @param reference the reference
360
     * @param useFullDatePublished wether to add the year only or the full date
361
     * @return the concatenated string
362
     */
363
    public static String addYear(String currentStr, Reference reference, boolean useFullDatePublished){
364
        String result;
365
        if (currentStr == null){
366
            return null;
367
        }
368
        String year = useFullDatePublished ? reference.getDatePublishedString() : reference.getYear();
369
        if (isBlank(year)){
370
            result = currentStr + afterYear;
371
        }else{
372
            String concat = isBlank(currentStr)  ? "" : currentStr.endsWith(".")  ? " " : beforeYear;
373
            result = currentStr + concat + year + afterYear;
374
        }
375
        return result;
376
    }
377

    
378
    private String addAuthorYear(String authorStr, Reference reference, boolean useFullDatePublished){
379
        String year = useFullDatePublished ? reference.getDatePublishedString() : reference.getYear();
380
        if (isBlank(year)){
381
            return authorStr;
382
        }else{
383
            return CdmUtils.concat(" ", authorStr, year);
384
        }
385
    }
386

    
387
    private String getTitleWithoutYearAndAuthor(Reference ref, boolean isAbbrev, boolean isNomRef){
388
        return TitleWithoutYearAndAuthorHelper.getTitleWithoutYearAndAuthor(ref, isAbbrev, isNomRef);
389
    }
390

    
391
    private Object getUndefinedLabel(ReferenceType type) {
392
        if (type == ReferenceType.BookSection){
393
            return "book";
394
        }else if (type == ReferenceType.Generic){
395
            return "generic reference";
396
        }else if (type == ReferenceType.Section){
397
            return "in reference";
398
        } else {
399
            return type.getLabel();
400
        }
401
    }
402

    
403
    /**
404
     * Returns <code>true</code> if the type of the reference originally corresponded to a cache strategy
405
     * which inherited from {@link InRefDefaultCacheStrategyBase} and in case of type {@link ReferenceType#Generic}
406
     * if it really has an inreference (reference.getInreference() != null).
407
     * @param reference
408
     */
409
    public static boolean isRealInRef(Reference reference) {
410
        ReferenceType type = (reference.getType());
411
        if (type == null){
412
            return false;
413
        }else if (type == ReferenceType.BookSection || type == ReferenceType.Section){
414
            return true;
415
        }else if (type == ReferenceType.Generic){
416
            return reference.getInReference() != null;
417
        }else{
418
            return false;
419
        }
420
    }
421

    
422
    /**
423
     * Returns <code>true</code> if the type of the reference originally corresponded to a cache strategy
424
     * which inherited from {@link NomRefDefaultCacheStrategyBase}.
425
     * @param type
426
     * @see ReferenceType#isNomRef()
427
     */
428
    public static boolean isNomRef(ReferenceType type){
429
        return type == null ? false : type.isNomRef();
430
    }
431

    
432
    /**
433
     * Returns year information as originally computed by {@link ReferenceDefaultCacheStrategy}.
434
     */
435
    private String addYearReferenceDefault(String string, Reference ref){
436
        String result;
437
        if (string == null){
438
            return null;
439
        }
440
        String year = CdmUtils.Nz(ref.getYear());
441
        if ("".equals(year)){
442
            result = string + afterYear;
443
        }else{
444
            result = string.trim() + beforeYear + year + afterYear;
445
        }
446
        return result;
447
    }
448

    
449
// *************************** EXTERNAL USE *******************************************/
450

    
451
   public static String putAuthorToEndOfString(String referenceTitle, String authorTitle) {
452
       if(authorTitle != null){
453
           referenceTitle = referenceTitle.replace(authorTitle + ", ", "");
454
           referenceTitle += " - " + authorTitle;
455
       }
456
       return referenceTitle;
457
   }
458
}
(2-2/3)