Block entire page - jsf-2

When I change the page (page1 to page2) exists some delay and it is possible to click other buttons and these actions go run. So I would like to block the page during the waiting time for loading the following page, how do I?
I use jsf2 and primefaces.
At this time already tested blockUI and blockUI-extensions -> not work

You should tell us. Why p:blockUI is not work?
Try this. It is work.
page1.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<f:facet name="first">
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8" />
<meta name="viewport"
content="user-scalable=no,
width=device-width,
initial-scale=1.0,
maximum-scale=1.0"/>
</f:facet>
<title>page1</title>
</h:head>
<h:body id="bodyView">
page1
<h:form id="form1">
<p:editor id="editor"
widgetVar="editorWidget"
width="600" />
</h:form>
<h:form id="form2">
<p:blockUI block=":bodyView"
widgetVar="bui"/>
<p:commandButton id="redirect"
value="go to page2"
onclick="PF('bui').show();"
actionListener="#{blockView.redirect}"/>
</h:form>
</h:body>
</html>
page2.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<f:facet name="first">
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8" />
<meta name="viewport"
content="user-scalable=no,
width=device-width,
initial-scale=1.0,
maximum-scale=1.0"/>
</f:facet>
<title>page2</title>
</h:head>
<h:body>
<h:form>
page2
</h:form>
</h:body>
</html>
MangedBean
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
/**
*
* #author Wittakarn
*/
#ViewScoped
#ManagedBean(name = "blockView")
public class BlockView implements Serializable{
public void redirect(ActionEvent event){
try {
Thread.sleep(4000);
FacesContext.getCurrentInstance().getExternalContext().redirect("page2.xhtml");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

Related

JSF selectOneMenu not saving Value to SessionScopedBean [duplicate]

This question already has answers here:
Conversion Error setting value for 'null Converter' - Why do I need a Converter in JSF?
(2 answers)
Closed 6 years ago.
I have a problem with the JSF selectOneMenu.
Here is my menu:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<ui:composition template="./../WEB-INF/templates/templateLC.xhtml">
<ui:define name="headtags">
<title>Title</title>
</ui:define>
<ui:define name="left">
<ui:include src="./../WEB-INF/templates/userCenterNavigation_left.xhtml"/>
</ui:define>
<ui:define name="content">
<h:form>
<table>
<tr>
<td>Kategorie:</td>
<td><h:selectOneMenu value="#{zbnEditController.zbnCategory}">
<f:selectItems value="#zbnEditController.zbnCategoryMap}"/>
</h:selectOneMenu>
</td>
</tr>
</table>
<br />
<h:commandButton value="Hinzufügen" action="#{zbnEditController.doSave()}" />
<h:commandButton value="Abbrechen" action="index.xhtml?faces-redirect=true" />
</h:form>
This is a part of my template:
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<h:outputStylesheet name="/css/newCssLayout.css"/>
<ui:insert name="headtags" />
</h:head>
This is my Bean with the Map property:
#Named
#SessionScoped
public class ZbnEditController implements Serializable {
#Inject
private ZbnCategoryService zbnCategoryService;
.
.
.
private Map<String,ZbnCategory> zbnCategoryMap = new HashMap<>();
//Getter & Setters...
public void doSave(){
//persist Entity Code
}
public void loadZbnCategoryMap(){
getZbnCategoryMap().clear();
List<ZbnCategory> zbnCategoryList = zbnCategoryService.getAllZbnCategorys();
for(ZbnCategory zbnCategoryInList : zbnCategoryList){
zbnCategoryMap.put(zbnCategoryInList.getZbnCategoryName(), zbnCategoryInList);
}
}
}
Before the page is rendered, a Controller, calls loadZbnCategoryMap() and fills the map with the String and the object.
There are no nested forms, no ui component has a rendered=false attribute and I included the "h:head" tag instead of "head".
If I use the code above and click the commandButton, the doSave() method IS NOT called. If I remove the h:selectOneMenu, everything works fine.
I don´t know how I can solve this problem. Can someone help please?
I somehow "solved" the problem. It seems, that h:selectOneMenu has problems with saving objects to a bean.
Found a workaround that I save a String to the bean and just before persisting the Object, I use that String to load the entity from the database.

How to pass method expression to the Facelets tagfile

I created a tagfile for a confirm dialog with a command button:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:aym="http://aym.com/facelets"
xmlns:rich="http://richfaces.org/rich"
>
<h:body>
<ui:composition>
<p:growl id="messages" />
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="#{label}" onclick="#{pupupId}.show()" type="button" ajax="false"/>
</h:panelGrid>
<p:confirmDialog message="#{message}"
showEffect="bounce" hideEffect="explode"
header="İşlem Onay" severity="alert" widgetVar="#{pupupId}">
<p:commandButton value="Evet" update="messages" oncomplete="#{pupupId}.hide()" ajax="false"
action="#{actionMethod}" />
<p:commandButton value="Hayır" onclick="#{pupupId}.hide()" type="button" />
</p:confirmDialog>
</ui:composition>
</h:body>
</html>
Here's how I'm using it:
<aym:onayButon id="onay2" label="#{lbl.kaydet}"
actionMethod="#{userMB.addUser}" pupupId="onaylaPopup"
message="#{msg.onay_sonuc}" />
I am passing the action method that I am going to call when I click the button. However, when I do that, then I am getting a PropertyNotFoundException:
WARNING: #{actionMethod}: javax.el.PropertyNotFoundException: /WEB-INF/tags/com/components/onayButton.xhtml #29,33 action="#{actionMethod}": /pages/index.xhtml #33,48 actionMethod="#{userMB.addUser}": Property 'addUser' not found on type com.otv.managed.bean.UserManagedBean
javax.faces.FacesException: #{actionMethod}: javax.el.PropertyNotFoundException: /WEB-INF/tags/com/components/onayButton.xhtml #29,33 action="#{actionMethod}": /pages/index.xhtml #33,48 actionMethod="#{userMB.addUser}": Property 'addUser' not found on type com.otv.managed.bean.UserManagedBean
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
It works fine when I hardcode the action method in the tagfile like so:
<p:commandButton ... action="#{userMB.addUser}" />
How is this caused and how can I solve it?
Try as a workaround to give action bean and action method as two separate parameters:
Template
<p:commandButton value="Evet"
update="messages" oncomplete="#{pupupId}.hide()" ajax="false"
action="#{actionBean[actionMethod]}" />
call
<aym:onayButon id="onay2" label="#{lbl.kaydet}"
actionBean="#{userMB}" actionMethod="addUser" pupupId="onaylaPopup"
message="#{msg.onay_sonuc}" />
On the call, the bean needs to be in curly brackets, the method name is only given as string. See also Solution on a similar topic .
Maybe it helps...

How to pass custom facelet tag attr to implementation in JSF 2

I have the next:
/src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="utf-8"?>
<webapp>
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/my-taglib.xml</param-value>
</context-param>
</webapp>
/src/main/webapp/WEB-INF/my-tablib.xml
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0">
<namespace>http://example.com/jsf/taglib</namespace>
<tag>
<tag-name>my-tag</tag-name>
<!-- /src/main/webapp/WEB-INF/tags/com/example/myTag.xml -->
<source>tags/com/example/myTag.xml</source>
</tag>
</facelet-taglib>
/src/main/webapp/WEB-INF/tags/com/example/myTag.xml
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="customAttr" />
</composite:interface>
<composite:implementation>
<h:outputText value="#{cc.attrs.customAttr}" />
</composite:implementation>
</html>
/src/main/webapp/index.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:exui="http://example.com/jsf/taglib">
<h:head>
</h:head>
<h:body>
<exui:my-tag customAttr="showMe" />
</h:body>
</html>
As the result, I don't see "showMe" message after war was deployed. How to fix that?
You put the composite component in /resources/<composite name> folder(no need to add my-tablib.xml to web.xml),
for example:
and then you can use by declare:
<html xmlns="http://www.w3.org/1999/xhtml"
...
xmlns:cps="http://java.sun.com/jsf/composite/composites/CPSI35"
>
...
<cps:cpscontact ....></cps:cpscontact>

Component ID form:composite:j_id2 has already been found in the view

/test.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:composite="http://java.sun.com/jsf/composite/components">
<f:view>
<h:head>
<title>Default Title</title>
</h:head>
<h:body>
<h:form id="form">
<composite:test id="composite"/>
</h:form>
</h:body>
</f:view>
</html>
/resources/components/test.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:composite="http://java.sun.com/jsf/composite/components"
xmlns:p="http://primefaces.org/ui">
<head>
<title>(For validation only)</title>
</head>
<body>
<cc:interface>
</cc:interface>
<cc:implementation>
<p:panel header="header foo bar">
<p:panel>
<f:facet name="header">
<h:outputText value="foo"/>
<h:outputText value="bar"/>
</f:facet>
</p:panel>
</p:panel>
</cc:implementation>
</body>
</html>
This combination gives:
GRAVE: Error Rendering View[/test.xhtml]
java.lang.IllegalStateException: Component ID form:composite:j_id2 has already been found in the view.
with this tree:
GRAVE: JSF1007: Duplicate component ID form:composite:j_id2 found in view.
GRAVE: +id: j_id1
type: javax.faces.component.UIViewRoot#47080ae5
+id: javax_faces_location_HEAD
type: com.sun.faces.component.ComponentResourceContainer#2daf59b3
+id: j_id3
type: javax.faces.component.UIOutput#532a0e33
+id: j_id4
type: javax.faces.component.UIOutput#6e0a60ec
+id: j_id5
type: javax.faces.component.UIOutput#6b615e64
+id: j_id6
type: javax.faces.component.UIOutput#457c2e4f
+id: j_id7
type: javax.faces.component.UIOutput#5bc4682c
+id: j_id8
type: javax.faces.component.UIOutput#3b934fc5
+id: j_idt37
type: <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+id: j_idt38
type: <html xmlns="http://www.w3.org/1999/xhtml">
+id: j_idt39
type: javax.faces.component.UIOutput#610364d1
+id: j_idt40
type:
<title>Default Title</title>
+id: j_idt55
type: javax.faces.component.UIOutput#25d00719
+id: form
type: javax.faces.component.html.HtmlForm#7c820db3
+id: composite
type: javax.faces.component.UINamingContainer#3e51a2a1
+id: j_id2
type: javax.faces.component.UIPanel#445a2d11
+id: j_idt52
type: org.primefaces.component.panel.Panel#618c17fd
+id: j_idt53
type: org.primefaces.component.panel.Panel#347b1513
+id: j_id2
type: javax.faces.component.UIPanel#7c44da25
+id: j_idt50
type: javax.faces.component.html.HtmlOutputText#7ca4ad4f
+id: j_idt54
type: javax.faces.component.html.HtmlOutputText#1f6e5d77
+id: j_idt47
type:
</html>
However, if I change composite component this way:
/resources/components/test.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:composite="http://java.sun.com/jsf/composite/components"
xmlns:p="http://primefaces.org/ui">
<head>
<title>(For validation only)</title>
</head>
<body>
<cc:interface>
</cc:interface>
<cc:implementation>
<p:panel header="header foo bar">
<p:panel>
<f:facet name="header">
<h:panelGroup>
<h:outputText value="foo"/>
<h:outputText value="bar"/>
</h:panelGroup>
</f:facet>
</p:panel>
</p:panel>
</cc:implementation>
</body>
</html>
Adding a <h:panelGroup> in <f:facet> solves the problem.
Bad tree indexing or am I missing something? I'm using mojarra 2.1.3 and PrimeFaces 3.0.M4-SNAPSHOT under Glassfish 3.1.1.
According to JSF2 documentations, The <f:facet> tag can have only one child. If you have many elements which you want to nest inside a facet tag, you should first wrap them in some other container like <h:panelGroup>, then put that single parent container in the <f:facet>.
exactly what you have done!
Here is the reference:
JavaServer Faces 2.0, The Complete Reference - Authors: Ed Burns, Chris Schalk
(ISBN-10: 0071625097 | ISBN-13: 978-0071625098)
Page Number: 538
Abstract:
The f:facet tag signifies a nested component that has a special
relationship to its enclosing tags. For example, stating that the
"header" of a table is to be provided by a JSF component. This element
adds the component represented by the JSF action in its body as a
facet with the specified name to the component represented by the
closest JSF component parent action element. This tag only allows one
component to be nested whithin itself. To use multiple component as a
facet, create them as children of a simple container component. For
example, nest the corresponding HTML library component actions within
the body a panelGroup component.
Regarding error JSF1007 please check out this : artilce

JSF 2 facelets <f:metadata/> in template and page

I have the following template (masterLayout.xhtml):
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:view contentType="text/html">
<ui:insert name="metadata"/>
<h:head>
<title><ui:insert name="windowTitle"/> | MySite</title>
</h:head>
<h:body>
<div id="container">
<div id="header">
<ui:insert name="header">
<ui:include src="/WEB-INF/templates/header.xhtml"/>
</ui:insert>
</div>
<div id="content">
<ui:insert name="content"/>
</div>
<div id="footer">
<ui:insert name="footer">
<ui:include src="/WEB-INF/templates/footer.xhtml"/>
</ui:insert>
</div>
</div>
</h:body>
</f:view>
</html>
and page that uses it (search.xhtml):
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title></title>
</h:head>
<h:body>
<ui:composition template="/WEB-INF/templates/masterLayout.xhtml">
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="address" value="#{searchBean.address}"/>
<f:event type="preRenderView" listener="#{userSessionBean.preRenderViewCookieLogin(e)}"/>
<f:event type="preRenderView" listener="#{searchBean.preRenderView(e)}"/>
</f:metadata>
</ui:define>
<ui:define name="windowTitle">#{searchBean.address}</ui:define>
<ui:define name="content">
<!-- Content goes here -->
</ui:define>
</ui:composition>
</h:body>
</html>
The problem is that I want to place the call to userSessionBean.preRenderViewCookieLogin(e) in the template because there are many other pages. This method checks that the user is logged in (according to session state) and, if not, checks that a cookie is available which can be used to log the user in and, if so (and if valid), logs the user in automatically. The system works in the code above, but when I try to push this into the template, my view parameters are no longer being set.
Here's the modified version of the above, with userSessionBean.preRenderViewCookieLogin(e) pushed up to the template.
masterLayout.xhtml:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:view contentType="text/html">
<f:metadata>
<f:event type="preRenderView" listener="#{userSessionBean.preRenderViewCookieLogin(e)}"/>
<ui:insert name="metadata"/>
</f:metadata>
<h:head>
<title><ui:insert name="windowTitle"/> | MySite</title>
</h:head>
<h:body>
<div id="container">
<div id="header">
<ui:insert name="header">
<ui:include src="/WEB-INF/templates/header.xhtml"/>
</ui:insert>
</div>
<div id="content">
<ui:insert name="content"/>
</div>
<div id="footer">
<ui:insert name="footer">
<ui:include src="/WEB-INF/templates/footer.xhtml"/>
</ui:insert>
</div>
</div>
</h:body>
</f:view>
</html>
search.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title></title>
</h:head>
<h:body>
<ui:composition template="/WEB-INF/templates/masterLayout.xhtml">
<ui:define name="metadata">
<f:viewParam name="address" value="#{searchBean.address}"/>
<f:event type="preRenderView" listener="#{searchBean.preRenderView(e)}"/>
</ui:define>
<ui:define name="windowTitle">#{searchBean.address}</ui:define>
<ui:define name="content">
<!-- Content goes here -->
</ui:define>
</ui:composition>
</h:body>
</html>
Notice that I've moved the <f:metadata/> tag to the template. That alone is the problem as removing userSessionBean.preRenderViewCookieLogin(e) makes no difference. I also tried a variation on the code that worked, which was to just move userSessionBean.preRenderViewCookieLogin(e) into the template which means it can't be inside the <f:metadata/> tag. In this case, that method executed after all the view parameters had been set and searchBean.preRenderView(e) called. I want userSessionBean.preRenderViewCookieLogin(e) to be called before any page's preRenderView(e) is called, not after. And just for fun I tried putting an <f:metadata/> around userSessionBean.preRenderViewCookieLogin(e), which called this method, but didn't set the view parameters.
So, I would like to know:
Why is this happening and is there a way to fix it?
Is there a better way to ensure the same method is called for each page before anything else?
Edit:
I just tried something else - a phase event:
<f:view contentType="text/html" beforePhase="#{userSessionBean.beforePhase(e)}">
This is in masterLayout.xhtml. It is not being called at all; not for any phase.
Edit:
Removed the e (damn you NetBeans!):
<f:view contentType="text/html" beforePhase="#{userSessionBean.beforePhase}">
This is only called before the render response phase, which of course means it's called after the preRenderView event is raised.
Why is this happening and is there a way to fix it?
From the <f:metadata> tag documentation (emphasis of 2nd paragraph is mine):
Declare the metadata facet for this view. This must be a child of the <f:view>. This tag must reside within the top level XHTML file for the given viewId, or in a template client, but not in a template. The implementation must insure that the direct child of the facet is a UIPanel, even if there is only one child of the facet. The implementation must set the id of the UIPanel to be the value of the UIViewRoot.METADATA_FACET_NAME symbolic constant.
So, it really has to go in the top view, not in the template.
Is there a better way to ensure the same method is called for each page before anything else?
In your particular case, store the logged-in user as a property of a session scoped managed bean instead of a cookie and use a filter on the appropriate URL pattern to check it. Session scoped managed beans are in the filter available as HttpSession attributes. Homegrown cookies are unnecessary as you're basically reinventing the HttpSession here. Unless when you want a "remember me" facility, but this should not be solved this way. Do it in a filter as well.
See also:
Prevent accessing restricted page without login in Jsf2
I got this working using a PhaseListener instead.
public class CookieLoginPhaseListener implements PhaseListener
{
#Override
public void beforePhase(PhaseEvent event)
{
}
#Override
public void afterPhase(PhaseEvent event)
{
UserSessionBean userSessionBean = Util.lookupCdiBean("userSessionBean");
userSessionBean.handleAuthCookie();
}
#Override
public PhaseId getPhaseId()
{
return PhaseId.RESTORE_VIEW;
}
}
and the little bit of bean lookup magic is here:
public static <T> T lookupCdiBean(String name)
{
return (T) FacesContext.getCurrentInstance().getApplication().evaluateExpressionGet(FacesContext.getCurrentInstance(), "#{" + name + "}", Object.class);
}
Thanks to #BalusC for this: JSF - get managed bean by name. Since I'm using CDI, I can't use the more declarative #ManagedProperty option. Not a big deal though.

Resources