All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wicketstuff.webflow.components.WebFlowContainerPanel Maven / Gradle / Ivy

There is a newer version: 1.4.21
Show newest version
/**
 * 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.
 *
 * Contributed by United Services Automotive Association (USAA)
 */
package org.wicketstuff.webflow.components;

import org.apache.wicket.Component;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.IHeaderContributor;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.protocol.http.WebResponse;
import org.apache.wicket.util.string.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wicketstuff.webflow.FlowUtils;
import org.wicketstuff.webflow.IFlowContainerPanel;
import org.wicketstuff.webflow.PageFlowConstants;
import org.wicketstuff.webflow.controller.SpringWebFlowFacade;
import org.wicketstuff.webflow.session.FlowState;
import org.wicketstuff.webflow.session.PageFlowSession;


/**
 *  Container Panel for Panel Flow Applications.
 *
 * @author Clint Checketts, Florian Braun, Doug Hall, Subramanian Murali
 * @version $Id: $
 */
//TODO Namespace the dynamically rendered java script
public class WebFlowContainerPanel extends Panel implements IHeaderContributor, IFlowContainerPanel
{

	private static final Logger LOG = LoggerFactory.getLogger(WebFlowContainerPanel.class);
	private static final long serialVersionUID	= 1L;
	
	/**
	 * The panel holding the contents displayed by the flow
	 */
	private Panel contentPanel;
	
	/**
	 * Constructor.
	 *
	 * @param id - Mark Up Id.
	 */
	public WebFlowContainerPanel(String id)
	{
		super(id);
		
		
		//Add a  panel that actually holds the content.
		setContentPanel(new WebFlowPanel(PageFlowConstants.FLOW_CONTENT_PANEL)); //NOPMD 
		
		//This behavior generates a java script "goBackTo(flowExecutionKey)" 
		//which will be called by YUI history manager when the user hits the back button on the browser.
		this.add(new CallBackBehavior());	
	}
	

	/**
	 * 

Getter for the field contentPanel.

* * @return a {@link org.apache.wicket.markup.html.panel.Panel} object. */ public Panel getContentPanel() { return contentPanel; } /** {@inheritDoc} */ public void setContentPanel(Panel newContentPanel) { addOrReplace(newContentPanel); this.contentPanel = newContentPanel; } /** {@inheritDoc} */ public void renderHead(IHeaderResponse response) { response.renderCSSReference(new ResourceReference(WebFlowContainerPanel.class,"WebFlowContainerPanel.css")); response.renderJavascriptReference(new ResourceReference(WebFlowContainerPanel.class,"WebFlowContainerPanel.js")); //These header setting tell the browser to always get he freshest content from the server so it doesn't cache // and display the wrong page in the flow, when it should truly be fetching a new page. if(response instanceof WebResponse){ ((WebResponse)response).setHeader("Pragma", "no-cache"); ((WebResponse)response).setHeader("Cache-Control", "no-cache, max-age=0, must-revalidate, no-store"); } } /** * {@inheritDoc} * * Hook that allows implementing classes to hook into the change event */ public void onPanelFlowChange(AjaxRequestTarget target) { } /** * Method that returns the class name of the content panel to be rendered for the incoming back button request from the client. * This method determines the class name of the content panel based on the flow execution key available in the request and * the value of the current view state available in the web flow session. This method also sets error / warning messages in the * page flow session during this process of determining the content panel class name. * * @return String - Wizard content panel class name. */ private Class getContentPanelClass() { //Variable that represents the content panel class to be returned Class contentPanelClass = null; //Retrieve the flow execution key available in the request String flowExecutionKey = RequestCycle.get().getRequest().getParameter(PageFlowConstants.FLOW_EXECUTION_KEY); //Retrieve the WebFlow Session FlowState flowState = PageFlowSession.get().getFlowState(); //Retrieve the current view state from Web Flow Session String currentViewState = flowState.getCurrentViewState(); //There is no flow execution key available in the request. if(Strings.isEmpty(flowExecutionKey)) { contentPanelClass = getPanelClassNoKey(flowState,currentViewState); } //There is flow execution key available in the request. //The flow execution key available in the request is DONE. else if(PageFlowConstants.PAGE_FLOW_FINAL_STATE_DONE.equals(flowExecutionKey)) { contentPanelClass = getPanelClassDoneKey(flowState,currentViewState); } else if(PageFlowConstants.PANEL_FLOW_INITIAL_STATE.equals(flowExecutionKey)) { //Set the start view state as null in the session. //Setting the start view state as null will let the home panel class name to be determined by //launching a new flow. flowState.setStartViewState(null); //Set the home panel class name as the content panel class name. contentPanelClass = FlowUtils.getFlowStartStateClass(); } //The flow execution key available in the request is not DONE. else { contentPanelClass = getPanelClassOtherKey(flowState,currentViewState,flowExecutionKey); } return contentPanelClass; } private Class getPanelClassOtherKey(FlowState flowState, String currentViewState, String flowExecutionKey) { Class contentPanelClass; //There is no current view state available in the session. if(Strings.isEmpty(currentViewState)) { //Set the start view state as null in the session. //Setting the start view state as null will let the home panel class name to be determined by //launching a new flow. flowState.setStartViewState(null); //Set the home panel class name as the content panel class name contentPanelClass = FlowUtils.getFlowStartStateClass(); } else if(new SpringWebFlowFacade().isFlowExecutionKeyValid(flowExecutionKey)) { //The input flow execution key is the same as the current view state in session. if(currentViewState.equals(flowExecutionKey)) { //Retrieve the view state class for the input flow execution key. //Set the view state class name for the input flow execution key as the content panel class name contentPanelClass = new SpringWebFlowFacade().getViewStateClass(flowExecutionKey); //Set the last rendered view class as the retrieved view state class. flowState.setLastRenderedViewClass(contentPanelClass); } else { //Set the current view state as the input flow execution key. flowState.setCurrentViewState(flowExecutionKey); //Retrieve the view state class for the input flow execution key. Class viewStateClass = new SpringWebFlowFacade().getViewStateClass(flowExecutionKey); //Set the view state class name for the input flow execution key as the content panel class name if(viewStateClass != null){ contentPanelClass = viewStateClass; //Set the last rendered view class as the retrieved view state class. flowState.setLastRenderedViewClass(contentPanelClass); } else { // WebSession.get().error(WicketConstants.FLOW_TRANSITION_ERROR); FlowUtils.addFeedbackErrorBadUrl("FLOW_CONTAINER_3"); contentPanelClass = flowState.getLastRenderedViewClass(); } } } //The flow execution key is not valid. else { //The current view state in the session is DONE. if(currentViewState.equals(PageFlowConstants.PAGE_FLOW_FINAL_STATE_DONE)) { //Set an error message in the Wicket session. //The Application Flow is complete. You cannot traverse back. // WebSession.get().error(WicketConstants.FLOW_TRANSITION_ERROR); FlowUtils.addFeedbackErrorBackDisallowed("FLOW_CONTAINER_1"); //Set the last rendered view class name as the content panel class name. contentPanelClass = flowState.getLastRenderedViewClass(); } else { //The flow execution key is messed up // WebSession.get().error(WicketConstants.FLOW_TRANSITION_ERROR); FlowUtils.addFeedbackErrorBadUrl("FLOW_CONTAINER_2"); //Set the last rendered view class name as the content panel class name. contentPanelClass = flowState.getLastRenderedViewClass(); } } return contentPanelClass; } private Class getPanelClassDoneKey(FlowState flowState, String currentViewState) { Class contentPanelClass; //There is no current view state available in the session. if(Strings.isEmpty(currentViewState)) { //Set the start view state as null in the session. //Setting the start view state as null will let the home panel class name to be determined by //launching a new flow. flowState.setStartViewState(null); //Set the home panel class name as the content panel class name. contentPanelClass = FlowUtils.getFlowStartStateClass(); } //There is current view state available in the session. //The current view state in the session is DONE. else if(currentViewState.equals(PageFlowConstants.PAGE_FLOW_FINAL_STATE_DONE)) { //Set the last rendered view class as the final view class. flowState.setLastRenderedViewClass(flowState.getFinalViewClass()); //Set the final view class name as the content panel class name. contentPanelClass = flowState.getFinalViewClass(); } //The current view state is not DONE and the user has not already completed the application flow. else { //You cannot traverse to this page. //WebSession.get().error(WicketConstants.FLOW_TRANSITION_ERROR); FlowUtils.addFeedbackErrorBackDisallowed("FLOW_CONTAINER_4"); flowState.setHasPageFlowErrorMessages(true); //Set the last rendered view class name as the content panel class name. contentPanelClass = flowState.getLastRenderedViewClass(); } return contentPanelClass; } private Class getPanelClassNoKey(FlowState flowState, String currentViewState) { Class contentPanelClass; //There is no current view state available in the session. if(Strings.isEmpty(currentViewState)) { //Set the home panel class name as the content panel class name contentPanelClass = FlowUtils.getFlowStartStateClass(); } //There is current view state available in the session. //The current view state is DONE and the user has already completed the application flow. else if(currentViewState.equals(PageFlowConstants.PAGE_FLOW_FINAL_STATE_DONE)) { //Set the start view state as null in the session. //Setting the start view state as null will let the home panel class name to be determined by //launching a new flow. flowState.setStartViewState(null); //Set the home panel class name as the content panel class name contentPanelClass = FlowUtils.getFlowStartStateClass(); } //The current view state is not DONE and the user has not already completed the application flow. else { //Set the last rendered view class name as the content panel class name. contentPanelClass = flowState.getLastRenderedViewClass(); } return contentPanelClass; } private class CallBackBehavior extends AbstractDefaultAjaxBehavior { private static final long serialVersionUID = 1L; @Override public void renderHead(IHeaderResponse response) { super.renderHead(response); //Retrieve the current view state // String currentViewState = PageFlowSession.get().getFlowState().getCurrentViewState(); String callbackUrl = getCallbackUrl().toString(); if(callbackUrl.indexOf("flowExecutionKey=") != -1) { callbackUrl = callbackUrl.substring(0, callbackUrl.indexOf("&flowExecutionKey=")); //TODO Is there a possibility that there could be anything after the flow execution key //need to verify } StringBuffer sb = new StringBuffer() .append("function goBackTo(flowExecutionKey) { \n") .append(" wicketAjaxGet('").append(callbackUrl).append("&flowExecutionKey=' + flowExecutionKey);\n") .append("}\n"); response.renderJavascript(sb.toString(), "BackButtonJS"); } @Override protected void respond(AjaxRequestTarget target) { //Flow Panel that needs to be added to the Ajax Target Panel flowPanel = null; //Retrieve the content panel class name Class contentPanelClass = getContentPanelClass(); if(contentPanelClass != null) { //Retrieve the panel for the retrieved content panel class name flowPanel = FlowUtils.getPageFlowContentPanel(contentPanelClass); if(flowPanel != null) { flowPanel.setOutputMarkupId(true); contentPanel.replaceWith(flowPanel); contentPanel= flowPanel; } } else { LOG.error("Flow panel class name cannot be determined for the back button request from the client"); } if(flowPanel != null){ target.addComponent(flowPanel); } onPanelFlowChange(target); //NOPMD This is an expected extension point } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy