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