Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ContainerBase |
|
| 1.4333333333333333;1.433 |
1 | /* | |
2 | * Copyright 2007 The Kuali Foundation | |
3 | * | |
4 | * Licensed under the Educational Community License, Version 1.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * | |
8 | * http://www.opensource.org/licenses/ecl1.php | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | package org.kuali.rice.krad.uif.container; | |
17 | ||
18 | import org.apache.commons.lang.StringUtils; | |
19 | import org.kuali.rice.krad.uif.core.Component; | |
20 | import org.kuali.rice.krad.uif.core.ComponentBase; | |
21 | import org.kuali.rice.krad.uif.field.AttributeField; | |
22 | import org.kuali.rice.krad.uif.field.ErrorsField; | |
23 | import org.kuali.rice.krad.uif.field.HeaderField; | |
24 | import org.kuali.rice.krad.uif.field.MessageField; | |
25 | import org.kuali.rice.krad.uif.layout.LayoutManager; | |
26 | import org.kuali.rice.krad.uif.util.ComponentUtils; | |
27 | import org.kuali.rice.krad.uif.widget.Help; | |
28 | ||
29 | import java.util.ArrayList; | |
30 | import java.util.List; | |
31 | ||
32 | /** | |
33 | * Base <code>Container</code> implementation which container implementations | |
34 | * can extend | |
35 | * | |
36 | * <p> | |
37 | * Provides properties for the basic <code>Container</code> functionality in | |
38 | * addition to default implementation of the lifecycle methods including some | |
39 | * setup of the header, items list, and layout manager | |
40 | * </p> | |
41 | * | |
42 | * @author Kuali Rice Team (rice.collab@kuali.org) | |
43 | */ | |
44 | public abstract class ContainerBase extends ComponentBase implements Container { | |
45 | private static final long serialVersionUID = -4182226230601746657L; | |
46 | ||
47 | private int itemOrderingSequence; | |
48 | ||
49 | private String additionalMessageKeys; | |
50 | private ErrorsField errorsField; | |
51 | ||
52 | private Help help; | |
53 | private LayoutManager layoutManager; | |
54 | ||
55 | private HeaderField header; | |
56 | private Group footer; | |
57 | ||
58 | private String summary; | |
59 | private MessageField summaryMessageField; | |
60 | ||
61 | private boolean fieldContainer; | |
62 | ||
63 | /** | |
64 | * Default Constructor | |
65 | */ | |
66 | 0 | public ContainerBase() { |
67 | 0 | itemOrderingSequence = 1; |
68 | 0 | } |
69 | ||
70 | /** | |
71 | * The following initialization is performed: | |
72 | * | |
73 | * <ul> | |
74 | * <li>Sorts the containers list of components</li> | |
75 | * <li>Initializes LayoutManager</li> | |
76 | * </ul> | |
77 | * | |
78 | * @see org.kuali.rice.krad.uif.core.ComponentBase#performInitialization(org.kuali.rice.krad.uif.container.View) | |
79 | */ | |
80 | @SuppressWarnings("unchecked") | |
81 | @Override | |
82 | public void performInitialization(View view) { | |
83 | 0 | super.performInitialization(view); |
84 | ||
85 | // sort items list by the order property | |
86 | 0 | List<? extends Component> sortedItems = (List<? extends Component>) ComponentUtils.sort(getItems(), |
87 | itemOrderingSequence); | |
88 | 0 | setItems(sortedItems); |
89 | ||
90 | 0 | if (layoutManager != null) { |
91 | 0 | layoutManager.performInitialization(view, this); |
92 | } | |
93 | 0 | } |
94 | ||
95 | /** | |
96 | * @see org.kuali.rice.krad.uif.core.ComponentBase#performApplyModel(org.kuali.rice.krad.uif.container.View, | |
97 | * java.lang.Object) | |
98 | */ | |
99 | @Override | |
100 | public void performApplyModel(View view, Object model, Component parent) { | |
101 | 0 | super.performApplyModel(view, model, parent); |
102 | ||
103 | 0 | if (layoutManager != null) { |
104 | 0 | layoutManager.performApplyModel(view, model, this); |
105 | } | |
106 | 0 | } |
107 | ||
108 | /** | |
109 | * The following finalization is performed: | |
110 | * | |
111 | * <ul> | |
112 | * <li>Sets the headerText of the header Group if it is blank</li> | |
113 | * <li>Set the messageText of the summary MessageField if it is blank</li> | |
114 | * <li>Finalizes LayoutManager</li> | |
115 | * </ul> | |
116 | * | |
117 | * @see org.kuali.rice.krad.uif.core.ComponentBase#performFinalize(org.kuali.rice.krad.uif.container.View, | |
118 | * java.lang.Object, org.kuali.rice.krad.uif.core.Component) | |
119 | */ | |
120 | @Override | |
121 | public void performFinalize(View view, Object model, Component parent) { | |
122 | 0 | super.performFinalize(view, model, parent); |
123 | ||
124 | // if header title not given, use the container title | |
125 | 0 | if (header != null && StringUtils.isBlank(header.getHeaderText())) { |
126 | 0 | header.setHeaderText(this.getTitle()); |
127 | } | |
128 | ||
129 | // setup summary message field if necessary | |
130 | 0 | if (summaryMessageField != null && StringUtils.isBlank(summaryMessageField.getMessageText())) { |
131 | 0 | summaryMessageField.setMessageText(summary); |
132 | } | |
133 | ||
134 | 0 | if (layoutManager != null) { |
135 | 0 | layoutManager.performFinalize(view, model, this); |
136 | } | |
137 | 0 | } |
138 | ||
139 | /** | |
140 | * @see org.kuali.rice.krad.uif.core.ComponentBase#getNestedComponents() | |
141 | */ | |
142 | @Override | |
143 | public List<Component> getNestedComponents() { | |
144 | 0 | List<Component> components = super.getNestedComponents(); |
145 | ||
146 | 0 | components.add(header); |
147 | 0 | components.add(footer); |
148 | 0 | components.add(errorsField); |
149 | 0 | components.add(help); |
150 | 0 | components.add(summaryMessageField); |
151 | ||
152 | 0 | for (Component component : getItems()) { |
153 | 0 | components.add(component); |
154 | } | |
155 | ||
156 | 0 | if (layoutManager != null) { |
157 | 0 | components.addAll(layoutManager.getNestedComponents()); |
158 | } | |
159 | ||
160 | 0 | return components; |
161 | } | |
162 | ||
163 | /** | |
164 | * Additional keys that should be matching on when gathering errors or other | |
165 | * messages for the <code>Container</code> | |
166 | * | |
167 | * <p> | |
168 | * Messages associated with the container will be displayed with the | |
169 | * container grouping in the user interface. Typically, these are a result | |
170 | * of problems with the containers fields or some other business logic | |
171 | * associated with the containers information. The framework will by default | |
172 | * include all the error keys for fields in the container, and also an | |
173 | * errors associated with the containers id. Keys given here will be matched | |
174 | * in addition to those defaults. | |
175 | * </p> | |
176 | * | |
177 | * <p> | |
178 | * Multple keys can be given using the comma delimiter, the * wildcard is | |
179 | * also allowed in the message key | |
180 | * </p> | |
181 | * | |
182 | * @return String additional message key string | |
183 | */ | |
184 | public String getAdditionalMessageKeys() { | |
185 | 0 | return this.additionalMessageKeys; |
186 | } | |
187 | ||
188 | /** | |
189 | * Setter for the components additional message key string | |
190 | * | |
191 | * @param additionalMessageKeys | |
192 | */ | |
193 | public void setAdditionalMessageKeys(String additionalMessageKeys) { | |
194 | 0 | this.additionalMessageKeys = additionalMessageKeys; |
195 | 0 | } |
196 | ||
197 | /** | |
198 | * @see org.kuali.rice.krad.uif.container.Container#getErrorsField() | |
199 | */ | |
200 | @Override | |
201 | public ErrorsField getErrorsField() { | |
202 | 0 | return this.errorsField; |
203 | } | |
204 | ||
205 | /** | |
206 | * @see org.kuali.rice.krad.uif.container.Container#setErrorsField(org.kuali.rice.krad.uif.field.ErrorsField) | |
207 | */ | |
208 | @Override | |
209 | public void setErrorsField(ErrorsField errorsField) { | |
210 | 0 | this.errorsField = errorsField; |
211 | 0 | } |
212 | ||
213 | /** | |
214 | * @see org.kuali.rice.krad.uif.container.Container#getHelp() | |
215 | */ | |
216 | @Override | |
217 | public Help getHelp() { | |
218 | 0 | return this.help; |
219 | } | |
220 | ||
221 | /** | |
222 | * @see org.kuali.rice.krad.uif.container.Container#setHelp(org.kuali.rice.krad.uif.widget.Help) | |
223 | */ | |
224 | @Override | |
225 | public void setHelp(Help help) { | |
226 | 0 | this.help = help; |
227 | 0 | } |
228 | ||
229 | /** | |
230 | * @see org.kuali.rice.krad.uif.container.Container#getItems() | |
231 | */ | |
232 | @Override | |
233 | public abstract List<? extends Component> getItems(); | |
234 | ||
235 | /** | |
236 | * Setter for the containers list of components | |
237 | * | |
238 | * @param items | |
239 | */ | |
240 | public abstract void setItems(List<? extends Component> items); | |
241 | ||
242 | /** | |
243 | * For <code>Component</code> instances in the container's items list that | |
244 | * do not have an order set, a default order number will be assigned using | |
245 | * this property. The first component found in the list without an order | |
246 | * will be assigned the configured initial value, and incremented by one for | |
247 | * each component (without an order) found afterwards | |
248 | * | |
249 | * @return int order sequence | |
250 | */ | |
251 | public int getItemOrderingSequence() { | |
252 | 0 | return this.itemOrderingSequence; |
253 | } | |
254 | ||
255 | /** | |
256 | * Setter for the container's item ordering sequence number (initial value) | |
257 | * | |
258 | * @param itemOrderingSequence | |
259 | */ | |
260 | public void setItemOrderingSequence(int itemOrderingSequence) { | |
261 | 0 | this.itemOrderingSequence = itemOrderingSequence; |
262 | 0 | } |
263 | ||
264 | /** | |
265 | * @see org.kuali.rice.krad.uif.container.Container#getLayoutManager() | |
266 | */ | |
267 | @Override | |
268 | public LayoutManager getLayoutManager() { | |
269 | 0 | return this.layoutManager; |
270 | } | |
271 | ||
272 | /** | |
273 | * @see org.kuali.rice.krad.uif.container.Container#setLayoutManager(org.kuali.rice.krad.uif.layout.LayoutManager) | |
274 | */ | |
275 | @Override | |
276 | public void setLayoutManager(LayoutManager layoutManager) { | |
277 | 0 | this.layoutManager = layoutManager; |
278 | 0 | } |
279 | ||
280 | /** | |
281 | * @see org.kuali.rice.krad.uif.container.Container#getHeader() | |
282 | */ | |
283 | @Override | |
284 | public HeaderField getHeader() { | |
285 | 0 | return this.header; |
286 | } | |
287 | ||
288 | /** | |
289 | * @see org.kuali.rice.krad.uif.container.Container#setHeader(org.kuali.rice.krad.uif.field.HeaderField) | |
290 | */ | |
291 | @Override | |
292 | public void setHeader(HeaderField header) { | |
293 | 0 | this.header = header; |
294 | 0 | } |
295 | ||
296 | /** | |
297 | * @see org.kuali.rice.krad.uif.container.Container#getFooter() | |
298 | */ | |
299 | @Override | |
300 | public Group getFooter() { | |
301 | 0 | return this.footer; |
302 | } | |
303 | ||
304 | /** | |
305 | * @see org.kuali.rice.krad.uif.container.Container#setFooter(org.kuali.rice.krad.uif.container.Group) | |
306 | */ | |
307 | @Override | |
308 | public void setFooter(Group footer) { | |
309 | 0 | this.footer = footer; |
310 | 0 | } |
311 | ||
312 | /** | |
313 | * Convenience setter for configuration to turn rendering of the header | |
314 | * on/off | |
315 | * | |
316 | * <p> | |
317 | * For nested groups (like Field Groups) it is often necessary to only show | |
318 | * the container body (the contained components). This method allows the | |
319 | * header to not be displayed | |
320 | * </p> | |
321 | * | |
322 | * @param renderHeader | |
323 | */ | |
324 | public void setRenderHeader(boolean renderHeader) { | |
325 | 0 | if (header != null) { |
326 | 0 | header.setRender(renderHeader); |
327 | } | |
328 | 0 | } |
329 | ||
330 | /** | |
331 | * Convenience setter for configuration to turn rendering of the footer | |
332 | * on/off | |
333 | * | |
334 | * <p> | |
335 | * For nested groups it is often necessary to only show the container body | |
336 | * (the contained components). This method allows the footer to not be | |
337 | * displayed | |
338 | * </p> | |
339 | * | |
340 | * @param renderFooter | |
341 | */ | |
342 | public void setRenderFooter(boolean renderFooter) { | |
343 | 0 | if (footer != null) { |
344 | 0 | footer.setRender(renderFooter); |
345 | } | |
346 | 0 | } |
347 | ||
348 | /** | |
349 | * Summary text for the container which will be used to set the summary | |
350 | * message field | |
351 | * | |
352 | * @return String summary text | |
353 | * @see org.kuali.rice.krad.uif.container.Container#getSummaryMessageField() | |
354 | */ | |
355 | public String getSummary() { | |
356 | 0 | return this.summary; |
357 | } | |
358 | ||
359 | /** | |
360 | * Setter for the containers summary text | |
361 | * | |
362 | * @param summary | |
363 | */ | |
364 | public void setSummary(String summary) { | |
365 | 0 | this.summary = summary; |
366 | 0 | } |
367 | ||
368 | /** | |
369 | * @see org.kuali.rice.krad.uif.container.Container#getSummaryMessageField() | |
370 | */ | |
371 | @Override | |
372 | public MessageField getSummaryMessageField() { | |
373 | 0 | return this.summaryMessageField; |
374 | } | |
375 | ||
376 | /** | |
377 | * @see org.kuali.rice.krad.uif.container.Container#setSummaryMessageField(org.kuali.rice.krad.uif.field.MessageField) | |
378 | */ | |
379 | @Override | |
380 | public void setSummaryMessageField(MessageField summaryMessageField) { | |
381 | 0 | this.summaryMessageField = summaryMessageField; |
382 | 0 | } |
383 | ||
384 | /** | |
385 | * Gets only the attribute fields that are nested in this container. This is a subset of | |
386 | * what getNestedComponents() returns. | |
387 | * | |
388 | * @return | |
389 | */ | |
390 | public List<AttributeField> getAttributeFields(){ | |
391 | 0 | List<AttributeField> attributeFields = new ArrayList<AttributeField>(); |
392 | 0 | for(Component c: this.getNestedComponents()){ |
393 | 0 | if(c instanceof AttributeField){ |
394 | 0 | attributeFields.add((AttributeField)c); |
395 | } | |
396 | } | |
397 | 0 | return attributeFields; |
398 | ||
399 | } | |
400 | ||
401 | /** | |
402 | * This property is true if the container is used to display a group of fields that is visually a single | |
403 | * field. | |
404 | * @return the fieldContainer | |
405 | */ | |
406 | public boolean isFieldContainer() { | |
407 | 0 | return this.fieldContainer; |
408 | } | |
409 | ||
410 | /** | |
411 | * @param fieldContainer the fieldContainer to set | |
412 | */ | |
413 | public void setFieldContainer(boolean fieldContainer) { | |
414 | 0 | this.fieldContainer = fieldContainer; |
415 | 0 | } |
416 | ||
417 | ||
418 | ||
419 | } |