[jboss-cvs] jboss-seam/src/remoting/org/jboss/seam/remoting/gwt ...

Shane Bryzak sbryzak at redhat.com
Mon Oct 15 20:51:40 EDT 2007


  User: sbryzak2
  Date: 07/10/15 20:51:39

  Added:       src/remoting/org/jboss/seam/remoting/gwt    
                        GWT13Service.java GWT14Service.java GWTService.java
  Removed:     src/remoting/org/jboss/seam/remoting/gwt    
                        GWTRemoteService.java
  Log:
  JBSEAM-1748 - GWT 1.4 integration
  
  Revision  Changes    Path
  1.1      date: 2007/10/16 00:51:39;  author: sbryzak2;  state: Exp;jboss-seam/src/remoting/org/jboss/seam/remoting/gwt/GWT13Service.java
  
  Index: GWT13Service.java
  ===================================================================
  package org.jboss.seam.remoting.gwt;
  
  import static org.jboss.seam.ScopeType.APPLICATION;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import java.lang.reflect.Constructor;
  
  import org.jboss.seam.annotations.Create;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Startup;
  import org.jboss.seam.annotations.intercept.BypassInterceptors;
  
  import com.google.gwt.user.client.rpc.SerializationException;
  import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader;
  import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter;
  
  /**
   * 
   * @author Shane Bryzak
   */
  @Startup
  @Scope(APPLICATION)
  @Name("org.jboss.seam.remoting.gwt.gwtRemoteService")
  @Install(value = false, precedence = BUILT_IN, classDependencies = {"com.google.gwt.user.client.rpc.RemoteService"})
  @BypassInterceptors
  public class GWT13Service extends GWTService
  {
     private static final String SERIALIZABLE_TYPE_CLASS = "com.google.gwt.user.server.rpc.impl.ServerSerializableTypeOracleImpl";
       
     private Object serializableTypeOracle;
     
     private Constructor streamReaderConstructor;
     private Constructor streamWriterConstructor;
     
     @Create
     public void startup() throws Exception
     {
        Class serializableType = Class.forName(SERIALIZABLE_TYPE_CLASS);
        String[] packagePaths = getPackagePaths();
        Constructor typeConstructor = serializableType.getConstructor(new Class[] { packagePaths.getClass() });
        
        serializableTypeOracle = typeConstructor.newInstance((Object[]) packagePaths);
        
        streamReaderConstructor = getConstructor(ServerSerializationStreamReader.class.getName(), new Class[] { serializableType } );
        streamWriterConstructor = getConstructor(ServerSerializationStreamWriter.class.getName(), new Class[] { serializableType } );
     }
  
     @Override
     protected String createResponse(ServerSerializationStreamWriter stream,
           Class responseType, Object responseObj, boolean isException)
     {
        stream.prepareToWrite();
        if (responseType != void.class)
        {
           try
           {
              stream.serializeValue(responseObj, responseType);
           } catch (SerializationException e)
           {
              responseObj = e;
              isException = true;
           }
        }
  
        return (isException ? "{EX}" : "{OK}") + stream.toString();     
     }   
  
     private Constructor getConstructor(String className, Class[] paramTypes)
     {
        try
        {
           Class cls = Class.forName(className);
           return cls.getConstructor(paramTypes);
        }
        catch (Exception ex)
        {
           log.error(String.format("Error initializing GWT13Service - class %s " +
                 "not found. Please ensure the GWT 1.3 libraries are in the classpath.",
                 className));
           throw new RuntimeException("Unable to create GWT13Service", ex);
        }
     }
     
     @Override
     public ServerSerializationStreamReader getStreamReader()
     {
        try
        {
           return (ServerSerializationStreamReader) streamReaderConstructor.newInstance(serializableTypeOracle);
        }
        catch (Exception ex) 
        { 
           throw new RuntimeException("Unable to create stream reader", ex);
        }
     }
     
     @Override
     public ServerSerializationStreamWriter getStreamWriter()
     {
        try
        {
           return (ServerSerializationStreamWriter) streamWriterConstructor.newInstance(serializableTypeOracle);
        }
        catch (Exception ex)
        {
           throw new RuntimeException("Unable to create stream writer", ex);
        }
     }
  }
  
  
  
  1.1      date: 2007/10/16 00:51:39;  author: sbryzak2;  state: Exp;jboss-seam/src/remoting/org/jboss/seam/remoting/gwt/GWT14Service.java
  
  Index: GWT14Service.java
  ===================================================================
  package org.jboss.seam.remoting.gwt;
  
  import static org.jboss.seam.ScopeType.APPLICATION;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Method;
  
  import org.jboss.seam.annotations.Create;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Startup;
  import org.jboss.seam.annotations.intercept.BypassInterceptors;
  
  import com.google.gwt.user.client.rpc.SerializationException;
  import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader;
  import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter;
  
  /**
   * 
   * @author Shane Bryzak
   */
  @Startup
  @Scope(APPLICATION)
  @Name("org.jboss.seam.remoting.gwt.gwtRemoteService")
  @Install(precedence = BUILT_IN, classDependencies = {"com.google.gwt.user.client.rpc.RemoteService"})
  @BypassInterceptors
  public class GWT14Service extends GWTService
  {
     private static final String SERIALIZATION_POLICY_PROVIDER_CLASS = "com.google.gwt.user.server.rpc.SerializationPolicyProvider";
     
     private static final String SERIALIZATION_POLICY_CLASS = "com.google.gwt.user.server.rpc.SerializationPolicy";
     private static final String LEGACY_SERIALIZATION_POLICY_CLASS = "com.google.gwt.user.server.rpc.impl.LegacySerializationPolicy";
     
     
     private Constructor streamReaderConstructor;
     private Constructor streamWriterConstructor;   
     
     private Object legacySerializationPolicy;
     
     @Create
     public void startup() throws Exception
     {
        Class policyProviderClass = Class.forName(SERIALIZATION_POLICY_PROVIDER_CLASS);
        Class serializationPolicyClass = Class.forName(SERIALIZATION_POLICY_CLASS);
        
        streamReaderConstructor = getConstructor(ServerSerializationStreamReader.class.getName(), 
              new Class[] { ClassLoader.class, policyProviderClass } );
        streamWriterConstructor = getConstructor(ServerSerializationStreamWriter.class.getName(), 
              new Class[] { serializationPolicyClass } );
  
        Class legacySerializationPolicyClass = Class.forName(LEGACY_SERIALIZATION_POLICY_CLASS);
        Method m = legacySerializationPolicyClass.getDeclaredMethod("getInstance");
        legacySerializationPolicy = m.invoke(null);
     } 
     
     private Constructor getConstructor(String className, Class[] paramTypes)
     {
        try
        {
           Class cls = Class.forName(className);
           return cls.getConstructor(paramTypes);
        }
        catch (Exception ex)
        {
           log.error(String.format("Error initializing GWT14Service - class %s " +
                 "not found. Please ensure the GWT 1.4 libraries are in the classpath.",
                 className));
           throw new RuntimeException("Unable to create GWT14Service", ex);
        }
     }   
     
     @Override
     protected String createResponse(ServerSerializationStreamWriter stream,
           Class responseType, Object responseObj, boolean isException)
     {
        stream.prepareToWrite();
        if (responseType != void.class)
        {
           try
           {
              stream.serializeValue(responseObj, responseType);
           } catch (SerializationException e)
           {
              responseObj = e;
              isException = true;
           }
        }
  
        return (isException ? "//EX" : "//OK") + stream.toString();      
     }   
     
     @Override
     public ServerSerializationStreamReader getStreamReader()
     {
        try
        {
           return (ServerSerializationStreamReader) streamReaderConstructor.newInstance(
                 Thread.currentThread().getContextClassLoader(), null);
        }
        catch (Exception ex) 
        { 
           throw new RuntimeException("Unable to create stream reader", ex);
        }
     }
     
     @Override
     public ServerSerializationStreamWriter getStreamWriter()
     {
        try
        {
           return (ServerSerializationStreamWriter) streamWriterConstructor.newInstance(legacySerializationPolicy);
        }
        catch (Exception ex)
        {
           throw new RuntimeException("Unable to create stream writer", ex);
        }
     }   
  }
  
  
  
  1.1      date: 2007/10/16 00:51:39;  author: sbryzak2;  state: Exp;jboss-seam/src/remoting/org/jboss/seam/remoting/gwt/GWTService.java
  
  Index: GWTService.java
  ===================================================================
  package org.jboss.seam.remoting.gwt;
  
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.UnsupportedEncodingException;
  import java.lang.reflect.InvocationTargetException;
  import java.util.HashMap;
  import java.util.zip.GZIPOutputStream;
  
  import javax.servlet.ServletContext;
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  import org.jboss.seam.log.LogProvider;
  import org.jboss.seam.log.Logging;
  import org.jboss.seam.remoting.gwt.GWTToSeamAdapter.ReturnedObject;
  import org.jboss.seam.servlet.ContextualHttpServletRequest;
  import org.jboss.seam.web.AbstractResource;
  
  import com.google.gwt.user.client.rpc.SerializableException;
  import com.google.gwt.user.client.rpc.SerializationException;
  import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader;
  import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter;
  
  /**
   * Abstract base class for GWT integration.
   * 
   * @author Shane Bryzak
   */
  public abstract class GWTService extends AbstractResource
  {
     protected static final LogProvider log = Logging.getLogProvider(GWTService.class);
     
     /*
      * These members are used to get and set the different HttpServletResponse
      * and HttpServletRequest headers.
      */
     private static final String ACCEPT_ENCODING = "Accept-Encoding";
     private static final String CHARSET_UTF8 = "UTF-8";
     private static final String CONTENT_ENCODING = "Content-Encoding";
     private static final String CONTENT_ENCODING_GZIP = "gzip";
     private static final String CONTENT_TYPE_TEXT_PLAIN_UTF8 = "text/plain; charset=utf-8";
     private static final String GENERIC_FAILURE_MSG = "The call failed on the server; see server log for details";
     private static final HashMap TYPE_NAMES;
  
     /**
      * Controls the compression threshold at and below which no compression will
      * take place.
      */
     private static final int UNCOMPRESSED_BYTE_SIZE_LIMIT = 256;
  
     static
     {
        TYPE_NAMES = new HashMap();
        TYPE_NAMES.put("Z", boolean.class);
        TYPE_NAMES.put("B", byte.class);
        TYPE_NAMES.put("C", char.class);
        TYPE_NAMES.put("D", double.class);
        TYPE_NAMES.put("F", float.class);
        TYPE_NAMES.put("I", int.class);
        TYPE_NAMES.put("J", long.class);
        TYPE_NAMES.put("S", short.class);
     }
  
     @Override
     public String getResourcePath()
     {
        return "/gwt";
     }
     
     protected abstract ServerSerializationStreamReader getStreamReader();
     protected abstract ServerSerializationStreamWriter getStreamWriter();
     protected abstract String createResponse(ServerSerializationStreamWriter stream,
           Class responseType, Object responseObj, boolean isException);
  
     /**
      * Return true if the response object accepts Gzip encoding. This is done by
      * checking that the accept-encoding header specifies gzip as a supported
      * encoding.
      */
     private static boolean acceptsGzipEncoding(HttpServletRequest request)
     {
        assert (request != null);
  
        String acceptEncoding = request.getHeader(ACCEPT_ENCODING);
        if (null == acceptEncoding)
        {
           return false;
        }
  
        return (acceptEncoding.indexOf(CONTENT_ENCODING_GZIP) != -1);
     }
  
     /**
      * This method attempts to estimate the number of bytes that a string will
      * consume when it is sent out as part of an HttpServletResponse. This really
      * a hack since we are assuming that every character will consume two bytes
      * upon transmission. This is definitely not true since some characters
      * actually consume more than two bytes and some consume less. This is even
      * less accurate if the string is converted to UTF8. However, it does save us
      * from converting every string that we plan on sending back to UTF8 just to
      * determine that we should not compress it.
      */
     private static int estimateByteSize(final String buffer)
     {
        return (buffer.length() * 2);
     }
  
     // private final Set knownImplementedInterfaces = new HashSet();
     private final ThreadLocal perThreadRequest = new ThreadLocal();
  
     private final ThreadLocal perThreadResponse = new ThreadLocal();
  
     /**
      * This is called internally.
      */
     @Override
     public final void getResource(final HttpServletRequest request,
           final HttpServletResponse response) throws ServletException,
           IOException
     {
        // We have to call getSession() before the response is written, as per the
        // servlet API docs.
        request.getSession(true);
  
        try
        {
           // Store the request & response objects in thread-local storage.
           perThreadRequest.set(request);
           perThreadResponse.set(response);
  
           new ContextualHttpServletRequest(request) {
              @Override
              public void process() throws Exception
              {
  
                 Throwable caught;
                 try
                 {
                    // Read the request fully.
                    //
                    String requestPayload = readPayloadAsUtf8(request);
  
                    // Invoke the core dispatching logic, which returns the
                    // serialized
                    // result.
                    //
                    String responsePayload = processCall(requestPayload);
  
                    // Write the response.
                    //
                    writeResponse(request, response, responsePayload);
                    return;
                 } catch (IOException e)
                 {
                    caught = e;
                 } catch (ServletException e)
                 {
                    caught = e;
                 } catch (SerializationException e)
                 {
                    caught = e;
                 } catch (Throwable e)
                 {
                    caught = e;
                 }
  
                 respondWithFailure(response, caught);
              }
  
              @Override
              protected void restoreConversationId()
              {
                 // no conversation support for gwt requests
              }
  
              @Override
              protected void handleConversationPropagation()
              {
              }
           }.run();
        } finally
        {
           perThreadRequest.remove();
           perThreadResponse.remove();
        }
     }
  
     /**
      * This is public so that it can be unit tested easily without HTTP.
      */
     public String processCall(String payload) throws SerializationException
     {
  
        // Let subclasses see the serialized request.
        //
        onBeforeRequestDeserialized(payload);
  
        // Create a stream to deserialize the request.
        //
        ServerSerializationStreamReader streamReader = getStreamReader();
        streamReader.prepareToRead(payload);
  
        // Read the service interface
        //
        String serviceIntfName = streamReader.readString();
  
        // Read the method name.
        //
        String methodName = streamReader.readString();
  
        // Read the number and names of the parameter classes from the stream.
        // We have to do this so that we can find the correct overload of the
        // method.
        //
        int paramCount = streamReader.readInt();
        Class[] paramTypes = new Class[paramCount];
        for (int i = 0; i < paramTypes.length; i++)
        {
           String paramClassName = streamReader.readString();
           try
           {
              paramTypes[i] = getClassOrPrimitiveFromName(paramClassName);
           } catch (ClassNotFoundException e)
           {
              throw new SerializationException("Unknown parameter " + i
                    + " type '" + paramClassName + "'", e);
           }
        }
  
        // Deserialize the parameters.
        //
        Object[] args = new Object[paramCount];
        for (int i = 0; i < args.length; i++)
        {
           args[i] = streamReader.deserializeValue(paramTypes[i]);
        }
  
        GWTToSeamAdapter adapter = GWTToSeamAdapter.instance();
  
        // Make the call via reflection.
        //
        String responsePayload = GENERIC_FAILURE_MSG;
        ServerSerializationStreamWriter streamWriter = getStreamWriter();
        Throwable caught = null;
        try
        {
           ReturnedObject returnedObject = adapter.callWebRemoteMethod(
                 serviceIntfName, methodName, paramTypes, args);
           Class returnType = returnedObject.returnType;
           Object returnVal = returnedObject.returnedObject;
           // Class returnType = serviceIntfMethod.getReturnType();
           // Object returnVal = serviceIntfMethod.invoke(this, args);
           responsePayload = createResponse(streamWriter, returnType, returnVal,
                 false);
        } catch (IllegalArgumentException e)
        {
           caught = e;
        } catch (IllegalAccessException e)
        {
           caught = e;
        } catch (InvocationTargetException e)
        {
           // Try to serialize the caught exception if the client is expecting it,
           // otherwise log the exception server-side.
           caught = e;
           Throwable cause = e.getCause();
           if (cause != null)
           {
              // Update the caught exception to the underlying cause
              caught = cause;
              // Serialize the exception back to the client if it's a declared
              // exception
              if (cause instanceof SerializableException)
              {
                 Class thrownClass = cause.getClass();
                 responsePayload = createResponse(streamWriter, thrownClass,
                       cause, true);
                 // Don't log the exception on the server
                 caught = null;
              }
           }
        }
  
        if (caught != null)
        {
           responsePayload = GENERIC_FAILURE_MSG;
           ServletContext servletContext = getServletContext();
           // servletContext may be null (for example, when unit testing)
           if (servletContext != null)
           {
              // Log the exception server side
              servletContext.log("Exception while dispatching incoming RPC call",
                    caught);
           }
        }
  
        // Let subclasses see the serialized response.
        //
        onAfterResponseSerialized(responsePayload);
  
        return responsePayload;
     }
  
     /**
      * Gets the <code>HttpServletRequest</code> object for the current call. It
      * is stored thread-locally so that simultaneous invocations can have
      * different request objects.
      */
     protected final HttpServletRequest getThreadLocalRequest()
     {
        return (HttpServletRequest) perThreadRequest.get();
     }
  
     /**
      * Gets the <code>HttpServletResponse</code> object for the current call.
      * It is stored thread-locally so that simultaneous invocations can have
      * different response objects.
      */
     protected final HttpServletResponse getThreadLocalResponse()
     {
        return (HttpServletResponse) perThreadResponse.get();
     }
  
     /**
      * Override this method to examine the serialized response that will be
      * returned to the client. The default implementation does nothing and need
      * not be called by subclasses.
      */
     protected void onAfterResponseSerialized(String serializedResponse)
     {
     }
  
     /**
      * Override this method to examine the serialized version of the request
      * payload before it is deserialized into objects. The default implementation
      * does nothing and need not be called by subclasses.
      */
     protected void onBeforeRequestDeserialized(String serializedRequest)
     {
     }
  
     /**
      * Determines whether the response to a given servlet request should or
      * should not be GZIP compressed. This method is only called in cases where
      * the requestor accepts GZIP encoding.
      * <p>
      * This implementation currently returns <code>true</code> if the response
      * string's estimated byte length is longer than 256 bytes. Subclasses can
      * override this logic.
      * </p>
      * 
      * @param request
      *           the request being served
      * @param response
      *           the response that will be written into
      * @param responsePayload
      *           the payload that is about to be sent to the client
      * @return <code>true</code> if responsePayload should be GZIP compressed,
      *         otherwise <code>false</code>.
      */
     protected boolean shouldCompressResponse(HttpServletRequest request,
           HttpServletResponse response, String responsePayload)
     {
        return estimateByteSize(responsePayload) > UNCOMPRESSED_BYTE_SIZE_LIMIT;
     }
  
     /**
      * Returns the {@link Class} instance for the named class.
      * 
      * @param name
      *           the name of a class or primitive type
      * @return Class instance for the given type name
      * @throws ClassNotFoundException
      *            if the named type was not found
      */
     private Class getClassFromName(String name) throws ClassNotFoundException
     {
        return Class.forName(name, false, this.getClass().getClassLoader());
     }
  
     /**
      * Returns the {@link Class} instance for the named class or primitive type.
      * 
      * @param name
      *           the name of a class or primitive type
      * @return Class instance for the given type name
      * @throws ClassNotFoundException
      *            if the named type was not found
      */
     private Class getClassOrPrimitiveFromName(String name)
           throws ClassNotFoundException
     {
        Object value = TYPE_NAMES.get(name);
        if (value != null)
        {
           return (Class) value;
        }
  
        return getClassFromName(name);
     }
  
     /**
      * Obtain the special package-prefixes we use to check for custom serializers
      * that would like to live in a package that they cannot. For example,
      * "java.util.ArrayList" is in a sealed package, so instead we use this
      * prefix to check for a custom serializer in
      * "com.google.gwt.user.client.rpc.core.java.util.ArrayList". Right now, it's
      * hard-coded because we don't have a pressing need for this mechanism to be
      * extensible, but it is imaginable, which is why it's implemented this way.
      */
     protected String[] getPackagePaths()
     {
        return new String[] { "com.google.gwt.user.client.rpc.core" };
     }
  
     private String readPayloadAsUtf8(HttpServletRequest request)
           throws IOException, ServletException
     {
        int contentLength = request.getContentLength();
        if (contentLength == -1)
        {
           // Content length must be known.
           throw new ServletException("Content-Length must be specified");
        }
  
        String contentType = request.getContentType();
        boolean contentTypeIsOkay = false;
        // Content-Type must be specified.
        if (contentType != null)
        {
           // The type must be plain text.
           if (contentType.startsWith("text/plain"))
           {
              // And it must be UTF-8 encoded (or unspecified, in which case we
              // assume that it's either UTF-8 or ASCII).
              if (contentType.indexOf("charset=") == -1)
              {
                 contentTypeIsOkay = true;
              } else if (contentType.indexOf("charset=utf-8") != -1)
              {
                 contentTypeIsOkay = true;
              }
           }
        }
        if (!contentTypeIsOkay)
        {
           throw new ServletException(
                 "Content-Type must be 'text/plain' with 'charset=utf-8' (or unspecified charset)");
        }
        InputStream in = request.getInputStream();
        try
        {
           byte[] payload = new byte[contentLength];
           int offset = 0;
           int len = contentLength;
           int byteCount;
           while (offset < contentLength)
           {
              byteCount = in.read(payload, offset, len);
              if (byteCount == -1)
              {
                 throw new ServletException("Client did not send "
                       + contentLength + " bytes as expected");
              }
              offset += byteCount;
              len -= byteCount;
           }
           return new String(payload, "UTF-8");
        } finally
        {
           if (in != null)
           {
              in.close();
           }
        }
     }
  
     /**
      * Called when the machinery of this class itself has a problem, rather than
      * the invoked third-party method. It writes a simple 500 message back to the
      * client.
      */
     private void respondWithFailure(HttpServletResponse response,
           Throwable caught)
     {
        ServletContext servletContext = getServletContext();
        servletContext.log("Exception while dispatching incoming RPC call",
              caught);
        try
        {
           response.setContentType("text/plain");
           response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
           response.getWriter().write(GENERIC_FAILURE_MSG);
        } catch (IOException e)
        {
           servletContext
                 .log(
                       "sendError() failed while sending the previous failure to the client",
                       caught);
        }
     }
  
     private void writeResponse(HttpServletRequest request,
           HttpServletResponse response, String responsePayload)
           throws IOException
     {
  
        byte[] reply = responsePayload.getBytes(CHARSET_UTF8);
        String contentType = CONTENT_TYPE_TEXT_PLAIN_UTF8;
  
        if (acceptsGzipEncoding(request)
              && shouldCompressResponse(request, response, responsePayload))
        {
           // Compress the reply and adjust headers.
           //
           ByteArrayOutputStream output = null;
           GZIPOutputStream gzipOutputStream = null;
           Throwable caught = null;
           try
           {
              output = new ByteArrayOutputStream(reply.length);
              gzipOutputStream = new GZIPOutputStream(output);
              gzipOutputStream.write(reply);
              gzipOutputStream.finish();
              gzipOutputStream.flush();
              response.setHeader(CONTENT_ENCODING, CONTENT_ENCODING_GZIP);
              reply = output.toByteArray();
           } catch (UnsupportedEncodingException e)
           {
              caught = e;
           } catch (IOException e)
           {
              caught = e;
           } finally
           {
              if (null != gzipOutputStream)
              {
                 gzipOutputStream.close();
              }
              if (null != output)
              {
                 output.close();
              }
           }
  
           if (caught != null)
           {
              getServletContext().log("Unable to compress response", caught);
              response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
              return;
           }
        }
  
        // Send the reply.
        //
        response.setContentLength(reply.length);
        response.setContentType(contentType);
        response.setStatus(HttpServletResponse.SC_OK);
        response.getOutputStream().write(reply);
     }
  
  }
  
  
  



More information about the jboss-cvs-commits mailing list