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
.location
;
13 import java
.util
.ArrayList
;
14 import java
.util
.HashMap
;
15 import java
.util
.HashSet
;
16 import java
.util
.List
;
19 import java
.util
.UUID
;
21 import javax
.persistence
.Entity
;
22 import javax
.persistence
.FetchType
;
23 import javax
.persistence
.JoinTable
;
24 import javax
.persistence
.ManyToMany
;
25 import javax
.persistence
.ManyToOne
;
26 import javax
.persistence
.Transient
;
27 import javax
.xml
.bind
.annotation
.XmlAccessType
;
28 import javax
.xml
.bind
.annotation
.XmlAccessorType
;
29 import javax
.xml
.bind
.annotation
.XmlElement
;
30 import javax
.xml
.bind
.annotation
.XmlElementWrapper
;
31 import javax
.xml
.bind
.annotation
.XmlIDREF
;
32 import javax
.xml
.bind
.annotation
.XmlRootElement
;
33 import javax
.xml
.bind
.annotation
.XmlSchemaType
;
34 import javax
.xml
.bind
.annotation
.XmlSeeAlso
;
35 import javax
.xml
.bind
.annotation
.XmlType
;
37 import org
.apache
.commons
.lang
.StringUtils
;
38 import org
.apache
.log4j
.Logger
;
39 import org
.hibernate
.annotations
.Cascade
;
40 import org
.hibernate
.annotations
.CascadeType
;
41 import org
.hibernate
.envers
.Audited
;
42 import org
.hibernate
.search
.annotations
.ClassBridge
;
43 import org
.hibernate
.search
.annotations
.Indexed
;
44 import org
.hibernate
.search
.annotations
.Parameter
;
46 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
47 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
48 import eu
.etaxonomy
.cdm
.hibernate
.search
.DefinedTermBaseClassBridge
;
49 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
50 import eu
.etaxonomy
.cdm
.model
.common
.DefaultTermInitializer
;
51 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTermBase
;
52 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
53 import eu
.etaxonomy
.cdm
.model
.common
.OrderedTermBase
;
54 import eu
.etaxonomy
.cdm
.model
.common
.Representation
;
55 import eu
.etaxonomy
.cdm
.model
.common
.TermType
;
56 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
57 import eu
.etaxonomy
.cdm
.model
.common
.TimePeriod
;
58 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
62 * @created 08-Nov-2007 13:06:36
64 @XmlAccessorType(XmlAccessType
.PROPERTY
)
65 @XmlType(name
= "NamedArea", propOrder
= {
77 @XmlRootElement(name
= "NamedArea")
82 @Indexed(index
= "eu.etaxonomy.cdm.model.common.DefinedTermBase")
84 @ClassBridge(impl
=DefinedTermBaseClassBridge
.class, params
={
85 @Parameter(name
="includeParentTerms", value
="true")
87 public class NamedArea
extends OrderedTermBase
<NamedArea
> implements Cloneable
{
88 private static final long serialVersionUID
= 6248434369557403036L;
89 private static final Logger logger
= Logger
.getLogger(NamedArea
.class);
93 private static final UUID uuidEurope
= UUID
.fromString("3b69f979-408c-4080-b573-0ad78a315610");
94 private static final UUID uuidAfrica
= UUID
.fromString("c204c529-d8d2-458f-b939-96f0ebd2cbe8");
95 private static final UUID uuidAsiaTemperate
= UUID
.fromString("7f4f4f89-3b4c-475d-929f-144109bd8457");
96 private static final UUID uuidAsiaTropical
= UUID
.fromString("f8039275-d2c0-4753-a1ab-0336642a1499");
97 private static final UUID uuidNAmerica
= UUID
.fromString("81d8aca3-ddd7-4537-9f2b-5327c95b6e28");
98 private static final UUID uuidSAmerica
= UUID
.fromString("12b861c9-c922-498c-8b1a-62afc26d19e3");
99 private static final UUID uuidAustralasia
= UUID
.fromString("a2afdb9a-04a0-434c-9e75-d07dbeb86526");
100 private static final UUID uuidPacific
= UUID
.fromString("c57adcff-5213-45f0-a5f0-97a9f5c0f1fe");
101 private static final UUID uuidAntarctica
= UUID
.fromString("71fd9ab7-9b07-4eb6-8e54-c519aff56728");
104 public static final UUID uuidTdwgAreaVocabulary
= UUID
.fromString("1fb40504-d1d7-44b0-9731-374fbe6cac77");
105 public static final UUID uuidContinentVocabulary
= UUID
.fromString("e72cbcb6-58f8-4201-9774-15d0c6abc128");
106 public static final UUID uuidWaterbodyVocabulary
= UUID
.fromString("35a62b25-f541-4f12-a7c7-17d90dec3e03");
109 private static final UUID uuidArcticOcean
= UUID
.fromString("af4271e5-8897-4e6f-9db7-54ea4f28cfc0");
110 private static final UUID uuidAtlanticOcean
= UUID
.fromString("77e79804-1b17-4c99-873b-933fe216e3da");
111 private static final UUID uuidPacificOcean
= UUID
.fromString("3d68a327-104c-49d5-a2d8-c71c6600181b");
112 private static final UUID uuidIndianOcean
= UUID
.fromString("ff744a37-5990-462c-9c20-1e85a9943851");
113 private static final UUID uuidSouthernOcean
= UUID
.fromString("ef04f363-f67f-4a2c-8d98-110de4c5f654");
114 private static final UUID uuidMediterraneanSea
= UUID
.fromString("8811a47e-29d6-4455-8f83-8916b78a692f");
115 private static final UUID uuidBlackSea
= UUID
.fromString("4cb4bbae-9aab-426c-9025-e34f809165af");
116 private static final UUID uuidCaspianSea
= UUID
.fromString("598fec0e-b93a-4947-a1f3-601e380797f7");
117 private static final UUID uuidRedSea
= UUID
.fromString("ee69385e-6c80-405c-be6e-974e9fd1e297");
118 private static final UUID uuidPersianGulf
= UUID
.fromString("8dc16e70-74b8-4143-95cf-a659a319a854");
122 private static Map
<String
, UUID
> tdwgAbbrevMap
= null;
123 private static Map
<String
, UUID
> tdwglabelMap
= null;
125 private static Map
<UUID
, NamedArea
> tdwgTermMap
= null;
126 private static Map
<UUID
, NamedArea
> continentMap
= null;
127 private static Map
<UUID
, NamedArea
> waterbodyMap
= null;
130 private static Map
<UUID
, NamedArea
> termMap
= null;
132 public static final NamedArea
ARCTICOCEAN () { return waterbodyMap
.get(uuidArcticOcean
);}
133 public static final NamedArea
ATLANTICOCEAN () { return waterbodyMap
.get(uuidAtlanticOcean
);}
134 public static final NamedArea
PACIFICOCEAN () { return waterbodyMap
.get(uuidPacificOcean
);}
135 public static final NamedArea
INDIANOCEAN () { return waterbodyMap
.get(uuidIndianOcean
);}
136 public static final NamedArea
SOUTHERNOCEAN () { return waterbodyMap
.get(uuidSouthernOcean
);}
137 public static final NamedArea
MEDITERRANEANSEA () { return waterbodyMap
.get(uuidMediterraneanSea
);}
138 public static final NamedArea
BLACKSEA () { return waterbodyMap
.get(uuidBlackSea
);}
139 public static final NamedArea
CASPIANSEA () { return waterbodyMap
.get(uuidCaspianSea
);}
140 public static final NamedArea
REDSEA () { return waterbodyMap
.get(uuidRedSea
);}
141 public static final NamedArea
PERSIANGULF () { return waterbodyMap
.get(uuidPersianGulf
);}
144 //************************* FACTORY METHODS ****************************************/
150 public static NamedArea
NewInstance(){
151 return new NamedArea();
158 public static NamedArea
NewInstance(String term
, String label
, String labelAbbrev
){
159 return new NamedArea(term
, label
, labelAbbrev
);
162 //**************************** VARIABLES *******************************/
164 //description of time valid context of this area. e.g. year range
165 private TimePeriod validPeriod
= TimePeriod
.NewInstance();
167 //Binary shape definition for user's defined area as polygon
168 @ManyToOne(fetch
= FetchType
.LAZY
)
169 @Cascade(CascadeType
.SAVE_UPDATE
)
172 private Point pointApproximation
;
174 @ManyToMany(fetch
= FetchType
.LAZY
)
175 @JoinTable(name
="DefinedTermBase_Country")
176 private final Set
<Country
> countries
= new HashSet
<Country
>();
178 @ManyToOne(fetch
= FetchType
.LAZY
)
179 private NamedAreaType type
;
181 @ManyToOne(fetch
= FetchType
.LAZY
)
182 private NamedAreaLevel level
;
185 //********************************** Constructor *******************************************************************/
187 //for hibernate use only
189 protected NamedArea() {
190 super(TermType
.NamedArea
);
193 protected NamedArea(String term
, String label
, String labelAbbrev
) {
194 super(TermType
.NamedArea
, term
, label
, labelAbbrev
);
197 //********************************* GETTER /SETTER *********************************************/
199 @XmlElement(name
= "NamedAreaType")
201 @XmlSchemaType(name
= "IDREF")
202 public NamedAreaType
getType(){
206 public void setType(NamedAreaType type
){
210 @XmlElement(name
= "NamedAreaLevel")
212 @XmlSchemaType(name
= "IDREF")
213 public NamedAreaLevel
getLevel(){
217 public void setLevel(NamedAreaLevel level
){
221 @XmlElement(name
= "ValidPeriod")
222 public TimePeriod
getValidPeriod(){
223 return this.validPeriod
;
226 public void setValidPeriod(TimePeriod validPeriod
){
227 this.validPeriod
= validPeriod
;
230 @XmlElement(name
= "Shape")
232 @XmlSchemaType(name
= "IDREF")
233 public Media
getShape(){
236 public void setShape(Media shape
){
240 @XmlElementWrapper(name
= "Countries")
241 @XmlElement(name
= "Country")
243 @XmlSchemaType(name
= "IDREF")
244 public Set
<Country
> getCountries() {
248 public void addCountry(Country country
) {
249 this.countries
.add(country
);
252 public void removeCountry(Country country
) {
253 this.countries
.remove(country
);
256 @XmlElement(name
= "PointApproximation")
257 public Point
getPointApproximation() {
258 return pointApproximation
;
260 public void setPointApproximation(Point pointApproximation
) {
261 this.pointApproximation
= pointApproximation
;
265 @XmlElement(name
= "KindOf", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
267 @XmlSchemaType(name
= "IDREF")
268 public NamedArea
getKindOf(){
269 return super.getKindOf();
273 public void setKindOf(NamedArea kindOf
){
274 super.setKindOf(kindOf
);
277 @XmlElement(name
= "PartOf", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
279 @XmlSchemaType(name
= "IDREF")
281 public NamedArea
getPartOf(){
282 return super.getPartOf();
286 * FIXME this method is a workaround for a casting problem in the getPartOf implementation
288 * the partOf instance variable is typically a proxy object of type DefinedTermBase, thus
289 * does not coincide with the return value of NamedArea and a ClassCastException is thrown.
291 * It is not clear why this only occurs in the editor and not in the webservice where the same
292 * method gets called and should lead to the same results.
294 * Seems to be a bigger problem although its origin is buggy behaviour of the javassist implementation.
298 public NamedArea
getPartOfWorkaround(){
299 Object area
= super.getPartOf();
301 if(!(area
instanceof NamedArea
)){
302 area
= HibernateProxyHelper
.deproxy(area
, NamedArea
.class);
305 return (NamedArea
) area
;
309 public void setPartOf(NamedArea partOf
){
310 this.partOf
= partOf
;
314 @XmlElementWrapper(name
= "Generalizations", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
315 @XmlElement(name
= "GeneralizationOf", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
317 @XmlSchemaType(name
= "IDREF")
318 public Set
<NamedArea
> getGeneralizationOf(){
319 return super.getGeneralizationOf();
323 protected void setGeneralizationOf(Set
<NamedArea
> value
){
324 super.setGeneralizationOf(value
);
328 @XmlElementWrapper(name
= "Includes", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
329 @XmlElement(name
= "Include", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
331 @XmlSchemaType(name
= "IDREF")
332 public Set
<NamedArea
> getIncludes(){
333 return super.getIncludes();
337 protected void setIncludes(Set
<NamedArea
> includes
) {
338 super.setIncludes(includes
);
342 public NamedArea
readCsvLine(Class
<NamedArea
> termClass
, List
<String
> csvLine
, Map
<UUID
,DefinedTermBase
> terms
, boolean abbrevAsId
) {
343 NamedArea newInstance
= super.readCsvLine(termClass
, csvLine
, terms
, abbrevAsId
);
345 String levelString
= csvLine
.get(6);
347 if(levelString
!= null && levelString
.length() != 0) {
348 UUID levelUuid
= UUID
.fromString(levelString
);
349 NamedAreaLevel level
= (NamedAreaLevel
)terms
.get(levelUuid
);
350 newInstance
.setLevel(level
);
353 // String partOfString = csvLine.get(7);
355 // if(partOfString != null && partOfString.length() != 0) {
356 // UUID partOfUuid = UUID.fromString(partOfString);
357 // NamedArea partOf = (NamedArea)terms.get(partOfUuid);
358 // partOf.addIncludes(newInstance);
364 protected int partOfCsvLineIndex(){
370 public void resetTerms(){
372 tdwgAbbrevMap
= null;
379 @Deprecated //preliminary, will be removed in future
380 protected static NamedArea
getContinentByUuid(UUID uuid
){
381 if (continentMap
== null){
384 return (NamedArea
)continentMap
.get(uuid
);
388 @Deprecated //preliminary, will be removed in future
389 protected static NamedArea
getWaterbodyByUuid(UUID uuid
){
390 if (waterbodyMap
== null){
393 return (NamedArea
)waterbodyMap
.get(uuid
);
397 @Deprecated //preliminary, will be removed in future
398 protected static NamedArea
getTdwgTermByUuid(UUID uuid
){
399 if (tdwgTermMap
== null){
400 DefaultTermInitializer vocabularyStore
= new DefaultTermInitializer();
401 vocabularyStore
.initialize();
403 return tdwgTermMap
.get(uuid
);
406 @Deprecated //preliminary, will be removed in future
407 public static NamedArea
getAreaByTdwgAbbreviation(String tdwgAbbreviation
){
408 if (tdwgAbbrevMap
== null){
411 UUID uuid
= tdwgAbbrevMap
.get(tdwgAbbreviation
);
413 logger
.info("Unknown TDWG area: " + CdmUtils
.Nz(tdwgAbbreviation
));
416 return NamedArea
.getTdwgTermByUuid(uuid
);
419 @Deprecated //preliminary, will be removed in future
420 public static NamedArea
getAreaByTdwgLabel(String tdwgLabel
){
421 if (tdwglabelMap
== null){
424 tdwgLabel
= tdwgLabel
.toLowerCase();
425 UUID uuid
= tdwglabelMap
.get(tdwgLabel
);
427 logger
.info("Unknown TDWG area: " + CdmUtils
.Nz(tdwgLabel
));
430 return NamedArea
.getTdwgTermByUuid(uuid
);
433 @Deprecated //preliminary, will be removed in future
434 public static boolean isTdwgAreaLabel(String label
){
435 label
= (label
== null?
null : label
.toLowerCase());
436 if (tdwglabelMap
.containsKey(label
)){
443 @Deprecated //preliminary, will be removed in future
444 public static boolean isTdwgAreaAbbreviation(String abbrev
){
445 if (tdwgAbbrevMap
.containsKey(abbrev
)){
452 public static final NamedArea
EUROPE(){
453 return getContinentByUuid(uuidEurope
);
456 public static final NamedArea
AFRICA(){
457 return getContinentByUuid(uuidAfrica
);
460 public static final NamedArea
ASIA_TEMPERATE(){
461 return getContinentByUuid(uuidAsiaTemperate
);
464 public static final NamedArea
ASIA_TROPICAL(){
465 return getContinentByUuid(uuidAsiaTropical
);
468 public static final NamedArea
NORTH_AMERICA(){
469 return getContinentByUuid(uuidNAmerica
);
472 public static final NamedArea
ANTARCTICA(){
473 return getContinentByUuid(uuidAntarctica
);
476 public static final NamedArea
SOUTH_AMERICA(){
477 return getContinentByUuid(uuidSAmerica
);
480 public static final NamedArea
AUSTRALASIA(){
481 return getContinentByUuid(uuidAustralasia
);
484 public static final NamedArea
PACIFIC(){
485 return getContinentByUuid(uuidPacific
);
489 protected void setDefaultContinentTerms(TermVocabulary
<NamedArea
> termVocabulary
) {
490 continentMap
= new HashMap
<UUID
, NamedArea
>();
491 for (NamedArea term
: termVocabulary
.getTerms()){
492 continentMap
.put(term
.getUuid(), (NamedArea
)term
); //TODO casting
496 protected void setDefaultWaterbodyTerms(TermVocabulary
<NamedArea
> termVocabulary
) {
497 waterbodyMap
= new HashMap
<UUID
, NamedArea
>();
498 for (NamedArea term
: termVocabulary
.getTerms()){
499 waterbodyMap
.put(term
.getUuid(), (NamedArea
)term
); //TODO casting
503 protected void setTdwgDefaultTerms(TermVocabulary
<NamedArea
> tdwgTermVocabulary
) {
504 tdwgTermMap
= new HashMap
<UUID
, NamedArea
>();
505 for (NamedArea term
: tdwgTermVocabulary
.getTerms()){
506 tdwgTermMap
.put(term
.getUuid(), term
); //TODO casting
512 protected static void addTdwgArea(NamedArea area
){
514 logger
.warn("tdwg area is null");
517 Language lang
= Language
.DEFAULT();
518 Representation representation
= area
.getRepresentation(lang
);
519 String tdwgAbbrevLabel
= representation
.getAbbreviatedLabel();
520 String tdwgLabel
= representation
.getLabel().toLowerCase();
521 if (tdwgAbbrevLabel
== null){
522 logger
.warn("tdwgLabel = null");
526 if (tdwgAbbrevMap
== null){
527 tdwgAbbrevMap
= new HashMap
<String
, UUID
>();
529 if (tdwglabelMap
== null){
530 tdwglabelMap
= new HashMap
<String
, UUID
>();
533 tdwgAbbrevMap
.put(tdwgAbbrevLabel
, area
.getUuid());
534 tdwglabelMap
.put(tdwgLabel
, area
.getUuid());
536 area
.setType(NamedAreaType
.ADMINISTRATION_AREA());
538 if (tdwgAbbrevLabel
.trim().length()== 1){
539 area
.setLevel(NamedAreaLevel
.TDWG_LEVEL1());
540 }else if (tdwgAbbrevLabel
.trim().length()== 2){
541 area
.setLevel(NamedAreaLevel
.TDWG_LEVEL2());
542 }else if (tdwgAbbrevLabel
.trim().length()== 3){
543 area
.setLevel(NamedAreaLevel
.TDWG_LEVEL3());
544 }else if (tdwgAbbrevLabel
.trim().length()== 6){
545 area
.setLevel(NamedAreaLevel
.TDWG_LEVEL4());
547 logger
.warn("Unknown TDWG Level " + tdwgAbbrevLabel
+ "! Unvalid string length (" + tdwgAbbrevLabel
.length() +")");
551 private static void initTdwgMaps(){
552 tdwglabelMap
= new HashMap
<String
, UUID
>();
553 tdwgAbbrevMap
= new HashMap
<String
, UUID
>();
559 protected void setDefaultTerms(TermVocabulary
<NamedArea
> termVocabulary
) {
560 if (termVocabulary
.getUuid().equals(this.uuidTdwgAreaVocabulary
)){
561 this.setTdwgDefaultTerms(termVocabulary
);
562 }else if (termVocabulary
.getUuid().equals(this.uuidContinentVocabulary
)){
563 this.setDefaultContinentTerms(termVocabulary
);
564 }else if (termVocabulary
.getUuid().equals(this.uuidWaterbodyVocabulary
)){
565 this.setDefaultWaterbodyTerms(termVocabulary
);
567 termMap
= new HashMap
<UUID
, NamedArea
>();
568 for (NamedArea term
: termVocabulary
.getTerms()){
569 termMap
.put(term
.getUuid(), term
);
574 // ************** Hierarchie List ****************************
577 * This method returns a sorted tree structure which sorts areas by it's level and within the same level
578 * alphabetically (TODO to be tested).
579 * The structure returned is a tree with alternating nodes that represent an area and an areaLevel.
580 * This way also areas that have children belonging to different levels can be handled.<BR>
581 * The root node is always an empty area node which holds the list of top level areaLevels.
582 * AreaLevels with no level defined are handled as if they have a separate level (level="null").
584 * There is a somehow similar implementation in {@link eu.etaxonomy.cdm.api.service.DistributionTree}
589 public static NamedAreaNode
getHiearchieList(List
<NamedArea
> areaList
){
590 NamedAreaNode result
= new NamedAreaNode();
591 for (NamedArea area
: areaList
){
592 List
<NamedArea
> areaHierarchie
= area
.getAllLevelList();
593 mergeIntoResult(result
, areaHierarchie
);
599 public static class LevelNode
{
600 NamedAreaLevel level
;
601 List
<NamedAreaNode
> areaList
= new ArrayList
<NamedAreaNode
>();
603 public NamedAreaNode
add(NamedArea area
) {
604 NamedAreaNode node
= new NamedAreaNode();
611 public NamedAreaNode
getNamedAreaNode(NamedArea area
) {
612 for (NamedAreaNode node
: areaList
) {
613 if (node
.area
.equals(area
)) {
620 ///****************** toString ***********************************************/
623 public String
toString() {
624 return toString(false, 0);
626 public String
toString(boolean recursive
, int identation
) {
627 String result
= level
== null?
"" :level
.getTitleCache();
628 if (recursive
== false){
631 int areaSize
= this.areaList
.size();
633 result
= "\n" + StringUtils
.leftPad("", identation
) + result
+ "[";
635 boolean isFirst
= true;
636 for (NamedAreaNode level
: this.areaList
){
642 result
+= level
.toString(recursive
, identation
+1);
654 public static class NamedAreaNode
{
656 List
<LevelNode
> levelList
= new ArrayList
<LevelNode
>();
658 public LevelNode
getLevelNode(NamedAreaLevel level
) {
659 for (LevelNode node
: levelList
) {
660 if (node
.level
!= null && node
.level
.equals(level
)) {
667 public List
<NamedAreaNode
> getList(NamedAreaLevel level
) {
668 LevelNode node
= getLevelNode(level
);
670 return new ArrayList
<NamedAreaNode
>();
672 return node
.areaList
;
676 public boolean contains(NamedAreaLevel level
) {
677 if (getList(level
).size() > 0) {
684 public LevelNode
add(NamedAreaLevel level
) {
685 LevelNode node
= new LevelNode();
692 public String
toString() {
693 return toString(false, 0);
696 public String
toString(boolean recursive
, int identation
) {
699 result
= area
.getTitleCache();
702 int levelSize
= this.levelList
.size();
704 result
= "\n" + StringUtils
.leftPad("", identation
) + result
+ "[";
706 boolean isFirst
= true;
707 for (LevelNode level
: this.levelList
){
713 result
+= level
.toString(recursive
, identation
+1);
721 int levelSize
= this.levelList
.size();
722 return result
+ "[" + levelSize
+ " sublevel(s)]";
727 private static void mergeIntoResult(NamedAreaNode root
, List
<NamedArea
> areaHierarchie
) {
728 if (areaHierarchie
.isEmpty()) {
731 NamedArea highestArea
= areaHierarchie
.get(0);
732 NamedAreaLevel level
= highestArea
.getLevel();
733 NamedAreaNode namedAreaNode
;
734 if (! root
.contains(level
)) {
735 LevelNode node
= root
.add(level
);
736 namedAreaNode
= node
.add(highestArea
);
738 // root.area = highestArea;
740 LevelNode levelNode
= root
.getLevelNode(level
);
741 namedAreaNode
= levelNode
.getNamedAreaNode(highestArea
);
742 if (namedAreaNode
== null) {
743 namedAreaNode
= levelNode
.add(highestArea
);
746 List
<NamedArea
> newList
= areaHierarchie
.subList(1, areaHierarchie
.size());
747 mergeIntoResult(namedAreaNode
, newList
);
752 public List
<NamedArea
> getAllLevelList() {
753 List
<NamedArea
> result
= new ArrayList
<NamedArea
>();
754 NamedArea copyArea
= this;
755 result
.add(copyArea
);
756 while (copyArea
.getPartOf() != null) {
757 copyArea
= copyArea
.getPartOf();
758 result
.add(0, copyArea
);
763 // ******************* toString **********************************/
766 public String
toString(){
767 String result
, label
, level
= "";
769 if (this.level
!= null){
770 level
= this.level
.getLabel();
774 label
= this.getLabel();
775 result
= "[" + level
+ ", " + label
+ "]";
783 * Returns the label of the named area together with the area level label and the abbreviated label.
784 * This is kind of a formatter method which may be moved to a better place in future.
785 * @param namedArea the area
786 * @param language the preferred language
787 * @return null if namedArea == null, the labelWithLevel otherwise
789 public static String
labelWithLevel(NamedArea namedArea
, Language language
) {
790 if (namedArea
== null){
793 NamedArea area
= CdmBase
.deproxy(namedArea
, NamedArea
.class);
795 StringBuilder title
= new StringBuilder();
796 Representation representation
= area
.getPreferredRepresentation(language
);
797 if (representation
!= null){
798 String areaString
= getPreferredAreaLabel(namedArea
, representation
);
800 title
.append(areaString
);
801 if (area
.getLevel() == null){
803 title
.append(area
.getClass().getSimpleName());
806 Representation levelRepresentation
= area
.getLevel().getPreferredRepresentation(language
);
807 String levelString
= getPreferredAreaLabel(area
.getLevel(), levelRepresentation
);
808 title
.append(levelString
);
811 return title
.toString();
816 * @param representation
819 private static String
getPreferredAreaLabel(DefinedTermBase
<?
> definedTerm
, Representation representation
) {
820 String areaString
= null;
821 if (representation
!= null){
822 areaString
= representation
.getLabel();
823 if (StringUtils
.isBlank(areaString
)){
824 areaString
= representation
.getAbbreviatedLabel();
826 if (StringUtils
.isBlank(areaString
)){
827 areaString
= representation
.getText();
830 if (StringUtils
.isBlank(areaString
)){
831 areaString
= definedTerm
== null ?
null : definedTerm
.getTitleCache();
833 if (StringUtils
.isBlank(areaString
)){
834 areaString
= "no title";
839 //*********************************** CLONE *****************************************/
842 * Clones <i>this</i> NamedArea. This is a shortcut that enables to create
843 * a new instance that differs only slightly from <i>this</i> NamedArea by
844 * modifying only some of the attributes.
846 * @see eu.etaxonomy.cdm.model.common.OrderedTermBase#clone()
847 * @see java.lang.Object#clone()
850 public Object
clone() {
853 result
= (NamedArea
)super.clone();
854 //no changes to level, pointApproximation, shape, type, validPeriod and countries