View Javadoc

1   /**
2    * Copyright 2005-2013 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.control;
17  
18  import java.util.HashMap;
19  import java.util.Map;
20  
21  import org.apache.commons.lang.StringUtils;
22  import org.kuali.rice.kim.api.KimConstants;
23  import org.kuali.rice.kim.api.identity.Person;
24  import org.kuali.rice.kim.api.identity.PersonService;
25  import org.kuali.rice.kim.api.identity.principal.Principal;
26  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
27  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
28  import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
29  import org.kuali.rice.krad.uif.UifConstants;
30  import org.kuali.rice.krad.uif.component.Component;
31  import org.kuali.rice.krad.uif.component.MethodInvokerConfig;
32  import org.kuali.rice.krad.uif.field.AttributeQuery;
33  import org.kuali.rice.krad.uif.field.InputField;
34  import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
35  import org.kuali.rice.krad.uif.util.ComponentFactory;
36  import org.kuali.rice.krad.uif.util.ScriptUtils;
37  import org.kuali.rice.krad.uif.widget.QuickFinder;
38  
39  /**
40   * Represents a user control, which is a special control to handle the input of a Person
41   *
42   * @author Kuali Rice Team (rice.collab@kuali.org)
43   */
44  @BeanTag(name = "kimPersonControl-bean", parent = "Uif-KimPersonControl")
45  public class UserControl extends TextControl implements FilterableLookupCriteriaControl {
46      private static final long serialVersionUID = 7468340793076585869L;
47  
48      private String principalIdPropertyName;
49      private String personNamePropertyName;
50      private String personObjectPropertyName;
51  
52      public UserControl() {
53          super();
54      }
55  
56      /**
57       * @see org.kuali.rice.krad.uif.component.ComponentBase#performApplyModel(org.kuali.rice.krad.uif.view.View,
58       *      java.lang.Object, org.kuali.rice.krad.uif.component.Component)
59       */
60      @Override
61      public void performApplyModel(Object model, Component parent) {
62          super.performApplyModel(model, parent);
63  
64          if (!(parent instanceof InputField)) {
65              return;
66          }
67  
68          InputField field = (InputField) parent;
69          field.getAdditionalHiddenPropertyNames().add(principalIdPropertyName);
70  
71          if (!field.isReadOnly()) {
72              // add information fields
73              if (StringUtils.isNotBlank(personNamePropertyName)) {
74                  field.getPropertyNamesForAdditionalDisplay().add(personNamePropertyName);
75              } else {
76                  field.getPropertyNamesForAdditionalDisplay().add(
77                          personObjectPropertyName + "." + KimConstants.AttributeConstants.NAME);
78              }
79  
80              // setup script to clear id field when name is modified
81              String idPropertyPath = field.getBindingInfo().getPropertyAdjustedBindingPath(principalIdPropertyName);
82              String onChangeScript = UifConstants.JsFunctions.SET_VALUE
83                      + "('"
84                      + ScriptUtils.escapeName(idPropertyPath)
85                      + "','');";
86  
87              if (StringUtils.isNotBlank(getOnChangeScript())) {
88                  onChangeScript = getOnChangeScript() + onChangeScript;
89              }
90              setOnChangeScript(onChangeScript);
91          }
92  
93          if (field.isReadOnly() && StringUtils.isBlank(field.getReadOnlyDisplaySuffixPropertyName())) {
94              if (StringUtils.isNotBlank(personNamePropertyName)) {
95                  field.setReadOnlyDisplaySuffixPropertyName(personNamePropertyName);
96              } else {
97                  field.setReadOnlyDisplaySuffixPropertyName(
98                          personObjectPropertyName + "." + KimConstants.AttributeConstants.NAME);
99              }
100         }
101 
102         // setup field query for displaying name
103         AttributeQuery attributeQuery = new AttributeQuery();
104 
105         MethodInvokerConfig methodInvokerConfig = new MethodInvokerConfig();
106         PersonService personService = KimApiServiceLocator.getPersonService();
107         methodInvokerConfig.setTargetObject(personService);
108 
109         attributeQuery.setQueryMethodInvokerConfig(methodInvokerConfig);
110         attributeQuery.setQueryMethodToCall("getPersonByPrincipalName");
111         attributeQuery.getQueryMethodArgumentFieldList().add(field.getPropertyName());
112         attributeQuery.getReturnFieldMapping().put(KimConstants.AttributeConstants.PRINCIPAL_ID,
113                 principalIdPropertyName);
114 
115         if (StringUtils.isNotBlank(personNamePropertyName)) {
116             attributeQuery.getReturnFieldMapping().put(KimConstants.AttributeConstants.NAME, personNamePropertyName);
117         } else {
118             attributeQuery.getReturnFieldMapping().put(KimConstants.AttributeConstants.NAME,
119                     personObjectPropertyName + "." + KimConstants.AttributeConstants.NAME);
120         }
121         field.setAttributeQuery(attributeQuery);
122 
123         buildUserQuickfinder(model, field);
124     }
125 
126     /**
127      * @see FilterableLookupCriteriaControl#filterSearchCriteria(String, java.util.Map)
128      */
129     @Override
130     public Map<String, String> filterSearchCriteria(String propertyName, Map<String, String> searchCriteria) {
131         Map<String, String> filteredSearchCriteria = new HashMap<String, String>(searchCriteria);
132 
133         // check valid principalName
134         // ToDo: move the principalId check and setting to the validation stage.  At that point the personName should
135         // be set as well or an error be displayed to the user that the principalName is invalid.
136         String principalName = searchCriteria.get(propertyName);
137         if (StringUtils.isNotBlank(principalName)) {
138             Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(principalName);
139             if (principal == null) {
140                 return null;
141             } else {
142                 filteredSearchCriteria.put(principalIdPropertyName, principal.getPrincipalId());
143             }
144         }
145 
146         // filter
147         filteredSearchCriteria.remove(propertyName);
148         filteredSearchCriteria.remove(personNamePropertyName);
149 
150         return filteredSearchCriteria;
151     }
152 
153     /**
154      * Configures the field's quickfinder for a user lookup
155      *
156      * @param view view instance that contains the field
157      * @param model object containing the view's data
158      * @param field field instance the quickfinder should be associated with
159      */
160     protected void buildUserQuickfinder(Object model, InputField field) {
161         QuickFinder quickFinder = field.getQuickfinder();
162 
163         // don't build quickfinder if explicitly turned off
164         if (!field.isEnableAutoQuickfinder()) {
165             return;
166         }
167 
168         if (quickFinder == null) {
169             quickFinder = ComponentFactory.getQuickFinder();
170             field.setQuickfinder(quickFinder);
171             ViewLifecycle.spawnSubLifecyle(model, quickFinder, field);
172         }
173 
174         if (StringUtils.isBlank(quickFinder.getDataObjectClassName())) {
175             quickFinder.setDataObjectClassName(Person.class.getName());
176         }
177 
178         if (quickFinder.getFieldConversions().isEmpty()) {
179             quickFinder.getFieldConversions().put(KimConstants.AttributeConstants.PRINCIPAL_ID,
180                     principalIdPropertyName);
181 
182             if (StringUtils.isNotBlank(personNamePropertyName)) {
183                 quickFinder.getFieldConversions().put(KimConstants.AttributeConstants.NAME, personNamePropertyName);
184             } else {
185                 quickFinder.getFieldConversions().put(KimConstants.AttributeConstants.NAME,
186                         personObjectPropertyName + "." + KimConstants.AttributeConstants.NAME);
187             }
188 
189             quickFinder.getFieldConversions().put(KimConstants.AttributeConstants.PRINCIPAL_NAME,
190                     field.getPropertyName());
191         }
192     }
193 
194     /**
195      * The name of the property on the parent object that holds the principal id
196      *
197      * @return principalIdPropertyName
198      */
199     @BeanTagAttribute(name = "principalIdPropertyName")
200     public String getPrincipalIdPropertyName() {
201         return principalIdPropertyName;
202     }
203 
204     /**
205      * Setter for the name of the property on the parent object that holds the principal id
206      *
207      * @param principalIdPropertyName
208      */
209     public void setPrincipalIdPropertyName(String principalIdPropertyName) {
210         this.principalIdPropertyName = principalIdPropertyName;
211     }
212 
213     /**
214      * The name of the property on the parent object that holds the person name
215      *
216      * @return personNamePropertyName
217      */
218     @BeanTagAttribute(name = "personNamePropertyName")
219     public String getPersonNamePropertyName() {
220         return personNamePropertyName;
221     }
222 
223     /**
224      * Setter for the name of the property on the parent object that holds the person name
225      *
226      * @param personNamePropertyName
227      */
228     public void setPersonNamePropertyName(String personNamePropertyName) {
229         this.personNamePropertyName = personNamePropertyName;
230     }
231 
232     /**
233      * The name of the property on the parent object that holds the person object
234      *
235      * @return personObjectPropertyName
236      */
237     @BeanTagAttribute(name = "personObjectPropertyName")
238     public String getPersonObjectPropertyName() {
239         return personObjectPropertyName;
240     }
241 
242     /**
243      * Setter for the name of the property on the parent object that holds the person object
244      *
245      * @param personObjectPropertyName
246      */
247     public void setPersonObjectPropertyName(String personObjectPropertyName) {
248         this.personObjectPropertyName = personObjectPropertyName;
249     }
250 
251     /**
252      * @see org.kuali.rice.krad.datadictionary.DictionaryBeanBase#copyProperties(Object)
253      */
254     @Override
255     protected <T> void copyProperties(T component) {
256         super.copyProperties(component);
257 
258         UserControl userControlCopy = (UserControl) component;
259 
260         userControlCopy.setPrincipalIdPropertyName(this.principalIdPropertyName);
261         userControlCopy.setPersonNamePropertyName(this.personNamePropertyName);
262         userControlCopy.setPersonObjectPropertyName(this.personObjectPropertyName);
263     }
264 }