View Javadoc

1   /**
2    * Copyright 2005-2012 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kew.rule.web;
17  
18  import org.apache.commons.beanutils.PropertyUtils;
19  import org.apache.commons.lang.ClassUtils;
20  import org.apache.struts.action.ActionErrors;
21  import org.apache.struts.action.ActionMessage;
22  import org.kuali.rice.core.api.delegation.DelegationType;
23  import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
24  import org.kuali.rice.kew.api.action.ActionRequestPolicy;
25  import org.kuali.rice.kew.rule.RuleBaseValues;
26  import org.kuali.rice.kew.rule.RuleDelegationBo;
27  import org.kuali.rice.kew.rule.RuleExtensionBo;
28  import org.kuali.rice.kew.rule.RuleExtensionValue;
29  import org.kuali.rice.kew.rule.RuleResponsibilityBo;
30  import org.kuali.rice.kew.rule.service.RuleServiceInternal;
31  import org.kuali.rice.kew.service.KEWServiceLocator;
32  import org.kuali.rice.kew.api.KewApiConstants;
33  import org.kuali.rice.kim.api.group.Group;
34  import org.kuali.rice.kim.api.identity.principal.Principal;
35  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
36  import org.kuali.rice.krad.util.KRADConstants;
37  
38  import java.lang.reflect.InvocationHandler;
39  import java.lang.reflect.Method;
40  import java.lang.reflect.Proxy;
41  import java.util.Iterator;
42  import java.util.List;
43  
44  
45  /**
46   * A decorator around a {@link org.kuali.rice.kew.rule.RuleResponsibilityBo} object which provides some
47   * convienance functions for interacting with the bean from the web-tier.
48   * This helps to alleviate some of the weaknesses of JSTL.
49   *
50   * @author Kuali Rice Team (rice.collab@kuali.org)
51   */
52  public class WebRuleResponsibility extends RuleResponsibilityBo {
53  
54  	private static final long serialVersionUID = -8422695726158274189L;
55  
56  	private static final String DISPLAY_INLINE = "display:inline";
57  
58  	private static final String DISPLAY_NONE = "display:none";
59  
60  	private String reviewer;
61  
62  	private String reviewerStyle = "";
63  
64  	private String personLookupStyle = "";
65  
66  	private String workgroupLookupStyle = "";
67  
68  	private String roleReviewer;
69  
70  	private String roleAreaStyle = "";
71  
72  	private boolean delegationRulesMaterialized = false;
73  
74  	private boolean showDelegations = false;
75  
76  	private int numberOfDelegations;
77  
78  	private int index = 0;
79  
80  	private boolean hasDelegateRuleTemplate = false;
81  
82  	/**
83  	 * "reviewerId added to support links to workgroup report or user report
84  	 */
85  
86  	private String reviewerId;
87  
88  	public String getReviewerId() {
89  		return reviewerId;
90  	}
91  
92  	public void setReviewerId(String reviewerId) {
93  		this.reviewerId = reviewerId;
94  	}
95  
96  	public WebRuleResponsibility() {
97  		setRuleResponsibilityType(KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID);
98  		setApprovePolicy(ActionRequestPolicy.FIRST.getCode());
99  	}
100 
101 	public void initialize() throws Exception {
102 		if (getDelegationRules().size() <= Integer.parseInt(CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.RULE_DETAIL_TYPE, KewApiConstants.RULE_DELEGATE_LIMIT))) {
103 			showDelegations = true;
104 		}
105 		setNumberOfDelegations(getDelegationRules().size());
106 		if (delegationRulesMaterialized) {
107 			for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) {
108 				RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next();
109 				WebRuleBaseValues webRule = (WebRuleBaseValues) ruleDelegation.getDelegationRule();
110 				webRule.initialize();
111 			}
112 		}
113 		establishRequiredState();
114 	}
115 
116 	private void loadWebValues() throws Exception {
117 		if (!org.apache.commons.lang.StringUtils.isEmpty(getRuleResponsibilityName())) {
118 			if (KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID.equals(getRuleResponsibilityType())) {
119 				// setReviewer(getUserService().getWorkflowUser(new
120 				// WorkflowUserId(getRuleResponsibilityName())).getPrincipalName().getAuthenticationId());
121 				Principal principal = KEWServiceLocator.getIdentityHelperService().getPrincipal(getRuleResponsibilityName());
122 				setReviewer(principal.getPrincipalName());
123 				setReviewerId(principal.getPrincipalId());
124 			} else if (KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID.equals(getRuleResponsibilityType())) {
125 				// setReviewer(getWorkgroupService().getWorkgroup(new
126 				// WorkflowGroupId(new
127 				// Long(getRuleResponsibilityName()))).getGroupNameId().getNameId());
128 				Group group = KimApiServiceLocator.getGroupService().
129 	                  getGroup(getRuleResponsibilityName());
130 				setReviewer(group.getName());
131 				setReviewerId(group.getId());
132 			} else if (KewApiConstants.RULE_RESPONSIBILITY_ROLE_ID.equals(getRuleResponsibilityType())) {
133 				setRoleReviewer(getRuleResponsibilityName());
134 				setReviewer(getResolvedRoleName());
135 			}
136 		}
137 	}
138 
139 	private void injectWebMembers() throws Exception {
140         DelegationRulesProxy delegationRulesProxy = new DelegationRulesProxy(getDelegationRules());
141         Class delegationRulesClass = getDelegationRules().getClass();
142         //System.err.println("delegation rules class: "+ delegationRulesClass);
143         Class[] delegationRulesInterfaces = new Class[0]; // = delegationRulesClass.getInterfaces();
144         List<Class> delegationRulesInterfaceList = (List<Class>) ClassUtils.getAllInterfaces(delegationRulesClass);
145         delegationRulesInterfaces = delegationRulesInterfaceList.toArray(delegationRulesInterfaces);
146         ClassLoader delegationRulesClassLoader = getDelegationRules().getClass().getClassLoader();
147         Object o = Proxy.newProxyInstance(delegationRulesClassLoader, delegationRulesInterfaces, delegationRulesProxy);
148         //setDelegationRules((List) o);
149 
150 		if (Integer.parseInt(CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.RULE_DETAIL_TYPE, KewApiConstants.RULE_DELEGATE_LIMIT)) > getDelegationRules().size() || showDelegations) {
151 			for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) {
152 				RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next();
153 				WebRuleBaseValues webRule = new WebRuleBaseValues();
154 				webRule.load(ruleDelegation.getDelegationRule());
155 				webRule.edit(ruleDelegation.getDelegationRule());
156 				ruleDelegation.setDelegationRule(webRule);
157 			}
158 		}
159 	}
160 
161 	public RuleDelegationBo addNewDelegation() {
162 		RuleDelegationBo ruleDelegation = new RuleDelegationBo();
163 		ruleDelegation.setDelegationRule(new WebRuleBaseValues());
164 		ruleDelegation.setDelegationType(DelegationType.PRIMARY);
165 		ruleDelegation.getDelegationRule().setDelegateRule(Boolean.TRUE);
166 		ruleDelegation.getDelegationRule().setDocTypeName(getRuleBaseValues().getDocTypeName());
167 		getDelegationRules().add(ruleDelegation);
168 		showDelegations = true;
169 		return ruleDelegation;
170 	}
171 
172 	public String getReviewer() {
173 		return reviewer;
174 	}
175 
176 	public void setReviewer(String reviewer) {
177 		this.reviewer = reviewer;
178 	}
179 
180 	public void setWorkgroupId(String workgroupId) {
181 	    Group workgroup = KimApiServiceLocator.getGroupService().getGroup(workgroupId);
182 		//Workgroup workgroup = getWorkgroupService().getWorkgroup(new WorkflowGroupId(workgroupId));
183 		if (workgroup != null) {
184 			setReviewer(workgroup.getName());
185 		} else {
186 			setReviewer("");
187 		}
188 	}
189 
190 	public String getPersonLookupStyle() {
191 		return personLookupStyle;
192 	}
193 
194 	public void setPersonLookupStyle(String personLookupStyle) {
195 		this.personLookupStyle = personLookupStyle;
196 	}
197 
198 	public String getReviewerStyle() {
199 		return reviewerStyle;
200 	}
201 
202 	public void setReviewerStyle(String reviewerStyle) {
203 		this.reviewerStyle = reviewerStyle;
204 	}
205 
206 	public String getRoleAreaStyle() {
207 		return roleAreaStyle;
208 	}
209 
210 	public void setRoleAreaStyle(String roleAreaLookupStyle) {
211 		this.roleAreaStyle = roleAreaLookupStyle;
212 	}
213 
214 	public String getWorkgroupLookupStyle() {
215 		return workgroupLookupStyle;
216 	}
217 
218 	public void setWorkgroupLookupStyle(String workgroupLookupStyle) {
219 		this.workgroupLookupStyle = workgroupLookupStyle;
220 	}
221 
222 	public RuleDelegationBo getDelegationRule(int index) {
223 		while (getDelegationRules().size() <= index) {
224 			addNewDelegation();
225 		}
226 		return (RuleDelegationBo) getDelegationRules().get(index);
227 	}
228 
229 	public int getNumberOfDelegations() {
230 		return numberOfDelegations;
231 	}
232 
233 	public void setNumberOfDelegations(int numberOfDelegations) {
234 		this.numberOfDelegations = numberOfDelegations;
235 	}
236 
237 	public boolean isDelegationRulesMaterialized() {
238 		return delegationRulesMaterialized;
239 	}
240 
241 	public void setDelegationRulesMaterialized(boolean isDelegationRulesMaterialized) {
242 		this.delegationRulesMaterialized = isDelegationRulesMaterialized;
243 	}
244 
245 	public String getRoleReviewer() {
246 		return roleReviewer;
247 	}
248 
249 	public void setRoleReviewer(String roleReviewer) {
250 		this.roleReviewer = roleReviewer;
251 	}
252 
253 	public int getIndex() {
254 		return index;
255 	}
256 
257 	public void setIndex(int index) {
258 		this.index = index;
259 	}
260 
261 	public boolean isShowDelegations() {
262 		return showDelegations;
263 	}
264 
265 	public void setShowDelegations(boolean showDelegations) {
266 		this.showDelegations = showDelegations;
267 	}
268 
269 	public void establishRequiredState() throws Exception {
270 		if (KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID.equals(getRuleResponsibilityType())) {
271 			reviewerStyle = DISPLAY_INLINE;
272 			personLookupStyle = DISPLAY_INLINE;
273 			workgroupLookupStyle = DISPLAY_NONE;
274 			roleAreaStyle = DISPLAY_NONE;
275 		}
276 		if (KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID.equals(getRuleResponsibilityType())) {
277 			reviewerStyle = DISPLAY_INLINE;
278 			personLookupStyle = DISPLAY_NONE;
279 			workgroupLookupStyle = DISPLAY_INLINE;
280 			roleAreaStyle = DISPLAY_NONE;
281 		}
282 		if (KewApiConstants.RULE_RESPONSIBILITY_ROLE_ID.equals(getRuleResponsibilityType())) {
283 			reviewerStyle = DISPLAY_NONE;
284 			personLookupStyle = DISPLAY_NONE;
285 			workgroupLookupStyle = DISPLAY_NONE;
286 			roleAreaStyle = DISPLAY_INLINE;
287 		}
288 		loadWebValues();
289 		if (delegationRulesMaterialized) {
290 			for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) {
291 				RuleDelegationBo delegation = (RuleDelegationBo) iterator.next();
292 				((WebRuleBaseValues) delegation.getDelegationRule()).establishRequiredState();
293 			}
294 		}
295 	}
296 
297 	public void validateResponsibility(String keyPrefix, ActionErrors errors) {
298 		if (KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID.equals(getRuleResponsibilityType())) {
299 			boolean invalidUser = org.apache.commons.lang.StringUtils.isEmpty(getReviewer());
300 			if (!invalidUser)
301 			{
302 				//chb: 10Jan2009: not using KEW IdentityHelperService b/c we want to deal w/ exception here
303 				Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(getReviewer());
304 				if( principal != null)
305 				{
306 					setRuleResponsibilityName(principal.getPrincipalId());
307 				}
308 				else
309 				{
310 					invalidUser = true;
311 				}
312 			}
313 			if (invalidUser) {
314 				errors.add(keyPrefix + "reviewer", new ActionMessage("routetemplate.ruleservice.user.invalid"));
315 			}
316 		} else if (KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID.equals(getRuleResponsibilityType())) {
317 			boolean invalidWorkgroup = org.apache.commons.lang.StringUtils.isEmpty(getReviewer());
318 			;
319 			if (!invalidWorkgroup) {
320 			    Group workgroup = KimApiServiceLocator.getGroupService().getGroup(getReviewerId());
321 				if (workgroup == null) {
322 					invalidWorkgroup = true;
323 				} else {
324 					setRuleResponsibilityName(workgroup.getId());
325 				}
326 			} else {
327 				errors.add(keyPrefix + "reviewer", new ActionMessage("routetemplate.ruleservice.workgroup.invalid"));
328 			}
329 
330 		} else if (KewApiConstants.RULE_RESPONSIBILITY_ROLE_ID.equals(getRuleResponsibilityType())) {
331 			setRuleResponsibilityName(getRoleReviewer());
332 		}
333 
334 		int delIndex = 0;
335 		for (Iterator respIterator = getDelegationRules().iterator(); respIterator.hasNext();) {
336 			String delPrefix = keyPrefix + "delegationRule[" + delIndex + "].delegationRuleBaseValues.";
337 			RuleDelegationBo ruleDelegation = (RuleDelegationBo) respIterator.next();
338 			((WebRuleBaseValues) ruleDelegation.getDelegationRule()).validateRule(delPrefix, errors);
339 		}
340 	}
341 
342 	public void edit(RuleResponsibilityBo ruleResponsibility) throws Exception {
343 		load(ruleResponsibility);
344 		initialize();
345 	}
346 
347 	public void load(RuleResponsibilityBo ruleResponsibility) throws Exception {
348 		PropertyUtils.copyProperties(this, ruleResponsibility);
349 		injectWebMembers();
350 	}
351 
352 	public void loadDelegations() throws Exception {
353 		fetchDelegations();
354 
355 		for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) {
356 			RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next();
357 			WebRuleBaseValues webRule = new WebRuleBaseValues();
358 			webRule.edit(ruleDelegation.getDelegationRule());
359 			ruleDelegation.setDelegationRule(webRule);
360 		}
361 		delegationRulesMaterialized = true;
362 		populatePreviousRuleIds();
363 	}
364 
365 	public void populatePreviousRuleIds() {
366 		if (delegationRulesMaterialized) {
367 			for (Iterator iterator = getDelegationRules().iterator(); iterator.hasNext();) {
368 				RuleDelegationBo delegation = (RuleDelegationBo) iterator.next();
369 				((WebRuleBaseValues) delegation.getDelegationRule()).populatePreviousRuleIds();
370 			}
371 		}
372 	}
373 
374 	private void fetchDelegations() {
375 		if (getId() != null) {
376 			RuleResponsibilityBo responsibility = getRuleService().findByRuleResponsibilityId(getId());
377 			if (responsibility == null) {
378 				return;
379 			}
380 			getDelegationRules().addAll(responsibility.getDelegationRules());
381 		}
382 	}
383 
384 	public void prepareHiddenDelegationsForRoute() {
385 		if (showDelegations) {
386 			return;
387 		}
388 
389 		fetchDelegations();
390 
391 		for (Iterator iter = getDelegationRules().iterator(); iter.hasNext();) {
392 			RuleDelegationBo delegation = (RuleDelegationBo) iter.next();
393 			delegation.setDelegateRuleId(null);
394 			delegation.setVersionNumber(null);
395 			delegation.setRuleDelegationId(null);
396 			//delegation.setRuleResponsibility(this);
397 			delegation.setResponsibilityId(null);
398 
399 			RuleBaseValues rule = delegation.getDelegationRule();
400 			rule.setVersionNumber(null);
401 			rule.setPreviousRuleId(rule.getId());
402 			rule.setDocumentId(null);
403 			rule.setId(null);
404 
405 			for (Iterator iterator = rule.getRuleResponsibilities().iterator(); iterator.hasNext();) {
406 				RuleResponsibilityBo responsibility = (RuleResponsibilityBo) iterator.next();
407 				responsibility.setVersionNumber(null);
408 				responsibility.setRuleBaseValuesId(null);
409 				responsibility.setRuleBaseValues(rule);
410 				responsibility.setId(null);
411 			}
412 
413 			for (Iterator iterator = rule.getRuleExtensions().iterator(); iterator.hasNext();) {
414 				RuleExtensionBo extension = (RuleExtensionBo) iterator.next();
415 				extension.setVersionNumber(null);
416 				extension.setRuleBaseValues(rule);
417 				extension.setRuleBaseValuesId(null);
418 				extension.setRuleExtensionId(null);
419 
420 				for (Iterator iter2 = extension.getExtensionValues().iterator(); iter2.hasNext();) {
421 					RuleExtensionValue value = (RuleExtensionValue) iter2.next();
422 					value.setExtension(extension);
423 					value.setLockVerNbr(null);
424 					value.setRuleExtensionId(null);
425 					value.setRuleExtensionValueId(null);
426 				}
427 			}
428 		}
429 	}
430 
431 	public boolean isHasDelegateRuleTemplate() {
432 		return hasDelegateRuleTemplate;
433 	}
434 
435 	public void setHasDelegateRuleTemplate(boolean hasDelegateRuleTemplate) {
436 		this.hasDelegateRuleTemplate = hasDelegateRuleTemplate;
437 	}
438 
439 	private RuleServiceInternal getRuleService() {
440 		return (RuleServiceInternal) KEWServiceLocator.getService(KEWServiceLocator.RULE_SERVICE);
441 	}
442 
443 	/**
444 	 * Just a little dynamic proxy to keep us from establishing required state
445 	 * on the delegation rules if they haven't been materialized from the
446 	 * database yet (they are currenty proxied by OJB)
447 	 *
448  * @author Kuali Rice Team (rice.collab@kuali.org)
449 	 */
450 	private class DelegationRulesProxy implements InvocationHandler, java.io.Serializable {
451 
452 		private static final long serialVersionUID = 7046323200221509473L;
453 
454 		private List delegationRules;
455 
456 		public DelegationRulesProxy(List delegationRules) {
457 			this.delegationRules = delegationRules;
458 		}
459 
460 		public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
461 			if (!delegationRulesMaterialized && !m.getName().equals("isEmpty") && !m.getName().equals("size")) {
462 				for (Iterator iterator = delegationRules.iterator(); iterator.hasNext();) {
463 					RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next();
464 					WebRuleBaseValues webRule = new WebRuleBaseValues();
465 					webRule.load(ruleDelegation.getDelegationRule());
466 					webRule.establishRequiredState();
467 					ruleDelegation.setDelegationRule(webRule);
468 				}
469 				delegationRulesMaterialized = true;
470 
471 			}
472 			return m.invoke(delegationRules, args);
473 		}
474 
475 	}
476 
477 }