Seam SVN: r8883 - trunk/seam-gen/view/layout.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-09-03 11:28:03 -0400 (Wed, 03 Sep 2008)
New Revision: 8883
Modified:
trunk/seam-gen/view/layout/template.xhtml
Log:
Only display error on 503
Modified: trunk/seam-gen/view/layout/template.xhtml
===================================================================
--- trunk/seam-gen/view/layout/template.xhtml 2008-09-03 12:49:13 UTC (rev 8882)
+++ trunk/seam-gen/view/layout/template.xhtml 2008-09-03 15:28:03 UTC (rev 8883)
@@ -12,9 +12,13 @@
<title>@projectName@</title>
<link href="stylesheet/theme.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
- A4J.AJAX.onError = function(req,status,message) {
+ A4J.AJAX.onError = function(req,status,message)
+ {
- alert(message);
+ if (status == 503)
+ {
+ alert(message);
+ }
};
</script>
16 years, 8 months
Seam SVN: r8882 - in trunk: seam-gen/resources/WEB-INF and 1 other directories.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-09-03 08:49:13 -0400 (Wed, 03 Sep 2008)
New Revision: 8882
Modified:
trunk/doc/Seam_Reference_Guide/en-US/Conversations.xml
trunk/seam-gen/resources/WEB-INF/pages.xml
trunk/seam-gen/view/layout/template.xhtml
Log:
JBSEAM-1832 part 2, docs and seam-gen for sending a 503
Modified: trunk/doc/Seam_Reference_Guide/en-US/Conversations.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Conversations.xml 2008-09-03 11:45:02 UTC (rev 8881)
+++ trunk/doc/Seam_Reference_Guide/en-US/Conversations.xml 2008-09-03 12:49:13 UTC (rev 8882)
@@ -1064,59 +1064,56 @@
concurrent-request-timeout="2000" />]]></programlisting>
<para>
- So far we've discussed serial AJAX requests - the client tells the
- server that an event has occur, and then rerenders part of the page
- based on the result. This approach is great when the AJAX request is
- lightweight (the methods called are simple e.g. calculating the sum of a
- column of numbers). But what if we need to do a complex computation?
+ So far we've discussed AJAX requests which appear serial to the user -
+ the client tells the server that an event has occur, and then rerenders
+ part of the page based on the result. This approach is great when the
+ AJAX request is lightweight (the methods called are simple e.g.
+ calculating the sum of a column of numbers). But what if we need to do
+ a complex computation thats going to take a minute?
</para>
+
<para>
- For heavy computation we should use a truly asynchronous (poll based)
- approach — the client sends an AJAX request to the server, which
- causes action to be executed asynchronously on the server (so the the
- response to the client is immediate); the client then polls the server
- for updates. This is useful when you have a long-running action for
- which it is important that every action executes (you don't want some to
- be dropped as duplicates, or to timeout).
+ For heavy computation we should use a poll based approach — the
+ client sends an AJAX request to the server, which causes action to be
+ executed asynchronously on the server (the response to the client is
+ immediate) and the client then polls the server for updates. This is
+ good approach when you have a long-running action for which it is
+ important that every action executes (you don't want some to timeout).
</para>
- <para>
- <emphasis>How should we design our conversational AJAX application?</emphasis>
- </para>
+ <section>
+ <title>How should we design our conversational AJAX application?</title>
- <para>
- Well first, you need to decide whether you want to use the simpler
- "synchronous" request or whether you want to add using a poll-style
- approach.
- </para>
+ <para>
+ Well first, you need to decide whether you want to use the simpler
+ "serial" request or whether you want to use a polling approach.
+ </para>
- <para>
- If you go for a "synchronous" approach, then you need to make an
- estimate of how long your AJAX request will take to complete - is it
- much shorter than the concurrent request timeout? If not, you probably
- want to alter the concurrent request timeout for this method (as
- discussed above). Next you probably want a queue on the client side to
- prevent flooding the server with requests. If the event occurs often
- (e.g. a keypress, onblur of input fields) and immediate update of the
- client is not a priority you should set a request delay on the client
- side. When working out your request delay, factor in that the event may
- also be queued on the server side.
- </para>
+ <para>
+ If you go for a "serial" requests, then you need to estimate how long
+ your request will take to complete - is it much shorter than the
+ concurrent request timeout? If not, you probably want to alter the
+ concurrent request timeout for this page (as discussed above). You
+ probably want a queue on the client side to prevent flooding the
+ server with requests. If the event occurs often (e.g. a keypress,
+ onblur of input fields) and immediate update of the client is not a
+ priority you should set a request delay on the client side. When
+ working out your request delay, factor in that the event may also be
+ queued on the server side.
+ </para>
- <para>
- Finally, the client library may provide an option to abort unfinished
- duplicate requests in favor of the most recent. You need to be careful
- with this option as it can lead to flooding of the server with requests
- if the server is not able to abort the unfinished request.
- </para>
+ <para>
+ Finally, the client library may provide an option to abort unfinished
+ duplicate requests in favor of the most recent.
+ </para>
- <para>
- Using a poll-style design requires less fine-tuning. You just mark your
- action method <literal>@Asynchronous</literal> and decide on a polling
- interval:
- </para>
+ <para>
+ Using a poll-style design requires less fine-tuning. You just mark your
+ action method <literal>@Asynchronous</literal> and decide on a polling
+ interval:
+ </para>
- <programlisting role="JAVA"><![CDATA[int total;
+ <programlisting role="JAVA"><![CDATA[int total;
// This method is called when an event occurs on the client
// It takes a really long time to execute
@@ -1130,61 +1127,119 @@
public int getTotal() {
return total;
}]]></programlisting>
+ </section>
+
+ <section>
+ <title>Dealing with errors</title>
+
+ <para>
+ However carefully you design your application to queue concurrent
+ requests to your conversational component, there is a risk that the
+ server will become overloaded and be unable to process all the
+ requests before the request will have to wait longer than the
+ <literal>concurrent-request-timeout</literal>. In this case Seam will
+ throw a <literal>ConcurrentRequestTimeoutException</literal> which can
+ be handled in <literal>pages.xml</literal>. We recommend sending an
+ HTTP 503 error:
+ </para>
+
+ <programlisting role="XML"><![CDATA[ <exception class="org.jboss.seam.ConcurrentRequestTimeoutException" logLevel="trace">
+ <http-error error-code="503" />
+ </exception>]]></programlisting>
+
+ <note>
+ <title>503 Service Unavailable (HTTP/1.1 RFC)</title>
+
+ <para>
+ The server is currently unable to handle the request due to a
+ temporary overloading or maintenance of the server. The implication
+ is that this is a temporary condition which will be alleviated after
+ some delay.
+ </para>
+ </note>
+
+ <para>
+ Alternatively you could redirect to an error page:
+ </para>
+
+ <programlisting role="XML"><![CDATA[<exception class="org.jboss.seam.ConcurrentRequestTimeoutException" logLevel="trace">
+ <end-conversation/>
+ <redirect view-id="/error.xhtml">
+ <message>The server is too busy to process your request, please try again later</message>
+ </redirect>
+</exception>]]></programlisting>
+
+ <para>
+ ICEfaces, RichFaces Ajax and Seam Remoting can all handle HTTP error
+ codes. Seam Remoting will pop up a dialog box showing the HTTP error
+ and ICEfaces will indicate the error in it's connection status
+ component. RichFaces Ajax provides the most complete support for
+ handling HTTP errors by providing a user definable callback. For
+ example, to show the error message to the user:
+ </para>
+
+ <programlisting><![CDATA[<script type="text/javascript">
+ A4J.AJAX.onError = function(req,status,message) {
+ alert("message");
+ };
+</script>]]></programlisting>
+
+ </section>
- <section>
- <title>RichFaces Ajax</title>
+ <section>
+ <title>RichFaces Ajax</title>
- <para>
- RichFaces Ajax is the AJAX library most commonly used with Seam, and
- provides all the controls discussed above:
- </para>
+ <para>
+ RichFaces Ajax is the AJAX library most commonly used with Seam, and
+ provides all the controls discussed above:
+ </para>
- <itemizedlist>
- <listitem>
- <para>
- <literal>eventsQueue</literal> — provide a queue in which
- events are placed. All events are queued and requests are sent to
- the server serially. This is useful if the request can to the
- server can take some time to execute (e.g. heavy computation,
- retrieving information from a slow source) as the server isn't
- flooded.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>ignoreDupResponses</literal> — ignore the response
- produced by the request if a more recent 'similar' request is
- already in the queue. ignoreDupResponses="true" does <emphasis>not
- cancel</emphasis> the the processing of the request on the server
- side — just prevents unnecessary updates on the client side.
- </para>
- <para>
- This option should be used with care with Seam's conversations as
- it allows multiple concurrent requests to be made.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>requestDelay</literal> — defines the time (in ms.)
- that the request will be remain on the queue. If the request has
- not been processed by after this time the request will be sent
- (regardless of whether a response has been received) or discarded
- (if there is a more recent similar event on the queue).
- </para>
- <para>
- This option should be used with care with Seam's conversations as
- it allows multiple concurrent requests to be made. You need to be
- sure that the delay you set (in combination with the concurrent
- request timeout) is longer than the action will take to execute.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal><a:poll reRender="total" interval="1000" /></literal> —
- Polls the server, and rerenders an area as needed
- </para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>eventsQueue</literal> — provide a queue in which
+ events are placed. All events are queued and requests are sent to
+ the server serially. This is useful if the request can to the
+ server can take some time to execute (e.g. heavy computation,
+ retrieving information from a slow source) as the server isn't
+ flooded.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ignoreDupResponses</literal> — ignore the response
+ produced by the request if a more recent 'similar' request is
+ already in the queue. ignoreDupResponses="true" does <emphasis>not
+ cancel</emphasis> the the processing of the request on the server
+ side — just prevents unnecessary updates on the client side.
+ </para>
+ <para>
+ This option should be used with care with Seam's conversations as
+ it allows multiple concurrent requests to be made.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>requestDelay</literal> — defines the time (in ms.)
+ that the request will be remain on the queue. If the request has
+ not been processed by after this time the request will be sent
+ (regardless of whether a response has been received) or discarded
+ (if there is a more recent similar event on the queue).
+ </para>
+ <para>
+ This option should be used with care with Seam's conversations as
+ it allows multiple concurrent requests to be made. You need to be
+ sure that the delay you set (in combination with the concurrent
+ request timeout) is longer than the action will take to execute.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal><a:poll reRender="total" interval="1000" /></literal> —
+ Polls the server, and rerenders an area as needed
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
</section>
- </section>
</chapter>
\ No newline at end of file
Modified: trunk/seam-gen/resources/WEB-INF/pages.xml
===================================================================
--- trunk/seam-gen/resources/WEB-INF/pages.xml 2008-09-03 11:45:02 UTC (rev 8881)
+++ trunk/seam-gen/resources/WEB-INF/pages.xml 2008-09-03 12:49:13 UTC (rev 8882)
@@ -50,6 +50,10 @@
<message>Your session has timed out, please try again</message>
</redirect>
</exception>
+
+ <exception class="org.jboss.seam.ConcurrentRequestTimeoutException" logLevel="trace">
+ <http-error error-code="503" />
+ </exception>
<exception>
<redirect view-id="/error.xhtml">
Modified: trunk/seam-gen/view/layout/template.xhtml
===================================================================
--- trunk/seam-gen/view/layout/template.xhtml 2008-09-03 11:45:02 UTC (rev 8881)
+++ trunk/seam-gen/view/layout/template.xhtml 2008-09-03 12:49:13 UTC (rev 8882)
@@ -11,6 +11,13 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>@projectName@</title>
<link href="stylesheet/theme.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript">
+ A4J.AJAX.onError = function(req,status,message) {
+
+ alert(message);
+
+ };
+ </script>
</head>
<body>
16 years, 8 months
Seam SVN: r8881 - trunk/doc/Seam_Reference_Guide/en-US.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-09-03 07:45:02 -0400 (Wed, 03 Sep 2008)
New Revision: 8881
Modified:
trunk/doc/Seam_Reference_Guide/en-US/Conversations.xml
Log:
ws
Modified: trunk/doc/Seam_Reference_Guide/en-US/Conversations.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Conversations.xml 2008-09-02 21:17:31 UTC (rev 8880)
+++ trunk/doc/Seam_Reference_Guide/en-US/Conversations.xml 2008-09-03 11:45:02 UTC (rev 8881)
@@ -1056,67 +1056,67 @@
<para>
We can also fine tune the concurrent request timeout on a page-by-page
basis:
- </para>
+ </para>
<programlisting role="XML"><![CDATA[<page view-id="/book.xhtml"
conversation-required="true"
login-required="true"
concurrent-request-timeout="2000" />]]></programlisting>
- <para>
- So far we've discussed serial AJAX requests - the client tells the
- server that an event has occur, and then rerenders part of the page based
- on the result. This approach is great when the AJAX request is
- lightweight (the methods called are simple e.g. calculating the sum of a
- column of numbers). But what if we need to do a complex computation?
- </para>
- <para>
- For heavy computation we should use a truly asynchronous (poll based)
- approach — the client sends an AJAX request to the server, which
- causes action to be executed asynchronously on the server (so the the
- response to the client is immediate); the client then polls the server
- for updates. This is useful when you have a long-running action for
- which it is important that every action executes (you don't want some to
- be dropped as duplicates, or to timeout).
- </para>
+ <para>
+ So far we've discussed serial AJAX requests - the client tells the
+ server that an event has occur, and then rerenders part of the page
+ based on the result. This approach is great when the AJAX request is
+ lightweight (the methods called are simple e.g. calculating the sum of a
+ column of numbers). But what if we need to do a complex computation?
+ </para>
+ <para>
+ For heavy computation we should use a truly asynchronous (poll based)
+ approach — the client sends an AJAX request to the server, which
+ causes action to be executed asynchronously on the server (so the the
+ response to the client is immediate); the client then polls the server
+ for updates. This is useful when you have a long-running action for
+ which it is important that every action executes (you don't want some to
+ be dropped as duplicates, or to timeout).
+ </para>
- <para>
- <emphasis>How should we design our conversational AJAX application?</emphasis>
- </para>
+ <para>
+ <emphasis>How should we design our conversational AJAX application?</emphasis>
+ </para>
- <para>
- Well first, you need to decide whether you want to use the simpler
- "synchronous" request or whether you want to add using a poll-style
- approach.
- </para>
+ <para>
+ Well first, you need to decide whether you want to use the simpler
+ "synchronous" request or whether you want to add using a poll-style
+ approach.
+ </para>
- <para>
- If you go for a "synchronous" approach, then you need to make an
- estimate of how long your AJAX request will take to complete - is it much
- shorter than the concurrent request timeout? If not, you probably want to
- alter the concurrent request timeout for this method (as discussed
- above). Next you probably want a queue on the client side to prevent
- flooding the server with requests. If the event occurs often (e.g. a
- keypress, onblur of input fields) and immediate update of the client is
- not a priority you should set a request delay on the client side. When
- working out your request delay, factor in that the event may also be
- queued on the server side.
- </para>
+ <para>
+ If you go for a "synchronous" approach, then you need to make an
+ estimate of how long your AJAX request will take to complete - is it
+ much shorter than the concurrent request timeout? If not, you probably
+ want to alter the concurrent request timeout for this method (as
+ discussed above). Next you probably want a queue on the client side to
+ prevent flooding the server with requests. If the event occurs often
+ (e.g. a keypress, onblur of input fields) and immediate update of the
+ client is not a priority you should set a request delay on the client
+ side. When working out your request delay, factor in that the event may
+ also be queued on the server side.
+ </para>
- <para>
- Finally, the client library may provide an option to abort unfinished
- duplicate requests in favor of the most recent. You need to be careful
- with this option as it can lead to flooding of the server with requests
- if the server is not able to abort the unfinished request.
- </para>
+ <para>
+ Finally, the client library may provide an option to abort unfinished
+ duplicate requests in favor of the most recent. You need to be careful
+ with this option as it can lead to flooding of the server with requests
+ if the server is not able to abort the unfinished request.
+ </para>
- <para>
- Using a poll-style design requires less fine-tuning. You just mark your
- action method <literal>@Asynchronous</literal> and decide on a polling
- interval:
- </para>
+ <para>
+ Using a poll-style design requires less fine-tuning. You just mark your
+ action method <literal>@Asynchronous</literal> and decide on a polling
+ interval:
+ </para>
- <programlisting role="JAVA"><![CDATA[int total;
+ <programlisting role="JAVA"><![CDATA[int total;
// This method is called when an event occurs on the client
// It takes a really long time to execute
16 years, 8 months
Seam SVN: r8880 - in trunk/src/main/org/jboss/seam: core and 1 other directories.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-09-02 17:17:31 -0400 (Tue, 02 Sep 2008)
New Revision: 8880
Added:
trunk/src/main/org/jboss/seam/ConcurrentRequestTimeoutException.java
Modified:
trunk/src/main/org/jboss/seam/core/Manager.java
trunk/src/main/org/jboss/seam/jsf/SeamPhaseListener.java
Log:
Throw an exception when a concurrent request timeout occurs (JBSEAM-1832, docs and examples to follow)
Added: trunk/src/main/org/jboss/seam/ConcurrentRequestTimeoutException.java
===================================================================
--- trunk/src/main/org/jboss/seam/ConcurrentRequestTimeoutException.java (rev 0)
+++ trunk/src/main/org/jboss/seam/ConcurrentRequestTimeoutException.java 2008-09-02 21:17:31 UTC (rev 8880)
@@ -0,0 +1,29 @@
+/**
+ *
+ */
+package org.jboss.seam;
+
+public class ConcurrentRequestTimeoutException extends RuntimeException
+{
+
+ public ConcurrentRequestTimeoutException()
+ {
+ super();
+ }
+
+ public ConcurrentRequestTimeoutException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ public ConcurrentRequestTimeoutException(String message)
+ {
+ super(message);
+ }
+
+ public ConcurrentRequestTimeoutException(Throwable cause)
+ {
+ super(cause);
+ }
+
+}
\ No newline at end of file
Property changes on: trunk/src/main/org/jboss/seam/ConcurrentRequestTimeoutException.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/src/main/org/jboss/seam/core/Manager.java
===================================================================
--- trunk/src/main/org/jboss/seam/core/Manager.java 2008-09-02 16:32:56 UTC (rev 8879)
+++ trunk/src/main/org/jboss/seam/core/Manager.java 2008-09-02 21:17:31 UTC (rev 8880)
@@ -16,6 +16,7 @@
import java.util.Map;
import org.jboss.seam.Component;
+import org.jboss.seam.ConcurrentRequestTimeoutException;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.FlushModeType;
import org.jboss.seam.annotations.Install;
@@ -44,6 +45,7 @@
@BypassInterceptors
public class Manager
{
+
private static final LogProvider log = Logging.getLogProvider(Manager.class);
public static final String REDIRECT_FROM_MANAGER = "org.jboss.seam.core.Manager";
@@ -502,8 +504,16 @@
private boolean restoreAndLockConversation(ConversationEntry ce)
{
- if ( ce!=null && ce.lock() )
+ if (ce == null)
{
+ //there was no id in either place, so there is no
+ //long-running conversation to restore
+ log.debug("No stored conversation");
+ initializeTemporaryConversation();
+ return false;
+ }
+ else if ( ce.lock() )
+ {
// do this ASAP, since there is a window where conversationTimeout() might
// try to destroy the conversation, even if he cannot obtain the lock!
touchConversationStack( ce.getConversationIdStack() );
@@ -523,14 +533,11 @@
return true;
- }
+ }
else
{
- //there was no id in either place, so there is no
- //long-running conversation to restore
- log.debug("No stored conversation, or concurrent call to the stored conversation");
- initializeTemporaryConversation();
- return false;
+ log.debug("Concurrent call to conversation");
+ throw new ConcurrentRequestTimeoutException("Concurrent call to conversation");
}
}
Modified: trunk/src/main/org/jboss/seam/jsf/SeamPhaseListener.java
===================================================================
--- trunk/src/main/org/jboss/seam/jsf/SeamPhaseListener.java 2008-09-02 16:32:56 UTC (rev 8879)
+++ trunk/src/main/org/jboss/seam/jsf/SeamPhaseListener.java 2008-09-02 21:17:31 UTC (rev 8880)
@@ -34,6 +34,7 @@
import org.jboss.seam.faces.FacesManager;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.faces.FacesPage;
+import org.jboss.seam.faces.HttpError;
import org.jboss.seam.faces.Switcher;
import org.jboss.seam.faces.Validation;
import org.jboss.seam.international.StatusMessage;
@@ -389,7 +390,7 @@
ConversationPropagation.instance().restoreConversationId(parameters);
boolean conversationFound = Manager.instance().restoreConversation();
FacesLifecycle.resumeConversation( facesContext.getExternalContext() );
- postRestorePage(facesContext, parameters, conversationFound);
+ postRestorePage(facesContext, parameters, conversationFound);
}
public void raiseEventsBeforePhase(PhaseEvent event)
16 years, 8 months
Seam SVN: r8879 - trunk/src/main/org/jboss/seam/international.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-09-02 12:32:56 -0400 (Tue, 02 Sep 2008)
New Revision: 8879
Modified:
trunk/src/main/org/jboss/seam/international/StatusMessage.java
Log:
Agh, isEmpty needs a conjuntion
Modified: trunk/src/main/org/jboss/seam/international/StatusMessage.java
===================================================================
--- trunk/src/main/org/jboss/seam/international/StatusMessage.java 2008-09-02 12:33:47 UTC (rev 8878)
+++ trunk/src/main/org/jboss/seam/international/StatusMessage.java 2008-09-02 16:32:56 UTC (rev 8879)
@@ -54,7 +54,7 @@
public boolean isEmpty()
{
- return Strings.isEmpty(summary) || Strings.isEmpty(summaryTemplate);
+ return Strings.isEmpty(summary) && Strings.isEmpty(summaryTemplate);
}
public void interpolate(Object... params)
16 years, 8 months
Seam SVN: r8878 - in trunk: src/main/org/jboss/seam and 3 other directories.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-09-02 08:33:47 -0400 (Tue, 02 Sep 2008)
New Revision: 8878
Modified:
trunk/doc/Seam_Reference_Guide/en-US/Conversations.xml
trunk/src/main/org/jboss/seam/core/Conversation.java
trunk/src/main/org/jboss/seam/core/ConversationEntry.java
trunk/src/main/org/jboss/seam/core/Manager.java
trunk/src/main/org/jboss/seam/faces/FacesManager.java
trunk/src/main/org/jboss/seam/navigation/Page.java
trunk/src/main/org/jboss/seam/navigation/Pages.java
trunk/src/main/org/jboss/seam/pages-2.1.xsd
Log:
JBSEAM-1832 part 1, support for setting concurrent request timeout in pages.xml
Modified: trunk/doc/Seam_Reference_Guide/en-US/Conversations.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Conversations.xml 2008-09-02 11:06:05 UTC (rev 8877)
+++ trunk/doc/Seam_Reference_Guide/en-US/Conversations.xml 2008-09-02 12:33:47 UTC (rev 8878)
@@ -1038,11 +1038,12 @@
</para>
<para>
- Therefore Seam queues the action event for a period of time (the
- concurrent request timeout); if it can't process the event in time, it
- creates a temporary conversation and prints out a message to the user to
- let them know what's going on. It's therefore very important not to
- flood the server with AJAX events!
+ Therefore, when you are working inside a long running conversation,
+ Seam queues the action event for a period of time (the concurrent
+ request timeout); if it can't process the event in time, it creates a
+ temporary conversation and prints out a message to the user to let them
+ know what's going on. It's therefore very important not to flood the
+ server with AJAX events!
</para>
<para>
@@ -1051,18 +1052,19 @@
</para>
<programlisting role="XML"><![CDATA[<core:manager concurrent-request-timeout="500" />]]></programlisting>
- <!-- TODO -->
- <!-- <para>
- We can also fine tune the concurrent request timeout for a request:
+
+ <para>
+ We can also fine tune the concurrent request timeout on a page-by-page
+ basis:
</para>
- <programlisting role="JAVA"><![CDATA[public void getTotal() {
- Manager.instance().setConcurrentRequestTimeout(1000);
- return someReallyComplicatedCalculation();
-}]]></programlisting>-->
+ <programlisting role="XML"><![CDATA[<page view-id="/book.xhtml"
+ conversation-required="true"
+ login-required="true"
+ concurrent-request-timeout="2000" />]]></programlisting>
<para>
- So far we've discussed "synchronous" AJAX requests - the client tells the
+ So far we've discussed serial AJAX requests - the client tells the
server that an event has occur, and then rerenders part of the page based
on the result. This approach is great when the AJAX request is
lightweight (the methods called are simple e.g. calculating the sum of a
Modified: trunk/src/main/org/jboss/seam/core/Conversation.java
===================================================================
--- trunk/src/main/org/jboss/seam/core/Conversation.java 2008-09-02 11:06:05 UTC (rev 8877)
+++ trunk/src/main/org/jboss/seam/core/Conversation.java 2008-09-02 12:33:47 UTC (rev 8878)
@@ -31,6 +31,7 @@
{
private static final long serialVersionUID = -6131304128727444876L;
private Integer timeout;
+ private Integer concurrentRequestTimeout;
String description;
String viewId;
@@ -54,6 +55,16 @@
this.timeout = timeout;
}
+ public Integer getConcurrentRequestTimeout()
+ {
+ return concurrentRequestTimeout == null ? Manager.instance().getCurrentConversationConcurrentRequestTimeout() : concurrentRequestTimeout;
+ }
+
+ public void setConcurrentRequestTimeout(Integer concurrentRequestTimeout)
+ {
+ this.concurrentRequestTimeout = concurrentRequestTimeout;
+ }
+
/**
* Get the conversation id.
*/
@@ -135,6 +146,10 @@
{
entry.setTimeout(timeout);
}
+ if (concurrentRequestTimeout != null)
+ {
+ entry.setConcurrentRequestTimeout(concurrentRequestTimeout);
+ }
description = null;
viewId = null;
Modified: trunk/src/main/org/jboss/seam/core/ConversationEntry.java
===================================================================
--- trunk/src/main/org/jboss/seam/core/ConversationEntry.java 2008-09-02 11:06:05 UTC (rev 8877)
+++ trunk/src/main/org/jboss/seam/core/ConversationEntry.java 2008-09-02 12:33:47 UTC (rev 8878)
@@ -25,6 +25,7 @@
private String viewId;
private List<String> conversationIdStack;
private Integer timeout;
+ private Integer concurrentRequestTimeout;
private boolean removeAfterRedirect;
private boolean ended;
@@ -176,6 +177,17 @@
this.timeout = conversationTimeout;
}
+ public Integer getConcurrentRequestTimeout()
+ {
+ return concurrentRequestTimeout == null ? Manager.instance().getConcurrentRequestTimeout() : concurrentRequestTimeout;
+ }
+
+ void setConcurrentRequestTimeout(Integer concurrentRequestTimeout)
+ {
+ entries.setDirty(this.concurrentRequestTimeout, concurrentRequestTimeout);
+ this.concurrentRequestTimeout = concurrentRequestTimeout;
+ }
+
public boolean isRemoveAfterRedirect()
{
return removeAfterRedirect;
@@ -201,7 +213,7 @@
{
try
{
- return lock.tryLock( Manager.instance().getConcurrentRequestTimeout(), TimeUnit.MILLISECONDS );
+ return lock.tryLock( getConcurrentRequestTimeout(), TimeUnit.MILLISECONDS );
}
catch (InterruptedException ie)
{
Modified: trunk/src/main/org/jboss/seam/core/Manager.java
===================================================================
--- trunk/src/main/org/jboss/seam/core/Manager.java 2008-09-02 11:06:05 UTC (rev 8877)
+++ trunk/src/main/org/jboss/seam/core/Manager.java 2008-09-02 12:33:47 UTC (rev 8878)
@@ -196,6 +196,13 @@
if ( ce==null ) return null;
return ce.getTimeout();
}
+
+ public Integer getCurrentConversationConcurrentRequestTimeout()
+ {
+ ConversationEntry ce = getCurrentConversationEntry();
+ if (ce == null) return null;
+ return ce.getConcurrentRequestTimeout();
+ }
public String getCurrentConversationViewId()
{
Modified: trunk/src/main/org/jboss/seam/faces/FacesManager.java
===================================================================
--- trunk/src/main/org/jboss/seam/faces/FacesManager.java 2008-09-02 11:06:05 UTC (rev 8877)
+++ trunk/src/main/org/jboss/seam/faces/FacesManager.java 2008-09-02 12:33:47 UTC (rev 8878)
@@ -284,6 +284,7 @@
conversation.setDescription( pages.renderDescription(viewId) );
}
conversation.setTimeout( pages.getTimeout(viewId) );
+ conversation.setConcurrentRequestTimeout( pages.getConcurrentRequestTimeout(viewId) );
}
}
else
Modified: trunk/src/main/org/jboss/seam/navigation/Page.java
===================================================================
--- trunk/src/main/org/jboss/seam/navigation/Page.java 2008-09-02 11:06:05 UTC (rev 8877)
+++ trunk/src/main/org/jboss/seam/navigation/Page.java 2008-09-02 12:33:47 UTC (rev 8878)
@@ -29,6 +29,7 @@
private final String viewId;
private String description;
private Integer timeout;
+ private Integer concurrentRequestTimeout;
private ValueExpression<String> noConversationViewId;
private String resourceBundleName;
private boolean switchEnabled = true;
@@ -130,6 +131,16 @@
return timeout;
}
+ public void setConcurrentRequestTimeout(Integer concurrentRequestTimeout)
+ {
+ this.concurrentRequestTimeout = concurrentRequestTimeout;
+ }
+
+ public Integer getConcurrentRequestTimeout()
+ {
+ return concurrentRequestTimeout;
+ }
+
public void setNoConversationViewId(ValueExpression<String> noConversationViewId)
{
this.noConversationViewId = noConversationViewId;
Modified: trunk/src/main/org/jboss/seam/navigation/Pages.java
===================================================================
--- trunk/src/main/org/jboss/seam/navigation/Pages.java 2008-09-02 11:06:05 UTC (rev 8877)
+++ trunk/src/main/org/jboss/seam/navigation/Pages.java 2008-09-02 12:33:47 UTC (rev 8878)
@@ -962,6 +962,26 @@
return Manager.instance().getConversationTimeout();
}
+ /**
+ * Search for a defined concurrent request timeout, beginning with
+ * the most specific view id, then wildcarded view ids, and
+ * finally the global setting from Manager
+ */
+ public Integer getConcurrentRequestTimeout(String viewId)
+ {
+ List<Page> stack = getPageStack(viewId);
+ for (int i=stack.size()-1; i>=0; i--)
+ {
+ Page page = stack.get(i);
+ Integer concurrentRequestTimeout = page.getConcurrentRequestTimeout();
+ if (concurrentRequestTimeout!=null)
+ {
+ return concurrentRequestTimeout;
+ }
+ }
+ return Manager.instance().getConcurrentRequestTimeout();
+ }
+
public static String getSuffix()
{
String defaultSuffix = FacesContext.getCurrentInstance().getExternalContext()
@@ -1149,6 +1169,12 @@
page.setTimeout(Integer.parseInt(timeoutString));
}
+ String concurrentRequestTimeoutString = element.attributeValue("concurrent-request-timeout");
+ if (concurrentRequestTimeoutString!=null)
+ {
+ page.setConcurrentRequestTimeout(Integer.parseInt(concurrentRequestTimeoutString));
+ }
+
String noConversationViewIdString = element.attributeValue("no-conversation-view-id");
if (noConversationViewIdString != null)
{
Modified: trunk/src/main/org/jboss/seam/pages-2.1.xsd
===================================================================
--- trunk/src/main/org/jboss/seam/pages-2.1.xsd 2008-09-02 11:06:05 UTC (rev 8877)
+++ trunk/src/main/org/jboss/seam/pages-2.1.xsd 2008-09-02 12:33:47 UTC (rev 8878)
@@ -118,6 +118,16 @@
</xs:attribute>
<xs:attribute name="scheme"/>
<xs:attribute name="timeout"/>
+ <xs:attribute name="concurrent-request-timeout">
+ <xs:annotation>
+ <xs:documentation>
+ Requests to conversations are serialized by default, and if
+ a lock cannot be acquired in time, the request will be
+ dropped. You can set the timeout on a page-by-page basis
+ here.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
<xs:attribute name="bundle"/>
<xs:attribute name="conversation"/>
<xs:attribute name="expires" />
16 years, 8 months
Seam SVN: r8877 - trunk/src/main/org/jboss/seam/international.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-09-02 07:06:05 -0400 (Tue, 02 Sep 2008)
New Revision: 8877
Modified:
trunk/src/main/org/jboss/seam/international/StatusMessage.java
trunk/src/main/org/jboss/seam/international/StatusMessages.java
Log:
Argh, another bug in adding messages!
Modified: trunk/src/main/org/jboss/seam/international/StatusMessage.java
===================================================================
--- trunk/src/main/org/jboss/seam/international/StatusMessage.java 2008-09-02 04:56:59 UTC (rev 8876)
+++ trunk/src/main/org/jboss/seam/international/StatusMessage.java 2008-09-02 11:06:05 UTC (rev 8877)
@@ -52,6 +52,11 @@
}
}
+ public boolean isEmpty()
+ {
+ return Strings.isEmpty(summary) || Strings.isEmpty(summaryTemplate);
+ }
+
public void interpolate(Object... params)
{
if (!Strings.isEmpty(summaryTemplate))
Modified: trunk/src/main/org/jboss/seam/international/StatusMessages.java
===================================================================
--- trunk/src/main/org/jboss/seam/international/StatusMessages.java 2008-09-02 04:56:59 UTC (rev 8876)
+++ trunk/src/main/org/jboss/seam/international/StatusMessages.java 2008-09-02 11:06:05 UTC (rev 8877)
@@ -14,7 +14,6 @@
import org.jboss.seam.ScopeType;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.international.StatusMessage.Severity;
-import org.jboss.seam.util.Strings;
/**
* Abstract base class for providing status messages. View layers should provide
@@ -73,16 +72,18 @@
public void add(Severity severity, String key, String detailKey, String messageTemplate, String messageDetailTemplate, final Object... params)
{
final StatusMessage message = new StatusMessage(severity, key, detailKey, messageTemplate, messageDetailTemplate);
- if (!Strings.isEmpty(message.getSummary()))
+ if (!message.isEmpty())
{
messages.add(message);
getTasks().add(
new Runnable()
{
+
public void run()
{
message.interpolate(params);
}
+
}
);
}
@@ -103,7 +104,7 @@
public void addToControl(String id, Severity severity, String key, String messageTemplate, final Object... params)
{
final StatusMessage message = new StatusMessage(severity, key, null, messageTemplate, null);
- if (!Strings.isEmpty(message.getSummary()))
+ if (!message.isEmpty())
{
if (keyedMessages.containsKey(id))
{
16 years, 8 months
Seam SVN: r8876 - in branches/Seam_2_0/src: main/org/jboss/seam/core and 1 other directories.
by seam-commits@lists.jboss.org
Author: matt.drees
Date: 2008-09-02 00:56:59 -0400 (Tue, 02 Sep 2008)
New Revision: 8876
Added:
branches/Seam_2_0/src/main/org/jboss/seam/CyclicDependencyException.java
Removed:
branches/Seam_2_0/src/main/org/jboss/seam/core/CyclicDependencyException.java
Modified:
branches/Seam_2_0/src/main/org/jboss/seam/core/BijectionInterceptor.java
branches/Seam_2_0/src/test/unit/org/jboss/seam/test/unit/InterceptorTest.java
Log:
Move CyclicDependencyException next to other exceptions
Copied: branches/Seam_2_0/src/main/org/jboss/seam/CyclicDependencyException.java (from rev 8863, branches/Seam_2_0/src/main/org/jboss/seam/core/CyclicDependencyException.java)
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/CyclicDependencyException.java (rev 0)
+++ branches/Seam_2_0/src/main/org/jboss/seam/CyclicDependencyException.java 2008-09-02 04:56:59 UTC (rev 8876)
@@ -0,0 +1,98 @@
+package org.jboss.seam;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.seam.core.BijectionInterceptor;
+
+/**
+ * An exception that is thrown when {@link BijectionInterceptor} detects that a
+ * component's dependencies cannot be injected due to a cyclic dependency. As
+ * the exception is passed up the stack, the call sequence is recorded so that a
+ * useful exception message can be constructed.
+ *
+ * @author Matt Drees
+ *
+ */
+public class CyclicDependencyException extends IllegalStateException
+{
+
+ /**
+ * stores the invocations in reverse call order
+ */
+ private final List<String> invocations = new ArrayList<String>();
+ private String tailComponentName;
+ private boolean cycleComplete;
+
+ /**
+ * Records this invocation's component name and method to be displayed in
+ * {@link #getMessage()}, unless this invocation is not part of the detected
+ * cycle. This method will be successively called as the exception is
+ * propagated up the stack.
+ *
+ * @param componentName
+ * @param method
+ */
+ public void addInvocation(String componentName, Method method)
+ {
+ if (cycleComplete)
+ {
+ return;
+ }
+
+ if (invocations.isEmpty())
+ {
+ tailComponentName = componentName;
+ }
+ else
+ {
+ if (tailComponentName.equals(componentName))
+ {
+ cycleComplete = true;
+ }
+ }
+ invocations.add(createInvocationLabel(componentName, method));
+ }
+
+ /**
+ * returns e.g. "foo.doSomething()"
+ */
+ private String createInvocationLabel(String componentName, Method method)
+ {
+ String invocationLabel = componentName + "." + method.getName() + "(";
+ int i = 1;
+ for (Class<?> parameterType : method.getParameterTypes())
+ {
+ invocationLabel += parameterType.getSimpleName();
+ if (i < method.getParameterTypes().length)
+ {
+ invocationLabel += ", ";
+ }
+ i++;
+ }
+ invocationLabel += ")";
+ return invocationLabel;
+ }
+
+ @Override
+ public String getMessage()
+ {
+ if (!cycleComplete)
+ {
+ return "Cyclic dependency found";
+ }
+ else
+ {
+ String message = "Injection into " + tailComponentName + " resulted in a dependency cycle, requiring the invocation of " + invocations.get(0) + ". The complete cycle: ";
+ for (int i = invocations.size() - 1; i >= 0; i--)
+ {
+ message += invocations.get(i);
+ if (i != 0)
+ message += " -> ";
+ }
+ return message;
+ }
+ }
+
+}
Property changes on: branches/Seam_2_0/src/main/org/jboss/seam/CyclicDependencyException.java
___________________________________________________________________
Name: svn:mergeinfo
+
Modified: branches/Seam_2_0/src/main/org/jboss/seam/core/BijectionInterceptor.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/core/BijectionInterceptor.java 2008-09-02 04:56:23 UTC (rev 8875)
+++ branches/Seam_2_0/src/main/org/jboss/seam/core/BijectionInterceptor.java 2008-09-02 04:56:59 UTC (rev 8876)
@@ -4,6 +4,7 @@
import java.util.concurrent.locks.ReentrantLock;
import org.jboss.seam.Component;
+import org.jboss.seam.CyclicDependencyException;
import org.jboss.seam.annotations.intercept.AroundInvoke;
import org.jboss.seam.annotations.intercept.Interceptor;
import org.jboss.seam.intercept.AbstractInterceptor;
Deleted: branches/Seam_2_0/src/main/org/jboss/seam/core/CyclicDependencyException.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/core/CyclicDependencyException.java 2008-09-02 04:56:23 UTC (rev 8875)
+++ branches/Seam_2_0/src/main/org/jboss/seam/core/CyclicDependencyException.java 2008-09-02 04:56:59 UTC (rev 8876)
@@ -1,96 +0,0 @@
-package org.jboss.seam.core;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An exception that is thrown when {@link BijectionInterceptor} detects that a
- * component's dependencies cannot be injected due to a cyclic dependency. As
- * the exception is passed up the stack, the call sequence is recorded so that a
- * useful exception message can be constructed.
- *
- * @author Matt Drees
- *
- */
-public class CyclicDependencyException extends IllegalStateException
-{
-
- /**
- * stores the invocations in reverse call order
- */
- private final List<String> invocations = new ArrayList<String>();
- private String tailComponentName;
- private boolean cycleComplete;
-
- /**
- * Records this invocation's component name and method to be displayed in
- * {@link #getMessage()}, unless this invocation is not part of the detected
- * cycle. This method will be successively called as the exception is
- * propagated up the stack.
- *
- * @param componentName
- * @param method
- */
- public void addInvocation(String componentName, Method method)
- {
- if (cycleComplete)
- {
- return;
- }
-
- if (invocations.isEmpty())
- {
- tailComponentName = componentName;
- }
- else
- {
- if (tailComponentName.equals(componentName))
- {
- cycleComplete = true;
- }
- }
- invocations.add(createInvocationLabel(componentName, method));
- }
-
- /**
- * returns e.g. "foo.doSomething()"
- */
- private String createInvocationLabel(String componentName, Method method)
- {
- String invocationLabel = componentName + "." + method.getName() + "(";
- int i = 1;
- for (Class<?> parameterType : method.getParameterTypes())
- {
- invocationLabel += parameterType.getSimpleName();
- if (i < method.getParameterTypes().length)
- {
- invocationLabel += ", ";
- }
- i++;
- }
- invocationLabel += ")";
- return invocationLabel;
- }
-
- @Override
- public String getMessage()
- {
- if (!cycleComplete)
- {
- return "Cyclic dependency found";
- }
- else
- {
- String message = "Injection into " + tailComponentName + " resulted in a dependency cycle, requiring the invocation of " + invocations.get(0) + ". The complete cycle: ";
- for (int i = invocations.size() - 1; i >= 0; i--)
- {
- message += invocations.get(i);
- if (i != 0)
- message += " -> ";
- }
- return message;
- }
- }
-
-}
Modified: branches/Seam_2_0/src/test/unit/org/jboss/seam/test/unit/InterceptorTest.java
===================================================================
--- branches/Seam_2_0/src/test/unit/org/jboss/seam/test/unit/InterceptorTest.java 2008-09-02 04:56:23 UTC (rev 8875)
+++ branches/Seam_2_0/src/test/unit/org/jboss/seam/test/unit/InterceptorTest.java 2008-09-02 04:56:59 UTC (rev 8876)
@@ -7,6 +7,7 @@
import javax.faces.event.PhaseId;
import org.jboss.seam.Component;
+import org.jboss.seam.CyclicDependencyException;
import org.jboss.seam.NoConversationException;
import org.jboss.seam.RequiredException;
import org.jboss.seam.Seam;
@@ -19,7 +20,6 @@
import org.jboss.seam.core.ConversationEntries;
import org.jboss.seam.core.ConversationInterceptor;
import org.jboss.seam.core.ConversationalInterceptor;
-import org.jboss.seam.core.CyclicDependencyException;
import org.jboss.seam.core.Events;
import org.jboss.seam.core.Init;
import org.jboss.seam.core.Interpolator;
16 years, 8 months
Seam SVN: r8875 - in trunk/src: main/org/jboss/seam/core and 1 other directories.
by seam-commits@lists.jboss.org
Author: matt.drees
Date: 2008-09-02 00:56:23 -0400 (Tue, 02 Sep 2008)
New Revision: 8875
Added:
trunk/src/main/org/jboss/seam/CyclicDependencyException.java
Removed:
trunk/src/main/org/jboss/seam/core/CyclicDependencyException.java
Modified:
trunk/src/main/org/jboss/seam/core/BijectionInterceptor.java
trunk/src/test/unit/org/jboss/seam/test/unit/InterceptorTest.java
Log:
Move CyclicDependencyException next to other exceptions
Copied: trunk/src/main/org/jboss/seam/CyclicDependencyException.java (from rev 8872, trunk/src/main/org/jboss/seam/core/CyclicDependencyException.java)
===================================================================
--- trunk/src/main/org/jboss/seam/CyclicDependencyException.java (rev 0)
+++ trunk/src/main/org/jboss/seam/CyclicDependencyException.java 2008-09-02 04:56:23 UTC (rev 8875)
@@ -0,0 +1,98 @@
+package org.jboss.seam;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.seam.core.BijectionInterceptor;
+
+/**
+ * An exception that is thrown when {@link BijectionInterceptor} detects that a
+ * component's dependencies cannot be injected due to a cyclic dependency. As
+ * the exception is passed up the stack, the call sequence is recorded so that a
+ * useful exception message can be constructed.
+ *
+ * @author Matt Drees
+ *
+ */
+public class CyclicDependencyException extends IllegalStateException
+{
+
+ /**
+ * stores the invocations in reverse call order
+ */
+ private final List<String> invocations = new ArrayList<String>();
+ private String tailComponentName;
+ private boolean cycleComplete;
+
+ /**
+ * Records this invocation's component name and method to be displayed in
+ * {@link #getMessage()}, unless this invocation is not part of the detected
+ * cycle. This method will be successively called as the exception is
+ * propagated up the stack.
+ *
+ * @param componentName
+ * @param method
+ */
+ public void addInvocation(String componentName, Method method)
+ {
+ if (cycleComplete)
+ {
+ return;
+ }
+
+ if (invocations.isEmpty())
+ {
+ tailComponentName = componentName;
+ }
+ else
+ {
+ if (tailComponentName.equals(componentName))
+ {
+ cycleComplete = true;
+ }
+ }
+ invocations.add(createInvocationLabel(componentName, method));
+ }
+
+ /**
+ * returns e.g. "foo.doSomething()"
+ */
+ private String createInvocationLabel(String componentName, Method method)
+ {
+ String invocationLabel = componentName + "." + method.getName() + "(";
+ int i = 1;
+ for (Class<?> parameterType : method.getParameterTypes())
+ {
+ invocationLabel += parameterType.getSimpleName();
+ if (i < method.getParameterTypes().length)
+ {
+ invocationLabel += ", ";
+ }
+ i++;
+ }
+ invocationLabel += ")";
+ return invocationLabel;
+ }
+
+ @Override
+ public String getMessage()
+ {
+ if (!cycleComplete)
+ {
+ return "Cyclic dependency found";
+ }
+ else
+ {
+ String message = "Injection into " + tailComponentName + " resulted in a dependency cycle, requiring the invocation of " + invocations.get(0) + ". The complete cycle: ";
+ for (int i = invocations.size() - 1; i >= 0; i--)
+ {
+ message += invocations.get(i);
+ if (i != 0)
+ message += " -> ";
+ }
+ return message;
+ }
+ }
+
+}
Property changes on: trunk/src/main/org/jboss/seam/CyclicDependencyException.java
___________________________________________________________________
Name: svn:mergeinfo
+
Modified: trunk/src/main/org/jboss/seam/core/BijectionInterceptor.java
===================================================================
--- trunk/src/main/org/jboss/seam/core/BijectionInterceptor.java 2008-09-02 04:53:18 UTC (rev 8874)
+++ trunk/src/main/org/jboss/seam/core/BijectionInterceptor.java 2008-09-02 04:56:23 UTC (rev 8875)
@@ -4,6 +4,7 @@
import java.util.concurrent.locks.ReentrantLock;
import org.jboss.seam.Component;
+import org.jboss.seam.CyclicDependencyException;
import org.jboss.seam.annotations.intercept.AroundInvoke;
import org.jboss.seam.annotations.intercept.Interceptor;
import org.jboss.seam.intercept.AbstractInterceptor;
Deleted: trunk/src/main/org/jboss/seam/core/CyclicDependencyException.java
===================================================================
--- trunk/src/main/org/jboss/seam/core/CyclicDependencyException.java 2008-09-02 04:53:18 UTC (rev 8874)
+++ trunk/src/main/org/jboss/seam/core/CyclicDependencyException.java 2008-09-02 04:56:23 UTC (rev 8875)
@@ -1,96 +0,0 @@
-package org.jboss.seam.core;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An exception that is thrown when {@link BijectionInterceptor} detects that a
- * component's dependencies cannot be injected due to a cyclic dependency. As
- * the exception is passed up the stack, the call sequence is recorded so that a
- * useful exception message can be constructed.
- *
- * @author Matt Drees
- *
- */
-public class CyclicDependencyException extends IllegalStateException
-{
-
- /**
- * stores the invocations in reverse call order
- */
- private final List<String> invocations = new ArrayList<String>();
- private String tailComponentName;
- private boolean cycleComplete;
-
- /**
- * Records this invocation's component name and method to be displayed in
- * {@link #getMessage()}, unless this invocation is not part of the detected
- * cycle. This method will be successively called as the exception is
- * propagated up the stack.
- *
- * @param componentName
- * @param method
- */
- public void addInvocation(String componentName, Method method)
- {
- if (cycleComplete)
- {
- return;
- }
-
- if (invocations.isEmpty())
- {
- tailComponentName = componentName;
- }
- else
- {
- if (tailComponentName.equals(componentName))
- {
- cycleComplete = true;
- }
- }
- invocations.add(createInvocationLabel(componentName, method));
- }
-
- /**
- * returns e.g. "foo.doSomething()"
- */
- private String createInvocationLabel(String componentName, Method method)
- {
- String invocationLabel = componentName + "." + method.getName() + "(";
- int i = 1;
- for (Class<?> parameterType : method.getParameterTypes())
- {
- invocationLabel += parameterType.getSimpleName();
- if (i < method.getParameterTypes().length)
- {
- invocationLabel += ", ";
- }
- i++;
- }
- invocationLabel += ")";
- return invocationLabel;
- }
-
- @Override
- public String getMessage()
- {
- if (!cycleComplete)
- {
- return "Cyclic dependency found";
- }
- else
- {
- String message = "Injection into " + tailComponentName + " resulted in a dependency cycle, requiring the invocation of " + invocations.get(0) + ". The complete cycle: ";
- for (int i = invocations.size() - 1; i >= 0; i--)
- {
- message += invocations.get(i);
- if (i != 0)
- message += " -> ";
- }
- return message;
- }
- }
-
-}
Modified: trunk/src/test/unit/org/jboss/seam/test/unit/InterceptorTest.java
===================================================================
--- trunk/src/test/unit/org/jboss/seam/test/unit/InterceptorTest.java 2008-09-02 04:53:18 UTC (rev 8874)
+++ trunk/src/test/unit/org/jboss/seam/test/unit/InterceptorTest.java 2008-09-02 04:56:23 UTC (rev 8875)
@@ -8,6 +8,7 @@
import javax.faces.event.PhaseId;
import org.jboss.seam.Component;
+import org.jboss.seam.CyclicDependencyException;
import org.jboss.seam.NoConversationException;
import org.jboss.seam.RequiredException;
import org.jboss.seam.Seam;
@@ -20,7 +21,6 @@
import org.jboss.seam.core.ConversationEntries;
import org.jboss.seam.core.ConversationInterceptor;
import org.jboss.seam.core.ConversationalInterceptor;
-import org.jboss.seam.core.CyclicDependencyException;
import org.jboss.seam.core.Events;
import org.jboss.seam.core.Init;
import org.jboss.seam.core.Interpolator;
16 years, 8 months
Seam SVN: r8874 - branches/Seam_2_0/src/main/org/jboss/seam/core.
by seam-commits@lists.jboss.org
Author: matt.drees
Date: 2008-09-02 00:53:18 -0400 (Tue, 02 Sep 2008)
New Revision: 8874
Modified:
branches/Seam_2_0/src/main/org/jboss/seam/core/BijectionInterceptor.java
Log:
JBSEAM-3362
add context info even if CyclicDependencyException is wrapped by another exception
Modified: branches/Seam_2_0/src/main/org/jboss/seam/core/BijectionInterceptor.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/core/BijectionInterceptor.java 2008-09-02 04:53:02 UTC (rev 8873)
+++ branches/Seam_2_0/src/main/org/jboss/seam/core/BijectionInterceptor.java 2008-09-02 04:53:18 UTC (rev 8874)
@@ -4,11 +4,11 @@
import java.util.concurrent.locks.ReentrantLock;
import org.jboss.seam.Component;
-import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.intercept.AroundInvoke;
import org.jboss.seam.annotations.intercept.Interceptor;
import org.jboss.seam.intercept.AbstractInterceptor;
import org.jboss.seam.intercept.InvocationContext;
+import org.jboss.seam.util.EJB;
/**
* Before invoking the component, inject all dependencies. After
@@ -98,10 +98,19 @@
return result;
}
- catch (CyclicDependencyException cyclicDependencyException)
+ catch (Exception e)
{
- cyclicDependencyException.addInvocation(getComponent().getName(), invocation.getMethod());
- throw cyclicDependencyException;
+ Exception root = e;
+ while (EJB.getCause(root) != null)
+ {
+ root = EJB.getCause(root);
+ }
+ if (root instanceof CyclicDependencyException)
+ {
+ CyclicDependencyException cyclicDependencyException = (CyclicDependencyException) root;
+ cyclicDependencyException.addInvocation(getComponent().getName(), invocation.getMethod());
+ }
+ throw e;
}
finally
{
16 years, 8 months