]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateOp.java
Allow UpdateOps to describe parent resource
[simantics/interop.git] / org.simantics.interop.update / src / org / simantics / interop / update / model / UpdateOp.java
1 package  org.simantics.interop.update.model;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.List;
6
7 import org.simantics.db.ReadGraph;
8 import org.simantics.db.Resource;
9 import org.simantics.db.Statement;
10 import org.simantics.db.WriteGraph;
11 import org.simantics.db.exception.DatabaseException;
12 import org.simantics.interop.test.GraphChanges;
13 import org.simantics.layer0.Layer0;
14
15 /**
16  * Base class for update operations (adding and deleting objects)  
17  * 
18  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
19  *
20  */
21 public abstract class UpdateOp {
22         
23         private GraphChanges changes;
24         
25         private boolean selected = false;
26         private boolean manualSelection = false;
27         protected boolean applied = false;
28         protected boolean visible = true;
29         protected boolean enabled = true;
30         
31         private Collection<UpdateOp> parentOps = new ArrayList<UpdateOp>();
32         private Collection<UpdateOp> subOps = new ArrayList<UpdateOp>();
33         
34         
35         public UpdateOp(GraphChanges changes) {
36                 this.changes = changes;
37         }
38         
39         public Collection<UpdateOp> getParentOps() {
40                 return parentOps;
41         }
42         
43         public <T extends UpdateOp> Collection<T> getParentOpsWithClass(Class<T> cls) {
44                 List<T> ops = new ArrayList<T>(parentOps.size());
45                 for (UpdateOp op : parentOps)
46                         if (cls.isAssignableFrom(op.getClass()))
47                                 ops.add((T)op);
48                 return ops;
49         }
50         
51         public Collection<UpdateOp> getSubOps() {
52                 return subOps;
53         }
54         
55         public <T extends UpdateOp> Collection<T> getSubOpsWithClass(Class<T> cls) {
56                 List<T> ops = new ArrayList<T>(subOps.size());
57                 for (UpdateOp op : subOps)
58                         if (cls.isAssignableFrom(op.getClass()))
59                                 ops.add((T)op);
60                 return ops;
61         }
62         
63         public void addParentOp(UpdateOp op) {
64                 assert (!op.equals(this));
65                 if (parentOps.contains(op))
66                         return;
67                 parentOps.add(op);
68         }
69         
70         public void addSubOp(UpdateOp op) {
71                 assert (!op.equals(this));
72                 if (subOps.contains(op))
73                         return;
74                 subOps.add(op);
75         }
76         
77         public void removeParentOp(UpdateOp op) {
78                 parentOps.remove(op);
79         }
80         
81         public void removeSubOp(UpdateOp op) {
82                 subOps.remove(op);
83         }
84         
85         public GraphChanges getChanges() {
86                 return changes;
87         }
88         
89         public abstract boolean isAdd();
90         public abstract boolean isDelete();
91         
92         public boolean isChange() {
93                 return isAdd() || isDelete();
94         }
95                 
96         /**
97          * Should given operation to be applied before this operation.
98          * @param op
99          * @return
100          */
101         public boolean requiresOp(UpdateOp op) {
102             return false;
103         }
104         
105         /**
106          * Should selection state to be propagated to given op.
107          * @param op parent or sub op of this.
108          * @param select selection flag.
109          * @return
110          */
111         public boolean selectOp(UpdateOp op, boolean select) {
112             return requiresOp(op);
113     }
114         
115         public boolean select(boolean select) {
116             if (!enabled)
117                 return false;
118             if (!isChange())
119                 return false;
120                 boolean b = _select(select);
121                 if (b)
122                         manualSelection = true;
123                 return b;
124         }
125
126         private boolean _select(boolean select) {
127                 if (select == selected)
128                         return true;
129                 if (applied)
130                         return false;
131                 if (select) {
132                     selected = true;
133             manualSelection = false;
134                     for (UpdateOp op : parentOps) {
135                         if (selectOp(op,true))
136                    op._select(true);
137             }
138                         for (UpdateOp op : subOps) {
139                             if (selectOp(op,true))
140                    op._select(true);
141             }
142                         return true;
143                 } else {
144                         selected = false;
145                         manualSelection = false;
146                         for (UpdateOp op : subOps) {
147                             if (selectOp(op, false))
148                     op._select(false);
149                 else if (!op.manualSelection)
150                     op._select(false);
151             }
152                         for (UpdateOp op : parentOps)
153                            if (selectOp(op, false))
154                   op._select(false);
155                         return true;
156                 }
157         }
158         
159         public boolean selected() {
160             if (!isChange())
161                 // Non change operations are not really selected, but the selected flag may be used for selection propagation
162                 return false;
163                 return selected;
164         }
165         
166         public boolean applied() {
167                 return applied;
168         }
169         
170         public boolean isVisible() {
171                 return visible;
172         }
173         
174         /**
175      * Is change enabled. Disabled changes do not allow changing selected state.
176      * @return
177      */
178     public boolean enabled() {
179         return enabled;
180     }
181     
182     public void setEnabled(boolean enabled) {
183         this.enabled = enabled;
184     }
185         
186         
187         public void apply(WriteGraph g) throws DatabaseException {
188                 if (applied)
189                         return;
190                 _apply(g);
191                 applied = true;
192                 
193         }
194         
195         /**
196          * Applies the changes into the database.
197          * 
198          * @param g
199          * @throws DatabaseException
200          */
201         protected abstract void _apply(WriteGraph g) throws DatabaseException;
202         
203         /**
204          * Returns resource that this operation is changing.
205          * @return
206          */
207         public abstract Resource getResource();
208         
209         /**
210          * Returns resource that this operation is changing.
211          * @return
212          */
213         public abstract Statement getStatement();
214         
215         /**
216          * Returns resource that this operation created during apply operation. If operation did not add anything, this returns null.
217          * @return
218          */
219         public abstract Resource getCreatedResource();
220         
221         public Resource getParentResource(ReadGraph g) throws DatabaseException {
222                 Layer0 l0 = Layer0.getInstance(g);
223                 return g.getPossibleObject(getResource(), l0.PartOf);
224         }
225
226         
227         @Override
228     public String toString() {
229         String s = this.getClass().getSimpleName();
230         if (selected)
231             s += " selected";
232         if (enabled)
233             s += " enabled";
234         if (visible)
235             s += " visible";
236         if (applied)
237             s += " applied";
238         return s;
239     }
240
241 }