4 package eu
.etaxonomy
.cdm
.strategy
.parser
;
6 import java
.util
.regex
.Matcher
;
7 import java
.util
.regex
.Pattern
;
9 import org
.apache
.log4j
.Logger
;
10 import org
.joda
.time
.DateTimeFieldType
;
11 import org
.joda
.time
.Partial
;
13 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
14 import eu
.etaxonomy
.cdm
.model
.agent
.Person
;
15 import eu
.etaxonomy
.cdm
.model
.agent
.Team
;
16 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
17 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
18 import eu
.etaxonomy
.cdm
.model
.common
.IParsable
;
19 import eu
.etaxonomy
.cdm
.model
.common
.TimePeriod
;
20 import eu
.etaxonomy
.cdm
.model
.name
.BacterialName
;
21 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
22 import eu
.etaxonomy
.cdm
.model
.name
.CultivarPlantName
;
23 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalCode
;
24 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
25 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
26 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
27 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
28 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
29 import eu
.etaxonomy
.cdm
.model
.name
.ZoologicalName
;
30 import eu
.etaxonomy
.cdm
.model
.reference
.IGeneric
;
31 import eu
.etaxonomy
.cdm
.model
.reference
.IArticle
;
32 import eu
.etaxonomy
.cdm
.model
.reference
.IBook
;
33 import eu
.etaxonomy
.cdm
.model
.reference
.IBookSection
;
34 import eu
.etaxonomy
.cdm
.model
.reference
.IJournal
;
35 import eu
.etaxonomy
.cdm
.model
.reference
.INomenclaturalReference
;
36 import eu
.etaxonomy
.cdm
.model
.reference
.IReferenceBase
;
37 import eu
.etaxonomy
.cdm
.model
.reference
.IVolumeReference
;
38 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceFactory
;
39 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
40 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceType
;
41 import eu
.etaxonomy
.cdm
.strategy
.exceptions
.StringNotParsableException
;
42 import eu
.etaxonomy
.cdm
.strategy
.exceptions
.UnknownCdmTypeException
;
49 public class NonViralNameParserImpl
extends NonViralNameParserImplRegExBase
implements INonViralNameParser
<NonViralName
> {
50 private static final Logger logger
= Logger
.getLogger(NonViralNameParserImpl
.class);
52 // good intro: http://java.sun.com/docs/books/tutorial/essential/regex/index.html
54 final static boolean MAKE_EMPTY
= true;
55 final static boolean MAKE_NOT_EMPTY
= false;
56 private ReferenceFactory refFactory
= ReferenceFactory
.newInstance();
59 public static NonViralNameParserImpl
NewInstance(){
60 return new NonViralNameParserImpl();
64 * @see eu.etaxonomy.cdm.strategy.ITaxonNameParser#parseSubGenericSimpleName(java.lang.String)
66 public NonViralName
parseSimpleName(String simpleName
){
67 return parseSimpleName(simpleName
, null, null);
72 * @see eu.etaxonomy.cdm.strategy.parser.INonViralNameParser#parseSimpleName(java.lang.String, eu.etaxonomy.cdm.model.name.NomenclaturalCode, eu.etaxonomy.cdm.model.name.Rank)
74 public NonViralName
parseSimpleName(String simpleName
, NomenclaturalCode code
, Rank rank
){
75 //"parseSimpleName() not yet implemented. Uses parseFullName() instead");
76 return parseFullName(simpleName
, code
, rank
);
79 public void parseSimpleName(NonViralName nameToBeFilled
, String simpleNameString
, Rank rank
, boolean makeEmpty
){
80 //"parseSimpleName() not yet implemented. Uses parseFullName() instead");
81 parseFullName(nameToBeFilled
, simpleNameString
, rank
, makeEmpty
);
85 public NonViralName
getNonViralNameInstance(String fullString
, NomenclaturalCode code
){
86 return getNonViralNameInstance(fullString
, code
, null);
89 public NonViralName
getNonViralNameInstance(String fullString
, NomenclaturalCode code
, Rank rank
){
90 NonViralName result
= null;
92 boolean isBotanicalName
= anyBotanicFullNamePattern
.matcher(fullString
).find();
93 boolean isZoologicalName
= anyZooFullNamePattern
.matcher(fullString
).find();;
94 boolean isBacteriologicalName
= false;
95 boolean isCultivatedPlantName
= false;
96 if ( (isBotanicalName
|| isCultivatedPlantName
) && ! isZoologicalName
&& !isBacteriologicalName
){
98 result
= BotanicalName
.NewInstance(rank
);
100 result
= CultivarPlantName
.NewInstance(rank
);
102 }else if ( isZoologicalName
/*&& ! isBotanicalName*/ && !isBacteriologicalName
&& !isCultivatedPlantName
){
103 result
= ZoologicalName
.NewInstance(rank
);
104 }else if ( isZoologicalName
&& ! isBotanicalName
&& !isBacteriologicalName
&& !isCultivatedPlantName
){
105 result
= BacterialName
.NewInstance(rank
);
107 result
= NonViralName
.NewInstance(rank
);
112 result
= BotanicalName
.NewInstance(rank
);
115 result
= ZoologicalName
.NewInstance(rank
);
118 logger
.warn("ICNCP parsing not yet implemented");
119 result
= CultivarPlantName
.NewInstance(rank
);
122 logger
.warn("ICNB not yet implemented");
123 result
= BacterialName
.NewInstance(rank
);
126 logger
.error("Viral name is not a NonViralName !!");
129 // FIXME Unreachable code
130 logger
.error("Unknown Nomenclatural Code !!");
138 * @see eu.etaxonomy.cdm.strategy.parser.INonViralNameParser#parseFullReference(java.lang.String)
140 public NonViralName
parseReferencedName(String fullReferenceString
) {
141 return parseReferencedName(fullReferenceString
, null, null);
145 * @see eu.etaxonomy.cdm.strategy.ITaxonNameParser#parseFullReference(java.lang.String, eu.etaxonomy.cdm.model.name.Rank)
147 public NonViralName
parseReferencedName(String fullReferenceString
, NomenclaturalCode nomCode
, Rank rank
) {
148 if (fullReferenceString
== null){
151 NonViralName result
= getNonViralNameInstance(fullReferenceString
, nomCode
, rank
);
152 parseReferencedName(result
, fullReferenceString
, rank
, MAKE_EMPTY
);
157 private String
standardize(NonViralName nameToBeFilled
, String fullReferenceString
, boolean makeEmpty
){
158 //Check null and standardize
159 if (fullReferenceString
== null){
164 makeEmpty(nameToBeFilled
);
166 fullReferenceString
= fullReferenceString
.replaceAll(oWs
, " ");
167 fullReferenceString
= fullReferenceString
.trim();
168 if ("".equals(fullReferenceString
)){
169 fullReferenceString
= null;
171 return fullReferenceString
;
175 * Returns the regEx to be used for the full-name depending on the code
176 * @param nameToBeFilled
179 private String
getLocalFullName(NonViralName nameToBeFilled
){
180 if (nameToBeFilled
instanceof ZoologicalName
){
181 return anyZooFullName
;
182 }else if (nameToBeFilled
instanceof BotanicalName
) {
183 return anyBotanicFullName
;
184 }else if (nameToBeFilled
instanceof NonViralName
) {
185 return anyBotanicFullName
; //TODO ?
187 logger
.warn("nameToBeFilled class not supported ("+nameToBeFilled
.getClass()+")");
193 * Returns the regEx to be used for the fsimple-name depending on the code
194 * @param nameToBeFilled
197 private String
getLocalSimpleName(NonViralName nameToBeFilled
){
198 if (nameToBeFilled
instanceof ZoologicalName
){
200 }else if (nameToBeFilled
instanceof NonViralName
){
201 return anyZooName
; //TODO ?
202 }else if (nameToBeFilled
instanceof BotanicalName
) {
203 return anyBotanicName
;
205 logger
.warn("nameToBeFilled class not supported ("+nameToBeFilled
.getClass()+")");
210 private Matcher
getMatcher(String regEx
, String matchString
){
211 Pattern pattern
= Pattern
.compile(regEx
);
212 Matcher matcher
= pattern
.matcher(matchString
);
217 * @see eu.etaxonomy.cdm.strategy.ITaxonNameParser#parseFullReference(eu.etaxonomy.cdm.model.name.BotanicalName, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, boolean)
219 public void parseReferencedName(NonViralName nameToBeFilled
, String fullReferenceString
, Rank rank
, boolean makeEmpty
) {
221 fullReferenceString
= standardize(nameToBeFilled
, fullReferenceString
, makeEmpty
);
222 if (fullReferenceString
== null){
225 // happens already in standardize(...)
226 // makeProblemEmpty(nameToBeFilled);
228 //make nomenclatural status and replace it by empty string
229 fullReferenceString
= parseNomStatus(fullReferenceString
, nameToBeFilled
);
230 nameToBeFilled
.setProblemEnds(fullReferenceString
.length());
233 String localFullName
= getLocalFullName(nameToBeFilled
);
235 String localSimpleName
= getLocalSimpleName(nameToBeFilled
);
237 //separate name and reference part
238 String nameAndRefSeparator
= "(^" + localFullName
+ ")("+ referenceSeperator
+ ")";
239 Matcher nameAndRefSeparatorMatcher
= getMatcher (nameAndRefSeparator
, fullReferenceString
);
241 Matcher onlyNameMatcher
= getMatcher (localFullName
, fullReferenceString
);
242 Matcher onlySimpleNameMatcher
= getMatcher (localSimpleName
, fullReferenceString
);
244 if (nameAndRefSeparatorMatcher
.find()){
245 makeNameWithReference(nameToBeFilled
, fullReferenceString
, nameAndRefSeparatorMatcher
, rank
, makeEmpty
);
246 }else if (onlyNameMatcher
.matches()){
248 parseFullName(nameToBeFilled
, fullReferenceString
, rank
, makeEmpty
);
249 }else if (onlySimpleNameMatcher
.matches()){
251 parseFullName(nameToBeFilled
, fullReferenceString
, rank
, makeEmpty
); //simpleName not yet implemented
253 makeNoFullRefMatch(nameToBeFilled
, fullReferenceString
, rank
);
255 //problem handling. Start and end solved in subroutines
256 if (! nameToBeFilled
.hasProblem()){
257 makeProblemEmpty(nameToBeFilled
);
261 private void makeProblemEmpty(IParsable parsable
){
262 boolean hasCheckRank
= parsable
.hasProblem(ParserProblem
.CheckRank
);
263 parsable
.setParsingProblem(0);
265 parsable
.addParsingProblem(ParserProblem
.CheckRank
);
267 parsable
.setProblemStarts(-1);
268 parsable
.setProblemEnds(-1);
271 private void makeNoFullRefMatch(NonViralName nameToBeFilled
, String fullReferenceString
, Rank rank
){
272 //try to parse first part as name, but keep in mind full string is not parsable
275 String localFullName
= getLocalFullName(nameToBeFilled
);
276 Matcher fullNameMatcher
= getMatcher (pStart
+ localFullName
, fullReferenceString
);
277 if (fullNameMatcher
.find()){
278 String fullNameString
= fullNameMatcher
.group(0);
279 nameToBeFilled
.setProtectedNameCache(false);
280 parseFullName(nameToBeFilled
, fullNameString
, rank
, false);
281 String sure
= nameToBeFilled
.getNameCache();
282 start
= sure
.length();
285 // String localSimpleName = getLocalSimpleName(nameToBeFilled);
286 // Matcher simpleNameMatcher = getMatcher (start + localSimpleName, fullReferenceString);
287 // if (simpleNameMatcher.find()){
288 // String simpleNameString = simpleNameMatcher.group(0);
289 // parseFullName(nameToBeFilled, simpleNameString, rank, false);
290 // start = simpleNameString.length();
293 //don't parse if name can't be separated
294 nameToBeFilled
.addParsingProblem(ParserProblem
.NameReferenceSeparation
);
295 nameToBeFilled
.setTitleCache(fullReferenceString
);
296 nameToBeFilled
.setFullTitleCache(fullReferenceString
);
297 // FIXME Quick fix, otherwise search would not deliver results for unparsable names
298 nameToBeFilled
.setNameCache(fullReferenceString
);
300 nameToBeFilled
.setProblemStarts(start
);
301 nameToBeFilled
.setProblemEnds(fullReferenceString
.length());
302 logger
.info("no applicable parsing rule could be found for \"" + fullReferenceString
+ "\"");
305 private void makeNameWithReference(NonViralName nameToBeFilled
,
306 String fullReferenceString
,
307 Matcher nameAndRefSeparatorMatcher
,
311 String nameAndSeparator
= nameAndRefSeparatorMatcher
.group(0);
312 String name
= nameAndRefSeparatorMatcher
.group(1);
313 String referenceString
= fullReferenceString
.substring(nameAndRefSeparatorMatcher
.end());
315 // is reference an in ref?
316 String separator
= nameAndSeparator
.substring(name
.length());
317 boolean isInReference
= separator
.matches(inReferenceSeparator
);
321 int oldProblemEnds
= nameToBeFilled
.getProblemEnds();
322 parseFullName(nameToBeFilled
, name
, rank
, makeEmpty
);
323 nameToBeFilled
.setProblemEnds(oldProblemEnds
);
325 //zoological new combinations should not have a nom. reference to be parsed
326 if (nameToBeFilled
.isInstanceOf(ZoologicalName
.class)){
327 ZoologicalName zooName
= CdmBase
.deproxy(nameToBeFilled
, ZoologicalName
.class);
328 //is name new combination?
329 if (zooName
.getBasionymAuthorTeam() != null || zooName
.getOriginalPublicationYear() != null){
330 ParserProblem parserProblem
= ParserProblem
.NewCombinationHasPublication
;
331 zooName
.addParsingProblem(parserProblem
);
332 nameToBeFilled
.setProblemStarts((nameToBeFilled
.getProblemStarts()> -1) ? nameToBeFilled
.getProblemStarts(): name
.length());
333 nameToBeFilled
.setProblemEnds(Math
.max(fullReferenceString
.length(), nameToBeFilled
.getProblemEnds()));
337 parseReference(nameToBeFilled
, referenceString
, isInReference
);
338 INomenclaturalReference ref
= (INomenclaturalReference
)nameToBeFilled
.getNomenclaturalReference();
341 int start
= nameToBeFilled
.getProblemStarts();
342 int nameLength
= name
.length();
343 int nameAndSeparatorLength
= nameAndSeparator
.length();
344 int fullRefLength
= nameToBeFilled
.getFullTitleCache().length();
346 if (nameToBeFilled
.isProtectedTitleCache() || nameToBeFilled
.getParsingProblems().contains(ParserProblem
.CheckRank
)){
347 start
= Math
.max(0, start
);
349 if (ref
!= null && ref
.getParsingProblem()!=0){
350 start
= Math
.max(nameAndSeparatorLength
, start
);
351 //TODO search within ref
356 int end
= nameToBeFilled
.getProblemEnds();
358 if (ref
!= null && ref
.getParsingProblem()!=0){
359 end
= Math
.min(nameAndSeparatorLength
+ ref
.getProblemEnds(), end
);
361 if (nameToBeFilled
.isProtectedTitleCache() ){
362 end
= Math
.min(end
, nameAndSeparatorLength
);
363 //TODO search within name
366 nameToBeFilled
.setProblemStarts(start
);
367 nameToBeFilled
.setProblemEnds(end
);
369 //delegate has problem to name
370 if (ref
!= null && ref
.getParsingProblem()!=0){
371 nameToBeFilled
.addParsingProblems(ref
.getParsingProblem());
374 ReferenceBase nomRef
;
375 if ( (nomRef
= (ReferenceBase
)nameToBeFilled
.getNomenclaturalReference()) != null ){
376 nomRef
.setAuthorTeam((TeamOrPersonBase
)nameToBeFilled
.getCombinationAuthorTeam());
380 //TODO make it an Array of status
382 * Extracts a {@link NomenclaturalStatus} from the reference String and adds it to the @link {@link TaxonNameBase}.
383 * The nomenclatural status part ist deleted from the reference String.
384 * @return String the new (shortend) reference String
386 private String
parseNomStatus(String fullString
, NonViralName nameToBeFilled
) {
388 Pattern hasStatusPattern
= Pattern
.compile("(" + pNomStatusPhrase
+ ")");
389 Matcher hasStatusMatcher
= hasStatusPattern
.matcher(fullString
);
391 if (hasStatusMatcher
.find()) {
392 String statusPhrase
= hasStatusMatcher
.group(0);
394 Pattern statusPattern
= Pattern
.compile(pNomStatus
);
395 Matcher statusMatcher
= statusPattern
.matcher(statusPhrase
);
396 statusMatcher
.find();
397 statusString
= statusMatcher
.group(0);
399 NomenclaturalStatusType nomStatusType
= NomenclaturalStatusType
.getNomenclaturalStatusTypeByAbbreviation(statusString
);
400 NomenclaturalStatus nomStatus
= NomenclaturalStatus
.NewInstance(nomStatusType
);
401 nameToBeFilled
.addStatus(nomStatus
);
403 fullString
= fullString
.replace(statusPhrase
, "");
404 } catch (UnknownCdmTypeException e
) {
412 private void parseReference(NonViralName nameToBeFilled
, String strReference
, boolean isInReference
){
414 INomenclaturalReference ref
;
415 String originalStrReference
= strReference
;
417 //End (just delete end (e.g. '.', may be ambigous for yearPhrase, but no real information gets lost
418 Matcher endMatcher
= getMatcher(referenceEnd
+ end
, strReference
);
419 if (endMatcher
.find()){
420 String endPart
= endMatcher
.group(0);
421 strReference
= strReference
.substring(0, strReference
.length() - endPart
.length());
424 // String pDetailYear = ".*" + detailSeparator + detail + fWs + yearSeperator + fWs + yearPhrase + fWs + end;
425 // Matcher detailYearMatcher = getMatcher(pDetailYear, strReference);
427 String strReferenceWithYear
= strReference
;
429 String yearPart
= null;
430 String pYearPhrase
= yearSeperator
+ fWs
+ yearPhrase
+ fWs
+ end
;
431 Matcher yearPhraseMatcher
= getMatcher(pYearPhrase
, strReference
);
432 if (yearPhraseMatcher
.find()){
433 yearPart
= yearPhraseMatcher
.group(0);
434 strReference
= strReference
.substring(0, strReference
.length() - yearPart
.length());
435 yearPart
= yearPart
.replaceFirst(pStart
+ yearSeperator
, "").trim();
437 if (nameToBeFilled
.isInstanceOf(ZoologicalName
.class)){
438 ZoologicalName zooName
= CdmBase
.deproxy(nameToBeFilled
, ZoologicalName
.class);
439 yearPart
= String
.valueOf(zooName
.getPublicationYear());
442 ref
= makeDetailYearUnparsable(nameToBeFilled
,strReference
);
443 ref
.setDatePublished(TimePeriod
.parseString(yearPart
));
450 String pDetailPhrase
= detailSeparator
+ fWs
+ detail
+ fWs
+ end
;
451 Matcher detailPhraseMatcher
= getMatcher(pDetailPhrase
, strReference
);
452 if (detailPhraseMatcher
.find()){
453 String detailPart
= detailPhraseMatcher
.group(0);
454 strReference
= strReference
.substring(0, strReference
.length() - detailPart
.length());
455 detailPart
= detailPart
.replaceFirst(pStart
+ detailSeparator
, "").trim();
456 nameToBeFilled
.setNomenclaturalMicroReference(detailPart
);
458 makeDetailYearUnparsable(nameToBeFilled
, strReferenceWithYear
);
461 //parse title and author
462 ref
= parseReferenceTitle(strReference
, yearPart
, isInReference
);
463 if (ref
.hasProblem()){
464 ref
.setTitleCache( (isInReference?
"in ":"") + originalStrReference
);
466 nameToBeFilled
.setNomenclaturalReference((ReferenceBase
)ref
);
467 int end
= Math
.min(strReference
.length(), ref
.getProblemEnds());
468 ref
.setProblemEnds(end
);
472 * @param nameToBeFilled
473 * @param strReference
476 private INomenclaturalReference
makeDetailYearUnparsable(NonViralName nameToBeFilled
, String strReference
) {
477 INomenclaturalReference ref
;
478 //ref = Generic.NewInstance();
480 ref
= refFactory
.newGeneric();
481 ref
.setTitleCache(strReference
);
482 ref
.setProblemEnds(strReference
.length());
483 ref
.addParsingProblem(ParserProblem
.CheckDetailOrYear
);
484 nameToBeFilled
.addParsingProblem(ParserProblem
.CheckDetailOrYear
);
485 nameToBeFilled
.setNomenclaturalReference((ReferenceBase
)ref
);
490 * Parses the referenceTitlePart, including the author volume and edition.
495 private INomenclaturalReference
parseReferenceTitle(String strReference
, String year
, boolean isInReference
){
498 Matcher refSineDetailMatcher
= referenceSineDetailPattern
.matcher(strReference
);
499 if (! refSineDetailMatcher
.matches()){
503 Matcher articleMatcher
= getMatcher(pArticleReference
, strReference
);
505 Matcher softArticleMatcher
= getMatcher(pSoftArticleReference
, strReference
);
506 Matcher bookMatcher
= getMatcher(pBookReference
, strReference
);
507 Matcher bookSectionMatcher
= getMatcher(pBookSectionReference
, strReference
);
510 if(isInReference
== false){
511 if (bookMatcher
.matches() ){
512 result
= parseBook(strReference
);
514 logger
.warn("Non-InRef must be book but does not match book");
515 result
= refFactory
.newBook();
516 makeUnparsableRefTitle(result
, strReference
);
519 if (articleMatcher
.matches()){
520 //article without separators like ","
521 result
= parseArticle(strReference
);
522 }else if (softArticleMatcher
.matches()){
523 result
= parseArticle(strReference
);
524 }else if (bookSectionMatcher
.matches()){
525 result
= parseBookSection(strReference
);
527 result
= refFactory
.newGeneric();
528 makeUnparsableRefTitle(result
, "in " + strReference
);
532 if (makeYear(result
, year
) == false){
534 logger
.warn("Year could not be parsed");
536 result
.setProblemStarts(0);
537 result
.setProblemEnds(strReference
.length());
541 private void makeUnparsableRefTitle(INomenclaturalReference result
, String reference
){
542 result
.setTitleCache(reference
);
543 result
.addParsingProblem(ParserProblem
.UnparsableReferenceTitle
);
547 * Parses a single date string. If the string is not parsable a StringNotParsableException is thrown
548 * @param singleDateString
550 * @throws StringNotParsableException
552 private static Partial
parseSingleDate(String singleDateString
)
553 throws StringNotParsableException
{
554 Partial dt
= new Partial();
555 if (CdmUtils
.isNumeric(singleDateString
)){
557 Integer year
= Integer
.valueOf(singleDateString
.trim());
558 if (year
> 1750 && year
< 2050){
559 dt
= dt
.with(DateTimeFieldType
.year(), year
);
563 } catch (NumberFormatException e
) {
564 logger
.debug("Not a Integer format in getCalendar()");
565 throw new StringNotParsableException(singleDateString
+ "is not parsable as a single Date");
573 * Parses the publication date part.
576 * @return If the string is not parsable <code>false</code>
577 * is returned. <code>True</code> otherwise
579 private boolean makeYear(INomenclaturalReference nomRef
, String year
){
580 boolean result
= true;
584 if ("".equals(year
.trim())){
587 TimePeriod datePublished
= TimePeriod
.parseString(year
);
589 if (nomRef
.getType().equals(ReferenceType
.BookSection
)){
590 handleBookSectionYear((IBookSection
)nomRef
, datePublished
);
591 }else if (nomRef
instanceof ReferenceBase
){
592 ((ReferenceBase
)nomRef
).setDatePublished(datePublished
);
594 throw new ClassCastException("nom Ref is not of type ReferenceBase but " + (nomRef
== null?
"(null)" : nomRef
.getClass()));
599 private String
makeVolume(IVolumeReference nomRef
, String strReference
){
601 String volPart
= null;
602 String pVolPhrase
= volumeSeparator
+ volume
+ end
;
603 Matcher volPhraseMatcher
= getMatcher(pVolPhrase
, strReference
);
604 if (volPhraseMatcher
.find()){
605 volPart
= volPhraseMatcher
.group(0);
606 strReference
= strReference
.substring(0, strReference
.length() - volPart
.length());
607 volPart
= volPart
.replaceFirst(pStart
+ volumeSeparator
, "").trim();
608 nomRef
.setVolume(volPart
);
613 private String
makeEdition(IBook book
, String strReference
){
615 String editionPart
= null;
616 Matcher editionPhraseMatcher
= getMatcher(pEditionPart
, strReference
);
618 Matcher editionVolumeMatcher
= getMatcher(pEditionVolPart
, strReference
);
619 boolean isEditionAndVol
= editionVolumeMatcher
.find();
621 if (editionPhraseMatcher
.find()){
622 editionPart
= editionPhraseMatcher
.group(0);
623 int pos
= strReference
.indexOf(editionPart
);
624 int posEnd
= pos
+ editionPart
.length();
625 if (isEditionAndVol
){
626 posEnd
++; //delete also comma
628 strReference
= strReference
.substring(0, pos
) + strReference
.substring(posEnd
);
629 editionPart
= editionPart
.replaceFirst(pStart
+ editionSeparator
, "").trim();
630 book
.setEdition(editionPart
);
635 private IBook
parseBook(String reference
){
636 IBook result
= refFactory
.newBook();
637 reference
= makeEdition(result
, reference
);
638 reference
= makeVolume(result
, reference
);
639 result
.setTitle(reference
);
644 private ReferenceBase
parseArticle(String reference
){
646 //(type, author, title, volume, editor, series;
647 ReferenceBase result
= refFactory
.newArticle();
648 reference
= makeVolume(result
, reference
);
649 ReferenceBase inJournal
= refFactory
.newJournal();
650 inJournal
.setTitle(reference
);
651 result
.setInReference(inJournal
);
655 private ReferenceBase
parseBookSection(String reference
){
656 ReferenceBase result
= refFactory
.newBookSection();
657 String
[] parts
= reference
.split(referenceAuthorSeparator
, 2);
658 if (parts
.length
!= 2){
659 logger
.warn("Unexpected number of parts");
660 result
.setTitleCache(reference
);
662 String authorString
= parts
[0];
663 String bookString
= parts
[1];
665 TeamOrPersonBase
<?
> authorTeam
= author(authorString
);
666 IBook inBook
= parseBook(bookString
);
667 inBook
.setAuthorTeam(authorTeam
);
668 result
.setInBook(inBook
);
674 * If the publication date of a book section and it's inBook do differ this is usually
675 * caused by the fact that a book has been published during a period, because originally
676 * it consisted of several parts that only later where put together to one book.
677 * If so, the book section's publication date may be a point in time (year or month of year)
678 * whereas the books publication date may be a period of several years.
679 * Therefore a valid nomenclatural reference string should use the book sections
680 * publication date rather then the book's publication date.<BR>
681 * This method in general adds the publication date to the book section.
682 * An exception exists if the publication date is a period. Then the parser
683 * assumes that the nomenclatural reference string does not follow the above rule but
684 * the books publication date is set.
686 * @param datePublished
688 private void handleBookSectionYear(IBookSection bookSection
, TimePeriod datePublished
){
689 if (datePublished
== null || datePublished
.getStart() == null || bookSection
== null){
692 if (datePublished
.isPeriod() && bookSection
.getInBook() != null){
693 bookSection
.getInBook().setDatePublished(datePublished
);
695 bookSection
.setDatePublished(datePublished
);
701 * @see eu.etaxonomy.cdm.strategy.parser.INonViralNameParser#parseFullName(java.lang.String)
703 public NonViralName
parseFullName(String fullNameString
){
704 return parseFullName(fullNameString
, null, null);
709 * @see eu.etaxonomy.cdm.strategy.ITaxonNameParser#parseFullName(java.lang.String, eu.etaxonomy.cdm.model.name.Rank)
711 public NonViralName
parseFullName(String fullNameString
, NomenclaturalCode nomCode
, Rank rank
) {
713 if (fullNameString
== null){
716 NonViralName result
= getNonViralNameInstance(fullNameString
, nomCode
, rank
);
717 parseFullName(result
, fullNameString
, rank
, false);
723 public void parseFullName(NonViralName nameToBeFilled
, String fullNameString
, Rank rank
, boolean makeEmpty
) {
725 boolean hasCheckRankProblem
= false; //was rank guessed in a previous parsing process?
726 if (nameToBeFilled
== null){
727 logger
.warn("name is null!");
729 hasCheckRankProblem
= nameToBeFilled
.hasProblem(ParserProblem
.CheckRank
);
730 nameToBeFilled
.removeParsingProblem(ParserProblem
.CheckRank
);
732 String authorString
= null;
734 if (fullNameString
== null){
739 makeEmpty(nameToBeFilled
);
741 fullNameString
.replaceAll(oWs
, " ");
743 // OLD: fullName = oWsRE.subst(fullName, " "); //substitute multiple whitespaces
744 fullNameString
= fullNameString
.trim();
746 String
[] epi
= pattern
.split(fullNameString
);
748 //cultivars //TODO 2 implement cultivars
749 // if ( cultivarMarkerRE.match(fullName) ){ funktioniert noch nicht, da es z.B. auch Namen gibt, wie 't Hart
750 // result = parseCultivar(fullName);
752 //hybrids //TODO 2 implement hybrids
754 if (hybridPattern
.matcher(fullNameString
).matches() ){
755 nameToBeFilled
= parseHybrid(fullNameString
);
757 else if (genusOrSupraGenusPattern
.matcher(fullNameString
).matches()){
759 if (rank
!= null && ! hasCheckRankProblem
&& (rank
.isSupraGeneric()|| rank
.isGenus())){
760 nameToBeFilled
.setRank(rank
);
761 nameToBeFilled
.setGenusOrUninomial(epi
[0]);
763 //genus or guess rank
765 rank
= guessUninomialRank(nameToBeFilled
, epi
[0]);
766 nameToBeFilled
.setRank(rank
);
767 nameToBeFilled
.setGenusOrUninomial(epi
[0]);
768 nameToBeFilled
.addParsingProblem(ParserProblem
.CheckRank
);
769 nameToBeFilled
.setProblemStarts(0);
770 nameToBeFilled
.setProblemEnds(epi
[0].length());
772 authorString
= fullNameString
.substring(epi
[0].length());
775 else if (infraGenusPattern
.matcher(fullNameString
).matches()){
776 nameToBeFilled
.setRank(Rank
.getRankByAbbreviation(epi
[1]));
777 nameToBeFilled
.setGenusOrUninomial(epi
[0]);
778 nameToBeFilled
.setInfraGenericEpithet(epi
[2]);
779 authorString
= fullNameString
.substring(epi
[0].length() + 1 + epi
[1].length()+ 1 + epi
[2].length());
782 else if (aggrOrGroupPattern
.matcher(fullNameString
).matches()){
783 nameToBeFilled
.setRank(Rank
.getRankByAbbreviation(epi
[2]));
784 nameToBeFilled
.setGenusOrUninomial(epi
[0]);
785 nameToBeFilled
.setSpecificEpithet(epi
[1]);
788 else if (speciesPattern
.matcher(fullNameString
).matches()){
789 nameToBeFilled
.setRank(Rank
.SPECIES());
790 nameToBeFilled
.setGenusOrUninomial(epi
[0]);
791 nameToBeFilled
.setSpecificEpithet(epi
[1]);
792 authorString
= fullNameString
.substring(epi
[0].length() + 1 + epi
[1].length());
795 else if (autonymPattern
.matcher(fullNameString
).matches()){
796 nameToBeFilled
.setRank(Rank
.getRankByAbbreviation(epi
[epi
.length
- 2]));
797 nameToBeFilled
.setGenusOrUninomial(epi
[0]);
798 nameToBeFilled
.setSpecificEpithet(epi
[1]);
799 nameToBeFilled
.setInfraSpecificEpithet(epi
[epi
.length
- 1]);
800 int lenSpecies
= 2 + epi
[0].length()+epi
[1].length();
801 int lenInfraSpecies
= 2 + epi
[epi
.length
- 2].length() + epi
[epi
.length
- 1].length();
802 authorString
= fullNameString
.substring(lenSpecies
, fullNameString
.length() - lenInfraSpecies
);
805 else if (infraSpeciesPattern
.matcher(fullNameString
).matches()){
806 String infraSpecRankEpi
= epi
[2];
807 String infraSpecEpi
= epi
[3];
808 if ("tax.".equals(infraSpecRankEpi
)){
809 infraSpecRankEpi
+= " " + epi
[3];
810 infraSpecEpi
= epi
[4];
812 nameToBeFilled
.setRank(Rank
.getRankByAbbreviation(infraSpecRankEpi
));
813 nameToBeFilled
.setGenusOrUninomial(epi
[0]);
814 nameToBeFilled
.setSpecificEpithet(epi
[1]);
815 nameToBeFilled
.setInfraSpecificEpithet(infraSpecEpi
);
816 authorString
= fullNameString
.substring(epi
[0].length()+ 1 + epi
[1].length() +1 + infraSpecRankEpi
.length() + 1 + infraSpecEpi
.length());
818 else if (oldInfraSpeciesPattern
.matcher(fullNameString
).matches()){
819 boolean implemented
= false;
821 nameToBeFilled
.setRank(Rank
.getRankByNameOrAbbreviation(epi
[2]));
822 nameToBeFilled
.setGenusOrUninomial(epi
[0]);
823 nameToBeFilled
.setSpecificEpithet(epi
[1]);
824 //TODO result.setUnnamedNamePhrase(epi[2] + " " + epi[3]);
825 authorString
= fullNameString
.substring(epi
[0].length()+ 1 + epi
[1].length() +1 + epi
[2].length() + 1 + epi
[3].length());
827 nameToBeFilled
.addParsingProblem(ParserProblem
.OldInfraSpeciesNotSupported
);
828 nameToBeFilled
.setTitleCache(fullNameString
);
829 // FIXME Quick fix, otherwise search would not deilver results for unparsable names
830 nameToBeFilled
.setNameCache(fullNameString
);
832 logger
.info("Name string " + fullNameString
+ " could not be parsed because UnnnamedNamePhrase is not yet implemented!");
837 nameToBeFilled
.addParsingProblem(ParserProblem
.UnparsableNamePart
);
838 nameToBeFilled
.setTitleCache(fullNameString
);
839 // FIXME Quick fix, otherwise search would not deilver results for unparsable names
840 nameToBeFilled
.setNameCache(fullNameString
);
842 logger
.info("no applicable parsing rule could be found for \"" + fullNameString
+ "\"");
845 if (nameToBeFilled
!= null && authorString
!= null && authorString
.trim().length() > 0 ){
846 TeamOrPersonBase
<?
>[] authors
= new TeamOrPersonBase
[4];
847 Integer
[] years
= new Integer
[4];
849 Class
<?
extends NonViralName
> clazz
= nameToBeFilled
.getClass();
850 fullAuthors(authorString
, authors
, years
, clazz
);
851 } catch (StringNotParsableException e
) {
852 nameToBeFilled
.addParsingProblem(ParserProblem
.UnparsableAuthorPart
);
853 nameToBeFilled
.setTitleCache(fullNameString
);
854 // FIXME Quick fix, otherwise search would not deilver results for unparsable names
855 nameToBeFilled
.setNameCache(fullNameString
);
857 logger
.info("no applicable parsing rule could be found for \"" + fullNameString
+ "\"");;
859 nameToBeFilled
.setCombinationAuthorTeam(authors
[0]);
860 nameToBeFilled
.setExCombinationAuthorTeam(authors
[1]);
861 nameToBeFilled
.setBasionymAuthorTeam(authors
[2]);
862 nameToBeFilled
.setExBasionymAuthorTeam(authors
[3]);
863 if (nameToBeFilled
instanceof ZoologicalName
){
864 ZoologicalName zooName
= (ZoologicalName
)nameToBeFilled
;
865 zooName
.setPublicationYear(years
[0]);
866 zooName
.setOriginalPublicationYear(years
[2]);
870 if (nameToBeFilled
!= null){
871 //return(BotanicalName)result;
874 } catch (UnknownCdmTypeException e
) {
875 nameToBeFilled
.addParsingProblem(ParserProblem
.RankNotSupported
);
876 nameToBeFilled
.setTitleCache(fullNameString
);
877 // FIXME Quick fix, otherwise search would not deilver results for unparsable names
878 nameToBeFilled
.setNameCache(fullNameString
);
880 logger
.info("unknown rank (" + (rank
== null?
"null":rank
) + ") or abbreviation in string " + fullNameString
);
889 * Guesses the rank of uninomial depending on the typical endings for ranks
890 * @param nameToBeFilled
893 private Rank
guessUninomialRank(NonViralName nameToBeFilled
, String uninomial
) {
894 Rank result
= Rank
.GENUS();
895 if (nameToBeFilled
.isInstanceOf(BotanicalName
.class)){
898 }else if (uninomial
.endsWith("phyta") || uninomial
.endsWith("mycota") ){ //plants, fungi
899 result
= Rank
.SECTION_BOTANY();
900 }else if (uninomial
.endsWith("bionta")){
901 result
= Rank
.SUBKINGDOM(); //TODO
902 }else if (uninomial
.endsWith("phytina")|| uninomial
.endsWith("mycotina") ){ //plants, fungi
903 result
= Rank
.SUBSECTION_BOTANY();
904 }else if (uninomial
.endsWith("opsida") || uninomial
.endsWith("phyceae") || uninomial
.endsWith("mycetes")){ //plants, algae, fungi
905 result
= Rank
.CLASS();
906 }else if (uninomial
.endsWith("idae") || uninomial
.endsWith("phycidae") || uninomial
.endsWith("mycetidae")){ //plants, algae, fungi
907 result
= Rank
.SUBCLASS();
908 }else if (uninomial
.endsWith("ales")){
909 result
= Rank
.ORDER();
910 }else if (uninomial
.endsWith("ineae")){
911 result
= Rank
.SUBORDER();
912 }else if (uninomial
.endsWith("aceae")){
913 result
= Rank
.FAMILY();
914 }else if (uninomial
.endsWith("oideae")){
915 result
= Rank
.SUBFAMILY();
916 }else if (uninomial
.endsWith("eae")){
917 result
= Rank
.TRIBE();
918 }else if (uninomial
.endsWith("inae")){
919 result
= Rank
.SUBTRIBE();
920 }else if (uninomial
.endsWith("ota")){
921 result
= Rank
.KINGDOM(); //TODO
923 }else if (nameToBeFilled
.isInstanceOf(ZoologicalName
.class)){
926 }else if (uninomial
.endsWith("oideae")){
927 result
= Rank
.SUPERFAMILY();
928 }else if (uninomial
.endsWith("idae")){
929 result
= Rank
.FAMILY();
930 }else if (uninomial
.endsWith("inae")){
931 result
= Rank
.SUBFAMILY();
932 }else if (uninomial
.endsWith("inae")){
933 result
= Rank
.SUBFAMILY();
934 }else if (uninomial
.endsWith("ini")){
935 result
= Rank
.TRIBE();
936 }else if (uninomial
.endsWith("ina")){
937 result
= Rank
.SUBTRIBE();
946 * Parses the fullAuthorString
947 * @param fullAuthorString
948 * @return array of Teams containing the Team[0],
949 * ExTeam[1], BasionymTeam[2], ExBasionymTeam[3]
951 protected void fullAuthors (String fullAuthorString
, TeamOrPersonBase
<?
>[] authors
, Integer
[] years
, Class
<?
extends NonViralName
> clazz
)
952 throws StringNotParsableException
{
953 fullAuthorString
= fullAuthorString
.trim();
954 if (fullAuthorString
== null || clazz
== null){
958 if ( BotanicalName
.class.isAssignableFrom(clazz
) ){
959 if (! fullBotanicAuthorStringPattern
.matcher(fullAuthorString
).matches() ){
960 throw new StringNotParsableException("fullAuthorString (" +fullAuthorString
+") not parsable: ");
964 else if ( ZoologicalName
.class.isAssignableFrom(clazz
) ){
965 if (! fullZooAuthorStringPattern
.matcher(fullAuthorString
).matches() ){
966 throw new StringNotParsableException("fullAuthorString (" +fullAuthorString
+") not parsable: ");
970 logger
.warn ("not yet implemented");
971 throw new StringNotParsableException("fullAuthorString (" +fullAuthorString
+") not parsable: ");
973 fullAuthorsChecked(fullAuthorString
, authors
, years
);
977 * like fullTeams but without trim and match check
979 protected void fullAuthorsChecked (String fullAuthorString
, TeamOrPersonBase
<?
>[] authors
, Integer
[] years
){
980 int authorTeamStart
= 0;
981 Matcher basionymMatcher
= basionymPattern
.matcher(fullAuthorString
);
983 if (basionymMatcher
.find(0)){
985 String basString
= basionymMatcher
.group();
986 basString
= basString
.replaceFirst(basStart
, "");
987 basString
= basString
.replaceAll(basEnd
, "").trim();
988 authorTeamStart
= basionymMatcher
.end(1) + 1;
990 TeamOrPersonBase
<?
>[] basAuthors
= new TeamOrPersonBase
[2];
991 Integer
[] basYears
= new Integer
[2];
992 authorsAndEx(basString
, basAuthors
, basYears
);
993 authors
[2]= basAuthors
[0];
994 years
[2] = basYears
[0];
995 authors
[3]= basAuthors
[1];
996 years
[3] = basYears
[1];
998 if (fullAuthorString
.length() >= authorTeamStart
){
999 TeamOrPersonBase
<?
>[] combinationAuthors
= new TeamOrPersonBase
[2];;
1000 Integer
[] combinationYears
= new Integer
[2];
1001 authorsAndEx(fullAuthorString
.substring(authorTeamStart
), combinationAuthors
, combinationYears
);
1002 authors
[0]= combinationAuthors
[0] ;
1003 years
[0] = combinationYears
[0];
1004 authors
[1]= combinationAuthors
[1];
1005 years
[1] = combinationYears
[1];
1011 * Parses the author and ex-author String
1012 * @param authorTeamString String representing the author and the ex-author team
1013 * @return array of Teams containing the Team[0] and the ExTeam[1]
1015 protected void authorsAndEx (String authorTeamString
, TeamOrPersonBase
<?
>[] authors
, Integer
[] years
){
1016 //TODO noch allgemeiner am anfang durch Replace etc.
1017 authorTeamString
= authorTeamString
.trim();
1018 authorTeamString
= authorTeamString
.replaceFirst(oWs
+ "ex" + oWs
, " ex. " );
1019 int authorEnd
= authorTeamString
.length();
1021 Matcher exAuthorMatcher
= exAuthorPattern
.matcher(authorTeamString
);
1022 if (exAuthorMatcher
.find(0)){
1023 int exAuthorBegin
= exAuthorMatcher
.end(0);
1024 String exString
= authorTeamString
.substring(exAuthorBegin
).trim();
1025 authorEnd
= exAuthorMatcher
.start(0);
1026 authors
[1] = author(exString
);
1028 zooOrBotanicAuthor(authorTeamString
.substring(0, authorEnd
), authors
, years
);
1032 * Parses the authorString and if it matches an botanical or zoological authorTeam it fills
1033 * the computes the AuthorTeam and fills it into the first field of the team array. Same applies
1034 * to the year in case of an zoological name.
1035 * @param authorString
1039 protected void zooOrBotanicAuthor(String authorString
, TeamOrPersonBase
<?
>[] team
, Integer
[] year
){
1040 if (authorString
== null){
1042 }else if ((authorString
= authorString
.trim()).length() == 0){
1045 Matcher zooAuthorAddidtionMatcher
= zooAuthorAddidtionPattern
.matcher(authorString
);
1046 if (zooAuthorAddidtionMatcher
.find()){
1047 int index
= zooAuthorAddidtionMatcher
.start(0);
1048 String strYear
= authorString
.substring(index
);
1049 strYear
= strYear
.replaceAll(zooAuthorYearSeperator
, "").trim();
1050 year
[0] = Integer
.valueOf(strYear
);
1051 authorString
= authorString
.substring(0, index
).trim();
1053 team
[0] = author(authorString
);
1058 * Parses an authorTeam String and returns the Team
1059 * !!! TODO (atomization not yet implemented)
1060 * @param authorTeamString String representing the author team
1063 protected TeamOrPersonBase
<?
> author (String authorString
){
1064 if (authorString
== null){
1066 }else if ((authorString
= authorString
.trim()).length() == 0){
1068 }else if (! teamSplitterPattern
.matcher(authorString
).find()){
1070 Person result
= Person
.NewInstance();
1071 result
.setNomenclaturalTitle(authorString
);
1074 return parsedTeam(authorString
);
1080 * Parses an authorString (reprsenting a team into the single authors and add
1081 * them to the return Team.
1082 * @param authorString
1085 protected Team
parsedTeam(String authorString
){
1086 Team result
= Team
.NewInstance();
1087 String
[] authors
= authorString
.split(teamSplitter
);
1088 for (String author
: authors
){
1089 Person person
= Person
.NewInstance();
1090 person
.setNomenclaturalTitle(author
);
1091 result
.addTeamMember(person
);
1097 //Parsing of the given full name that has been identified as hybrid already somewhere else.
1098 private BotanicalName
parseHybrid(String fullName
){
1099 logger
.warn("parseHybrid --> function not yet implemented");
1100 BotanicalName result
= BotanicalName
.NewInstance(null);
1101 result
.setTitleCache(fullName
);
1105 // // Parsing of the given full name that has been identified as a cultivar already somwhere else.
1106 // // The ... cv. ... syntax is not covered here as it is not according the rules for naming cultivars.
1107 public BotanicalName
parseCultivar(String fullName
) throws StringNotParsableException
{
1108 CultivarPlantName result
= null;
1109 String
[] words
= oWsPattern
.split(fullName
);
1111 /* ---------------------------------------------------------------------------------
1113 * ---------------------------------------------------------------------------------*/
1114 if (fullName
.indexOf(" '") != 0){
1115 //TODO location of 'xx' is probably not arbitrary
1116 Matcher cultivarMatcher
= cultivarPattern
.matcher(fullName
);
1117 if (cultivarMatcher
.find()){
1118 String namePart
= fullName
.replaceFirst(cultivar
, "");
1120 String cultivarPart
= cultivarMatcher
.group(0).replace("'","").trim();
1121 //OLD: String cultivarPart = cultivarRE.getParen(0).replace("'","").trim();
1123 result
= (CultivarPlantName
)parseFullName(namePart
);
1124 result
.setCultivarName(cultivarPart
);
1126 }else if (fullName
.indexOf(" cv.") != 0){
1127 // cv. is old form (not official)
1128 throw new StringNotParsableException("Cultivars with only cv. not yet implemented in name parser!");
1131 /* ---------------------------------------------------------------------------------
1133 * ---------------------------------------------------------------------------------
1136 //Ann. this is not the official way of noting cultivar groups
1137 String group
= oWs
+ "Group" + oWs
+ capitalEpiWord
+ end
;
1138 Pattern groupRE
= Pattern
.compile(group
);
1139 Matcher groupMatcher
= groupRE
.matcher(fullName
);
1140 if (groupMatcher
.find()){
1141 if (! words
[words
.length
- 2].equals("group")){
1142 throw new StringNotParsableException ("fct ParseHybrid --> term before cultivar group name in " + fullName
+ " should be 'group'");
1145 String namePart
= fullName
.substring(0, groupMatcher
.start(0) - 0);
1146 //OLD: String namePart = fullName.substring(0, groupRE.getParenStart(0) - 0);
1148 String cultivarPart
= words
[words
.length
-1];
1149 result
= (CultivarPlantName
)parseFullName(namePart
);
1150 if (result
!= null){
1151 result
.setCultivarName(cultivarPart
);
1153 //OLD: result.setCultivarGroupName(cultivarPart);
1158 // // ---------------------------------------------------------------------------------
1159 // if ( result = "" ){
1160 // return "I: fct ParseCultivar: --> could not parse cultivar " + fullName;
1164 return result
; //TODO
1168 private void makeEmpty(NonViralName nameToBeFilled
){
1169 nameToBeFilled
.setRank(null);
1170 nameToBeFilled
.setTitleCache(null, false);
1171 nameToBeFilled
.setFullTitleCache(null, false);
1172 nameToBeFilled
.setNameCache(null, false);
1174 nameToBeFilled
.setAppendedPhrase(null);
1175 nameToBeFilled
.setBasionymAuthorTeam(null);
1176 nameToBeFilled
.setCombinationAuthorTeam(null);
1177 nameToBeFilled
.setExBasionymAuthorTeam(null);
1178 nameToBeFilled
.setExCombinationAuthorTeam(null);
1179 nameToBeFilled
.setAuthorshipCache(null, false);
1182 //delete problems except check rank
1183 makeProblemEmpty(nameToBeFilled
);
1186 //nameToBeFilled.setHomotypicalGroup(newHomotypicalGroup);
1189 nameToBeFilled
.setGenusOrUninomial(null);
1190 nameToBeFilled
.setInfraGenericEpithet(null);
1191 nameToBeFilled
.setSpecificEpithet(null);
1192 nameToBeFilled
.setInfraSpecificEpithet(null);
1194 nameToBeFilled
.setNomenclaturalMicroReference(null);
1195 nameToBeFilled
.setNomenclaturalReference(null);
1197 nameToBeFilled
.setHybridFormula(false);
1198 nameToBeFilled
.setMonomHybrid(false);
1199 nameToBeFilled
.setBinomHybrid(false);
1200 nameToBeFilled
.setTrinomHybrid(false);
1202 if (nameToBeFilled
.isInstanceOf(BotanicalName
.class)){
1203 BotanicalName botanicalName
= (BotanicalName
)nameToBeFilled
;
1204 botanicalName
.setAnamorphic(false);
1207 if (nameToBeFilled
.isInstanceOf(ZoologicalName
.class)){
1208 ZoologicalName zoologicalName
= (ZoologicalName
)nameToBeFilled
;
1209 zoologicalName
.setBreed(null);
1210 zoologicalName
.setOriginalPublicationYear(null);