Salome HOME
The draft of the "Copy from existing study" action is added. The YACS step is introdu...
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / dal / bo / kernel / Entity.java
1 package org.splat.dal.bo.kernel;
2
3 /**
4  * Abstract root class of persistent objects supporting relations to other persistent objects.<br/>
5  * Relations are instances of concrete subclasses of Relation that are assigned to Entity objects at run time.<br/>
6  * <br/>
7  * Entity objects also support dynamic attributes provided by the Any class.
8  * 
9  * @see Relation
10  * @author    Daniel Brunier-Coulin
11  * @copyright OPEN CASCADE 2012
12  */
13
14 import java.util.ArrayList;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Set;
18
19 import org.splat.kernel.InvalidPropertyException;
20 import org.splat.kernel.MissedPropertyException;
21 import org.splat.kernel.MultiplyDefinedException;
22 import org.splat.kernel.ObjectProperties;
23 import org.splat.log.AppLogger;
24
25 /**
26  * Persistent entity class. Entity can have relations to other persistent objects.
27  */
28 public abstract class Entity extends Any {
29
30         /**
31          * The service logger.
32          */
33         public final static AppLogger LOG = AppLogger.getLogger(Entity.class);
34
35         /**
36          * Persistent collection of relations to other persistent objects.
37          */
38         private final Set<Relation> relations = new HashSet<Relation>(); // NOPMD:RKV: mapped as field
39
40         /**
41          * Database fetch constructor.
42          */
43         protected Entity() {
44                 super();
45         }
46
47         /**
48          * Initialization constructor.
49          * 
50          * @param prop
51          *            object properties
52          * @throws MissedPropertyException
53          *             if some mandatory property is missed
54          * @throws InvalidPropertyException
55          *             if some property has invalid value
56          * @throws MultiplyDefinedException
57          *             if some property is defined several times
58          */
59         protected Entity(final ObjectProperties prop)
60                         throws MissedPropertyException, InvalidPropertyException,
61                         MultiplyDefinedException {
62                 super(prop);
63         }
64
65         // ==============================================================================================================================
66         // Public member functions
67         // ==============================================================================================================================
68
69         /**
70          * Get first relation of the given type.
71          * 
72          * @param type
73          *            the relation type to look for
74          * @return the found relation or null
75          */
76         public Relation getFirstRelation(final Class<? extends Relation> type) {
77                 Relation found = null;
78                 for (Relation link : relations) {
79                         if (link.getClass().equals(type)) {
80                                 found = link;
81                         }
82                 }
83                 return found;
84         }
85
86         /**
87          * Get list of all relations of the given type.
88          * 
89          * @param type
90          *            the relation type to look for
91          * @return the list if found relations
92          */
93         public List<Relation> getRelations(final Class<? extends Relation> type) {
94                 List<Relation> result = new ArrayList<Relation>();
95
96                 for (Relation link : relations) {
97                         if (link.getClass().equals(type)) {
98                                 result.add(link);
99                         }
100                 }
101                 return result;
102         }
103
104         // ==============================================================================================================================
105         // Protected services
106         // ==============================================================================================================================
107
108         /**
109          * Get persistent collection of relations.
110          * 
111          * @return entity relations set
112          */
113         public Set<Relation> getAllRelations() {
114                 return relations;
115         }
116
117         /**
118          * Add a relation for the entity. If the link is bidirectional then also add the reverse link to the referenced object.
119          * 
120          * @param link
121          *            the relation from this entity to some persistent object
122          * @return the reverse link if the given link is bidirectional otherwise returns the given link
123          */
124         public Relation addRelation(final Relation link) {
125
126                 Relation back = link;
127                 relations.add(link);
128
129                 if (link.isBidirectional()) {
130                         Entity to = (Entity) link.getTo(); // Bidirectional relation are necessarily between entities
131
132                         back = link.getReverse();
133                         to.relations.add(back);
134                 }
135                 return back;
136         }
137
138         /**
139          * Remove the first relation of the given type to the given object.
140          * 
141          * @param type
142          *            the type of the relation to remove
143          * @param to
144          *            the referenced object to identify the relation to remove
145          * @return the removed relation
146          */
147         public Relation removeRelation(final Class<? extends Relation> type,
148                         final Persistent to) {
149                 Relation res = null;
150                 if (LOG.isDebugEnabled()) {
151                         LOG.debug("Try to remove the link " + type.getSimpleName()
152                                         + " from " + this.toString() + " to " + to.toString());
153                 }
154                 for (Relation link : relations) {
155                         if (LOG.isDebugEnabled()) {
156                                 LOG.debug("Compare the link " + link.toString());
157                                 LOG.debug("link.getClass().equals(type): "
158                                                 + link.getClass().equals(type));
159                         }
160                         if (link.getClass().equals(type) && link.getTo().equals(to)) {
161                                 if (LOG.isDebugEnabled()) {
162                                         LOG.debug("Remove the link "
163                                                         + link.getClass().getSimpleName() + " from "
164                                                         + this.toString() + " to " + to.toString());
165                                 }
166                                 res = link;
167                                 break;
168                         }
169                 }
170                 if (res != null) {
171                         if (LOG.isDebugEnabled()) {
172                                 LOG.debug("Contains: " + this.getAllRelations().contains(res));
173                                 LOG.debug("Nb relations of this before: "
174                                                 + this.getAllRelations().size());
175                         }
176                         res.owner = null;
177                         this.getAllRelations().remove(res);
178                         if (LOG.isDebugEnabled()) {
179                                 LOG.debug("Nb relations of this after: "
180                                                 + this.getAllRelations().size());
181                         }
182                         if (res.isBidirectional()) {
183                                 if (LOG.isDebugEnabled()) {
184                                         LOG.debug("Nb relations of reverse before: "
185                                                         + ((Entity) res.getTo()).getAllRelations().size());
186                                 }
187                                 ((Entity) res.getTo()).getAllRelations().remove(
188                                                 res.getReverse());
189                                 if (LOG.isDebugEnabled()) {
190                                         LOG.debug("Nb relations of reverse after: "
191                                                         + ((Entity) res.getTo()).getAllRelations().size());
192                                 }
193                         }
194                 }
195                 return res;
196         }
197
198         /**
199          * {@inheritDoc}
200          * 
201          * @see org.splat.dal.bo.kernel.Any#evict()
202          */
203         @Override
204         public void evict() {
205                 super.evict();
206                 // Evict all attributes of the persistent object
207                 Set<Relation> tmpSet = new HashSet<Relation>();
208                 tmpSet.addAll(relations);
209                 relations.clear();
210                 // Evict relations
211                 for (Relation rel : tmpSet) {
212                         if (rel.isSaved()) { // to avoid recursive evict
213                                 rel.evict();
214                         }
215                         relations.add(rel);
216                 }
217         }
218 }