Project

General

Profile

Download (27.9 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.List;
12
import java.util.UUID;
13

    
14
import org.apache.commons.lang.StringUtils;
15
import org.apache.log4j.Logger;
16
import org.joda.time.DateTime;
17
import org.joda.time.format.DateTimeFormat;
18
import org.joda.time.format.DateTimeFormatter;
19

    
20
import eu.etaxonomy.cdm.common.CdmUtils;
21
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
22
import eu.etaxonomy.cdm.model.agent.Person;
23
import eu.etaxonomy.cdm.model.agent.Team;
24
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
25
import eu.etaxonomy.cdm.model.common.CdmBase;
26
import eu.etaxonomy.cdm.model.common.VerbatimTimePeriod;
27
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
28
import eu.etaxonomy.cdm.model.reference.Reference;
29
import eu.etaxonomy.cdm.model.reference.ReferenceType;
30
import eu.etaxonomy.cdm.strategy.StrategyBase;
31

    
32
/**
33
 * #5833
34
 * The new single default cache strategy for {@link Reference references}.
35
 * As we do have only one {@link Reference} class left which implements multiple interfaces,
36
 * we may also only need 1 single cache strategy. However, care must be taken as the formatting
37
 * differs dependent on the type an the in-reference structure.
38
 *
39
 * Generally the cache strategy computes allows 3 formattings:<BR>
40
 *
41
 *  1.) for bibliographic references (stored in {@link Reference#getTitleCache() titleCache}).<BR>
42
 *
43
 *  2.) for nomenclatural references (stored in {@link Reference#getAbbrevTitleCache() abbrevTitleCache}),
44
 *      but without micro reference (detail).<BR>
45
 *
46
 *  3.) for nomenclatural references with micro reference, but not stored anywhere as the micro reference
47
 *      is part of the name, not of the reference<BR>
48
 *
49
 *  4.) for short citation (e.g. Author 2009) as defined in {@link IReferenceCacheStrategy#getCitation(Reference)}
50
 *
51
 * @author a.mueller
52
 * @since 25.05.2016
53
 */
54
public class DefaultReferenceCacheStrategy extends StrategyBase implements INomenclaturalReferenceCacheStrategy{
55
    private static final long serialVersionUID = 6773742298840407263L;
56

    
57
    private static final Logger logger = Logger.getLogger(DefaultReferenceCacheStrategy.class);
58

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

    
61
    //article
62
    public static final String UNDEFINED_JOURNAL = "- undefined journal -";
63
    private static final String afterAuthor = ", ";
64

    
65
    //book
66

    
67

    
68
    //(book?) section
69
    private String afterSectionAuthor = " - ";
70

    
71
    //in reference
72
    private String inSeparator = "in ";
73
    private static final String afterInRefAuthor = ", ";
74

    
75
    //common
76
    private static final String blank = " ";
77
    private static final String beforeYear = ". ";
78
    private static final String beforeMicroReference = ": ";
79
    private static final String afterYear = "";
80

    
81
    private static final boolean trim = true;
82

    
83
// ************************ FACTORY ****************************/
84

    
85
    public static DefaultReferenceCacheStrategy NewInstance(){
86
        return new DefaultReferenceCacheStrategy();
87
    }
88

    
89
// ******************************* Main methods ******************************/
90

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

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

    
106
        String result;
107
        ReferenceType type = reference.getType();
108

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

    
118
            if (type == ReferenceType.Article){
119
                result = CdmUtils.concat(" ", reference.getTitle(), result);
120
                if (team != null &&  isNotBlank(team.getTitleCache())){
121
                    String authorSeparator = isNotBlank(reference.getTitle())? afterAuthor : " ";
122
                    result = team.getTitleCache() + authorSeparator + result;
123
                }
124
            }else{  //if Book, CdDvd, flat Generic, Thesis, WebPage
125
                if (team != null){
126
                    String teamTitle = CdmUtils.getPreferredNonEmptyString(team.getTitleCache(),
127
                            team.getNomenclaturalTitle(), isNotAbbrev, trim);
128
                    if (teamTitle.length() > 0 ){
129
                        String concat = isNotBlank(result) ? afterAuthor : "";
130
                        result = teamTitle + concat + result;
131
                    }
132
                }
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
            //might become UTF8.EN_DASH in future
141
            result = CdmUtils.concat(" - ", result, reference.getUri().toString());
142
        }
143
        if(reference.getAccessed() != null){
144
            //TODO still a bit preliminary, also brackets may change in future
145
            result = result + " [accessed " + getAccessedString(reference.getAccessed()) +"]";
146
        }
147
        return result;
148
    }
149

    
150
    private String getAccessedString(DateTime accessed) {
151
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
152
        String result = formatter.print(accessed);
153
        if (result.endsWith(" 00:00")){
154
            result = result.replace(" 00:00", "");
155
        }
156
        return result;
157
    }
158

    
159
    private String addPages(String result, Reference reference) {
160
        //pages
161
        if (isNotBlank(reference.getPages())){
162
            //Removing trailing added just in case, maybe not necessary
163
            result = RemoveTrailingDot(Nz(result)).trim() + ": " + reference.getPages();
164
        }
165
        return result;
166
    }
167

    
168
    private static String RemoveTrailingDot(String str) {
169
        if (str != null && str.endsWith(".")){
170
            str = str.substring(0, str.length()-1);
171
        }
172
        return str;
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);
190
            boolean useFullDatePublished = false;
191
            result = addYear(result, reference, useFullDatePublished);
192
            TeamOrPersonBase<?> team = reference.getAuthorship();
193
            String articleTitle = CdmUtils.getPreferredNonEmptyString(reference.getTitle(),
194
                    reference.getAbbrevTitle(), isAbbrev, trim);
195
            result = CdmUtils.concat(" ", articleTitle, result);  //Article should maybe left out for nomenclatural references (?)
196
            if (team != null &&  isNotBlank(team.getNomenclaturalTitle())){
197
                String authorSeparator = isNotBlank(articleTitle) ? afterAuthor : " ";
198
                result = team.getNomenclaturalTitle() + authorSeparator + result;
199
            }
200
        }else if (isRealInRef(reference)){
201
            result = titleCacheRealInRef(reference, isAbbrev);
202
        }else if (isNomRef(type)){
203
            //FIXME same as titleCache => try to merge, but note article case
204
            result =  getTitleWithoutYearAndAuthor(reference, isAbbrev);
205
            boolean useFullDatePublished = false;
206
            result = addYear(result, reference, useFullDatePublished);
207
            TeamOrPersonBase<?> team = reference.getAuthorship();
208

    
209
            if (team != null){
210
                String teamTitle = CdmUtils.getPreferredNonEmptyString(team.getTitleCache(),
211
                        team.getNomenclaturalTitle(), isAbbrev, trim);
212
                if (teamTitle.length() > 0 ){
213
                    String concat = isNotBlank(result) ? afterAuthor : "";
214
                    result = teamTitle + concat + result;
215
                }
216
            }
217
        }else if(type == ReferenceType.Journal){
218
            result = titleCacheJournal(reference, isAbbrev);
219
        }else{
220
            result = titleCacheDefaultReference(reference, isAbbrev);
221
        }
222

    
223
        return result;
224
    }
225

    
226
    @Override
227
    public String getCitation(Reference reference) {
228
        // mostly copied from nomRefCacheStrat, refCache, journalCache
229

    
230
        if (reference == null){
231
            return null;
232
        }
233
        StringBuilder stringBuilder = new StringBuilder();
234
        TeamOrPersonBase<?> team = reference.getAuthorship();
235

    
236
        String nextConcat = "";
237

    
238
        if (team != null &&  isNotBlank(team.getTitleCache())){
239
            stringBuilder.append(team.getTitleCache() );
240
            //here is the difference between nomRef and others
241
            if (isNomRef(reference.getType())) {
242
                nextConcat = afterAuthor;
243
            }else{
244
                //FIXME check if this really makes sense
245
                stringBuilder.append(afterAuthor);
246
                nextConcat = beforeYear;
247
            }
248
        }
249

    
250
        String year = reference.getYear();
251
        if (StringUtils.isNotBlank(year)){
252
            stringBuilder.append(nextConcat + year);
253
        }
254

    
255
        return stringBuilder.toString();
256
    }
257

    
258
    public String createShortCitation(Reference reference) {
259
        TeamOrPersonBase<?> authorship = reference.getAuthorship();
260
        String shortCitation = "";
261
        if (authorship == null) {
262
            return null;
263
        }
264
        authorship = HibernateProxyHelper.deproxy(authorship);
265
        if (authorship instanceof Person){
266
            shortCitation = ((Person)authorship).getFamilyName();
267
            if (StringUtils.isBlank(shortCitation) ){
268
                shortCitation = ((Person)authorship).getTitleCache();
269
            }
270
        }
271
        else if (authorship instanceof Team){
272

    
273
            Team authorTeam = HibernateProxyHelper.deproxy(authorship, Team.class);
274
            int index = 0;
275

    
276
            for (Person teamMember : authorTeam.getTeamMembers()){
277
                index++;
278
                if (index == 3){
279
                    shortCitation += " & al.";
280
                    break;
281
                }
282
                String concat = concatString(authorTeam, authorTeam.getTeamMembers(), index, ", ", " & ");
283
                if (teamMember.getFamilyName() != null){
284
                    shortCitation += concat + teamMember.getFamilyName();
285
                }else{
286
                    shortCitation += concat + teamMember.getTitleCache();
287
                }
288

    
289
            }
290
            if (StringUtils.isBlank(shortCitation)){
291
                shortCitation = authorTeam.getTitleCache();
292
            }
293

    
294
        }
295
        if (reference.getDatePublished() != null) {
296
            if (!StringUtils.isBlank(reference.getDatePublished().getFreeText())){
297
                shortCitation = shortCitation + " (" + reference.getDatePublished().getFreeText() + ")";
298
            }else if (!StringUtils.isBlank(reference.getYear()) ){
299
                shortCitation = shortCitation + " (" + reference.getYear() + ")";
300
            }
301
        }
302

    
303
        return shortCitation;
304
    }
305

    
306
    private static String concatString(Team team, List<Person> teamMembers, int i, String std_team_concatination, String final_team_concatination) {
307
        String concat;
308
        if (i <= 1){
309
            concat = "";
310
        }else if (i < teamMembers.size() || ( team.isHasMoreMembers() && i == teamMembers.size())){
311
            concat = std_team_concatination;
312
        }else{
313
            concat = final_team_concatination;
314
        }
315
        return concat;
316
    }
317

    
318
    @Override
319
    public String getNomenclaturalCache(Reference reference) {
320
        return this.getNomenclaturalCitation(reference, null);
321
    }
322

    
323
// ************************ TITLE CACHE SUBS ********************************************/
324

    
325
    private String titleCacheRealInRef(Reference reference, boolean isAbbrev) {
326
        ReferenceType type = reference.getType();
327
        Reference inRef = reference.getInReference();
328
        boolean hasInRef = (inRef != null);
329

    
330
        String result;
331
        //copy from InRefDefaultCacheStrategyBase
332
        if (inRef != null){
333
            result = CdmUtils.getPreferredNonEmptyString(inRef.getTitleCache(),
334
                    inRef.getAbbrevTitleCache(), isAbbrev, trim)  ;
335
        }else{
336
            result = String.format("- undefined %s -", getUndefinedLabel(type));
337
        }
338

    
339
        //in
340
        result = inSeparator +  result;
341

    
342
        //section title
343
        String title = CdmUtils.getPreferredNonEmptyString(
344
                reference.getTitle(), reference.getAbbrevTitle(), isAbbrev, trim);
345
        if (title.length() > 0){
346
            result = title + blank + result;
347
        }
348

    
349
        //section author
350
        TeamOrPersonBase<?> thisRefTeam = reference.getAuthorship();
351
        String thisRefAuthor = "";
352
        if (thisRefTeam != null){
353
            thisRefAuthor = CdmUtils.getPreferredNonEmptyString(thisRefTeam.getTitleCache(),
354
                    thisRefTeam.getNomenclaturalTitle(), isAbbrev, trim);
355
        }
356
        result = CdmUtils.concat(afterSectionAuthor, thisRefAuthor, result);
357

    
358
        //date
359
        if (reference.getDatePublished() != null && ! reference.getDatePublished().isEmpty()){
360
            String thisRefDate = reference.getDatePublished().toString();
361
            if (hasInRef && reference.getInBook().getDatePublished() != null){
362
                VerbatimTimePeriod inRefDate = reference.getInReference().getDatePublished();
363
                String inRefDateString = inRefDate.getYear();
364
                if (isNotBlank(inRefDateString)){
365
                    int pos = StringUtils.lastIndexOf(result, inRefDateString);
366
                    if (pos > -1 ){
367
                        result = result.substring(0, pos) + thisRefDate + result.substring(pos + inRefDateString.length());
368
                    }else{
369
                        logger.warn("InRefDateString (" + inRefDateString + ") could not be found in result (" + result +")");
370
                    }
371
                }else{
372
                    //avoid duplicate dots ('..')
373
                    String bYearSeparator = result.substring(result.length() -1).equals(beforeYear.substring(0, 1)) ? beforeYear.substring(1) : beforeYear;
374
                    result = result + bYearSeparator + thisRefDate + afterYear;
375
                }
376
            }else{
377
                result = result + beforeYear + thisRefDate + afterYear;
378
            }
379
        }
380
        return result;
381
    }
382

    
383
    private String titleCacheJournal(Reference reference, boolean isAbbrev) {
384
        String result;
385
        //copied from Journal
386

    
387
        //title
388
        result = CdmUtils.getPreferredNonEmptyString(reference.getTitle(),
389
                reference.getAbbrevTitle(), isAbbrev, trim);
390

    
391
//          //delete .
392
//          while (result.endsWith(".")){
393
//              result = result.substring(0, result.length()-1);
394
//          }
395
//          result = addYear(result, journal);
396

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

    
408
    private String titleCacheDefaultReference(Reference reference, boolean isAbbrev) {
409
        String result;
410
        //copied from ReferenceDefaultCacheStrategy
411
        result = "";
412
        String titel = CdmUtils.getPreferredNonEmptyString(reference.getTitle(),
413
                reference.getAbbrevTitle(), isAbbrev, trim);
414
        if (isNotBlank(titel)){
415
            result = titel + blank;
416
        }
417
        //delete .
418
        while (result.endsWith(".")){
419
            result = result.substring(0, result.length()-1);
420
        }
421

    
422
        result = addYearReferenceDefault(result, reference);
423
        TeamOrPersonBase<?> team = reference.getAuthorship();
424
        if (team != null){
425
            String author = CdmUtils.getPreferredNonEmptyString(team.getTitleCache(),
426
                    team.getNomenclaturalTitle(), isAbbrev, trim);
427
            if (isNotBlank(author)){
428
                result = author + afterAuthor + result;
429
            }
430
        }
431
        return result;
432
    }
433

    
434
// ******************************* HELPER *****************************************/
435

    
436
    @Override
437
    public String getBeforeMicroReference(){
438
        return beforeMicroReference;
439
    }
440

    
441
    private String addYear(String string, Reference nomRef, boolean useFullDatePublished){
442
        String result;
443
        if (string == null){
444
            return null;
445
        }
446
        String year = useFullDatePublished ? nomRef.getDatePublishedString() : nomRef.getYear();
447
        if (isBlank(year)){
448
            result = string + afterYear;
449
        }else{
450
            String concat = isBlank(string)  ? "" : string.endsWith(".")  ? " " : beforeYear;
451
            result = string + concat + year + afterYear;
452
        }
453
        return result;
454
    }
455

    
456
    private String getTitleWithoutYearAndAuthor(Reference ref, boolean isAbbrev){
457
        return TitleWithoutYearAndAuthorHelper.getTitleWithoutYearAndAuthor(ref, isAbbrev);
458
    }
459
    private String getTitleWithoutYearAndAuthorGeneric(Reference ref, boolean isAbbrev){
460
        return TitleWithoutYearAndAuthorHelper.getTitleWithoutYearAndAuthorGeneric(ref, isAbbrev);
461
    }
462

    
463
    private Object getUndefinedLabel(ReferenceType type) {
464
        if (type == ReferenceType.BookSection){
465
            return "book";
466
        }else if (type == ReferenceType.Generic){
467
            return "generic reference";
468
        }else if (type == ReferenceType.Section){
469
            return "in reference";
470
        } else {
471
            return type.getMessage();
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 InRefDefaultCacheStrategyBase} and in case of type {@link ReferenceType#Generic}
478
     * if it really has an inreference (reference.getInreference() != null).
479
     * @param reference
480
     */
481
    private boolean isRealInRef(Reference reference) {
482
        ReferenceType type = (reference.getType());
483
        if (type == null){
484
            return false;
485
        }else if (type == ReferenceType.BookSection || type == ReferenceType.Section){
486
            return true;
487
        }else if (type == ReferenceType.Generic){
488
            return reference.getInReference() != null;
489
        }else{
490
            return false;
491
        }
492
    }
493

    
494
    /**
495
     * Returns <code>true</code> if the type of the reference originally corresponded to a cache strategy
496
     * which inherited from {@link NomRefDefaultCacheStrategyBase}.
497
     * @param type
498
     */
499
    protected static boolean isNomRef(ReferenceType type){
500
        switch (type){
501
            case Article:
502
            case Book:
503
            case BookSection:
504
            case CdDvd:
505
            case Generic:
506
            case Section:
507
            case Thesis:
508
            case WebPage:
509
                return true;
510

    
511
            case Journal:
512
            default:
513
                return false;
514
        }
515
    }
516

    
517
    /**
518
     * Returns year information as originally computed by {@link ReferenceDefaultCacheStrategy}.
519
     */
520
    private String addYearReferenceDefault(String string, Reference ref){
521
        String result;
522
        if (string == null){
523
            return null;
524
        }
525
        String year = CdmUtils.Nz(ref.getYear());
526
        if ("".equals(year)){
527
            result = string + afterYear;
528
        }else{
529
            result = string.trim() + beforeYear + year + afterYear;
530
        }
531
        return result;
532
    }
533

    
534
// ********************* Nomenclatural title ***************************************/
535

    
536
    @Override
537
    public String getNomenclaturalCitation(Reference reference, String microReference) {
538
        if (reference.isProtectedAbbrevTitleCache()){
539
            String cache = reference.getAbbrevTitleCache();
540
            return handleDetailAndYearForProtected(reference, cache, microReference);
541
        }
542

    
543
        String result = getTokenizedNomenclaturalTitel(reference);
544
        //if no data is available and only titleCache is protected take the protected title
545
        //this is to avoid empty cache if someone forgets to set also the abbrevTitleCache
546
        //we need to think about handling protected not separate for abbrevTitleCache  and titleCache
547
        if (result.equals(INomenclaturalReference.MICRO_REFERENCE_TOKEN) && reference.isProtectedTitleCache() ){
548
            String cache = reference.getTitleCache();
549
            return handleDetailAndYearForProtected(reference, cache, microReference);
550
        }
551

    
552
        microReference = Nz(microReference);
553
        if (isNotBlank(microReference)){
554
            microReference = getBeforeMicroReference() + microReference;
555
            if (microReference.endsWith(".")  && result.contains(INomenclaturalReference.MICRO_REFERENCE_TOKEN + ".") ){
556
                microReference = microReference.substring(0, microReference.length() - 1);
557
            }
558
        }
559
        result = replaceMicroRefToken(microReference, result);
560
        if (result.startsWith(". ")){  //only year available, remove '. '
561
            result = result.substring(2);
562
        }
563
        return result;
564
    }
565

    
566
    private String handleDetailAndYearForProtected(Reference nomenclaturalReference, String cache, String microReference) {
567
        String microRef = isNotBlank(microReference) ? getBeforeMicroReference() + microReference : "";
568
        if (cache == null){
569
            logger.warn("Cache is null. This should never be the case.");
570
            cache = "";
571
        }
572
        String  result = cache + (cache.contains(microRef) ? "" : microRef);
573

    
574
        String date = nomenclaturalReference.getDatePublishedString();
575
        if (isNotBlank(date) && ! result.contains(date)){
576
            result = result + beforeYear + date;
577
        }
578
        return result;
579
    }
580

    
581
    /**
582
     * Returns the nomenclatural title with micro reference represented as token
583
     * which can later be replaced by the real data.
584
     *
585
     * @see INomenclaturalReference#MICRO_REFERENCE_TOKEN
586
     */
587
    private String getTokenizedNomenclaturalTitel(Reference ref) {
588
        if (isRealInRef(ref)){
589
            return getTokenizedNomenclaturalTitelInRef(ref);
590
        }else{
591
            String result = getTitleWithoutYearAndAuthor(ref, true);
592
            result += INomenclaturalReference.MICRO_REFERENCE_TOKEN;
593
            result = addYear(result, ref, true);
594
            return result;
595
        }
596
    }
597

    
598
    private String getTokenizedNomenclaturalTitelInRef(Reference thisRef) {
599
        if (thisRef == null){
600
            return null;
601
        }
602

    
603
        Reference inRef = CdmBase.deproxy(thisRef.getInReference(), Reference.class);
604
        if (inRef != null && inRef.getInReference() != null && thisRef.getType() == ReferenceType.Section){
605
            //this is a reference of type Section which has a in-in-Ref
606
            //TODO maybe we do not need to restrict to type=Section only
607
            return this.getTokenizedNomenclaturalTitelInInRef(thisRef);
608
        }
609

    
610
        String result;
611
        //use generics's publication date if it exists
612
        if (inRef == null ||  (thisRef.hasDatePublished() ) ){
613
            result =  inRef == null ? "" : getTitleWithoutYearAndAuthorGeneric(inRef, true);
614
            //added //TODO unify with non-inRef references formatting
615

    
616
            if (isNotBlank(thisRef.getVolume())){
617
                result = result + " " + thisRef.getVolume();
618
            }
619
            //TODO series / edition
620

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

    
633
        result = getInRefAuthorPart(thisRef.getInReference(), afterInRefAuthor) + result;
634
        result = "in " +  result;
635
        return result;
636
    }
637

    
638
    /**
639
     * For handling in-in-Ref case.
640
     * Must only be called if a reference has inRef and inInRef
641
     * @param section
642
     * @return
643
     */
644
    private String getTokenizedNomenclaturalTitelInInRef(Reference ref) {
645
        String result;
646

    
647
        Reference inRef = CdmBase.deproxy(ref.getInReference(), Reference.class);
648
        Reference inInRef = CdmBase.deproxy(inRef.getInReference(), Reference.class);
649

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

    
665
        Reference dataReference = (ref.hasDatePublished() ? ref : inRef.hasDatePublished() ? inRef : inInRef);
666

    
667
        result = addYear(result, dataReference, true);
668

    
669
        result = getInRefAuthorPart(inInRef, afterInRefAuthor) + result;
670
        if (! result.startsWith("in ")){
671
            result = "in " +  result;
672
        }
673
        return result;
674
    }
675

    
676
    private String getInRefAuthorPart(Reference book, String seperator){
677
        if (book == null){
678
            return "";
679
        }
680
        TeamOrPersonBase<?> team = book.getAuthorship();
681
        String result = Nz( team == null ? "" : team.getNomenclaturalTitle());
682
        if (! result.trim().equals("")){
683
            result = result + seperator;
684
        }
685
        return result;
686
    }
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
   public static String putAuthorToEndOfString(String referenceTitleCache, String authorTitleCache) {
710
       if(authorTitleCache != null){
711
           referenceTitleCache = referenceTitleCache.replace(authorTitleCache + ", ", "");
712
           referenceTitleCache += " - " + authorTitleCache;
713
       }
714
       return referenceTitleCache;
715
   }
716
}
(1-1/4)