001 /** 002 * Copyright 2005-2014 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 */ 016 package org.kuali.rice.kew.rule.bo; 017 018 import org.apache.commons.lang.StringUtils; 019 import org.kuali.rice.core.api.uif.RemotableAttributeError; 020 import org.kuali.rice.core.api.util.ConcreteKeyValue; 021 import org.kuali.rice.core.api.util.KeyValue; 022 import org.kuali.rice.core.api.util.RiceKeyConstants; 023 import org.kuali.rice.core.web.format.BooleanFormatter; 024 import org.kuali.rice.core.web.format.CollectionFormatter; 025 import org.kuali.rice.core.web.format.DateFormatter; 026 import org.kuali.rice.core.web.format.Formatter; 027 import org.kuali.rice.kew.api.KewApiServiceLocator; 028 import org.kuali.rice.kew.api.rule.RuleTemplate; 029 import org.kuali.rice.kew.api.rule.RuleTemplateAttribute; 030 import org.kuali.rice.kew.lookupable.MyColumns; 031 import org.kuali.rice.kew.rule.RuleBaseValues; 032 import org.kuali.rice.kew.rule.WorkflowRuleAttributeRows; 033 import org.kuali.rice.kew.rule.service.RuleServiceInternal; 034 import org.kuali.rice.kew.rule.service.RuleTemplateService; 035 import org.kuali.rice.kew.service.KEWServiceLocator; 036 import org.kuali.rice.kim.api.KimConstants; 037 import org.kuali.rice.kim.api.group.Group; 038 import org.kuali.rice.kim.api.group.GroupService; 039 import org.kuali.rice.kim.api.identity.Person; 040 import org.kuali.rice.kim.api.identity.principal.Principal; 041 import org.kuali.rice.kim.api.services.KimApiServiceLocator; 042 import org.kuali.rice.kns.document.authorization.BusinessObjectRestrictions; 043 import org.kuali.rice.kns.lookup.HtmlData; 044 import org.kuali.rice.kns.lookup.KualiLookupableHelperServiceImpl; 045 import org.kuali.rice.kns.lookup.LookupableHelperService; 046 import org.kuali.rice.kns.service.KNSServiceLocator; 047 import org.kuali.rice.kns.web.comparator.CellComparatorHelper; 048 import org.kuali.rice.kns.web.struts.form.LookupForm; 049 import org.kuali.rice.kns.web.ui.Column; 050 import org.kuali.rice.kns.web.ui.Field; 051 import org.kuali.rice.kns.web.ui.ResultRow; 052 import org.kuali.rice.kns.web.ui.Row; 053 import org.kuali.rice.krad.bo.BusinessObject; 054 import org.kuali.rice.krad.bo.PersistableBusinessObject; 055 import org.kuali.rice.krad.exception.ValidationException; 056 import org.kuali.rice.krad.util.GlobalVariables; 057 import org.kuali.rice.krad.util.KRADConstants; 058 import org.kuali.rice.krad.util.ObjectUtils; 059 060 import java.sql.Date; 061 import java.util.ArrayList; 062 import java.util.Collection; 063 import java.util.HashMap; 064 import java.util.Iterator; 065 import java.util.List; 066 import java.util.Map; 067 068 /** 069 * This is a description of what this class does - jjhanso don't forget to fill this in. 070 * 071 * @author Kuali Rice Team (rice.collab@kuali.org) 072 * 073 */ 074 public class RuleBaseValuesLookupableHelperServiceImpl extends KualiLookupableHelperServiceImpl { 075 private List<Row> rows = new ArrayList<Row>(); 076 //private List<Column> columns = establishColumns(); 077 //private Long previousRuleTemplateId; 078 private LookupableHelperService ruleDelegationLookupableHelperService; 079 private List<?> delegationPkNames; 080 081 private static final String RULE_TEMPLATE_PROPERTY_NAME = "ruleTemplate.name"; 082 private static final String RULE_ID_PROPERTY_NAME = "id"; 083 private static final String RULE_TEMPLATE_ID_PROPERTY_NAME = "ruleTemplateId"; 084 private static final String ACTIVE_IND_PROPERTY_NAME = "active"; 085 private static final String DELEGATE_RULE_PROPERTY_NAME = "delegateRule"; 086 private static final String GROUP_REVIEWER_PROPERTY_NAME = "groupReviewer"; 087 private static final String GROUP_REVIEWER_NAME_PROPERTY_NAME = "groupReviewerName"; 088 private static final String GROUP_REVIEWER_NAMESPACE_PROPERTY_NAME = "groupReviewerNamespace"; 089 private static final String PERSON_REVIEWER_PROPERTY_NAME = "personReviewer"; 090 private static final String PERSON_REVIEWER_TYPE_PROPERTY_NAME = "personReviewerType"; 091 private static final String DOC_TYP_NAME_PROPERTY_NAME = "documentType.name"; 092 private static final String RULE_DESC_PROPERTY_NAME = "description"; 093 094 private static final String BACK_LOCATION = "backLocation"; 095 private static final String DOC_FORM_KEY = "docFormKey"; 096 private static final String INVALID_WORKGROUP_ERROR = "The Group Reviewer Namespace and Name combination is not valid"; 097 private static final String INVALID_PERSON_ERROR = "The Person Reviewer is not valid"; 098 099 @Override 100 public List<Row> getRows() { 101 List<Row> superRows = super.getRows(); 102 List<Row> returnRows = new ArrayList<Row>(); 103 returnRows.addAll(superRows); 104 returnRows.addAll(rows); 105 return returnRows; 106 } 107 108 @Override 109 public boolean checkForAdditionalFields(Map<String, String> fieldValues) { 110 String ruleTemplateNameParam = fieldValues.get(RULE_TEMPLATE_PROPERTY_NAME); 111 112 if (StringUtils.isNotBlank(ruleTemplateNameParam)) { 113 rows = new ArrayList<Row>(); 114 RuleTemplate ruleTemplate = KewApiServiceLocator.getRuleService().getRuleTemplateByName(ruleTemplateNameParam); 115 116 for (RuleTemplateAttribute ruleTemplateAttribute : ruleTemplate.getActiveRuleTemplateAttributes()) { 117 if (!RuleAttribute.isWorkflowAttribute(ruleTemplateAttribute.getRuleAttribute().getType())) { 118 continue; 119 } 120 // run through the attributes fields once to populate field values we have to do this 121 // to allow rows dependent on another row value to populate correctly in the loop below 122 WorkflowRuleAttributeRows workflowRuleAttributeRows = 123 KEWServiceLocator.getWorkflowRuleAttributeMediator().getSearchRows(fieldValues, ruleTemplateAttribute); 124 for (Row row : workflowRuleAttributeRows.getRows()) { 125 List<Field> fields = new ArrayList<Field>(); 126 for (Iterator<Field> iterator2 = row.getFields().iterator(); iterator2.hasNext(); ) { 127 Field field = (Field) iterator2.next(); 128 if (fieldValues.get(field.getPropertyName()) != null) { 129 field.setPropertyValue(fieldValues.get(field.getPropertyName())); 130 } 131 fields.add(field); 132 fieldValues.put(field.getPropertyName(), field.getPropertyValue()); 133 } 134 } 135 // now run through a second time with our shiny new field values 136 // ...by the way, just trying to preserve behavior from Rice 1.0.x here...generally speaking, this stuff is crazy!!! 137 workflowRuleAttributeRows = 138 KEWServiceLocator.getWorkflowRuleAttributeMediator().getSearchRows(fieldValues, ruleTemplateAttribute); 139 for (Row row : workflowRuleAttributeRows.getRows()) { 140 List<Field> fields = new ArrayList<Field>(); 141 for (Iterator<Field> iterator2 = row.getFields().iterator(); iterator2.hasNext(); ) { 142 Field field = iterator2.next(); 143 if (fieldValues.get(field.getPropertyName()) != null) { 144 field.setPropertyValue(fieldValues.get(field.getPropertyName())); 145 } 146 fields.add(field); 147 fieldValues.put(field.getPropertyName(), field.getPropertyValue()); 148 } 149 row.setFields(fields); 150 rows.add(row); 151 152 } 153 } 154 return true; 155 } 156 rows.clear(); 157 return false; 158 } 159 160 @Override 161 public List<? extends BusinessObject> getSearchResults(Map<String, String> fieldValues) { 162 String docTypeNameParam = fieldValues.get(DOC_TYP_NAME_PROPERTY_NAME); 163 String ruleTemplateIdParam = fieldValues.get(RULE_TEMPLATE_ID_PROPERTY_NAME); 164 String ruleTemplateNameParam = fieldValues.get(RULE_TEMPLATE_PROPERTY_NAME); 165 String groupIdParam = fieldValues.get(GROUP_REVIEWER_PROPERTY_NAME); 166 String groupNameParam = fieldValues.get(GROUP_REVIEWER_NAME_PROPERTY_NAME); 167 String groupNamespaceParam = fieldValues.get(GROUP_REVIEWER_NAMESPACE_PROPERTY_NAME); 168 String networkIdParam = fieldValues.get(PERSON_REVIEWER_PROPERTY_NAME); 169 String userDirectiveParam = fieldValues.get(PERSON_REVIEWER_TYPE_PROPERTY_NAME); 170 String activeParam = fieldValues.get(ACTIVE_IND_PROPERTY_NAME); 171 String ruleIdParam = fieldValues.get(RULE_ID_PROPERTY_NAME); 172 String ruleDescription = fieldValues.get(RULE_DESC_PROPERTY_NAME); 173 String deleteSelection = fieldValues.get(DELEGATE_RULE_PROPERTY_NAME); 174 175 String docTypeSearchName = null; 176 String workflowId = null; 177 String workgroupId = null; 178 String ruleTemplateId = null; 179 Boolean isDelegateRule = null; 180 Boolean isActive = null; 181 String ruleId = null; 182 183 184 //for KULRICE-3678 185 if(StringUtils.isNotBlank(deleteSelection)) 186 { 187 if(deleteSelection.equalsIgnoreCase("Y")) { 188 isDelegateRule = Boolean.TRUE; 189 } else { 190 isDelegateRule = Boolean.FALSE; 191 } 192 } 193 194 if (StringUtils.isNotBlank(ruleIdParam)) { 195 ruleId = ruleIdParam.trim(); 196 } 197 198 if (StringUtils.isNotBlank(activeParam)) { 199 if (activeParam.equals("Y")) { 200 isActive = Boolean.TRUE; 201 } else { 202 isActive = Boolean.FALSE; 203 } 204 } 205 206 if (StringUtils.isNotBlank(docTypeNameParam)) { 207 docTypeSearchName = docTypeNameParam.replace('*', '%'); 208 docTypeSearchName = "%" + docTypeSearchName.trim() + "%"; 209 } 210 211 if (StringUtils.isNotBlank(networkIdParam)) { 212 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(networkIdParam); 213 if (principal != null) { 214 workflowId = principal.getPrincipalId(); 215 } 216 } 217 218 if (!StringUtils.isEmpty(groupIdParam) || !StringUtils.isEmpty(groupNameParam)) { 219 Group group = null; 220 if (groupIdParam != null && !"".equals(groupIdParam)) { 221 group = getGroupService().getGroup(groupIdParam.trim()); 222 } else { 223 if (groupNamespaceParam == null) { 224 groupNamespaceParam = KimConstants.KIM_GROUP_DEFAULT_NAMESPACE_CODE; 225 } 226 group = getGroupService().getGroupByNamespaceCodeAndName(groupNamespaceParam, groupNameParam.trim()); 227 if (group == null) { 228 GlobalVariables.getMessageMap().putError(GROUP_REVIEWER_NAMESPACE_PROPERTY_NAME, RiceKeyConstants.ERROR_CUSTOM, INVALID_WORKGROUP_ERROR); 229 } else { 230 workgroupId = group.getId(); 231 } 232 } 233 } 234 235 Map<String, String> attributes = null; 236 MyColumns myColumns = new MyColumns(); 237 if (StringUtils.isNotBlank(ruleTemplateNameParam) || StringUtils.isNotBlank(ruleTemplateIdParam) && !"null".equals(ruleTemplateIdParam)) { 238 RuleTemplate ruleTemplate = null; 239 if (StringUtils.isNotBlank(ruleTemplateIdParam)) { 240 ruleTemplate = KewApiServiceLocator.getRuleService().getRuleTemplate(ruleTemplateIdParam); 241 } else { 242 ruleTemplate = KewApiServiceLocator.getRuleService().getRuleTemplateByName(ruleTemplateNameParam.trim()); 243 ruleTemplateId = ruleTemplate.getId(); 244 } 245 246 attributes = new HashMap<String, String>(); 247 for (RuleTemplateAttribute ruleTemplateAttribute : ruleTemplate.getActiveRuleTemplateAttributes()) { 248 if (!RuleAttribute.isWorkflowAttribute(ruleTemplateAttribute.getRuleAttribute().getType())) { 249 continue; 250 } 251 WorkflowRuleAttributeRows workflowRuleAttributeRows = 252 KEWServiceLocator.getWorkflowRuleAttributeMediator().getSearchRows(fieldValues, ruleTemplateAttribute, false); 253 254 for (RemotableAttributeError error : workflowRuleAttributeRows.getValidationErrors()) { 255 GlobalVariables.getMessageMap().putError(error.getAttributeName(), RiceKeyConstants.ERROR_CUSTOM, error.getMessage()); 256 } 257 258 for (Row row : workflowRuleAttributeRows.getRows()) { 259 for (Field field : row.getFields()) { 260 if (fieldValues.get(field.getPropertyName()) != null) { 261 String attributeParam = fieldValues.get(field.getPropertyName()); 262 if (!attributeParam.equals("")) { 263 attributes.put(field.getPropertyName(), attributeParam.trim()); 264 } 265 } 266 if (field.getFieldType().equals(Field.TEXT) || field.getFieldType().equals(Field.DROPDOWN) || field.getFieldType().equals(Field.DROPDOWN_REFRESH) || field.getFieldType().equals(Field.RADIO)) { 267 myColumns.getColumns().add(new ConcreteKeyValue(field.getPropertyName(), ruleTemplateAttribute.getId())); 268 } 269 } 270 } 271 } 272 } 273 274 if (!StringUtils.isEmpty(ruleDescription)) { 275 ruleDescription = ruleDescription.replace('*', '%'); 276 ruleDescription = "%" + ruleDescription.trim() + "%"; 277 } 278 279 if (!GlobalVariables.getMessageMap().hasNoErrors()) { 280 throw new ValidationException("errors in search criteria"); 281 } 282 283 284 // TODO: replace this with new API find method ?? 285 List<RuleBaseValues> rules = getRuleService().search(docTypeSearchName, ruleId, ruleTemplateId, ruleDescription, workgroupId, workflowId, isDelegateRule, isActive, attributes, userDirectiveParam); 286 List<RuleBaseValues> displayList = new ArrayList<RuleBaseValues>(); 287 288 for (RuleBaseValues record : rules) { 289 if (StringUtils.isEmpty(record.getDescription())) { 290 record.setDescription(""); 291 } 292 293 if (ruleTemplateNameParam != null && !ruleTemplateNameParam.trim().equals("") || ruleTemplateIdParam != null && !"".equals(ruleTemplateIdParam) && !"null".equals(ruleTemplateIdParam)) { 294 MyColumns myNewColumns = new MyColumns(); 295 for (KeyValue pair : myColumns.getColumns()) { 296 final KeyValue newPair; 297 if (record.getRuleExtensionValue(pair.getValue(), pair.getKey().toString()) != null) { 298 newPair = new ConcreteKeyValue(pair.getKey(), record.getRuleExtensionValue(pair.getValue(), pair.getKey().toString()).getValue()); 299 } else { 300 newPair = new ConcreteKeyValue(pair.getKey(), ""); 301 } 302 myNewColumns.getColumns().add(newPair); 303 record.getFieldValues().put(newPair.getKey(), newPair.getValue()); 304 } 305 record.setMyColumns(myNewColumns); 306 } 307 308 StringBuffer returnUrl = new StringBuffer("<a href=\""); 309 returnUrl.append(fieldValues.get(BACK_LOCATION)).append("?methodToCall=refresh&docFormKey=").append(fieldValues.get(DOC_FORM_KEY)).append("&"); 310 311 returnUrl.append(RULE_ID_PROPERTY_NAME); 312 returnUrl.append("=").append(record.getId()).append("\">return value</a>"); 313 record.setReturnUrl(returnUrl.toString()); 314 315 String destinationUrl = "<a href=\"Rule.do?methodToCall=report¤tRuleId=" + record.getId() + "\">report</a>"; 316 317 record.setDestinationUrl(destinationUrl); 318 319 displayList.add(record); 320 } 321 return displayList; 322 323 } 324 325 326 327 private GroupService getGroupService() { 328 return KimApiServiceLocator.getGroupService(); 329 } 330 331 private RuleTemplateService getRuleTemplateService() { 332 return (RuleTemplateService) KEWServiceLocator.getService(KEWServiceLocator.RULE_TEMPLATE_SERVICE); 333 } 334 private RuleServiceInternal getRuleService() { 335 return (RuleServiceInternal) KEWServiceLocator.getService(KEWServiceLocator.RULE_SERVICE); 336 } 337 338 @Override 339 public void validateSearchParameters(Map<String, String> fieldValues) { 340 super.validateSearchParameters(fieldValues); 341 342 // make sure that if we have either groupName or Namespace, that both are filled in 343 String groupName = (String)fieldValues.get(GROUP_REVIEWER_NAME_PROPERTY_NAME); 344 String groupNamespace = (String)fieldValues.get(GROUP_REVIEWER_NAMESPACE_PROPERTY_NAME); 345 String principalName = (String)fieldValues.get(PERSON_REVIEWER_PROPERTY_NAME); 346 347 if (StringUtils.isEmpty(groupName) && !StringUtils.isEmpty(groupNamespace)) { 348 String attributeLabel = getDataDictionaryService().getAttributeLabel(getBusinessObjectClass(), GROUP_REVIEWER_NAME_PROPERTY_NAME); 349 GlobalVariables.getMessageMap().putError(GROUP_REVIEWER_NAME_PROPERTY_NAME, RiceKeyConstants.ERROR_REQUIRED, attributeLabel); 350 } 351 352 if (!StringUtils.isEmpty(groupName) && StringUtils.isEmpty(groupNamespace)) { 353 String attributeLabel = getDataDictionaryService().getAttributeLabel(getBusinessObjectClass(), GROUP_REVIEWER_NAMESPACE_PROPERTY_NAME); 354 GlobalVariables.getMessageMap().putError(GROUP_REVIEWER_NAMESPACE_PROPERTY_NAME, RiceKeyConstants.ERROR_REQUIRED, attributeLabel); 355 } 356 357 if (!StringUtils.isEmpty(groupName) && !StringUtils.isEmpty(groupNamespace)) { 358 Group group = KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName(groupNamespace, 359 groupName); 360 if (group == null) { 361 GlobalVariables.getMessageMap().putError(GROUP_REVIEWER_NAME_PROPERTY_NAME, RiceKeyConstants.ERROR_CUSTOM, INVALID_WORKGROUP_ERROR); 362 } 363 } 364 365 if (!StringUtils.isEmpty(principalName)) { 366 Person person = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(principalName); 367 if (person == null) { 368 GlobalVariables.getMessageMap().putError(PERSON_REVIEWER_PROPERTY_NAME, RiceKeyConstants.ERROR_CUSTOM, INVALID_PERSON_ERROR); 369 } 370 } 371 if (!GlobalVariables.getMessageMap().hasNoErrors()) { 372 throw new ValidationException("errors in search criteria"); 373 } 374 } 375 376 @Override 377 public Collection performLookup(LookupForm lookupForm, 378 Collection resultTable, boolean bounded) { 379 //return super.performLookup(lookupForm, resultTable, bounded); 380 setBackLocation((String) lookupForm.getFieldsForLookup().get(KRADConstants.BACK_LOCATION)); 381 setDocFormKey((String) lookupForm.getFieldsForLookup().get(KRADConstants.DOC_FORM_KEY)); 382 Collection displayList; 383 384 // call search method to get results 385 if (bounded) { 386 displayList = getSearchResults(lookupForm.getFieldsForLookup()); 387 } 388 else { 389 displayList = getSearchResultsUnbounded(lookupForm.getFieldsForLookup()); 390 } 391 392 HashMap<String,Class> propertyTypes = new HashMap<String, Class>(); 393 394 boolean hasReturnableRow = false; 395 396 List returnKeys = getReturnKeys(); 397 List pkNames = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(getBusinessObjectClass()); 398 Person user = GlobalVariables.getUserSession().getPerson(); 399 400 // iterate through result list and wrap rows with return url and action urls 401 for (Iterator iter = displayList.iterator(); iter.hasNext();) { 402 BusinessObject element = (BusinessObject) iter.next(); 403 if(element instanceof PersistableBusinessObject){ 404 lookupForm.setLookupObjectId(((PersistableBusinessObject)element).getObjectId()); 405 } 406 407 BusinessObjectRestrictions businessObjectRestrictions = getBusinessObjectAuthorizationService().getLookupResultRestrictions(element, user); 408 409 HtmlData returnUrl = getReturnUrl(element, lookupForm, returnKeys, businessObjectRestrictions); 410 411 String actionUrls = getActionUrls(element, pkNames, businessObjectRestrictions); 412 //Fix for JIRA - KFSMI-2417 413 if("".equals(actionUrls)){ 414 actionUrls = ACTION_URLS_EMPTY; 415 } 416 417 // Determine whether or not this rule is a delegate rule. 418 boolean isRuleDelegation = (element instanceof RuleBaseValues && ((RuleBaseValues) element).getDelegateRule().booleanValue()); 419 420 List<Column> columns = getColumns(); 421 for (Object element2 : columns) { 422 423 Column col = (Column) element2; 424 Formatter formatter = col.getFormatter(); 425 426 // pick off result column from result list, do formatting 427 String propValue = KRADConstants.EMPTY_STRING; 428 Object prop = null; 429 boolean skipPropTypeCheck = false; 430 //try to get value elsewhere 431 if (element instanceof RuleBaseValues) { 432 prop = ((RuleBaseValues)element).getFieldValues().get(col.getPropertyName()); 433 skipPropTypeCheck = true; 434 } 435 if (prop == null) { 436 prop = ObjectUtils.getPropertyValue(element, col.getPropertyName()); 437 } 438 439 // set comparator and formatter based on property type 440 Class propClass = propertyTypes.get(col.getPropertyName()); 441 if ( propClass == null && !skipPropTypeCheck) { 442 try { 443 propClass = ObjectUtils.getPropertyType( element, col.getPropertyName(), getPersistenceStructureService() ); 444 propertyTypes.put( col.getPropertyName(), propClass ); 445 } catch (Exception e) { 446 throw new RuntimeException("Cannot access PropertyType for property " + "'" + col.getPropertyName() + "' " + " on an instance of '" + element.getClass().getName() + "'.", e); 447 } 448 } 449 450 // formatters 451 if (prop != null) { 452 // for Booleans, always use BooleanFormatter 453 if (prop instanceof Boolean) { 454 formatter = new BooleanFormatter(); 455 } 456 457 // for Dates, always use DateFormatter 458 if (prop instanceof Date) { 459 formatter = new DateFormatter(); 460 } 461 462 // for collection, use the list formatter if a formatter hasn't been defined yet 463 if (prop instanceof Collection && formatter == null) { 464 formatter = new CollectionFormatter(); 465 } 466 467 if (formatter != null) { 468 propValue = (String) formatter.format(prop); 469 } 470 else { 471 propValue = prop.toString(); 472 } 473 } 474 475 // comparator 476 col.setComparator(CellComparatorHelper.getAppropriateComparatorForPropertyClass(propClass)); 477 col.setValueComparator(CellComparatorHelper.getAppropriateValueComparatorForPropertyClass(propClass)); 478 479 propValue = maskValueIfNecessary(element.getClass(), col.getPropertyName(), propValue, businessObjectRestrictions); 480 481 col.setPropertyValue(propValue); 482 483 if (StringUtils.isNotBlank(propValue)) { 484 if (RULE_ID_PROPERTY_NAME.equals(col.getPropertyName()) && isRuleDelegation) { 485 // If the row represents a delegate rule, make the ID column's inquiry link lead to the corresponding delegate rule instead. 486 List<?> delegationList = KEWServiceLocator.getRuleDelegationService().findByDelegateRuleId( 487 ((RuleBaseValues) element).getId()); 488 if (ObjectUtils.isNotNull(delegationList) && !delegationList.isEmpty()) { 489 BusinessObject ruleDelegation = (BusinessObject) delegationList.get(0); 490 col.setColumnAnchor(getInquiryUrl(ruleDelegation, "ruleDelegationId")); 491 } else { 492 col.setColumnAnchor(getInquiryUrl(element, col.getPropertyName())); 493 } 494 }else { 495 col.setColumnAnchor(getInquiryUrl(element, col.getPropertyName())); 496 } 497 498 } 499 } 500 501 ResultRow row = new ResultRow(columns, returnUrl.constructCompleteHtmlTag(), actionUrls); 502 row.setRowId(returnUrl.getName()); 503 row.setReturnUrlHtmlData(returnUrl); 504 // because of concerns of the BO being cached in session on the ResultRow, 505 // let's only attach it when needed (currently in the case of export) 506 if (getBusinessObjectDictionaryService().isExportable(getBusinessObjectClass())) { 507 row.setBusinessObject(element); 508 } 509 if(element instanceof PersistableBusinessObject){ 510 row.setObjectId((((PersistableBusinessObject)element).getObjectId())); 511 } 512 513 514 boolean rowReturnable = isResultReturnable(element); 515 row.setRowReturnable(rowReturnable); 516 if (rowReturnable) { 517 hasReturnableRow = true; 518 } 519 resultTable.add(row); 520 } 521 522 lookupForm.setHasReturnableRow(hasReturnableRow); 523 524 return displayList; 525 } 526 527 @Override 528 public List<Column> getColumns() { 529 List<Column> columns = super.getColumns(); 530 for (Row row : rows) { 531 for (Field field : row.getFields()) { 532 Column newColumn = new Column(); 533 newColumn.setColumnTitle(field.getFieldLabel()); 534 newColumn.setMaxLength(field.getMaxLength()); 535 newColumn.setPropertyName(field.getPropertyName()); 536 columns.add(newColumn); 537 } 538 } 539 return columns; 540 } 541 542 @Override 543 public List<HtmlData> getCustomActionUrls(BusinessObject businessObject, 544 List pkNames) { 545 RuleBaseValues ruleBaseValues = (RuleBaseValues)businessObject; 546 List<HtmlData> htmlDataList = new ArrayList<HtmlData>(); 547 if (StringUtils.isNotBlank(ruleBaseValues.getRuleTemplateName()) && StringUtils.isNotBlank(getMaintenanceDocumentTypeName())) { 548 if (ruleBaseValues.getDelegateRule().booleanValue()) { 549 // If the rule is a delegate rule, have the edit/copy links open the rule delegation maintenance document screen instead. 550 List<?> delegationList = KEWServiceLocator.getRuleDelegationService().findByDelegateRuleId(ruleBaseValues.getId()); 551 if (ObjectUtils.isNotNull(delegationList) && !delegationList.isEmpty()) { 552 BusinessObject ruleDelegation = (BusinessObject) delegationList.get(0); 553 // Retrieve the rule delegation lookupable helper service and the primary key names, if they have not been obtained yet. 554 if (ruleDelegationLookupableHelperService == null) { 555 ruleDelegationLookupableHelperService = KNSServiceLocator.getLookupable( 556 KNSServiceLocator.getBusinessObjectDictionaryService() 557 .getLookupableID(ruleDelegation.getClass())).getLookupableHelperService(); 558 if (ruleDelegationLookupableHelperService.getBusinessObjectClass() == null) { 559 ruleDelegationLookupableHelperService.setBusinessObjectClass(ruleDelegation.getClass()); 560 } 561 delegationPkNames = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(ruleDelegation.getClass()); 562 } 563 // Allow the rule delegation's lookupable helper service to handle the custom action URL generation instead. 564 htmlDataList = ruleDelegationLookupableHelperService.getCustomActionUrls(ruleDelegation, delegationPkNames); 565 } 566 } else { 567 // Otherwise, have the links open the regular routing rule maintenance document screen. 568 if (allowsMaintenanceEditAction(businessObject)) { 569 htmlDataList.add(getUrlData(businessObject, KRADConstants.MAINTENANCE_EDIT_METHOD_TO_CALL, pkNames)); 570 } 571 if (allowsMaintenanceNewOrCopyAction()) { 572 htmlDataList.add(getUrlData(businessObject, KRADConstants.MAINTENANCE_COPY_METHOD_TO_CALL, pkNames)); 573 } 574 } 575 } 576 577 return htmlDataList; 578 } 579 580 581 582 }