You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ServerRpcManager.java 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Copyright 2000-2016 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  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, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.server;
  17. import java.io.Serializable;
  18. import java.lang.reflect.Field;
  19. import java.lang.reflect.Method;
  20. import java.util.HashMap;
  21. import java.util.Map;
  22. import java.util.logging.Level;
  23. import java.util.logging.Logger;
  24. import com.vaadin.shared.Connector;
  25. import com.vaadin.shared.communication.ServerRpc;
  26. /**
  27. * Server side RPC manager that handles RPC calls coming from the client.
  28. *
  29. * Each {@link RpcTarget} (typically a {@link ClientConnector}) should have its
  30. * own instance of {@link ServerRpcManager} if it wants to receive RPC calls
  31. * from the client.
  32. *
  33. * @since 7.0
  34. */
  35. public class ServerRpcManager<T extends ServerRpc> implements Serializable {
  36. private final T implementation;
  37. private final Class<T> rpcInterface;
  38. /**
  39. * Wrapper exception for exceptions which occur during invocation of an RPC
  40. * call
  41. *
  42. * @author Vaadin Ltd
  43. * @since 7.0
  44. *
  45. */
  46. public static class RpcInvocationException extends Exception {
  47. public RpcInvocationException() {
  48. super();
  49. }
  50. public RpcInvocationException(String message, Throwable cause) {
  51. super(message, cause);
  52. }
  53. public RpcInvocationException(String message) {
  54. super(message);
  55. }
  56. public RpcInvocationException(Throwable cause) {
  57. super(cause);
  58. }
  59. }
  60. private static final Map<Class<?>, Class<?>> boxedTypes = new HashMap<>();
  61. static {
  62. try {
  63. Class<?>[] boxClasses = new Class<?>[] { Boolean.class, Byte.class,
  64. Short.class, Character.class, Integer.class, Long.class,
  65. Float.class, Double.class };
  66. for (Class<?> boxClass : boxClasses) {
  67. Field typeField = boxClass.getField("TYPE");
  68. Class<?> primitiveType = (Class<?>) typeField.get(boxClass);
  69. boxedTypes.put(primitiveType, boxClass);
  70. }
  71. } catch (Exception e) {
  72. throw new RuntimeException(e);
  73. }
  74. }
  75. /**
  76. * Create a RPC manager for an RPC target.
  77. *
  78. * @param target
  79. * RPC call target (normally a {@link Connector})
  80. * @param implementation
  81. * RPC interface implementation for the target
  82. * @param rpcInterface
  83. * RPC interface type
  84. */
  85. public ServerRpcManager(T implementation, Class<T> rpcInterface) {
  86. this.implementation = implementation;
  87. this.rpcInterface = rpcInterface;
  88. }
  89. /**
  90. * Invoke a method in a server side RPC target class. This method is to be
  91. * used by the RPC framework and unit testing tools only.
  92. *
  93. * @param target
  94. * non-null target of the RPC call
  95. * @param invocation
  96. * method invocation to perform
  97. * @throws RpcInvocationException
  98. */
  99. public static void applyInvocation(ClientConnector target,
  100. ServerRpcMethodInvocation invocation)
  101. throws RpcInvocationException {
  102. ServerRpcManager<?> manager = target
  103. .getRpcManager(invocation.getInterfaceName());
  104. if (manager != null) {
  105. manager.applyInvocation(invocation);
  106. } else {
  107. getLogger().log(Level.WARNING,
  108. "RPC call received for RpcTarget {0} ({1}) but the target has not registered any RPC interfaces",
  109. new Object[] { target.getClass().getName(),
  110. invocation.getConnectorId() });
  111. }
  112. }
  113. /**
  114. * Returns the RPC interface implementation for the RPC target.
  115. *
  116. * @return RPC interface implementation
  117. */
  118. protected T getImplementation() {
  119. return implementation;
  120. }
  121. /**
  122. * Returns the RPC interface type managed by this RPC manager instance.
  123. *
  124. * @return RPC interface type
  125. */
  126. public Class<T> getRpcInterface() {
  127. return rpcInterface;
  128. }
  129. /**
  130. * Invoke a method in a server side RPC target class. This method is to be
  131. * used by the RPC framework and unit testing tools only.
  132. *
  133. * @param invocation
  134. * method invocation to perform
  135. */
  136. public void applyInvocation(ServerRpcMethodInvocation invocation)
  137. throws RpcInvocationException {
  138. Method method = invocation.getMethod();
  139. Object[] arguments = invocation.getParameters();
  140. try {
  141. method.invoke(implementation, arguments);
  142. } catch (Exception e) {
  143. throw new RpcInvocationException(
  144. "Unable to invoke method " + invocation.getMethodName()
  145. + " in " + invocation.getInterfaceName(),
  146. e);
  147. }
  148. }
  149. private static Logger getLogger() {
  150. return Logger.getLogger(ServerRpcManager.class.getName());
  151. }
  152. }