001/**
002 * Copyright 2005-2015 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.control;
017
018import java.io.Serializable;
019import java.util.HashMap;
020import java.util.Map;
021
022import org.apache.commons.lang.StringUtils;
023import org.kuali.rice.kim.api.group.Group;
024import org.kuali.rice.kim.api.services.KimApiServiceLocator;
025import org.kuali.rice.krad.datadictionary.parse.BeanTag;
026import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
027import org.kuali.rice.krad.uif.field.InputField;
028import org.kuali.rice.krad.uif.util.ComponentFactory;
029import org.kuali.rice.krad.uif.util.LifecycleElement;
030import org.kuali.rice.krad.uif.widget.QuickFinder;
031
032/**
033 * Represents a group control, which is a special control to handle
034 * the input of a KIM Group by group name
035 *
036 * @author Kuali Rice Team (rice.collab@kuali.org)
037 */
038@BeanTag(name = "kimGroupControl", parent = "Uif-KimGroupControl")
039public class GroupControl extends TextControlBase implements FilterableLookupCriteriaControl {
040    private static final long serialVersionUID = 5598459655735440981L;
041
042    private String namespaceCodePropertyName;
043    private String groupIdPropertyName;
044
045    public GroupControl() {
046        super();
047    }
048
049    @Override
050    public void performApplyModel(Object model, LifecycleElement parent) {
051        super.performApplyModel(model, parent);
052
053        if (!(parent instanceof InputField)) {
054            return;
055        }
056
057        InputField field = (InputField) parent;
058
059        if (StringUtils.isNotBlank(groupIdPropertyName)) {
060            field.getAdditionalHiddenPropertyNames().add(groupIdPropertyName);
061        }
062
063        buildGroupQuickfinder(model, field);
064    }
065
066    protected void buildGroupQuickfinder(Object model, InputField field) {
067        QuickFinder quickFinder = field.getQuickfinder();
068
069        // don't build quickfinder if explicitly turned off
070        if (!field.isEnableAutoQuickfinder()) {
071            return;
072        }
073
074        if (quickFinder == null) {
075            quickFinder = ComponentFactory.getQuickFinder();
076            field.setQuickfinder(quickFinder);
077        }
078
079        if (field.getQuickfinder() != null) {
080            if (StringUtils.isBlank(field.getQuickfinder().getDataObjectClassName())) {
081                field.getQuickfinder().setDataObjectClassName("org.kuali.rice.kim.impl.group.GroupBo");
082            }
083
084            if (field.getQuickfinder().getFieldConversions().isEmpty()) {
085                if (StringUtils.isNotBlank(groupIdPropertyName)) {
086                    field.getQuickfinder().getFieldConversions().put("id", groupIdPropertyName);
087                }
088
089                field.getQuickfinder().getFieldConversions().put("name", field.getPropertyName());
090
091                if (StringUtils.isNotBlank(namespaceCodePropertyName)) {
092                    field.getQuickfinder().getFieldConversions().put("namespaceCode", namespaceCodePropertyName);
093                }
094            }
095
096            if (field.getQuickfinder().getLookupParameters().isEmpty()) {
097                if (StringUtils.isNotBlank(namespaceCodePropertyName)) {
098                    field.getQuickfinder().getLookupParameters().put(namespaceCodePropertyName, "namespaceCode");
099                }
100            }
101        }
102    }
103
104    /**
105     * {@inheritDoc}
106     */
107    @Override
108    public Map<String, String> filterSearchCriteria(String propertyName, Map<String, String> searchCriteria, FilterableLookupCriteriaControlPostData postData) {
109        Map<String, String> filteredSearchCriteria = new HashMap<String, String>(searchCriteria);
110
111        GroupControlPostData groupControlPostData = (GroupControlPostData) postData;
112
113        // check valid groupId
114        // ToDo: move the groupId check and setting to the validation stage.  At that point
115        //       an error should be displayed to the user that the group name and namespace is invalid.
116        String groupName = searchCriteria.get(propertyName);
117        String groupNamespaceCd = searchCriteria.get(groupControlPostData.getNamespaceCodePropertyName());
118        if (StringUtils.isNotBlank(groupName) && StringUtils.isNotBlank(groupNamespaceCd)) {
119            Group group = KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName(groupNamespaceCd,groupName);
120            if( group == null) {
121                return null;
122            } else {
123                filteredSearchCriteria.put(groupControlPostData.getGroupIdPropertyName(), group.getId());
124            }
125        }
126
127        // filter
128        filteredSearchCriteria.remove(propertyName);
129        filteredSearchCriteria.remove(groupControlPostData.getNamespaceCodePropertyName());
130
131        return filteredSearchCriteria;
132    }
133
134    /**
135     * The name of the property on the parent object that holds the group namespace
136     *
137     * @return namespaceCodePropertyName
138     */
139    @BeanTagAttribute
140    public String getNamespaceCodePropertyName() {
141        return namespaceCodePropertyName;
142    }
143
144    /**
145     * Setter for the name of the property on the parent object that holds the group namespace
146     *
147     * @param namespaceCodePropertyName
148     */
149    public void setNamespaceCodePropertyName(String namespaceCodePropertyName) {
150        this.namespaceCodePropertyName = namespaceCodePropertyName;
151    }
152
153    /**
154     * The name of the property on the parent object that holds the group id
155     *
156     * @return groupIdPropertyName
157     */
158    @BeanTagAttribute
159    public String getGroupIdPropertyName() {
160        return groupIdPropertyName;
161    }
162
163    /**
164     * Setter for the name of the property on the parent object that holds the group id
165     *
166     * @param groupIdPropertyName
167     */
168    public void setGroupIdPropertyName(String groupIdPropertyName) {
169        this.groupIdPropertyName = groupIdPropertyName;
170    }
171
172    /**
173     * {@inheritDoc}
174     */
175    @Override
176    public GroupControlPostData getPostData(String propertyName) {
177        return new GroupControlPostData(propertyName, this);
178    }
179
180    /**
181     * Holds post data for the {@link GroupControl}.
182     */
183    public static class GroupControlPostData implements FilterableLookupCriteriaControlPostData, Serializable {
184
185        private static final long serialVersionUID = -1859777965985379673L;
186
187        private String propertyName;
188
189        private String namespaceCodePropertyName;
190        private String groupIdPropertyName;
191
192        /**
193         * Constructs the post data from the property name and the {@link GroupControl}.
194         *
195         * @param propertyName the name of the property to filter
196         * @param groupControl the control to pull data from
197         */
198        public GroupControlPostData(String propertyName, GroupControl groupControl) {
199            this.propertyName = propertyName;
200            this.namespaceCodePropertyName = groupControl.getNamespaceCodePropertyName();
201            this.groupIdPropertyName = groupControl.getGroupIdPropertyName();
202        }
203
204        /**
205         * {@inheritDoc}
206         */
207        @Override
208        public Class<? extends FilterableLookupCriteriaControl> getControlClass() {
209            return GroupControl.class;
210        }
211
212        /**
213         * {@inheritDoc}
214         */
215        @Override
216        public String getPropertyName() {
217            return propertyName;
218        }
219
220        /**
221         * @see GroupControl#getNamespaceCodePropertyName()
222         */
223        public String getNamespaceCodePropertyName() {
224            return namespaceCodePropertyName;
225        }
226
227        /**
228         * @see GroupControl#getGroupIdPropertyName()
229         */
230        public String getGroupIdPropertyName() {
231            return groupIdPropertyName;
232        }
233
234    }
235
236}