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