1 /**
2 * Copyright 2005-2011 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.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/ecl2.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.component.Component;
20 import org.kuali.rice.krad.uif.component.DataBinding;
21 import org.kuali.rice.krad.uif.field.Field;
22 import org.kuali.rice.krad.uif.field.FieldGroup;
23 import org.kuali.rice.krad.uif.view.View;
24 import org.kuali.rice.krad.uif.widget.Disclosure;
25
26 import java.util.ArrayList;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Set;
30
31 /**
32 * Container that holds a list of <code>Field</code> or other <code>Group</code>
33 * instances
34 *
35 * <p>
36 * Groups can exist at different levels of the <code>View</code>, providing
37 * conceptual groupings such as the page, section, and group. In addition, other
38 * group types can be created to add behavior like collection support
39 * </p>
40 *
41 * <p>
42 * <code>Group</code> implementation has properties for defaulting the binding
43 * information (such as the parent object path and a binding prefix) for the
44 * fields it contains. During the phase these properties (if given) are set on
45 * the fields contained in the <code>Group</code> that implement
46 * <code>DataBinding</code>, unless they have already been set on the field.
47 * </p>
48 *
49 * @author Kuali Rice Team (rice.collab@kuali.org)
50 */
51 public class Group extends ContainerBase {
52 private static final long serialVersionUID = 7953641325356535509L;
53
54 private String fieldBindByNamePrefix;
55 private String fieldBindingObjectPath;
56
57 private Disclosure disclosure;
58
59 private List<? extends Component> items;
60
61 /**
62 * Default Constructor
63 */
64 public Group() {
65 items = new ArrayList<Component>();
66 }
67
68 /**
69 * The following actions are performed:
70 *
71 * <ul>
72 * <li>Sets the bindByNamePrefix if blank on any InputField and
73 * FieldGroup instances within the items List</li>
74 * </ul>
75 *
76 * @see org.kuali.rice.krad.uif.component.ComponentBase#performInitialization(org.kuali.rice.krad.uif.view.View, java.lang.Object)
77 */
78 @Override
79 public void performInitialization(View view, Object model) {
80 super.performInitialization(view, model);
81
82 for (Component component : getItems()) {
83 // append group's field bind by name prefix (if set) to each
84 // attribute field's binding prefix
85 if (component instanceof DataBinding) {
86 DataBinding dataBinding = (DataBinding) component;
87
88 if (StringUtils.isNotBlank(getFieldBindByNamePrefix())) {
89 String bindByNamePrefixToSet = getFieldBindByNamePrefix();
90
91 if (StringUtils.isNotBlank(dataBinding.getBindingInfo().getBindByNamePrefix())) {
92 bindByNamePrefixToSet += "." + dataBinding.getBindingInfo().getBindByNamePrefix();
93 }
94 dataBinding.getBindingInfo().setBindByNamePrefix(bindByNamePrefixToSet);
95 }
96
97 if (StringUtils.isNotBlank(fieldBindingObjectPath) &&
98 StringUtils.isBlank(dataBinding.getBindingInfo().getBindingObjectPath())) {
99 dataBinding.getBindingInfo().setBindingObjectPath(fieldBindingObjectPath);
100 }
101 }
102 // set on FieldGroup's group to recursively set AttributeFields
103 else if (component instanceof FieldGroup) {
104 FieldGroup fieldGroup = (FieldGroup) component;
105
106 if (fieldGroup.getGroup() != null) {
107 if (StringUtils.isBlank(fieldGroup.getGroup().getFieldBindByNamePrefix())) {
108 fieldGroup.getGroup().setFieldBindByNamePrefix(fieldBindByNamePrefix);
109 }
110 if (StringUtils.isBlank(fieldGroup.getGroup().getFieldBindingObjectPath())) {
111 fieldGroup.getGroup().setFieldBindingObjectPath(fieldBindingObjectPath);
112 }
113 }
114 } else if (component instanceof Group) {
115 Group subGroup = (Group) component;
116 if (StringUtils.isNotBlank(getFieldBindByNamePrefix())) {
117 if (StringUtils.isNotBlank(subGroup.getFieldBindByNamePrefix())) {
118 subGroup.setFieldBindByNamePrefix(
119 getFieldBindByNamePrefix() + "." + subGroup.getFieldBindByNamePrefix());
120 } else {
121 subGroup.setFieldBindByNamePrefix(getFieldBindByNamePrefix());
122 }
123 }
124 }
125 }
126 }
127
128 /**
129 * @see org.kuali.rice.krad.uif.component.ComponentBase#getComponentsForLifecycle()
130 */
131 @Override
132 public List<Component> getComponentsForLifecycle() {
133 List<Component> components = super.getComponentsForLifecycle();
134
135 components.add(disclosure);
136
137 return components;
138 }
139
140 /**
141 * @see org.kuali.rice.krad.web.view.container.ContainerBase#getSupportedComponents()
142 */
143 @Override
144 public Set<Class<? extends Component>> getSupportedComponents() {
145 Set<Class<? extends Component>> supportedComponents = new HashSet<Class<? extends Component>>();
146 supportedComponents.add(Field.class);
147 supportedComponents.add(Group.class);
148
149 return supportedComponents;
150 }
151
152 /**
153 * @see org.kuali.rice.krad.uif.component.Component#getComponentTypeName()
154 */
155 @Override
156 public final String getComponentTypeName() {
157 return "group";
158 }
159
160 /**
161 * Binding prefix string to set on each of the groups <code>DataField</code> instances
162 *
163 * <p>
164 * As opposed to setting the bindingPrefix on each attribute field instance,
165 * it can be set here for the group. During initialize the string will then
166 * be set on each attribute field instance if the bindingPrefix is blank and
167 * not a form field
168 * </p>
169 *
170 * @return String binding prefix to set
171 */
172 public String getFieldBindByNamePrefix() {
173 return this.fieldBindByNamePrefix;
174 }
175
176 /**
177 * Setter for the field binding prefix
178 *
179 * @param fieldBindByNamePrefix
180 */
181 public void setFieldBindByNamePrefix(String fieldBindByNamePrefix) {
182 this.fieldBindByNamePrefix = fieldBindByNamePrefix;
183 }
184
185 /**
186 * Object binding path to set on each of the group's
187 * <code>InputField</code> instances
188 *
189 * <p>
190 * When the attributes of the group belong to a object whose path is
191 * different from the default then this property can be given to set each of
192 * the attributes instead of setting the model path on each one. The object
193 * path can be overridden at the attribute level. The object path is set to
194 * the fieldBindingObjectPath during the initialize phase.
195 * </p>
196 *
197 * @return String model path to set
198 * @see org.kuali.rice.krad.uif.BindingInfo.getBindingObjectPath()
199 */
200 public String getFieldBindingObjectPath() {
201 return this.fieldBindingObjectPath;
202 }
203
204 /**
205 * Setter for the field object binding path
206 *
207 * @param fieldBindingObjectPath
208 */
209 public void setFieldBindingObjectPath(String fieldBindingObjectPath) {
210 this.fieldBindingObjectPath = fieldBindingObjectPath;
211 }
212
213 /**
214 * Disclosure widget that provides collapse/expand functionality for the
215 * group
216 *
217 * @return Accordion instance
218 */
219 public Disclosure getDisclosure() {
220 return this.disclosure;
221 }
222
223 /**
224 * Setter for the group's disclosure instance
225 *
226 * @param disclosure
227 */
228 public void setDisclosure(Disclosure disclosure) {
229 this.disclosure = disclosure;
230 }
231
232 /**
233 * @see org.kuali.rice.krad.uif.container.ContainerBase#getItems()
234 */
235 @Override
236 public List<? extends Component> getItems() {
237 return this.items;
238 }
239
240 /**
241 * Setter for the Group's list of components
242 *
243 * @param items
244 */
245 @Override
246 public void setItems(List<? extends Component> items) {
247 this.items = items;
248 }
249
250 }