001    /**
002     * Copyright 2005-2013 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.web;
017    
018    import org.apache.commons.beanutils.PropertyUtils;
019    import org.apache.commons.lang.ClassUtils;
020    import org.kuali.rice.core.api.delegation.DelegationType;
021    import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
022    import org.kuali.rice.kew.api.KewApiConstants;
023    import org.kuali.rice.kew.api.action.ActionRequestPolicy;
024    import org.kuali.rice.kew.rule.RuleBaseValues;
025    import org.kuali.rice.kew.rule.RuleDelegationBo;
026    import org.kuali.rice.kew.rule.RuleExtensionBo;
027    import org.kuali.rice.kew.rule.RuleExtensionValue;
028    import org.kuali.rice.kew.rule.RuleResponsibilityBo;
029    import org.kuali.rice.kew.rule.service.RuleServiceInternal;
030    import org.kuali.rice.kew.service.KEWServiceLocator;
031    import org.kuali.rice.kim.api.group.Group;
032    import org.kuali.rice.kim.api.identity.principal.Principal;
033    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
034    import org.kuali.rice.krad.util.KRADConstants;
035    
036    import java.lang.reflect.InvocationHandler;
037    import java.lang.reflect.Method;
038    import java.lang.reflect.Proxy;
039    import java.util.Iterator;
040    import java.util.List;
041    
042    
043    /**
044     * A decorator around a {@link org.kuali.rice.kew.rule.RuleResponsibilityBo} object which provides some
045     * convienance functions for interacting with the bean from the web-tier.
046     * This helps to alleviate some of the weaknesses of JSTL.
047     *
048     * @author Kuali Rice Team (rice.collab@kuali.org)
049     */
050    public class WebRuleResponsibility extends RuleResponsibilityBo {
051    
052            private static final long serialVersionUID = -8422695726158274189L;
053    
054            private static final String DISPLAY_INLINE = "display:inline";
055    
056            private static final String DISPLAY_NONE = "display:none";
057    
058            private String reviewer;
059    
060            private String reviewerStyle = "";
061    
062            private String personLookupStyle = "";
063    
064            private String workgroupLookupStyle = "";
065    
066            private String roleReviewer;
067    
068            private String roleAreaStyle = "";
069    
070            private boolean delegationRulesMaterialized = false;
071    
072            private boolean showDelegations = false;
073    
074            private int numberOfDelegations;
075    
076            private int index = 0;
077    
078            private boolean hasDelegateRuleTemplate = false;
079    
080            /**
081             * "reviewerId added to support links to workgroup report or user report
082             */
083    
084            private String reviewerId;
085    
086            public String getReviewerId() {
087                    return reviewerId;
088            }
089    
090            public void setReviewerId(String reviewerId) {
091                    this.reviewerId = reviewerId;
092            }
093    
094            public WebRuleResponsibility() {
095                    setRuleResponsibilityType(KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID);
096                    setApprovePolicy(ActionRequestPolicy.FIRST.getCode());
097            }
098    
099            public void initialize() throws Exception {
100                    if (getDelegationRules().size() <= Integer.parseInt(CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.RULE_DETAIL_TYPE, KewApiConstants.RULE_DELEGATE_LIMIT))) {
101                            showDelegations = true;
102                    }
103                    setNumberOfDelegations(getDelegationRules().size());
104                    if (delegationRulesMaterialized) {
105                            for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) {
106                                    RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next();
107                                    WebRuleBaseValues webRule = (WebRuleBaseValues) ruleDelegation.getDelegationRule();
108                                    webRule.initialize();
109                            }
110                    }
111                    establishRequiredState();
112            }
113    
114            private void loadWebValues() throws Exception {
115                    if (!org.apache.commons.lang.StringUtils.isEmpty(getRuleResponsibilityName())) {
116                            if (KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID.equals(getRuleResponsibilityType())) {
117                                    // setReviewer(getUserService().getWorkflowUser(new
118                                    // WorkflowUserId(getRuleResponsibilityName())).getPrincipalName().getAuthenticationId());
119                                    Principal principal = KEWServiceLocator.getIdentityHelperService().getPrincipal(getRuleResponsibilityName());
120                                    setReviewer(principal.getPrincipalName());
121                                    setReviewerId(principal.getPrincipalId());
122                            } else if (KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID.equals(getRuleResponsibilityType())) {
123                                    // setReviewer(getWorkgroupService().getWorkgroup(new
124                                    // WorkflowGroupId(new
125                                    // Long(getRuleResponsibilityName()))).getGroupNameId().getNameId());
126                                    Group group = KimApiServiceLocator.getGroupService().
127                              getGroup(getRuleResponsibilityName());
128                                    setReviewer(group.getName());
129                                    setReviewerId(group.getId());
130                            } else if (KewApiConstants.RULE_RESPONSIBILITY_ROLE_ID.equals(getRuleResponsibilityType())) {
131                                    setRoleReviewer(getRuleResponsibilityName());
132                                    setReviewer(getResolvedRoleName());
133                            }
134                    }
135            }
136    
137            private void injectWebMembers() throws Exception {
138            DelegationRulesProxy delegationRulesProxy = new DelegationRulesProxy(getDelegationRules());
139            Class delegationRulesClass = getDelegationRules().getClass();
140            //System.err.println("delegation rules class: "+ delegationRulesClass);
141            Class[] delegationRulesInterfaces = new Class[0]; // = delegationRulesClass.getInterfaces();
142            List<Class> delegationRulesInterfaceList = (List<Class>) ClassUtils.getAllInterfaces(delegationRulesClass);
143            delegationRulesInterfaces = delegationRulesInterfaceList.toArray(delegationRulesInterfaces);
144            ClassLoader delegationRulesClassLoader = getDelegationRules().getClass().getClassLoader();
145            Object o = Proxy.newProxyInstance(delegationRulesClassLoader, delegationRulesInterfaces, delegationRulesProxy);
146            //setDelegationRules((List) o);
147    
148                    if (Integer.parseInt(CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.RULE_DETAIL_TYPE, KewApiConstants.RULE_DELEGATE_LIMIT)) > getDelegationRules().size() || showDelegations) {
149                            for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) {
150                                    RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next();
151                                    WebRuleBaseValues webRule = new WebRuleBaseValues();
152                                    webRule.load(ruleDelegation.getDelegationRule());
153                                    webRule.edit(ruleDelegation.getDelegationRule());
154                                    ruleDelegation.setDelegationRule(webRule);
155                            }
156                    }
157            }
158    
159            public RuleDelegationBo addNewDelegation() {
160                    RuleDelegationBo ruleDelegation = new RuleDelegationBo();
161                    ruleDelegation.setDelegationRule(new WebRuleBaseValues());
162                    ruleDelegation.setDelegationType(DelegationType.PRIMARY);
163                    ruleDelegation.getDelegationRule().setDelegateRule(Boolean.TRUE);
164                    ruleDelegation.getDelegationRule().setDocTypeName(getRuleBaseValues().getDocTypeName());
165                    getDelegationRules().add(ruleDelegation);
166                    showDelegations = true;
167                    return ruleDelegation;
168            }
169    
170            public String getReviewer() {
171                    return reviewer;
172            }
173    
174            public void setReviewer(String reviewer) {
175                    this.reviewer = reviewer;
176            }
177    
178            public void setWorkgroupId(String workgroupId) {
179                Group workgroup = KimApiServiceLocator.getGroupService().getGroup(workgroupId);
180                    //Workgroup workgroup = getWorkgroupService().getWorkgroup(new WorkflowGroupId(workgroupId));
181                    if (workgroup != null) {
182                            setReviewer(workgroup.getName());
183                    } else {
184                            setReviewer("");
185                    }
186            }
187    
188            public String getPersonLookupStyle() {
189                    return personLookupStyle;
190            }
191    
192            public void setPersonLookupStyle(String personLookupStyle) {
193                    this.personLookupStyle = personLookupStyle;
194            }
195    
196            public String getReviewerStyle() {
197                    return reviewerStyle;
198            }
199    
200            public void setReviewerStyle(String reviewerStyle) {
201                    this.reviewerStyle = reviewerStyle;
202            }
203    
204            public String getRoleAreaStyle() {
205                    return roleAreaStyle;
206            }
207    
208            public void setRoleAreaStyle(String roleAreaLookupStyle) {
209                    this.roleAreaStyle = roleAreaLookupStyle;
210            }
211    
212            public String getWorkgroupLookupStyle() {
213                    return workgroupLookupStyle;
214            }
215    
216            public void setWorkgroupLookupStyle(String workgroupLookupStyle) {
217                    this.workgroupLookupStyle = workgroupLookupStyle;
218            }
219    
220            public RuleDelegationBo getDelegationRule(int index) {
221                    while (getDelegationRules().size() <= index) {
222                            addNewDelegation();
223                    }
224                    return (RuleDelegationBo) getDelegationRules().get(index);
225            }
226    
227            public int getNumberOfDelegations() {
228                    return numberOfDelegations;
229            }
230    
231            public void setNumberOfDelegations(int numberOfDelegations) {
232                    this.numberOfDelegations = numberOfDelegations;
233            }
234    
235            public boolean isDelegationRulesMaterialized() {
236                    return delegationRulesMaterialized;
237            }
238    
239            public void setDelegationRulesMaterialized(boolean isDelegationRulesMaterialized) {
240                    this.delegationRulesMaterialized = isDelegationRulesMaterialized;
241            }
242    
243            public String getRoleReviewer() {
244                    return roleReviewer;
245            }
246    
247            public void setRoleReviewer(String roleReviewer) {
248                    this.roleReviewer = roleReviewer;
249            }
250    
251            public int getIndex() {
252                    return index;
253            }
254    
255            public void setIndex(int index) {
256                    this.index = index;
257            }
258    
259            public boolean isShowDelegations() {
260                    return showDelegations;
261            }
262    
263            public void setShowDelegations(boolean showDelegations) {
264                    this.showDelegations = showDelegations;
265            }
266    
267            public void establishRequiredState() throws Exception {
268                    if (KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID.equals(getRuleResponsibilityType())) {
269                            reviewerStyle = DISPLAY_INLINE;
270                            personLookupStyle = DISPLAY_INLINE;
271                            workgroupLookupStyle = DISPLAY_NONE;
272                            roleAreaStyle = DISPLAY_NONE;
273                    }
274                    if (KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID.equals(getRuleResponsibilityType())) {
275                            reviewerStyle = DISPLAY_INLINE;
276                            personLookupStyle = DISPLAY_NONE;
277                            workgroupLookupStyle = DISPLAY_INLINE;
278                            roleAreaStyle = DISPLAY_NONE;
279                    }
280                    if (KewApiConstants.RULE_RESPONSIBILITY_ROLE_ID.equals(getRuleResponsibilityType())) {
281                            reviewerStyle = DISPLAY_NONE;
282                            personLookupStyle = DISPLAY_NONE;
283                            workgroupLookupStyle = DISPLAY_NONE;
284                            roleAreaStyle = DISPLAY_INLINE;
285                    }
286                    loadWebValues();
287                    if (delegationRulesMaterialized) {
288                            for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) {
289                                    RuleDelegationBo delegation = (RuleDelegationBo) iterator.next();
290                                    ((WebRuleBaseValues) delegation.getDelegationRule()).establishRequiredState();
291                            }
292                    }
293            }
294    
295            public void edit(RuleResponsibilityBo ruleResponsibility) throws Exception {
296                    load(ruleResponsibility);
297                    initialize();
298            }
299    
300            public void load(RuleResponsibilityBo ruleResponsibility) throws Exception {
301                    PropertyUtils.copyProperties(this, ruleResponsibility);
302                    injectWebMembers();
303            }
304    
305            public void loadDelegations() throws Exception {
306                    fetchDelegations();
307    
308                    for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) {
309                            RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next();
310                            WebRuleBaseValues webRule = new WebRuleBaseValues();
311                            webRule.edit(ruleDelegation.getDelegationRule());
312                            ruleDelegation.setDelegationRule(webRule);
313                    }
314                    delegationRulesMaterialized = true;
315                    populatePreviousRuleIds();
316            }
317    
318            public void populatePreviousRuleIds() {
319                    if (delegationRulesMaterialized) {
320                            for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) {
321                                    RuleDelegationBo delegation = (RuleDelegationBo) iterator.next();
322                                    ((WebRuleBaseValues) delegation.getDelegationRule()).populatePreviousRuleIds();
323                            }
324                    }
325            }
326    
327            private void fetchDelegations() {
328                    if (getId() != null) {
329                            RuleResponsibilityBo responsibility = getRuleService().findByRuleResponsibilityId(getId());
330                            if (responsibility == null) {
331                                    return;
332                            }
333                            getDelegationRules().addAll(responsibility.getDelegationRules());
334                    }
335            }
336    
337            public void prepareHiddenDelegationsForRoute() {
338                    if (showDelegations) {
339                            return;
340                    }
341    
342                    fetchDelegations();
343    
344                    for (Iterator iter = getDelegationRules().iterator(); iter.hasNext();) {
345                            RuleDelegationBo delegation = (RuleDelegationBo) iter.next();
346                            delegation.setDelegateRuleId(null);
347                            delegation.setVersionNumber(null);
348                            delegation.setRuleDelegationId(null);
349                            //delegation.setRuleResponsibility(this);
350                            delegation.setResponsibilityId(null);
351    
352                            RuleBaseValues rule = delegation.getDelegationRule();
353                            rule.setVersionNumber(null);
354                            rule.setPreviousRuleId(rule.getId());
355                            rule.setDocumentId(null);
356                            rule.setId(null);
357    
358                            for (Iterator iterator = rule.getRuleResponsibilities().iterator(); iterator.hasNext();) {
359                                    RuleResponsibilityBo responsibility = (RuleResponsibilityBo) iterator.next();
360                                    responsibility.setVersionNumber(null);
361                                    responsibility.setRuleBaseValuesId(null);
362                                    responsibility.setRuleBaseValues(rule);
363                                    responsibility.setId(null);
364                            }
365    
366                            for (Iterator iterator = rule.getRuleExtensions().iterator(); iterator.hasNext();) {
367                                    RuleExtensionBo extension = (RuleExtensionBo) iterator.next();
368                                    extension.setVersionNumber(null);
369                                    extension.setRuleBaseValues(rule);
370                                    extension.setRuleBaseValuesId(null);
371                                    extension.setRuleExtensionId(null);
372    
373                                    for (Iterator iter2 = extension.getExtensionValues().iterator(); iter2.hasNext();) {
374                                            RuleExtensionValue value = (RuleExtensionValue) iter2.next();
375                                            value.setExtension(extension);
376                                            value.setLockVerNbr(null);
377                                            value.setRuleExtensionId(null);
378                                            value.setRuleExtensionValueId(null);
379                                    }
380                            }
381                    }
382            }
383    
384            public boolean isHasDelegateRuleTemplate() {
385                    return hasDelegateRuleTemplate;
386            }
387    
388            public void setHasDelegateRuleTemplate(boolean hasDelegateRuleTemplate) {
389                    this.hasDelegateRuleTemplate = hasDelegateRuleTemplate;
390            }
391    
392            private RuleServiceInternal getRuleService() {
393                    return (RuleServiceInternal) KEWServiceLocator.getService(KEWServiceLocator.RULE_SERVICE);
394            }
395    
396            /**
397             * Just a little dynamic proxy to keep us from establishing required state
398             * on the delegation rules if they haven't been materialized from the
399             * database yet (they are currenty proxied by OJB)
400             *
401     * @author Kuali Rice Team (rice.collab@kuali.org)
402             */
403            private class DelegationRulesProxy implements InvocationHandler, java.io.Serializable {
404    
405                    private static final long serialVersionUID = 7046323200221509473L;
406    
407                    private List delegationRules;
408    
409                    public DelegationRulesProxy(List delegationRules) {
410                            this.delegationRules = delegationRules;
411                    }
412    
413                    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
414                            if (!delegationRulesMaterialized && !m.getName().equals("isEmpty") && !m.getName().equals("size")) {
415                                    for (Iterator iterator = delegationRules.iterator(); iterator.hasNext();) {
416                                            RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next();
417                                            WebRuleBaseValues webRule = new WebRuleBaseValues();
418                                            webRule.load(ruleDelegation.getDelegationRule());
419                                            webRule.establishRequiredState();
420                                            ruleDelegation.setDelegationRule(webRule);
421                                    }
422                                    delegationRulesMaterialized = true;
423    
424                            }
425                            return m.invoke(delegationRules, args);
426                    }
427    
428            }
429    
430    }