View Javadoc
1   /**
2    * Copyright 2005-2016 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.kns.util;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.CoreApiServiceLocator;
20  import org.kuali.rice.krad.keyvalues.KeyValuesFinder;
21  import org.kuali.rice.krad.keyvalues.PersistableBusinessObjectValuesFinder;
22  import org.kuali.rice.krad.util.KRADConstants;
23  
24  import java.lang.reflect.Method;
25  import java.security.GeneralSecurityException;
26  import java.util.ArrayList;
27  import java.util.HashMap;
28  import java.util.List;
29  
30  /**
31   * Utility map for the action form to provide a way for calling functions through jstl.
32   *
33   *
34   */
35  @SuppressWarnings("unchecked")
36  public class ActionFormUtilMap extends HashMap {
37      private static final long serialVersionUID = 1L;
38  	private boolean cacheValueFinderResults;
39  
40      /**
41       * This method parses from the key the actual method to run.
42       *
43       * @see java.util.Map#get(java.lang.Object)
44       */
45      @Override
46  	public Object get(Object key) {
47      	if (cacheValueFinderResults) {
48      	    if (super.containsKey(key)) {
49      		// doing a 2 step retrieval allows us to also cache the null key correctly
50      		Object cachedObject = super.get(key);
51      	    	return cachedObject;
52      	    }
53      	}
54          String[] methodKey = StringUtils.split((String) key, KRADConstants.ACTION_FORM_UTIL_MAP_METHOD_PARM_DELIMITER);
55  
56          String methodToCall = methodKey[0];
57  
58          // handle method calls with more than one parameter
59          Object[] methodParms = new Object[methodKey.length - 1];
60          Class[] methodParmsPrototype = new Class[methodKey.length - 1];
61          for (int i=1;i<methodKey.length;i++) {
62              methodParms[i-1] = methodKey[i];
63              methodParmsPrototype[i-1] = Object.class;
64          }
65  
66          Method method = null;
67          try {
68              method = ActionFormUtilMap.class.getMethod(methodToCall, methodParmsPrototype);
69          }
70          catch (SecurityException e) {
71              throw new RuntimeException("Unable to object handle on method given to ActionFormUtilMap: " + e.getMessage());
72          }
73          catch (NoSuchMethodException e1) {
74              throw new RuntimeException("Unable to object handle on method given to ActionFormUtilMap: " + e1.getMessage());
75          }
76  
77          Object methodValue = null;
78          try {
79              methodValue = method.invoke(this, methodParms);
80          }
81          catch (Exception e) {
82              throw new RuntimeException("Unable to invoke method " + methodToCall,e);
83          }
84  
85          if (cacheValueFinderResults) {
86              super.put(key, methodValue);
87          }
88  
89          return methodValue;
90      }
91  
92      /*
93       * Will take in a class name parameter and attempt to create a KeyValueFinder instance, then call the finder to return a list of
94       * KeyValue pairs. This is used by the htmlControlAttribute.tag to render select options from a given finder class specified in
95       * the data dictionary.
96       */
97  	public Object getOptionsMap(Object key) {
98          List optionsList = new ArrayList();
99  
100         if (StringUtils.isBlank((String) key)) {
101             return optionsList;
102         }
103 
104         /*
105          * the class name has . replaced with | in the jsp to prevent struts from treating each part of the class name as a property
106          * substitute back here to get the correct name
107          */
108         key = StringUtils.replace((String) key, "|", ".");
109 
110         KeyValuesFinder finder;
111         try {
112             Class finderClass = Class.forName((String) key);
113             finder = (KeyValuesFinder) finderClass.newInstance();
114             optionsList = finder.getKeyValues();
115         }
116         catch (ClassNotFoundException e) {
117             throw new RuntimeException(e.getMessage());
118         }
119         catch (InstantiationException e) {
120             throw new RuntimeException(e.getMessage());
121         }
122         catch (IllegalAccessException e) {
123             throw new RuntimeException(e.getMessage());
124         }
125 
126         return optionsList;
127     }
128 
129     // Method added to keep backward compatibility for non-kimTypeId cases
130     public Object getOptionsMap(Object key, Object boClass, Object keyAttribute, Object labelAttribute, Object includeKeyInLabel) {
131     	return getOptionsMap(key, boClass, keyAttribute, labelAttribute, null, includeKeyInLabel );
132     }
133 
134     /**
135      * This method will take in a key parameter (values finder class name - in this case the generic
136      * PersistableObjectValuesFinder) along with the related parameters required by this ValuesFinder,
137      * and attempt to create a KeyValueFinder instance, then call the finder to return a list of
138      * KeyValue pairs. This is used by the htmlControlAttribute.tag to render select options from
139      * a given finder class specified in the data dictionary.
140      *
141      * @param key values finder class name
142      * @param boClass BO class name
143      * @param keyAttribute name of BO attribute for key
144      * @param labelAttribute name of BO attribute for label
145      * @param includeKeyInLabel whether to include the key in the label or not
146      * @return list of KeyValue pairs
147      */
148 	public Object getOptionsMap(Object key, Object boClass, Object keyAttribute, Object labelAttribute, Object includeBlankRow, Object includeKeyInLabel) {
149         List optionsList = new ArrayList();
150 
151         if (StringUtils.isBlank((String) key)) {
152             return optionsList;
153         }
154 
155         /*
156          * the class name has . replaced with | in the jsp to prevent struts from treating each part of the class name as a property
157          * substitute back here to get the correct name
158          */
159         key = StringUtils.replace((String) key, "|", ".");
160 
161         KeyValuesFinder finder;
162         try {
163     		Class finderClass = Class.forName((String) key);
164             finder = (KeyValuesFinder) finderClass.newInstance();
165             if (finder instanceof PersistableBusinessObjectValuesFinder) {
166                 String businessObjectClassName = StringUtils.replace((String) boClass, "|", ".");
167                 Class businessObjectClass = Class.forName((String) businessObjectClassName);
168                 ((PersistableBusinessObjectValuesFinder) finder).setBusinessObjectClass(businessObjectClass);
169                 ((PersistableBusinessObjectValuesFinder) finder).setKeyAttributeName((String)keyAttribute);
170                 ((PersistableBusinessObjectValuesFinder) finder).setLabelAttributeName((String)labelAttribute);
171                 ((PersistableBusinessObjectValuesFinder) finder).setIncludeBlankRow(Boolean.parseBoolean((String)includeBlankRow));
172                 ((PersistableBusinessObjectValuesFinder) finder).setIncludeKeyInDescription(Boolean.parseBoolean((String)includeKeyInLabel));
173             }
174 
175             optionsList = finder.getKeyValues();
176         }
177         catch (ClassNotFoundException e) {
178             throw new RuntimeException(e.getMessage(),e);
179         }
180         catch (InstantiationException e) {
181             throw new RuntimeException(e.getMessage(),e);
182         }
183         catch (IllegalAccessException e) {
184             throw new RuntimeException(e.getMessage(),e);
185         }
186 
187         return optionsList;
188     }
189 
190     /**
191      * Encrypts a value passed from the ui.
192      * @param value - clear text
193      * @return String - encrypted text
194      */
195     public String encryptValue(Object value) {
196         String encrypted = "";
197         if (value != null) {
198             encrypted = value.toString();
199         }
200 
201         try {
202             if(CoreApiServiceLocator.getEncryptionService().isEnabled()) {
203                 encrypted = CoreApiServiceLocator.getEncryptionService().encrypt(value);
204             }
205         }
206         catch (GeneralSecurityException e) {
207             throw new RuntimeException("Unable to encrypt value in action form: " + e.getMessage());
208         }
209 
210         return encrypted;
211     }
212 
213     public void setCacheValueFinderResults(boolean cacheValueFinderResults) {
214         this.cacheValueFinderResults = cacheValueFinderResults;
215     }
216 
217 
218 }