View Javadoc

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.kew.rule;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.hibernate.annotations.Fetch;
20  import org.hibernate.annotations.FetchMode;
21  import org.hibernate.annotations.GenericGenerator;
22  import org.hibernate.annotations.Parameter;
23  import org.joda.time.DateTime;
24  import org.kuali.rice.core.api.util.RiceConstants;
25  import org.kuali.rice.kew.api.rule.RuleContract;
26  import org.kuali.rice.kew.api.rule.RuleExtension;
27  import org.kuali.rice.kew.api.util.CodeTranslator;
28  import org.kuali.rice.kew.doctype.bo.DocumentType;
29  import org.kuali.rice.kew.lookupable.MyColumns;
30  import org.kuali.rice.kew.routeheader.DocumentContent;
31  import org.kuali.rice.kew.rule.bo.RuleAttribute;
32  import org.kuali.rice.kew.rule.bo.RuleTemplateAttributeBo;
33  import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
34  import org.kuali.rice.kew.rule.service.RuleServiceInternal;
35  import org.kuali.rice.kew.rule.xmlrouting.GenericXMLRuleAttribute;
36  import org.kuali.rice.kew.service.KEWServiceLocator;
37  import org.kuali.rice.kew.api.KewApiConstants;
38  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
39  import org.kuali.rice.kim.impl.group.GroupBo;
40  import org.kuali.rice.kim.impl.identity.PersonImpl;
41  import org.kuali.rice.kns.web.ui.Field;
42  import org.kuali.rice.kns.web.ui.Row;
43  import org.kuali.rice.krad.bo.PersistableBusinessObjectBase;
44  
45  import javax.persistence.CascadeType;
46  import javax.persistence.Column;
47  import javax.persistence.Entity;
48  import javax.persistence.FetchType;
49  import javax.persistence.GeneratedValue;
50  import javax.persistence.Id;
51  import javax.persistence.JoinColumn;
52  import javax.persistence.ManyToOne;
53  import javax.persistence.OneToMany;
54  import javax.persistence.OneToOne;
55  import javax.persistence.Table;
56  import javax.persistence.Transient;
57  import java.sql.Timestamp;
58  import java.util.ArrayList;
59  import java.util.Date;
60  import java.util.HashMap;
61  import java.util.Iterator;
62  import java.util.List;
63  import java.util.Map;
64  
65  /*import org.kuali.rice.kim.api.group.Group;*/
66  
67  
68  /**
69   * A model bean for a Rule within the KEW rules engine.
70   *
71   * @author Kuali Rice Team (rice.collab@kuali.org)
72   */
73  @Entity
74  @Table(name="KREW_RULE_T")
75  //@Sequence(name="KREW_RTE_TMPL_S", property="id")
76  public class RuleBaseValues extends PersistableBusinessObjectBase implements RuleContract {
77  
78      private static final long serialVersionUID = 6137765574728530156L;
79      @Id
80      @GeneratedValue(generator="KREW_RTE_TMPL_S")
81  	@GenericGenerator(name="KREW_RTE_TMPL_S",strategy="org.hibernate.id.enhanced.SequenceStyleGenerator",parameters={
82  			@Parameter(name="sequence_name",value="KREW_RTE_TMPL_S"),
83  			@Parameter(name="value_column",value="id")
84  	})
85  	@Column(name="RULE_ID")
86      private String id;
87      /**
88       * Unique Rule name
89       */
90      @Column(name="NM")
91  	private String name;
92      @Column(name="RULE_TMPL_ID", insertable=false, updatable=false)
93  	private String ruleTemplateId;
94      @Column(name="PREV_VER_RULE_ID")
95  	private String previousRuleId;
96      @Column(name="ACTV_IND")
97  	private boolean active = true;
98      @Column(name="RULE_BASE_VAL_DESC")
99  	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 }