1 /**
2 * Copyright 2005-2014 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.util;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
20 import org.kuali.rice.kim.api.identity.Person;
21 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
22 import org.kuali.rice.krad.data.platform.MaxValueIncrementerFactory;
23 import org.kuali.rice.krad.service.KRADServiceLocator;
24 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
25 import org.kuali.rice.krad.service.KualiModuleService;
26 import org.kuali.rice.krad.service.ModuleService;
27 import org.kuali.rice.krad.util.GlobalVariables;
28
29 import javax.sql.DataSource;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Date;
33 import java.util.List;
34 import java.util.Map;
35
36 /**
37 * Defines functions that can be used in el expressions within
38 * the UIF dictionary files
39 *
40 * @author Kuali Rice Team (rice.collab@kuali.org)
41 */
42 public class ExpressionFunctions {
43
44 /**
45 * Checks whether the given class parameter is assignable from the given object class
46 * parameter
47 *
48 * @param assignableClass class to use for assignable to
49 * @param objectClass class to use for assignable from
50 * @return true if the object class is of type assignable class, false if not
51 */
52 public static boolean isAssignableFrom(Class<?> assignableClass, Class<?> objectClass) {
53 return assignableClass.isAssignableFrom(objectClass);
54 }
55
56 /**
57 * Checks whether the given value is null or blank string
58 *
59 * @param value property value to check
60 * @return true if value is null or blank, false if not
61 */
62 public static boolean empty(Object value) {
63 return (value == null) || (StringUtils.isBlank(value.toString()));
64 }
65
66 /**
67 * Checks to see if the list is empty. Throws a RuntimeException if list is not a List.
68 *
69 * @param list the list
70 * @return true if the list is null or empty, false otherwise
71 */
72 public static boolean emptyList(List<?> list) {
73 return (list == null) || list.isEmpty();
74 }
75
76 /**
77 * Check to see if the list contains the values passed in.
78 *
79 * <p>In the SpringEL call values can be single item or array due to the way the EL converts values.
80 * The values can be string or numeric and should match
81 * the content type being stored in the list. If the list is String and the values passed in are not string,
82 * toString() conversion will be used. Returns true if the values are in the list and both lists are non-empty,
83 * false otherwise.
84 * </p>
85 *
86 * @param list the list to be evaluated
87 * @param values the values to be to check for in the list
88 * @return true if all values exist in the list and both values and list are non-null/not-empty, false otherwise
89 */
90 public static boolean listContains(List<?> list, Object[] values) {
91 if (list != null && values != null && values.length > 0 && !list.isEmpty()) {
92 //conversion for if the values are non-string but the list is string (special case)
93 if (list.get(0) instanceof String && !(values[0] instanceof String)) {
94 String[] stringValues = new String[values.length];
95 for (int i = 0; i < values.length; i++) {
96 stringValues[i] = values[i].toString();
97 }
98 return list.containsAll(Arrays.asList(stringValues));
99 } else if (list.get(0) instanceof Date && values[0] instanceof String) {
100 //TODO date conversion
101 return false;
102 } else if (!(list.get(0) instanceof String) && values[0] instanceof String) {
103 //values passed in are string but the list is of objects, use object's toString method
104 List<String> stringList = new ArrayList<String>();
105 for (Object value : list) {
106 stringList.add(value.toString());
107 }
108 return stringList.containsAll(Arrays.asList(values));
109 } else {
110 //no conversion for if neither list is String, assume matching types (numeric case)
111 return list.containsAll(Arrays.asList(values));
112 }
113 }
114
115 //no cases satisfied, return false
116 return false;
117
118 }
119
120 /**
121 * Returns the name for the given class
122 *
123 * @param clazz class object to return name for
124 * @return class name or empty string if class is null
125 */
126 public static String getName(Class<?> clazz) {
127 if (clazz == null) {
128 return "";
129 } else {
130 return clazz.getName();
131 }
132 }
133
134 /**
135 * Retrieves the value of the parameter identified with the given namespace, component, and name
136 *
137 * @param namespaceCode namespace code for the parameter to retrieve
138 * @param componentCode component code for the parameter to retrieve
139 * @param parameterName name of the parameter to retrieve
140 * @return String value of parameter as a string or null if parameter does not exist
141 */
142 public static String getParam(String namespaceCode, String componentCode, String parameterName) {
143 return CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(namespaceCode, componentCode,
144 parameterName);
145 }
146
147 /**
148 * Retrieves the value of the parameter identified with the given namespace, component, and name and converts
149 * to a Boolean
150 *
151 * @param namespaceCode namespace code for the parameter to retrieve
152 * @param componentCode component code for the parameter to retrieve
153 * @param parameterName name of the parameter to retrieve
154 * @return Boolean value of parameter as a boolean or null if parameter does not exist
155 */
156 public static Boolean getParamAsBoolean(String namespaceCode, String componentCode, String parameterName) {
157 return CoreFrameworkServiceLocator.getParameterService().getParameterValueAsBoolean(namespaceCode,
158 componentCode, parameterName);
159 }
160
161 /**
162 * Indicates whether the current user has the permission identified by the given namespace and permission name
163 *
164 * @param namespaceCode namespace code for the permission to check
165 * @param permissionName name of the permission to check
166 * @return true if the current user has the permission, false if not or the permission does not exist
167 */
168 public static boolean hasPerm(String namespaceCode, String permissionName) {
169 Person user = GlobalVariables.getUserSession().getPerson();
170
171 return KimApiServiceLocator.getPermissionService().hasPermission(user.getPrincipalId(), namespaceCode,
172 permissionName);
173 }
174
175 /**
176 * Indicates whether the current user has the permission identified by the given namespace and permission name
177 * and with the given details and role qualification
178 *
179 * @param namespaceCode namespace code for the permission to check
180 * @param permissionName name of the permission to check
181 * @param permissionDetails details for the permission check
182 * @param roleQualifiers qualification for assigned roles
183 * @return true if the current user has the permission, false if not or the permission does not exist
184 */
185 public static boolean hasPermDtls(String namespaceCode, String permissionName,
186 Map<String, String> permissionDetails, Map<String, String> roleQualifiers) {
187 Person user = GlobalVariables.getUserSession().getPerson();
188
189 return KimApiServiceLocator.getPermissionService().isAuthorized(user.getPrincipalId(), namespaceCode,
190 permissionName, roleQualifiers);
191 }
192
193 /**
194 * Indicates whether the current user has the permission identified by the given namespace and template name
195 * and with the given details and role qualification
196 *
197 * @param namespaceCode namespace code for the permission to check
198 * @param templateName name of the permission template to find permissions for
199 * @param permissionDetails details for the permission check
200 * @param roleQualifiers qualification for assigned roles
201 * @return true if the current user has a permission with the given template, false if not or
202 * the permission does not exist
203 */
204 public static boolean hasPermTmpl(String namespaceCode, String templateName, Map<String, String> permissionDetails,
205 Map<String, String> roleQualifiers) {
206 Person user = GlobalVariables.getUserSession().getPerson();
207
208 return KimApiServiceLocator.getPermissionService().isAuthorizedByTemplate(user.getPrincipalId(), namespaceCode,
209 templateName, permissionDetails, roleQualifiers);
210 }
211
212 /**
213 * Gets the next available number from a sequence
214 *
215 * @param sequenceName name of the sequence to retrieve from
216 * @return next sequence value
217 */
218 public static Long sequence(String sequenceName) {
219 DataSource dataSource = KRADServiceLocator.getKradApplicationDataSource();
220 return Long.valueOf(MaxValueIncrementerFactory.getIncrementer(dataSource, sequenceName).nextLongValue());
221 }
222
223 /**
224 * Get the a primary key (valid for inquiry/maintenance view retrieval) for the dataObject by class name passed in
225 *
226 * @param dataObjectClassName the class name to get the key for
227 * @return a key valid for use as a request parameter for retrieving an inquiry or maintenance doc
228 */
229 public static String getDataObjectKey(String dataObjectClassName) {
230
231 if (StringUtils.isBlank(dataObjectClassName)) {
232 throw new RuntimeException("getDataObjectKey SpringEL function failed because the class name was blank");
233 }
234
235 Class dataObjectClass = null;
236
237 try {
238 dataObjectClass = Class.forName(dataObjectClassName);
239 } catch (ClassNotFoundException e) {
240 throw new RuntimeException(
241 "getDataObjectKey SpringEL function failed when trying to find class " + dataObjectClassName, e);
242 }
243
244 // build list of key values from the map parameters
245 List<String> pkPropertyNames = KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(dataObjectClass);
246
247 //return first primary key found
248 if (pkPropertyNames != null && !pkPropertyNames.isEmpty()) {
249 return pkPropertyNames.get(0);
250 }
251
252 //this likely won't be reached, as most should have a primary key (assumption)
253 KualiModuleService kualiModuleService = KRADServiceLocatorWeb.getKualiModuleService();
254 ModuleService moduleService = kualiModuleService.getResponsibleModuleService(dataObjectClass);
255
256 // some classes might have alternate keys defined for retrieving
257 List<List<String>> altKeys = null;
258 if (moduleService != null) {
259 altKeys = moduleService.listAlternatePrimaryKeyFieldNames(dataObjectClass);
260 }
261
262 if (altKeys != null && !altKeys.isEmpty()) {
263 for (List<String> list : altKeys) {
264 if (list != null && !list.isEmpty()) {
265 //return any key first found
266 return list.get(0);
267 }
268 }
269 }
270
271 return null;
272 }
273 }