001 /** 002 * Copyright 2005-2012 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.krad.uif.container; 017 018 import org.apache.commons.lang.StringUtils; 019 import org.kuali.rice.krad.uif.component.Component; 020 import org.kuali.rice.krad.uif.component.DataBinding; 021 import org.kuali.rice.krad.uif.field.Field; 022 import org.kuali.rice.krad.uif.field.FieldGroup; 023 import org.kuali.rice.krad.uif.view.View; 024 import org.kuali.rice.krad.uif.widget.Scrollpane; 025 import org.kuali.rice.krad.uif.widget.Disclosure; 026 027 import java.util.ArrayList; 028 import java.util.HashSet; 029 import java.util.List; 030 import java.util.Set; 031 032 /** 033 * Container that holds a list of <code>Field</code> or other <code>Group</code> 034 * instances 035 * 036 * <p> 037 * Groups can exist at different levels of the <code>View</code>, providing 038 * conceptual groupings such as the page, section, and group. In addition, other 039 * group types can be created to add behavior like collection support 040 * </p> 041 * 042 * <p> 043 * <code>Group</code> implementation has properties for defaulting the binding 044 * information (such as the parent object path and a binding prefix) for the 045 * fields it contains. During the phase these properties (if given) are set on 046 * the fields contained in the <code>Group</code> that implement 047 * <code>DataBinding</code>, unless they have already been set on the field. 048 * </p> 049 * 050 * @author Kuali Rice Team (rice.collab@kuali.org) 051 */ 052 public class Group extends ContainerBase { 053 private static final long serialVersionUID = 7953641325356535509L; 054 055 private String fieldBindByNamePrefix; 056 private String fieldBindingObjectPath; 057 058 private Disclosure disclosure; 059 private Scrollpane scrollpane; 060 061 private List<? extends Component> items; 062 063 /** 064 * Default Constructor 065 */ 066 public Group() { 067 items = new ArrayList<Component>(); 068 } 069 070 /** 071 * The following actions are performed: 072 * 073 * <ul> 074 * <li>Sets the bindByNamePrefix if blank on any InputField and 075 * FieldGroup instances within the items List</li> 076 * </ul> 077 * 078 * @see org.kuali.rice.krad.uif.component.ComponentBase#performInitialization(org.kuali.rice.krad.uif.view.View, java.lang.Object) 079 */ 080 @Override 081 public void performInitialization(View view, Object model) { 082 super.performInitialization(view, model); 083 084 for (Component component : getItems()) { 085 // append group's field bind by name prefix (if set) to each 086 // attribute field's binding prefix 087 if (component instanceof DataBinding) { 088 DataBinding dataBinding = (DataBinding) component; 089 090 if (StringUtils.isNotBlank(getFieldBindByNamePrefix())) { 091 String bindByNamePrefixToSet = getFieldBindByNamePrefix(); 092 093 if (StringUtils.isNotBlank(dataBinding.getBindingInfo().getBindByNamePrefix())) { 094 bindByNamePrefixToSet += "." + dataBinding.getBindingInfo().getBindByNamePrefix(); 095 } 096 dataBinding.getBindingInfo().setBindByNamePrefix(bindByNamePrefixToSet); 097 } 098 099 if (StringUtils.isNotBlank(fieldBindingObjectPath) && 100 StringUtils.isBlank(dataBinding.getBindingInfo().getBindingObjectPath())) { 101 dataBinding.getBindingInfo().setBindingObjectPath(fieldBindingObjectPath); 102 } 103 } 104 // set on FieldGroup's group to recursively set AttributeFields 105 else if (component instanceof FieldGroup) { 106 FieldGroup fieldGroup = (FieldGroup) component; 107 108 if (fieldGroup.getGroup() != null) { 109 if (StringUtils.isBlank(fieldGroup.getGroup().getFieldBindByNamePrefix())) { 110 fieldGroup.getGroup().setFieldBindByNamePrefix(fieldBindByNamePrefix); 111 } 112 if (StringUtils.isBlank(fieldGroup.getGroup().getFieldBindingObjectPath())) { 113 fieldGroup.getGroup().setFieldBindingObjectPath(fieldBindingObjectPath); 114 } 115 } 116 } else if (component instanceof Group) { 117 Group subGroup = (Group) component; 118 if (StringUtils.isNotBlank(getFieldBindByNamePrefix())) { 119 if (StringUtils.isNotBlank(subGroup.getFieldBindByNamePrefix())) { 120 subGroup.setFieldBindByNamePrefix( 121 getFieldBindByNamePrefix() + "." + subGroup.getFieldBindByNamePrefix()); 122 } else { 123 subGroup.setFieldBindByNamePrefix(getFieldBindByNamePrefix()); 124 } 125 } 126 if (StringUtils.isNotBlank(getFieldBindingObjectPath())) { 127 if (StringUtils.isNotBlank(subGroup.getFieldBindingObjectPath())) { 128 subGroup.setFieldBindingObjectPath( 129 getFieldBindingObjectPath() + "." + subGroup.getFieldBindingObjectPath()); 130 } else { 131 subGroup.setFieldBindingObjectPath(getFieldBindingObjectPath()); 132 } 133 } 134 } 135 } 136 } 137 138 /** 139 * @see org.kuali.rice.krad.uif.component.ComponentBase#getComponentsForLifecycle() 140 */ 141 @Override 142 public List<Component> getComponentsForLifecycle() { 143 List<Component> components = super.getComponentsForLifecycle(); 144 145 components.add(disclosure); 146 components.add(scrollpane); 147 148 return components; 149 } 150 151 /** 152 * @see org.kuali.rice.krad.uif.container.Container#getSupportedComponents() 153 */ 154 @Override 155 public Set<Class<? extends Component>> getSupportedComponents() { 156 Set<Class<? extends Component>> supportedComponents = new HashSet<Class<? extends Component>>(); 157 supportedComponents.add(Field.class); 158 supportedComponents.add(Group.class); 159 160 return supportedComponents; 161 } 162 163 /** 164 * @see org.kuali.rice.krad.uif.component.Component#getComponentTypeName() 165 */ 166 @Override 167 public String getComponentTypeName() { 168 return "group"; 169 } 170 171 /** 172 * Binding prefix string to set on each of the groups <code>DataField</code> instances 173 * 174 * <p> 175 * As opposed to setting the bindingPrefix on each attribute field instance, 176 * it can be set here for the group. During initialize the string will then 177 * be set on each attribute field instance if the bindingPrefix is blank and 178 * not a form field 179 * </p> 180 * 181 * @return String binding prefix to set 182 */ 183 public String getFieldBindByNamePrefix() { 184 return this.fieldBindByNamePrefix; 185 } 186 187 /** 188 * Setter for the field binding prefix 189 * 190 * @param fieldBindByNamePrefix 191 */ 192 public void setFieldBindByNamePrefix(String fieldBindByNamePrefix) { 193 this.fieldBindByNamePrefix = fieldBindByNamePrefix; 194 } 195 196 /** 197 * Object binding path to set on each of the group's 198 * <code>InputField</code> instances 199 * 200 * <p> 201 * When the attributes of the group belong to a object whose path is 202 * different from the default then this property can be given to set each of 203 * the attributes instead of setting the model path on each one. The object 204 * path can be overridden at the attribute level. The object path is set to 205 * the fieldBindingObjectPath during the initialize phase. 206 * </p> 207 * 208 * @return String model path to set 209 * @see org.kuali.rice.krad.uif.component.BindingInfo#getBindingObjectPath() 210 */ 211 public String getFieldBindingObjectPath() { 212 return this.fieldBindingObjectPath; 213 } 214 215 /** 216 * Setter for the field object binding path 217 * 218 * @param fieldBindingObjectPath 219 */ 220 public void setFieldBindingObjectPath(String fieldBindingObjectPath) { 221 this.fieldBindingObjectPath = fieldBindingObjectPath; 222 } 223 224 /** 225 * Disclosure widget that provides collapse/expand functionality for the 226 * group 227 * 228 * @return Disclosure instance 229 */ 230 public Disclosure getDisclosure() { 231 return this.disclosure; 232 } 233 234 /** 235 * Setter for the group's disclosure instance 236 * 237 * @param disclosure 238 */ 239 public void setDisclosure(Disclosure disclosure) { 240 this.disclosure = disclosure; 241 } 242 243 /** 244 * Scrollpane widget that provides scrolling functionality for the 245 * group 246 * 247 * @return Scrollpane instance 248 */ 249 public Scrollpane getScrollpane() { 250 return this.scrollpane; 251 } 252 253 /** 254 * Setter for the group's scrollpane instance 255 * 256 * @param scrollpane 257 */ 258 public void setScrollpane(Scrollpane scrollpane) { 259 this.scrollpane = scrollpane; 260 } 261 262 /** 263 * @see org.kuali.rice.krad.uif.container.ContainerBase#getItems() 264 */ 265 @Override 266 public List<? extends Component> getItems() { 267 return this.items; 268 } 269 270 /** 271 * Setter for the Group's list of components 272 * 273 * @param items 274 */ 275 @Override 276 public void setItems(List<? extends Component> items) { 277 this.items = items; 278 } 279 280 }