View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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;
20  
21  import java.io.InputStream;
22  import java.io.Reader;
23  import java.lang.reflect.InvocationTargetException;
24  import java.lang.reflect.Method;
25  
26  import org.eclipse.jetty.util.log.Log;
27  import org.eclipse.jetty.util.log.Logger;
28  import org.eclipse.jetty.websocket.api.Session;
29  import org.eclipse.jetty.websocket.api.WebSocketException;
30  
31  public class EventMethod
32  {
33      private static final Logger LOG = Log.getLogger(EventMethod.class);
34  
35      private static Object[] dropFirstArg(Object[] args)
36      {
37          if (args.length == 1)
38          {
39              return new Object[0];
40          }
41          Object ret[] = new Object[args.length - 1];
42          System.arraycopy(args,1,ret,0,ret.length);
43          return ret;
44      }
45  
46      protected Class<?> pojo;
47      protected Method method;
48      private boolean hasSession = false;
49      private boolean isStreaming = false;
50      private Class<?>[] paramTypes;
51  
52      public EventMethod(Class<?> pojo, Method method)
53      {
54          this.pojo = pojo;
55          this.paramTypes = method.getParameterTypes();
56          this.method = method;
57          identifyPresentParamTypes();
58      }
59  
60      public EventMethod(Class<?> pojo, String methodName, Class<?>... paramTypes)
61      {
62          try
63          {
64              this.pojo = pojo;
65              this.paramTypes = paramTypes;
66              this.method = pojo.getMethod(methodName,paramTypes);
67              identifyPresentParamTypes();
68          }
69          catch (NoSuchMethodException | SecurityException e)
70          {
71              LOG.warn("Cannot use method {}({}): {}",methodName,paramTypes,e.getMessage());
72              this.method = null;
73          }
74      }
75  
76      public void call(Object obj, Object... args)
77      {
78          if ((this.pojo == null) || (this.method == null))
79          {
80              LOG.warn("Cannot execute call: pojo={}, method={}",pojo,method);
81              return; // no call event method determined
82          }
83          if (obj == null)
84          {
85              LOG.warn("Cannot call {} on null object",this.method);
86              return;
87          }
88          if (args.length > paramTypes.length)
89          {
90              Object trimArgs[] = dropFirstArg(args);
91              call(obj,trimArgs);
92              return;
93          }
94          if (args.length < paramTypes.length)
95          {
96              throw new IllegalArgumentException("Call arguments length [" + args.length + "] must always be greater than or equal to captured args length ["
97                      + paramTypes.length + "]");
98          }
99  
100         try
101         {
102             this.method.invoke(obj,args);
103         }
104         catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
105         {
106             String err = String.format("Cannot call method %s on %s with args: %s",method,pojo,args);
107             throw new WebSocketException(err,e);
108         }
109     }
110 
111     protected Method getMethod()
112     {
113         return method;
114     }
115 
116     protected Class<?>[] getParamTypes()
117     {
118         return this.paramTypes;
119     }
120 
121     private void identifyPresentParamTypes()
122     {
123         this.hasSession = false;
124         this.isStreaming = false;
125 
126         if (paramTypes == null)
127         {
128             return;
129         }
130 
131         for (Class<?> paramType : paramTypes)
132         {
133             if (Session.class.isAssignableFrom(paramType))
134             {
135                 this.hasSession = true;
136             }
137             if (Reader.class.isAssignableFrom(paramType) || InputStream.class.isAssignableFrom(paramType))
138             {
139                 this.isStreaming = true;
140             }
141         }
142     }
143 
144     public boolean isHasSession()
145     {
146         return hasSession;
147     }
148 
149     public boolean isStreaming()
150     {
151         return isStreaming;
152     }
153 }