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.web;
017
018import org.apache.commons.beanutils.PropertyUtils;
019import org.apache.commons.lang.ClassUtils;
020import org.kuali.rice.core.api.delegation.DelegationType;
021import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
022import org.kuali.rice.kew.api.KewApiConstants;
023import org.kuali.rice.kew.api.action.ActionRequestPolicy;
024import org.kuali.rice.kew.rule.RuleBaseValues;
025import org.kuali.rice.kew.rule.RuleDelegationBo;
026import org.kuali.rice.kew.rule.RuleExtensionBo;
027import org.kuali.rice.kew.rule.RuleExtensionValue;
028import org.kuali.rice.kew.rule.RuleResponsibilityBo;
029import org.kuali.rice.kew.rule.service.RuleServiceInternal;
030import org.kuali.rice.kew.service.KEWServiceLocator;
031import org.kuali.rice.kim.api.group.Group;
032import org.kuali.rice.kim.api.identity.principal.Principal;
033import org.kuali.rice.kim.api.services.KimApiServiceLocator;
034import org.kuali.rice.krad.util.KRADConstants;
035
036import java.lang.reflect.InvocationHandler;
037import java.lang.reflect.Method;
038import java.lang.reflect.Proxy;
039import java.util.Iterator;
040import 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 */
050public 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.getExtension().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}