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