[jbossseam-issues] [JBoss JIRA] Created: (JBSEAM-2588) s:conversationPropagation breaks a4j:commandButton
by Fijai Cairo (JIRA)
s:conversationPropagation breaks a4j:commandButton
--------------------------------------------------
Key: JBSEAM-2588
URL: http://jira.jboss.com/jira/browse/JBSEAM-2588
Project: JBoss Seam
Issue Type: Bug
Components: JSF Controls
Affects Versions: 2.0.1.GA
Environment: Firefox OSX 10.51, JBoss AS 4.22, JAVA 1.5.0_13-b05-237
Reporter: Fijai Cairo
<a4j:commandButton styleClass="btn" id="contactButton#{accountHolder}" oncomplete="UIControl('contactForm', 'contact', 'identification');" reRender="contactBlock#{accountHolder},uiSec" actionListener="#{accountOpen.submitContactInfo}" value="Continue" >
<a4j:actionparam name="holder" value="getSuffix()" noEscape="true"/>
<s:conversationPropagation type="join" />
</a4j:commandButton>
Renders the following: Notice that the onclick handler is rendered before the input is rendered and causes a document.getElementById("contactButton1") has no properties javascript error.
<div id="contactContinueSection1" style="padding: 10px 10px 10px 10px; display: block">
<script language="JavaScript" type="text/javascript">
//<![CDATA[
document.getElementById('contactButton1').onclick = new Function("event", "{if (document.getElementById){var form = document.getElementById('contactForm1');var input = documen
t.createElement('input');if (document.all){ input.type = 'hidden';input.name = 'conversationPropagat
ion';input.value = 'join';}else if (document.getElementById) {input.setAttribute('type', 'hidden');i
nput.setAttribute('name', 'conversationPropagation');input.setAttribute('value', 'join');}form.appen
dChild(input);return true;}}");
//]]>
</script>
<input id="contactButton1" name="contactButton1" onclick="A4J.AJAX.Submit('_viewRoot','contactForm1',event,{'parameters':{'holder':getSuffix(),'conversationPr
opagation':'join','contactButton1':'contactButton1'} ,'actionUrl':'/BaisiPrototype/AE/primary.jspv?j
avax.portlet.faces.DirectLink=true','oncomplete':function(request,event,data){UIControl('contactForm
', 'contact', 'identification');}} );return false;" value="Continue" class="btn" type="button" />
</div>
Without <s:conversationPropagation type="join" />, the onclick handler is rendered as an attribute of the button as ff:
<div id="contactContinueSection1" style="padding: 10px 10px 10px 10px; display: block"><input id="contactButton1" name="contactButton1" onclick="A4J.AJAX.Submit('_viewRoot','contactForm1',event,{'parameters':{'holder':getSuffix(),'contactButton1
':'contactButton1'} ,'actionUrl':'/BaisiPrototype/AE/primary.jspv?javax.portlet.faces.DirectLink=tru
e','oncomplete':function(request,event,data){UIControl('contactForm', 'contact', 'identification');}
} );return false;" value="Continue" class="btn" type="button" />
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/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, 10 months
[jbossseam-issues] [JBoss JIRA] Created: (JBSEAM-2652) s:decorate does not respect prependId="false" on h:form
by Erik Magnusson (JIRA)
s:decorate does not respect prependId="false" on h:form
-------------------------------------------------------
Key: JBSEAM-2652
URL: http://jira.jboss.com/jira/browse/JBSEAM-2652
Project: JBoss Seam
Issue Type: Bug
Components: JSF Controls
Affects Versions: 2.0.1.GA
Environment: JBoss Seam 2.0.1GA
Reporter: Erik Magnusson
Given the following code:
<h:form id="login" prependId="false">
<s:validateAll>
<f:facet name="afterInvalidField">
<s:label styleClass="error">
<s:message/>
</s:label>
</f:facet>
<div class="labelinputcombo ilcblock">
<h:outputLabel for="username">User name:</h:outputLabel>
<s:decorate>
<h:inputText id="username" value="#{registrationService.newUser.userName}" required="true"/>
</s:decorate>
</div>
</s:validateAll>
<div>
<h:commandButton value="Register" action="#{registrationService.registerUser}"/>
</div>
</h:form>
One would expect that none of the generated <input> elements would have prepended IDs, since the h:form has prependId="false". However, since s:decorate insists on inserting a superfluous <div> with a generated ID around the <input> elements it surrounds, those <input> elements end up having prepended IDs from that <div>. The relevant generated HTML:
<div class="labelinputcombo ilcblock">
<label for="j_id31:username">User name:</label><div id="j_id31"><input id="j_id31:username" type="text" name="j_id31:username" /></div>
</div>
I did not ask for either the <div> or it's ID (<div id="j_id31">), or its insertion into my <input> element's ID (id="j_id31:username").
Proposed solutions:
1. Remove the generated <div>. Is it really necessary for the functionality of s:decorate? If I want a div I can always add it myself.
2. If the <div> really is necessary, at least make s:decorate respect the prependId="false" attribute of the surrounding h:form.
3. If that is not possible, as a last resort, introduce a prependId attribute on the <s:decorate> tag so we can at least force this behaviour if we want it.
On a more general note,
I'm a really big fan of the JSF-Seam-EJB3 combo, but some of the design decisions in the frameworks are baffling. Why so many superfluous generated html tags? And who thought of the bright idea of prepending element id attributes using : (colon) as the delimeter?? This effectively cripples the ability to use CSS to style JSF-generated HTML elements with a simple CSS id selector (since : is a reserved symbol in CSS).
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
13 years, 11 months
[jbossseam-issues] [JBoss JIRA] Created: (JBSEAM-2275) Document on Seam iText charting
by Joshua Partogi (JIRA)
Document on Seam iText charting
-------------------------------
Key: JBSEAM-2275
URL: http://jira.jboss.com/jira/browse/JBSEAM-2275
Project: JBoss Seam
Issue Type: Patch
Affects Versions: 2.0.0.GA
Environment: JBoss 4.2.1.GA
Reporter: Joshua Partogi
Fix For: 2.0.1.GA
Point 16.2
1. Write in doc to use the charting support, we need to add the jfreechart.jar and jcommon-*.jar in the project classpath. We can also add this is our build.xml
2. The key attribute is needed upon p:data component usage otherwise it will throw
this exception java.lang.IllegalArgumentException: Null 'key' argument.
at org.jfree.data.DefaultKeyedValues.setValue(DefaultKeyedValues.java:239)
at org.jfree.data.DefaultKeyedValues2D.setValue(DefaultKeyedValues2D.java:337)
at org.jfree.data.DefaultKeyedValues2D.addValue(DefaultKeyedValues2D.java:303).
In examples, it is used in (the ones below are the fixed value):
Barchart, Linechart, Series
PieChart
1. Attributes:
title — The chart title text.
legend — A boolean value indicating whether or not the chart should include a legend. Default value is true
is3D - A boolean value indicating that the chart should be rendered in 3D instead of 2D.
labelLinkMargin - The link margin
labelLinkPaint - The paint used for the label linking lines.
labelLinkStroke - The stroke used for the label linking lines.
labelLinksVisible - A flag that controls whether or not the label links are drawn.
labelOutlinePaint - The paint used to draw the outline of the section labels
labelOutlineStroke - The stroke used to draw the outline of the section labels
labelShadowPaint - The paint used to draw the shadow for the section labels
labelPaint - The color used to draw the section labels
labelGap - The gap between the labels and the plot as a percentage of the plot width.
labelBackgroundPaint - The color used to draw the background of the section labels. If this is null, the background is not filled.
startAngle - The starting angle
circular - A boolean value indicating whether whether to draw an ellipse or a perfect circle.
direction - The direction for the pie segments. If value is not set "anticlockwise" then by default it is clockwise.
sectionOutlinePaint - The outline paint for ALL sections (overrides list).
sectionOutlineStroke - The outline stroke for ALL sections (overrides list).
sectionOutlinesVisible - A flag that controls whether or not an outline is drawn for each section in the plot.
baseSectionOutlinePaint - The base section outline paint
baseSectionPaint - The base section paint
baseSectionOutlineStroke - The base section outline stroke
2. Usage:
<p:document xmlns:p="http://jboss.com/products/seam/pdf">
<p:piechart title="Pie Chart" circular="false" direction="anticlockwise"
startAngle="30" labelGap="0.1" labelLinkPaint="red">
<p:series key="Prices">
<p:data key="2003" columnKey="2003" value="7.36" />
<p:data key="2004" columnKey="2004" value="11.50" />
<p:data key="2005" columnKey="2005" value="34.625" />
<p:data key="2006" columnKey="2006" value="76.30" />
<p:data key="2007" columnKey="2007" value="85.05" />
</p:series>
</p:piechart>
</p:document>
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
13 years, 11 months
[jbossseam-issues] [JBoss JIRA] Created: (JBSEAM-3251) ValidateAllRendererBase not robust enough for dynamic components
by Richard Kennard (JIRA)
ValidateAllRendererBase not robust enough for dynamic components
----------------------------------------------------------------
Key: JBSEAM-3251
URL: https://jira.jboss.org/jira/browse/JBSEAM-3251
Project: Seam
Issue Type: Bug
Components: JSF Controls
Affects Versions: 2.1.0.A1, 2.0.3.CR1, 2.0.2.SP1
Environment: Any
Reporter: Richard Kennard
Priority: Minor
org.jboss.seam.ui.renderkit.ValidateAllRendererBase has two minor problems (with easy fixes) that stop it working with highly dynamic components:
1. doEncodeChildren attaches its ModelValidators before calling renderChildren. This misses any subcomponents the children may themselves dynamically create during their encodeBegin phase. Moving renderChildren down fixes this
2. A ModelValidator is only attached if the component has no existing Validators. This seems a bit of a blunt instrument. Presumably the idea is to stop attaching multiple ModelValidators. If the component happens to have, say, a LengthValidator that shouldn't stop ModelValidator entirely.
I have attached an updated ValidateAllRendererBase. It does not break any existing unit tests.
Disclaimer: my vested interest in this is because of Metawidget (http://www.metawidget.org).
--
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
14 years