[JBoss JIRA] Created: (SEAMFACES-24) Provide convenience classes for Validators/Converters
by Lincoln Baxter III (JIRA)
Provide convenience classes for Validators/Converters
-----------------------------------------------------
Key: SEAMFACES-24
URL: https://jira.jboss.org/browse/SEAMFACES-24
Project: Seam Faces
Issue Type: Feature Request
Reporter: Lincoln Baxter III
Fix For: 3.0.0.Alpha4
Provide generic abstract classes implementing Validator and Converter, for convenient removal of typecasting. Work will need to be done to figure out how to best handle ClassCastExceptions in the case when the provided value argument is not of the type required.
---------------------------------------------------------------------------------------------------------------------------------------------------
public abstract class Converter<T> implements javax.faces.convert.Converter
{
FacesContext context;
public abstract T toObject(UIComponent comp, String value);
public abstract String toString(UIComponent comp, T value);
@Override
public Object getAsObject(final FacesContext context, final UIComponent comp, final String value)
{
this.context = context;
return toObject(comp, value);
}
@Override
@SuppressWarnings("unchecked")
public String getAsString(final FacesContext context, final UIComponent comp, final Object value)
{
this.context = context;
return toString(comp, (T) value);
}
public FacesContext getContext()
{
return context;
}
}
---------------------------------------------------------------------------------------------------------------------------------------------------
public abstract class Validator<T> implements javax.faces.validator.Validator
{
FacesContext context;
public abstract void validate(UIComponent component, T value) throws ValidatorException;
@Override
@SuppressWarnings("unchecked")
public void validate(final FacesContext context, final UIComponent component, final Object value) throws javax.faces.validator.ValidatorException
{
this.context = context;
validate(component, (T) value);
}
public FacesContext getContext()
{
return context;
}
}
---------------------------------------------------------------------------------------------------------------------------------------------------
Provide extension of ValidatorException to remove need for creating new FacesMessage objects when throwing ValidatorExceptions from Validators.
public class ValidatorException extends javax.faces.validator.ValidatorException
{
public ValidatorException(final String message)
{
super(new FacesMessage(message));
}
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
13 years, 9 months
[jbossseam-issues] [JBoss JIRA] Created: (JBSEAM-3924) This patch adds full integration of seam with gwt 1.5.
by Nicolae Tabusca (JIRA)
This patch adds full integration of seam with gwt 1.5.
------------------------------------------------------
Key: JBSEAM-3924
URL: https://jira.jboss.org/jira/browse/JBSEAM-3924
Project: Seam
Issue Type: Patch
Components: GWT
Affects Versions: 2.1.1.GA
Environment: Any
Reporter: Nicolae Tabusca
Priority: Critical
Fix For: 2.1.2.GA
### Eclipse Workspace Patch 1.0
#P jboss-seam
Index: src/remoting/org/jboss/seam/remoting/gwt/GWTService.java
===================================================================
--- src/remoting/org/jboss/seam/remoting/gwt/GWTService.java (revision 9989)
+++ src/remoting/org/jboss/seam/remoting/gwt/GWTService.java (working copy)
@@ -1,976 +1,178 @@
package org.jboss.seam.remoting.gwt;
+import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.text.ParseException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.jboss.seam.core.ConversationPropagation;
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.annotations.remoting.WebRemote;
+import org.jboss.seam.contexts.ServletLifecycle;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
import org.jboss.seam.servlet.ContextualHttpServletRequest;
+import org.jboss.seam.util.EJB;
import org.jboss.seam.web.AbstractResource;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
-import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RPC;
import com.google.gwt.user.server.rpc.RPCRequest;
-import com.google.gwt.user.server.rpc.RPCServletUtils;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
-import com.google.gwt.user.server.rpc.SerializationPolicy;
-import com.google.gwt.user.server.rpc.SerializationPolicyLoader;
-import com.google.gwt.user.server.rpc.SerializationPolicyProvider;
-import com.google.gwt.user.server.rpc.UnexpectedException;
import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader;
-import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter;
/**
- * Abstract base class for GWT 1.5 integration.
+ * GWT integration.
*
- * @author Shane Bryzak
+ * @author Nicolae Tabusca
*/
-public abstract class GWTService extends AbstractResource implements SerializationPolicyProvider
-{
- protected static final LogProvider log = Logging.getLogProvider(GWTService.class);
+@Scope(APPLICATION)
+@Name("org.jboss.seam.remoting.gwt.gwtRemoteService")
+@Install(precedence = BUILT_IN, classDependencies = {"com.google.gwt.user.client.rpc.RemoteService"})
+@BypassInterceptors
+public class GWTService extends AbstractResource {
+
+ protected static final LogProvider log
+ = Logging.getLogProvider(GWTService.class);
- private static final HashMap<String, Class<?>> TYPE_NAMES;
+ public GWTService() {
+ }
- static
- {
- TYPE_NAMES = new HashMap<String, Class<?>>();
- 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";
+ }
- }
-
- /**
- * A cache of moduleBaseURL and serialization policy strong name to
- * {@link SerializationPolicy}.
- */
- private final Map<String, SerializationPolicy> serializationPolicyCache = new HashMap<String, SerializationPolicy>();
+ /**
+ * This is called internally.
+ *
+ * @see RemoteServiceServlet#doPost
+ */
+ @Override
+ public final void getResource(final HttpServletRequest request,
+ final HttpServletResponse response)
+ throws ServletException, IOException {
- @Override
- public String getResourcePath()
- {
- return "/gwt";
- }
+ ContextualHttpServletRequest contextualRequest
+ = new ContextualHttpServletRequest(request) {
- protected abstract ServerSerializationStreamReader getStreamReader();
+ private GWTController controller = new GWTController();
- protected abstract ServerSerializationStreamWriter getStreamWriter();
-
- protected abstract String createResponse(
- ServerSerializationStreamWriter stream, Class responseType,
- Object responseObj, boolean isException);
-
- // private final Set knownImplementedInterfaces = new HashSet();
- private final ThreadLocal<HttpServletRequest> perThreadRequest = new ThreadLocal<HttpServletRequest>();
-
- private final ThreadLocal<HttpServletResponse> perThreadResponse = new ThreadLocal<HttpServletResponse>();
-
- /**
- * This is called internally.
- *
- * @see RemoteServiceServlet#doPost
- */
- @Override
- public final void getResource(final HttpServletRequest request,
- final HttpServletResponse response) throws ServletException,
- IOException
- {
- 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
- {
-
- try
- {
- // Read the request fully.
- //
- String requestPayload = RemoteServiceServlet_readContent(request);
-
- RemoteServiceServlet_onBeforeRequestDeserialized(requestPayload);
-
- // Invoke the core dispatching logic, which returns the
- // serialized result
- String responsePayload = processCall(requestPayload);
-
- RemoteServiceServlet_onAfterResponseSerialized(responsePayload);
-
- // Write the response.
- //
- RemoteServiceServlet_writeResponse(request, response,
- responsePayload);
-
- } catch (Throwable e)
- {
- RemoteServiceServlet_doUnexpectedFailure(e);
- }
-
+ public void process() throws Exception {
+
+ controller.service(request, response);
}
+ };
- @Override
- protected void restoreConversationId()
- {
- ConversationPropagation.instance().setConversationId(
- GWTService.this.perThreadRequest.get().getParameter(
- "conversationId"));
- }
+ contextualRequest.run();
- @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
- {
- // 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]);
- // }
+ @SuppressWarnings("serial")
+ private class GWTController extends RemoteServiceServlet {
- try
- {
- SeamRPCRequest rpcRequest = RPC_decodeRequest(payload,
- this.getClass(), this);
+ @Override
+ public ServletContext getServletContext() {
+ return ServletLifecycle.getServletContext();
+ }
+
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public String processCall(String payload) throws SerializationException {
+ try {
+ Component remoteService = getRemoteServiceComponent(payload);
+
+ Class beanClass = remoteService.getBeanClass();
+ RPCRequest rpcRequest = RPC.decodeRequest(payload, beanClass, this);
- return RPC_invokeAndEncodeResponse(this, rpcRequest.getMethod(),
- rpcRequest.getParameterTypes(), rpcRequest.getParameters(),
- rpcRequest.getSerializationPolicy());
- } catch (IncompatibleRemoteServiceException ex)
- {
- getServletContext()
- .log(
- "An IncompatibleRemoteServiceException was thrown while processing this call.",
- ex);
- return RPC.encodeResponseForFailure(null, ex);
- }
+ Method serviceDef = rpcRequest.getMethod();
+ Method serviceImpl = beanClass.getMethod(serviceDef.getName(),
+ serviceDef.getParameterTypes());
+ if (isWebRemoteAnnotated(serviceImpl) == false) {
+ throw new RuntimeException(
+ "Unable to access a service method called ["
+ + serviceImpl.getName() + "] on class ["
+ + beanClass.getName()
+ + "] without the @WebRemote attribute. ");
+ }
- // Make the call via reflection.
- //
- // String responsePayload = GENERIC_FAILURE_MSG;
- // ServerSerializationStreamWriter streamWriter = getStreamWriter();
- // Throwable caught = null;
- // try
- // {
- // GWTToSeamAdapter.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);
- // }
- // }
- }
+ return RPC.invokeAndEncodeResponse(
+ Component.getInstance(remoteService.getName()),
+ rpcRequest.getMethod(), rpcRequest.getParameters(),
+ rpcRequest.getSerializationPolicy());
- /**
- * 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 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 perThreadResponse.get();
- }
-
- /**
- * Returns an {@link RPCRequest} that is built by decoding the contents of an
- * encoded RPC request and optionally validating that type can handle the
- * request. If the type parameter is not <code>null</code>, the
- * implementation checks that the type is assignable to the
- * {@link com.google.gwt.user.client.rpc.RemoteService} interface requested
- * in the encoded request string.
- *
- * <p>
- * If the serializationPolicyProvider parameter is not <code>null</code>, it
- * is asked for a {@link SerializationPolicy} to use to restrict the set of
- * types that can be decoded from the request. If this parameter is
- * <code>null</code>, then only subtypes of
- * {@link com.google.gwt.user.client.rpc.IsSerializable IsSerializable} or
- * types which have custom field serializers can be decoded.
- * </p>
- *
- * <p>
- * Invoking this method with <code>null</code> for the type parameter,
- * <code>decodeRequest(encodedRequest, null)</code>, is equivalent to calling
- * <code>decodeRequest(encodedRequest)</code>.
- * </p>
- *
- * @param encodedRequest
- * a string that encodes the
- * {@link com.google.gwt.user.client.rpc.RemoteService} interface,
- * the service method, and the arguments to pass to the service
- * method
- * @param type
- * if not <code>null</code>, the implementation checks that the
- * type is assignable to the
- * {@link com.google.gwt.user.client.rpc.RemoteService} interface
- * encoded in the encoded request string.
- * @param serializationPolicyProvider
- * if not <code>null</code>, the implementation asks this provider
- * for a {@link SerializationPolicy} which will be used to restrict
- * the set of types that can be decoded from this request
- * @return an {@link RPCRequest} instance
- *
- * @throws NullPointerException
- * if the encodedRequest is <code>null</code>
- * @throws IllegalArgumentException
- * if the encodedRequest is an empty string
- * @throws IncompatibleRemoteServiceException
- * if any of the following conditions apply:
- * <ul>
- * <li>if the types in the encoded request cannot be deserialized</li>
- * <li>if the {@link ClassLoader} acquired from
- * <code>Thread.currentThread().getContextClassLoader()</code>
- * cannot load the service interface or any of the types specified
- * in the encodedRequest</li>
- * <li>the requested interface is not assignable to
- * {@link com.google.gwt.user.client.rpc.RemoteService}</li>
- * <li>the service method requested in the encodedRequest is not a
- * member of the requested service interface</li>
- * <li>the type parameter is not <code>null</code> and is not
- * assignable to the requested
- * {@link com.google.gwt.user.client.rpc.RemoteService} interface
- * </ul>
- */
- public static SeamRPCRequest RPC_decodeRequest(String encodedRequest,
- Class<?> type, SerializationPolicyProvider serializationPolicyProvider)
- {
- if (encodedRequest == null)
- {
- throw new NullPointerException("encodedRequest cannot be null");
- }
-
- if (encodedRequest.length() == 0)
- {
- throw new IllegalArgumentException("encodedRequest cannot be empty");
- }
-
- ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-
- try
- {
- ServerSerializationStreamReader streamReader = new ServerSerializationStreamReader(
- classLoader, serializationPolicyProvider);
- streamReader.prepareToRead(encodedRequest);
-
- // Read the name of the RemoteService interface
- String serviceIntfName = streamReader.readString();
-
- /*
- * todo?? if (type != null) { if (!implementsInterface(type,
- * serviceIntfName)) { // The service does not implement the requested
- * interface throw new IncompatibleRemoteServiceException(
- * "Blocked attempt to access interface '" + serviceIntfName +
- * "', which is not implemented by '" + printTypeName(type) +
- * "'; this is either misconfiguration or a hack attempt"); } }
- */
-
- SerializationPolicy serializationPolicy = streamReader
- .getSerializationPolicy();
- Class<?> serviceIntf;
- try
- {
- serviceIntf = RPC_getClassFromSerializedName(serviceIntfName,
- classLoader);
- if (!RemoteService.class.isAssignableFrom(serviceIntf))
- {
- // The requested interface is not a RemoteService interface
- throw new IncompatibleRemoteServiceException(
- "Blocked attempt to access interface '"
- + printTypeName(serviceIntf)
- + "', which doesn't extend RemoteService; this is either misconfiguration or a hack attempt");
+ } catch (IncompatibleRemoteServiceException ex) {
+ log.error(ex.getMessage(), ex);
+ return RPC.encodeResponseForFailure(null, ex);
+ } catch (SecurityException e) {
+ log.error(e.getMessage(), e);
+ return RPC.encodeResponseForFailure(null, e);
+ } catch (NoSuchMethodException e) {
+ log.error(e.getMessage(), e);
+ return RPC.encodeResponseForFailure(null, e);
}
- } catch (ClassNotFoundException e)
- {
- throw new IncompatibleRemoteServiceException(
- "Could not locate requested interface '" + serviceIntfName
- + "' in default classloader", e);
- }
+ }
- String serviceMethodName = streamReader.readString();
+ @SuppressWarnings("unchecked")
+ private Component getRemoteServiceComponent(String payload)
+ throws SerializationException {
- int paramCount = streamReader.readInt();
- Class<?>[] parameterTypes = new Class[paramCount];
+ ClassLoader classLoader = Thread.currentThread()
+ .getContextClassLoader();
+ ServerSerializationStreamReader streamReader
+ = new ServerSerializationStreamReader(classLoader, this);
- for (int i = 0; i < parameterTypes.length; i++)
- {
- String paramClassName = streamReader.readString();
- try
- {
- parameterTypes[i] = RPC_getClassFromSerializedName(
- paramClassName, classLoader);
- } catch (ClassNotFoundException e)
- {
- throw new IncompatibleRemoteServiceException("Parameter " + i
- + " of is of an unknown type '" + paramClassName + "'", e);
- }
- }
+ streamReader.prepareToRead(payload);
- try
- {
- Method method = serviceIntf.getMethod(serviceMethodName,
- parameterTypes);
+ // Read the name of the RemoteService interface
+ String serviceIntfName = streamReader.readString();
- Object[] parameterValues = new Object[parameterTypes.length];
- for (int i = 0; i < parameterValues.length; i++)
- {
- parameterValues[i] = streamReader
- .deserializeValue(parameterTypes[i]);
+ Component component = Component.forName(serviceIntfName);
+ if (null == component) {
+ throw new RuntimeException("No such component: "
+ + serviceIntfName);
}
- return new SeamRPCRequest(method, parameterValues, parameterTypes,
- serializationPolicy);
+ if (component.getType().isSessionBean()
+ && component.getBusinessInterfaces().size() > 0) {
- } catch (NoSuchMethodException e)
- {
- throw new IncompatibleRemoteServiceException(
- formatMethodNotFoundErrorMessage(serviceIntf,
- serviceMethodName, parameterTypes));
- }
- } catch (SerializationException ex)
- {
- throw new IncompatibleRemoteServiceException(ex.getMessage(), ex);
- }
- }
+ boolean localDefined = false;
+ for (Class c : component.getBusinessInterfaces()) {
+ if (c.isAnnotationPresent(EJB.LOCAL)) {
+ localDefined = true;
+ break;
+ }
+ }
- /**
- * Returns the {@link Class} instance for the named class or primitive type.
- *
- * @param serializedName
- * the serialized name of a class or primitive type
- * @param classLoader
- * the classLoader used to load {@link Class}es
- * @return Class instance for the given type name
- * @throws ClassNotFoundException
- * if the named type was not found
- */
- private static Class<?> RPC_getClassFromSerializedName(
- String serializedName, ClassLoader classLoader)
- throws ClassNotFoundException
- {
- Class<?> value = TYPE_NAMES.get(serializedName);
- if (value != null)
- {
- return value;
- }
-
- return Class.forName(serializedName, false, classLoader);
- }
-
- /**
- * Returns a string that encodes the result of calling a service method,
- * which could be the value returned by the method or an exception thrown by
- * it.
- *
- * <p>
- * If the serializationPolicy parameter is not <code>null</code>, it is used
- * to determine what types can be encoded as part of this response. If this
- * parameter is <code>null</code>, then only subtypes of
- * {@link com.google.gwt.user.client.rpc.IsSerializable IsSerializable} or
- * types which have custom field serializers may be encoded.
- * </p>
- *
- * <p>
- * This method does no security checking; security checking must be done on
- * the method prior to this invocation.
- * </p>
- *
- * @param target
- * instance on which to invoke the serviceMethod
- * @param serviceMethod
- * the method to invoke
- * @param args
- * arguments used for the method invocation
- * @param serializationPolicy
- * determines the serialization policy to be used
- * @return a string which encodes either the method's return or a checked
- * exception thrown by the method
- *
- * @throws NullPointerException
- * if the serviceMethod or the serializationPolicy are
- * <code>null</code>
- * @throws SecurityException
- * if the method cannot be accessed or if the number or type of
- * actual and formal arguments differ
- * @throws SerializationException
- * if an object could not be serialized by the stream
- * @throws UnexpectedException
- * if the serviceMethod throws a checked exception that is not
- * declared in its signature
- */
- public static String RPC_invokeAndEncodeResponse(Object target,
- Method serviceMethod, Class[] paramTypes, Object[] args,
- SerializationPolicy serializationPolicy) throws SerializationException
- {
- if (serviceMethod == null)
- {
- throw new NullPointerException("serviceMethod");
- }
-
- if (serializationPolicy == null)
- {
- throw new NullPointerException("serializationPolicy");
- }
-
- String responsePayload;
- try
- {
- GWTToSeamAdapter adapter = GWTToSeamAdapter.instance();
-
- String serviceIntfName = serviceMethod.getDeclaringClass().getName();
-
- GWTToSeamAdapter.ReturnedObject returnedObject = adapter
- .callWebRemoteMethod(serviceIntfName, serviceMethod.getName(),
- paramTypes, args);
-
- // Object result = serviceMethod.invoke(target, args);
-
- responsePayload = RPC.encodeResponseForSuccess(serviceMethod,
- returnedObject.returnedObject, serializationPolicy);
- } catch (IllegalAccessException e)
- {
- SecurityException securityException = new SecurityException(
- formatIllegalAccessErrorMessage(target, serviceMethod));
- securityException.initCause(e);
- throw securityException;
- } catch (IllegalArgumentException e)
- {
- SecurityException securityException = new SecurityException(
- formatIllegalArgumentErrorMessage(target, serviceMethod, args));
- securityException.initCause(e);
- throw securityException;
- } catch (InvocationTargetException e)
- {
- // Try to encode the caught exception
- //
- Throwable cause = e.getCause();
-
- responsePayload = RPC.encodeResponseForFailure(serviceMethod, cause,
- serializationPolicy);
- }
-
- return responsePayload;
- }
-
- /**
- * 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 RemoteServiceServlet_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 RemoteServiceServlet_onBeforeRequestDeserialized(
- String serializedRequest)
- {
- }
-
- /**
- * Override this method in order to control the parsing of the incoming
- * request. For example, you may want to bypass the check of the Content-Type
- * and character encoding headers in the request, as some proxies re-write
- * the request headers. Note that bypassing these checks may expose the
- * servlet to some cross-site vulnerabilities.
- *
- * @param request
- * the incoming request
- * @return the content of the incoming request encoded as a string.
- */
- protected String RemoteServiceServlet_readContent(HttpServletRequest request)
- throws ServletException, IOException
- {
- return RPCServletUtils.readContentAsUtf8(request, true);
- }
-
- public final SerializationPolicy getSerializationPolicy(
- String moduleBaseURL, String strongName)
- {
-
- SerializationPolicy serializationPolicy = getCachedSerializationPolicy(
- moduleBaseURL, strongName);
- if (serializationPolicy != null)
- {
- return serializationPolicy;
- }
-
- serializationPolicy = doGetSerializationPolicy(getThreadLocalRequest(),
- moduleBaseURL, strongName);
-
- if (serializationPolicy == null)
- {
- // Failed to get the requested serialization policy; use the default
- getServletContext()
- .log(
- "WARNING: Failed to get the SerializationPolicy '"
- + strongName
- + "' for module '"
- + moduleBaseURL
- + "'; a legacy, 1.3.3 compatible, serialization policy will be used. You may experience SerializationExceptions as a result.");
- serializationPolicy = RPC.getDefaultSerializationPolicy();
- }
-
- // This could cache null or an actual instance. Either way we will not
- // attempt to lookup the policy again.
- putCachedSerializationPolicy(moduleBaseURL, strongName,
- serializationPolicy);
-
- return serializationPolicy;
- }
-
- private SerializationPolicy getCachedSerializationPolicy(
- String moduleBaseURL, String strongName)
- {
- synchronized (serializationPolicyCache)
- {
- return serializationPolicyCache.get(moduleBaseURL + strongName);
- }
- }
-
- private void putCachedSerializationPolicy(String moduleBaseURL,
- String strongName, SerializationPolicy serializationPolicy)
- {
- synchronized (serializationPolicyCache)
- {
- serializationPolicyCache.put(moduleBaseURL + strongName,
- serializationPolicy);
- }
- }
-
- /**
- * Gets the {@link SerializationPolicy} for given module base URL and strong
- * name if there is one.
- *
- * Override this method to provide a {@link SerializationPolicy} using an
- * alternative approach.
- *
- * @param request
- * the HTTP request being serviced
- * @param moduleBaseURL
- * as specified in the incoming payload
- * @param strongName
- * a strong name that uniquely identifies a serialization policy
- * file
- * @return a {@link SerializationPolicy} for the given module base URL and
- * strong name, or <code>null</code> if there is none
- */
- protected SerializationPolicy doGetSerializationPolicy(
- HttpServletRequest request, String moduleBaseURL, String strongName)
- {
- // The request can tell you the path of the web app relative to the
- // container root.
- String contextPath = request.getContextPath();
-
- String modulePath = null;
- if (moduleBaseURL != null)
- {
- try
- {
- modulePath = new URL(moduleBaseURL).getPath();
- } catch (MalformedURLException ex)
- {
- // log the information, we will default
- getServletContext().log(
- "Malformed moduleBaseURL: " + moduleBaseURL, ex);
- }
- }
-
- SerializationPolicy serializationPolicy = null;
-
- /*
- * Check that the module path must be in the same web app as the servlet
- * itself. If you need to implement a scheme different than this, override
- * this method.
- */
- if (modulePath == null || !modulePath.startsWith(contextPath))
- {
- String message = "ERROR: The module path requested, "
- + modulePath
- + ", is not in the same web application as this servlet, "
- + contextPath
- + ". Your module may not be properly configured or your client and server code maybe out of date.";
- getServletContext().log(message);
- } else
- {
- // Strip off the context path from the module base URL. It should be a
- // strict prefix.
- String contextRelativePath = modulePath
- .substring(contextPath.length());
-
- String serializationPolicyFilePath = SerializationPolicyLoader
- .getSerializationPolicyFileName(contextRelativePath + strongName);
-
- // Open the RPC resource file read its contents.
- InputStream is = getServletContext().getResourceAsStream(
- serializationPolicyFilePath);
- try
- {
- if (is != null)
- {
- try
- {
- serializationPolicy = SerializationPolicyLoader
- .loadFromStream(is, null);
- } catch (ParseException e)
- {
- getServletContext().log(
- "ERROR: Failed to parse the policy file '"
- + serializationPolicyFilePath + "'", e);
- } catch (IOException e)
- {
- getServletContext().log(
- "ERROR: Could not read the policy file '"
- + serializationPolicyFilePath + "'", e);
- }
- } else
- {
- String message = "ERROR: The serialization policy file '"
- + serializationPolicyFilePath
- + "' was not found; did you forget to include it in this deployment?";
- getServletContext().log(message);
+ if (localDefined == false) {
+ throw new RuntimeException(
+ String.format("Type cannot be determined for component [%s]. Please ensure that it has a local interface.",
+ component));
+ }
}
- } finally
- {
- if (is != null)
- {
- try
- {
- is.close();
- } catch (IOException e)
- {
- // Ignore this error
- }
- }
- }
- }
+
+ return component;
+ }
- return serializationPolicy;
- }
-
- private void RemoteServiceServlet_writeResponse(HttpServletRequest request,
- HttpServletResponse response, String responsePayload)
- throws IOException
- {
- boolean gzipEncode = RPCServletUtils.acceptsGzipEncoding(request)
- && shouldCompressResponse(request, response, responsePayload);
-
- RPCServletUtils.writeResponse(getServletContext(), response,
- responsePayload, gzipEncode);
- }
-
- /**
- * Override this method to control what should happen when an exception
- * escapes the {@link #processCall(String)} method. The default
- * implementation will log the failure and send a generic failure response to
- * the client.
- * <p/>
- *
- * An "expected failure" is an exception thrown by a service method that is
- * declared in the signature of the service method. These exceptions are
- * serialized back to the client, and are not passed to this method. This
- * method is called only for exceptions or errors that are not part of the
- * service method's signature, or that result from SecurityExceptions,
- * SerializationExceptions, or other failures within the RPC framework.
- * <p/>
- *
- * Note that if the desired behavior is to both send the GENERIC_FAILURE_MSG
- * response AND to rethrow the exception, then this method should first send
- * the GENERIC_FAILURE_MSG response itself (using getThreadLocalResponse),
- * and then rethrow the exception. Rethrowing the exception will cause it to
- * escape into the servlet container.
- *
- * @param e
- * the exception which was thrown
- */
- protected void RemoteServiceServlet_doUnexpectedFailure(Throwable e)
- {
- ServletContext servletContext = getServletContext();
- RPCServletUtils.writeResponseForUnexpectedFailure(servletContext,
- getThreadLocalResponse(), e);
- }
-
- /**
- * 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 requester 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 RPCServletUtils
- .exceedsUncompressedContentLengthLimit(responsePayload);
- }
-
- private static String formatMethodNotFoundErrorMessage(Class<?> serviceIntf,
- String serviceMethodName, Class<?>[] parameterTypes)
- {
- StringBuffer sb = new StringBuffer();
-
- sb.append("Could not locate requested method '");
- sb.append(serviceMethodName);
- sb.append("(");
- for (int i = 0; i < parameterTypes.length; ++i)
- {
- if (i > 0)
- {
- sb.append(", ");
- }
- sb.append(printTypeName(parameterTypes[i]));
- }
- sb.append(")'");
-
- sb.append(" in interface '");
- sb.append(printTypeName(serviceIntf));
- sb.append("'");
-
- return sb.toString();
- }
-
- private static String formatIllegalAccessErrorMessage(Object target,
- Method serviceMethod)
- {
- StringBuffer sb = new StringBuffer();
- sb.append("Blocked attempt to access inaccessible method '");
- sb.append(getSourceRepresentation(serviceMethod));
- sb.append("'");
-
- if (target != null)
- {
- sb.append(" on target '");
- sb.append(printTypeName(target.getClass()));
- sb.append("'");
- }
-
- sb.append("; this is either misconfiguration or a hack attempt");
-
- return sb.toString();
- }
-
- private static String formatIllegalArgumentErrorMessage(Object target,
- Method serviceMethod, Object[] args)
- {
- StringBuffer sb = new StringBuffer();
- sb.append("Blocked attempt to invoke method '");
- sb.append(getSourceRepresentation(serviceMethod));
- sb.append("'");
-
- if (target != null)
- {
- sb.append(" on target '");
- sb.append(printTypeName(target.getClass()));
- sb.append("'");
- }
-
- sb.append(" with invalid arguments");
-
- if (args != null && args.length > 0)
- {
- sb.append(Arrays.asList(args));
- }
-
- return sb.toString();
- }
-
- /**
- * Returns the source representation for a method signature.
- *
- * @param method
- * method to get the source signature for
- * @return source representation for a method signature
- */
- private static String getSourceRepresentation(Method method)
- {
- return method.toString().replace('$', '.');
- }
-
- /**
- * Straight copy from
- * {@link com.google.gwt.dev.util.TypeInfo#getSourceRepresentation(Class)} to
- * avoid runtime dependency on gwt-dev.
- */
- private static String printTypeName(Class<?> type)
- {
- // Primitives
- //
- if (type.equals(Integer.TYPE))
- {
- return "int";
- } else if (type.equals(Long.TYPE))
- {
- return "long";
- } else if (type.equals(Short.TYPE))
- {
- return "short";
- } else if (type.equals(Byte.TYPE))
- {
- return "byte";
- } else if (type.equals(Character.TYPE))
- {
- return "char";
- } else if (type.equals(Boolean.TYPE))
- {
- return "boolean";
- } else if (type.equals(Float.TYPE))
- {
- return "float";
- } else if (type.equals(Double.TYPE))
- {
- return "double";
- }
-
- // Arrays
- //
- if (type.isArray())
- {
- Class<?> componentType = type.getComponentType();
- return printTypeName(componentType) + "[]";
- }
-
- // Everything else
- //
- return type.getName().replace('$', '.');
- }
-
-}
+ /**
+ * Only allow methods annotated with @WebRemote for security reasons.
+ */
+ private boolean isWebRemoteAnnotated(Method method) {
+ if (method == null)
+ return false;
+ return method.getAnnotation(WebRemote.class) != null;
+ }
+ }
+}
\ No newline at end of file
Index: src/remoting/org/jboss/seam/remoting/gwt/GWTToSeamAdapter.java
===================================================================
--- src/remoting/org/jboss/seam/remoting/gwt/GWTToSeamAdapter.java (revision 9989)
+++ src/remoting/org/jboss/seam/remoting/gwt/GWTToSeamAdapter.java (working copy)
@@ -1,210 +0,0 @@
-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.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.intercept.BypassInterceptors;
-import org.jboss.seam.annotations.remoting.WebRemote;
-import org.jboss.seam.util.EJB;
-
-/**
- * This class adapts GWT RPC mechanism to Seam actions.
- *
- * @author Michael Neale
- */
-@Scope(APPLICATION)
-@Name("org.jboss.seam.remoting.gwt.gwtToSeamAdapter")
-@BypassInterceptors
-@Install(precedence=BUILT_IN)
-public class GWTToSeamAdapter {
-
- /** A very simple cache of previously looked up methods */
- private final Map METHOD_CACHE = new HashMap();
-
- public static GWTToSeamAdapter instance()
- {
- GWTToSeamAdapter adapter = (GWTToSeamAdapter) Component.getInstance(GWTToSeamAdapter.class);
-
- if (adapter == null)
- {
- throw new IllegalStateException("No GWTToSeamAdapter exists");
- }
-
- return adapter;
- }
-
- /**
- * Call the service.
- *
- * @param serviceIntfName
- * The interface name - this will be the fully qualified name of
- * the remote service interface as understood by GWT. This
- * correlates to a component name in seam.
- * @param methodName
- * The method name of the service being invoked.
- * @param paramTypes
- * The types of parameters - needed for method lookup for
- * polymorphism.
- * @param args
- * The values to be passed to the service method.
- * @return A populated ReturnedObject - the returned object payload may be
- * null, but the type will not be.
- * @throws InvocationTargetException
- * @throws IllegalAccessException
- */
- public ReturnedObject callWebRemoteMethod(String serviceIntfName,
- String methodName, Class[] paramTypes, Object[] args)
- throws InvocationTargetException, IllegalAccessException,
- SecurityException {
-
- // Find the component we're calling
- Component component = Component.forName(serviceIntfName);
-
- if (component == null)
- throw new RuntimeException("No such component: " + serviceIntfName);
-
- Object instance = getServiceComponent(serviceIntfName);
- Class clz = null;
-
- if (component.getType().isSessionBean()
- && component.getBusinessInterfaces().size() > 0) {
- for (Class c : component.getBusinessInterfaces()) {
- if (c.isAnnotationPresent(EJB.LOCAL)) {
- clz = c;
- break;
- }
- }
-
- if (clz == null)
- throw new RuntimeException(
- String
- .format(
- "Type cannot be determined for component [%s]. Please ensure that it has a local interface.",
- component));
- }
-
- if (clz == null)
- clz = component.getBeanClass();
-
- Method method = getMethod(serviceIntfName, methodName, clz, paramTypes);
-
- Object result = method.invoke(instance, args);
- return new ReturnedObject(method.getReturnType(), result);
- }
-
- /**
- * Get the method on the class, including walking up the class heirarchy if
- * needed. Methods have to be marked as "@WebRemote" to be allowed.
- *
- * @param methodName
- * @param clz
- * @param paramTypes
- */
- private Method getMethod(String serviceName, String methodName, Class clz,
- Class[] paramTypes) {
- String key = getKey(serviceName, methodName, paramTypes);
- if (METHOD_CACHE.containsKey(key)) {
- return (Method) METHOD_CACHE.get(key);
- } else {
- try {
- synchronized (METHOD_CACHE) {
- Method m = findMethod(clz, methodName, paramTypes);
- if (m == null)
- throw new NoSuchMethodException();
- METHOD_CACHE.put(key, m);
- return m;
- }
-
- } catch (NoSuchMethodException e) {
- throw new SecurityException(
- "Unable to access a service method called ["
- + methodName
- + "] on class ["
- + clz.getName()
- + "] without the @WebRemote attribute. "
- + "This may be a hack attempt, or someone simply neglected to use the @WebRemote attribute to indicate a method as"
- + " remotely accessible.");
- }
- }
- }
-
- private String getKey(String serviceName, String methodName,
- Class[] paramTypes) {
- if (paramTypes == null) {
- return serviceName + "." + methodName;
- } else {
- String pTypes = "";
- for (int i = 0; i < paramTypes.length; i++) {
- pTypes += paramTypes[i].getName();
- }
- return serviceName + "." + methodName + "(" + pTypes + ")";
- }
-
- }
-
- /**
- * Recurse up the class hierarchy, looking for a compatable method that is
- * marked as "@WebRemote". If one is not found (or we hit Object.class) then
- * we barf - basically trust nothing from the client other then what we want
- * to allow them to call.
- */
- private Method findMethod(Class clz, String methodName, Class[] paramTypes)
- throws NoSuchMethodException {
- if (clz == Object.class) {
- return null;
- } else {
- Method m = clz.getMethod(methodName, paramTypes);
- if (isWebRemoteAnnotated(m)) {
- return m;
- } else {
- return findMethod(clz.getSuperclass(), methodName, paramTypes);
- }
- }
- }
-
- /**
- * Only allow methods annotated with
- *
- * @WebRemote for security reasons.
- */
- private boolean isWebRemoteAnnotated(Method method) {
- if (method == null)
- return false;
- return method.getAnnotation(WebRemote.class) != null;
- }
-
- /**
- * Return the service component that has been bound to the given name.
- */
- protected Object getServiceComponent(String serviceIntfName) {
- return Component.getInstance(serviceIntfName);
- }
-
- /**
- * This is used for returning results to the GWT service endpoint. The class
- * is needed even if the result is null. a void.class responseType is
- * perfectly acceptable.
- *
- * @author Michael Neale
- */
- static class ReturnedObject {
- public ReturnedObject(Class type, Object result) {
- this.returnType = type;
- this.returnedObject = result;
- }
-
- public Class returnType;
-
- public Object returnedObject;
- }
-
-}
Index: src/remoting/org/jboss/seam/remoting/gwt/SeamRPCRequest.java
===================================================================
--- src/remoting/org/jboss/seam/remoting/gwt/SeamRPCRequest.java (revision 9989)
+++ src/remoting/org/jboss/seam/remoting/gwt/SeamRPCRequest.java (working copy)
@@ -1,47 +0,0 @@
-package org.jboss.seam.remoting.gwt;
-
-import com.google.gwt.user.server.rpc.SerializationPolicy;
-
-import java.lang.reflect.Method;
-
-/**
- * @author Tomaz Cerar
- * @version $Revision$
- * @modifiedBy $Author$
- * @modified $Date$
- */
-public class SeamRPCRequest
-{
- private final java.lang.reflect.Method method;
- private final java.lang.Object[] parameters;
- private final Class[] parameterTypes;
- private final com.google.gwt.user.server.rpc.SerializationPolicy serializationPolicy;
-
- public SeamRPCRequest(Method method, Object[] parameters,
- Class[] parameterTypes, SerializationPolicy serializationPolicy) {
- this.method = method;
- this.parameters = parameters;
- this.parameterTypes = parameterTypes;
- this.serializationPolicy = serializationPolicy;
- }
-
- public Method getMethod()
- {
- return method;
- }
-
- public Object[] getParameters()
- {
- return parameters;
- }
-
- public Class[] getParameterTypes()
- {
- return parameterTypes;
- }
-
- public SerializationPolicy getSerializationPolicy()
- {
- return serializationPolicy;
- }
-}
Index: src/remoting/org/jboss/seam/remoting/gwt/GWT14Service.java
===================================================================
--- src/remoting/org/jboss/seam/remoting/gwt/GWT14Service.java (revision 9989)
+++ src/remoting/org/jboss/seam/remoting/gwt/GWT14Service.java (working copy)
@@ -1,113 +0,0 @@
-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.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
- */
-@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
- {
- try
- {
- log.trace("GWT14Service starting up");
-
- Class policyProviderClass = Class.forName(SERIALIZATION_POLICY_PROVIDER_CLASS);
- Class serializationPolicyClass = Class.forName(SERIALIZATION_POLICY_CLASS);
-
- streamReaderConstructor = ServerSerializationStreamReader.class.getConstructor(
- new Class[] { ClassLoader.class, policyProviderClass } );
- streamWriterConstructor = ServerSerializationStreamWriter.class.getConstructor(
- new Class[] { serializationPolicyClass } );
-
- Class legacySerializationPolicyClass = Class.forName(LEGACY_SERIALIZATION_POLICY_CLASS);
- Method m = legacySerializationPolicyClass.getDeclaredMethod("getInstance");
- legacySerializationPolicy = m.invoke(null);
- }
- catch (Exception ex)
- {
- log.error("Error initializing GWT14Service. Please ensure " +
- "the GWT 1.4 libraries are in the classpath.");
- throw 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);
- }
- }
-}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
13 years, 9 months