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&currentRuleTemplateId=" + id + "\" >report</a>" /*+ "&nbsp;&nbsp;|&nbsp;&nbsp;<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    }