On 1/27/06, Gary VanMatre <[EMAIL PROTECTED]> wrote: Hi Gary,
> The basic idea creates a convention in the url for invoking the method. > contextroot/dynamic/remoting$business/cityAndStateForZip.faces?zip=80124 Right it's all about naming conventions :-) I looked a Business.java's cityAndStateForZip() method. I don't like the parameter lookup by ExternalContext inside of a backing bean That is equal to let your backing bean construktor handle that parameter stuff... I played during my train travel with somesthing similar. A given url: host/app/bookmark/test.faces?foo=HALLO&bar=moin > A phase listener intercepts "dynamic" folder as the special identifier. > Next comes the managed bean name and then the method. right. my phase listener intercepts "bookmark". I strip "/bookmark" from viewId, so I set it to "/test.jsp" (in this case) I also have (like Shale's view controller) the convention that "test" is the name of my backing bean bean (yes, something like host/app/bookmark/folder/test.faces?foo=HALLO&bar=moin will look for a "viewController named folder$test) Now the phase listener has the convention, that "foo" and "bar" are the bean properties and populates the bean with the given values. Of course, this is a first shot. May be it is to restrictive? However, let's see :-) PS: code is attached... because I am away from my *real* box, (had to use a usb stick to upload the file :-)) For Rendering the bookmarkable URL, I liked Adam's (or John's ;)) suggestion with the optional interface for the NavigationHandler -Matthias <code> /* * Copyright 2006 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. */ package net.wessendorf.faces.bookmark; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.faces.application.ViewHandler; import javax.faces.context.FacesContext; import javax.faces.el.ValueBinding; import javax.faces.event.PhaseEvent; import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * * @author matzew * */ public class BookmarkPhaseListener implements PhaseListener { private static final Log log = LogFactory.getLog(BookmarkPhaseListener.class); public static String BOOKMARK = "/bookmark"; private static final long serialVersionUID = 1L; public void afterPhase(PhaseEvent event) { FacesContext facesContext = event.getFacesContext(); if(facesContext.getViewRoot().getViewId().startsWith(BOOKMARK)) invokeApplication(facesContext); } public void invokeApplication(FacesContext facesContext) { String oldViewId = facesContext.getViewRoot().getViewId(); if(log.isTraceEnabled()) log.trace("Incomming view id: " + oldViewId); String newViewId = oldViewId.substring(BOOKMARK.length()); facesContext.getViewRoot().setViewId(newViewId); if(log.isTraceEnabled()) log.trace("new generated view id: " + newViewId); Map parameters = facesContext.getExternalContext().getRequestParameterMap(); Set keys = parameters.keySet(); ValueBinding vb = null; String beanName = extractViewControllerName(newViewId); if(!parameters.isEmpty()){ for(Iterator it = keys.iterator(); it.hasNext();){ String key = it.next().toString(); if(log.isTraceEnabled()) log.trace("Looking for vb: " + "#{" + beanName + "." + key + "}"); vb = facesContext.getApplication().createValueBinding("#{" + beanName + "." + key + "}"); vb.setValue(facesContext, parameters.get(key)); } } } private String extractViewControllerName(String newViewId) { String extract = newViewId.substring(1); extract = extract.substring(0,extract.indexOf(ViewHandler.DEFAULT_SUFFIX)); if(StringUtils.contains(extract, "/")){ extract = StringUtils.replace(extract, "/", "$"); } return extract; } public void beforePhase(PhaseEvent event) { } public PhaseId getPhaseId() { return PhaseId.RESTORE_VIEW; } } </code>