jsf 2 - JSF: how prevent stackoverflow due to recursion during build phase (despite rendered test) -


apologies not abstracting problem in dedicated test case, hope example real project simple enough describe problem.

i have javaee/jpa2/jsf web application every @entity element (or subclass) has templated view.xhtml page, , standard link generator composite component util:view_link.xhtml, invoked database id parameter. portion (only) of each view page represents expert system summary; portion can abstracted composite component, inclusion in view page or elsewhere.

i have introduced primefaces p:dialog modal popup displaying expert system summary portion (and additional diagnostics) when clicking on small status icon displayed next view link. if let status icon represented x looks this:

x link_to_element_by_id

click on 'link_to_element_by_id' , brings full view page.

click on 'x' icon (expert system test failure indicator) , pops p:dialog expert system summary (only).

so expert system portion of view page shared composite component.

but can lead recursion , stackoverflow if either:

  1. the popup p:dialog expert system summary shows status icon indicator of element being inspected.

  2. i include additional element view links along with status indicators (that launch p:dialog expert system summary).

i have tried using rendered tests using recursion blocking attribute 'preventrecursionondialog' fails, apparently because recursion happening during build phase.

q: how can block possible recursion using test variable ?

also, have tried c:if tests instead of jsf 'rendered' tests, seems variable tested not available under @viewscoped.

example, activity element, util_primefaces:dialog_summary merely customised encapsulation of p:dialog.

from util:status_activity.xhtml:

     <composite:attribute          name="activity"         required="true"         type="com.example.entity.activity"       />     <composite:attribute         name="preventrecursionondialog"         required="false"         default="false"         type="java.lang.boolean"         /> </composite:interface>  <composite:implementation>      <util_primefaces:dialog_summary          header="expert system summary report"         rendered="#{not cc.attrs.preventrecursionondialog}"         element="#{cc.attrs.activity}">          <!-- causes stackoverflowerror -->          <util:warn_insufficient_subactivities              activitycontainer="#{cc.attrs.activity}"             humantypedescription="composite activity"             preventrecursionondialog="true"             />          <util:expertsystem_activity activity="#{cc.attrs.activity}"/>      </util_primefaces:dialog_summary>     ..     <span          onclick="#{not cc.attrs.preventrecursionondialog ? ('dialog'.concat(cc.attrs.activity.id).concat('.show();')) : ''}"          style="float:left;"          class="icon-completed-#{cc.attrs.activity.acceptedeffective}-small"         title=".."         >&nbsp;</span> 

the util:warn_insufficient_subactivities (which shows subactivities of composite activity have not passed expert system test) can cause recursion:

    <cc:interface>     <cc:attribute name="activitycontainer" required="true" type="com.example.entity.iactivitycontainer"/>     <cc:attribute name="humantypedescription" required="true" type="java.lang.string"/>     <cc:attribute         name="preventrecursionondialog"         required="false"         default="false"         type="java.lang.boolean"         />  </cc:interface>   <cc:implementation>          <h:panelgroup          rendered="#{not cc.attrs.activitycontainer.sufficientsubactivitiesaccepted}">         <util:warn_box              message=".."             >             <!-- caution: can cause stackoverflow when list included in expertsystem p:dialog popup -->             <util:list_activity_compact                  list="#{cc.attrs.activitycontainer.activities}"                  preventrecursionondialog="#{cc.attrs.preventrecursionondialog}"                 rendered="#{not cc.attrs.preventrecursionondialog}"                 />                         </util:warn_box> 

and util:list_activity_compact shows list status icon indicators (which in turn can offer popup p:dialog expert system summary, , can recurse) , util:view_link:

    <cc:interface>      <cc:attribute          name="list" required="true" type="java.util.list"         />      <cc:attribute         name="preventrecursionondialog"         required="false"         default="false"         type="java.lang.boolean"         />  </cc:interface>  <cc:implementation>     <h:panelgroup display="block">         <ul class="view-field-list-medium">             <ui:repeat var="a" value="#{cc.attrs.list}">                 <li class="view-field-list">                     <util:status_activity                          activity="#{a}"                          preventrecursionondialog="#{cc.attrs.preventrecursionondialog}"/>                      <util:view_link element="#{a}"/>                 </li>             </ui:repeat>         </ul>     </h:panelgroup> </cc:implementation> 

the point of question test rendered="#{not cc.attrs.preventrecursionondialog}" not sufficient block recursion, though part recurse not rendered (blocked rendered test), seems recursion can still happen during jsf build phase.


btw encounter similar problem when want render particular composite component bound type, within subset of type choices; performing type test in 'rendered' not enough prevent type error. imagine below 'value' 1 of many element subclasses including activity, 1 wants display following composite component portion activity:

        <util:component_for_activity_only              activity="#{cc.attrs.value}"             rendered="#{cc.attrs.value['class'].simplename=='activity'}"             /> 

(cf. instanceof check in el expression language, , note that class string based type test solution not flexible, not work subclasses or interface tests.)

again, attempt block calling 'rendered' not enough, seems type test fails during build phase. solution recursion problem offer solution this. introduction (finally) of instanceof in jsf2 (vote here please http://java.net/jira/browse/jsp_spec_public-113) not here if used in 'rendered',

that question perfect example why dislike jsf: non-trivial (such - gasp - trying reuse code on large scale), need knowledge of jsf internals.

jsf represents view component tree. tree built out of view definition tag handlers, stateful, , lives until user leaves view. inclusion of composite component done tag handler. c:if implemented tag handler.

the component tree traversed during every phase of request processing lifecycle. individual components decide whether (or how many times) children processed. that's how rendered attribute implemented: during every phase, component checks whether rendered, , skips processing of (and children) if not.

the jsf view scope kept within uiviewroot, root node of component tree. therefore unavailable while tag handlers processed. that's 1 of many shortcomings :-)

so can do?

  1. you can include composite component every activity in activity tree, because inclusion happens @ view build time, can not occur on demand. setting aside problems of mutual recursion, wasteful create dialog every subactivity on off chance user want see particular dialog. can of course limit recursion c:if, need put information in scope available @ view build time.

  2. alternatively, can create single dialog in component tree, have show different activity @ different times binding current activity el-expression target update. of course means single dialog shown @ time. if need stack dialogs of subactivities, might create many dialogs tree deep.

  3. alternatively, can create single component recursively processes in every phase of request processing lifecycle. can either existing component adapt (such tree component), or 1 written scratch (which not trivial because component tree stateful, , state must preserved , restored every iteration of child components).


Comments

Popular posts from this blog

blackberry 10 - how to add multiple markers on the google map just by url? -

php - guestbook returning database data to flash -

delphi - Dynamic file type icon -