Project

General

Profile

Download (10.8 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.logging.log4j.LogManager;
38
import org.apache.logging.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.springframework.util.Assert;
44

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

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

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

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

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

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

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

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

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

    
117
    @XmlElement(name = "OriginalInfo")
118
    private String originalInfo;
119

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

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

    
134
//***************** CONSTRUCTOR ***********************/
135

    
136
    //for hibernate use only, protected required by subclasses
137
    @Deprecated
138
	protected OriginalSourceBase(){}
139

    
140
	protected OriginalSourceBase(OriginalSourceType type){
141
		if (type == null){
142
			throw new IllegalArgumentException("OriginalSourceType must not be null");
143
		}
144
		this.type = type;
145
	}
146

    
147
//**************** GETTER / SETTER *******************************/
148

    
149
    @Override
150
    public OriginalSourceType getType() {
151
        return type;
152
    }
153
    @Override
154
    public void setType(OriginalSourceType type) {
155
        Assert.notNull(type, "OriginalSourceType must not be null");
156
        this.type = type;
157
    }
158

    
159
	@Override
160
	public String getIdInSource(){
161
		return this.idInSource;
162
	}
163
	@Override
164
	public void setIdInSource(String idInSource){
165
		this.idInSource = idInSource;
166
	}
167

    
168
	@Override
169
	public String getIdNamespace() {
170
		return idNamespace;
171
	}
172
	@Override
173
	public void setIdNamespace(String idNamespace) {
174
		this.idNamespace = idNamespace;
175
	}
176

    
177
    @Override
178
    public Reference getCitation(){
179
        return this.citation;
180
    }
181
    @Override
182
    public void setCitation(Reference citation) {
183
        this.citation = citation;
184
    }
185

    
186
    @Override
187
    public String getCitationMicroReference(){
188
        return this.citationMicroReference;
189
    }
190
    @Override
191
    public void setCitationMicroReference(String citationMicroReference){
192
        this.citationMicroReference = citationMicroReference;
193
    }
194

    
195
    public String getOriginalInfo(){
196
        return this.originalInfo;
197
    }
198
    public void setOriginalInfo(String originalInfo){
199
        this.originalInfo = originalInfo;
200
    }
201

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

    
217
//	@Override
218
//    public void setCdmSource(CdmLinkSource cdmSource) {
219
//        this.cdmSource = cdmSource;
220
//    }
221

    
222
    @Override
223
    public void setCdmSource(ICdmTarget cdmTarget){
224
        if (cdmTarget != null){
225
            this.cdmSource = CdmLinkSource.NewInstance(cdmTarget);
226
        }else{
227
            if (cdmSource != null){
228
                cdmSource.setTarget(null);  //as long as orphan-removal does not work #9801
229
            }
230
            this.cdmSource = null;
231
        }
232
    }
233

    
234
//********************** External Links **********************************************
235

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

    
253
//********************** CLONE ************************************************/
254

    
255
	@Override
256
	public OriginalSourceBase clone() throws CloneNotSupportedException{
257

    
258
        OriginalSourceBase result = (OriginalSourceBase)super.clone();
259

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

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

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

    
275
// **************** EMPTY ************************/
276

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

    
282
    /**
283
     * Checks if the source is completely empty.
284
     *
285
     * @param excludeType if <code>true</code> the source type
286
     * is ignored for the check.
287
     *
288
     * @see #checkEmpty()
289
     * @return <code>true</code> if empty
290
     */
291
    public boolean checkEmpty(boolean excludeType){
292
	   return super.checkEmpty()
293
	        && (excludeType || this.type == null)
294
	        && this.getCitation() == null
295
	        && isBlank(this.getCitationMicroReference())
296
	        && isBlank(this.getOriginalInfo())
297
	        && isBlank(this.getIdInSource())
298
	        && isBlank(this.getIdNamespace())
299
	        && this.links.isEmpty()
300
	        && this.cdmSource == null
301
           ;
302
	}
303

    
304
//************************ toString ***************************************/
305
	@Override
306
	public String toString(){
307
		if (isNotBlank(idInSource) || isNotBlank(idNamespace) ){
308
			return "OriginalSource:" + CdmUtils.concat(":", idNamespace, idInSource);
309
		}else{
310
			return super.toString();
311
		}
312
	}
313

    
314
//*********************************** EQUALS *********************************************************/
315

    
316
    /**
317
     * Indicates whether some other object is "equal to" this one.
318
     *
319
     * Uses a content based compare strategy which avoids bean initialization. This is achieved by
320
     * comparing the cdm entity ids.
321
     */
322
    public boolean equalsByShallowCompare(OriginalSourceBase other) {
323

    
324
        int thisCitationId = -1;
325
        int otherCitationId = -1;
326
        if(this.getCitation() != null) {
327
            thisCitationId = this.getCitation().getId();
328
        }
329
        if(other.getCitation() != null) {
330
            otherCitationId = other.getCitation().getId();
331
        }
332

    
333
        if(thisCitationId != otherCitationId
334
                || !StringUtils.equals(this.getCitationMicroReference(), other.getCitationMicroReference())
335
                || !StringUtils.equals(this.getOriginalInfo(), other.getOriginalInfo())
336
                        ){
337
            return false;
338
        }
339

    
340
        OriginalSourceBase theOther = other;
341
        if(!StringUtils.equals(this.getIdInSource(), theOther.getIdInSource())
342
                || !CdmUtils.nullSafeEqual(this.getIdNamespace(), theOther.getIdNamespace())
343
                || !CdmUtils.nullSafeEqual(this.getType(), theOther.getType())
344
                || !CdmUtils.nullSafeEqual(this.getCdmSource(), theOther.getCdmSource())
345
                || !CdmUtils.nullSafeEqual(this.getLinks(), theOther.getLinks())) {
346
            return false;
347
        }
348

    
349
        return true;
350
    }
351
}
(34-34/41)