minor
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / RelationshipBase.java
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.common;
11
12 import java.util.HashSet;
13 import java.util.Set;
14
15 import javax.persistence.MappedSuperclass;
16 import javax.persistence.Transient;
17 import javax.xml.bind.annotation.XmlAccessType;
18 import javax.xml.bind.annotation.XmlAccessorType;
19 import javax.xml.bind.annotation.XmlAttribute;
20 import javax.xml.bind.annotation.XmlEnum;
21 import javax.xml.bind.annotation.XmlEnumValue;
22 import javax.xml.bind.annotation.XmlRootElement;
23 import javax.xml.bind.annotation.XmlTransient;
24 import javax.xml.bind.annotation.XmlType;
25
26 import org.apache.log4j.Logger;
27 import org.hibernate.envers.Audited;
28
29 import eu.etaxonomy.cdm.model.reference.Reference;
30
31 /**
32 * Concrete implementations of this abstract base class express a directed relationship between two
33 * cdm entities ( {@link IRelated} ). The most important properties of the relationship are:
34 * <ul>
35 * <li>{@link #getRelatedFrom(IRelated)}</li>
36 * <li>{@link #getRelatedTo(IRelated)}</li>
37 * <li>The {@code <TYPE>}, a RelationshipTermBase which specifies the kind of the relationship</li>
38 * </ul>
39 * A relationship thus is forming a directed graph consisting of two nodes and an edge:
40 * <pre>
41 relatedFrom -----[TYPE]----> relatedTo
42 </pre>
43 * Whereas the direction of the relation can be valid for the direct (everted) and also for the inverted {@link Direction} direction.
44 * This directional validity is defined by {@link RelationshipTermBase#isSymmetric()}
45 *
46 *
47 *
48 * @author m.doering
49 * @author a.kohlbecker (Documentation)
50 */
51 @XmlAccessorType(XmlAccessType.FIELD)
52 @XmlType(name = "RelationshipBase")
53 @XmlRootElement(name = "RelationshipBase")
54 @MappedSuperclass
55 @Audited
56 public abstract class RelationshipBase<FROM extends IRelated, TO extends IRelated, TYPE extends RelationshipTermBase> extends ReferencedEntityBase implements Cloneable {
57 private static final long serialVersionUID = -5030154633820061997L;
58 @SuppressWarnings("unused")
59 private static final Logger logger = Logger.getLogger(RelationshipBase.class);
60
61 @XmlAttribute(name = "isDoubtful")
62 private boolean doubtful;
63
64 //this set is used only for persistence (CdmDeleteListener) to delete safely relationships and update their former related objects
65 @XmlTransient
66 @Transient
67 protected Set<IRelated> deletedObjects = new HashSet<IRelated>();
68
69
70 /**
71 * Enumeration and String representation of the <code>relatedFrom</code> (invers) and
72 * <code>relatedTo</code> (direct, everted) bean properties. Intended to be used in the
73 * persistence layer only.( But also used in the service layer now - a.kohlbecker )
74 *
75 * See also {@link RelationshipBase} for an explanation on relationships in general.
76 */
77 @XmlEnum
78 public enum Direction {
79 @XmlEnumValue("relatedFrom")
80 relatedFrom,
81 @XmlEnumValue("relatedTo")
82 relatedTo
83 }
84
85 protected RelationshipBase(){
86 super();
87 }
88
89 /**
90 * Creates a relationship between 2 objects and adds it to the respective
91 * relation sets of both objects.
92 *
93 * @param from
94 * @param to
95 * @param type
96 * @param citation
97 * @param citationMicroReference
98 */
99 protected RelationshipBase(FROM from, TO to, TYPE type, Reference citation, String citationMicroReference) {
100 super(citation, citationMicroReference, null);
101 setRelatedFrom(from);
102 setRelatedTo(to);
103 setType(type);
104 from.addRelationship(this);
105 to.addRelationship(this);
106 }
107
108 public abstract TYPE getType();
109
110 public abstract void setType(TYPE type);
111
112 protected abstract FROM getRelatedFrom();
113
114 protected abstract void setRelatedFrom(FROM relatedFrom);
115
116 protected abstract TO getRelatedTo();
117
118 protected abstract void setRelatedTo(TO relatedTo);
119
120 /**
121 * A boolean flag that marks the relationship between two objects as doubtful
122 * Please be aware that this flag should not be used to mark any status of the
123 * objects themselves. E.g. when marking a synonym relationship as doubtful
124 * this means that it is doubtful that the synonym is really a synonym to the
125 * taxon. It does not mean that the synonym is doubtfully a synonym.
126 * @return true, if the relationship is doubtful, false otherwise
127 */
128 public boolean isDoubtful(){
129 return this.doubtful;
130 }
131
132 public void setDoubtful(boolean doubtful){
133 this.doubtful = doubtful;
134 }
135
136 public boolean isRemoved(){
137 if ( this.getRelatedFrom() == null ^ this.getRelatedTo() == null){
138 throw new IllegalStateException("A relationship may have only both related object as null or none. But just one is null!");
139 }
140 return this.getRelatedFrom() == null || this.getRelatedTo() == null;
141 }
142
143 public Set getDeletedObjects(){
144 return this.deletedObjects;
145 }
146
147 // TODO
148 // UUID toUuid;
149 // UUID fromUuid;
150 //
151 // @Transient
152 // public UUID getToUuidCache(){
153 // return relationTo.getUuid();
154 // }
155 // protected void setToUuid(UUID uuid){
156 // toUuid = uuid;
157 // }
158 //
159 // public UUID getFromUuid(){
160 // return relationTo.getUuid();
161 // }
162 // protected void setFromUuid(UUID uuid){
163 // fromUuid = uuid;
164 // }
165
166
167 //*********************** CLONE ********************************************************/
168
169 /**
170 * Clones <i>this</i> relationship. This is a shortcut that enables to create
171 * a new instance that differs only slightly from <i>this</i> relationship by
172 * modifying only some of the attributes.
173 * @throws CloneNotSupportedException
174 *
175 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#clone()
176 * @see java.lang.Object#clone()
177 */
178 @Override
179 public Object clone() throws CloneNotSupportedException {
180 RelationshipBase<FROM,TO,TYPE> result = (RelationshipBase<FROM,TO,TYPE>)super.clone();
181 //no changes to: doubtful, deletedObjects
182 return result;
183 }
184 }