Project

General

Profile

Download (11.7 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy 
4
* http://www.e-taxonomy.eu
5
* 
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.
8
*/
9

    
10
package eu.etaxonomy.cdm.model.location;
11

    
12
import java.util.ArrayList;
13
import java.util.HashMap;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import javax.persistence.Entity;
21
import javax.persistence.FetchType;
22
import javax.persistence.JoinTable;
23
import javax.persistence.ManyToMany;
24
import javax.persistence.ManyToOne;
25
import javax.persistence.Transient;
26
import javax.xml.bind.annotation.XmlAccessType;
27
import javax.xml.bind.annotation.XmlAccessorType;
28
import javax.xml.bind.annotation.XmlElement;
29
import javax.xml.bind.annotation.XmlElementWrapper;
30
import javax.xml.bind.annotation.XmlIDREF;
31
import javax.xml.bind.annotation.XmlRootElement;
32
import javax.xml.bind.annotation.XmlSchemaType;
33
import javax.xml.bind.annotation.XmlSeeAlso;
34
import javax.xml.bind.annotation.XmlType;
35

    
36
import org.apache.log4j.Logger;
37
import org.hibernate.annotations.Cascade;
38
import org.hibernate.annotations.CascadeType;
39
import org.hibernate.envers.Audited;
40
import org.hibernate.search.annotations.Indexed;
41

    
42
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
43
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
44
import eu.etaxonomy.cdm.model.common.OrderedTermBase;
45
import eu.etaxonomy.cdm.model.common.TermVocabulary;
46
import eu.etaxonomy.cdm.model.common.TimePeriod;
47
import eu.etaxonomy.cdm.model.media.Media;
48

    
49
/**
50
 * @author m.doering
51
 * @version 1.0
52
 * @created 08-Nov-2007 13:06:36
53
 */
54
@XmlAccessorType(XmlAccessType.PROPERTY)
55
@XmlType(name = "NamedArea", propOrder = {
56
	"kindOf",
57
	"generalizationOf",
58
	"partOf",
59
	"includes",
60
    "validPeriod",
61
    "shape",
62
    "pointApproximation",
63
    "waterbodiesOrCountries",
64
    "type",
65
    "level"
66
})
67
@XmlRootElement(name = "NamedArea")
68
@XmlSeeAlso({
69
	TdwgArea.class,
70
	Continent.class,
71
	WaterbodyOrCountry.class
72
})
73
@Entity
74
@Indexed(index = "eu.etaxonomy.cdm.model.common.DefinedTermBase")
75
@Audited
76
public class NamedArea extends OrderedTermBase<NamedArea> {
77
	private static final long serialVersionUID = 6248434369557403036L;
78
	private static final Logger logger = Logger.getLogger(NamedArea.class);
79
	
80
	protected static Map<UUID, NamedArea> termMap = null;		
81

    
82
//************************* FACTORY METHODS ****************************************/
83
	
84
	/**
85
	 * Factory method
86
	 * @return
87
	 */
88
	public static NamedArea NewInstance(){
89
		logger.debug("NewInstance");
90
		return new NamedArea();
91
	}
92

    
93
	/**
94
	 * Factory method
95
	 * @return
96
	 */
97
	public static NamedArea NewInstance(String term, String label, String labelAbbrev){
98
		return new NamedArea(term, label, labelAbbrev);
99
	}
100
	
101
//**************************** VARIABLES *******************************/
102
	
103
	//description of time valid context of this area. e.g. year range
104
	private TimePeriod validPeriod = TimePeriod.NewInstance();
105
	
106
	//Binary shape definition for user's defined area as polygon
107
	@ManyToOne(fetch = FetchType.LAZY)
108
	@Cascade(CascadeType.SAVE_UPDATE)
109
	private Media shape;
110
	
111
	private Point pointApproximation;
112
	
113
	@ManyToMany(fetch = FetchType.LAZY)
114
    @JoinTable(name="DefinedTermBase_WaterbodyOrCountry")
115
	private Set<WaterbodyOrCountry> waterbodiesOrCountries = new HashSet<WaterbodyOrCountry>();
116
	
117
	@ManyToOne(fetch = FetchType.LAZY)
118
	private NamedAreaType type;
119
	
120
	@ManyToOne(fetch = FetchType.LAZY)
121
	private NamedAreaLevel level;
122

    
123
//*************************** CONSTRUCTOR ******************************************/
124
	
125
	/**
126
	 * Constructor
127
	 */
128
	public NamedArea() {
129
	}
130
	
131
	public NamedArea(String term, String label, String labelAbbrev) {
132
		super(term, label, labelAbbrev);
133
	}
134
	
135
//********************************* GETTER /SETTER *********************************************/	
136

    
137
	@XmlElement(name = "NamedAreaType")
138
	@XmlIDREF
139
	@XmlSchemaType(name = "IDREF")
140
	public NamedAreaType getType(){
141
		return this.type;
142
	}
143
	
144
	public void setType(NamedAreaType type){
145
		this.type = type;
146
	}
147

    
148
	@XmlElement(name = "NamedAreaLevel")
149
	@XmlIDREF
150
	@XmlSchemaType(name = "IDREF")
151
	public NamedAreaLevel getLevel(){
152
		return this.level;
153
	}
154
	
155
	public void setLevel(NamedAreaLevel level){
156
		this.level = level;
157
	}
158

    
159
	@XmlElement(name = "ValidPeriod")
160
	public TimePeriod getValidPeriod(){
161
		return this.validPeriod;
162
	}
163
	
164
	public void setValidPeriod(TimePeriod validPeriod){
165
		this.validPeriod = validPeriod;
166
	}
167

    
168
	@XmlElement(name = "Shape")
169
	@XmlIDREF
170
	@XmlSchemaType(name = "IDREF")
171
	public Media getShape(){
172
		return this.shape;
173
	}
174
	public void setShape(Media shape){
175
		this.shape = shape;
176
	}
177

    
178
	@XmlElementWrapper(name = "WaterbodiesOrCountries")
179
	@XmlElement(name = "WaterbodiesOrCountry")
180
	@XmlIDREF
181
	@XmlSchemaType(name = "IDREF")
182
	public Set<WaterbodyOrCountry> getWaterbodiesOrCountries() {
183
		return waterbodiesOrCountries;
184
	}
185
	
186
	public void addWaterbodyOrCountry(WaterbodyOrCountry waterbodyOrCountry) {
187
		this.waterbodiesOrCountries.add(waterbodyOrCountry);
188
	}
189
	
190
	public void removeWaterbodyOrCountry(WaterbodyOrCountry waterbodyOrCountry) {
191
		this.waterbodiesOrCountries.remove(waterbodyOrCountry);
192
	}
193
	
194
	@XmlElement(name = "PointApproximation")
195
	public Point getPointApproximation() {
196
		return pointApproximation;
197
	}
198
	public void setPointApproximation(Point pointApproximation) {
199
		this.pointApproximation = pointApproximation;
200
	}
201
	
202
	@XmlElement(name = "KindOf", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
203
    @XmlIDREF
204
    @XmlSchemaType(name = "IDREF")
205
	public NamedArea getKindOf(){
206
		return super.getKindOf();
207
	}
208

    
209
	public void setKindOf(NamedArea kindOf){
210
		super.setKindOf(kindOf);
211
	}
212
	
213
	@XmlElement(name = "PartOf", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
214
	@XmlIDREF
215
    @XmlSchemaType(name = "IDREF")
216
    @Override
217
	public NamedArea getPartOf(){
218
		return super.getPartOf();
219
	}
220
	
221
	/**
222
	 * FIXME this method is a workaround for a casting problem in the getPartOf implementation
223
	 * 
224
	 * the partOf instance variable is typically a proxy object of type DefinedTermBase, thus
225
	 * does not coincide with the return value of NamedArea and a ClassCastException is thrown.
226
	 * 
227
	 * It is not clear why this only occurs in the editor and not in the webservice where the same
228
	 * method gets called and should lead to the same results.
229
	 * 
230
	 * Seems to be a bigger problem although its origin is buggy behaviour of the javassist implementation.
231
	 */
232
	@Deprecated
233
	@Transient
234
	public NamedArea getPartOfWorkaround(){
235
		Object area = super.getPartOf();
236
		
237
		if(!(area instanceof NamedArea)){
238
			area = HibernateProxyHelper.deproxy(area, NamedArea.class);
239
		}
240
		
241
		return (NamedArea) area;
242
	}
243
	
244
	public void setPartOf(NamedArea partOf){
245
		this.partOf = partOf;
246
	}
247
	
248
	@XmlElementWrapper(name = "Generalizations", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
249
	@XmlElement(name = "GeneralizationOf", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
250
    @XmlIDREF
251
    @XmlSchemaType(name = "IDREF")
252
	public Set<NamedArea> getGeneralizationOf(){
253
		return super.getGeneralizationOf();
254
	}
255
	
256
	protected void setGeneralizationOf(Set<NamedArea> value){
257
		super.setGeneralizationOf(value);
258
	}
259
	
260
	@XmlElementWrapper(name = "Includes", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
261
	@XmlElement(name = "Include", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
262
	@XmlIDREF
263
    @XmlSchemaType(name = "IDREF")
264
	public Set<NamedArea> getIncludes(){
265
		return super.getIncludes();
266
	}
267
	
268
	protected void setIncludes(Set<NamedArea> includes) {
269
		super.setIncludes(includes);
270
	}
271
	
272

    
273
	/* (non-Javadoc)
274
	 * @see eu.etaxonomy.cdm.model.common.DefinedTermBase#readCsvLine(java.util.List)
275
	 */
276
	@Override
277
	public NamedArea readCsvLine(Class<NamedArea> termClass, List<String> csvLine, Map<UUID,DefinedTermBase> terms) {
278
		NamedArea newInstance = super.readCsvLine(termClass, csvLine, terms);
279
		
280
		String levelString = (String)csvLine.get(6);
281
		
282
		if(levelString != null && levelString.length() != 0) {
283
			UUID levelUuid = UUID.fromString(levelString);
284
			NamedAreaLevel level = (NamedAreaLevel)terms.get(levelUuid);
285
			newInstance.setLevel(level);
286
		}
287
		
288
		String partOfString = (String)csvLine.get(7);
289
	
290
		if(partOfString != null && partOfString.length() != 0) {
291
			UUID partOfUuid = UUID.fromString(partOfString);
292
			NamedArea partOf = (NamedArea)terms.get(partOfUuid);
293
			partOf.addIncludes(newInstance);
294
		} 
295
		return newInstance;
296
	}
297
	
298
	@Override
299
	protected void setDefaultTerms(TermVocabulary<NamedArea> termVocabulary) {
300
		termMap = new HashMap<UUID, NamedArea>();
301
		for (NamedArea term : termVocabulary.getTerms()){
302
			termMap.put(term.getUuid(), term);
303
		}
304
	}
305
	
306
	
307
/*	public boolean equals(NamedArea area){
308
		boolean result = false;
309
		if (this.getLabel().toString().compareTo(area.getLabel().toString()) == 0){
310
			result = true;
311
		}
312
		return result;
313
	}*/
314
	
315
	public int compareTo(NamedArea area){
316
		return getLabel().compareTo(area.getLabel());
317
	}
318
	
319
	public NamedAreaNode getHiearchieList(List<NamedArea> areaList){
320
		NamedAreaNode result = new NamedAreaNode();
321
		for (NamedArea area : areaList){
322
			List<NamedArea> areaHierarchie  = area.getAllLevelList();
323
			mergeIntoResult(result, areaHierarchie);
324
		}
325
		return result;
326
	}
327
	
328
	
329
	public class LevelNode {
330
		NamedAreaLevel level;
331
		List<NamedAreaNode> areaList = new ArrayList<NamedAreaNode>();
332

    
333
		public NamedAreaNode add(NamedArea area) {
334
			NamedAreaNode node = new NamedAreaNode();
335
			node.area = area;
336
			areaList.add(node);
337
			return node;
338

    
339
		}
340

    
341
		public NamedAreaNode getNamedAreaNode(NamedArea area) {
342
			for (NamedAreaNode node : areaList) {
343
				if (node.area.equals(area)) {
344
					return node;
345
				}
346
			}
347
			return null;
348
		}
349

    
350
		public String toString() {
351
			return level.getTitleCache();
352
		}
353

    
354
	}
355

    
356
	public class NamedAreaNode {
357
		NamedArea area;
358
		List<LevelNode> levelList = new ArrayList<LevelNode>();
359
		
360
		public LevelNode getLevelNode(NamedAreaLevel level) {
361
			for (LevelNode node : levelList) {
362
				if (node.level.equals(level)) {
363
					return node;
364
				}
365
			}
366
			return null;
367
		}
368

    
369
		public List<NamedAreaNode> getList(NamedAreaLevel level) {
370
			LevelNode node = getLevelNode(level);
371
			if (node == null) {
372
				return new ArrayList<NamedAreaNode>();
373
			} else {
374
				return node.areaList;
375
			}
376
		};
377

    
378
		public boolean contains(NamedAreaLevel level) {
379
			if (getList(level).size() > 0) {
380
				return true;
381
			} else {
382
				return false;
383
			}
384
		}
385

    
386
		public LevelNode add(NamedAreaLevel level) {
387
			LevelNode node = new LevelNode();
388
			node.level = level;
389
			levelList.add(node);
390
			return node;
391
		}
392

    
393
		public String toString() {
394
			if (area == null) {
395
				return "";
396
			}
397
			return area.getTitleCache();
398
		}
399
	}
400

    
401
	private void mergeIntoResult(NamedAreaNode root,
402
			List<NamedArea> areaHierarchie) {
403
		if (areaHierarchie.isEmpty()) {
404
			return;
405
		}
406
		NamedArea highestArea = areaHierarchie.get(0);
407
		NamedAreaLevel level = highestArea.getLevel();
408
		NamedAreaNode namedAreaNode;
409
		if (!root.contains(level)) {
410
			LevelNode node = root.add(level);
411
			namedAreaNode = node.add(highestArea);
412
		} else {
413
			LevelNode levelNode = root.getLevelNode(level);
414
			namedAreaNode = levelNode.getNamedAreaNode(highestArea);
415
			if (namedAreaNode == null) {
416
				namedAreaNode = levelNode.add(highestArea);
417
			}
418
		}
419
		List<NamedArea> newList = areaHierarchie.subList(1, areaHierarchie
420
				.size());
421
		mergeIntoResult(namedAreaNode, newList);
422

    
423
	}
424

    
425
	@Transient
426
	public List<NamedArea> getAllLevelList() {
427
		List<NamedArea> result = new ArrayList<NamedArea>();
428
		NamedArea copyArea = this;
429
		result.add(copyArea);		
430
		while (copyArea.getPartOf() != null) {
431
			copyArea = copyArea.getPartOf();
432
			result.add(0, copyArea);
433
		}
434
		return result;
435
	}
436
	
437
	public String toString(){
438
		String result, label, level = "";
439
		
440
		if (this.level != null){
441
			level = this.level.getLabel();
442
		}
443
		label = this.getLabel();
444
		result = "[" + level + ", " + label + "]";
445
		
446
		return result;
447
	}
448
}
(2-2/10)