Project

General

Profile

Download (24.7 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

    
16
import eu.etaxonomy.cdm.common.CdmUtils;
17
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
18
import eu.etaxonomy.cdm.model.common.CdmBase;
19
import eu.etaxonomy.cdm.model.common.TimePeriod;
20
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
21
import eu.etaxonomy.cdm.model.reference.Reference;
22
import eu.etaxonomy.cdm.model.reference.ReferenceType;
23
import eu.etaxonomy.cdm.strategy.StrategyBase;
24

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

    
51
    private static final Logger logger = Logger.getLogger(DefaultReferenceCacheStrategy.class);
52

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

    
55
    //article
56
    public static final String UNDEFINED_JOURNAL = "- undefined journal -";
57
    private static final String afterAuthor = ", ";
58

    
59
    //book
60

    
61

    
62
    //(book?) section
63
    private String afterSectionAuthor = " - ";
64

    
65
    //in reference
66
    private String inSeparator = "in ";
67
    private static final String afterInRefAuthor = ", ";
68

    
69
    //common
70
    private static final String blank = " ";
71
    private static final String beforeYear = ". ";
72
    private static final String beforeMicroReference = ": ";
73
    private static final String afterYear = "";
74

    
75

    
76
    private static final boolean trim = true;
77

    
78
// ************************ FACTORY ****************************/
79

    
80
    /**
81
     * Factory method
82
     * @return
83
     */
84
    public static DefaultReferenceCacheStrategy NewInstance(){
85
        return new DefaultReferenceCacheStrategy();
86
    }
87

    
88

    
89
    @Override
90
    protected UUID getUuid() {
91
        return uuid;
92
    }
93

    
94
// ******************************* Main methods ******************************/
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 = addYear(result, reference, false);
115
            TeamOrPersonBase<?> team = reference.getAuthorship();
116

    
117
            if (type == ReferenceType.Article){
118
                result = CdmUtils.concat(" ", reference.getTitle(), result);
119
                if (team != null &&  isNotBlank(team.getTitleCache())){
120
                    String authorSeparator = isNotBlank(reference.getTitle())? afterAuthor : " ";
121
                    result = team.getTitleCache() + authorSeparator + result;
122
                }
123
            }else{  //if Book, CdDvd, flat Generic, Thesis, WebPage
124
                if (team != null){
125
                    String teamTitle = CdmUtils.getPreferredNonEmptyString(team.getTitleCache(),
126
                            team.getNomenclaturalTitle(), isNotAbbrev, trim);
127
                    if (teamTitle.length() > 0 ){
128
                        String concat = isNotBlank(result) ? afterAuthor : "";
129
                        result = teamTitle + concat + result;
130
                    }
131
                }
132
            }
133
        }else if (type == ReferenceType.Journal){
134
            result = titleCacheJournal(reference, isNotAbbrev);
135
        }else{
136
            result = titleCacheDefaultReference(reference, isNotAbbrev);
137
        }
138
        return result;
139
    }
140

    
141

    
142
    @Override
143
    public String getFullAbbrevTitleString(Reference reference) {
144
        if (reference == null){
145
            return null;
146
        }
147
        String result;
148
        ReferenceType type = reference.getType();
149
        boolean isAbbrev = true;
150

    
151
        if (reference.isProtectedAbbrevTitleCache()){
152
            return reference.getAbbrevTitleCache();
153
        }
154

    
155
        if (type == ReferenceType.Article){
156
            result =  getTitleWithoutYearAndAuthor(reference, isAbbrev);
157
            boolean useFullDatePublished = false;
158
            result = addYear(result, reference, useFullDatePublished);
159
            TeamOrPersonBase<?> team = reference.getAuthorship();
160
            String articleTitle = CdmUtils.getPreferredNonEmptyString(reference.getTitle(),
161
                    reference.getAbbrevTitle(), isAbbrev, trim);
162
            result = CdmUtils.concat(" ", articleTitle, result);  //Article should maybe left out for nomenclatural references (?)
163
            if (team != null &&  isNotBlank(team.getNomenclaturalTitle())){
164
                String authorSeparator = isNotBlank(articleTitle) ? afterAuthor : " ";
165
                result = team.getNomenclaturalTitle() + authorSeparator + result;
166
            }
167
        }else if (isRealInRef(reference)){
168
            result = titleCacheRealInRef(reference, isAbbrev);
169
        }else if (isNomRef(type)){
170
            //FIXME same as titleCache => try to merge, but note article case
171
            result =  getTitleWithoutYearAndAuthor(reference, isAbbrev);
172
            boolean useFullDatePublished = false;
173
            result = addYear(result, reference, useFullDatePublished);
174
            TeamOrPersonBase<?> team = reference.getAuthorship();
175

    
176
            if (team != null){
177
                String teamTitle = CdmUtils.getPreferredNonEmptyString(team.getTitleCache(),
178
                        team.getNomenclaturalTitle(), isAbbrev, trim);
179
                if (teamTitle.length() > 0 ){
180
                    String concat = isNotBlank(result) ? afterAuthor : "";
181
                    result = teamTitle + concat + result;
182
                }
183
            }
184
        }else if(type == ReferenceType.Journal){
185
            result = titleCacheJournal(reference, isAbbrev);
186
        }else{
187
            result = titleCacheDefaultReference(reference, isAbbrev);
188
        }
189

    
190
        return result;
191
    }
192

    
193
    @Override
194
    public String getCitation(Reference reference) {
195
        // mostly copied from nomRefCacheStrat, refCache, journalCache
196

    
197
        if (reference == null){
198
            return null;
199
        }
200
        StringBuilder stringBuilder = new StringBuilder();
201
        TeamOrPersonBase<?> team = reference.getAuthorship();
202

    
203
        String nextConcat = "";
204

    
205
        if (team != null &&  isNotBlank(team.getTitleCache())){
206
            stringBuilder.append(team.getTitleCache() );
207
            //here is the difference between nomRef and others
208
            if (isNomRef(reference.getType())) {
209
                nextConcat = afterAuthor;
210
            }else{
211
                //FIXME check if this really makes sense
212
                stringBuilder.append(afterAuthor);
213
                nextConcat = beforeYear;
214
            }
215
        }
216

    
217
        String year = reference.getYear();
218
        if (StringUtils.isNotBlank(year)){
219
            stringBuilder.append(nextConcat + year);
220
        }
221

    
222
        return stringBuilder.toString();
223
    }
224

    
225
    @Override
226
    public String getNomenclaturalCache(Reference reference) {
227
        return this.getNomenclaturalCitation(reference, null);
228
    }
229

    
230
// ************************ TITLE CACHE SUBS ********************************************/
231

    
232
    /**
233
     * @param reference
234
     * @param type
235
     * @param inRef
236
     * @param hasInRef
237
     * @return
238
     */
239
    private String titleCacheRealInRef(Reference reference, boolean isAbbrev) {
240
        ReferenceType type = reference.getType();
241
        Reference inRef = reference.getInReference();
242
        boolean hasInRef = (inRef != null);
243

    
244
        String result;
245
        //copy from InRefDefaultCacheStrategyBase
246
        if (inRef != null){
247
            result = CdmUtils.getPreferredNonEmptyString(inRef.getTitleCache(),
248
                    inRef.getAbbrevTitleCache(), isAbbrev, trim)  ;
249
        }else{
250
            result = String.format("- undefined %s -", getUndefinedLabel(type));
251
        }
252

    
253
        //in
254
        result = inSeparator +  result;
255

    
256
        //section title
257
        String title = CdmUtils.getPreferredNonEmptyString(
258
                reference.getTitle(), reference.getAbbrevTitle(), isAbbrev, trim);
259
        if (title.length() > 0){
260
            result = title + blank + result;
261
        }
262

    
263
        //section author
264
        TeamOrPersonBase<?> thisRefTeam = reference.getAuthorship();
265
        String thisRefAuthor = "";
266
        if (thisRefTeam != null){
267
            thisRefAuthor = CdmUtils.getPreferredNonEmptyString(thisRefTeam.getTitleCache(),
268
                    thisRefTeam.getNomenclaturalTitle(), isAbbrev, trim);
269
        }
270
        result = CdmUtils.concat(afterSectionAuthor, thisRefAuthor, result);
271

    
272
        //date
273
        if (reference.getDatePublished() != null && ! reference.getDatePublished().isEmpty()){
274
            String thisRefDate = reference.getDatePublished().toString();
275
            if (hasInRef && reference.getInBook().getDatePublished() != null){
276
                TimePeriod inRefDate = reference.getInReference().getDatePublished();
277
                String inRefDateString = inRefDate.getYear();
278
                if (isNotBlank(inRefDateString)){
279
                    int pos = StringUtils.lastIndexOf(result, inRefDateString);
280
                    if (pos > -1 ){
281
                        result = result.substring(0, pos) + thisRefDate + result.substring(pos + inRefDateString.length());
282
                    }else{
283
                        logger.warn("InRefDateString (" + inRefDateString + ") could not be found in result (" + result +")");
284
                    }
285
                }else{
286
                    //avoid duplicate dots ('..')
287
                    String bYearSeparator = result.substring(result.length() -1).equals(beforeYear.substring(0, 1)) ? beforeYear.substring(1) : beforeYear;
288
                    result = result + bYearSeparator + thisRefDate + afterYear;
289
                }
290
            }else{
291
                result = result + beforeYear + thisRefDate + afterYear;
292
            }
293
        }
294
        return result;
295
    }
296

    
297

    
298
    /**
299
     * @param reference
300
     * @return
301
     */
302
    private String titleCacheJournal(Reference reference, boolean isAbbrev) {
303
        String result;
304
        //copied from Journal
305

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

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

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

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

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

    
358
// ******************************* HELPER *****************************************/
359
    @Override
360
    public String getBeforeMicroReference(){
361
        return beforeMicroReference;
362
    }
363

    
364
    private String addYear(String string, Reference nomRef, boolean useFullDatePublished){
365
        String result;
366
        if (string == null){
367
            return null;
368
        }
369
        String year = useFullDatePublished ? nomRef.getDatePublishedString() : nomRef.getYear();
370
        if (isBlank(year)){
371
            result = string + afterYear;
372
        }else{
373
            String concat = isBlank(string)  ? "" : string.endsWith(".")  ? " " : beforeYear;
374
            result = string + concat + year + afterYear;
375
        }
376
        return result;
377
    }
378

    
379
    private String getTitleWithoutYearAndAuthor(Reference ref, boolean isAbbrev){
380
        return TitleWithoutYearAndAuthorHelper.getTitleWithoutYearAndAuthor(ref, isAbbrev);
381
    }
382
    private String getTitleWithoutYearAndAuthorGeneric(Reference ref, boolean isAbbrev){
383
        return TitleWithoutYearAndAuthorHelper.getTitleWithoutYearAndAuthorGeneric(ref, isAbbrev);
384
    }
385

    
386
    /**
387
     * @param type
388
     * @return
389
     */
390
    private Object getUndefinedLabel(ReferenceType type) {
391
        if (type == ReferenceType.BookSection){
392
            return "book";
393
        }else if (type == ReferenceType.Generic){
394
            return "generic reference";
395
        }else if (type == ReferenceType.Section){
396
            return "in reference";
397
        } else {
398
            return type.getMessage();
399
        }
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
    private 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
     */
427
    protected static boolean isNomRef(ReferenceType type){
428
        switch (type){
429
            case Article:
430
            case Book:
431
            case BookSection:
432
            case CdDvd:
433
            case Generic:
434
            case Section:
435
            case Thesis:
436
            case WebPage:
437
                return true;
438

    
439
            case Journal:
440
            default:
441
                return false;
442
        }
443
    }
444

    
445
    /**
446
     * Returns year information as originally computed by {@link ReferenceDefaultCacheStrategy}
447
     * @param string
448
     * @param ref
449
     * @return
450
     */
451
    private String addYearReferenceDefault(String string, Reference ref){
452
        String result;
453
        if (string == null){
454
            return null;
455
        }
456
        String year = CdmUtils.Nz(ref.getYear());
457
        if ("".equals(year)){
458
            result = string + afterYear;
459
        }else{
460
            result = string + beforeYear + year + afterYear;
461
        }
462
        return result;
463
    }
464

    
465

    
466
// ********************* Nomenclatural title ***************************************/
467

    
468
    @Override
469
    public String getNomenclaturalCitation(Reference reference, String microReference) {
470
        if (reference.isProtectedAbbrevTitleCache()){
471
            String cache = reference.getAbbrevTitleCache();
472
            return handleDetailAndYearForPreliminary(reference, cache, microReference);
473

    
474
        }
475
        String result = getTokenizedNomenclaturalTitel(reference);
476
        //if no data is available and only titleCache is protected take the protected title
477
        //this is to avoid empty cache if someone forgets to set also the abbrevTitleCache
478
        //we need to think about handling protected not separate for abbrevTitleCache  and titleCache
479
        if (result.equals(INomenclaturalReference.MICRO_REFERENCE_TOKEN) && reference.isProtectedTitleCache() ){
480
            String cache = reference.getTitleCache();
481
            return handleDetailAndYearForPreliminary(reference, cache, microReference);
482
        }
483

    
484
        microReference = Nz(microReference);
485
        if (StringUtils.isNotBlank(microReference)){
486
            microReference = getBeforeMicroReference() + microReference;
487
            if (microReference.endsWith(".")  && result.contains(INomenclaturalReference.MICRO_REFERENCE_TOKEN + ".") ){
488
                microReference = microReference.substring(0, microReference.length() - 1);
489
            }
490
        }
491
        result = replaceMicroRefToken(microReference, result);
492
        if (result.startsWith(". ")){  //only year available, remove '. '
493
            result = result.substring(2);
494
        }
495
        return result;
496
    }
497

    
498
    /**
499
     * @param nomenclaturalReference
500
     * @param microRef
501
     * @return
502
     */
503
    private String handleDetailAndYearForPreliminary(Reference nomenclaturalReference, String cache, String microReference) {
504
        String microRef = isNotBlank(microReference) ? getBeforeMicroReference() + microReference : "";
505
        if (cache == null){
506
            logger.warn("Cache is null. This should never be the case.");
507
            cache = "";
508
        }
509
        String  result = cache + (cache.contains(microRef) ? "" : microRef);
510

    
511
        String date = nomenclaturalReference.getDatePublishedString();
512
        if (isNotBlank(date) && ! result.contains(date)){
513
            result = result + beforeYear + date;
514
        }
515
        return result;
516
    }
517

    
518
    /**
519
     * Returns the nomenclatural title with micro reference represented as token
520
     * which can later be replaced by the real data.
521
     *
522
     * @see INomenclaturalReference#MICRO_REFERENCE_TOKEN
523
     *
524
     * @param ref The reference
525
     * @return
526
     */
527
    private String getTokenizedNomenclaturalTitel(Reference ref) {
528
        if (isRealInRef(ref)){
529
            return getTokenizedNomenclaturalTitelInRef(ref);
530
        }else{
531
            String result = getTitleWithoutYearAndAuthor(ref, true);
532
            result += INomenclaturalReference.MICRO_REFERENCE_TOKEN;
533
            result = addYear(result, ref, true);
534
            return result;
535
        }
536
    }
537

    
538
    private String getTokenizedNomenclaturalTitelInRef(Reference thisRef) {
539
        if (thisRef == null){
540
            return null;
541
        }
542

    
543
        Reference inRef = CdmBase.deproxy(thisRef.getInReference(), Reference.class);
544
        if (inRef != null && inRef.getInReference() != null && thisRef.getType() == ReferenceType.Section){
545
            //this is a reference of type Section which has a in-in-Ref
546
            //TODO maybe we do not need to restrict to type=Section only
547
            return this.getTokenizedNomenclaturalTitelInInRef(thisRef);
548
        }
549

    
550
        String result;
551
        //use generics's publication date if it exists
552
        if (inRef == null ||  (thisRef.hasDatePublished() ) ){
553
            getTitleWithoutYearAndAuthorGeneric(inRef, true);
554
            result =  inRef == null ? "" : getTitleWithoutYearAndAuthorGeneric(inRef, true);
555
            //added //TODO unify with non-inRef references formatting
556

    
557
            if (isNotBlank(thisRef.getVolume())){
558
                result = result + " " + thisRef.getVolume();
559
            }
560
            //TODO series / edition
561

    
562
            //end added
563
            result += INomenclaturalReference.MICRO_REFERENCE_TOKEN;
564
            result = addYear(result, thisRef, true);
565
        }else{
566
            //else use inRefs's publication date
567
            result = inRef.getNomenclaturalCitation(INomenclaturalReference.MICRO_REFERENCE_TOKEN);
568
            if (result != null){
569
                result = result.replace(beforeMicroReference +  INomenclaturalReference.MICRO_REFERENCE_TOKEN, INomenclaturalReference.MICRO_REFERENCE_TOKEN);
570
            }
571
        }
572
        //FIXME: vol. etc., http://dev.e-taxonomy.eu/trac/ticket/2862
573

    
574
        result = getInRefAuthorPart(thisRef.getInReference(), afterInRefAuthor) + result;
575
        result = "in " +  result;
576
        return result;
577
    }
578

    
579
    /**
580
     * For handling in-in-Ref case.
581
     * Must only be called if a reference has inRef and inInRef
582
     * @param section
583
     * @return
584
     */
585
    private String getTokenizedNomenclaturalTitelInInRef(Reference ref) {
586
        String result;
587

    
588
        Reference inRef = CdmBase.deproxy(ref.getInReference(), Reference.class);
589
        Reference inInRef = CdmBase.deproxy(inRef.getInReference(), Reference.class);
590

    
591
        if (! isNomRef(inInRef.getType())){
592
            if (! isNomRef(inRef.getType())){
593
                logger.warn("Neither inReference nor inInReference is a "
594
                        + " nomenclatural reference. This is not correct or not handled yet."
595
                        + " Generic titleWithoutYearAndAuthor used instead");
596
                result = getTitleWithoutYearAndAuthorGeneric(inInRef, true);
597
                //FIXME: vol. etc., http://dev.e-taxonomy.eu/trac/ticket/2862  (comment taken from super.getTokenizedNomenclaturalTitel())
598
            }else{
599
                result = getTitleWithoutYearAndAuthor(inRef, true);
600
            }
601
        }else{
602
            result = getTitleWithoutYearAndAuthor(inInRef, true);
603
        }
604
        result += INomenclaturalReference.MICRO_REFERENCE_TOKEN;
605

    
606
        Reference dataReference = (ref.hasDatePublished() ? ref : inRef.hasDatePublished() ? inRef : inInRef);
607

    
608
        result = addYear(result, dataReference, true);
609

    
610
        result = getInRefAuthorPart(inInRef, afterInRefAuthor) + result;
611
        if (! result.startsWith("in ")){
612
            result = "in " +  result;
613
        }
614
        return result;
615
    }
616

    
617
    private String getInRefAuthorPart(Reference book, String seperator){
618
        if (book == null){
619
            return "";
620
        }
621
        TeamOrPersonBase<?> team = book.getAuthorship();
622
        String result = Nz( team == null ? "" : team.getNomenclaturalTitle());
623
        if (! result.trim().equals("")){
624
            result = result + seperator;
625
        }
626
        return result;
627
    }
628

    
629

    
630
    /**
631
     * @param microReference
632
     * @param result
633
     * @return
634
     */
635
    private String replaceMicroRefToken(String microReference, String string) {
636
        int index = string.indexOf(INomenclaturalReference.MICRO_REFERENCE_TOKEN);
637

    
638
        if (index > -1){
639
            String before = string.substring(0, index);
640
            String after = string.substring(index + INomenclaturalReference.MICRO_REFERENCE_TOKEN.length() );
641
            String localMicroReference = microReference.trim();   //needed ?
642
            if (after.length() > 0){
643
                if (  ("".equals(localMicroReference) && before.endsWith(after.substring(0,1)) || localMicroReference.endsWith(after.substring(0,1)))){
644
                    after = after.substring(1);
645
                }
646
            }
647
            String result = before + localMicroReference + after;
648
            return result;
649
        }else{
650
            return string;
651
        }
652
    }
653

    
654
// *************************** EXTERNAL USE *******************************************/
655
   /**
656
    *
657
    * @param referenceTitleCache
658
    * @param authorTitleCache
659
    * @return
660
    */
661
   public static String putAuthorToEndOfString(String referenceTitleCache, String authorTitleCache) {
662
       if(authorTitleCache != null){
663
           referenceTitleCache = referenceTitleCache.replace(authorTitleCache + ", ", "");
664
           referenceTitleCache += " - " + authorTitleCache;
665
       }
666
       return referenceTitleCache;
667
   }
668
}
(1-1/4)