mx4j/src/tools/mx4j/tools/remote/caucho CauchoClientInvoker.java,NONE,1.1 CauchoInput.java,NONE,1.1 CauchoOutput.java,NONE,1.1 CauchoService.java,NONE,1.1 CauchoServlet.java,NONE,1.1

Simone Bordet <[email protected]>
Newsgroups gmane.comp.java.mx4j.cvs
Message-ID <[email protected]>
Update of /cvsroot/mx4j/mx4j/src/tools/mx4j/tools/remote/caucho
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24799/src/tools/mx4j/tools/remote/caucho

Added Files:
	CauchoClientInvoker.java CauchoInput.java CauchoOutput.java 
	CauchoService.java CauchoServlet.java 
Log Message:
Implementation of the JSR 160 JMXConnector and JMXConnectorServer over Caucho's Hessian and Burlap protocols

--- NEW FILE: CauchoInput.java ---
/*
 * Copyright (C) MX4J.
 * All rights reserved.
 *
 * This software is distributed under the terms of the MX4J License version 1.0.
 * See the terms of the MX4J License in the documentation provided with this software.
 */

package mx4j.tools.remote.caucho;

import java.io.IOException;

/**
 * @author <a href="mailto:[email protected]">Simone Bordet</a>
 * @version $
 */
public interface CauchoInput
{
   public void startCall() throws IOException;

   public void completeCall() throws IOException;

   public String readHeader() throws IOException;

   public String readMethod() throws IOException;

   /**
    * Reads and returns an object of the given class,
    * or a generic object if the class is null.
    */
   public Object readObject(Class cls) throws IOException;

   /**
    * Starts reading a reply of a previous call; if the call threw an exception,
    * the exception is read and re-thrown, otherwise the result of the call
    * can be read using {@link #readObject}.
    */
   public void startReply() throws Exception;

   public void completeReply() throws IOException;
}

--- NEW FILE: CauchoService.java ---
/*
 * Copyright (C) MX4J.
 * All rights reserved.
 *
 * This software is distributed under the terms of the MX4J License version 1.0.
 * See the terms of the MX4J License in the documentation provided with this software.
 */

package mx4j.tools.remote.caucho;

import java.lang.reflect.Method;

import mx4j.tools.remote.http.HTTPService;

/**
 * @author <a href="mailto:[email protected]">Simone Bordet</a>
 * @version $
 */
public class CauchoService extends HTTPService
{
   static final String CONNECTION_ID_HEADER_NAME = "connectionContext";

   private static ThreadLocal connectionContext = new ThreadLocal();

   private final String protocol;

   public CauchoService(String protocol)
   {
      this.protocol = protocol;
   }

   protected String getProtocol()
   {
      return protocol;
   }

   protected String findRequestURL()
   {
      ConnectionContext context = (ConnectionContext)connectionContext.get();
      return context == null ? null : context.url;
   }

   protected String findConnectionId()
   {
      ConnectionContext context = (ConnectionContext)connectionContext.get();
      return context == null ? null : context.connectionId;
   }

   static void setConnectionContext(String url, String connectionId)
   {
      connectionContext.set(new ConnectionContext(url, connectionId));
   }

   static void resetConnectionContext()
   {
      connectionContext.set(null);
   }

   static String mangleMethodName(Method method)
   {
      return method.getName() + "__" + method.getParameterTypes().length;
   }

   private static class ConnectionContext
   {
      private String url;
      private String connectionId;

      private ConnectionContext(String url, String connectionId)
      {
         this.url = url;
         this.connectionId = connectionId;
      }
   }
}

--- NEW FILE: CauchoClientInvoker.java ---
/*
 * Copyright (C) MX4J.
 * All rights reserved.
 *
 * This software is distributed under the terms of the MX4J License version 1.0.
 * See the terms of the MX4J License in the documentation provided with this software.
 */

package mx4j.tools.remote.caucho;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.net.URLConnection;

import mx4j.log.Log;
import mx4j.log.Logger;
import mx4j.tools.remote.http.HTTPClientInvoker;
import mx4j.tools.remote.http.HTTPConnection;

/**
 * @author <a href="mailto:[email protected]">Simone Bordet</a>
 * @version $Revision: 1.1 $
 */
public abstract class CauchoClientInvoker extends HTTPClientInvoker
{
   private final String endpoint;
   private final HTTPConnection service;

   public CauchoClientInvoker(String endpoint)
   {
      this.endpoint = endpoint;
      CauchoServiceProxy proxy = new CauchoServiceProxy();
      service = (HTTPConnection)Proxy.newProxyInstance(proxy.getClass().getClassLoader(), new Class[]{HTTPConnection.class}, proxy);
   }

   protected HTTPConnection getService()
   {
      return service;
   }

   protected abstract CauchoInput createCauchoInput(InputStream stream);

   protected abstract CauchoOutput createCauchoOutput(OutputStream stream);

   private class CauchoServiceProxy implements InvocationHandler
   {
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
      {
         URLConnection connection = new URL(endpoint).openConnection();
         connection.setDoInput(true);
         connection.setDoOutput(true);
         connection.setUseCaches(false);
         OutputStream os = new BufferedOutputStream(connection.getOutputStream());
         try
         {
            CauchoOutput output = createCauchoOutput(os);
            startCall(output);
            writeHeaders(output);
            writeMethod(output, method);
            writeArguments(output, args);
            completeCall(output);
            os.flush();

            InputStream is = new BufferedInputStream(connection.getInputStream());
            try
            {
               CauchoInput input = createCauchoInput(is);
               input.startReply();
               Object result = input.readObject(method.getReturnType());
               input.completeReply();
               return result;
            }
            catch (Throwable x)
            {
               Logger logger = Log.getLogger(CauchoClientInvoker.class.getName());
               if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("", x);
               throw x;
            }
            finally
            {
               is.close();
            }
         }
         finally
         {
            os.close();
         }
      }

      private void startCall(CauchoOutput output) throws IOException
      {
         output.startCall();
      }

      private void writeHeaders(CauchoOutput output) throws IOException
      {
         output.writeHeader(CauchoService.CONNECTION_ID_HEADER_NAME);
         output.writeObject(getConnectionId());
      }

      private void writeMethod(CauchoOutput output, Method method) throws IOException
      {
         String methodName = mangleMethodName(method);
         output.writeMethod(methodName);
      }

      private String mangleMethodName(Method method)
      {
         return CauchoService.mangleMethodName(method);
      }

      private void writeArguments(CauchoOutput output, Object[] args) throws IOException
      {
         if (args != null) for (int i = 0; i < args.length; ++i) output.writeObject(args[i]);
      }

      private void completeCall(CauchoOutput output) throws IOException
      {
         output.completeCall();
      }
   }
}

--- NEW FILE: CauchoServlet.java ---
/*
 * Copyright (C) MX4J.
 * All rights reserved.
 *
 * This software is distributed under the terms of the MX4J License version 1.0.
 * See the terms of the MX4J License in the documentation provided with this software.
 */

package mx4j.tools.remote.caucho;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import mx4j.tools.remote.http.HTTPConnection;

/**
 * @author <a href="mailto:[email protected]">Simone Bordet</a>
 * @version $Revision: 1.1 $
 */
public abstract class CauchoServlet extends HttpServlet
{
   private Map methods;

   public void init() throws ServletException
   {
      methods = new HashMap();
      mapMethods(HTTPConnection.class, methods);
   }

   protected void mapMethods(Class cls, Map methods)
   {
      Method[] mthds = cls.getMethods();
      for (int i = 0; i < mthds.length; ++i)
      {
         Method mthd = mthds[i];
         String key = mangleMethodName(mthd);
         methods.put(key, mthd);
      }
   }

   protected Method findMethod(String methodName)
   {
      return (Method)methods.get(methodName);
   }

   protected String mangleMethodName(Method method)
   {
      return CauchoService.mangleMethodName(method);
   }

   protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
   {
      if (!"POST".equalsIgnoreCase(request.getMethod())) throw new ServletException("Caucho protocol requires POST");

      BufferedInputStream is = new BufferedInputStream(request.getInputStream(), 48);
      CauchoInput input = createCauchoInput(is);
      BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream(), 48);
      CauchoOutput output = createCauchoOutput(bos);

      invoke(request, input, output);

      bos.flush();
   }

   protected abstract CauchoInput createCauchoInput(InputStream stream);

   protected abstract CauchoOutput createCauchoOutput(OutputStream stream);

   protected abstract Object getService();

   protected void invoke(HttpServletRequest request, CauchoInput input, CauchoOutput output) throws IOException
   {
      input.startCall();
      Map headers = readHeaders(input);
      String methodName = input.readMethod();
      Method method = findMethod(methodName);
      if (method == null)
      {
         output.startReply();
         NoSuchMethodException x = new NoSuchMethodException(methodName);
         output.writeFault(x);
         output.completeReply();
      }
      else
      {
         Object[] values = readArguments(input, method);
         input.completeCall();

         Object result = null;
         try
         {
            result = invoke(request.getRequestURL().toString(), getService(), method, headers, values);
         }
         catch (Throwable x)
         {
            output.startReply();
            output.writeFault(x);
            output.completeReply();
            return;
         }
         output.startReply();
         output.writeObject(result);
         output.completeReply();
      }
   }

   protected Map readHeaders(CauchoInput input) throws IOException
   {
      Map headers = new HashMap();
      String header = null;
      while ((header = input.readHeader()) != null) headers.put(header, input.readObject(null));
      return headers;
   }

   protected Object[] readArguments(CauchoInput input, Method method) throws IOException
   {
      Class[] types = method.getParameterTypes();
      Object[] values = new Object[types.length];
      for (int i = 0; i < types.length; ++i) values[i] = input.readObject(types[i]);
      return values;
   }

   protected Object invoke(String url, Object target, Method method, Map headers, Object[] values) throws Exception
   {
      if (target == null) throw new IOException("Service is not available");
      String connectionId = (String)headers.get(CauchoService.CONNECTION_ID_HEADER_NAME);
      CauchoService.setConnectionContext(url, connectionId);
      try
      {
         return method.invoke(target, values);
      }
      catch (InvocationTargetException x)
      {
         Throwable t = x.getTargetException();
         if (t instanceof Exception) throw (Exception)t;
         throw (Error)t;
      }
      finally
      {
         CauchoService.resetConnectionContext();
      }
   }
}

--- NEW FILE: CauchoOutput.java ---
/*
 * Copyright (C) MX4J.
 * All rights reserved.
 *
 * This software is distributed under the terms of the MX4J License version 1.0.
 * See the terms of the MX4J License in the documentation provided with this software.
 */

package mx4j.tools.remote.caucho;

import java.io.IOException;

/**
 * @author <a href="mailto:[email protected]">Simone Bordet</a>
 * @version $
 */
public interface CauchoOutput
{
   public void startCall() throws IOException;

   public void completeCall() throws IOException;

   public void startReply() throws IOException;

   public void completeReply() throws IOException;

   public void writeHeader(String header) throws IOException;

   public void writeMethod(String methodName) throws IOException;

   public void writeObject(Object object) throws IOException;

   public void writeFault(Throwable fault) throws IOException;
}



-------------------------------------------------------
SF.Net email is sponsored by Shop4tech.com-Lowest price on Blank Media
100pk Sonic DVD-R 4x for only $29 -100pk Sonic DVD+R for only $33
Save 50% off Retail on Ink & Toner - Free Shipping and Free Gift.
http://www.shop4tech.com/z/Inkjet_Cartridges/9_108_r285
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.