1. /*
  2. * Copyright 2002-2004 the original author or authors.
  3. *
  4. * Licensed under the Apache 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.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,
  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.springframework.remoting.caucho;
  17. import java.lang.reflect.InvocationTargetException;
  18. import java.lang.reflect.UndeclaredThrowableException;
  19. import java.net.MalformedURLException;
  20. import com.caucho.hessian.client.HessianProxyFactory;
  21. import com.caucho.hessian.client.HessianRuntimeException;
  22. import org.aopalliance.intercept.MethodInterceptor;
  23. import org.aopalliance.intercept.MethodInvocation;
  24. import org.springframework.beans.factory.InitializingBean;
  25. import org.springframework.remoting.RemoteAccessException;
  26. import org.springframework.remoting.support.UrlBasedRemoteAccessor;
  27. /**
  28. * Interceptor for accessing a Hessian service.
  29. * Supports authentication via username and password.
  30. * The service URL must be an HTTP URL exposing a Hessian service.
  31. *
  32. * <p>Hessian is a slim, binary RPC protocol.
  33. * For information on Hessian, see the
  34. * <a href="http://www.caucho.com/hessian">Hessian website</a>
  35. *
  36. * <p>Note: Hessian services accessed with this proxy factory do not
  37. * have to be exported via HessianServiceExporter, as there isn't
  38. * any special handling involved. Therefore, you can also access
  39. * services that are exported via Caucho's HessianServlet.
  40. *
  41. * @author Juergen Hoeller
  42. * @since 29.09.2003
  43. * @see #setServiceInterface
  44. * @see #setServiceUrl
  45. * @see #setUsername
  46. * @see #setPassword
  47. * @see com.caucho.hessian.client.HessianProxyFactory
  48. */
  49. public class HessianClientInterceptor extends UrlBasedRemoteAccessor implements MethodInterceptor, InitializingBean {
  50. private final HessianProxyFactory proxyFactory = new HessianProxyFactory();
  51. private Object hessianProxy;
  52. /**
  53. * Set the username that this factory should use to access the remote service.
  54. * Default is none.
  55. * <p>The username will be sent by Hessian via HTTP Basic Authentication.
  56. * @see com.caucho.hessian.client.HessianProxyFactory#setUser
  57. */
  58. public void setUsername(String username) {
  59. this.proxyFactory.setUser(username);
  60. }
  61. /**
  62. * Set the password that this factory should use to access the remote service.
  63. * Default is none.
  64. * <p>The password will be sent by Hessian via HTTP Basic Authentication.
  65. * @see com.caucho.hessian.client.HessianProxyFactory#setPassword
  66. */
  67. public void setPassword(String password) {
  68. this.proxyFactory.setPassword(password);
  69. }
  70. /**
  71. * Set whether overloaded methods should be enabled for remote invocations.
  72. * Default is false.
  73. * @see com.caucho.hessian.client.HessianProxyFactory#setOverloadEnabled
  74. */
  75. public void setOverloadEnabled(boolean overloadEnabled) {
  76. this.proxyFactory.setOverloadEnabled(overloadEnabled);
  77. }
  78. public void afterPropertiesSet() throws MalformedURLException {
  79. if (getServiceInterface() == null) {
  80. throw new IllegalArgumentException("serviceInterface is required");
  81. }
  82. if (getServiceUrl() == null) {
  83. throw new IllegalArgumentException("serviceUrl is required");
  84. }
  85. this.hessianProxy = createHessianProxy(this.proxyFactory);
  86. }
  87. /**
  88. * Create the Hessian proxy that is wrapped by this interceptor.
  89. * @param proxyFactory the proxy factory to use
  90. * @return the Hessian proxy
  91. * @throws MalformedURLException if thrown by the proxy factory
  92. * @see com.caucho.hessian.client.HessianProxyFactory#create
  93. */
  94. protected Object createHessianProxy(HessianProxyFactory proxyFactory) throws MalformedURLException {
  95. return proxyFactory.create(getServiceInterface(), getServiceUrl());
  96. }
  97. public Object invoke(MethodInvocation invocation) throws Throwable {
  98. try {
  99. return invocation.getMethod().invoke(this.hessianProxy, invocation.getArguments());
  100. }
  101. catch (UndeclaredThrowableException ex) {
  102. throw new RemoteAccessException("Cannot access Hessian service", ex.getUndeclaredThrowable());
  103. }
  104. catch (InvocationTargetException ex) {
  105. logger.debug("Hessian service [" + getServiceUrl() + "] threw exception", ex.getTargetException());
  106. if (ex.getTargetException() instanceof HessianRuntimeException) {
  107. HessianRuntimeException hre = (HessianRuntimeException) ex.getTargetException();
  108. Throwable rootCause = (hre.getRootCause() != null) ? hre.getRootCause() : hre;
  109. throw new RemoteAccessException("Cannot access Hessian service", rootCause);
  110. }
  111. else if (ex.getTargetException() instanceof UndeclaredThrowableException) {
  112. UndeclaredThrowableException utex = (UndeclaredThrowableException) ex.getTargetException();
  113. throw new RemoteAccessException("Cannot access Hessian service", utex.getUndeclaredThrowable());
  114. }
  115. throw ex.getTargetException();
  116. }
  117. }
  118. }