2 * Copyright (C) 2016 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.strategy
.cache
.reference
;
11 import java
.util
.List
;
12 import java
.util
.UUID
;
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
;
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
;
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.
39 * Generally the cache strategy computes allows 3 formattings:<BR>
41 * 1.) for bibliographic references (stored in {@link Reference#getTitleCache() titleCache}).<BR>
43 * 2.) for nomenclatural references (stored in {@link Reference#getAbbrevTitleCache() abbrevTitleCache}),
44 * but without micro reference (detail).<BR>
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>
49 * 4.) for short citation (e.g. Author 2009) as defined in {@link IReferenceCacheStrategy#getCitation(Reference)}
55 public class DefaultReferenceCacheStrategy
extends StrategyBase
implements INomenclaturalReferenceCacheStrategy
{
56 private static final long serialVersionUID
= 6773742298840407263L;
58 private static final Logger logger
= Logger
.getLogger(DefaultReferenceCacheStrategy
.class);
60 private final static UUID uuid
= UUID
.fromString("63e669ca-c6be-4a8a-b157-e391c22580f9");
63 public static final String UNDEFINED_JOURNAL
= "- undefined journal -";
64 private static final String afterAuthor
= ", ";
70 private String afterSectionAuthor
= " - ";
73 private String inSeparator
= "in ";
74 private static final String afterInRefAuthor
= ", ";
77 private static final String blank
= " ";
78 private static final String beforeYear
= ". ";
79 private static final String beforeMicroReference
= ": ";
80 private static final String afterYear
= "";
83 private static final boolean trim
= true;
85 // ************************ FACTORY ****************************/
91 public static DefaultReferenceCacheStrategy
NewInstance(){
92 return new DefaultReferenceCacheStrategy();
97 protected UUID
getUuid() {
101 // ******************************* Main methods ******************************/
104 public String
getTitleCache(Reference reference
) {
105 if (reference
== null){
108 if (reference
.isProtectedTitleCache()){
109 return reference
.getTitleCache();
111 boolean isNotAbbrev
= false;
114 ReferenceType type
= reference
.getType();
116 if (isRealInRef(reference
)){
117 result
= titleCacheRealInRef(reference
, isNotAbbrev
);
118 }else if(isNomRef(type
)){
119 //all Non-InRef NomRefs
120 result
= getTitleWithoutYearAndAuthor(reference
, isNotAbbrev
);
121 result
= addPages(result
, reference
);
122 result
= addYear(result
, reference
, false);
123 TeamOrPersonBase
<?
> team
= reference
.getAuthorship();
125 if (type
== ReferenceType
.Article
){
126 result
= CdmUtils
.concat(" ", reference
.getTitle(), result
);
127 if (team
!= null && isNotBlank(team
.getTitleCache())){
128 String authorSeparator
= isNotBlank(reference
.getTitle())? afterAuthor
: " ";
129 result
= team
.getTitleCache() + authorSeparator
+ result
;
131 }else{ //if Book, CdDvd, flat Generic, Thesis, WebPage
133 String teamTitle
= CdmUtils
.getPreferredNonEmptyString(team
.getTitleCache(),
134 team
.getNomenclaturalTitle(), isNotAbbrev
, trim
);
135 if (teamTitle
.length() > 0 ){
136 String concat
= isNotBlank(result
) ? afterAuthor
: "";
137 result
= teamTitle
+ concat
+ result
;
141 }else if (type
== ReferenceType
.Journal
){
142 result
= titleCacheJournal(reference
, isNotAbbrev
);
144 result
= titleCacheDefaultReference(reference
, isNotAbbrev
);
146 if (reference
.getType() == ReferenceType
.WebPage
&& reference
.getUri() != null && !result
.contains(reference
.getUri().toString())){
147 //might become UTF8.EN_DASH in future
148 result
= CdmUtils
.concat(" - ", result
, reference
.getUri().toString());
150 if(reference
.getAccessed() != null){
151 //TODO still a bit preliminary, also brackets may change in future
152 result
= result
+ " [accessed " + getAccessedString(reference
.getAccessed()) +"]";
162 private String
getAccessedString(DateTime accessed
) {
163 DateTimeFormatter formatter
= DateTimeFormat
.forPattern("yyyy-MM-dd HH:mm");
164 String result
= formatter
.print(accessed
);
165 if (result
.endsWith(" 00:00")){
166 result
= result
.replace(" 00:00", "");
171 private String
addPages(String result
, Reference reference
) {
173 if (isNotBlank(reference
.getPages())){
174 //Removing trailing added just in case, maybe not necessary
175 result
= RemoveTrailingDot(Nz(result
)).trim() + ": " + reference
.getPages();
180 private static String
RemoveTrailingDot(String str
) {
181 if (str
!= null && str
.endsWith(".")){
182 str
= str
.substring(0, str
.length()-1);
189 public String
getFullAbbrevTitleString(Reference reference
) {
190 if (reference
== null){
194 ReferenceType type
= reference
.getType();
195 boolean isAbbrev
= true;
197 if (reference
.isProtectedAbbrevTitleCache()){
198 return reference
.getAbbrevTitleCache();
201 if (type
== ReferenceType
.Article
){
202 result
= getTitleWithoutYearAndAuthor(reference
, isAbbrev
);
203 boolean useFullDatePublished
= false;
204 result
= addYear(result
, reference
, useFullDatePublished
);
205 TeamOrPersonBase
<?
> team
= reference
.getAuthorship();
206 String articleTitle
= CdmUtils
.getPreferredNonEmptyString(reference
.getTitle(),
207 reference
.getAbbrevTitle(), isAbbrev
, trim
);
208 result
= CdmUtils
.concat(" ", articleTitle
, result
); //Article should maybe left out for nomenclatural references (?)
209 if (team
!= null && isNotBlank(team
.getNomenclaturalTitle())){
210 String authorSeparator
= isNotBlank(articleTitle
) ? afterAuthor
: " ";
211 result
= team
.getNomenclaturalTitle() + authorSeparator
+ result
;
213 }else if (isRealInRef(reference
)){
214 result
= titleCacheRealInRef(reference
, isAbbrev
);
215 }else if (isNomRef(type
)){
216 //FIXME same as titleCache => try to merge, but note article case
217 result
= getTitleWithoutYearAndAuthor(reference
, isAbbrev
);
218 boolean useFullDatePublished
= false;
219 result
= addYear(result
, reference
, useFullDatePublished
);
220 TeamOrPersonBase
<?
> team
= reference
.getAuthorship();
223 String teamTitle
= CdmUtils
.getPreferredNonEmptyString(team
.getTitleCache(),
224 team
.getNomenclaturalTitle(), isAbbrev
, trim
);
225 if (teamTitle
.length() > 0 ){
226 String concat
= isNotBlank(result
) ? afterAuthor
: "";
227 result
= teamTitle
+ concat
+ result
;
230 }else if(type
== ReferenceType
.Journal
){
231 result
= titleCacheJournal(reference
, isAbbrev
);
233 result
= titleCacheDefaultReference(reference
, isAbbrev
);
240 public String
getCitation(Reference reference
) {
241 // mostly copied from nomRefCacheStrat, refCache, journalCache
243 if (reference
== null){
246 StringBuilder stringBuilder
= new StringBuilder();
247 TeamOrPersonBase
<?
> team
= reference
.getAuthorship();
249 String nextConcat
= "";
251 if (team
!= null && isNotBlank(team
.getTitleCache())){
252 stringBuilder
.append(team
.getTitleCache() );
253 //here is the difference between nomRef and others
254 if (isNomRef(reference
.getType())) {
255 nextConcat
= afterAuthor
;
257 //FIXME check if this really makes sense
258 stringBuilder
.append(afterAuthor
);
259 nextConcat
= beforeYear
;
263 String year
= reference
.getYear();
264 if (StringUtils
.isNotBlank(year
)){
265 stringBuilder
.append(nextConcat
+ year
);
268 return stringBuilder
.toString();
271 public String
createShortCitation(Reference reference
) {
272 TeamOrPersonBase
<?
> authorship
= reference
.getAuthorship();
273 String shortCitation
= "";
274 if (authorship
== null) {
277 authorship
= HibernateProxyHelper
.deproxy(authorship
);
278 if (authorship
instanceof Person
){
279 shortCitation
= ((Person
)authorship
).getFamilyName();
280 if (StringUtils
.isBlank(shortCitation
) ){
281 shortCitation
= ((Person
)authorship
).getTitleCache();
284 else if (authorship
instanceof Team
){
286 Team authorTeam
= HibernateProxyHelper
.deproxy(authorship
, Team
.class);
289 for (Person teamMember
: authorTeam
.getTeamMembers()){
292 shortCitation
+= " & al.";
295 String concat
= concatString(authorTeam
, authorTeam
.getTeamMembers(), index
, ", ", " & ");
296 if (teamMember
.getFamilyName() != null){
297 shortCitation
+= concat
+ teamMember
.getFamilyName();
299 shortCitation
+= concat
+ teamMember
.getTitleCache();
303 if (StringUtils
.isBlank(shortCitation
)){
304 shortCitation
= authorTeam
.getTitleCache();
308 if (reference
.getDatePublished() != null) {
309 if (!StringUtils
.isBlank(reference
.getDatePublished().getFreeText())){
310 shortCitation
= shortCitation
+ " (" + reference
.getDatePublished().getFreeText() + ")";
311 }else if (!StringUtils
.isBlank(reference
.getYear()) ){
312 shortCitation
= shortCitation
+ " (" + reference
.getYear() + ")";
316 return shortCitation
;
319 private static String
concatString(Team team
, List
<Person
> teamMembers
, int i
, String std_team_concatination
, String final_team_concatination
) {
323 }else if (i
< teamMembers
.size() || ( team
.isHasMoreMembers() && i
== teamMembers
.size())){
324 concat
= std_team_concatination
;
326 concat
= final_team_concatination
;
333 public String
getNomenclaturalCache(Reference reference
) {
334 return this.getNomenclaturalCitation(reference
, null);
337 // ************************ TITLE CACHE SUBS ********************************************/
339 private String
titleCacheRealInRef(Reference reference
, boolean isAbbrev
) {
340 ReferenceType type
= reference
.getType();
341 Reference inRef
= reference
.getInReference();
342 boolean hasInRef
= (inRef
!= null);
345 //copy from InRefDefaultCacheStrategyBase
347 result
= CdmUtils
.getPreferredNonEmptyString(inRef
.getTitleCache(),
348 inRef
.getAbbrevTitleCache(), isAbbrev
, trim
) ;
350 result
= String
.format("- undefined %s -", getUndefinedLabel(type
));
354 result
= inSeparator
+ result
;
357 String title
= CdmUtils
.getPreferredNonEmptyString(
358 reference
.getTitle(), reference
.getAbbrevTitle(), isAbbrev
, trim
);
359 if (title
.length() > 0){
360 result
= title
+ blank
+ result
;
364 TeamOrPersonBase
<?
> thisRefTeam
= reference
.getAuthorship();
365 String thisRefAuthor
= "";
366 if (thisRefTeam
!= null){
367 thisRefAuthor
= CdmUtils
.getPreferredNonEmptyString(thisRefTeam
.getTitleCache(),
368 thisRefTeam
.getNomenclaturalTitle(), isAbbrev
, trim
);
370 result
= CdmUtils
.concat(afterSectionAuthor
, thisRefAuthor
, result
);
373 if (reference
.getDatePublished() != null && ! reference
.getDatePublished().isEmpty()){
374 String thisRefDate
= reference
.getDatePublished().toString();
375 if (hasInRef
&& reference
.getInBook().getDatePublished() != null){
376 VerbatimTimePeriod inRefDate
= reference
.getInReference().getDatePublished();
377 String inRefDateString
= inRefDate
.getYear();
378 if (isNotBlank(inRefDateString
)){
379 int pos
= StringUtils
.lastIndexOf(result
, inRefDateString
);
381 result
= result
.substring(0, pos
) + thisRefDate
+ result
.substring(pos
+ inRefDateString
.length());
383 logger
.warn("InRefDateString (" + inRefDateString
+ ") could not be found in result (" + result
+")");
386 //avoid duplicate dots ('..')
387 String bYearSeparator
= result
.substring(result
.length() -1).equals(beforeYear
.substring(0, 1)) ? beforeYear
.substring(1) : beforeYear
;
388 result
= result
+ bYearSeparator
+ thisRefDate
+ afterYear
;
391 result
= result
+ beforeYear
+ thisRefDate
+ afterYear
;
397 private String
titleCacheJournal(Reference reference
, boolean isAbbrev
) {
399 //copied from Journal
402 result
= CdmUtils
.getPreferredNonEmptyString(reference
.getTitle(),
403 reference
.getAbbrevTitle(), isAbbrev
, trim
);
406 // while (result.endsWith(".")){
407 // result = result.substring(0, result.length()-1);
409 // result = addYear(result, journal);
411 TeamOrPersonBase
<?
> team
= reference
.getAuthorship();
413 String author
= CdmUtils
.getPreferredNonEmptyString(team
.getTitleCache(),
414 team
.getNomenclaturalTitle(), isAbbrev
, trim
);
415 if (StringUtils
.isNotBlank(author
)){
416 result
= author
+ afterAuthor
+ result
;
422 private String
titleCacheDefaultReference(Reference reference
, boolean isAbbrev
) {
424 //copied from ReferenceDefaultCacheStrategy
426 String titel
= CdmUtils
.getPreferredNonEmptyString(reference
.getTitle(),
427 reference
.getAbbrevTitle(), isAbbrev
, trim
);
428 if (isNotBlank(titel
)){
429 result
= titel
+ blank
;
432 while (result
.endsWith(".")){
433 result
= result
.substring(0, result
.length()-1);
436 result
= addYearReferenceDefault(result
, reference
);
437 TeamOrPersonBase
<?
> team
= reference
.getAuthorship();
439 String author
= CdmUtils
.getPreferredNonEmptyString(team
.getTitleCache(),
440 team
.getNomenclaturalTitle(), isAbbrev
, trim
);
441 if (isNotBlank(author
)){
442 result
= author
+ afterAuthor
+ result
;
448 // ******************************* HELPER *****************************************/
450 public String
getBeforeMicroReference(){
451 return beforeMicroReference
;
454 private String
addYear(String string
, Reference nomRef
, boolean useFullDatePublished
){
459 String year
= useFullDatePublished ? nomRef
.getDatePublishedString() : nomRef
.getYear();
461 result
= string
+ afterYear
;
463 String concat
= isBlank(string
) ?
"" : string
.endsWith(".") ?
" " : beforeYear
;
464 result
= string
+ concat
+ year
+ afterYear
;
469 private String
getTitleWithoutYearAndAuthor(Reference ref
, boolean isAbbrev
){
470 return TitleWithoutYearAndAuthorHelper
.getTitleWithoutYearAndAuthor(ref
, isAbbrev
);
472 private String
getTitleWithoutYearAndAuthorGeneric(Reference ref
, boolean isAbbrev
){
473 return TitleWithoutYearAndAuthorHelper
.getTitleWithoutYearAndAuthorGeneric(ref
, isAbbrev
);
476 private Object
getUndefinedLabel(ReferenceType type
) {
477 if (type
== ReferenceType
.BookSection
){
479 }else if (type
== ReferenceType
.Generic
){
480 return "generic reference";
481 }else if (type
== ReferenceType
.Section
){
482 return "in reference";
484 return type
.getMessage();
490 * Returns <code>true</code> if the type of the reference originally corresponded to a cache strategy
491 * which inherited from {@link InRefDefaultCacheStrategyBase} and in case of type {@link ReferenceType#Generic}
492 * if it really has an inreference (reference.getInreference() != null).
495 private boolean isRealInRef(Reference reference
) {
496 ReferenceType type
= (reference
.getType());
499 }else if (type
== ReferenceType
.BookSection
|| type
== ReferenceType
.Section
){
501 }else if (type
== ReferenceType
.Generic
){
502 return reference
.getInReference() != null;
509 * Returns <code>true</code> if the type of the reference originally corresponded to a cache strategy
510 * which inherited from {@link NomRefDefaultCacheStrategyBase}.
513 protected static boolean isNomRef(ReferenceType type
){
532 * Returns year information as originally computed by {@link ReferenceDefaultCacheStrategy}
534 private String
addYearReferenceDefault(String string
, Reference ref
){
539 String year
= CdmUtils
.Nz(ref
.getYear());
540 if ("".equals(year
)){
541 result
= string
+ afterYear
;
543 result
= string
.trim() + beforeYear
+ year
+ afterYear
;
549 // ********************* Nomenclatural title ***************************************/
552 public String
getNomenclaturalCitation(Reference reference
, String microReference
) {
553 if (reference
.isProtectedAbbrevTitleCache()){
554 String cache
= reference
.getAbbrevTitleCache();
555 return handleDetailAndYearForProtected(reference
, cache
, microReference
);
558 String result
= getTokenizedNomenclaturalTitel(reference
);
559 //if no data is available and only titleCache is protected take the protected title
560 //this is to avoid empty cache if someone forgets to set also the abbrevTitleCache
561 //we need to think about handling protected not separate for abbrevTitleCache and titleCache
562 if (result
.equals(INomenclaturalReference
.MICRO_REFERENCE_TOKEN
) && reference
.isProtectedTitleCache() ){
563 String cache
= reference
.getTitleCache();
564 return handleDetailAndYearForProtected(reference
, cache
, microReference
);
567 microReference
= Nz(microReference
);
568 if (StringUtils
.isNotBlank(microReference
)){
569 microReference
= getBeforeMicroReference() + microReference
;
570 if (microReference
.endsWith(".") && result
.contains(INomenclaturalReference
.MICRO_REFERENCE_TOKEN
+ ".") ){
571 microReference
= microReference
.substring(0, microReference
.length() - 1);
574 result
= replaceMicroRefToken(microReference
, result
);
575 if (result
.startsWith(". ")){ //only year available, remove '. '
576 result
= result
.substring(2);
581 private String
handleDetailAndYearForProtected(Reference nomenclaturalReference
, String cache
, String microReference
) {
582 String microRef
= isNotBlank(microReference
) ?
getBeforeMicroReference() + microReference
: "";
584 logger
.warn("Cache is null. This should never be the case.");
587 String result
= cache
+ (cache
.contains(microRef
) ?
"" : microRef
);
589 String date
= nomenclaturalReference
.getDatePublishedString();
590 if (isNotBlank(date
) && ! result
.contains(date
)){
591 result
= result
+ beforeYear
+ date
;
597 * Returns the nomenclatural title with micro reference represented as token
598 * which can later be replaced by the real data.
600 * @see INomenclaturalReference#MICRO_REFERENCE_TOKEN
602 * @param ref The reference
605 private String
getTokenizedNomenclaturalTitel(Reference ref
) {
606 if (isRealInRef(ref
)){
607 return getTokenizedNomenclaturalTitelInRef(ref
);
609 String result
= getTitleWithoutYearAndAuthor(ref
, true);
610 result
+= INomenclaturalReference
.MICRO_REFERENCE_TOKEN
;
611 result
= addYear(result
, ref
, true);
616 private String
getTokenizedNomenclaturalTitelInRef(Reference thisRef
) {
617 if (thisRef
== null){
621 Reference inRef
= CdmBase
.deproxy(thisRef
.getInReference(), Reference
.class);
622 if (inRef
!= null && inRef
.getInReference() != null && thisRef
.getType() == ReferenceType
.Section
){
623 //this is a reference of type Section which has a in-in-Ref
624 //TODO maybe we do not need to restrict to type=Section only
625 return this.getTokenizedNomenclaturalTitelInInRef(thisRef
);
629 //use generics's publication date if it exists
630 if (inRef
== null || (thisRef
.hasDatePublished() ) ){
631 getTitleWithoutYearAndAuthorGeneric(inRef
, true);
632 result
= inRef
== null ?
"" : getTitleWithoutYearAndAuthorGeneric(inRef
, true);
633 //added //TODO unify with non-inRef references formatting
635 if (isNotBlank(thisRef
.getVolume())){
636 result
= result
+ " " + thisRef
.getVolume();
638 //TODO series / edition
641 result
+= INomenclaturalReference
.MICRO_REFERENCE_TOKEN
;
642 result
= addYear(result
, thisRef
, true);
644 //else use inRefs's publication date
645 result
= inRef
.getNomenclaturalCitation(INomenclaturalReference
.MICRO_REFERENCE_TOKEN
);
647 result
= result
.replace(beforeMicroReference
+ INomenclaturalReference
.MICRO_REFERENCE_TOKEN
, INomenclaturalReference
.MICRO_REFERENCE_TOKEN
);
650 //FIXME: vol. etc., http://dev.e-taxonomy.eu/trac/ticket/2862
652 result
= getInRefAuthorPart(thisRef
.getInReference(), afterInRefAuthor
) + result
;
653 result
= "in " + result
;
658 * For handling in-in-Ref case.
659 * Must only be called if a reference has inRef and inInRef
663 private String
getTokenizedNomenclaturalTitelInInRef(Reference ref
) {
666 Reference inRef
= CdmBase
.deproxy(ref
.getInReference(), Reference
.class);
667 Reference inInRef
= CdmBase
.deproxy(inRef
.getInReference(), Reference
.class);
669 if (! isNomRef(inInRef
.getType())){
670 if (! isNomRef(inRef
.getType())){
671 logger
.warn("Neither inReference nor inInReference is a "
672 + " nomenclatural reference. This is not correct or not handled yet."
673 + " Generic titleWithoutYearAndAuthor used instead");
674 result
= getTitleWithoutYearAndAuthorGeneric(inInRef
, true);
675 //FIXME: vol. etc., http://dev.e-taxonomy.eu/trac/ticket/2862 (comment taken from super.getTokenizedNomenclaturalTitel())
677 result
= getTitleWithoutYearAndAuthor(inRef
, true);
680 result
= getTitleWithoutYearAndAuthor(inInRef
, true);
682 result
+= INomenclaturalReference
.MICRO_REFERENCE_TOKEN
;
684 Reference dataReference
= (ref
.hasDatePublished() ? ref
: inRef
.hasDatePublished() ? inRef
: inInRef
);
686 result
= addYear(result
, dataReference
, true);
688 result
= getInRefAuthorPart(inInRef
, afterInRefAuthor
) + result
;
689 if (! result
.startsWith("in ")){
690 result
= "in " + result
;
695 private String
getInRefAuthorPart(Reference book
, String seperator
){
699 TeamOrPersonBase
<?
> team
= book
.getAuthorship();
700 String result
= Nz( team
== null ?
"" : team
.getNomenclaturalTitle());
701 if (! result
.trim().equals("")){
702 result
= result
+ seperator
;
707 private String
replaceMicroRefToken(String microReference
, String string
) {
708 int index
= string
.indexOf(INomenclaturalReference
.MICRO_REFERENCE_TOKEN
);
711 String before
= string
.substring(0, index
);
712 String after
= string
.substring(index
+ INomenclaturalReference
.MICRO_REFERENCE_TOKEN
.length() );
713 String localMicroReference
= microReference
.trim(); //needed ?
714 if (after
.length() > 0){
715 if ( ("".equals(localMicroReference
) && before
.endsWith(after
.substring(0,1)) || localMicroReference
.endsWith(after
.substring(0,1)))){
716 after
= after
.substring(1);
719 String result
= before
+ localMicroReference
+ after
;
726 // *************************** EXTERNAL USE *******************************************/
728 public static String
putAuthorToEndOfString(String referenceTitleCache
, String authorTitleCache
) {
729 if(authorTitleCache
!= null){
730 referenceTitleCache
= referenceTitleCache
.replace(authorTitleCache
+ ", ", "");
731 referenceTitleCache
+= " - " + authorTitleCache
;
733 return referenceTitleCache
;