001/** 002 * Copyright 2005-2016 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 */ 016package org.kuali.rice.krad.uif.container; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.rice.krad.uif.component.Component; 020import org.kuali.rice.krad.uif.component.DataBinding; 021import org.kuali.rice.krad.uif.component.ComponentSecurity; 022import org.kuali.rice.krad.uif.field.Field; 023import org.kuali.rice.krad.uif.field.FieldGroup; 024import org.kuali.rice.krad.uif.view.View; 025import org.kuali.rice.krad.uif.widget.Disclosure; 026 027import java.util.ArrayList; 028import java.util.HashSet; 029import java.util.List; 030import 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 */ 052public 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 060 private List<? extends Component> items; 061 062 /** 063 * Default Constructor 064 */ 065 public Group() { 066 items = new ArrayList<Component>(); 067 } 068 069 /** 070 * The following actions are performed: 071 * 072 * <ul> 073 * <li>Sets the bindByNamePrefix if blank on any InputField and 074 * FieldGroup instances within the items List</li> 075 * </ul> 076 * 077 * @see org.kuali.rice.krad.uif.component.ComponentBase#performInitialization(org.kuali.rice.krad.uif.view.View, java.lang.Object) 078 */ 079 @Override 080 public void performInitialization(View view, Object model) { 081 super.performInitialization(view, model); 082 083 for (Component component : getItems()) { 084 // append group's field bind by name prefix (if set) to each 085 // attribute field's binding prefix 086 if (component instanceof DataBinding) { 087 DataBinding dataBinding = (DataBinding) component; 088 089 if (StringUtils.isNotBlank(getFieldBindByNamePrefix())) { 090 String bindByNamePrefixToSet = getFieldBindByNamePrefix(); 091 092 if (StringUtils.isNotBlank(dataBinding.getBindingInfo().getBindByNamePrefix())) { 093 bindByNamePrefixToSet += "." + dataBinding.getBindingInfo().getBindByNamePrefix(); 094 } 095 dataBinding.getBindingInfo().setBindByNamePrefix(bindByNamePrefixToSet); 096 } 097 098 if (StringUtils.isNotBlank(fieldBindingObjectPath) && 099 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}