001/** 002 * Copyright 2005-2016 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.bo; 017 018import org.apache.commons.lang.ArrayUtils; 019import org.hibernate.annotations.Fetch; 020import org.hibernate.annotations.FetchMode; 021import org.hibernate.annotations.GenericGenerator; 022import org.hibernate.annotations.Parameter; 023import org.kuali.rice.kew.api.KewApiConstants; 024import org.kuali.rice.kew.api.rule.RoleName; 025import org.kuali.rice.kew.api.rule.RuleTemplate; 026import org.kuali.rice.kew.api.rule.RuleTemplateContract; 027import org.kuali.rice.kew.rule.RuleTemplateOptionBo; 028import org.kuali.rice.kew.service.KEWServiceLocator; 029import org.kuali.rice.krad.bo.PersistableBusinessObjectBase; 030 031import javax.persistence.CascadeType; 032import javax.persistence.Column; 033import javax.persistence.Entity; 034import javax.persistence.FetchType; 035import javax.persistence.GeneratedValue; 036import javax.persistence.Id; 037import javax.persistence.JoinColumn; 038import javax.persistence.NamedQueries; 039import javax.persistence.NamedQuery; 040import javax.persistence.OneToMany; 041import javax.persistence.OneToOne; 042import javax.persistence.Table; 043import javax.persistence.Transient; 044import java.net.URLEncoder; 045import java.util.ArrayList; 046import java.util.Collections; 047import java.util.Iterator; 048import java.util.List; 049 050 051/** 052 * A model bean which represents a template upon which a rule is created. 053 * The RuleTemplate is essentially a collection of {@link RuleAttribute}s 054 * (associated vai the {@link RuleTemplateAttributeBo} bean). 055 * 056 * @author Kuali Rice Team (rice.collab@kuali.org) 057 */ 058@Entity 059@Table(name="KREW_RULE_TMPL_T") 060//@Sequence(name="KREW_RTE_TMPL_S", property="id") 061@NamedQueries({@NamedQuery(name="findAllOrderedByName", query="SELECT rt FROM RuleTemplate rt ORDER BY rt.name ASC")}) 062public class RuleTemplateBo extends PersistableBusinessObjectBase implements RuleTemplateContract { 063 064 private static final long serialVersionUID = -3387940485523951302L; 065 066 /** 067 * A list of default rule template option keys. 068 */ 069 public static final String[] DEFAULT_OPTION_KEYS = { 070 //KewApiConstants.RULE_INSTRUCTIONS_CD, 071 KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, 072 KewApiConstants.ACTION_REQUEST_APPROVE_REQ, 073 KewApiConstants.ACTION_REQUEST_COMPLETE_REQ, 074 KewApiConstants.ACTION_REQUEST_FYI_REQ, 075 KewApiConstants.ACTION_REQUEST_DEFAULT_CD 076 }; 077 078 @Id 079 @GeneratedValue(generator="KREW_RTE_TMPL_S") 080 @GenericGenerator(name="KREW_RTE_TMPL_S",strategy="org.hibernate.id.enhanced.SequenceStyleGenerator",parameters={ 081 @Parameter(name="sequence_name",value="KREW_RTE_TMPL_S"), 082 @Parameter(name="value_column",value="id") 083 }) 084 @Column(name="RULE_TMPL_ID") 085 private String id; 086 @Column(name="NM") 087 private String name; 088 @Column(name="RULE_TMPL_DESC") 089 private String description; 090 091 @Column(name="DLGN_RULE_TMPL_ID", insertable=false, updatable=false) 092 private String delegationTemplateId; 093 @OneToOne(fetch=FetchType.EAGER) 094 @JoinColumn(name="DLGN_RULE_TMPL_ID") 095 private RuleTemplateBo delegationTemplate; 096 @Fetch(value = FetchMode.SELECT) 097 @OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE}, 098 mappedBy="ruleTemplate") 099 private List<RuleTemplateAttributeBo> ruleTemplateAttributes; 100 @Fetch(value = FetchMode.SELECT) 101 @OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE}, 102 mappedBy="ruleTemplate", orphanRemoval=true) 103 private List<RuleTemplateOptionBo> ruleTemplateOptions; 104 105 // required to be lookupable 106 @Transient 107 private String returnUrl; 108 109 public RuleTemplateBo() { 110 ruleTemplateAttributes = new ArrayList<RuleTemplateAttributeBo>(); 111 ruleTemplateOptions = new ArrayList<RuleTemplateOptionBo>(); 112 } 113 114 115 /** 116 * Removes any non-default rule template options on the template 117 */ 118 public void removeNonDefaultOptions() { 119 Iterator<RuleTemplateOptionBo> it = ruleTemplateOptions.iterator(); 120 while (it.hasNext()) { 121 RuleTemplateOptionBo option = it.next(); 122 // if it's not one of the default options, remove it 123 if (!ArrayUtils.contains(DEFAULT_OPTION_KEYS, option.getCode())) { 124 it.remove(); 125 } 126 } 127 } 128 129 public String getDelegateTemplateName() { 130 if (delegationTemplate != null) { 131 return delegationTemplate.getName(); 132 } 133 return ""; 134 } 135 136 public String getRuleTemplateActionsUrl() { 137 return "<a href=\"RuleTemplate.do?methodToCall=report¤tRuleTemplateId=" + id + "\" >report</a>" /*+ " | <a href=\"RuleTemplate.do?methodToCall=edit&ruleTemplate.id=" + id + "\" >edit</a>"*/; 138 } 139 140 /** 141 * Returns the rule template attribute on this instance whose name matches the name of the rule template attribute 142 * passed as a parameter, qualified by it's active state, or null if a match was not found. 143 */ 144 private RuleTemplateAttributeBo getRuleTemplateAttribute(RuleTemplateAttributeBo ruleTemplateAttribute, Boolean active) { 145 for (RuleTemplateAttributeBo currentRuleTemplateAttribute: getRuleTemplateAttributes()) { 146 if (currentRuleTemplateAttribute.getRuleAttribute().getName().equals(ruleTemplateAttribute.getRuleAttribute().getName())) { 147 if (active == null) { 148 return currentRuleTemplateAttribute; 149 } 150 else if (active.compareTo(currentRuleTemplateAttribute.getActive()) == 0) { 151 return currentRuleTemplateAttribute; 152 } 153 } 154 } 155 return null; 156 } 157 158 public RuleTemplateAttributeBo getRuleTemplateAttribute(RuleTemplateAttributeBo ruleTemplateAttribute) { 159 return getRuleTemplateAttribute(ruleTemplateAttribute, null); 160 } 161 162 public boolean containsActiveRuleTemplateAttribute(RuleTemplateAttributeBo templateAttribute) { 163 return (getRuleTemplateAttribute(templateAttribute, Boolean.TRUE) != null); 164 } 165 166 public boolean containsRuleTemplateAttribute(RuleTemplateAttributeBo templateAttribute) { 167 return (getRuleTemplateAttribute(templateAttribute, null) != null); 168 } 169 170 public RuleTemplateAttributeBo getRuleTemplateAttribute(int index) { 171 while (getRuleTemplateAttributes().size() <= index) { 172 getRuleTemplateAttributes().add(new RuleTemplateAttributeBo()); 173 } 174 return (RuleTemplateAttributeBo) getRuleTemplateAttributes().get(index); 175 } 176 177 public List<RuleTemplateAttributeBo> getRuleTemplateAttributes() { 178 Collections.sort(ruleTemplateAttributes); 179 return ruleTemplateAttributes; 180 } 181 182 /** 183 * Returns a List of only the active RuleTemplateAttributes on the RuleTemplate 184 * sorted according to display order (ascending). 185 * @return 186 */ 187 public List<RuleTemplateAttributeBo> getActiveRuleTemplateAttributes() { 188 List<RuleTemplateAttributeBo> activeAttributes = new ArrayList<RuleTemplateAttributeBo>(); 189 for (RuleTemplateAttributeBo templateAttribute : getRuleTemplateAttributes()) 190 { 191 if (templateAttribute.isActive()) 192 { 193 activeAttributes.add(templateAttribute); 194 } 195 } 196 Collections.sort(activeAttributes); 197 return activeAttributes; 198 } 199 200 /** 201 * This is implemented to allow us to use this collection on the inquiry for RuleTemplate. In the 202 * KNS code it does an explicit check that the property is writable. 203 */ 204 public void setActiveRuleTemplateAttributes(List<RuleTemplateAttributeBo> ruleTemplateAttributes) { 205 throw new UnsupportedOperationException("setActiveRuleTemplateAttributes is not implemented"); 206 } 207 208 public void setRuleTemplateAttributes(List<RuleTemplateAttributeBo> ruleTemplateAttributes) { 209 this.ruleTemplateAttributes = ruleTemplateAttributes; 210 } 211 212 public String getDescription() { 213 return description; 214 } 215 216 public void setDescription(String description) { 217 this.description = description; 218 } 219 220 public String getName() { 221 return name; 222 } 223 224 public void setName(String name) { 225 this.name = name; 226 } 227 228 public String getId() { 229 return id; 230 } 231 232 public void setId(String id) { 233 this.id = id; 234 } 235 236 public String getDelegationTemplateId() { 237 return delegationTemplateId; 238 } 239 240 public void setDelegationTemplateId(String delegationTemplateId) { 241 this.delegationTemplateId = delegationTemplateId; 242 } 243 244 public RuleTemplateBo getDelegationTemplate() { 245 return delegationTemplate; 246 } 247 248 public void setDelegationTemplate(RuleTemplateBo delegationTemplate) { 249 this.delegationTemplate = delegationTemplate; 250 } 251 252 public String getReturnUrl() { 253 return returnUrl; 254 } 255 256 public void setReturnUrl(String returnUrl) { 257 this.returnUrl = returnUrl; 258 } 259 260 /** 261 * Used from the rule quicklinks when doing the focus channel. 262 */ 263 public String getEncodedName() { 264 return URLEncoder.encode(getName()); 265 } 266 267 public List<RuleTemplateOptionBo> getRuleTemplateOptions() { 268 return ruleTemplateOptions; 269 } 270 271 public void setRuleTemplateOptions(List<RuleTemplateOptionBo> ruleTemplateOptions) { 272 this.ruleTemplateOptions = ruleTemplateOptions; 273 } 274 275 public RuleTemplateOptionBo getRuleTemplateOption(String key) { 276 for (RuleTemplateOptionBo option: ruleTemplateOptions) { 277 if (option.getCode().equals(key)) { 278 return option; 279 } 280 } 281 return null; 282 } 283 284 public void setAcknowledge(RuleTemplateOptionBo acknowledge) { 285 RuleTemplateOptionBo option = getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ); 286 option.setValue(acknowledge.getValue()); 287 option.setId(acknowledge.getId()); 288 option.setVersionNumber(acknowledge.getVersionNumber()); 289 } 290 291 public void setComplete(RuleTemplateOptionBo complete) { 292 RuleTemplateOptionBo option = getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_COMPLETE_REQ); 293 option.setValue(complete.getValue()); 294 option.setId(complete.getId()); 295 option.setVersionNumber(complete.getVersionNumber()); 296 } 297 298 public void setApprove(RuleTemplateOptionBo approve) { 299 RuleTemplateOptionBo option = getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_APPROVE_REQ); 300 option.setValue(approve.getValue()); 301 option.setId(approve.getId()); 302 option.setVersionNumber(approve.getVersionNumber()); 303 } 304 305 public void setFyi(RuleTemplateOptionBo fyi) { 306 RuleTemplateOptionBo option = getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_FYI_REQ); 307 option.setValue(fyi.getValue()); 308 option.setId(fyi.getId()); 309 option.setVersionNumber(fyi.getVersionNumber()); 310 } 311 312 public void setDefaultActionRequestValue(RuleTemplateOptionBo defaultActionRequestValue) { 313 RuleTemplateOptionBo option = getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_DEFAULT_CD); 314 option.setValue(defaultActionRequestValue.getValue()); 315 option.setId(defaultActionRequestValue.getId()); 316 option.setVersionNumber(defaultActionRequestValue.getVersionNumber()); 317 } 318 319 public RuleTemplateOptionBo getAcknowledge() { 320 return getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ); 321 } 322 323 public RuleTemplateOptionBo getComplete() { 324 return getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_COMPLETE_REQ); 325 } 326 327 public RuleTemplateOptionBo getApprove() { 328 return getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_APPROVE_REQ); 329 } 330 331 public RuleTemplateOptionBo getFyi() { 332 return getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_FYI_REQ); 333 } 334 335 public RuleTemplateOptionBo getDefaultActionRequestValue() { 336 return getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_DEFAULT_CD); 337 } 338 339 /** 340 * Returns a List of Roles from all RoleAttributes attached to this template. 341 * 342 * @return list of roles 343 */ 344 public List<RoleName> getRoles() { 345 List<RoleName> roleNames = new ArrayList<RoleName>(); 346 List<RuleTemplateAttributeBo> templateAttributes = getRuleTemplateAttributes(); 347 for (RuleTemplateAttributeBo templateAttribute : templateAttributes) { 348 if (!templateAttribute.isWorkflowAttribute()) 349 { 350 continue; 351 } 352 roleNames.addAll(KEWServiceLocator.getWorkflowRuleAttributeMediator().getRoleNames(templateAttribute)); 353 } 354 return roleNames; 355 } 356 357 public static RuleTemplate to(RuleTemplateBo bo) { 358 if (bo == null) { 359 return null; 360 } 361 return RuleTemplate.Builder.create(bo).build(); 362 } 363}