001/* 002 * Copyright 2010 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 1.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/ecl1.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.ole.sec.businessobject.lookup; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022 023import org.apache.commons.lang.StringUtils; 024import org.kuali.ole.sec.SecConstants; 025import org.kuali.ole.sec.SecPropertyConstants; 026import org.kuali.ole.sec.businessobject.SecurityAttributeMetadata; 027import org.kuali.ole.sec.service.AccessSecurityService; 028import org.kuali.ole.sys.OLEPropertyConstants; 029import org.kuali.ole.sys.context.SpringContext; 030import org.kuali.ole.sys.service.UniversityDateService; 031import org.kuali.rice.core.web.format.Formatter; 032import org.kuali.rice.kim.api.KimConstants; 033import org.kuali.rice.kim.api.identity.Person; 034import org.kuali.rice.kim.api.identity.PersonService; 035import org.kuali.rice.kim.api.services.KimApiServiceLocator; 036import org.kuali.rice.kns.datadictionary.BusinessObjectEntry; 037import org.kuali.rice.kns.lookup.KualiLookupableHelperServiceImpl; 038import org.kuali.rice.kns.service.DataDictionaryService; 039import org.kuali.rice.kns.util.FieldUtils; 040import org.kuali.rice.kns.web.ui.Column; 041import org.kuali.rice.kns.web.ui.Field; 042import org.kuali.rice.kns.web.ui.Row; 043import org.kuali.rice.krad.bo.BusinessObject; 044import org.kuali.rice.krad.util.KRADConstants; 045 046 047/** 048 * Calls the access security service to simulate validation for the specified user, attribute, and action 049 */ 050public class AccessSecuritySimulationLookupableHelperServiceImpl extends KualiLookupableHelperServiceImpl { 051 protected AccessSecurityService accessSecurityService; 052 protected UniversityDateService universityDateService; 053 054 protected List<Row> rows; 055 056 public AccessSecuritySimulationLookupableHelperServiceImpl() { 057 rows = null; 058 } 059 060 /** 061 * @see org.kuali.rice.kns.lookup.KualiLookupableHelperServiceImpl#getSearchResults(java.util.Map) 062 * 063 * KRAD Conversion: Lookupable performs customization of the search results. 064 * by retrieving the default sort columns using data dictionary service. 065 */ 066 @Override 067 public List<? extends BusinessObject> getSearchResults(Map<String, String> fieldValues) { 068 String principalName = fieldValues.get(SecPropertyConstants.SECURITY_PERSON_PRINCIPAL_NAME); 069 Person person = SpringContext.getBean(PersonService.class).getPersonByPrincipalName(principalName); 070 071 String attributeName = fieldValues.get(SecPropertyConstants.ATTRIBUTE_NAME); 072 String templateId = fieldValues.get(SecPropertyConstants.TEMPLATE_ID); 073 074 Map<String,String> additionalPermissionDetails = new HashMap<String,String>(); 075 if (accessSecurityService.getInquiryWithFieldValueTemplate().getId().equals(templateId)) { 076 String namespaceCode = fieldValues.get(SecPropertyConstants.INQUIRY_NAMESPACE_CODE); 077 additionalPermissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, namespaceCode); 078 } 079 else if (!accessSecurityService.getLookupWithFieldValueTemplate().getId().equals(templateId)) { 080 String documentTypeCode = fieldValues.get(SecPropertyConstants.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE); 081 additionalPermissionDetails.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, documentTypeCode); 082 } 083 084 return runSimulation(person, attributeName, templateId, additionalPermissionDetails); 085 } 086 087 /** 088 * @param person 089 * @param attribute 090 * @param templateId 091 * @param additionalPermissionDetails 092 * @return 093 * 094 * KRAD Conversion: Lookupable performs customization of the search results. 095 * by retrieving the columns using data dictionary service. 096 * 097 */ 098 protected List<? extends BusinessObject> runSimulation(Person person, String attributeName, String templateId, Map<String,String> additionalPermissionDetails) { 099 List<BusinessObject> resultRecords = new ArrayList<BusinessObject>(); 100 101 if (!SecConstants.ATTRIBUTE_SIMULATION_MAP.containsKey(attributeName)) { 102 throw new RuntimeException("Unable to find attribute metadata for attribute: " + attributeName); 103 } 104 SecurityAttributeMetadata attributeMetadata = SecConstants.ATTRIBUTE_SIMULATION_MAP.get(attributeName); 105 Class attributeClass = attributeMetadata.getAttributeClass(); 106 107 // build criteria for retrieving attribute records 108 Map<String, Object> searchCriteria = new HashMap<String, Object>(); 109 List<String> fieldNames = getPersistenceStructureService().listFieldNames(attributeClass); 110 if (fieldNames.contains(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR)) { 111 searchCriteria.put(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, universityDateService.getCurrentFiscalYear()); 112 } 113 114 if (fieldNames.contains(OLEPropertyConstants.ACTIVE)) { 115 searchCriteria.put(OLEPropertyConstants.ACTIVE, true); 116 } 117 118 // retrieve records for this attribute to iterate over and call security service 119 List allAttributeData = (List) getBusinessObjectService().findMatching(attributeClass, searchCriteria); 120 accessSecurityService.applySecurityRestrictions(allAttributeData, person, KimApiServiceLocator.getPermissionService().getPermissionTemplate(templateId), additionalPermissionDetails); 121 122 // iterate through business object instances and construct simulation info result objects 123 // for (Iterator iterator = allAttributeData.iterator(); iterator.hasNext();) { 124 // BusinessObject businessObject = (BusinessObject) iterator.next(); 125 // 126 // AccessSecuritySimulation securitySimulation = new AccessSecuritySimulation(); 127 // 128 // Object boKeyFieldValue = ObjectUtils.getPropertyValue(businessObject, attributeMetadata.getAttributeField()); 129 // Object boNameFieldValue = ObjectUtils.getPropertyValue(businessObject, attributeMetadata.getAttributeNameField()); 130 // 131 // securitySimulation.setAttributeValue(boKeyFieldValue.toString()); 132 // securitySimulation.setAttributeValueName(boNameFieldValue.toString()); 133 // 134 // resultRecords.add(securitySimulation); 135 // } 136 137 return allAttributeData; 138 } 139 140 /** 141 * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#setRows() 142 */ 143 @Override 144 protected void setRows() { 145 List<String> lookupFieldAttributeList = new ArrayList<String>(); 146 if (getParameters().containsKey(SecPropertyConstants.TEMPLATE_ID)) { 147 String templateId = ((String[]) getParameters().get(SecPropertyConstants.TEMPLATE_ID))[0]; 148 149 if (accessSecurityService.getInquiryWithFieldValueTemplate().getId().equals(templateId)) { 150 lookupFieldAttributeList = getInquiryTemplateFields(); 151 } 152 else if (accessSecurityService.getLookupWithFieldValueTemplate().getId().equals(templateId)) { 153 lookupFieldAttributeList = getLookupTemplateFields(); 154 } 155 else { 156 lookupFieldAttributeList = getDocumentTemplateFields(); 157 } 158 } 159 else { 160 lookupFieldAttributeList = getLookupTemplateFields(); 161 } 162 163 // construct field object for each search attribute 164 List<Field> fields = new ArrayList<Field>(); 165 int numCols; 166 try { 167 fields = FieldUtils.createAndPopulateFieldsForLookup(lookupFieldAttributeList, getReadOnlyFieldsList(), getBusinessObjectClass()); 168 169 BusinessObjectEntry boe = (BusinessObjectEntry) SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(this.getBusinessObjectClass().getName()); 170 numCols = boe.getLookupDefinition().getNumOfColumns(); 171 172 } 173 catch (InstantiationException e) { 174 throw new RuntimeException("Unable to create instance of business object class" + e.getMessage()); 175 } 176 catch (IllegalAccessException e) { 177 throw new RuntimeException("Unable to create instance of business object class" + e.getMessage()); 178 } 179 180 if (numCols == 0) { 181 numCols = KRADConstants.DEFAULT_NUM_OF_COLUMNS; 182 } 183 184 rows = FieldUtils.wrapFields(fields, numCols); 185 } 186 187 /** 188 * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#getRows() 189 */ 190 @Override 191 public List<Row> getRows() { 192 return rows; 193 } 194 195 /** 196 * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#getColumns() 197 * 198 * KRAD Conversion: Lookupable performs the customization of columns 199 * by using data dictionary service for attribute properties. 200 */ 201 @Override 202 public List<Column> getColumns() { 203 String searchAttributeName = ((String[]) getParameters().get(SecPropertyConstants.ATTRIBUTE_NAME))[0]; 204 205 SecurityAttributeMetadata attributeMetadata = SecConstants.ATTRIBUTE_SIMULATION_MAP.get(searchAttributeName); 206 Class attributeClass = attributeMetadata.getAttributeClass(); 207 208 ArrayList<Column> columns = new ArrayList<Column>(); 209 for (String attributeName : getBusinessObjectDictionaryService().getLookupResultFieldNames(attributeClass)) { 210 Column column = new Column(); 211 column.setPropertyName(attributeName); 212 213 String columnTitle = getDataDictionaryService().getAttributeLabel(attributeClass, attributeName); 214 Boolean useShortLabel = getBusinessObjectDictionaryService().getLookupResultFieldUseShortLabel(attributeClass, attributeName); 215 if (useShortLabel != null && useShortLabel) { 216 columnTitle = getDataDictionaryService().getAttributeShortLabel(attributeClass, attributeName); 217 } 218 if (StringUtils.isBlank(columnTitle)) { 219 columnTitle = getDataDictionaryService().getCollectionLabel(attributeClass, attributeName); 220 } 221 column.setColumnTitle(columnTitle); 222 223 Integer fieldDefinedMaxLength = getBusinessObjectDictionaryService().getLookupResultFieldMaxLength(attributeClass, attributeName); 224 if (fieldDefinedMaxLength == null) { 225 try { 226 fieldDefinedMaxLength = Integer.valueOf(getParameterService().getParameterValueAsString(KRADConstants.KNS_NAMESPACE, KRADConstants.DetailTypes.LOOKUP_PARM_DETAIL_TYPE, KRADConstants.RESULTS_DEFAULT_MAX_COLUMN_LENGTH)); 227 } 228 catch (NumberFormatException ex) { 229 LOG.error("Lookup field max length parameter not found for " + attributeClass.getName() + "." + attributeName + " -- and unable to parse default set in system parameters (RESULTS_DEFAULT_MAX_COLUMN_LENGTH)."); 230 fieldDefinedMaxLength = 50; 231 } 232 } 233 column.setMaxLength(fieldDefinedMaxLength.intValue()); 234 235 Class formatterClass = getDataDictionaryService().getAttributeFormatter(attributeClass, attributeName); 236 if (formatterClass != null) { 237 try { 238 column.setFormatter((Formatter) formatterClass.newInstance()); 239 } 240 catch (InstantiationException e) { 241 LOG.error("Unable to get new instance of formatter class: " + formatterClass.getName()); 242 throw new RuntimeException("Unable to get new instance of formatter class: " + formatterClass.getName()); 243 } 244 catch (IllegalAccessException e) { 245 LOG.error("Unable to get new instance of formatter class: " + formatterClass.getName()); 246 throw new RuntimeException("Unable to get new instance of formatter class: " + formatterClass.getName()); 247 } 248 } 249 250 columns.add(column); 251 } 252 253 return columns; 254 } 255 256 /** 257 * Builds List of search field names for searching the inquiry template 258 * 259 * @return List<String> containing lookup field names 260 */ 261 protected List<String> getInquiryTemplateFields() { 262 List<String> lookupFields = new ArrayList<String>(); 263 264 lookupFields.add(SecPropertyConstants.SECURITY_PERSON_PRINCIPAL_NAME); 265 lookupFields.add(SecPropertyConstants.ATTRIBUTE_NAME); 266 lookupFields.add(SecPropertyConstants.TEMPLATE_ID); 267 lookupFields.add(SecPropertyConstants.INQUIRY_NAMESPACE_CODE); 268 269 return lookupFields; 270 } 271 272 /** 273 * Builds List of search field names for searching the lookup template 274 * 275 * @return List<String> containing lookup field names 276 */ 277 protected List<String> getLookupTemplateFields() { 278 List<String> lookupFields = new ArrayList<String>(); 279 280 lookupFields.add(SecPropertyConstants.SECURITY_PERSON_PRINCIPAL_NAME); 281 lookupFields.add(SecPropertyConstants.ATTRIBUTE_NAME); 282 lookupFields.add(SecPropertyConstants.TEMPLATE_ID); 283 284 return lookupFields; 285 } 286 287 /** 288 * Builds List of search field names for searching document templates 289 * 290 * @return List<String> containing lookup field names 291 */ 292 protected List<String> getDocumentTemplateFields() { 293 List<String> lookupFields = new ArrayList<String>(); 294 295 lookupFields.add(SecPropertyConstants.SECURITY_PERSON_PRINCIPAL_NAME); 296 lookupFields.add(SecPropertyConstants.ATTRIBUTE_NAME); 297 lookupFields.add(SecPropertyConstants.TEMPLATE_ID); 298 lookupFields.add(SecPropertyConstants.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE); 299 300 return lookupFields; 301 } 302 303 /** 304 * Sets the accessSecurityService attribute value. 305 * 306 * @param accessSecurityService The accessSecurityService to set. 307 */ 308 public void setAccessSecurityService(AccessSecurityService accessSecurityService) { 309 this.accessSecurityService = accessSecurityService; 310 } 311 312 /** 313 * Sets the universityDateService attribute value. 314 * 315 * @param universityDateService The universityDateService to set. 316 */ 317 public void setUniversityDateService(UniversityDateService universityDateService) { 318 this.universityDateService = universityDateService; 319 } 320 321}