Project

General

Profile

Download (12.1 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.media;
11

    
12
import java.net.URI;
13
import java.util.HashMap;
14
import java.util.HashSet;
15
import java.util.Map;
16
import java.util.Set;
17

    
18
import javax.persistence.Basic;
19
import javax.persistence.Entity;
20
import javax.persistence.FetchType;
21
import javax.persistence.Inheritance;
22
import javax.persistence.InheritanceType;
23
import javax.persistence.JoinTable;
24
import javax.persistence.ManyToOne;
25
import javax.persistence.OneToMany;
26
import javax.persistence.Transient;
27
import javax.validation.constraints.NotNull;
28
import javax.xml.bind.annotation.XmlAccessType;
29
import javax.xml.bind.annotation.XmlAccessorType;
30
import javax.xml.bind.annotation.XmlElement;
31
import javax.xml.bind.annotation.XmlElementWrapper;
32
import javax.xml.bind.annotation.XmlIDREF;
33
import javax.xml.bind.annotation.XmlRootElement;
34
import javax.xml.bind.annotation.XmlSchemaType;
35
import javax.xml.bind.annotation.XmlType;
36
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
37

    
38
import org.apache.log4j.Logger;
39
import org.hibernate.annotations.Cascade;
40
import org.hibernate.annotations.CascadeType;
41
import org.hibernate.annotations.Type;
42
import org.hibernate.envers.Audited;
43
import org.hibernate.search.annotations.Indexed;
44
import org.hibernate.search.annotations.IndexedEmbedded;
45
import org.hibernate.validator.constraints.NotEmpty;
46
import org.joda.time.DateTime;
47

    
48
import eu.etaxonomy.cdm.jaxb.DateTimeAdapter;
49
import eu.etaxonomy.cdm.jaxb.MultilanguageTextAdapter;
50
import eu.etaxonomy.cdm.model.agent.AgentBase;
51
import eu.etaxonomy.cdm.model.common.IMultiLanguageTextHolder;
52
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
53
import eu.etaxonomy.cdm.model.common.Language;
54
import eu.etaxonomy.cdm.model.common.LanguageString;
55
import eu.etaxonomy.cdm.model.common.MultilanguageText;
56
import eu.etaxonomy.cdm.strategy.cache.media.MediaDefaultCacheStrategy;
57
import eu.etaxonomy.cdm.validation.Level2;
58

    
59
/**
60
 * A {@link Media media} is any kind of media that represents a media object. 
61
 * This media object can have multiple {@link MediaRepresentation media representations} that differ in MIME-type 
62
 * and/or quality. 
63
 * E.g. 
64
 * (1) an image can have a tiff and a jpg media representation. 
65
 * (2) an formatted text can have a text/html or an application/pdf representation. 
66
 * @author m.doering
67
 * @version 1.0
68
 * @created 08-Nov-2007 13:06:34
69
 */
70
@XmlAccessorType(XmlAccessType.FIELD)
71
@XmlType(name = "Media", propOrder = {
72
    "title",
73
    "mediaCreated",
74
    "description",
75
    "representations",
76
    "artist"
77
})
78
@XmlRootElement(name = "Media")
79
@Entity
80
@Indexed
81
@Audited
82
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
83
public class Media extends IdentifiableEntity implements Cloneable, IMultiLanguageTextHolder {
84
	private static final long serialVersionUID = -1927421567263473658L;
85
	@SuppressWarnings("unused")
86
	private static final Logger logger = Logger.getLogger(Media.class);
87

    
88
    // TODO once hibernate annotations support custom collection type
89
	// private MultilanguageText title = new MultilanguageText();
90
	@XmlElement(name = "MediaTitle")
91
    @XmlJavaTypeAdapter(MultilanguageTextAdapter.class)
92
    @OneToMany(fetch = FetchType.LAZY)
93
    @IndexedEmbedded
94
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE,CascadeType.DELETE, CascadeType.DELETE_ORPHAN, CascadeType.REFRESH})
95
    @NotNull
96
    @NotEmpty(groups = Level2.class)
97
	private Map<Language,LanguageString> title = new HashMap<Language,LanguageString>();
98
	
99
	//creation date of the media (not of the record) 
100
	@XmlElement(name = "MediaCreated", type= String.class)
101
	@XmlJavaTypeAdapter(DateTimeAdapter.class)
102
	@Type(type="dateTimeUserType")
103
	@Basic(fetch = FetchType.LAZY)
104
	private DateTime mediaCreated;
105
	
106
	 // TODO once hibernate annotations support custom collection type
107
	// private MultilanguageText description = new MultilanguageText();
108
	@XmlElement(name = "MediaDescription")
109
    @XmlJavaTypeAdapter(MultilanguageTextAdapter.class)
110
    @OneToMany(fetch = FetchType.LAZY)
111
    @IndexedEmbedded
112
    @JoinTable(name = "Media_Description")
113
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE,CascadeType.DELETE,CascadeType.DELETE_ORPHAN, CascadeType.REFRESH})
114
    @NotNull
115
	private Map<Language,LanguageString> description = new HashMap<Language,LanguageString>();
116
	
117
	//A single medium such as a picture can have multiple representations in files. 
118
	//Common are multiple resolutions or file formats for images for example
119
	@XmlElementWrapper(name = "MediaRepresentations")
120
	@XmlElement(name = "MediaRepresentation")
121
	@OneToMany(mappedBy="media",fetch = FetchType.LAZY)
122
	@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE, CascadeType.DELETE_ORPHAN, CascadeType.REFRESH})
123
	@NotNull
124
	@NotEmpty(groups = Level2.class)
125
	private Set<MediaRepresentation> representations = new HashSet<MediaRepresentation>();
126
	
127
	@XmlElement(name = "Artist")
128
	@XmlIDREF
129
	@XmlSchemaType(name = "IDREF")
130
	@ManyToOne(fetch = FetchType.LAZY)
131
	@IndexedEmbedded
132
	@Cascade(CascadeType.SAVE_UPDATE)
133
	private AgentBase artist;
134

    
135

    
136
	/**
137
	 * Factory method
138
	 * @return
139
	 */
140
	public static Media NewInstance(){
141
		return new Media();
142
	}
143
	
144

    
145
	/**
146
	 * Factory method which creates a new media, adds a reprsentation including mime type and suffix information
147
	 * and adds to the later a representation part for a given uri and size
148
	 * Returns <code>null</code> if uri is empty
149
	 * @return Media
150
	 */
151
	public static Media NewInstance(URI uri, Integer size, String mimeType, String suffix){
152
		MediaRepresentation representation = MediaRepresentation.NewInstance(mimeType, suffix, uri, size);
153
		if (representation == null){
154
			return null;
155
		}
156
		Media media = new Media();
157
		media.addRepresentation(representation);
158
		return media;
159
	}
160
	
161
	/**
162
	 * Constructor
163
	 */
164
	protected Media() {
165
		super();
166
		setMediaCacheStrategy();
167
	}
168

    
169
	private void setMediaCacheStrategy() {
170
		if (getClass() == Media.class){
171
			this.cacheStrategy = MediaDefaultCacheStrategy.NewInstance();
172
		}
173
		
174
	}
175

    
176

    
177
	public Set<MediaRepresentation> getRepresentations(){
178
		if(representations == null) {
179
			this.representations = new HashSet<MediaRepresentation>();
180
		}
181
		return this.representations;
182
	}
183

    
184
	@SuppressWarnings("deprecation")
185
	public void addRepresentation(MediaRepresentation representation){
186
		if (representation != null){
187
			this.getRepresentations().add(representation);
188
			representation.setMedia(this);
189
		}
190
	}
191
	
192
	@SuppressWarnings("deprecation")
193
	public void removeRepresentation(MediaRepresentation representation){
194
		this.getRepresentations().remove(representation);
195
		if (representation != null){
196
			representation.setMedia(null);
197
		}
198

    
199
	}
200

    
201
	public AgentBase getArtist(){
202
		return this.artist;
203
	}
204
	
205
	public void setArtist(AgentBase artist){
206
		this.artist = artist;
207
	}
208

    
209
//************************ title / title cache *********************************
210
	
211
	public LanguageString getTitle(){
212
		return getTitle(Language.DEFAULT());
213
	}
214
	
215
	public LanguageString getTitle(Language language){
216
		return title.get(language);
217
	}
218
	
219
	@Transient
220
	public Map<Language,LanguageString> getAllTitles(){
221
		if(title == null) {
222
			this.title = new HashMap<Language,LanguageString>();
223
		}
224
		return this.title;
225
	}
226
	/**
227
	 * Adds the languageString to the {@link MultilanguageText multilanguage text} 
228
	 * used to be the title of <i>this</i> media.
229
	 * 
230
	 * @param title		the languageString with the title in a particular language
231
	 * @see    	   		#getTitle()
232
	 * @see    	   		#putTitle(Language String)
233
	 * @deprecated		should follow the put semantic of maps, this method will be removed in v4.0
234
	 * 					Use the {@link #putTitle(LanguageString) putTitle} method instead
235
	 */
236
	@Deprecated
237
	public void addTitle(LanguageString title){
238
		this.putTitle(title);
239
	}
240
	public void putTitle(LanguageString title){
241
		this.title.put(title.getLanguage(), title);
242
	}
243
	
244
	/**
245
	 * Creates a {@link LanguageString language string} based on the given text string
246
	 * and the given {@link Language language} and adds it to the {@link MultilanguageText multilanguage text} 
247
	 * used to be the title of <i>this</i> media.
248
	 * 
249
	 * @param text		the title in a particular language
250
	 * @param language	the language in which the title string is formulated
251
	 * @see    	   		#getTitle()
252
	 * @see    	   		#putTitle(LanguageString)
253
	 * @deprecated		should follow the put semantic of maps, this method will be removed in v4.0
254
	 * 					Use the {@link #putTitle(Language, String) putTitle} method instead
255
	 */
256
	@Deprecated
257
	public void addTitle(String title, Language language){
258
		this.putTitle(language, title);
259
	}
260
	/**
261
	 * Creates a {@link LanguageString language string} based on the given text string
262
	 * and the given {@link Language language} and adds it to the {@link MultilanguageText multilanguage text} 
263
	 * used to be the title of <i>this</i> media.
264
	 * 
265
	 * @param language	the language in which the title string is formulated
266
	 * @param text		the title in a particular language
267
	 * 
268
	 * @see    	   		#getTitle()
269
	 * @see    	   		#putTitle(LanguageString)
270
	 */
271
	public void putTitle(Language language, String title){
272
		this.title.put(language, LanguageString.NewInstance(title, language));
273
	}
274
	
275
	public void removeTitle(Language language){
276
		this.title.remove(language);
277
	}
278
	
279

    
280
	@Transient 
281
	public String getTitleCacheByLanguage(Language lang){
282
		if (cacheStrategy != null){
283
			return ((MediaDefaultCacheStrategy)cacheStrategy).getTitleCacheByLanguage(this, lang);
284
		}else{
285
			return null;
286
		}
287
			
288
	}
289
	
290
	
291
	/*
292
	 * (non-Javadoc)
293
	 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#setTitleCache(java.lang.String)
294
	 */
295
	@Override
296
	public void setTitleCache(String titleCache) {
297
		putTitle(LanguageString.NewInstance(titleCache, Language.DEFAULT()));
298
	}
299
	
300
	/* (non-Javadoc)
301
	 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#getTitleCache()
302
	 */
303
	@Override
304
	public String getTitleCache(){
305
		if (protectedTitleCache){
306
			return this.titleCache;			
307
		}
308
		// is title dirty, i.e. equal NULL?
309
		if (titleCache == null){
310
			this.titleCache = generateTitle();
311
			this.titleCache = getTruncatedCache(this.titleCache) ;
312
		}else{
313
			//do the same as listeners on dependend objects like representations parts
314
			//are not yet installed
315
			this.titleCache = generateTitle();
316
			this.titleCache = getTruncatedCache(this.titleCache) ;
317
		}
318
		return titleCache;
319
	}
320
	
321
	
322
	
323

    
324
	public DateTime getMediaCreated(){
325
		return this.mediaCreated;
326
	}
327
	
328
	public void setMediaCreated(DateTime mediaCreated){
329
		this.mediaCreated = mediaCreated;
330
	}
331

    
332
	//************* Descriptions
333

    
334
	public Map<Language,LanguageString> getAllDescriptions(){
335
		if(this.description == null) {
336
			this.description = new HashMap<Language,LanguageString>();
337
		}
338
		return this.description;
339
	}
340
	
341
	public LanguageString getDescription(Language language){
342
		return getAllDescriptions().get(language);
343
	}
344
	
345
	public void addDescription(LanguageString description){
346
		this.description.put(description.getLanguage(), description);
347
	}
348
	
349
	public void addDescription(String text, Language language){
350
		this.description.put(language, LanguageString.NewInstance(text, language));
351
	}
352
	
353
	public void removeDescription(Language language){
354
		this.description.remove(language);
355
	}
356
	
357
//************************* CLONE **************************/
358
	
359
	
360
	/* (non-Javadoc)
361
	 * @see java.lang.Object#clone()
362
	 */
363
	@Override
364
	public Object clone() throws CloneNotSupportedException{
365
		Media result = (Media)super.clone();
366
		//description
367
		result.description = new HashMap<Language, LanguageString>();
368
		for (Language language: this.description.keySet()){
369
			result.description.put(language, this.description.get(language));
370
		}
371
		//title
372
		result.title = new HashMap<Language, LanguageString>();
373
		for (Language language: this.title.keySet()){
374
			result.title.put(language, this.title.get(language));
375
		}
376
		//media representations
377
		result.representations = new HashSet<MediaRepresentation>();
378
		for (MediaRepresentation mediaRepresentation: this.representations){
379
			result.representations.add((MediaRepresentation)mediaRepresentation.clone());
380
		}
381
		//no changes to: artist
382
		return result;
383
	}
384
	
385
	public int compareTo(Object o) {
386
		return 0;
387
	}
388
	
389
	
390
	
391
}
(6-6/14)