View Javadoc
1   /**
2    * Copyright 2005-2015 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.kns.workflow.attribute;
17  
18  import net.sf.cglib.proxy.Enhancer;
19  import net.sf.cglib.proxy.InvocationHandler;
20  import org.kuali.rice.core.web.format.BooleanFormatter;
21  import org.kuali.rice.krad.bo.BusinessObject;
22  import org.kuali.rice.krad.util.ObjectUtils;
23  
24  import java.lang.reflect.Method;
25  import java.util.HashMap;
26  
27  /**
28   * This class provides access to the properties of business objects returned as search results by the WorkflowLookupableImpl.
29   * 
30   * 
31   * @see org.kuali.rice.kew.attribute.WorkflowLookupableImpl
32   * @deprecated This will go away once workflow supports simple url integration for custom attribute lookups.
33   */
34  @Deprecated
35  public class WorkflowLookupableInvocationHandler implements InvocationHandler {
36      private BusinessObject proxiedBusinessObject;
37      private ClassLoader classLoader;
38  
39      private String returnUrl;
40  
41      /**
42       * Constructs a WorkflowLookupableInvocationHandler.java.
43       * 
44       * @param proxiedBusinessObject The BusinessObject that this instance is providing access to.
45       */
46      public WorkflowLookupableInvocationHandler(BusinessObject proxiedBusinessObject, ClassLoader classLoader) {
47          this.proxiedBusinessObject = proxiedBusinessObject;
48          this.classLoader = classLoader;
49      }
50  
51      /**
52       * Constructs a WorkflowLookupableInvocationHandler.java.
53       * 
54       * @param proxiedBusinessObject The BusinessObject that this instance is providing access to.
55       * @param returnUrl The returnUrl String for selection of a result from the UI
56       */
57      public WorkflowLookupableInvocationHandler(BusinessObject proxiedBusinessObject, String returnUrl, ClassLoader classLoader) {
58          this.proxiedBusinessObject = proxiedBusinessObject;
59          this.returnUrl = returnUrl;
60          this.classLoader = classLoader;
61      }
62  
63      /**
64       * This method intercepts "getReturnUrl" and returns this objects returnUrl attribute. It proxies access to nested
65       * BusinessObjects to ensure that the application plugin classloader is used to resolve OJB proxies. And, it translates booleans
66       * for the UI, using the BooleanFormatter.
67       * 
68       * @see net.sf.cglib.proxy.InvocationHandler#invoke(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[]
69       *      args)
70       * 
71       */
72      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
73          ClassLoader oldClassloader = Thread.currentThread().getContextClassLoader();
74          try {
75              Thread.currentThread().setContextClassLoader(classLoader);
76              if ("getReturnUrl".equals(method.getName())) {
77                  return returnUrl;
78              }
79              else if ("getWorkflowLookupableResult".equals(method.getName())) {
80                  return Enhancer.create(HashMap.class, new Class[] { WorkflowLookupableResult.class }, this);
81              }
82              else if ("get".equals(method.getName())) {
83                  Object propertyValue = ObjectUtils.getNestedValue(proxiedBusinessObject, args[0].toString());
84                  if (propertyValue instanceof BusinessObject) {
85                      return Enhancer.create(propertyValue.getClass(), new WorkflowLookupableInvocationHandler((BusinessObject) propertyValue, classLoader));
86                  }
87                  else {
88                      if (propertyValue instanceof Boolean) {
89                          return new BooleanFormatter().format(propertyValue);
90                      }
91                      return propertyValue;
92                  }
93              }
94              else {
95                  return method.invoke(proxiedBusinessObject, args);
96              }
97          }
98          catch (Exception e) {
99              throw (e.getCause() != null ? e.getCause() : e);
100         }
101         finally {
102             Thread.currentThread().setContextClassLoader(oldClassloader);
103         }
104     }
105 }