001 /**
002 * Copyright 2005-2014 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.KewApiConstants;
024 import org.kuali.rice.kew.api.rule.RoleName;
025 import org.kuali.rice.kew.api.rule.RuleTemplate;
026 import org.kuali.rice.kew.api.rule.RuleTemplateContract;
027 import org.kuali.rice.kew.rule.RuleTemplateOptionBo;
028 import org.kuali.rice.kew.service.KEWServiceLocator;
029 import org.kuali.rice.krad.bo.PersistableBusinessObjectBase;
030
031 import javax.persistence.CascadeType;
032 import javax.persistence.Column;
033 import javax.persistence.Entity;
034 import javax.persistence.FetchType;
035 import javax.persistence.GeneratedValue;
036 import javax.persistence.Id;
037 import javax.persistence.JoinColumn;
038 import javax.persistence.NamedQueries;
039 import javax.persistence.NamedQuery;
040 import javax.persistence.OneToMany;
041 import javax.persistence.OneToOne;
042 import javax.persistence.Table;
043 import javax.persistence.Transient;
044 import java.net.URLEncoder;
045 import java.util.ArrayList;
046 import java.util.Collections;
047 import java.util.Iterator;
048 import 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")})
062 public 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 }