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&currentRuleTemplateId=" + id + "\" >report</a>" /*+ "&nbsp;&nbsp;|&nbsp;&nbsp;<a href=\"RuleTemplate.do?methodToCall=edit&ruleTemplate.id=" + id + "\" >edit</a>"*/;
139    //                      "&nbsp;&nbsp;|&nbsp;&nbsp;<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    }