001/** 002 * Copyright 2005-2015 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 */ 016package org.kuali.rice.kew.rule; 017 018import org.apache.commons.lang.StringUtils; 019import org.hibernate.annotations.Fetch; 020import org.hibernate.annotations.FetchMode; 021import org.hibernate.annotations.GenericGenerator; 022import org.hibernate.annotations.Parameter; 023import org.joda.time.DateTime; 024import org.kuali.rice.core.api.util.RiceConstants; 025import org.kuali.rice.kew.api.rule.RuleContract; 026import org.kuali.rice.kew.api.rule.RuleExtension; 027import org.kuali.rice.kew.api.util.CodeTranslator; 028import org.kuali.rice.kew.doctype.bo.DocumentType; 029import org.kuali.rice.kew.lookupable.MyColumns; 030import org.kuali.rice.kew.routeheader.DocumentContent; 031import org.kuali.rice.kew.rule.bo.RuleAttribute; 032import org.kuali.rice.kew.rule.bo.RuleTemplateAttributeBo; 033import org.kuali.rice.kew.rule.bo.RuleTemplateBo; 034import org.kuali.rice.kew.rule.service.RuleServiceInternal; 035import org.kuali.rice.kew.rule.xmlrouting.GenericXMLRuleAttribute; 036import org.kuali.rice.kew.service.KEWServiceLocator; 037import org.kuali.rice.kew.api.KewApiConstants; 038import org.kuali.rice.kim.api.services.KimApiServiceLocator; 039import org.kuali.rice.kim.impl.group.GroupBo; 040import org.kuali.rice.kim.impl.identity.PersonImpl; 041import org.kuali.rice.kns.web.ui.Field; 042import org.kuali.rice.kns.web.ui.Row; 043import org.kuali.rice.krad.bo.PersistableBusinessObjectBase; 044 045import javax.persistence.CascadeType; 046import javax.persistence.Column; 047import javax.persistence.Entity; 048import javax.persistence.FetchType; 049import javax.persistence.GeneratedValue; 050import javax.persistence.Id; 051import javax.persistence.JoinColumn; 052import javax.persistence.ManyToOne; 053import javax.persistence.OneToMany; 054import javax.persistence.OneToOne; 055import javax.persistence.Table; 056import javax.persistence.Transient; 057import java.sql.Timestamp; 058import java.util.ArrayList; 059import java.util.Date; 060import java.util.HashMap; 061import java.util.Iterator; 062import java.util.List; 063import java.util.Map; 064 065/*import org.kuali.rice.kim.api.group.Group;*/ 066 067 068/** 069 * A model bean for a Rule within the KEW rules engine. 070 * 071 * @author Kuali Rice Team (rice.collab@kuali.org) 072 */ 073@Entity 074@Table(name="KREW_RULE_T") 075//@Sequence(name="KREW_RTE_TMPL_S", property="id") 076public class RuleBaseValues extends PersistableBusinessObjectBase implements RuleContract { 077 078 private static final long serialVersionUID = 6137765574728530156L; 079 @Id 080 @GeneratedValue(generator="KREW_RTE_TMPL_S") 081 @GenericGenerator(name="KREW_RTE_TMPL_S",strategy="org.hibernate.id.enhanced.SequenceStyleGenerator",parameters={ 082 @Parameter(name="sequence_name",value="KREW_RTE_TMPL_S"), 083 @Parameter(name="value_column",value="id") 084 }) 085 @Column(name="RULE_ID") 086 private String id; 087 /** 088 * Unique Rule name 089 */ 090 @Column(name="NM") 091 private String name; 092 @Column(name="RULE_TMPL_ID", insertable=false, updatable=false) 093 private String ruleTemplateId; 094 @Column(name="PREV_VER_RULE_ID") 095 private String previousRuleId; 096 @Column(name="ACTV_IND") 097 private boolean active = true; 098 @Column(name="RULE_BASE_VAL_DESC") 099 private String description; 100 @Column(name="DOC_TYP_NM") 101 private String docTypeName; 102 @Column(name="DOC_HDR_ID") 103 private String documentId; 104 @Column(name="FRM_DT") 105 private Timestamp fromDateValue; 106 @Column(name="TO_DT") 107 private Timestamp toDateValue; 108 @Column(name="DACTVN_DT") 109 private Timestamp deactivationDate; 110 @Column(name="CUR_IND") 111 private Boolean currentInd = Boolean.TRUE; 112 @Column(name="RULE_VER_NBR") 113 private Integer versionNbr = new Integer(0); 114 @Column(name="FRC_ACTN") 115 private boolean forceAction; 116 @Fetch(value = FetchMode.SELECT) 117 @OneToMany(fetch=FetchType.EAGER,cascade={CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE},mappedBy="ruleBaseValues") 118 private List<RuleResponsibilityBo> ruleResponsibilities; 119 @Fetch(value = FetchMode.SELECT) 120 @OneToMany(fetch=FetchType.EAGER,cascade={CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE},mappedBy="ruleBaseValues") 121 private List<RuleExtensionBo> ruleExtensions; 122 @ManyToOne(fetch=FetchType.EAGER) 123 @JoinColumn(name="RULE_TMPL_ID") 124 private RuleTemplateBo ruleTemplate; 125 @OneToOne(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE}) 126 @JoinColumn(name="RULE_EXPR_ID") 127 private RuleExpressionDef ruleExpressionDef; 128 @Transient 129 private RuleBaseValues previousVersion; 130 @Column(name="ACTVN_DT") 131 private Timestamp activationDate; 132 @Column(name="DLGN_IND") 133 private Boolean delegateRule = Boolean.FALSE; 134 /** 135 * Indicator that signifies that this rule is a defaults/template rule which contains 136 * template-defined rule defaults for other rules which use the associated template 137 */ 138 @Column(name="TMPL_RULE_IND") 139 private Boolean templateRuleInd = Boolean.FALSE; 140 141 // required to be lookupable 142 @Transient 143 private String returnUrl; 144 @Transient 145 private String destinationUrl; 146 @Transient 147 private MyColumns myColumns; 148 @Transient 149 private List<PersonRuleResponsibility> personResponsibilities = new ArrayList<PersonRuleResponsibility>(); 150 @Transient 151 private List<GroupRuleResponsibility> groupResponsibilities = new ArrayList<GroupRuleResponsibility>(); 152 @Transient 153 private List<RoleRuleResponsibility> roleResponsibilities = new ArrayList<RoleRuleResponsibility>(); 154 @Transient 155 private Map<String, String> fieldValues; 156 @Transient 157 private String groupReviewerName; 158 @Transient 159 private String groupReviewerNamespace; 160 @Transient 161 private String personReviewer; 162 @Transient 163 private String personReviewerType; 164 165 public RuleBaseValues() { 166 ruleResponsibilities = new ArrayList<RuleResponsibilityBo>(); 167 ruleExtensions = new ArrayList<RuleExtensionBo>(); 168 /*personResponsibilities = new AutoPopulatingList<PersonRuleResponsibility>(PersonRuleResponsibility.class); 169 groupResponsibilities = new AutoPopulatingList<GroupRuleResponsibility>(GroupRuleResponsibility.class); 170 roleResponsibilities = new AutoPopulatingList<RoleRuleResponsibility>(RoleRuleResponsibility.class);*/ 171 fieldValues = new HashMap<String, String>(); 172 } 173 174 /** 175 * @return the rule expression definition for this rule, if defined 176 */ 177 public RuleExpressionDef getRuleExpressionDef() { 178 return ruleExpressionDef; 179 } 180 181 /** 182 * @param ruleExpressionDef the rule expression definition to set for this rule 183 */ 184 public void setRuleExpressionDef(RuleExpressionDef ruleExpressionDef) { 185 this.ruleExpressionDef = ruleExpressionDef; 186 } 187 188 public String getRuleTemplateName() { 189 if (ruleTemplate != null) { 190 return ruleTemplate.getName(); 191 } 192 return null; 193 } 194 195 public RuleBaseValues getPreviousVersion() { 196 if (previousVersion == null && previousRuleId != null) { 197 RuleServiceInternal ruleService = (RuleServiceInternal) KEWServiceLocator.getService(KEWServiceLocator.RULE_SERVICE); 198 return ruleService.findRuleBaseValuesById(previousRuleId); 199 } 200 return previousVersion; 201 } 202 203 public void setPreviousVersion(RuleBaseValues previousVersion) { 204 this.previousVersion = previousVersion; 205 } 206 207 public RuleResponsibilityBo getResponsibility(int index) { 208 while (getRuleResponsibilities().size() <= index) { 209 RuleResponsibilityBo ruleResponsibility = new RuleResponsibilityBo(); 210 ruleResponsibility.setRuleBaseValues(this); 211 getRuleResponsibilities().add(ruleResponsibility); 212 } 213 return (RuleResponsibilityBo) getRuleResponsibilities().get(index); 214 } 215 216 public RuleExtensionBo getRuleExtension(int index) { 217 while (getRuleExtensions().size() <= index) { 218 getRuleExtensions().add(new RuleExtensionBo()); 219 } 220 return (RuleExtensionBo) getRuleExtensions().get(index); 221 } 222 223 public RuleExtensionValue getRuleExtensionValue(String key) { 224 for (Iterator iter = getRuleExtensions().iterator(); iter.hasNext();) { 225 RuleExtensionBo ruleExtension = (RuleExtensionBo) iter.next(); 226 for (Iterator iterator = ruleExtension.getExtensionValues().iterator(); iterator.hasNext();) { 227 RuleExtensionValue ruleExtensionValue = (RuleExtensionValue) iterator.next(); 228 if (ruleExtensionValue.getKey().equals(key)) { 229 return ruleExtensionValue; 230 } 231 } 232 } 233 return null; 234 } 235 236 public RuleExtensionValue getRuleExtensionValue(String ruleTemplateAttributeId, String key) { 237 for (Iterator iter = getRuleExtensions().iterator(); iter.hasNext();) { 238 RuleExtensionBo ruleExtension = (RuleExtensionBo) iter.next(); 239 if (ruleExtension.getRuleTemplateAttributeId().equals(ruleTemplateAttributeId)) { 240 for (Iterator iterator = ruleExtension.getExtensionValues().iterator(); iterator.hasNext();) { 241 RuleExtensionValue ruleExtensionValue = (RuleExtensionValue) iterator.next(); 242 if (ruleExtensionValue.getKey().equals(key)) { 243 return ruleExtensionValue; 244 } 245 } 246 } 247 } 248 return null; 249 } 250 251 public String getPreviousRuleId() { 252 return previousRuleId; 253 } 254 255 public void setPreviousRuleId(String previousVersion) { 256 this.previousRuleId = previousVersion; 257 } 258 259 public void addRuleResponsibility(RuleResponsibilityBo ruleResponsibility) { 260 addRuleResponsibility(ruleResponsibility, new Integer(getRuleResponsibilities().size())); 261 } 262 263 public void addRuleResponsibility(RuleResponsibilityBo ruleResponsibility, Integer counter) { 264 boolean alreadyAdded = false; 265 int location = 0; 266 if (counter != null) { 267 for (RuleResponsibilityBo ruleResponsibilityRow : getRuleResponsibilities()) { 268 if (counter.intValue() == location) { 269 ruleResponsibilityRow.setPriority(ruleResponsibility.getPriority()); 270 ruleResponsibilityRow.setActionRequestedCd(ruleResponsibility.getActionRequestedCd()); 271 ruleResponsibilityRow.setVersionNumber(ruleResponsibility.getVersionNumber()); 272 ruleResponsibilityRow.setRuleBaseValuesId(ruleResponsibility.getRuleBaseValuesId()); 273 ruleResponsibilityRow.setRuleResponsibilityName(ruleResponsibility.getRuleResponsibilityName()); 274 ruleResponsibilityRow.setRuleResponsibilityType(ruleResponsibility.getRuleResponsibilityType()); 275 //ruleResponsibilityRow.setDelegationRules(ruleResponsibility.getDelegationRules()); 276 ruleResponsibilityRow.setApprovePolicy(ruleResponsibility.getApprovePolicy()); 277 alreadyAdded = true; 278 } 279 location++; 280 } 281 } 282 if (!alreadyAdded) { 283 getRuleResponsibilities().add(ruleResponsibility); 284 } 285 } 286 287 public RuleTemplateBo getRuleTemplate() { 288 return ruleTemplate; 289 } 290 291 public void setRuleTemplate(RuleTemplateBo ruleTemplate) { 292 this.ruleTemplate = ruleTemplate; 293 } 294 295 public String getRuleTemplateId() { 296 return ruleTemplateId; 297 } 298 299 public void setRuleTemplateId(String ruleTemplateId) { 300 this.ruleTemplateId = ruleTemplateId; 301 } 302 303 public DocumentType getDocumentType() { 304 return KEWServiceLocator.getDocumentTypeService().findByName(getDocTypeName()); 305 } 306 307 public String getDocTypeName() { 308 return docTypeName; 309 } 310 311 public void setDocTypeName(String docTypeName) { 312 this.docTypeName = docTypeName; 313 } 314 315 public List<RuleExtensionBo> getRuleExtensions() { 316 return ruleExtensions; 317 } 318 319 public Map<String, String> getRuleExtensionMap() { 320 Map<String, String> extensions = new HashMap<String, String>(); 321 for (RuleExtensionBo ext : this.getRuleExtensions()) { 322 for (RuleExtensionValue value : ext.getExtensionValues()) { 323 extensions.put(value.getKey(), value.getValue()); 324 } 325 } 326 return extensions; 327 } 328 329 public void setRuleExtensions(List<RuleExtensionBo> ruleExtensions) { 330 this.ruleExtensions = ruleExtensions; 331 } 332 333 public List<RuleResponsibilityBo> getRuleResponsibilities() { 334 return this.ruleResponsibilities; 335 } 336 337 public void setRuleResponsibilities(List<RuleResponsibilityBo> ruleResponsibilities) { 338 this.ruleResponsibilities = ruleResponsibilities; 339 } 340 341 public RuleResponsibilityBo getResponsibility(Long ruleResponsibilityKey) { 342 for (Iterator iterator = getRuleResponsibilities().iterator(); iterator.hasNext();) { 343 RuleResponsibilityBo responsibility = (RuleResponsibilityBo) iterator.next(); 344 if (responsibility.getId() != null 345 && responsibility.getId().equals(ruleResponsibilityKey)) { 346 return responsibility; 347 } 348 } 349 return null; 350 } 351 352 public void removeResponsibility(int index) { 353 getRuleResponsibilities().remove(index); 354 } 355 356 @Override 357 public boolean isActive() { 358 return active; 359 } 360 361 public void setActive(boolean active) { 362 this.active = active; 363 } 364 365 public String getActiveIndDisplay() { 366 return CodeTranslator.getActiveIndicatorLabel(isActive()); 367 } 368 369 public Boolean getCurrentInd() { 370 return currentInd; 371 } 372 373 public void setCurrentInd(Boolean currentInd) { 374 this.currentInd = currentInd; 375 } 376 377 public Timestamp getFromDateValue() { 378 return fromDateValue; 379 } 380 381 @Override 382 public DateTime getFromDate() { 383 if (this.fromDateValue == null) { 384 return null; 385 } 386 return new DateTime(this.fromDateValue.getTime()); 387 } 388 389 public void setFromDateValue(Timestamp fromDateValue) { 390 this.fromDateValue = fromDateValue; 391 } 392 393 public String getDescription() { 394 return description; 395 } 396 397 public void setDescription(String description) { 398 this.description = description; 399 } 400 401 public String getId() { 402 return id; 403 } 404 405 public void setId(String id) { 406 this.id = id; 407 } 408 409 public Timestamp getToDateValue() { 410 return toDateValue; 411 } 412 413 @Override 414 public DateTime getToDate() { 415 if (this.toDateValue == null) { 416 return null; 417 } 418 return new DateTime(this.toDateValue.getTime()); 419 } 420 421 public void setToDateValue(Timestamp toDateValue) { 422 this.toDateValue = toDateValue; 423 } 424 425 public Integer getVersionNbr() { 426 return versionNbr; 427 } 428 429 public void setVersionNbr(Integer versionNbr) { 430 this.versionNbr = versionNbr; 431 } 432 433 public String getReturnUrl() { 434 return returnUrl; 435 } 436 437 public void setReturnUrl(String returnUrl) { 438 this.returnUrl = returnUrl; 439 } 440 441 public String getFromDateString() { 442 if (this.fromDateValue != null) { 443 return RiceConstants.getDefaultDateFormat().format(this.fromDateValue); 444 } 445 return null; 446 } 447 448 public String getToDateString() { 449 if (this.toDateValue != null) { 450 return RiceConstants.getDefaultDateFormat().format(this.toDateValue); 451 } 452 return null; 453 } 454 455 @Override 456 public boolean isForceAction() { 457 return forceAction; 458 } 459 460 public void setForceAction(boolean forceAction) { 461 this.forceAction = forceAction; 462 } 463 464 public boolean isActive(Date date) { 465 boolean isAfterFromDate = getFromDateValue() == null || date.after(getFromDateValue()); 466 boolean isBeforeToDate = getToDateValue() == null || date.before(getToDateValue()); 467 return isActive() && isAfterFromDate && isBeforeToDate; 468 } 469 470 public boolean isMatch(DocumentContent docContent) { 471 for (RuleTemplateAttributeBo ruleTemplateAttribute : getRuleTemplate().getActiveRuleTemplateAttributes()) { 472 if (!ruleTemplateAttribute.isWorkflowAttribute()) { 473 continue; 474 } 475 WorkflowRuleAttribute routingAttribute = (WorkflowRuleAttribute) ruleTemplateAttribute.getWorkflowAttribute(); 476 477 RuleAttribute ruleAttribute = ruleTemplateAttribute.getRuleAttribute(); 478 if (ruleAttribute.getType().equals(KewApiConstants.RULE_XML_ATTRIBUTE_TYPE)) { 479 ((GenericXMLRuleAttribute) routingAttribute).setExtensionDefinition(RuleAttribute.to(ruleAttribute)); 480 } 481 String className = ruleAttribute.getResourceDescriptor(); 482 List<RuleExtension> editedRuleExtensions = new ArrayList<RuleExtension>(); 483 for (RuleExtensionBo extension : getRuleExtensions()) { 484 if (extension.getRuleTemplateAttribute().getRuleAttribute().getResourceDescriptor().equals(className)) { 485 editedRuleExtensions.add(RuleExtensionBo.to(extension)); 486 } 487 } 488 if (!routingAttribute.isMatch(docContent, editedRuleExtensions)) { 489 return false; 490 } 491 } 492 return true; 493 } 494 495 public RuleResponsibilityBo findResponsibility(String roleName) { 496 for (Iterator iter = getRuleResponsibilities().iterator(); iter.hasNext();) { 497 RuleResponsibilityBo resp = (RuleResponsibilityBo) iter.next(); 498 if (KewApiConstants.RULE_RESPONSIBILITY_ROLE_ID.equals(resp.getRuleResponsibilityType()) 499 && roleName.equals(resp.getRuleResponsibilityName())) { 500 return resp; 501 } 502 } 503 return null; 504 } 505 506 public String getDocumentId() { 507 return documentId; 508 } 509 510 public void setDocumentId(String documentId) { 511 this.documentId = documentId; 512 } 513 514 public Boolean getDelegateRule() { 515 return delegateRule; 516 } 517 518 public void setDelegateRule(Boolean isDelegateRule) { 519 this.delegateRule = isDelegateRule; 520 } 521 522 public Timestamp getActivationDate() { 523 return activationDate; 524 } 525 526 public void setActivationDate(Timestamp activationDate) { 527 this.activationDate = activationDate; 528 } 529 530 public MyColumns getMyColumns() { 531 return myColumns; 532 } 533 534 public void setMyColumns(MyColumns additionalColumns) { 535 this.myColumns = additionalColumns; 536 } 537 538 public String getDestinationUrl() { 539 return destinationUrl; 540 } 541 542 public void setDestinationUrl(String destinationUrl) { 543 this.destinationUrl = destinationUrl; 544 } 545 546 public Timestamp getDeactivationDate() { 547 return deactivationDate; 548 } 549 550 public void setDeactivationDate(Timestamp deactivationDate) { 551 this.deactivationDate = deactivationDate; 552 } 553 554 /** 555 * @return whether this is a defaults/template rule 556 */ 557 public Boolean getTemplateRuleInd() { 558 return templateRuleInd; 559 } 560 561 /** 562 * @param templateRuleInd whether this is a defaults/template rule 563 */ 564 public void setTemplateRuleInd(Boolean templateRuleInd) { 565 this.templateRuleInd = templateRuleInd; 566 } 567 568 /** 569 * Get the rule name 570 * @return the rule name 571 */ 572 public String getName() { 573 return name; 574 } 575 576 /** 577 * Set the rule name 578 * @param name the rule name 579 */ 580 public void setName(String name) { 581 this.name = name; 582 } 583 584 public List<PersonRuleResponsibility> getPersonResponsibilities() { 585 return this.personResponsibilities; 586 } 587 588 public void setPersonResponsibilities(List<PersonRuleResponsibility> personResponsibilities) { 589 this.personResponsibilities = personResponsibilities; 590 } 591 592 public List<GroupRuleResponsibility> getGroupResponsibilities() { 593 return this.groupResponsibilities; 594 } 595 596 public void setGroupResponsibilities(List<GroupRuleResponsibility> groupResponsibilities) { 597 this.groupResponsibilities = groupResponsibilities; 598 } 599 600 public List<RoleRuleResponsibility> getRoleResponsibilities() { 601 return this.roleResponsibilities; 602 } 603 604 public void setRoleResponsibilities(List<RoleRuleResponsibility> roleResponsibilities) { 605 this.roleResponsibilities = roleResponsibilities; 606 } 607 608 /** 609 * @return the fieldValues 610 */ 611 public Map<String, String> getFieldValues() { 612 return this.fieldValues; 613 } 614 615 /** 616 * @param fieldValues the fieldValues to set 617 */ 618 public void setFieldValues(Map<String, String> fieldValues) { 619 this.fieldValues = fieldValues; 620 } 621 622 public String getGroupReviewerName() { 623 return this.groupReviewerName; 624 } 625 626 public String getGroupReviewerNamespace() { 627 return this.groupReviewerNamespace; 628 } 629 630 public String getPersonReviewer() { 631 return this.personReviewer; 632 } 633 634 public void setGroupReviewerName(String groupReviewerName) { 635 this.groupReviewerName = groupReviewerName; 636 } 637 638 public void setGroupReviewerNamespace(String groupReviewerNamespace) { 639 this.groupReviewerNamespace = groupReviewerNamespace; 640 } 641 642 public void setPersonReviewer(String personReviewer) { 643 this.personReviewer = personReviewer; 644 } 645 646 public GroupBo getGroupBo() { 647 GroupBo groupBo = null; 648 if (StringUtils.isNotBlank(getGroupReviewerName())) { 649 if ( groupBo == null ) { 650 groupBo = GroupBo.from(KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName( 651 getGroupReviewerNamespace(), getGroupReviewerName())); 652 } 653 } 654 return groupBo; 655 } 656 657 public PersonImpl getPersonImpl() { 658 return new PersonImpl(); 659 } 660 661 public String getPersonReviewerType() { 662 return this.personReviewerType; 663 } 664 665 public void setPersonReviewerType(String personReviewerType) { 666 this.personReviewerType = personReviewerType; 667 } 668 669 /** 670 * Converts a mutable bo to its immutable counterpart 671 * @param bo the mutable business object 672 * @return the immutable object 673 */ 674 public static org.kuali.rice.kew.api.rule.Rule to(RuleBaseValues bo) { 675 if (bo == null) { 676 return null; 677 } 678 return org.kuali.rice.kew.api.rule.Rule.Builder.create(bo).build(); 679 } 680}