Project

General

Profile

Download (11.4 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.common.TimePeriod;
49
import eu.etaxonomy.cdm.model.media.ExternalLink;
50
import eu.etaxonomy.cdm.strategy.merge.Merge;
51
import eu.etaxonomy.cdm.strategy.merge.MergeMode;
52

    
53
/**
54
 * Abstract base class for classes implementing {@link eu.etaxonomy.cdm.model.reference.IOriginalSource IOriginalSource}.
55
 * @see eu.etaxonomy.cdm.model.reference.IOriginalSource
56
 *
57
 * @author m.doering
58
 * @since 08-Nov-2007 13:06:22
59
 */
60
@XmlAccessorType(XmlAccessType.FIELD)
61
@XmlType(name = "OriginalSource", propOrder = {
62
    "type",
63
	"idInSource",
64
    "idNamespace",
65
    "citation",
66
    "citationMicroReference",
67
    "accessed",
68
    "originalInfo",
69
    "cdmSource",
70
    "links"
71
})
72
@XmlRootElement(name = "OriginalSource")
73
@Entity
74
@Audited
75
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
76
@Table(name="OriginalSourceBase")
77
public abstract class OriginalSourceBase
78
        extends AnnotatableEntity
79
        implements IOriginalSource, IIntextReferenceTarget {
80

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

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

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

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

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

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

    
118
    //#10057
119
    @XmlElement(name = "Accessed", type= String.class)
120
    private TimePeriod accessed = TimePeriod.NewInstance();
121

    
122
    //#10097
123
    @XmlElement(name = "OriginalInfo")
124
    private String originalInfo;
125

    
126
    @XmlElement(name = "CdmSource")
127
    @XmlIDREF
128
    @XmlSchemaType(name = "IDREF")
129
    @OneToOne(fetch = FetchType.EAGER, orphanRemoval=true)  //EAGER to avoid LIEs cdmSource should always be part of the OriginalSource itself
130
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE})
131
    private CdmLinkSource cdmSource;
132

    
133
    @XmlElementWrapper(name = "Links", nillable = true)
134
    @XmlElement(name = "Link")
135
    @OneToMany(fetch=FetchType.LAZY, orphanRemoval=true)
136
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE})
137
    @Merge(MergeMode.ADD_CLONE)
138
	private Set<ExternalLink> links = new HashSet<>();
139

    
140
//***************** CONSTRUCTOR ***********************/
141

    
142
    //for hibernate use only, protected required by subclasses
143
    @Deprecated
144
	protected OriginalSourceBase(){}
145

    
146
	protected OriginalSourceBase(OriginalSourceType type){
147
		if (type == null){
148
			throw new IllegalArgumentException("OriginalSourceType must not be null");
149
		}
150
		this.type = type;
151
	}
152

    
153
//**************** GETTER / SETTER *******************************/
154

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

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

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

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

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

    
201
    public TimePeriod getAccessed() {
202
        return accessed;
203
    }
204
    public void setAccessed(TimePeriod accessed) {
205
        this.accessed = accessed;
206
    }
207

    
208
    public String getOriginalInfo(){
209
        return this.originalInfo;
210
    }
211
    public void setOriginalInfo(String originalInfo){
212
        this.originalInfo = originalInfo;
213
    }
214

    
215
	@Override
216
    public ICdmTarget getCdmSource() {
217
        return cdmSource == null? null: cdmSource.getTarget();
218
    }
219
     /* this method was implemented in the context of the CdmLinkSourceBeanProcessor which is unused
220
      *  method is preserved for the time when the REST API will be revised (#8637)
221
    @Override
222
    public CdmLinkSource getCdmSource() {
223
        if(cdmSource != null){
224
            logger.error("NOT NULL");
225
        }
226
        return cdmSource;
227
    }
228
	*/
229

    
230
//	@Override
231
//    public void setCdmSource(CdmLinkSource cdmSource) {
232
//        this.cdmSource = cdmSource;
233
//    }
234

    
235
    @Override
236
    public void setCdmSource(ICdmTarget cdmTarget){
237
        if (cdmTarget != null){
238
            this.cdmSource = CdmLinkSource.NewInstance(cdmTarget);
239
        }else{
240
            if (cdmSource != null){
241
                cdmSource.setTarget(null);  //as long as orphan-removal does not work #9801
242
            }
243
            this.cdmSource = null;
244
        }
245
    }
246

    
247
//********************** External Links **********************************************
248

    
249
    public Set<ExternalLink> getLinks(){
250
        return this.links;
251
    }
252
    public void setLinks(Set<ExternalLink> links){
253
        this.links = links;
254
    }
255
    public void addLink(ExternalLink link){
256
        if (link != null){
257
            links.add(link);
258
        }
259
    }
260
    public void removeLink(ExternalLink link){
261
        if(links.contains(link)) {
262
            links.remove(link);
263
        }
264
    }
265

    
266
//********************** CLONE ************************************************/
267

    
268
	@Override
269
	public OriginalSourceBase clone() throws CloneNotSupportedException{
270

    
271
        OriginalSourceBase result = (OriginalSourceBase)super.clone();
272

    
273
		Set<ExternalLink> links = new HashSet<>();
274
		result.setLinks(links);
275
		for(ExternalLink link : this.links){
276
		    result.addLink(link.clone());
277
		}
278

    
279
		if (this.cdmSource != null){
280
		    result.setCdmSource(this.cdmSource.getTarget());
281
		}
282

    
283
        if (this.accessed != null) {
284
            result.accessed = this.accessed.clone();
285
        }
286

    
287
		//no changes to: type, idInSource, idNamespace,
288
		//   citation, citationMicroReference, originalInfo
289
		return result;
290
	}
291

    
292
// **************** EMPTY ************************/
293

    
294
    @Override
295
    protected boolean checkEmpty(){
296
        return checkEmpty(false);
297
    }
298

    
299
    /**
300
     * Checks if the source is completely empty.
301
     *
302
     * @param excludeType if <code>true</code> the source type
303
     * is ignored for the check.
304
     *
305
     * @see #checkEmpty()
306
     * @return <code>true</code> if empty
307
     */
308
    public boolean checkEmpty(boolean excludeType){
309
	   return super.checkEmpty()
310
	        && (excludeType || this.type == null)
311
	        && this.getCitation() == null
312
	        && isBlank(this.getCitationMicroReference())
313
	        && isBlank(this.getOriginalInfo())
314
	        && isBlank(this.getIdInSource())
315
	        && isBlank(this.getIdNamespace())
316
	        && (this.accessed == null || this.accessed.isEmpty())
317
	        && this.links.isEmpty()
318
	        && this.cdmSource == null
319
           ;
320
	}
321

    
322
//************************ toString ***************************************/
323

    
324
	@Override
325
	public String toString(){
326
		if (isNotBlank(idInSource) || isNotBlank(idNamespace) ){
327
			return "OriginalSource:" + CdmUtils.concat(":", idNamespace, idInSource);
328
		}else{
329
			return super.toString();
330
		}
331
	}
332

    
333
//*********************************** EQUALS *********************************************************/
334

    
335
    /**
336
     * Indicates whether some other object is "equal to" this one.
337
     *
338
     * Uses a content based compare strategy which avoids bean initialization. This is achieved by
339
     * comparing the cdm entity ids.
340
     */
341
    public boolean equalsByShallowCompare(OriginalSourceBase other) {
342

    
343
        int thisCitationId = -1;
344
        int otherCitationId = -1;
345
        if(this.getCitation() != null) {
346
            thisCitationId = this.getCitation().getId();
347
        }
348
        if(other.getCitation() != null) {
349
            otherCitationId = other.getCitation().getId();
350
        }
351

    
352
        if(thisCitationId != otherCitationId
353
                || !StringUtils.equals(this.getCitationMicroReference(), other.getCitationMicroReference())
354
                || !StringUtils.equals(this.getOriginalInfo(), other.getOriginalInfo())
355
                        ){
356
            return false;
357
        }
358

    
359
        if(!StringUtils.equals(this.getIdInSource(), other.getIdInSource())
360
                || !CdmUtils.nullSafeEqual(this.getIdNamespace(), other.getIdNamespace())
361
                || !CdmUtils.nullSafeEqual(this.getType(), other.getType())
362
                || !TimePeriod.equalsNullAndEmptySafe(accessed, other.getAccessed())
363
                || !CdmUtils.nullSafeEqual(this.getCdmSource(), other.getCdmSource())
364
                || !CdmUtils.nullSafeEqual(this.getLinks(), other.getLinks())) {
365
            return false;
366
        }
367

    
368
        return true;
369
    }
370
}
(34-34/41)