Project

General

Profile

Download (10.3 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.util.ArrayList;
13
import java.util.Arrays;
14
import java.util.HashMap;
15
import java.util.HashSet;
16
import java.util.List;
17
import java.util.Map;
18
import java.util.Set;
19
import java.util.SortedMap;
20
import java.util.TreeMap;
21
import java.util.regex.Matcher;
22
import java.util.regex.Pattern;
23

    
24
import javax.persistence.Basic;
25
import javax.persistence.Entity;
26
import javax.persistence.FetchType;
27
import javax.persistence.Inheritance;
28
import javax.persistence.InheritanceType;
29
import javax.persistence.JoinTable;
30
import javax.persistence.ManyToOne;
31
import javax.persistence.OneToMany;
32
import javax.persistence.Transient;
33
import javax.validation.constraints.NotNull;
34
import javax.xml.bind.annotation.XmlAccessType;
35
import javax.xml.bind.annotation.XmlAccessorType;
36
import javax.xml.bind.annotation.XmlElement;
37
import javax.xml.bind.annotation.XmlElementWrapper;
38
import javax.xml.bind.annotation.XmlIDREF;
39
import javax.xml.bind.annotation.XmlRootElement;
40
import javax.xml.bind.annotation.XmlSchemaType;
41
import javax.xml.bind.annotation.XmlType;
42
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
43

    
44
import org.apache.log4j.Logger;
45
import org.hibernate.annotations.Cascade;
46
import org.hibernate.annotations.CascadeType;
47
import org.hibernate.annotations.Type;
48
import org.hibernate.envers.Audited;
49
import org.hibernate.search.annotations.Indexed;
50
import org.hibernate.search.annotations.IndexedEmbedded;
51
import org.hibernate.validator.constraints.NotEmpty;
52
import org.joda.time.DateTime;
53

    
54
import eu.etaxonomy.cdm.jaxb.DateTimeAdapter;
55
import eu.etaxonomy.cdm.jaxb.MultilanguageTextAdapter;
56
import eu.etaxonomy.cdm.model.agent.AgentBase;
57
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
58
import eu.etaxonomy.cdm.model.common.Language;
59
import eu.etaxonomy.cdm.model.common.LanguageString;
60
import eu.etaxonomy.cdm.model.common.MultilanguageTextHelper;
61
import eu.etaxonomy.cdm.strategy.cache.media.MediaDefaultCacheStrategy;
62
import eu.etaxonomy.cdm.validation.Level2;
63

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

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

    
139

    
140
	/**
141
	 * Factory method
142
	 * @return
143
	 */
144
	public static Media NewInstance(){
145
		return new Media();
146
	}
147
	
148

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

    
173
	private void setMediaCacheStrategy() {
174
		if (getClass() == Media.class){
175
			this.cacheStrategy = MediaDefaultCacheStrategy.NewInstance();
176
		}
177
		
178
	}
179

    
180

    
181
	public Set<MediaRepresentation> getRepresentations(){
182
		if(representations == null) {
183
			this.representations = new HashSet<MediaRepresentation>();
184
		}
185
		return this.representations;
186
	}
187

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

    
203
	}
204

    
205
	public AgentBase getArtist(){
206
		return this.artist;
207
	}
208
	
209
	public void setArtist(AgentBase artist){
210
		this.artist = artist;
211
	}
212

    
213
	public LanguageString getTitle(){
214
		return getTitle(Language.DEFAULT());
215
	}
216
	
217
	public LanguageString getTitle(Language language){
218
		return title.get(language);
219
	}
220
	
221
	@Transient
222
	public Map<Language,LanguageString> getAllTitles(){
223
		if(title == null) {
224
			this.title = new HashMap<Language,LanguageString>();
225
		}
226
		return this.title;
227
	}
228
	
229
	public void addTitle(LanguageString title){
230
		this.title.put(title.getLanguage(), title);
231
	}
232
	
233
	public void removeTitle(Language language){
234
		this.title.remove(language);
235
	}
236

    
237
	public DateTime getMediaCreated(){
238
		return this.mediaCreated;
239
	}
240
	
241
	public void setMediaCreated(DateTime mediaCreated){
242
		this.mediaCreated = mediaCreated;
243
	}
244

    
245
	@Deprecated // will be removed in next release; use getAllDescriptions instead
246
	public Map<Language,LanguageString> getDescription(){
247
		return getAllDescriptions();
248
	}
249
	
250
	public Map<Language,LanguageString> getAllDescriptions(){
251
		if(this.description == null) {
252
			this.description = new HashMap<Language,LanguageString>();
253
		}
254
		return this.description;
255
	}
256
	
257
	public LanguageString getDescription(Language language){
258
		return getAllDescriptions().get(language);
259
	}
260
	
261
	public void addDescription(LanguageString description){
262
		this.description.put(description.getLanguage(), description);
263
	}
264
	
265
	public void addDescription(String text, Language language){
266
		this.description.put(language, LanguageString.NewInstance(text, language));
267
	}
268
	
269
	public void removeDescription(Language language){
270
		this.description.remove(language);
271
	}
272
	
273
//************************* CLONE **************************/
274
	
275
	
276
	/* (non-Javadoc)
277
	 * @see java.lang.Object#clone()
278
	 */
279
	@Override
280
	public Object clone() throws CloneNotSupportedException{
281
		Media result = (Media)super.clone();
282
		//description
283
		result.description = new HashMap<Language, LanguageString>();
284
		for (Language language: this.description.keySet()){
285
			result.description.put(language, this.description.get(language));
286
		}
287
		//title
288
		result.title = new HashMap<Language, LanguageString>();
289
		for (Language language: this.title.keySet()){
290
			result.title.put(language, this.title.get(language));
291
		}
292
		//media representations
293
		result.representations = new HashSet<MediaRepresentation>();
294
		for (MediaRepresentation mediaRepresentation: this.representations){
295
			result.representations.add((MediaRepresentation)mediaRepresentation.clone());
296
		}
297
		//no changes to: artist
298
		return result;
299
	}
300
	
301
	public int compareTo(Object o) {
302
		return 0;
303
	}
304
	
305
	
306
	@Transient 
307
	public String getTitleCacheByLanguage(Language lang){
308
		if (cacheStrategy != null){
309
			return ((MediaDefaultCacheStrategy)cacheStrategy).getTitleCacheByLanguage(this, lang);
310
		}else{
311
			return null;
312
		}
313
			
314
	}
315
	
316
	
317
	/*
318
	 * (non-Javadoc)
319
	 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#setTitleCache(java.lang.String)
320
	 */
321
	@Override
322
	public void setTitleCache(String titleCache) {
323
		addTitle(LanguageString.NewInstance(titleCache, Language.DEFAULT()));
324
	}
325
	
326
	/*
327
	 * Overriding the title cache methods here to avoid confusion with the title field
328
	 */
329
	
330
	/*
331
	 * (non-Javadoc)
332
	 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache()
333
	 */
334
	@Override
335
	public String getTitleCache() {
336
		List<Language> languages = Arrays.asList(new Language[]{Language.DEFAULT()});
337
		LanguageString languageString = MultilanguageTextHelper.getPreferredLanguageString(title, languages);
338
		return languageString != null ? languageString.getText() : null;
339
	}
340
	
341
	@Override
342
	public String generateTitle() {
343
		return getTitleCache();
344
	}
345
	
346
}
(6-6/14)