2 * Copyright (C) 2007 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.
10 package eu
.etaxonomy
.cdm
.model
.description
;
12 import java
.text
.ParseException
;
13 import java
.util
.HashMap
;
14 import java
.util
.List
;
16 import java
.util
.UUID
;
18 import javax
.persistence
.Entity
;
19 import javax
.xml
.bind
.annotation
.XmlAccessType
;
20 import javax
.xml
.bind
.annotation
.XmlAccessorType
;
21 import javax
.xml
.bind
.annotation
.XmlAttribute
;
22 import javax
.xml
.bind
.annotation
.XmlRootElement
;
23 import javax
.xml
.bind
.annotation
.XmlType
;
25 import org
.apache
.commons
.lang
.StringUtils
;
26 import org
.apache
.log4j
.Logger
;
27 import org
.hibernate
.envers
.Audited
;
29 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
30 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTermBase
;
31 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
32 import eu
.etaxonomy
.cdm
.model
.common
.OrderedTermBase
;
33 import eu
.etaxonomy
.cdm
.model
.common
.TermType
;
34 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
35 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
36 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
40 * This class represents terms describing the {@link AbsenceTerm absence}
41 * (like "extinct") or the {@link PresenceTerm presence} (like "cultivated") of a
42 * {@link Taxon taxon} in an {@link NamedArea area}. These terms are only
43 * used for {@link Distribution distributions}.
45 * The current implementation includes multiple qualities of distribution status:<BR><BR>
47 * 1. Degree of "presence": present, presence questionable, reported in error, absent, ...<BR>
48 * 2. Nativeness/naturalization/...: native, alien (introduced), naturalized, cultivated, invasive, ... <BR>
50 * There might be further qualities like adventive(unwanted)<->introduced(wanted - for cultivation)
52 * For an interesting discussion of these status see Pyšek & al.: Alien plants in checklists and floras;
53 * Taxon 53(1), Feb. 2004: 131-143 <BR>
55 * Pyšek et al. distinguises<BR>
57 * alien => cultivated-outside cultivation<BR>
58 * outside cultivation=>casual - naturalized<BR>
59 * naturalized => non invasive - invasive<BR>
60 * invasive => not harmful - transformers - weeds
62 * @see http://dev.e-taxonomy.eu/redmine/issues/6000
65 * @created 08-Nov-2007 13:06:44
68 @XmlAccessorType(XmlAccessType
.FIELD
)
69 @XmlType(name
= "PresenceAbsenceTerm")
70 @XmlRootElement(name
= "PresenceAbsenceTerm")
72 //@Indexed disabled to reduce clutter in indexes, since this type is not used by any search
73 //@Indexed(index = "eu.etaxonomy.cdm.model.common.DefinedTermBase")
75 public class PresenceAbsenceTerm
extends OrderedTermBase
<PresenceAbsenceTerm
> {
76 private static final long serialVersionUID
= 1036807546935584396L;
77 private static final Logger logger
= Logger
.getLogger(PresenceAbsenceTerm
.class);
81 private static final UUID uuidP
=UUID
.fromString("cef81d25-501c-48d8-bbea-542ec50de2c2");
82 private static final UUID uuidPD
=UUID
.fromString("75a60279-a4c2-4f53-bc57-466028a4b3db");
85 private static final UUID uuidN
=UUID
.fromString("ddeac4f2-d8fa-43b8-ad7e-ca13abdd32c7");
86 private static final UUID uuidND
=UUID
.fromString("310373bf-7df4-4d02-8cb3-bcc7448805fc");
87 private static final UUID uuidC
=UUID
.fromString("9eb99fe6-59e2-4445-8e6a-478365bd0fa9");
88 private static final UUID uuidI
=UUID
.fromString("643cf9d1-a5f1-4622-9837-82ef961e880b");
89 private static final UUID uuidID
=UUID
.fromString("0c54761e-4887-4788-9dfa-7190c88746e3");
90 private static final UUID uuidIP
=UUID
.fromString("da159544-b0dd-4599-a9c9-640826af8c17");
91 private static final UUID uuidIA
=UUID
.fromString("42946bd6-9c22-45ad-a910-7427e8f60bfd");
92 private static final UUID uuidIN
=UUID
.fromString("e191e89a-a751-4b0c-b883-7f1de70915c9");
93 private static final UUID uuidIC
=UUID
.fromString("fac8c347-8262-44a1-b0a4-db4de451c021");
94 private static final UUID uuidE
=UUID
.fromString("c3ee7048-15b7-4be1-b687-9ce9c1a669d6");
95 //was merged int uuidIN
96 // private static final UUID uuidNa=UUID.fromString("4e04990a-66fe-4fdf-856c-f40772fbcf0a");
97 private static final UUID uuidIV
=UUID
.fromString("dc536e3d-a753-4bbe-a386-dd8aff35c234");
100 private static final UUID uuidNQ
=UUID
.fromString("925662c1-bb10-459a-8c53-da5a738ac770");
101 private static final UUID uuidCQ
=UUID
.fromString("4f31bfc8-3058-4d83-aea5-3a1fe9773f9f");
102 private static final UUID uuidIQ
=UUID
.fromString("83eb0aa0-1a45-495a-a3ca-bf6958b74366");
103 private static final UUID uuidEQ
=UUID
.fromString("5f954f08-267a-4928-b073-12328f74c187");
104 // private static final UUID uuidNDQ=UUID.fromString("7ddfd94d-01a4-496c-a6d6-18584c00af59");
107 private static final UUID uuidAbsence
=UUID
.fromString("59709861-f7d9-41f9-bb21-92559cedd598");
108 private static final UUID uuidReportedInError
= UUID
.fromString("38604788-cf05-4607-b155-86db456f7680");
110 private static final UUID uuidNF
=UUID
.fromString("61cee840-801e-41d8-bead-015ad866c2f1");
111 private static final UUID uuidIF
=UUID
.fromString("aeec2947-2700-4623-8e32-9e3a430569d1");
112 private static final UUID uuidCF
=UUID
.fromString("9d4d3431-177a-4abe-8e4b-1558573169d6");
113 private static final UUID uuidNE
=UUID
.fromString("5c397f7b-59ef-4c11-a33c-45691ceda91b");
114 private static final UUID uuidNDE
=UUID
.fromString("71b72e24-c2b6-44a5-bdab-39f083bf0f06");
115 private static final UUID uuidIE
=UUID
.fromString("b74dc30b-ee93-496d-8c00-4d00abae1ec7");
116 private static final UUID uuidEE
=UUID
.fromString("679b215d-c231-4ee2-ae12-3ffc3dd528ad");
117 private static final UUID uuidNaE
=UUID
.fromString("8d918a37-3add-4e1c-a233-c37dbee209aa");
120 protected static Map
<UUID
, PresenceAbsenceTerm
> termMap
= null;
122 private String defaultColor
= "000000";
124 @XmlAttribute(name
= "absenceTerm")
125 private boolean absenceTerm
= false;
127 //********* METHODS **************************************/
129 * Creates a new empty presence term.
131 * @see #NewInstance(String, String, String)
133 public static PresenceAbsenceTerm
NewInstance(){
134 return new PresenceAbsenceTerm();
138 * Creates a new presence term with a description (in the {@link Language#DEFAULT() default language}),
139 * a label and a label abbreviation.
141 * @param term the string (in the default language) describing the
142 * new presence term to be created
143 * @param label the string identifying the new presence term to be created
144 * @param labelAbbrev the string identifying (in abbreviated form) the
145 * new presence term to be created
146 * @see #NewInstance()
148 public static PresenceAbsenceTerm
NewPresenceInstance(String term
, String label
, String labelAbbrev
){
149 return new PresenceAbsenceTerm(term
, label
, labelAbbrev
, false);
153 * Creates a new absence term with a description (in the {@link Language#DEFAULT() default language}),
154 * a label and a label abbreviation.
156 * @param term the string (in the default language) describing the
157 * new presence term to be created
158 * @param label the string identifying the new presence term to be created
159 * @param labelAbbrev the string identifying (in abbreviated form) the
160 * new presence term to be created
161 * @see #NewInstance()
163 public static PresenceAbsenceTerm
NewAbsenceInstance(String term
, String label
, String labelAbbrev
){
164 return new PresenceAbsenceTerm(term
, label
, labelAbbrev
, true);
168 //********************************** Constructor *******************************************************************/
170 //for hibernate use only
172 protected PresenceAbsenceTerm() {
173 super(TermType
.PresenceAbsenceTerm
);
177 * Class constructor: creates a new presence or absence term with a description
178 * (in the {@link Language#DEFAULT() default language}), a label and a label abbreviation.
180 * @param term the string (in the default language) describing the
181 * new presence or absence term to be created
182 * @param label the string identifying the new presence or absence term to be created
183 * @param labelAbbrev the string identifying (in abbreviated form) the
184 * new presence or absence term to be created
185 * @param isAbsenceTerm boolean value indicating if this term represents an absence or not
186 * @see #PresenceAbsenceTermBase()
188 protected PresenceAbsenceTerm(String term
, String label
, String labelAbbrev
, boolean isAbsenceTerm
) {
189 super(TermType
.PresenceAbsenceTerm
, term
, label
, labelAbbrev
);
190 this.setAbsenceTerm(isAbsenceTerm
);
194 //******************************* STATIC METHODS *****************************************
196 protected static PresenceAbsenceTerm
getTermByUuid(UUID uuid
){
197 if (termMap
== null || termMap
.isEmpty()){
198 return getTermByClassAndUUID(PresenceAbsenceTerm
.class, uuid
);
200 return termMap
.get(uuid
);
204 //TODO read from label(abbrevs) like in TDWGArea
205 public static PresenceAbsenceTerm
getPresenceAbsenceTermByAbbreviation(String abbrev
) {
206 if (abbrev
== null) { throw new NullPointerException("abbrev is 'null' in getPresenceTermByAbbreviation");
207 } else if (abbrev
.equalsIgnoreCase("c")) { return PresenceAbsenceTerm
.CULTIVATED();
208 } else if (abbrev
.equalsIgnoreCase("e")) { return PresenceAbsenceTerm
.ENDEMIC_FOR_THE_RELEVANT_AREA();
209 } else if (abbrev
.equalsIgnoreCase("i")) { return PresenceAbsenceTerm
.INTRODUCED();
210 } else if (abbrev
.equalsIgnoreCase("ia")) { return PresenceAbsenceTerm
.INTRODUCED_ADVENTITIOUS();
211 } else if (abbrev
.equalsIgnoreCase("ic")) { return PresenceAbsenceTerm
.INTRODUCED_CULTIVATED();
212 } else if (abbrev
.equalsIgnoreCase("id")) { return PresenceAbsenceTerm
.INTRODUCED_DOUBTFULLY_INTRODUCED();
213 } else if (abbrev
.equalsIgnoreCase("in")) { return PresenceAbsenceTerm
.NATURALISED();
214 } else if (abbrev
.equalsIgnoreCase("ip")) { return PresenceAbsenceTerm
.INTRODUCED_UNCERTAIN_DEGREE_OF_NATURALISATION();
215 } else if (abbrev
.equalsIgnoreCase("iq")) { return PresenceAbsenceTerm
.INTRODUCED_PRESENCE_QUESTIONABLE();
216 } else if (abbrev
.equalsIgnoreCase("n")) { return PresenceAbsenceTerm
.NATIVE();
217 } else if (abbrev
.equalsIgnoreCase("nd")) { return PresenceAbsenceTerm
.NATIVE_DOUBTFULLY_NATIVE();
218 } else if (abbrev
.equalsIgnoreCase("nq")) { return PresenceAbsenceTerm
.NATIVE_PRESENCE_QUESTIONABLE();
219 } else if (abbrev
.equalsIgnoreCase("p")) { return PresenceAbsenceTerm
.PRESENT();
220 } else if (abbrev
.equalsIgnoreCase("na")) { return PresenceAbsenceTerm
.NATURALISED();
221 } else if (abbrev
.equalsIgnoreCase("iv")) { return PresenceAbsenceTerm
.INVASIVE();
223 } else if (abbrev
.equalsIgnoreCase("cf")) { return PresenceAbsenceTerm
.CULTIVATED_REPORTED_IN_ERROR();
224 } else if (abbrev
.equalsIgnoreCase("if")) { return PresenceAbsenceTerm
.INTRODUCED_REPORTED_IN_ERROR();
225 } else if (abbrev
.equalsIgnoreCase("nf")) { return PresenceAbsenceTerm
.NATIVE_REPORTED_IN_ERROR();
226 } else if (abbrev
.equalsIgnoreCase("ne")) { return PresenceAbsenceTerm
.NATIVE_FORMERLY_NATIVE();
227 } else if (abbrev
.equalsIgnoreCase("ie")) { return PresenceAbsenceTerm
.INTRODUCED_FORMERLY_INTRODUCED();
229 logger
.warn("Unknown presence or absence status term abbreviation: " + abbrev
);
235 * The taxon is endemic for the given area.
238 * @see #ENDEMIC_DOUBTFULLY_PRESENT()
239 * @see #ENDEMIC_REPORTED_IN_ERROR()
241 public static final PresenceAbsenceTerm
ENDEMIC_FOR_THE_RELEVANT_AREA(){
242 return getTermByUuid(uuidE
);
246 * The taxon is endemic for the given area but doubtfully present.
247 * @see #ENDEMIC_FOR_THE_RELEVANT_AREA()
248 * @see #ENDEMIC_REPORTED_IN_ERROR()
249 * @see #PRESENT_DOUBTFULLY()
250 * @see #NATIVE_PRESENCE_QUESTIONABLE()
252 public static final PresenceAbsenceTerm
ENDEMIC_DOUBTFULLY_PRESENT(){
253 return getTermByUuid(uuidEQ
);
257 * The taxon if it exists is endemic for the given area but was only
258 * erroneously reported.
259 * So it either does not exist or it is unclear where it was originally found.
260 * @see #ENDEMIC_FOR_THE_RELEVANT_AREA()
261 * @see #ENDEMIC_DOUBTFULLY_PRESENT()
262 * @see #REPORTED_IN_ERROR()
263 * @see #NATIVE_REPORTED_IN_ERROR()
265 public static final PresenceAbsenceTerm
ENDEMIC_REPORTED_IN_ERROR(){
266 return getTermByUuid(uuidEE
);
271 * The taxon is present in the given area. No information given about
272 * nativeness/establishment means.
274 * @see #PRESENT_DOUBTFULLY()
277 public static final PresenceAbsenceTerm
PRESENT(){
278 return getTermByUuid(uuidP
);
282 * Presence of the taxon in the given area is doubtful. No information given about
283 * nativeness/establishment means.
288 public static final PresenceAbsenceTerm
PRESENT_DOUBTFULLY(){
289 return getTermByUuid(uuidPD
);
293 * The taxon is not native but cultivated.
295 * @see #CULTIVATED_PRESENCE_QUESTIONABLE()
296 * @see #CULTIVATED_REPORTED_IN_ERROR()
298 public static final PresenceAbsenceTerm
CULTIVATED(){
299 return getTermByUuid(uuidC
);
303 * The taxon is cultivated but presence is questionable.
306 * @see #CULTIVATED_REPORTED_IN_ERROR()
308 public static final PresenceAbsenceTerm
CULTIVATED_PRESENCE_QUESTIONABLE(){
309 return getTermByUuid(uuidCQ
);
313 * The taxon is erroneously reported as cultivated.
316 * @see #CULTIVATED_REPORTED_IN_ERROR()
318 public static final PresenceAbsenceTerm
CULTIVATED_REPORTED_IN_ERROR(){
319 return getTermByUuid(uuidCF
);
323 public static final PresenceAbsenceTerm
INTRODUCED(){
324 return getTermByUuid(uuidI
);
328 * This term is of questional value. Introduced often is handled as opposite
329 * of adventitious/adventive and describes how the alien species came
330 * - on purpose for cultivation (introduced) or not (adventive).
331 * Adventitious or better adventive is often a synonym for casual which might
332 * be the better term here.
335 public static final PresenceAbsenceTerm
INTRODUCED_ADVENTITIOUS(){
336 return getTermByUuid(uuidIA
);
339 public static final PresenceAbsenceTerm
INTRODUCED_CULTIVATED(){
340 return getTermByUuid(uuidIC
);
343 public static final PresenceAbsenceTerm
INTRODUCED_DOUBTFULLY_INTRODUCED(){
344 return getTermByUuid(uuidID
);
349 * @see #NATURALISED()
351 public static final PresenceAbsenceTerm
NATURALISED(){
352 return getTermByUuid(uuidIN
);
355 public static final PresenceAbsenceTerm
INTRODUCED_UNCERTAIN_DEGREE_OF_NATURALISATION(){
356 return getTermByUuid(uuidIP
);
359 public static final PresenceAbsenceTerm
INTRODUCED_PRESENCE_QUESTIONABLE(){
360 return getTermByUuid(uuidIQ
);
363 public static final PresenceAbsenceTerm
INTRODUCED_FORMERLY_INTRODUCED(){
364 return getTermByUuid(uuidIE
);
367 public static final PresenceAbsenceTerm
INTRODUCED_REPORTED_IN_ERROR(){
368 return getTermByUuid(uuidIF
);
372 * Use native if the taxon is native in the according area. Native and indigenous
373 * have the same meaning. Native might be problematic because the abbreviation
374 * N is already used for naturalised.
376 * @see #NATIVE_DOUBTFULLY_NATIVE()
377 * @see #NATIVE_PRESENCE_QUESTIONABLE()
378 * @see #NATIVE_REPORTED_IN_ERROR()
380 public static final PresenceAbsenceTerm
NATIVE(){
381 return getTermByUuid(uuidN
);
385 * Same as {@link #NATIVE()} but presence is questionable
387 * @see #NATIVE_DOUBTFULLY_NATIVE()
388 * @see #NATIVE_REPORTED_IN_ERROR()
390 public static final PresenceAbsenceTerm
NATIVE_PRESENCE_QUESTIONABLE(){
391 return getTermByUuid(uuidNQ
);
395 * The taxon was formerly native, but is extinct now in the given area.
400 public static final PresenceAbsenceTerm
NATIVE_FORMERLY_NATIVE(){
401 return getTermByUuid(uuidNE
);
405 * Same as {@link #NATIVE()} but presence was reported in error, so
406 * finally it is not native.
408 * @see #NATIVE_PRESENCE_QUESTIONABLE()
409 * @see #NATIVE_DOUBTFULLY_NATIVE()
411 public static final PresenceAbsenceTerm
NATIVE_REPORTED_IN_ERROR(){
412 return getTermByUuid(uuidNF
);
416 * Same as {@link #NATIVE()} but the nativeness is doubtful, while presence
417 * is NOT questionable
419 * @see #NATIVE_PRESENCE_QUESTIONABLE()
420 * @see #NATIVE_REPORTED_IN_ERROR()
422 public static final PresenceAbsenceTerm
NATIVE_DOUBTFULLY_NATIVE(){
423 return getTermByUuid(uuidND
);
427 * Same as {@link #NATIVE()} but the nativeness is doubtful, while presence
428 * is NOT questionable
429 * @see #NATIVE_DOUBTFULLY_NATIVE()
431 * @see #NATIVE_PRESENCE_QUESTIONABLE()
433 public static final PresenceAbsenceTerm
NATIVE_DOUBTFULLY_NATIVE_REPORTED_IN_ERROR(){
434 return getTermByUuid(uuidNDE
);
437 public static final PresenceAbsenceTerm
NATURALISED_REPORTED_IN_ERROR(){
438 return getTermByUuid(uuidNaE
);
442 * The taxon is present but not native in the given area.
443 * Additionally it is dangerous for the native species.
447 public static final PresenceAbsenceTerm
INVASIVE(){
448 return getTermByUuid(uuidIV
);
453 * @see #REPORTED_IN_ERROR()
455 public static final PresenceAbsenceTerm
ABSENT(){
456 return getTermByUuid(uuidAbsence
);
460 * The taxon is {@link #ABSENT() absent} in the given area
461 * but was erroneously reported as present.
464 * @see #NATIVE_REPORTED_IN_ERROR()
465 * @see #INTRODUCED_REPORTED_IN_ERROR()
467 public static final PresenceAbsenceTerm
REPORTED_IN_ERROR(){
468 return getTermByUuid(uuidReportedInError
);
472 //******************************** METHODS ****************************/
475 public void resetTerms(){
480 protected void setDefaultTerms(TermVocabulary
<PresenceAbsenceTerm
> termVocabulary
) {
481 termMap
= new HashMap
<UUID
, PresenceAbsenceTerm
>();
482 for (PresenceAbsenceTerm term
: termVocabulary
.getTerms()){
483 termMap
.put(term
.getUuid(), term
);
488 public PresenceAbsenceTerm
readCsvLine(Class
<PresenceAbsenceTerm
> termClass
, List
<String
> csvLine
, Map
<UUID
,DefinedTermBase
> terms
, boolean abbrevAsId
){
489 PresenceAbsenceTerm newInstance
= super.readCsvLine(termClass
, csvLine
, terms
, abbrevAsId
);
490 String abbreviatedLabel
= csvLine
.get(4);
491 // String uuid = (String)csvLine.get(0);
492 // map.put(abbreviatedLabel, UUID.fromString(uuid));
493 String symbol
= csvLine
.get(5);
494 newInstance
.setSymbol(symbol
);
495 String color
= csvLine
.get(6);
497 newInstance
.setDefaultColor(color
);
498 } catch (ParseException e
) {
499 throw new RuntimeException(e
);
501 boolean isAbsence
= csvLine
.get(7).equals("1") ?
true : false;
502 newInstance
.setAbsenceTerm(isAbsence
);
504 newInstance
.getRepresentation(Language
.DEFAULT()).setAbbreviatedLabel(abbreviatedLabel
);
509 * @return the defaultColor
511 public String
getDefaultColor() {
516 * @param defaultColor the defaultColor to set
517 * @throws ParseException
519 //TODO make format checking a hibernate validation rule
520 public void setDefaultColor(String defaultColor
) throws ParseException
{
521 String regEx
= "[0-9a-fA-F]{6}";
522 if (StringUtils
.isEmpty(defaultColor
)){
523 this.defaultColor
= null;
524 }else if (StringUtils
.isEmpty(defaultColor
) || defaultColor
.matches(regEx
)){
525 this.defaultColor
= defaultColor
;
527 throw new java
.text
.ParseException("Default color is not of correct format. Required is 'FFFFFF'", -1);
532 * Compares this OrderedTermBase with the specified OrderedTermBase for
533 * order. Returns a -1, 0, or +1 if the orderId of this object is greater
534 * than, equal to, or less than the specified object.
536 * <b>Note:</b> The compare logic of this method is the <b>inverse logic</b>
537 * of the the one implemented in
538 * {@link java.lang.Comparable#compareTo(java.lang.Object)}
541 * the OrderedTermBase to be compared
542 * @param skipVocabularyCheck
543 * whether to skip checking if both terms to compare are in the
545 * @throws NullPointerException
546 * if the specified object is null
549 protected int performCompareTo(PresenceAbsenceTerm presenceAbsenceTerm
, boolean skipVocabularyCheck
) {
551 PresenceAbsenceTerm presenceAbsenceTermLocal
= CdmBase
.deproxy(presenceAbsenceTerm
, PresenceAbsenceTerm
.class);
552 if(! skipVocabularyCheck
){
553 if (this.vocabulary
== null || presenceAbsenceTermLocal
.vocabulary
== null){
554 throw new IllegalStateException("An ordered term (" + this.toString() + " or " +
555 presenceAbsenceTermLocal
.toString() + ") of class " + this.getClass() + " or " +
556 presenceAbsenceTermLocal
.getClass() + " does not belong to a vocabulary and therefore "
557 + "can not be compared");
559 if (presenceAbsenceTermLocal
.isAbsenceTerm() != this.isAbsenceTerm() ){
560 if (presenceAbsenceTermLocal
.isAbsenceTerm()){
572 orderThat
= presenceAbsenceTermLocal
.orderIndex
;//OLD: this.getVocabulary().getTerms().indexOf(orderedTerm);
573 orderThis
= orderIndex
; //OLD: this.getVocabulary().getTerms().indexOf(this);
574 } catch (RuntimeException e
) {
577 if (orderThis
> orderThat
){
579 }else if (orderThis
< orderThat
){
587 public boolean isAbsenceTerm() {
591 public void setAbsenceTerm(boolean isAbsenceTerm
) {
592 this.absenceTerm
= isAbsenceTerm
;