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 }