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 }