Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
PartPresenter |
|
| 1.8095238095238095;1.81 |
1 | /* | |
2 | * Copyright (c) 2009, Swiss Federal Department of Defence Civil Protection and Sport | |
3 | * (http://www.vbs.admin.ch) | |
4 | * Copyright (c) 2009, Ergon Informatik AG (http://www.ergon.ch) | |
5 | * All rights reserved. | |
6 | * | |
7 | * Licensed under the Open Permis License which accompanies this distribution, | |
8 | * and is available at http://www.openpermis.org/BSDlicenceKent.txt | |
9 | */ | |
10 | package org.openpermis.editor.policy.presenter; | |
11 | ||
12 | import java.util.ArrayList; | |
13 | import java.util.List; | |
14 | ||
15 | import org.jdesktop.observablecollections.ObservableCollections; | |
16 | import org.jdesktop.observablecollections.ObservableList; | |
17 | import org.jdesktop.observablecollections.ObservableListListener; | |
18 | ||
19 | import org.openpermis.editor.policy.beans.PropertyChangeDispatcher; | |
20 | import org.openpermis.editor.policy.command.Command; | |
21 | import org.openpermis.editor.policy.command.PropertyChangeCommand; | |
22 | import org.openpermis.policy.bean.ActionBean; | |
23 | import org.openpermis.policy.bean.AuthorityBean; | |
24 | import org.openpermis.policy.bean.DomainBean; | |
25 | import org.openpermis.policy.bean.ObligationBean; | |
26 | import org.openpermis.policy.bean.PartBean; | |
27 | import org.openpermis.policy.bean.PartBeanFactory; | |
28 | import org.openpermis.policy.bean.SerialNumber; | |
29 | import org.openpermis.policy.bean.TargetBean; | |
30 | ||
31 | /** | |
32 | * Abstract base class for all presenters that work on a part bean. | |
33 | * @param <M> the type of part bean of this presenter. | |
34 | * @since 0.1.0 | |
35 | */ | |
36 | public abstract class PartPresenter<M extends PartBean> | |
37 | extends Presenter<M> | |
38 | { | |
39 | ||
40 | //---- State | |
41 | ||
42 | /** | |
43 | * The property change dispatcher for the model. | |
44 | * @since 0.1.0 | |
45 | */ | |
46 | private final PropertyChangeDispatcher changeDispatcher; | |
47 | ||
48 | /** | |
49 | * The policy context. | |
50 | * @since 0.1.0 | |
51 | */ | |
52 | private final PolicyContext context; | |
53 | ||
54 | //---- Constructors | |
55 | ||
56 | /** | |
57 | * Creates a new part presenter for the specified model. | |
58 | * @param model the part bean that this presenter works on, must not be {@code null}. | |
59 | * @param context the context of the policy. | |
60 | * @since 0.1.0 | |
61 | */ | |
62 | public PartPresenter (M model, PolicyContext context) { | |
63 | 9 | super(model); |
64 | 9 | this.context = context; |
65 | 9 | this.changeDispatcher = new PropertyChangeDispatcher(getModel(), this); |
66 | 9 | } |
67 | ||
68 | //---- Methods | |
69 | ||
70 | /** | |
71 | * Check if the part beans are equivalent with respect to serial number. | |
72 | * @param one the first bean. | |
73 | * @param two the second bean. | |
74 | * @return {@code true} if they are equivalent. | |
75 | * @since 0.1.0 | |
76 | */ | |
77 | protected boolean sameSerial (PartBean one, PartBean two) { | |
78 | 0 | if (one == null || two == null) { |
79 | 0 | return one == two; |
80 | } | |
81 | 0 | return one.equalSerialNumber(two); |
82 | } | |
83 | ||
84 | /** | |
85 | * Checks if a collection contains a partbean. | |
86 | * @return true if exists, false else | |
87 | * @since 0.1.0 | |
88 | */ | |
89 | protected <T extends PartBean> boolean containsSerial (Iterable<T> collection, T part) { | |
90 | 0 | for (T other : collection) { |
91 | 0 | if (sameSerial(part, other)) { |
92 | 0 | return true; |
93 | } | |
94 | } | |
95 | 0 | return false; |
96 | } | |
97 | ||
98 | /** | |
99 | * Gets index of a PartBean in a collection. | |
100 | * @return index>=0 if exists, -1 else | |
101 | * @since 0.1.0 | |
102 | */ | |
103 | protected <T extends PartBean> int indexOfBySerial (List<T> list, T part) { | |
104 | 0 | for (int i = 0 ; i < list.size() ; i++) { |
105 | 0 | if (sameSerial(part, list.get(i))) { |
106 | 0 | return i; |
107 | } | |
108 | } | |
109 | 0 | return -1; |
110 | } | |
111 | ||
112 | /** | |
113 | * Returns the serial number of the model attached to this presenter. | |
114 | * @return the serial number of the model attached to this presenter. | |
115 | * @since 0.1.0 | |
116 | */ | |
117 | public final SerialNumber getModelSerialNumber () { | |
118 | 0 | return getModel().getSerialNumber(); |
119 | } | |
120 | ||
121 | /** | |
122 | * Returns the part bean factory to use when creating new parts. | |
123 | * @return the part bean factory to use when creating new parts. | |
124 | * @since 0.1.0 | |
125 | */ | |
126 | protected PartBeanFactory getPartBeanFactory () { | |
127 | 0 | return this.context.getPartBeanFactory(); |
128 | } | |
129 | ||
130 | /** | |
131 | * Returns the policy context. | |
132 | * @return Returns the policy context. | |
133 | * @since 0.1.0 | |
134 | */ | |
135 | public PolicyContext getContext () { | |
136 | 0 | return this.context; |
137 | } | |
138 | ||
139 | /** | |
140 | * Returns the policy pool. | |
141 | * @return Returns the policy pool. | |
142 | * @since 0.1.0 | |
143 | */ | |
144 | public PolicyPartPool<ActionBean> getActionPool () { | |
145 | 0 | return this.context.getActionPool(); |
146 | } | |
147 | ||
148 | /** | |
149 | * Returns the policy pool for obligations. | |
150 | * @return Returns the policy pool for obligations. | |
151 | * @since 0.3.0 | |
152 | */ | |
153 | public PolicyPartPool<ObligationBean> getObligationPool () { | |
154 | 0 | return this.context.getObligationPool(); |
155 | } | |
156 | ||
157 | /** | |
158 | * Returns the policy pool for authorities. | |
159 | * @return the policy pool for authorities. | |
160 | * @since 0.3.0 | |
161 | */ | |
162 | public PolicyPartPool<AuthorityBean> getAuthorityPool () { | |
163 | 0 | return this.context.getAuthorityPool(); |
164 | } | |
165 | ||
166 | /** | |
167 | * Returns the policy pool. | |
168 | * @return Returns the policy pool. | |
169 | * @since 0.1.0 | |
170 | */ | |
171 | public PolicyPartPool<DomainBean> getResourceDomainPool () { | |
172 | 0 | return this.context.getResourceDomainPool(); |
173 | } | |
174 | ||
175 | /** | |
176 | * Returns the policy pool. | |
177 | * @return Returns the policy pool. | |
178 | * @since 0.3.0 | |
179 | */ | |
180 | public PolicyPartPool<DomainBean> getSubjectDomainPool () { | |
181 | 0 | return this.context.getSubjectDomainPool(); |
182 | } | |
183 | ||
184 | /** | |
185 | * Returns the policy pool. | |
186 | * @return Returns the policy pool. | |
187 | * @since 0.1.0 | |
188 | */ | |
189 | public PolicyPartPool<TargetBean> getTargetPool () { | |
190 | 0 | return this.context.getTargetPool(); |
191 | } | |
192 | ||
193 | /** | |
194 | * Returns the role pool. | |
195 | * @return the role pool. | |
196 | * @since 0.3.0 | |
197 | */ | |
198 | public PolicyRoleRefPool getRolePool () { | |
199 | 0 | return this.context.getRolePool(); |
200 | } | |
201 | ||
202 | /** | |
203 | * Creates a command that performs a change on a part. | |
204 | * @param part the part to modify. | |
205 | * @param property the property to set. | |
206 | * @param value the value to set. | |
207 | * @since 0.1.0 | |
208 | */ | |
209 | protected Command createChangeCommand (PartBean part, String property, Object value) { | |
210 | 0 | return new PropertyChangeCommand(part, property, value); |
211 | } | |
212 | ||
213 | /** | |
214 | * Performs a change on the model of this presenter. | |
215 | * @param property the property to set. | |
216 | * @param value the value to set. | |
217 | * @since 0.1.0 | |
218 | */ | |
219 | protected void change (String property, Object value) { | |
220 | 0 | change(getModel(), property, value); |
221 | 0 | } |
222 | ||
223 | /** | |
224 | * Performs a change on a part. | |
225 | * @param part the part to modify. | |
226 | * @param property the property to set. | |
227 | * @param value the value to set. | |
228 | * @since 0.1.0 | |
229 | */ | |
230 | protected void change (PartBean part, String property, Object value) { | |
231 | 0 | execute(createChangeCommand(part, property, value)); |
232 | 0 | } |
233 | ||
234 | /** | |
235 | * Executes a command using the built-in dispatcher. | |
236 | * @param command the command to execute. | |
237 | * @since 0.1.0 | |
238 | */ | |
239 | protected void execute (Command command) { | |
240 | 0 | this.context.getCommandDispatcher().execute(command); |
241 | 0 | } |
242 | ||
243 | /** | |
244 | * Creates the initial presenter list for the specified model list. | |
245 | * @param modelCollection the modelcollection to create the presenter list for. | |
246 | * @return the list, never {@code null}. | |
247 | * @since 0.1.0 | |
248 | */ | |
249 | protected <P> ObservableList<P> createCollectionAtPresenter ( | |
250 | Iterable<P> modelCollection | |
251 | ) { | |
252 | 0 | final List<P> list = new ArrayList<P>(); |
253 | 0 | for (P part : modelCollection) { |
254 | 0 | list.add(part); |
255 | } | |
256 | 0 | return ObservableCollections.observableList(list); |
257 | } | |
258 | ||
259 | /** | |
260 | * Writes the parts in the presenter according to the model. | |
261 | * @since 0.1.0 | |
262 | */ | |
263 | protected <P extends PartBean> void updateCollectionAtPresenter ( | |
264 | Iterable<P> modelCollection, | |
265 | ObservableList<P> presenterCollection, | |
266 | ObservableListListener listener | |
267 | ) { | |
268 | 0 | final List<P> add = new ArrayList<P>(); |
269 | 0 | final List<P> remove = new ArrayList<P>(); |
270 | ||
271 | // check for new elements | |
272 | 0 | for (P part : modelCollection) { |
273 | 0 | if (!containsSerial(presenterCollection, part)) { |
274 | 0 | add.add(part); |
275 | } | |
276 | } | |
277 | ||
278 | // check for removed elements | |
279 | 0 | for (P part : presenterCollection) { |
280 | 0 | if (!containsSerial(modelCollection, part)) { |
281 | 0 | remove.add(part); |
282 | } | |
283 | } | |
284 | ||
285 | // do the add/remove | |
286 | 0 | presenterCollection.removeObservableListListener(listener); |
287 | 0 | for (P toAdd : add) { |
288 | 0 | presenterCollection.add(toAdd); |
289 | } | |
290 | 0 | for (P toRemove : remove) { |
291 | 0 | final int index = indexOfBySerial(presenterCollection, toRemove); |
292 | 0 | if (index != -1) { |
293 | 0 | presenterCollection.remove(index); |
294 | } | |
295 | 0 | } |
296 | 0 | presenterCollection.addObservableListListener(listener); |
297 | 0 | } |
298 | ||
299 | //---- Presenter | |
300 | ||
301 | /** | |
302 | * @since 0.1.0 | |
303 | */ | |
304 | @Override | |
305 | public void dispose () { | |
306 | 0 | this.changeDispatcher.dispose(); |
307 | 0 | } |
308 | ||
309 | } |