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.kuali.rice.core.api.mo.common.active.MutableInactivatable; 019import org.kuali.rice.kew.api.KewApiConstants; 020import org.kuali.rice.kew.api.KewApiServiceLocator; 021import org.kuali.rice.kew.api.WorkflowRuntimeException; 022import org.kuali.rice.kew.api.extension.ExtensionUtils; 023import org.kuali.rice.kew.api.rule.RuleTemplateAttributeContract; 024import org.kuali.rice.kew.rule.RuleExtensionBo; 025import org.kuali.rice.kew.rule.RuleExtensionValue; 026import org.kuali.rice.kew.rule.RuleValidationAttribute; 027import org.kuali.rice.kew.rule.WorkflowRuleAttribute; 028import org.kuali.rice.kew.service.KEWServiceLocator; 029import org.kuali.rice.krad.bo.PersistableBusinessObjectBase; 030import org.kuali.rice.krad.data.jpa.converters.Boolean01BigDecimalConverter; 031import org.kuali.rice.krad.data.jpa.PortableSequenceGenerator; 032 033import javax.persistence.CascadeType; 034import javax.persistence.Column; 035import javax.persistence.Convert; 036import javax.persistence.Entity; 037import javax.persistence.FetchType; 038import javax.persistence.GeneratedValue; 039import javax.persistence.Id; 040import javax.persistence.JoinColumn; 041import javax.persistence.ManyToOne; 042import javax.persistence.OneToMany; 043import javax.persistence.Table; 044import javax.persistence.Transient; 045import java.util.HashMap; 046import java.util.List; 047import java.util.Map; 048 049/** 050 * A model bean which services as the link between a {@link RuleTemplateBo} and 051 * a {@link RuleAttribute}. 052 * 053 * @author Kuali Rice Team (rice.collab@kuali.org) 054 */ 055@Entity 056@Table(name="KREW_RULE_TMPL_ATTR_T") 057//@Sequence(name="KREW_RTE_TMPL_S", property="id") 058public class RuleTemplateAttributeBo extends PersistableBusinessObjectBase 059 implements Comparable<RuleTemplateAttributeBo>, MutableInactivatable, RuleTemplateAttributeContract { 060 061 private static final long serialVersionUID = -3580049225424553828L; 062 @Id 063 @PortableSequenceGenerator(name="KREW_RTE_TMPL_S") 064 @GeneratedValue(generator="KREW_RTE_TMPL_S") 065 @Column(name="RULE_TMPL_ATTR_ID") 066 private String id; 067 @Column(name="RULE_ATTR_ID", insertable=false, updatable=false) 068 private String ruleAttributeId; 069 @Column(name="REQ_IND") 070 @Convert(converter=Boolean01BigDecimalConverter.class) 071 private Boolean required; 072 @Column(name="ACTV_IND") 073 @Convert(converter=Boolean01BigDecimalConverter.class) 074 private Boolean active; 075 @Column(name="DSPL_ORD") 076 private Integer displayOrder; 077 @Column(name="DFLT_VAL") 078 private String defaultValue; 079 080 @Transient 081 private String ruleTemplateId; 082 083 @ManyToOne(fetch=FetchType.EAGER, cascade = CascadeType.ALL) 084 @JoinColumn(name="RULE_TMPL_ID", nullable = false) 085 private RuleTemplateBo ruleTemplate; 086 @ManyToOne(fetch=FetchType.EAGER) 087 @JoinColumn(name="RULE_ATTR_ID") 088 private RuleAttribute ruleAttribute; 089 @OneToMany(fetch=FetchType.LAZY,mappedBy="ruleTemplateAttribute") 090 private List<RuleExtensionBo> ruleExtensions; 091 092 093 public RuleTemplateAttributeBo() { 094 this.required = Boolean.FALSE; 095 this.active = Boolean.TRUE; 096 } 097 098 public int compareTo(RuleTemplateAttributeBo ruleTemplateAttribute) { 099 if ((this.getDisplayOrder() != null) && (ruleTemplateAttribute.getDisplayOrder() != null)) { 100 return this.getDisplayOrder().compareTo(ruleTemplateAttribute.getDisplayOrder()); 101 } 102 return 0; 103 } 104 105 public Object getAttribute() { 106 try { 107 //ObjectDefinition objectDefinition = new ObjectDefinition(getRuleAttribute().getResourceDescriptor(), getRuleAttribute().getApplicationId()); 108 Object attribute = ExtensionUtils.loadExtension(RuleAttribute.to(getRuleAttribute()), getRuleAttribute().getApplicationId()); 109 if (attribute == null) { 110 throw new WorkflowRuntimeException("Could not find attribute " + getRuleAttribute().getName()); 111 } 112 if (attribute instanceof WorkflowRuleAttribute) { 113 ((WorkflowRuleAttribute) attribute).setRequired(required.booleanValue()); 114 } 115 return attribute; 116 } catch (Exception e) { 117 throw new RuntimeException("Caught error attempting to load attribute class: " + getRuleAttribute().getResourceDescriptor(), e); 118 } 119 } 120 121 public boolean isWorkflowAttribute() { 122 return getRuleAttribute().isWorkflowAttribute(); 123 } 124 125 public boolean isRuleValidationAttribute() { 126 // just check the type here to avoid having to load the class from the class loader if it's not actually there 127 return KewApiConstants.RULE_VALIDATION_ATTRIBUTE_TYPE.equals(getRuleAttribute().getType()); 128 } 129 130 /** 131 * Instantiates and returns a new instance of the WorkflowAttribute class configured on this template. 132 * The calling code should be sure to call isWorkflowAttribute first to verify the type of this attribute 133 * is that of a WorkflowAttribute. Otherwise a RuntimeException will be thrown. 134 */ 135 public WorkflowRuleAttribute getWorkflowAttribute() { 136 try { 137 Object tempAttr = ExtensionUtils.loadExtension(RuleAttribute.to(getRuleAttribute()), getRuleAttribute().getApplicationId()); 138 139 if (tempAttr == null 140 || !WorkflowRuleAttribute.class.isAssignableFrom(tempAttr.getClass())) { 141 throw new WorkflowRuntimeException("Could not find workflow attribute " + getRuleAttribute().getName()); 142 } 143 WorkflowRuleAttribute workflowAttribute = (WorkflowRuleAttribute)tempAttr; 144 workflowAttribute.setRequired(required.booleanValue()); 145 return workflowAttribute; 146 } catch (Exception e) { 147 throw new RuntimeException("Caught exception instantiating new " + getRuleAttribute().getResourceDescriptor(), e); 148 } 149 } 150 151 /** 152 * Instantiates and returns a new instance of the RuleValidationAttribute class configured on this template. 153 * The calling code should be sure to call isRuleValidationAttribute first to verify the type of this attribute 154 * is that of a RuleValidationAttribute. Otherwise a RuntimeException will be thrown. 155 */ 156 public RuleValidationAttribute getRuleValidationAttribute() { 157 try { 158 RuleAttribute attrib = getRuleAttribute(); 159 return KEWServiceLocator.getRuleValidationAttributeResolver().resolveRuleValidationAttribute(attrib.getName(), attrib.getApplicationId()); 160 } catch (Exception e) { 161 throw new RuntimeException("Caught exception instantiating new " + getRuleAttribute().getResourceDescriptor(), e); 162 } 163 } 164 165 public List<RuleExtensionBo> getRuleExtensions() { 166 return ruleExtensions; 167 } 168 169 public Map<String, String> getRuleExtensionMap() { 170 Map<String, String> extensions = new HashMap<String, String>(); 171 if (this.getRuleExtensions() != null) { 172 for (RuleExtensionBo ext : this.getRuleExtensions()) { 173 for (RuleExtensionValue value : ext.getExtensionValues()) { 174 extensions.put(value.getKey(), value.getValue()); 175 } 176 } 177 } 178 return extensions; 179 } 180 181 public void setRuleExtensions(List<RuleExtensionBo> ruleExtensions) { 182 this.ruleExtensions = ruleExtensions; 183 } 184 185 public RuleAttribute getRuleAttribute() { 186 if (ruleAttribute == null && ruleAttributeId != null) { 187 ruleAttribute = RuleAttribute.from(KewApiServiceLocator.getExtensionRepositoryService().getExtensionById(ruleAttributeId)); 188 } 189 return ruleAttribute; 190 } 191 192 public void setRuleAttribute(org.kuali.rice.kew.rule.bo.RuleAttribute ruleAttribute) { 193 this.ruleAttribute = ruleAttribute; 194 } 195 196 public RuleTemplateBo getRuleTemplate() { 197 return ruleTemplate; 198 } 199 200 public void setRuleTemplate(RuleTemplateBo ruleTemplate) { 201 this.ruleTemplate = ruleTemplate; 202 } 203 204 public String getDefaultValue() { 205 return defaultValue; 206 } 207 208 public void setDefaultValue(String defaultValue) { 209 this.defaultValue = defaultValue; 210 } 211 212 public Integer getDisplayOrder() { 213 return displayOrder; 214 } 215 216 public void setDisplayOrder(Integer displayOrder) { 217 this.displayOrder = displayOrder; 218 } 219 220 public boolean isRequired() { 221 return (getRequired() == null) || (getRequired().booleanValue()); 222 } 223 224 public Boolean getRequired() { 225 return required; 226 } 227 228 public void setRequired(Boolean required) { 229 this.required = required; 230 } 231 232 public boolean isActive() { 233 return (getActive() == null) || (getActive().booleanValue()); 234 } 235 236 public Boolean getActive() { 237 return active; 238 } 239 240 public void setActive(Boolean active) { 241 this.active = active; 242 } 243 244 public void setActive(boolean active) { 245 this.active = active; 246 } 247 248 public String getRuleAttributeId() { 249 return ruleAttributeId; 250 } 251 252 public void setRuleAttributeId(String ruleAttributeId) { 253 this.ruleAttributeId = ruleAttributeId; 254 } 255 256 public String getId() { 257 return id; 258 } 259 260 public void setId(String id) { 261 this.id = id; 262 } 263 264 public String getRuleTemplateId() { 265 return getRuleTemplate() != null ? getRuleTemplate().getId() : null; 266 } 267 268 /** 269 * @deprecated use {@link #setRuleTemplate(RuleTemplateBo)} instead 270 */ 271 @Deprecated 272 public void setRuleTemplateId(String ruleTemplateId) { 273 // there's no way to do this now after the JPA conversion! 274 } 275 276}