Hi Matt,

I don't see the jar there either at the moment. It was in jsfExt-source.zip
containing only one class file, which I've pasted below to give you an idea
of how it works.

Mark


/*
 * Copyright 2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * --
 * 
 * $Log: OnLoadPhaseListener.java,v $
 * Revision 1.1.1.1  2005/11/07 04:23:26  arobinson74
 * Initial import
 *
 */
package net.sf.jsfcomp.ext.onload;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.faces.FacesException;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * This class allows for actions to be run on the load of a JSF page. When a
page
 * is requested or a page is being redirected to due to a result of JSF
navigation
 * action result, this phase listener intercepts the call. Based on the
configuration
 * of on load phase listener, actions can be invoked based on the requested
view ID.
 * <p>
 * The configuration of the phase listener is needed. Inside of the web.xml
file
 * of the application, the onload-rules context property must be given.
 * This value should be a URL to where to find the XML file with the
configuration
 * information.
 * </p>
 * Example:
 * <pre>
 * &lt;context-param&gt;
 *      &lt;param-name&gt;onload-rules&lt;/param-name&gt;
 *      &lt;param-value&gt;/WEB-INF/onload-rules.xml&lt;/param-value&gt;
 * &lt;/context-param&gt;
 * </pre>
 * <p>
 * The XML file must use the onload-rules.xsd schema. An example file and
the
 * schema is included in the release.
 * </p>
 * <p>
 * The 'view-id' element of the configuration has the same functionality
 * of the NavigationHandler behavior. The view ID value of the XML element
 * must be exactly the view ID or part of the view ID followed by the '*'
 * character. To match all views, use a '*' as the view-id element value   
 * </p>
 *  
 * @version $Revision: 1.1.1.1 $
 * @author $Author: arobinson74 $
 */
public class OnLoadPhaseListener
        implements PhaseListener
{
        private final static long serialVersionUID = 1l;
        private static Log logger =
LogFactory.getLog(OnLoadPhaseListener.class);
        private List<NavigationRule> rules;

        /**
         * Default constructor
         */
        public OnLoadPhaseListener()
        {
                logger.info("OnLoadPhaseListener created");
        }
 
        /* (non-Javadoc)
         * @see
javax.faces.event.PhaseListener#afterPhase(javax.faces.event.PhaseEvent)
         */
        public void afterPhase(PhaseEvent event)
        {
                // nothing to do here
        }

        /* (non-Javadoc)
         * @see
javax.faces.event.PhaseListener#beforePhase(javax.faces.event.PhaseEvent)
         */
        public void beforePhase(PhaseEvent event)
        {
                processOnLoad(event.getFacesContext(), 
                        event.getFacesContext().getViewRoot().getViewId());

        }

        /* (non-Javadoc)
         * @see javax.faces.event.PhaseListener#getPhaseId()
         */
        public PhaseId getPhaseId()
        {
                return PhaseId.RENDER_RESPONSE;
        }

        /**
         * Allows someone to extend this class and handle any events
         * they want to accomplish before the control is handed to the
         * navigation handler. This function is only invoked when the
         * result of the on load action is not null and is not equal
         * to the success result
         * 
         * @param requestedViewId The original requested view ID
         * @param onLoadAction The action that was invoked on load
         * @param onLoadActionResult The on load actions result
         * @return true to let the control be passed to the navigation
handler,
         * false to abort the processing and let the current (requested)
view
         * be rendered
         */
        protected boolean beforeHandleNavigation(String requestedViewId,
                String onLoadAction, String onLoadActionResult)
        {
                return true;
        }
 
        private void processOnLoad(FacesContext ctx, String viewId)
        {
                NavigationRule rule;

                // ensure the settings have been loaded
                initialize();

                logger.debug("Processing on load of view " + viewId);
                rule = getRule(viewId);
                if (rule == null)
                {
                        logger.debug("No rule found for view " + viewId);
                        return;
                }
                else
                        processRule(ctx, rule, viewId);
        }

        private NavigationRule getRule(String viewId)
        {
                logger.debug("Looking for rule for view " + viewId);
                for (NavigationRule rule : this.rules)
                {
                        String rViewId = rule.getViewId();
                 
                        // check for exact match
                        logger.debug("Checking for exact match. Rule view: "
+ rViewId);
                        if (rViewId.equals(viewId)) 
                        {
                                logger.info("Found rule with exact match");
                                return rule;
                        }
                 
                        // see if the rule ends with a wildcard
                        if (rule.getViewId().endsWith("*") == false)
continue;
                 
                        String ruleViewPrefix = rule.getViewId();
                        ruleViewPrefix = ruleViewPrefix.substring(0,
ruleViewPrefix.length() - 1);
                        logger.debug("Checking if view starts with " +
ruleViewPrefix);
                 
                        if (viewId.startsWith(ruleViewPrefix) == false)
continue;
                 
                        logger.debug("Found rule for viewId path " +
rule.getViewId());
                        return rule;
                }
         
                return null;
        }
 
        private void processRule(FacesContext ctx, NavigationRule rule,
String viewId)
        {
                MethodBinding method =
ctx.getApplication().createMethodBinding(
                        rule.getAction(), new Class[0]);
         
                if (method == null)
                {
                        logger.warn("No method found for rule action " +
rule.getAction());
                        return;
                }
         
                logger.debug("Invoking action: " + rule.getAction());
 
                Object result = method.invoke(ctx, new Object[0]);

                if (result != null && (result instanceof String))
                {
                        if (result.equals(rule.successResult) == false)
                        {
                                // allow sub classes to abort the navigation
                                if (beforeHandleNavigation(viewId,
rule.getAction(), 
                                        (String)result) == false)
                                {
                                        logger.info("Before handle
navigation has aborted the on load " +
                                                "navigation");
                                        return;
                                }
                                logger.debug("Calling navigation handler
with result: "
                                        + result);
                         
                                // let the navigation handler implementation
handle the rest of the load
 
ctx.getApplication().getNavigationHandler().handleNavigation(ctx, 
                                        rule.getAction(), (String)result);
                         
                                // shouldn't be necessary, but make sure the
render response is called
                                // if the request wasn't redirected
                                if (!ctx.getResponseComplete())
                                        ctx.renderResponse();
                        }
                        else
                                logger.debug("Result is equal to the success
result. Result: " +
                                        rule.successResult);
                } 
                else
                {
                        if (logger.isDebugEnabled())
                                logger.debug("Result from rule is null or
not a string. Result: " + result);               
                }
        }
 
        private void initialize()
        {
                if (this.rules != null) return;
                loadConfiguration();
        }

        private synchronized void loadConfiguration()
        {
                if (this.rules != null) return;
                this.rules = new ArrayList<NavigationRule>();
                FacesContext ctx = FacesContext.getCurrentInstance();
                String url = ctx.getExternalContext().getInitParameter(
                        "onload-config");
         
                try
                {
                        if (url == null)
                        {
                                String msg = "The external context did not
have the 'onload-rules' initialization " +
                                        "parameter. Please check your
configuration.";
                                logger.error(msg);
                                throw new FacesException(msg);
                        }

                        logger.info("On Load configuration is being loaded
from " + url);
                        InputStream configStream =
FacesContext.getCurrentInstance()
 
.getExternalContext().getResourceAsStream(url);
                 
                        // get the XML parsing structure
                        DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
                        DocumentBuilder docBuilder =
dbf.newDocumentBuilder();
                        Document doc = docBuilder.parse(configStream);
                        XPath xpath = XPathFactory.newInstance().newXPath();

                        // pars out the rules
                        NodeList rules =
doc.getDocumentElement().getElementsByTagName(
                                "navigation-rule");
                        logger.info(rules.getLength() + " rule(s) have been
found");

                        for (int i = 0; i < rules.getLength(); i++)
                        {
                                NavigationRule rule;
                                Element node = (Element)rules.item(i);

                                rule = new
NavigationRule((String)xpath.evaluate("view-id",
                                        node, XPathConstants.STRING),
(String)xpath.evaluate(
                                        "action", node,
XPathConstants.STRING), (String)xpath
                                        .evaluate("success-result", node,
XPathConstants.STRING));

                                this.rules.add(rule);
                        }
                 
                        Collections.sort(this.rules);
                        if (logger.isDebugEnabled())
                        {
                                for (NavigationRule rule : this.rules)
                                        logger.debug("Rule: " + rule);
                        }
                }
                catch (Exception ex)
                {
                        logger.error("Failed to parse onload configuration",
ex);
                }
        }

        private class NavigationRule
                implements Comparable<NavigationRule>
        {
                private String action;
                private String viewId;
                private String successResult;

                NavigationRule(String viewId, String action, String
successResult)
                {
                        this.viewId = viewId;
                        this.action = action;
                        this.successResult = successResult;
                }

                /**
                 * @return Returns the successResult.
                 */
                String getSuccessResult()
                {
                        return this.successResult;
                }

                /**
                 * @return Returns the action.
                 */
                String getAction()
                {
                        return this.action;
                }

                /**
                 * @return Returns the fromViewId.
                 */
                String getViewId()
                {
                        return this.viewId;
                }

                @Override
                public String toString()
                {
                        return String.format("view-id: %s, action: %s,
success-result: %s",
                                new Object[] { this.viewId, this.action,
this.successResult });
                }

         
                /* (non-Javadoc)
                 * @see java.lang.Comparable#compareTo(T)
                 */
                public int compareTo(NavigationRule rule)
                {
                        // sort longest to shortest
                        return viewId.compareTo(rule.getViewId()) * -1;
                }
        }
}

-----Original Message-----
From: Matt Raible [mailto:[EMAIL PROTECTED] 
Sent: Thursday, February 08, 2007 1:40 AM
To: [email protected]
Subject: Re: [appfuse-user] Call default JSF managed bean method

On 2/7/07, md10024 <[EMAIL PROTECTED]> wrote:
>
> Catching up on your backlog? this post is almost a month old  ;^)
>
> alpha, beta, gamma, whatever... the source is provided and all it does 
> is a intercept the pre-load and give you a config file to specify 
> which URL patterns to intercept. It's simple enough to be low/no risk 
> and is quite handy. Do you use new code that the guy in the cube across
the aisle writes?
> Of course, after testing and verifying it you do. This is no different.
>
> I'm not saying it should be included in Appfuse, but just that it 
> solves a common complaint in JSF.

I agree it would be nice to solve this problem.  I downloaded the source for
this project, but didn't see any JARs or XML that have the solution to the
problem.  Is this On-Load Action Listener similar?

http://jsf-comp.sourceforge.net/components/onload/index.html

Thanks,

Matt

>
>
>
> Matt Raible-3 wrote:
> >
> > I'm a little leary of using a alpha0.1 version from an open source 
> > project that only has 1 developer and hasn't had a release in 3 years.
> > ;-)
> >
> > Matt
> >
> > On 1/18/07, Mark Dopheide <[EMAIL PROTECTED]> wrote:
> >>
> >> Yes! There is a cool add-in that I use for exactly this purpose. 
> >> Check out http://sourceforge.net/projects/jsfcomp/
> >>
> >> It's a sweet little phase listener that you can easily and 
> >> seamlessly add to handle this very thing. Since you can pass url's 
> >> like /myurl.html?cid=12 it gives convenient bookmarking support to 
> >> jsf also.
> >>
> >> Mark
> >> -----Original Message-----
> >> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> >> Sent: Wednesday, January 17, 2007 2:11 PM
> >> To: [email protected]
> >> Subject: [appfuse-user] Call default JSF managed bean method
> >>
> >>
> >> Hi
> >> Appfuse is using the struts-menu for its menu system and I like it 
> >> so I would prefer not to change it. Not my problem is that you 
> >> define the links for the menu in the menu-config.xml file. That 
> >> means NO JSF stuff there :| I have a link to a JSF page where the 
> >> backing bean has a method that I want to call. Normally you would 
> >> just use a commandLink og outputlink with the action attr set but 
> >> this is not possible ín this case because it's a struts-menu page. 
> >> How can you call a default method in a backing bean with a normal 
> >> link ?
> >>
> >> In appfuse the password page is using some javascript to call the 
> >> method when you call on the link but that looks like a hack to me . 
> >> Is there any alternative way ? The best would be to have a 
> >> menu-config that accepted JSF tags Cheers Tommy
> >> --
> >> View this message in context:
> >> http://www.nabble.com/Call-default-JSF-managed-bean-method-tf302924
> >> 8s2369..ht
> >> ml#a8416874
> >> Sent from the AppFuse - User mailing list archive at Nabble.com.
> >>
> >> -------------------------------------------------------------------
> >> -- To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> For additional commands, e-mail: [EMAIL PROTECTED]
> >>
> >>
> >> -------------------------------------------------------------------
> >> -- To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> For additional commands, e-mail: [EMAIL PROTECTED]
> >>
> >>
> >
> >
> >
> > --
> > http://raibledesigns.com
> >
> >
>
> --
> View this message in context: 
> http://www.nabble.com/Call-default-JSF-managed-bean-method-tf3029248s2
> 369.html#a8860123 Sent from the AppFuse - User mailing list archive at 
> Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>


--
http://raibledesigns.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to