View Javadoc

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