Project

General

Profile

Download (24.8 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2016 EDIT
4
* European Distributed Institute of Taxonomy
5
* http://www.e-taxonomy.eu
6
*
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10
package eu.etaxonomy.cdm.strategy.cache.reference;
11

    
12
import java.util.UUID;
13

    
14
import org.apache.commons.lang.StringUtils;
15
import org.apache.log4j.Logger;
16

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

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

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

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

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

    
60
    //book
61

    
62

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

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

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

    
76

    
77
    private static final boolean trim = true;
78

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

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

    
89

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

    
95
// ******************************* Main methods ******************************/
96

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

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

    
110
        if (isRealInRef(reference)){
111
            result = titleCacheRealInRef(reference, isNotAbbrev);
112
        }else if(isNomRef(type)){
113
            //all Non-InRef NomRefs
114
            result =  getTitleWithoutYearAndAuthor(reference, isNotAbbrev);
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
        return result;
140
    }
141

    
142

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

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

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

    
187
        return result;
188
    }
189

    
190
    @Override
191
    public String getCitation(Reference reference) {
192
        // mostly copied from nomRefCacheStrat, refCache, journalCache
193

    
194
        if (reference == null){
195
            return null;
196
        }
197
        StringBuilder stringBuilder = new StringBuilder();
198
        TeamOrPersonBase<?> team = reference.getAuthorship();
199

    
200
        String nextConcat = "";
201

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

    
214
        String year = reference.getYear();
215
        if (StringUtils.isNotBlank(year)){
216
            stringBuilder.append(nextConcat + year);
217
        }
218

    
219
        return stringBuilder.toString();
220
    }
221

    
222
    @Override
223
    public String getNomenclaturalCache(Reference reference) {
224
        //TODO maybe not needed as getNomenclaturalCitation also handles protected
225
        if (reference.isProtectedAbbrevTitleCache()){
226
            return reference.getAbbrevTitleCache();
227
        }
228

    
229
        return this.getNomenclaturalCitation(reference, null);
230
    }
231

    
232
// ************************ TITLE CACHE SUBS ********************************************/
233

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

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

    
255
        //in
256
        result = inSeparator +  result;
257

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

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

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

    
299

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

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

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

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

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

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

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

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

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

    
388
    /**
389
     * @param type
390
     * @return
391
     */
392
    private Object getUndefinedLabel(ReferenceType type) {
393
        if (type == ReferenceType.BookSection){
394
            return "book";
395
        }else if (type == ReferenceType.Generic){
396
            return "generic reference";
397
        }else if (type == ReferenceType.Section){
398
            return "in reference";
399
        } else {
400
            return type.getMessage();
401
        }
402
    }
403

    
404

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

    
424
    /**
425
     * Returns <code>true</code> if the type of the reference originally corresponded to a cache strategy
426
     * which inherited from {@link NomRefDefaultCacheStrategyBase}.
427
     * @param type
428
     */
429
    protected static boolean isNomRef(ReferenceType type){
430
        switch (type){
431
            case Article:
432
            case Book:
433
            case BookSection:
434
            case CdDvd:
435
            case Generic:
436
            case Section:
437
            case Thesis:
438
            case WebPage:
439
                return true;
440

    
441
            case Journal:
442
            default:
443
                return false;
444
        }
445
    }
446

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

    
467

    
468
// ********************* Nomenclatural title ***************************************/
469

    
470
    @Override
471
    public String getNomenclaturalCitation(Reference reference, String microReference) {
472
        if (reference.isProtectedAbbrevTitleCache()){
473
            String cache = reference.getAbbrevTitleCache();
474
            return handleDetailAndYearForProtected(reference, cache, microReference);
475
        }
476

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

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

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

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

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

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

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

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

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

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

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

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

    
590
        Reference inRef = CdmBase.deproxy(ref.getInReference(), Reference.class);
591
        Reference inInRef = CdmBase.deproxy(inRef.getInReference(), Reference.class);
592

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

    
608
        Reference dataReference = (ref.hasDatePublished() ? ref : inRef.hasDatePublished() ? inRef : inInRef);
609

    
610
        result = addYear(result, dataReference, true);
611

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

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

    
631

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

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

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