2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.model
.reference
;
13 import java
.util
.HashSet
;
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
;
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
;
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
;
52 * Abstract base class for classes implementing {@link eu.etaxonomy.cdm.model.reference.IOriginalSource IOriginalSource}.
53 * @see eu.etaxonomy.cdm.model.reference.IOriginalSource
56 * @since 08-Nov-2007 13:06:22
59 @XmlAccessorType(XmlAccessType
.FIELD
)
60 @XmlType(name
= "OriginalSource", propOrder
= {
66 "citationMicroReference",
70 @XmlRootElement(name
= "OriginalSource")
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
{
79 private static final long serialVersionUID
= -1972959999261181462L;
80 @SuppressWarnings("unused")
81 private static final Logger logger
= Logger
.getLogger(OriginalSourceBase
.class);
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
88 @XmlAttribute(name
="type")
89 @Column(name
="sourceType")
91 @Type(type
= "eu.etaxonomy.cdm.hibernate.EnumUserType",
92 parameters
= {@org.hibernate
.annotations
.Parameter(name
="enumClass", value
="eu.etaxonomy.cdm.model.reference.OriginalSourceType")}
95 private OriginalSourceType type
;
97 //The object's ID in the source, where the alternative string comes from
98 @XmlElement(name
= "IdInSource")
99 private String idInSource
;
101 @XmlElement(name
= "IdNamespace")
102 private String idNamespace
;
104 @XmlElement(name
= "Citation")
106 @XmlSchemaType(name
= "IDREF")
107 @ManyToOne(fetch
= FetchType
.LAZY
)
108 @Cascade({CascadeType
.SAVE_UPDATE
,CascadeType
.MERGE
})
109 private Reference citation
;
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
;
116 @XmlElement(name
= "OriginalNameString")
117 private String originalNameString
;
119 @XmlElement(name
= "CdmSource")
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
;
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
<>();
133 //***************** CONSTRUCTOR ***********************/
135 //for hibernate use only
136 protected OriginalSourceBase() {
144 protected OriginalSourceBase(OriginalSourceType type
){
146 throw new IllegalArgumentException("OriginalSourceType must not be null");
151 //**************** GETTER / SETTER *******************************/
154 public OriginalSourceType
getType() {
158 public void setType(OriginalSourceType type
) {
159 Assert
.notNull(type
, "OriginalSourceType must not be null");
164 public String
getIdInSource(){
165 return this.idInSource
;
168 public void setIdInSource(String idInSource
){
169 this.idInSource
= idInSource
;
173 public String
getIdNamespace() {
177 public void setIdNamespace(String idNamespace
) {
178 this.idNamespace
= idNamespace
;
182 public Reference
getCitation(){
183 return this.citation
;
186 public void setCitation(Reference citation
) {
187 this.citation
= citation
;
191 public String
getCitationMicroReference(){
192 return this.citationMicroReference
;
195 public void setCitationMicroReference(String citationMicroReference
){
196 this.citationMicroReference
= citationMicroReference
;
199 public String
getOriginalNameString(){
200 return this.originalNameString
;
202 public void setOriginalNameString(String originalNameString
){
203 this.originalNameString
= originalNameString
;
207 public ICdmTarget
getCdmSource() {
208 return cdmSource
== null?
null: cdmSource
.getTarget();
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)
213 public CdmLinkSource getCdmSource() {
214 if(cdmSource != null){
215 logger.error("NOT NULL");
223 // public void setCdmSource(CdmLinkSource cdmSource) {
224 // this.cdmSource = cdmSource;
227 public void setCdmSource(ICdmTarget cdmTarget
){
228 if (cdmTarget
!= null){
229 this.cdmSource
= CdmLinkSource
.NewInstance(cdmTarget
);
231 this.cdmSource
= null;
235 //********************** External Links **********************************************
238 public Set
<ExternalLink
> getLinks(){
241 public void setLinks(Set
<ExternalLink
> links
){
244 public void addLink(ExternalLink link
){
249 public void removeLink(ExternalLink link
){
250 if(links
.contains(link
)) {
255 //********************** CLONE ************************************************/
258 public OriginalSourceBase
<T
> clone() throws CloneNotSupportedException
{
260 @SuppressWarnings("unchecked")
261 OriginalSourceBase
<T
> result
= (OriginalSourceBase
<T
>)super.clone();
263 Set
<ExternalLink
> links
= new HashSet
<>();
264 result
.setLinks(links
);
265 for(ExternalLink link
: this.links
){
266 result
.addLink(link
.clone());
269 if (this.cdmSource
!= null){
270 result
.setCdmSource(this.cdmSource
.getTarget());
273 //no changes to: type, idInSource, idNamespace,
274 // citation, citationMicroReference, originalNameString
278 // **************** EMPTY ************************/
281 protected boolean checkEmpty(){
282 return checkEmpty(false);
286 * Checks if the source is completely empty.
288 * @param excludeType if <code>true</code> the source type
289 * is ignored for the check.
292 * @return <code>true</code> if empty
294 public boolean checkEmpty(boolean excludeType
){
295 return super.checkEmpty()
296 && (excludeType
|| this.type
== null)
297 && this.getCitation() == null
298 && isBlank(this.getCitationMicroReference())
299 && isBlank(this.getOriginalNameString())
300 && isBlank(this.getIdInSource())
301 && isBlank(this.getIdNamespace())
302 && this.links
.isEmpty()
303 && this.cdmSource
== null
307 //************************ toString ***************************************/
309 public String
toString(){
310 if (isNotBlank(idInSource
) || isNotBlank(idNamespace
) ){
311 return "OriginalSource:" + CdmUtils
.concat(":", idNamespace
, idInSource
);
313 return super.toString();
317 //*********************************** EQUALS *********************************************************/
320 * Indicates whether some other object is "equal to" this one.
322 * Uses a content based compare strategy which avoids bean initialization. This is achieved by
323 * comparing the cdm entity ids.
325 public boolean equalsByShallowCompare(OriginalSourceBase
<T
> other
) {
327 int thisCitationId
= -1;
328 int otherCitationId
= -1;
329 if(this.getCitation() != null) {
330 thisCitationId
= this.getCitation().getId();
332 if(other
.getCitation() != null) {
333 otherCitationId
= other
.getCitation().getId();
336 if(thisCitationId
!= otherCitationId
337 || !StringUtils
.equals(this.getCitationMicroReference(), other
.getCitationMicroReference())
338 || !StringUtils
.equals(this.getOriginalNameString(), other
.getOriginalNameString())
343 OriginalSourceBase
<T
> theOther
= other
;
344 if(!StringUtils
.equals(this.getIdInSource(), theOther
.getIdInSource())
345 || !CdmUtils
.nullSafeEqual(this.getIdNamespace(), theOther
.getIdNamespace())
346 || !CdmUtils
.nullSafeEqual(this.getType(), theOther
.getType())
347 || !CdmUtils
.nullSafeEqual(this.getCdmSource(), theOther
.getCdmSource())
348 || !CdmUtils
.nullSafeEqual(this.getLinks(), theOther
.getLinks())) {