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.apache.commons.lang.ArrayUtils;
019import org.kuali.rice.kew.api.KewApiConstants;
020import org.kuali.rice.kew.api.rule.RoleName;
021import org.kuali.rice.kew.api.rule.RuleTemplate;
022import org.kuali.rice.kew.api.rule.RuleTemplateContract;
023import org.kuali.rice.kew.rule.RuleTemplateOptionBo;
024import org.kuali.rice.kew.service.KEWServiceLocator;
025import org.kuali.rice.krad.bo.PersistableBusinessObjectBase;
026import org.kuali.rice.krad.data.jpa.PortableSequenceGenerator;
027
028import javax.persistence.CascadeType;
029import javax.persistence.Column;
030import javax.persistence.Entity;
031import javax.persistence.FetchType;
032import javax.persistence.GeneratedValue;
033import javax.persistence.Id;
034import javax.persistence.JoinColumn;
035import javax.persistence.NamedQueries;
036import javax.persistence.NamedQuery;
037import javax.persistence.OneToMany;
038import javax.persistence.OneToOne;
039import javax.persistence.Table;
040import javax.persistence.Transient;
041import java.net.URLEncoder;
042import java.util.ArrayList;
043import java.util.Collections;
044import java.util.Iterator;
045import java.util.List;
046
047
048/**
049 * A model bean which represents a template upon which a rule is created.
050 * The RuleTemplate is essentially a collection of {@link RuleAttribute}s
051 * (associated vai the {@link RuleTemplateAttributeBo} bean).
052 *
053 * @author Kuali Rice Team (rice.collab@kuali.org)
054 */
055@Entity
056@Table(name="KREW_RULE_TMPL_T")
057//@Sequence(name="KREW_RTE_TMPL_S", property="id")
058@NamedQueries({@NamedQuery(name="findAllOrderedByName", query="SELECT rt FROM RuleTemplateBo rt ORDER BY rt.name ASC")})
059public class RuleTemplateBo extends PersistableBusinessObjectBase implements RuleTemplateContract {
060
061    private static final long serialVersionUID = -3387940485523951302L;
062
063    /**
064     * A list of default rule template option keys.
065     */
066    public static final String[] DEFAULT_OPTION_KEYS = {
067        //KewApiConstants.RULE_INSTRUCTIONS_CD,
068        KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ,
069        KewApiConstants.ACTION_REQUEST_APPROVE_REQ,
070        KewApiConstants.ACTION_REQUEST_COMPLETE_REQ,
071        KewApiConstants.ACTION_REQUEST_FYI_REQ,
072        KewApiConstants.ACTION_REQUEST_DEFAULT_CD
073    };
074    
075    @Id
076    @PortableSequenceGenerator(name="KREW_RTE_TMPL_S")
077    @GeneratedValue(generator="KREW_RTE_TMPL_S")
078        @Column(name="RULE_TMPL_ID")
079        private String id;
080    @Column(name="NM")
081        private String name;
082    @Column(name="RULE_TMPL_DESC")
083        private String description;
084
085    @Column(name="DLGN_RULE_TMPL_ID", insertable=false, updatable=false)
086        private String delegationTemplateId;
087    @OneToOne(fetch=FetchType.EAGER)
088        @JoinColumn(name="DLGN_RULE_TMPL_ID")
089        private RuleTemplateBo delegationTemplate;
090    @OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.ALL},
091           mappedBy="ruleTemplate")
092        private List<RuleTemplateAttributeBo> ruleTemplateAttributes;
093    @OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE},
094           mappedBy="ruleTemplate", orphanRemoval=true)
095        private List<RuleTemplateOptionBo> ruleTemplateOptions;
096
097    // required to be lookupable
098    @Transient
099    private String returnUrl;
100
101    public RuleTemplateBo() {
102        ruleTemplateAttributes = new ArrayList<RuleTemplateAttributeBo>();
103        ruleTemplateOptions = new ArrayList<RuleTemplateOptionBo>();
104    }
105    
106 
107    /**
108     * Removes any non-default rule template options on the template
109     */
110    public void removeNonDefaultOptions() {
111        Iterator<RuleTemplateOptionBo> it = ruleTemplateOptions.iterator();
112        while (it.hasNext()) {
113            RuleTemplateOptionBo option = it.next();
114            // if it's not one of the default options, remove it
115            if (!ArrayUtils.contains(DEFAULT_OPTION_KEYS, option.getCode())) {
116                it.remove();
117            }
118        }
119    }
120
121    public String getDelegateTemplateName() {
122        if (delegationTemplate != null) {
123            return delegationTemplate.getName();
124        }        
125        return "";
126    }
127
128    public String getRuleTemplateActionsUrl() {
129        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>"*/;
130    }
131
132    /**
133     * Returns the rule template attribute on this instance whose name matches the name of the rule template attribute
134     * passed as a parameter, qualified by it's active state, or null if a match was not found.
135     */
136    private RuleTemplateAttributeBo getRuleTemplateAttribute(RuleTemplateAttributeBo ruleTemplateAttribute, Boolean active) {
137        for (RuleTemplateAttributeBo currentRuleTemplateAttribute: getRuleTemplateAttributes()) {
138            if (currentRuleTemplateAttribute.getRuleAttribute().getName().equals(ruleTemplateAttribute.getRuleAttribute().getName())) {
139                if (active == null) {
140                    return currentRuleTemplateAttribute;
141                }
142                else if (active.compareTo(currentRuleTemplateAttribute.getActive()) == 0) {
143                    return currentRuleTemplateAttribute;
144                }
145            }
146        }
147        return null;
148    }
149    
150    public RuleTemplateAttributeBo getRuleTemplateAttribute(RuleTemplateAttributeBo ruleTemplateAttribute) {
151        return getRuleTemplateAttribute(ruleTemplateAttribute, null);
152    }
153    
154    public boolean containsActiveRuleTemplateAttribute(RuleTemplateAttributeBo templateAttribute) {
155        return (getRuleTemplateAttribute(templateAttribute, Boolean.TRUE) != null);
156    }
157
158    public boolean containsRuleTemplateAttribute(RuleTemplateAttributeBo templateAttribute) {
159        return (getRuleTemplateAttribute(templateAttribute, null) != null);
160    }
161
162    public RuleTemplateAttributeBo getRuleTemplateAttribute(int index) {
163        while (getRuleTemplateAttributes().size() <= index) {
164            getRuleTemplateAttributes().add(new RuleTemplateAttributeBo());
165        }
166        return (RuleTemplateAttributeBo) getRuleTemplateAttributes().get(index);
167    }
168
169    public List<RuleTemplateAttributeBo> getRuleTemplateAttributes() {
170        Collections.sort(ruleTemplateAttributes);
171        return ruleTemplateAttributes;
172    }
173
174    /**
175     * Returns a List of only the active RuleTemplateAttributes on the RuleTemplate
176     * sorted according to display order (ascending).
177     * @return
178     */
179    public List<RuleTemplateAttributeBo> getActiveRuleTemplateAttributes() {
180        List<RuleTemplateAttributeBo> activeAttributes = new ArrayList<RuleTemplateAttributeBo>();
181        for (RuleTemplateAttributeBo templateAttribute : getRuleTemplateAttributes())
182        {
183            if (templateAttribute.isActive())
184            {
185                activeAttributes.add(templateAttribute);
186            }
187        }
188        Collections.sort(activeAttributes);
189        return activeAttributes;
190    }
191    
192    /**
193     * This is implemented to allow us to use this collection on the inquiry for RuleTemplate.  In the
194     * KNS code it does an explicit check that the property is writable.
195     */
196    public void setActiveRuleTemplateAttributes(List<RuleTemplateAttributeBo> ruleTemplateAttributes) {
197        throw new UnsupportedOperationException("setActiveRuleTemplateAttributes is not implemented");
198    }
199
200    public void setRuleTemplateAttributes(List<RuleTemplateAttributeBo> ruleTemplateAttributes) {
201        this.ruleTemplateAttributes = ruleTemplateAttributes;
202    }
203
204    public String getDescription() {
205        return description;
206    }
207
208    public void setDescription(String description) {
209        this.description = description;
210    }
211
212    public String getName() {
213        return name;
214    }
215
216    public void setName(String name) {
217        this.name = name;
218    }
219
220    public String getId() {
221        return id;
222    }
223
224    public void setId(String id) {
225        this.id = id;
226    }
227
228    public String getDelegationTemplateId() {
229        return delegationTemplateId;
230    }
231
232    public void setDelegationTemplateId(String delegationTemplateId) {
233        this.delegationTemplateId = delegationTemplateId;
234    }
235
236    public RuleTemplateBo getDelegationTemplate() {
237        return delegationTemplate;
238    }
239
240    public void setDelegationTemplate(RuleTemplateBo delegationTemplate) {
241        this.delegationTemplate = delegationTemplate;
242    }
243
244    public String getReturnUrl() {
245        return returnUrl;
246    }
247
248    public void setReturnUrl(String returnUrl) {
249        this.returnUrl = returnUrl;
250    }
251
252    /**
253     * Used from the rule quicklinks when doing the focus channel.
254     */
255    public String getEncodedName() {
256        return URLEncoder.encode(getName());
257    }
258
259    public List<RuleTemplateOptionBo> getRuleTemplateOptions() {
260        return ruleTemplateOptions;
261    }
262
263    public void setRuleTemplateOptions(List<RuleTemplateOptionBo> ruleTemplateOptions) {
264        this.ruleTemplateOptions = ruleTemplateOptions;
265    }
266
267    public RuleTemplateOptionBo getRuleTemplateOption(String key) {
268        for (RuleTemplateOptionBo option: ruleTemplateOptions) {
269            if (option.getCode().equals(key)) {
270                return option;
271            }
272        }
273        return null;
274    }
275
276    public void setAcknowledge(RuleTemplateOptionBo acknowledge) {
277        RuleTemplateOptionBo option = getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ);
278        option.setValue(acknowledge.getValue());
279        option.setId(acknowledge.getId());
280        option.setVersionNumber(acknowledge.getVersionNumber());
281    }
282
283    public void setComplete(RuleTemplateOptionBo complete) {
284        RuleTemplateOptionBo option = getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_COMPLETE_REQ);
285        option.setValue(complete.getValue());
286        option.setId(complete.getId());
287        option.setVersionNumber(complete.getVersionNumber());
288    }
289
290    public void setApprove(RuleTemplateOptionBo approve) {
291        RuleTemplateOptionBo option = getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_APPROVE_REQ);
292        option.setValue(approve.getValue());
293        option.setId(approve.getId());
294        option.setVersionNumber(approve.getVersionNumber());
295    }
296
297    public void setFyi(RuleTemplateOptionBo fyi) {
298        RuleTemplateOptionBo option = getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_FYI_REQ);
299        option.setValue(fyi.getValue());
300        option.setId(fyi.getId());
301        option.setVersionNumber(fyi.getVersionNumber());
302    }
303
304    public void setDefaultActionRequestValue(RuleTemplateOptionBo defaultActionRequestValue) {
305        RuleTemplateOptionBo option = getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_DEFAULT_CD);
306        option.setValue(defaultActionRequestValue.getValue());
307        option.setId(defaultActionRequestValue.getId());
308        option.setVersionNumber(defaultActionRequestValue.getVersionNumber());
309    }
310
311    public RuleTemplateOptionBo getAcknowledge() {
312        return getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ);
313    }
314
315    public RuleTemplateOptionBo getComplete() {
316        return getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_COMPLETE_REQ);
317    }
318
319    public RuleTemplateOptionBo getApprove() {
320        return getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_APPROVE_REQ);
321    }
322
323    public RuleTemplateOptionBo getFyi() {
324        return getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_FYI_REQ);
325    }
326
327    public RuleTemplateOptionBo getDefaultActionRequestValue() {
328        return getRuleTemplateOption(KewApiConstants.ACTION_REQUEST_DEFAULT_CD);
329    }
330
331    /**
332     * Returns a List of Roles from all RoleAttributes attached to this template.
333     *
334     * @return list of roles
335     */
336    public List<RoleName> getRoles() {
337        List<RoleName> roleNames = new ArrayList<RoleName>();
338        List<RuleTemplateAttributeBo> templateAttributes = getRuleTemplateAttributes();
339        for (RuleTemplateAttributeBo templateAttribute : templateAttributes) {
340            if (!templateAttribute.isWorkflowAttribute())
341            {
342                                continue;
343                        }
344            roleNames.addAll(KEWServiceLocator.getWorkflowRuleAttributeMediator().getRoleNames(templateAttribute));
345        }
346        return roleNames;
347    }
348
349    public static RuleTemplate to(RuleTemplateBo bo) {
350        if (bo == null) {
351            return null;
352        }
353        return RuleTemplate.Builder.create(bo).build();
354    }
355}