Project

General

Profile

Download (26.4 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.commons.lang.StringUtils;
14
import org.apache.log4j.Logger;
15
import org.joda.time.DateTime;
16
import org.joda.time.format.DateTimeFormat;
17
import org.joda.time.format.DateTimeFormatter;
18

    
19
import eu.etaxonomy.cdm.common.CdmUtils;
20
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
21
import eu.etaxonomy.cdm.model.common.CdmBase;
22
import eu.etaxonomy.cdm.model.common.TimePeriod;
23
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
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 computes allows 3 formattings:<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
 *
42
 *  3.) for nomenclatural references with micro reference, but not stored anywhere as the micro reference
43
 *      is part of the name, not of the reference<BR>
44
 *
45
 *  4.) for short citation (e.g. Author 2009) as defined in {@link IReferenceCacheStrategy#getCitation(Reference)}
46
 *
47
 * @author a.mueller
48
 \* @since 25.05.2016
49
 *
50
 */
51
public class DefaultReferenceCacheStrategy extends StrategyBase implements INomenclaturalReferenceCacheStrategy{
52
    private static final long serialVersionUID = 6773742298840407263L;
53

    
54
    private static final Logger logger = Logger.getLogger(DefaultReferenceCacheStrategy.class);
55

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

    
58
    //article
59
    public static final String UNDEFINED_JOURNAL = "- undefined journal -";
60
    private static final String afterAuthor = ", ";
61

    
62
    //book
63

    
64

    
65
    //(book?) section
66
    private String afterSectionAuthor = " - ";
67

    
68
    //in reference
69
    private String inSeparator = "in ";
70
    private static final String afterInRefAuthor = ", ";
71

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

    
78

    
79
    private static final boolean trim = true;
80

    
81
// ************************ FACTORY ****************************/
82

    
83
    /**
84
     * Factory method
85
     * @return
86
     */
87
    public static DefaultReferenceCacheStrategy NewInstance(){
88
        return new DefaultReferenceCacheStrategy();
89
    }
90

    
91

    
92
    @Override
93
    protected UUID getUuid() {
94
        return uuid;
95
    }
96

    
97
// ******************************* Main methods ******************************/
98

    
99
    @Override
100
    public String getTitleCache(Reference reference) {
101
        if (reference == null){
102
            return null;
103
        }
104
        if (reference.isProtectedTitleCache()){
105
            return reference.getTitleCache();
106
        }
107
        boolean isNotAbbrev = false;
108

    
109
        String result;
110
        ReferenceType type = reference.getType();
111

    
112
        if (isRealInRef(reference)){
113
            result = titleCacheRealInRef(reference, isNotAbbrev);
114
        }else if(isNomRef(type)){
115
            //all Non-InRef NomRefs
116
            result =  getTitleWithoutYearAndAuthor(reference, isNotAbbrev);
117
            result = addPages(result, reference);
118
            result = addYear(result, reference, false);
119
            TeamOrPersonBase<?> team = reference.getAuthorship();
120

    
121
            if (type == ReferenceType.Article){
122
                result = CdmUtils.concat(" ", reference.getTitle(), result);
123
                if (team != null &&  isNotBlank(team.getTitleCache())){
124
                    String authorSeparator = isNotBlank(reference.getTitle())? afterAuthor : " ";
125
                    result = team.getTitleCache() + authorSeparator + result;
126
                }
127
            }else{  //if Book, CdDvd, flat Generic, Thesis, WebPage
128
                if (team != null){
129
                    String teamTitle = CdmUtils.getPreferredNonEmptyString(team.getTitleCache(),
130
                            team.getNomenclaturalTitle(), isNotAbbrev, trim);
131
                    if (teamTitle.length() > 0 ){
132
                        String concat = isNotBlank(result) ? afterAuthor : "";
133
                        result = teamTitle + concat + result;
134
                    }
135
                }
136
            }
137
        }else if (type == ReferenceType.Journal){
138
            result = titleCacheJournal(reference, isNotAbbrev);
139
        }else{
140
            result = titleCacheDefaultReference(reference, isNotAbbrev);
141
        }
142
        if (reference.getType() == ReferenceType.WebPage && reference.getUri() != null && !result.contains(reference.getUri().toString())){
143
            //might become UTF8.EN_DASH in future
144
            result = CdmUtils.concat(" - ", result, reference.getUri().toString());
145
        }
146
        if(reference.getAccessed() != null){
147
            //TODO still a bit preliminary, also brackets may change in future
148
            result = result + " [accessed " + getAccessedString(reference.getAccessed()) +"]";
149
        }
150
        return result;
151
    }
152

    
153

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

    
167

    
168
    /**
169
     * @param result
170
     * @param reference
171
     * @return
172
     */
173
    private String addPages(String result, Reference reference) {
174
        //pages
175
        if (isNotBlank(reference.getPages())){
176
            //Removing trailing added just in case, maybe not necessary
177
            result = RemoveTrailingDot(Nz(result)).trim() + ": " + reference.getPages();
178
        }
179
        return result;
180
    }
181

    
182

    
183
    /**
184
     * @param nz
185
     * @return
186
     */
187
    private static String RemoveTrailingDot(String str) {
188
        if (str != null && str.endsWith(".")){
189
            str = str.substring(0, str.length()-1);
190
        }
191
        return str;
192
    }
193

    
194

    
195
    @Override
196
    public String getFullAbbrevTitleString(Reference reference) {
197
        if (reference == null){
198
            return null;
199
        }
200
        String result;
201
        ReferenceType type = reference.getType();
202
        boolean isAbbrev = true;
203

    
204
        if (reference.isProtectedAbbrevTitleCache()){
205
            return reference.getAbbrevTitleCache();
206
        }
207

    
208
        if (type == ReferenceType.Article){
209
            result =  getTitleWithoutYearAndAuthor(reference, isAbbrev);
210
            boolean useFullDatePublished = false;
211
            result = addYear(result, reference, useFullDatePublished);
212
            TeamOrPersonBase<?> team = reference.getAuthorship();
213
            String articleTitle = CdmUtils.getPreferredNonEmptyString(reference.getTitle(),
214
                    reference.getAbbrevTitle(), isAbbrev, trim);
215
            result = CdmUtils.concat(" ", articleTitle, result);  //Article should maybe left out for nomenclatural references (?)
216
            if (team != null &&  isNotBlank(team.getNomenclaturalTitle())){
217
                String authorSeparator = isNotBlank(articleTitle) ? afterAuthor : " ";
218
                result = team.getNomenclaturalTitle() + authorSeparator + result;
219
            }
220
        }else if (isRealInRef(reference)){
221
            result = titleCacheRealInRef(reference, isAbbrev);
222
        }else if (isNomRef(type)){
223
            //FIXME same as titleCache => try to merge, but note article case
224
            result =  getTitleWithoutYearAndAuthor(reference, isAbbrev);
225
            boolean useFullDatePublished = false;
226
            result = addYear(result, reference, useFullDatePublished);
227
            TeamOrPersonBase<?> team = reference.getAuthorship();
228

    
229
            if (team != null){
230
                String teamTitle = CdmUtils.getPreferredNonEmptyString(team.getTitleCache(),
231
                        team.getNomenclaturalTitle(), isAbbrev, trim);
232
                if (teamTitle.length() > 0 ){
233
                    String concat = isNotBlank(result) ? afterAuthor : "";
234
                    result = teamTitle + concat + result;
235
                }
236
            }
237
        }else if(type == ReferenceType.Journal){
238
            result = titleCacheJournal(reference, isAbbrev);
239
        }else{
240
            result = titleCacheDefaultReference(reference, isAbbrev);
241
        }
242

    
243
        return result;
244
    }
245

    
246
    @Override
247
    public String getCitation(Reference reference) {
248
        // mostly copied from nomRefCacheStrat, refCache, journalCache
249

    
250
        if (reference == null){
251
            return null;
252
        }
253
        StringBuilder stringBuilder = new StringBuilder();
254
        TeamOrPersonBase<?> team = reference.getAuthorship();
255

    
256
        String nextConcat = "";
257

    
258
        if (team != null &&  isNotBlank(team.getTitleCache())){
259
            stringBuilder.append(team.getTitleCache() );
260
            //here is the difference between nomRef and others
261
            if (isNomRef(reference.getType())) {
262
                nextConcat = afterAuthor;
263
            }else{
264
                //FIXME check if this really makes sense
265
                stringBuilder.append(afterAuthor);
266
                nextConcat = beforeYear;
267
            }
268
        }
269

    
270
        String year = reference.getYear();
271
        if (StringUtils.isNotBlank(year)){
272
            stringBuilder.append(nextConcat + year);
273
        }
274

    
275
        return stringBuilder.toString();
276
    }
277

    
278
    @Override
279
    public String getNomenclaturalCache(Reference reference) {
280
        return this.getNomenclaturalCitation(reference, null);
281
    }
282

    
283
// ************************ TITLE CACHE SUBS ********************************************/
284

    
285
    /**
286
     * @param reference
287
     * @param type
288
     * @param inRef
289
     * @param hasInRef
290
     * @return
291
     */
292
    private String titleCacheRealInRef(Reference reference, boolean isAbbrev) {
293
        ReferenceType type = reference.getType();
294
        Reference inRef = reference.getInReference();
295
        boolean hasInRef = (inRef != null);
296

    
297
        String result;
298
        //copy from InRefDefaultCacheStrategyBase
299
        if (inRef != null){
300
            result = CdmUtils.getPreferredNonEmptyString(inRef.getTitleCache(),
301
                    inRef.getAbbrevTitleCache(), isAbbrev, trim)  ;
302
        }else{
303
            result = String.format("- undefined %s -", getUndefinedLabel(type));
304
        }
305

    
306
        //in
307
        result = inSeparator +  result;
308

    
309
        //section title
310
        String title = CdmUtils.getPreferredNonEmptyString(
311
                reference.getTitle(), reference.getAbbrevTitle(), isAbbrev, trim);
312
        if (title.length() > 0){
313
            result = title + blank + result;
314
        }
315

    
316
        //section author
317
        TeamOrPersonBase<?> thisRefTeam = reference.getAuthorship();
318
        String thisRefAuthor = "";
319
        if (thisRefTeam != null){
320
            thisRefAuthor = CdmUtils.getPreferredNonEmptyString(thisRefTeam.getTitleCache(),
321
                    thisRefTeam.getNomenclaturalTitle(), isAbbrev, trim);
322
        }
323
        result = CdmUtils.concat(afterSectionAuthor, thisRefAuthor, result);
324

    
325
        //date
326
        if (reference.getDatePublished() != null && ! reference.getDatePublished().isEmpty()){
327
            String thisRefDate = reference.getDatePublished().toString();
328
            if (hasInRef && reference.getInBook().getDatePublished() != null){
329
                TimePeriod inRefDate = reference.getInReference().getDatePublished();
330
                String inRefDateString = inRefDate.getYear();
331
                if (isNotBlank(inRefDateString)){
332
                    int pos = StringUtils.lastIndexOf(result, inRefDateString);
333
                    if (pos > -1 ){
334
                        result = result.substring(0, pos) + thisRefDate + result.substring(pos + inRefDateString.length());
335
                    }else{
336
                        logger.warn("InRefDateString (" + inRefDateString + ") could not be found in result (" + result +")");
337
                    }
338
                }else{
339
                    //avoid duplicate dots ('..')
340
                    String bYearSeparator = result.substring(result.length() -1).equals(beforeYear.substring(0, 1)) ? beforeYear.substring(1) : beforeYear;
341
                    result = result + bYearSeparator + thisRefDate + afterYear;
342
                }
343
            }else{
344
                result = result + beforeYear + thisRefDate + afterYear;
345
            }
346
        }
347
        return result;
348
    }
349

    
350

    
351
    /**
352
     * @param reference
353
     * @return
354
     */
355
    private String titleCacheJournal(Reference reference, boolean isAbbrev) {
356
        String result;
357
        //copied from Journal
358

    
359
        //title
360
        result = CdmUtils.getPreferredNonEmptyString(reference.getTitle(),
361
                reference.getAbbrevTitle(), isAbbrev, trim);
362

    
363
//          //delete .
364
//          while (result.endsWith(".")){
365
//              result = result.substring(0, result.length()-1);
366
//          }
367
//          result = addYear(result, journal);
368

    
369
        TeamOrPersonBase<?> team = reference.getAuthorship();
370
        if (team != null){
371
            String author = CdmUtils.getPreferredNonEmptyString(team.getTitleCache(),
372
                    team.getNomenclaturalTitle(), isAbbrev, trim);
373
            if (StringUtils.isNotBlank(author)){
374
                result = author + afterAuthor + result;
375
            }
376
        }
377
        return result;
378
    }
379

    
380
    /**
381
     * @param reference
382
     * @param isNotAbbrev
383
     * @return
384
     */
385
    private String titleCacheDefaultReference(Reference reference, boolean isAbbrev) {
386
        String result;
387
        //copied from ReferenceDefaultCacheStrategy
388
        result = "";
389
        String titel = CdmUtils.getPreferredNonEmptyString(reference.getTitle(),
390
                reference.getAbbrevTitle(), isAbbrev, trim);
391
        if (isNotBlank(titel)){
392
            result = titel + blank;
393
        }
394
        //delete .
395
        while (result.endsWith(".")){
396
            result = result.substring(0, result.length()-1);
397
        }
398

    
399
        result = addYearReferenceDefault(result, reference);
400
        TeamOrPersonBase<?> team = reference.getAuthorship();
401
        if (team != null){
402
            String author = CdmUtils.getPreferredNonEmptyString(team.getTitleCache(),
403
                    team.getNomenclaturalTitle(), isAbbrev, trim);
404
            if (isNotBlank(author)){
405
                result = author + afterAuthor + result;
406
            }
407
        }
408
        return result;
409
    }
410

    
411
// ******************************* HELPER *****************************************/
412
    @Override
413
    public String getBeforeMicroReference(){
414
        return beforeMicroReference;
415
    }
416

    
417
    private String addYear(String string, Reference nomRef, boolean useFullDatePublished){
418
        String result;
419
        if (string == null){
420
            return null;
421
        }
422
        String year = useFullDatePublished ? nomRef.getDatePublishedString() : nomRef.getYear();
423
        if (isBlank(year)){
424
            result = string + afterYear;
425
        }else{
426
            String concat = isBlank(string)  ? "" : string.endsWith(".")  ? " " : beforeYear;
427
            result = string + concat + year + afterYear;
428
        }
429
        return result;
430
    }
431

    
432
    private String getTitleWithoutYearAndAuthor(Reference ref, boolean isAbbrev){
433
        return TitleWithoutYearAndAuthorHelper.getTitleWithoutYearAndAuthor(ref, isAbbrev);
434
    }
435
    private String getTitleWithoutYearAndAuthorGeneric(Reference ref, boolean isAbbrev){
436
        return TitleWithoutYearAndAuthorHelper.getTitleWithoutYearAndAuthorGeneric(ref, isAbbrev);
437
    }
438

    
439
    /**
440
     * @param type
441
     * @return
442
     */
443
    private Object getUndefinedLabel(ReferenceType type) {
444
        if (type == ReferenceType.BookSection){
445
            return "book";
446
        }else if (type == ReferenceType.Generic){
447
            return "generic reference";
448
        }else if (type == ReferenceType.Section){
449
            return "in reference";
450
        } else {
451
            return type.getMessage();
452
        }
453
    }
454

    
455

    
456
    /**
457
     * Returns <code>true</code> if the type of the reference originally corresponded to a cache strategy
458
     * which inherited from {@link InRefDefaultCacheStrategyBase} and in case of type {@link ReferenceType#Generic}
459
     * if it really has an inreference (reference.getInreference() != null).
460
     * @param reference
461
     */
462
    private boolean isRealInRef(Reference reference) {
463
        ReferenceType type = (reference.getType());
464
        if (type == null){
465
            return false;
466
        }else if (type == ReferenceType.BookSection || type == ReferenceType.Section){
467
            return true;
468
        }else if (type == ReferenceType.Generic){
469
            return reference.getInReference() != null;
470
        }else{
471
            return false;
472
        }
473
    }
474

    
475
    /**
476
     * Returns <code>true</code> if the type of the reference originally corresponded to a cache strategy
477
     * which inherited from {@link NomRefDefaultCacheStrategyBase}.
478
     * @param type
479
     */
480
    protected static boolean isNomRef(ReferenceType type){
481
        switch (type){
482
            case Article:
483
            case Book:
484
            case BookSection:
485
            case CdDvd:
486
            case Generic:
487
            case Section:
488
            case Thesis:
489
            case WebPage:
490
                return true;
491

    
492
            case Journal:
493
            default:
494
                return false;
495
        }
496
    }
497

    
498
    /**
499
     * Returns year information as originally computed by {@link ReferenceDefaultCacheStrategy}
500
     * @param string
501
     * @param ref
502
     * @return
503
     */
504
    private String addYearReferenceDefault(String string, Reference ref){
505
        String result;
506
        if (string == null){
507
            return null;
508
        }
509
        String year = CdmUtils.Nz(ref.getYear());
510
        if ("".equals(year)){
511
            result = string + afterYear;
512
        }else{
513
            result = string + beforeYear + year + afterYear;
514
        }
515
        return result;
516
    }
517

    
518

    
519
// ********************* Nomenclatural title ***************************************/
520

    
521
    @Override
522
    public String getNomenclaturalCitation(Reference reference, String microReference) {
523
        if (reference.isProtectedAbbrevTitleCache()){
524
            String cache = reference.getAbbrevTitleCache();
525
            return handleDetailAndYearForPreliminary(reference, cache, microReference);
526

    
527
        }
528
        String result = getTokenizedNomenclaturalTitel(reference);
529
        //if no data is available and only titleCache is protected take the protected title
530
        //this is to avoid empty cache if someone forgets to set also the abbrevTitleCache
531
        //we need to think about handling protected not separate for abbrevTitleCache  and titleCache
532
        if (result.equals(INomenclaturalReference.MICRO_REFERENCE_TOKEN) && reference.isProtectedTitleCache() ){
533
            String cache = reference.getTitleCache();
534
            return handleDetailAndYearForPreliminary(reference, cache, microReference);
535
        }
536

    
537
        microReference = Nz(microReference);
538
        if (StringUtils.isNotBlank(microReference)){
539
            microReference = getBeforeMicroReference() + microReference;
540
            if (microReference.endsWith(".")  && result.contains(INomenclaturalReference.MICRO_REFERENCE_TOKEN + ".") ){
541
                microReference = microReference.substring(0, microReference.length() - 1);
542
            }
543
        }
544
        result = replaceMicroRefToken(microReference, result);
545
        if (result.startsWith(". ")){  //only year available, remove '. '
546
            result = result.substring(2);
547
        }
548
        return result;
549
    }
550

    
551
    /**
552
     * @param nomenclaturalReference
553
     * @param microRef
554
     * @return
555
     */
556
    private String handleDetailAndYearForPreliminary(Reference nomenclaturalReference, String cache, String microReference) {
557
        String microRef = isNotBlank(microReference) ? getBeforeMicroReference() + microReference : "";
558
        if (cache == null){
559
            logger.warn("Cache is null. This should never be the case.");
560
            cache = "";
561
        }
562
        String  result = cache + (cache.contains(microRef) ? "" : microRef);
563

    
564
        String date = nomenclaturalReference.getDatePublishedString();
565
        if (isNotBlank(date) && ! result.contains(date)){
566
            result = result + beforeYear + date;
567
        }
568
        return result;
569
    }
570

    
571
    /**
572
     * Returns the nomenclatural title with micro reference represented as token
573
     * which can later be replaced by the real data.
574
     *
575
     * @see INomenclaturalReference#MICRO_REFERENCE_TOKEN
576
     *
577
     * @param ref The reference
578
     * @return
579
     */
580
    private String getTokenizedNomenclaturalTitel(Reference ref) {
581
        if (isRealInRef(ref)){
582
            return getTokenizedNomenclaturalTitelInRef(ref);
583
        }else{
584
            String result = getTitleWithoutYearAndAuthor(ref, true);
585
            result += INomenclaturalReference.MICRO_REFERENCE_TOKEN;
586
            result = addYear(result, ref, true);
587
            return result;
588
        }
589
    }
590

    
591
    private String getTokenizedNomenclaturalTitelInRef(Reference thisRef) {
592
        if (thisRef == null){
593
            return null;
594
        }
595

    
596
        Reference inRef = CdmBase.deproxy(thisRef.getInReference(), Reference.class);
597
        if (inRef != null && inRef.getInReference() != null && thisRef.getType() == ReferenceType.Section){
598
            //this is a reference of type Section which has a in-in-Ref
599
            //TODO maybe we do not need to restrict to type=Section only
600
            return this.getTokenizedNomenclaturalTitelInInRef(thisRef);
601
        }
602

    
603
        String result;
604
        //use generics's publication date if it exists
605
        if (inRef == null ||  (thisRef.hasDatePublished() ) ){
606
            getTitleWithoutYearAndAuthorGeneric(inRef, true);
607
            result =  inRef == null ? "" : getTitleWithoutYearAndAuthorGeneric(inRef, true);
608
            //added //TODO unify with non-inRef references formatting
609

    
610
            if (isNotBlank(thisRef.getVolume())){
611
                result = result + " " + thisRef.getVolume();
612
            }
613
            //TODO series / edition
614

    
615
            //end added
616
            result += INomenclaturalReference.MICRO_REFERENCE_TOKEN;
617
            result = addYear(result, thisRef, true);
618
        }else{
619
            //else use inRefs's publication date
620
            result = inRef.getNomenclaturalCitation(INomenclaturalReference.MICRO_REFERENCE_TOKEN);
621
            if (result != null){
622
                result = result.replace(beforeMicroReference +  INomenclaturalReference.MICRO_REFERENCE_TOKEN, INomenclaturalReference.MICRO_REFERENCE_TOKEN);
623
            }
624
        }
625
        //FIXME: vol. etc., http://dev.e-taxonomy.eu/trac/ticket/2862
626

    
627
        result = getInRefAuthorPart(thisRef.getInReference(), afterInRefAuthor) + result;
628
        result = "in " +  result;
629
        return result;
630
    }
631

    
632
    /**
633
     * For handling in-in-Ref case.
634
     * Must only be called if a reference has inRef and inInRef
635
     * @param section
636
     * @return
637
     */
638
    private String getTokenizedNomenclaturalTitelInInRef(Reference ref) {
639
        String result;
640

    
641
        Reference inRef = CdmBase.deproxy(ref.getInReference(), Reference.class);
642
        Reference inInRef = CdmBase.deproxy(inRef.getInReference(), Reference.class);
643

    
644
        if (! isNomRef(inInRef.getType())){
645
            if (! isNomRef(inRef.getType())){
646
                logger.warn("Neither inReference nor inInReference is a "
647
                        + " nomenclatural reference. This is not correct or not handled yet."
648
                        + " Generic titleWithoutYearAndAuthor used instead");
649
                result = getTitleWithoutYearAndAuthorGeneric(inInRef, true);
650
                //FIXME: vol. etc., http://dev.e-taxonomy.eu/trac/ticket/2862  (comment taken from super.getTokenizedNomenclaturalTitel())
651
            }else{
652
                result = getTitleWithoutYearAndAuthor(inRef, true);
653
            }
654
        }else{
655
            result = getTitleWithoutYearAndAuthor(inInRef, true);
656
        }
657
        result += INomenclaturalReference.MICRO_REFERENCE_TOKEN;
658

    
659
        Reference dataReference = (ref.hasDatePublished() ? ref : inRef.hasDatePublished() ? inRef : inInRef);
660

    
661
        result = addYear(result, dataReference, true);
662

    
663
        result = getInRefAuthorPart(inInRef, afterInRefAuthor) + result;
664
        if (! result.startsWith("in ")){
665
            result = "in " +  result;
666
        }
667
        return result;
668
    }
669

    
670
    private String getInRefAuthorPart(Reference book, String seperator){
671
        if (book == null){
672
            return "";
673
        }
674
        TeamOrPersonBase<?> team = book.getAuthorship();
675
        String result = Nz( team == null ? "" : team.getNomenclaturalTitle());
676
        if (! result.trim().equals("")){
677
            result = result + seperator;
678
        }
679
        return result;
680
    }
681

    
682

    
683
    /**
684
     * @param microReference
685
     * @param result
686
     * @return
687
     */
688
    private String replaceMicroRefToken(String microReference, String string) {
689
        int index = string.indexOf(INomenclaturalReference.MICRO_REFERENCE_TOKEN);
690

    
691
        if (index > -1){
692
            String before = string.substring(0, index);
693
            String after = string.substring(index + INomenclaturalReference.MICRO_REFERENCE_TOKEN.length() );
694
            String localMicroReference = microReference.trim();   //needed ?
695
            if (after.length() > 0){
696
                if (  ("".equals(localMicroReference) && before.endsWith(after.substring(0,1)) || localMicroReference.endsWith(after.substring(0,1)))){
697
                    after = after.substring(1);
698
                }
699
            }
700
            String result = before + localMicroReference + after;
701
            return result;
702
        }else{
703
            return string;
704
        }
705
    }
706

    
707
// *************************** EXTERNAL USE *******************************************/
708
   /**
709
    *
710
    * @param referenceTitleCache
711
    * @param authorTitleCache
712
    * @return
713
    */
714
   public static String putAuthorToEndOfString(String referenceTitleCache, String authorTitleCache) {
715
       if(authorTitleCache != null){
716
           referenceTitleCache = referenceTitleCache.replace(authorTitleCache + ", ", "");
717
           referenceTitleCache += " - " + authorTitleCache;
718
       }
719
       return referenceTitleCache;
720
   }
721
}
(1-1/4)