Project

General

Profile

Download (9.77 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 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
package eu.etaxonomy.cdm.model.name;
10

    
11
import java.util.HashSet;
12
import java.util.Set;
13

    
14
import javax.persistence.Basic;
15
import javax.persistence.Column;
16
import javax.persistence.Entity;
17
import javax.persistence.FetchType;
18
import javax.persistence.ManyToMany;
19
import javax.persistence.ManyToOne;
20
import javax.validation.constraints.NotNull;
21
import javax.xml.bind.annotation.XmlAccessType;
22
import javax.xml.bind.annotation.XmlAccessorType;
23
import javax.xml.bind.annotation.XmlAttribute;
24
import javax.xml.bind.annotation.XmlElement;
25
import javax.xml.bind.annotation.XmlElementWrapper;
26
import javax.xml.bind.annotation.XmlIDREF;
27
import javax.xml.bind.annotation.XmlSchemaType;
28
import javax.xml.bind.annotation.XmlType;
29
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
30

    
31
import org.apache.log4j.Logger;
32
import org.hibernate.annotations.Cascade;
33
import org.hibernate.annotations.CascadeType;
34
import org.hibernate.annotations.Type;
35
import org.hibernate.envers.Audited;
36
import org.hibernate.search.annotations.IndexedEmbedded;
37
import org.joda.time.DateTime;
38

    
39
import eu.etaxonomy.cdm.jaxb.DateTimeAdapter;
40
import eu.etaxonomy.cdm.model.agent.Institution;
41
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
42
import eu.etaxonomy.cdm.model.permission.User;
43
import eu.etaxonomy.cdm.validation.annotation.NullOrNotEmpty;
44

    
45
/**
46
 * A registration represents a nomenclatural act, either a {@link TaxonName taxon name}
47
 * registration or a {@link TypeDesignationBase type} registration.
48
 * <p>
49
 * The name and all type designations associated with the Registration must share
50
 * the same citation and citation detail.
51
 *
52
 * @author a.mueller
53
 * @since 13.03.2017
54
 */
55

    
56
@XmlAccessorType(XmlAccessType.FIELD)
57
@XmlType(name = "Registration", propOrder = {
58
    "identifier",
59
    "specificIdentifier",
60
    "registrationDate",
61
    "status",
62
    "institution",
63
    "name",
64
    "typeDesignations",
65
    "blockedBy",
66
    "submitter"
67
})
68
@Entity
69
@Audited
70
public class Registration extends AnnotatableEntity {
71

    
72
    private static final long serialVersionUID = -5633923579539766801L;
73
    private static final Logger logger = Logger.getLogger(Registration.class);
74

    
75
    @XmlElement(name = "Identifier")
76
    @NullOrNotEmpty
77
    @Column(length=255)
78
    private String identifier;
79

    
80
    //id without http-domain
81
    @XmlElement(name = "SpecificIdentifier")
82
    @NullOrNotEmpty
83
    @Column(length=255)
84
    private String specificIdentifier;
85

    
86
    @XmlElement (name = "RegistrationDate", type= String.class)
87
    @XmlJavaTypeAdapter(DateTimeAdapter.class)
88
    @Type(type="dateTimeUserType")
89
    //TODO ??
90
    @Basic(fetch = FetchType.LAZY)
91
//    @Field(analyze = Analyze.NO)
92
//    @FieldBridge(impl = DateTimeBridge.class)
93
    private DateTime registrationDate;
94

    
95
    @XmlAttribute(name ="Status")
96
    @Column(name="status", length=10)
97
    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
98
        parameters = {@org.hibernate.annotations.Parameter(name  = "enumClass", value = "eu.etaxonomy.cdm.model.name.RegistrationStatus")}
99
    )
100
    @NotNull
101
    private RegistrationStatus status = RegistrationStatus.PREPARATION;
102

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

    
111
    @XmlElement(name = "Name")
112
    @XmlIDREF
113
    @XmlSchemaType(name = "IDREF")
114
    @ManyToOne(fetch = FetchType.LAZY)
115
//    @IndexedEmbedded(includeEmbeddedObjectId=true)
116
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
117
    private TaxonName name;
118

    
119
    @XmlElementWrapper(name = "TypeDesignations")
120
    @XmlElement(name = "TypeDesignation")
121
    @XmlIDREF
122
    @XmlSchemaType(name = "IDREF")
123
    @ManyToMany(fetch = FetchType.LAZY)
124
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
125
    @NotNull
126
    private Set<TypeDesignationBase> typeDesignations = new HashSet<>();
127

    
128
    @XmlElementWrapper(name = "BlockingRegistrations")
129
    @XmlElement(name = "BlockedBy")
130
    @XmlIDREF
131
    @XmlSchemaType(name = "IDREF")
132
    @ManyToMany(fetch = FetchType.LAZY)
133
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
134
    @NotNull
135
    private Set<Registration> blockedBy = new HashSet<>();
136

    
137
    @XmlElement (name = "Submitter")
138
    @XmlIDREF
139
    @XmlSchemaType(name = "IDREF")
140
    @ManyToOne(fetch=FetchType.LAZY)
141
    private User submitter;
142

    
143
// ****************** Factory ******************/
144

    
145
    public static Registration NewInstance(){
146
        return new Registration();
147
    }
148

    
149

    
150
    /**
151
     * @param identifier
152
     * @param specificIdentifier
153
     * @param name can be <code>null</code>
154
     * @param typeDesignations can be <code>null</code>
155
     * @return
156
     */
157
    public static Registration NewInstance(String identifier, String specificIdentifier,
158
            TaxonName name, Set<TypeDesignationBase> typeDesignations){
159
        Registration result = new Registration();
160
        result.setIdentifier(identifier);
161
        result.setSpecificIdentifier(specificIdentifier);
162
        result.setName(name);
163
        if (typeDesignations != null){
164
            result.setTypeDesignations(typeDesignations);
165
        }
166
        return result;
167
    }
168

    
169
// **************** CONSTRUCTOR ****************/
170

    
171
    private Registration(){}
172

    
173

    
174

    
175
// *************** GETTER / SETTER  *************/
176

    
177
    public String getIdentifier() {return identifier;}
178
    public void setIdentifier(String identifier) {this.identifier = identifier;}
179

    
180
    public String getSpecificIdentifier() {return specificIdentifier;}
181
    public void setSpecificIdentifier(String specificIdentifier) {this.specificIdentifier = specificIdentifier;}
182

    
183
    public RegistrationStatus getStatus() {return status;}
184

    
185
    /**
186
     * Sets the status to the passed value.
187
     * <p>
188
     * In most situations where the registration is controlled in a strict
189
     * workflow you may want to use {@link #updateStatusAndDate(RegistrationStatus)} instead.
190
     *
191
     * @param status
192
     */
193
    public void setStatus(RegistrationStatus status) {this.status = status;}
194
    /**
195
     * Sets the {@link RegistrationStatus} of the registration and manages the {@link #registrationDate}
196
     * at the same time:
197
     * <ul>
198
     * <li>It will be set to <code>now</code> when the
199
     * {@link #status} is set to {@link RegistrationStatus#PUBLISHED}.</li>
200
     * <li>Removal of the
201
     * <code>PUBLISHED</code> state will cause the the registrationDate to be reset to <code>null</code>.</li>
202
     * </ul>
203
     *
204
     * @param status
205
     */
206
    public void updateStatusAndDate(RegistrationStatus status) {
207
        if(status != this.status){
208
            if(status == RegistrationStatus.PUBLISHED){
209
                setRegistrationDate(DateTime.now());
210
            } else if(this.status == RegistrationStatus.PUBLISHED){
211
                setRegistrationDate(null);
212
            }
213
            setStatus(status);
214
        }
215
    }
216

    
217
    public DateTime getRegistrationDate() {return registrationDate;}
218
    public void setRegistrationDate(DateTime registrationDate) {this.registrationDate = registrationDate;}
219

    
220
    public Institution getInstitution() {return institution;}
221
    public void setInstitution(Institution institution) {this.institution = institution;}
222

    
223
    public TaxonName getName() {return name;}
224
    public void setName(TaxonName name) {
225
        if (this.name != null && !this.name.equals(name)){
226
            this.name.getRegistrations().remove(this);
227
        }
228
        if (name != null && !name.equals(this.name)){
229
            name.getRegistrations().add(this);
230
        }
231
        this.name = name;
232
    }
233

    
234
    public User getSubmitter() {return submitter;}
235
    public void setSubmitter(User submitter) {this.submitter = submitter;}
236

    
237
    public Set<Registration> getBlockedBy() {return blockedBy;}
238
    @SuppressWarnings("unused")
239
    private void setBlockedBy(Set<Registration> blockedBy) {this.blockedBy = blockedBy;}
240
    public void addBlockedBy(Registration blockingRegistration) {
241
        this.blockedBy.add(blockingRegistration);
242
    }
243
    public void removeBlockedBy(Registration blockingRegistration) {
244
        this.blockedBy.remove(blockingRegistration);
245
    }
246

    
247
    public Set<TypeDesignationBase> getTypeDesignations() {return typeDesignations;}
248
    public void setTypeDesignations(Set<TypeDesignationBase> typeDesignations) {
249
        this.typeDesignations = typeDesignations;
250
    }
251

    
252
    public void addTypeDesignation(TypeDesignationBase designation) {
253
        this.typeDesignations.add(designation);
254
        if (!designation.getRegistrations().contains(this)){
255
            designation.getRegistrations().add(this);
256
        }
257
    }
258
    public void removeTypeDesignation(TypeDesignationBase designation) {
259
        this.typeDesignations.remove(designation);
260
        if (designation.getRegistrations().contains(this)){
261
            designation.getRegistrations().remove(this);
262
        }
263
    }
264

    
265
    @Override
266
    public Registration clone() {
267
        try {
268
            Registration result = (Registration)super.clone();
269

    
270
            result.blockedBy = new HashSet<>();
271
            for (Registration blockedByReg: this.blockedBy){
272
                result.addBlockedBy(blockedByReg);
273
            }
274

    
275
            result.typeDesignations = new HashSet<>();
276
            for (TypeDesignationBase<?> typeDesignation: this.typeDesignations){
277
                result.addTypeDesignation(typeDesignation);
278
            }
279

    
280

    
281
            //no changes to: identifier, institution, registrationDate, specificIdentifier,
282
            //status, submitter
283
            return result;
284
        } catch (CloneNotSupportedException e) {
285
            logger.warn("Object does not implement cloneable");
286
            e.printStackTrace();
287
            return null;
288
        }
289

    
290
    }
291

    
292
}
(30-30/43)