View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.websocket.common.events.annotated;
20  
21  import java.lang.reflect.InvocationTargetException;
22  import java.lang.reflect.Method;
23  import java.util.Objects;
24  
25  import org.eclipse.jetty.util.log.Log;
26  import org.eclipse.jetty.util.log.Logger;
27  import org.eclipse.jetty.websocket.api.WebSocketException;
28  import org.eclipse.jetty.websocket.common.util.ReflectUtils;
29  
30  /**
31   * A Callable Method
32   */
33  public class CallableMethod
34  {
35      private static final Logger LOG = Log.getLogger(CallableMethod.class);
36      protected final Class<?> pojo;
37      protected final Method method;
38      protected Class<?>[] paramTypes;
39  
40      public CallableMethod(Class<?> pojo, Method method)
41      {
42          Objects.requireNonNull(pojo, "Pojo cannot be null");
43          Objects.requireNonNull(method, "Method cannot be null");
44          this.pojo = pojo;
45          this.method = method;
46          this.paramTypes = method.getParameterTypes();
47      }
48  
49      public Object call(Object obj, Object... args)
50      {
51          if ((this.pojo == null) || (this.method == null))
52          {
53              LOG.warn("Cannot execute call: pojo={}, method={}",pojo,method);
54              return null; // no call event method determined
55          }
56  
57          if (obj == null)
58          {
59              LOG.warn("Cannot call {} on null object",this.method);
60              return null;
61          }
62  
63          if (args.length < paramTypes.length)
64          {
65              throw new IllegalArgumentException("Call arguments length [" + args.length + "] must always be greater than or equal to captured args length ["
66                      + paramTypes.length + "]");
67          }
68  
69          try
70          {
71              return this.method.invoke(obj,args);
72          }
73          catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
74          {
75              StringBuilder err = new StringBuilder();
76              err.append("Cannot call method ");
77              err.append(ReflectUtils.toString(pojo,method));
78              err.append(" with args: [");
79  
80              boolean delim = false;
81              for (Object arg : args)
82              {
83                  if (delim)
84                  {
85                      err.append(", ");
86                  }
87                  if (arg == null)
88                  {
89                      err.append("<null>");
90                  }
91                  else
92                  {
93                      err.append(arg.getClass().getName());
94                  }
95                  delim = true;
96              }
97              err.append("]");
98  
99              throw new WebSocketException(err.toString(),e);
100         }
101     }
102 
103     public Method getMethod()
104     {
105         return method;
106     }
107 
108     public Class<?>[] getParamTypes()
109     {
110         return paramTypes;
111     }
112 
113     public Class<?> getPojo()
114     {
115         return pojo;
116     }
117 
118     @Override
119     public String toString()
120     {
121         return String.format("%s[%s]",this.getClass().getSimpleName(),method.toGenericString());
122     }
123 }