Salome HOME
Refactoring: kernel and som are moved to Siman-Common.
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / kernel / Relation.java
1 package org.splat.kernel;
2 /**
3  * Base implementation of relations between entities.<br/>
4  * A relation makes a typed link from an entity to any kind persistent object. The relations are typed by subclasses of this
5  * abstract class which define the actual object referenced by the relation.<br/>
6  * This Relation base class implements unidirectional relations. The bidirectionality must be implemented in concrete subclasses
7  * by:
8  * <ul>
9  * <li>overriding the isBidirectional() and getReverseClass() methods,</li>
10  * <li>creating the reverse relation in constructors.</li>
11  * </ul>
12  * Relation objects also support dynamic attributes provided by the Any class.
13  * 
14  * @see Entity
15  * @author    Daniel Brunier-Coulin
16  * @copyright OPEN CASCADE 2012
17  */
18
19 import java.util.Iterator;
20
21 import org.hibernate.Session;
22
23
24 public abstract class Relation extends Any {
25
26 //  Persistent fields
27         protected  Entity   owner;        // Study or Document
28
29 //  Transient field
30     protected  Relation reverse;
31
32 //  ==============================================================================================================================
33 //  Constructors
34 //  ==============================================================================================================================
35
36 //  Database fetch constructor
37     protected Relation () {
38 //  ---------------------
39       reverse = null;
40     }
41 //  Initialization constructor
42     protected Relation (Entity from) {
43 //  --------------------------------
44       super((Attribute)null);       // For building the collection of attributes
45       this.owner   = from;
46       this.reverse = null;          // Initialized by subclasses
47     }
48
49 //  ==============================================================================================================================
50 //  Public member functions
51 //  ==============================================================================================================================
52
53     public Entity getFrom () {
54 //  ------------------------
55       return owner;
56     }
57
58     public Relation getReverse () {
59 //  -----------------------------
60       if (!this.isBidirectional() || reverse != null) return reverse;
61
62       Class<? extends Relation> type = this.getReverseClass();
63       Entity                    to   = (Entity)this.getTo();   // Bidirectional relations are necessarily between Entities
64
65       for (Iterator<Relation> i=to.getAllRelations().iterator(); i.hasNext(); ) {
66         Relation asked = i.next();
67         if (!asked.getClass().equals(type)) continue;
68         if (!asked.getTo().equals(owner))   continue;
69         reverse = asked;
70         reverse.reverse = this;     // For benefiting from this execution
71         return reverse;
72       }
73       return null;
74     }
75
76     public Class<? extends Relation> getReverseClass () {
77 //  ---------------------------------------------------
78       return null;
79     }
80
81     public boolean isBidirectional () {
82 //  ---------------------------------
83       return false;
84     }
85
86 /**
87  * Moves this relation from its current owner entity to the given one.
88  * 
89  * @param nowner the document to which this relation is moved
90  * */
91     public void moveTo (Entity nowner) {
92 //  ----------------------------------
93       Session  session = Database.getSession();
94
95       this.owner = nowner;
96       nowner.getAllRelations().add(this);
97 //    myold.getAllRelations().remove(this);  Harmful as it leads to remove this relation from the database (!?)
98       session.update(this);
99       session.update(nowner);
100
101       if (this.isBidirectional()) {
102         Relation  link = this.getReverse();
103         link.setTo(nowner);
104         session.update(link);
105       }
106     }
107
108 //  ==============================================================================================================================
109 //  Abstract functions
110 //  ==============================================================================================================================
111
112     public    abstract Persistent getTo ();
113     protected abstract void       setTo (Persistent to);         // For the need of the moveTo() method
114 }