Project

General

Profile

Download (10.5 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.reference;
11

    
12

    
13
import java.util.HashSet;
14
import java.util.Set;
15

    
16
import javax.persistence.Column;
17
import javax.persistence.Entity;
18
import javax.persistence.FetchType;
19
import javax.persistence.Inheritance;
20
import javax.persistence.InheritanceType;
21
import javax.persistence.ManyToOne;
22
import javax.persistence.OneToMany;
23
import javax.persistence.OneToOne;
24
import javax.persistence.Table;
25
import javax.validation.constraints.NotNull;
26
import javax.xml.bind.annotation.XmlAccessType;
27
import javax.xml.bind.annotation.XmlAccessorType;
28
import javax.xml.bind.annotation.XmlAttribute;
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.XmlType;
35

    
36
import org.apache.commons.lang3.StringUtils;
37
import org.apache.log4j.Logger;
38
import org.hibernate.annotations.Cascade;
39
import org.hibernate.annotations.CascadeType;
40
import org.hibernate.annotations.Type;
41
import org.hibernate.envers.Audited;
42
import org.springframework.util.Assert;
43

    
44
import eu.etaxonomy.cdm.common.CdmUtils;
45
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
46
import eu.etaxonomy.cdm.model.common.IIntextReferenceTarget;
47
import eu.etaxonomy.cdm.model.media.ExternalLink;
48
import eu.etaxonomy.cdm.strategy.merge.Merge;
49
import eu.etaxonomy.cdm.strategy.merge.MergeMode;
50

    
51
/**
52
 * Abstract base class for classes implementing {@link eu.etaxonomy.cdm.model.reference.IOriginalSource IOriginalSource}.
53
 * @see eu.etaxonomy.cdm.model.reference.IOriginalSource
54
 *
55
 * @author m.doering
56
 * @since 08-Nov-2007 13:06:22
57
 */
58

    
59
@XmlAccessorType(XmlAccessType.FIELD)
60
@XmlType(name = "OriginalSource", propOrder = {
61
    "type",
62
	"idInSource",
63
    "idNamespace",
64
    "originalNameString",
65
    "citation",
66
    "citationMicroReference",
67
    "cdmSource",
68
    "links"
69
})
70
@XmlRootElement(name = "OriginalSource")
71
@Entity
72
@Audited
73
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
74
@Table(name="OriginalSourceBase")
75
public abstract class OriginalSourceBase<T extends ISourceable>
76
        extends AnnotatableEntity
77
        implements IOriginalSource<T>, IIntextReferenceTarget {
78

    
79
	private static final long serialVersionUID = -1972959999261181462L;
80
	@SuppressWarnings("unused")
81
	private static final Logger logger = Logger.getLogger(OriginalSourceBase.class);
82

    
83
	/**
84
	 * The {@link OriginalSourceType type} of this source. According to PROV the type has to be thought as
85
	 * an activity that leads from the source entity to the current entity. It is not a property of the
86
	 * source itself.
87
	 */
88
	@XmlAttribute(name ="type")
89
	@Column(name="sourceType")
90
	@NotNull
91
    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
92
    	parameters = {@org.hibernate.annotations.Parameter(name="enumClass", value="eu.etaxonomy.cdm.model.reference.OriginalSourceType")}
93
    )
94
	@Audited
95
	private OriginalSourceType type;
96

    
97
	//The object's ID in the source, where the alternative string comes from
98
	@XmlElement(name = "IdInSource")
99
	private String idInSource;
100

    
101
	@XmlElement(name = "IdNamespace")
102
	private String idNamespace;
103

    
104
    @XmlElement(name = "Citation")
105
    @XmlIDREF
106
    @XmlSchemaType(name = "IDREF")
107
    @ManyToOne(fetch = FetchType.LAZY)
108
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
109
    private Reference citation;
110

    
111
    //Details of the reference. These are mostly (implicitly) pages but can also be tables or any other element of a
112
    //publication. {if the citationMicroReference exists then there must be also a reference}
113
    @XmlElement(name = "CitationMicroReference")
114
    private String citationMicroReference;
115

    
116
    @XmlElement(name = "OriginalNameString")
117
    private String originalNameString;
118

    
119
    @XmlElement(name = "CdmSource")
120
    @XmlIDREF
121
    @XmlSchemaType(name = "IDREF")
122
    @OneToOne(fetch = FetchType.EAGER, orphanRemoval=true)  //EAGER to avoid LIEs cdmSource should always be part of the OriginalSource itself
123
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE, CascadeType.DELETE})
124
    private CdmLinkSource cdmSource;
125

    
126
    @XmlElementWrapper(name = "Links", nillable = true)
127
    @XmlElement(name = "Link")
128
    @OneToMany(fetch=FetchType.LAZY, orphanRemoval=true)
129
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE})
130
    @Merge(MergeMode.ADD_CLONE)
131
	private Set<ExternalLink> links = new HashSet<>();
132

    
133
//***************** CONSTRUCTOR ***********************/
134

    
135
	//for hibernate use only
136
	protected OriginalSourceBase() {
137

    
138
	}
139

    
140
	/**
141
	 * Constructor
142
	 * @param type
143
	 */
144
	protected OriginalSourceBase(OriginalSourceType type){
145
		if (type == null){
146
			throw new IllegalArgumentException("OriginalSourceType must not be null");
147
		}
148
		this.type = type;
149
	}
150

    
151
//**************** GETTER / SETTER *******************************/
152

    
153
    @Override
154
    public OriginalSourceType getType() {
155
        return type;
156
    }
157
    @Override
158
    public void setType(OriginalSourceType type) {
159
        Assert.notNull(type, "OriginalSourceType must not be null");
160
        this.type = type;
161
    }
162

    
163
	@Override
164
	public String getIdInSource(){
165
		return this.idInSource;
166
	}
167
	@Override
168
	public void setIdInSource(String idInSource){
169
		this.idInSource = idInSource;
170
	}
171

    
172
	@Override
173
	public String getIdNamespace() {
174
		return idNamespace;
175
	}
176
	@Override
177
	public void setIdNamespace(String idNamespace) {
178
		this.idNamespace = idNamespace;
179
	}
180

    
181
    @Override
182
    public Reference getCitation(){
183
        return this.citation;
184
    }
185
    @Override
186
    public void setCitation(Reference citation) {
187
        this.citation = citation;
188
    }
189

    
190
    @Override
191
    public String getCitationMicroReference(){
192
        return this.citationMicroReference;
193
    }
194
    @Override
195
    public void setCitationMicroReference(String citationMicroReference){
196
        this.citationMicroReference = citationMicroReference;
197
    }
198

    
199
    public String getOriginalNameString(){
200
        return this.originalNameString;
201
    }
202
    public void setOriginalNameString(String originalNameString){
203
        this.originalNameString = originalNameString;
204
    }
205

    
206
	@Override
207
    public ICdmTarget getCdmSource() {
208
        return cdmSource == null? null: cdmSource.getTarget();
209
    }
210
     /* this method was implemented in the context of the CdmLinkSourceBeanProcessor which is unused
211
      *  method is preserved for the time when the REST API will be revised (#8637)
212
    @Override
213
    public CdmLinkSource getCdmSource() {
214
        if(cdmSource != null){
215
            logger.error("NOT NULL");
216
        }
217
        return cdmSource;
218
    }
219
	*/
220

    
221

    
222
//	@Override
223
//    public void setCdmSource(CdmLinkSource cdmSource) {
224
//        this.cdmSource = cdmSource;
225
//    }
226
    @Override
227
    public void setCdmSource(ICdmTarget cdmTarget){
228
        if (cdmTarget != null){
229
            this.cdmSource = CdmLinkSource.NewInstance(cdmTarget);
230
        }else{
231
            this.cdmSource = null;
232
        }
233
    }
234

    
235
//********************** External Links **********************************************
236

    
237

    
238
    public Set<ExternalLink> getLinks(){
239
        return this.links;
240
    }
241
    public void setLinks(Set<ExternalLink> links){
242
        this.links = links;
243
    }
244
    public void addLink(ExternalLink link){
245
        if (link != null){
246
            links.add(link);
247
        }
248
    }
249
    public void removeLink(ExternalLink link){
250
        if(links.contains(link)) {
251
            links.remove(link);
252
        }
253
    }
254

    
255
//********************** CLONE ************************************************/
256

    
257
	@Override
258
	public Object clone() throws CloneNotSupportedException{
259
		OriginalSourceBase<?> result = (OriginalSourceBase<?>)super.clone();
260

    
261
		Set<ExternalLink> links = new HashSet<>();
262
		result.setLinks(links);
263
		for(ExternalLink link : this.links){
264
		    result.addLink(link.clone());
265
		}
266

    
267
		if (this.cdmSource != null){
268
		    result.setCdmSource(this.cdmSource.getTarget());
269
		}
270

    
271
		//no changes to: type, idInSource, idNamespace,
272
		//   citation, citationMicroReference, originalNameString
273
		return result;
274
	}
275

    
276
// **************** EMPTY ************************/
277

    
278
    @Override
279
    protected boolean checkEmpty(){
280
        return checkEmpty(false);
281
    }
282

    
283
    public boolean checkEmpty(boolean excludeType){
284
	   return super.checkEmpty()
285
	        && (excludeType || this.type == null)
286
	        && this.getCitation() == null
287
	        && isBlank(this.getCitationMicroReference())
288
	        && isBlank(this.getOriginalNameString())
289
	        && isBlank(this.getIdInSource())
290
	        && isBlank(this.getIdNamespace())
291
	        && this.links.isEmpty()
292
	        && this.cdmSource == null
293
           ;
294
	}
295

    
296
//************************ toString ***************************************/
297
	@Override
298
	public String toString(){
299
		if (isNotBlank(idInSource) || isNotBlank(idNamespace) ){
300
			return "OriginalSource:" + CdmUtils.concat(":", idNamespace, idInSource);
301
		}else{
302
			return super.toString();
303
		}
304
	}
305

    
306
//*********************************** EQUALS *********************************************************/
307

    
308
    /**
309
     * Indicates whether some other object is "equal to" this one.
310
     *
311
     * Uses a content based compare strategy which avoids bean initialization. This is achieved by
312
     * comparing the cdm entity ids.
313
     */
314
    public boolean equalsByShallowCompare(OriginalSourceBase<T> other) {
315

    
316
        int thisCitationId = -1;
317
        int otherCitationId = -1;
318
        if(this.getCitation() != null) {
319
            thisCitationId = this.getCitation().getId();
320
        }
321
        if(other.getCitation() != null) {
322
            otherCitationId = other.getCitation().getId();
323
        }
324

    
325
        if(thisCitationId != otherCitationId
326
                || !StringUtils.equals(this.getCitationMicroReference(), other.getCitationMicroReference())
327
                || !StringUtils.equals(this.getOriginalNameString(), other.getOriginalNameString())
328
                        ){
329
            return false;
330
        }
331

    
332
        @SuppressWarnings("unchecked")
333
        OriginalSourceBase<T> theOther = other;
334
        if(!StringUtils.equals(this.getIdInSource(), theOther.getIdInSource())
335
                || !CdmUtils.nullSafeEqual(this.getIdNamespace(), theOther.getIdNamespace())
336
                || !CdmUtils.nullSafeEqual(this.getType(), theOther.getType())
337
                || !CdmUtils.nullSafeEqual(this.getCdmSource(), theOther.getCdmSource())
338
                || !CdmUtils.nullSafeEqual(this.getLinks(), theOther.getLinks())) {
339
            return false;
340
        }
341

    
342
        return true;
343
    }
344

    
345
}
(31-31/38)