com.arsdigita.bebop
Class PageState

java.lang.Object
  extended bycom.arsdigita.bebop.PageState

public class PageState
extends Object

The request-specific data (state) for a Page. All methods that need access to the state of the associated page during the processing of an HTTP request are passed a PageState object. Since PageState contains request-specific data, it should only be live during the servicing of one HTTP request. This class has several related responsibilites:

State Management

PageState objects store the values for global and component state parameters and are responsible for retrieving these values from the HTTP request. Components can access the values of their state parameters through the getValue and setValue methods.

This class is also responsible for serializing the current state of the page in a variety of ways for inclusion in the output: generateXML adds the state to an XML element and stateAsURL encodes the page's URL.

The serialized form of the current page state can be quite large so the page state can also be preserved in the HttpSession, on the server. The Page object specifies this by calling setUsingHttpSession(true). When this flag is set, then the page state will be preserved in the HttpSession, and the stateAsURL method will only serialize the current URL and the control event. It will also include a URL variable that the subsequent request uses to retrieve the correct page state from the HttpSession. If the page state for a particular request cannot be found, the constructor will throw a SessionExpiredException.

Up to getMaxStatesInSession() independent copies of the page state may be stored in the HttpSession, to preserve the behavior of the browser's "back" button.

Note: As a convention, only the component to which a state parameter belongs should modify it by calling getValue and setValue. All other objects should manipulate the state of a component only through well-defined methods on the component.

Control Events

The control event consists of a pair of strings, the name of the event and its associated value. Components use the control event to send themselves a "delayed signal", i.e. a signal that is triggered when the same page is requested again through a link that has been generated with the result of stateAsURL() as the target. The component can then access the name and value of the event with calls to getControlEventName() and getControlEventValue().

Typically, a component will contain code corresponding to the following in its generateXML method:

  public void generateXML(PageState state, Element parent) {
  if ( isVisible(state) ) {
      MyComponent target = firePrintEvent(state);
      Element link = new Element ("bebop:link", BEBOP_XML_NS);
      parent.addContent(link);
      target.generateURL(state, link);
      target.exportAttributes(link);
      target.generateExtraXMLAttributes(state, link);
      target.getChild().generateXML(state, link);
  }
  }
 
(In reality, the component would not write a bebop:link element directly, but use a ControlLink to do that automatically.)

When the user clicks on the link that the above generateXML method produces, the component's respond method is called and can access the name and value of the event with code similar to the following:

   public void respond(PageState state) {
     String name = state.getControlEventName();
     String value = state.getControlEventValue();
     if ( "name".equals(name) ) {
       doSomeStateChange(value);
     } else {
       throw new IllegalArgumentException("Can't understand event " + name);
     }
   }
 

Temporary Storage

Request local variables make it possible to store arbitrary objects in the page state and allow components (and other objects) to cache results of previous computations. For example, the Form component uses a request local variable to store the FormData it generates from the request and make it acessible to the widgets it contains, and to other components through calling Form.getFormData(state). See the documentation for RequestLocal on how to use your own request local variables.

Convenience Access to Related Objects

PageState objects store references to the HTTP request and response that is currently being served. Components are free to manipulate these objects as they see fit.

Version:
$Id: //core-platform/dev/src/com/arsdigita/bebop/PageState.java#22 $
Author:
David Lutterkort, Uday Mathur

Field Summary
static String versionId
           
 
Constructor Summary
PageState(Page page, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
          Construct the PageState for an HTTP request.
 
Method Summary
 void clearControlEvent()
          Clear the control event.
protected  BitSet decodeVisibility()
           
protected  BitSet encodeVisibility(BitSet current)
           
 void forceValidate()
          Force the validation of all global and component state parameters against their parameter models.
 void generateXML(Element parent)
          Add elements to parent that represent the current page state.
 void generateXML(Element parent, Iterator models)
           
 Object getAttribute(Object key)
          Deprecated. Use either getAttribute on the HTTP request object, or, preferrably, use a request local variable. Will be removed on 2001-06-13.
 String getControlEventName()
          Get the name of the control event.
 String getControlEventValue()
          Get the value associated with the control event.
 Iterator getErrors()
          Return an iterator over the errors that occurred in trying to validate the state parameters against their parameter models in Page.
 String getErrorsString()
          Return a string with all the errors that occurred in trying to validate the state parameters against their parameter models in Page.
 Object getGlobalValue(String name)
          Deprecated. Use getValue(ParameterModel m) instead. If you don't have a reference to the parameter model, you should not be calling this method. Instead, the component that registered the parameter should provide methods to manipulate it. Will be removed 2001-06-20.
static int getMaxStatesInSession()
          Returns the maximum number of independent page states that may be stored in the HttpSession, for preserving the behavior of the "back" button.
 Page getPage()
          Return the page for which this object holds the state.
static PageState getPageState()
          Returns the page state object for the current request, or null if none exists yet.
static PageState getPageState(javax.servlet.http.HttpServletRequest request)
          Returns the page state object for the given request, or null if none exists yet.
 javax.servlet.http.HttpServletRequest getRequest()
          Return the request object for the HTTP request.
 String getRequestURI()
          Get the URI to which the current request was made.
 javax.servlet.http.HttpServletResponse getResponse()
          Return the response object for the HTTP response.
 Object getValue(ParameterModel p)
          Get the value of state parameter p.
 void grabControlEvent(Component c)
          Grab the control event.
 boolean isValid()
          Return true if all the global and component state parameters extracted from the HTTP request were successfully validated against their parameter models in the Page.
 boolean isVisible(Component c)
          Return true is the comonent c is currently visible.
 boolean isVisibleOnPage(Component c)
          Return true is the component c is currently visible on the page displayed to the end user.
 void releaseControlEvent(Component c)
          Release the control event.
 void reset(Component c)
          Resets the given component and its children to their default visibility.
 void respond()
          Process the PageState and fire necessary events.
 void setAttribute(Object key, Object value)
          Deprecated. Use either setAttribute on the HTTP request object, or, preferrably, use a request local variable. Will be removed on 2001-06-13.
 void setControlEvent(Component c)
          Set the control event.
 void setControlEvent(Component c, String name, String value)
          Set the control event.
 void setGlobalValue(String name, Object value)
          Deprecated. Use setValue(ParameterModel m, Object o) instead. If you don't have a reference to the parameter model, you should not be calling this method. Instead, the component that registered the parameter should provide methods to manipulate it. Will be removed 2001-06-20.
static void setMaxStatesInSession(int x)
          Sets the maximum number of independent page states that may be stored in the HttpSession, for preserving the behavior of the "back" button.
 void setValue(ParameterModel p, Object value)
          Set the value of the state parameter p.
 void setVisible(Component c, boolean v)
          Set the visibility of a component.
 String stateAsURL()
          Write the current state of the page as a URL.
 String toString()
          Convert to a String.
 URL toURL()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

versionId

public static final String versionId
See Also:
Constant Field Values
Constructor Detail

PageState

public PageState(Page page,
                 javax.servlet.http.HttpServletRequest request,
                 javax.servlet.http.HttpServletResponse response)
          throws javax.servlet.ServletException
Construct the PageState for an HTTP request. Calls process on the form model underlying the page model and calls respond on the component from which the request originated.

Parameters:
page - The model of the page
request - The request being served
response - Where the response should be sent
Method Detail

getMaxStatesInSession

public static int getMaxStatesInSession()
Returns the maximum number of independent page states that may be stored in the HttpSession, for preserving the behavior of the "back" button.

Returns:
the maximum number of independent page states that may be stored in the HttpSession.

setMaxStatesInSession

public static void setMaxStatesInSession(int x)
Sets the maximum number of independent page states that may be stored in the HttpSession, for preserving the behavior of the "back" button.

Parameters:
x - the maximum number of independent page states to store in the HttpSession.

getPageState

public static PageState getPageState(javax.servlet.http.HttpServletRequest request)
Returns the page state object for the given request, or null if none exists yet.

Parameters:
request - The servlet request.
Returns:
The page state object for the given request, or null if none exists yet.

getPageState

public static PageState getPageState()
Returns the page state object for the current request, or null if none exists yet.

Returns:
The page state object for the current request, or null if none exists yet.

decodeVisibility

protected BitSet decodeVisibility()

encodeVisibility

protected BitSet encodeVisibility(BitSet current)

respond

public void respond()
             throws javax.servlet.ServletException
Process the PageState and fire necessary events. Call respond on the selected bebop component.

Throws:
javax.servlet.ServletException

getPage

public final Page getPage()
Return the page for which this object holds the state.

Returns:
the page for which this object holds state.

getRequest

public final javax.servlet.http.HttpServletRequest getRequest()
Return the request object for the HTTP request.

Returns:
The HTTP request being currently served.

getResponse

public final javax.servlet.http.HttpServletResponse getResponse()
Return the response object for the HTTP response.

Returns:
The response for the HTTP request being served

isVisible

public boolean isVisible(Component c)
Return true is the comonent c is currently visible. This method should only be used by components internally. All other objects should call Component.isVisible on the component.

Parameters:
c - the components whose visibility should be returned
Returns:
true if the component is visible

isVisibleOnPage

public boolean isVisibleOnPage(Component c)
Return true is the component c is currently visible on the page displayed to the end user. This is true if the component's visibility flag is set, and it is in a container visible to the end user.

This method is different than isVisible which only returns the visibility flag for the individual component.

Parameters:
c - the components whose visibility should be returned
Returns:
true if the component is visible

setVisible

public void setVisible(Component c,
                       boolean v)
Set the visibility of a component. Calls to this method change the default visibility set with Page.setVisibleDefault. This method should only be used by components internally. All other objects should call Component.setVisible on the component.

Without explicit changes, a component is visible.

Parameters:
c - the component whose visibility is to be changed
v - true if the component should be visible

reset

public void reset(Component c)
Resets the given component and its children to their default visibility. Also resets the state parameters of the given component and its children to null. This is not a speedy method. Do not call gratuitously.

Parameters:
c - the parent component whose state parameters and visibility you wish to reset.

setAttribute

public void setAttribute(Object key,
                         Object value)
Deprecated. Use either setAttribute on the HTTP request object, or, preferrably, use a request local variable. Will be removed on 2001-06-13.

Store an attribute keyed on the object key. The PageState puts no restrictions on what can be stored as an attribute or how they are managed. To remove an attribute, call setAttribute(key, null). The attributes are only accessible as long as the PageState is alive, typically only for the duration of the request.


getAttribute

public Object getAttribute(Object key)
Deprecated. Use either getAttribute on the HTTP request object, or, preferrably, use a request local variable. Will be removed on 2001-06-13.

Get the value of an attribute stored with the same key with setAttribute.


setValue

public void setValue(ParameterModel p,
                     Object value)
Set the value of the state parameter p. The concrete type of value must be compatible with the type of the state parameter.

The parameter must have been previously added with a call to Page.getComponentStateParam. This method should only be called by the component that added the state parameter to the page. Users of the component should manipulate the parameter through methods the component provides.

Parameters:
p - a state parameter
value - the new value for this state parameter. The concrete type depends on the type of the parameter being used.

getValue

public Object getValue(ParameterModel p)
Get the value of state parameter p. The concrete type of the return value depends on the type of the parameter being used.

The parameter must have been previously added with a call to Page.addComponentStateParam. This method should only be called by the component that added the state parameter to the page. Users of the component should manipulate the parameter through methods the component provides.

Parameters:
p - a state parameter
Returns:
the current value for this state parameter. The concrete type depends on the type of the parameter being used.

getGlobalValue

public Object getGlobalValue(String name)
Deprecated. Use getValue(ParameterModel m) instead. If you don't have a reference to the parameter model, you should not be calling this method. Instead, the component that registered the parameter should provide methods to manipulate it. Will be removed 2001-06-20.

Get the value of a global state parameter.


setGlobalValue

public void setGlobalValue(String name,
                           Object value)
Deprecated. Use setValue(ParameterModel m, Object o) instead. If you don't have a reference to the parameter model, you should not be calling this method. Instead, the component that registered the parameter should provide methods to manipulate it. Will be removed 2001-06-20.

Change the value of a global parameter


grabControlEvent

public void grabControlEvent(Component c)
Grab the control event. Until releaseControlEvent(c) is called, only the component c can be used in calls to setControlEvent.


setControlEvent

public void setControlEvent(Component c,
                            String name,
                            String value)
Set the control event. The control event is a delayed event that only gets acted on when another request to this Page is made. It is used to set which component should receive the submission and lets the component set one comonent-specific name-value pair to be used in the submission.

After calling this method links and hidden form controls generated with stateAsURL() have been amended so that if the user clicks such a link or submits a form containing those hidden controls, the exact same values can be retrieved with getControlEventName() and getControlEventValue().

Stateful components can use the control event to change their state. For example, a tabbed pane t might call setControlEvent(t, "select", "2") just prior to generating the link for its second tab.

The values of name and value have no meaning to the page state, they are simply passed through without modifications. It is up to specific components what values of name and value are meaningful for it.

Parameters:
c -
name - The component specific name of the event, may be null
value - The component specific value of the event, may be null

setControlEvent

public void setControlEvent(Component c)
Set the control event. Both the event name and its value will be null.


clearControlEvent

public void clearControlEvent()
Clear the control event. Links and hidden form variables generated after this call will not cause any component's respond method to be called.

Throws:
IllegalStateException - if any component has grabbed the control event but not released it yet.

getControlEventName

public String getControlEventName()
Get the name of the control event.


getControlEventValue

public String getControlEventValue()
Get the value associated with the control event.


releaseControlEvent

public void releaseControlEvent(Component c)
Release the control event.

Parameters:
c - The component that was passed to the last call to grabControlEvent

generateXML

public void generateXML(Element parent)
Add elements to parent that represent the current page state. For each component or global state parameter on the page, a <bebop:pageState> element is added to parent. The name and value attributes of the element contain the name and value of the state parameters as they should appear in an HTTP request made back to this page.

Generates DOM fragment:

 <bebop:pageState name=... value=.../>
 

See Also:
setControlEvent

generateXML

public void generateXML(Element parent,
                        Iterator models)

stateAsURL

public String stateAsURL()
                  throws IOException

Write the current state of the page as a URL.

The URL representing the state points to the same URL that the current request was made from and contains a query string that represents the page state.

If the current page has the useHttpSession flag set, then the URL query string that we generate will only contain the current value of the control event, and the rest of the page state is preserved via the HttpSession. Otherwise, the query string contains the entire page state.

Returns:
a string containing the current state of a page.
Throws:
IOException
See Also:
setControlEvent, Page.isUsingHttpSession, Page.setUsingHttpSession

toURL

public final URL toURL()

getRequestURI

public String getRequestURI()
Get the URI to which the current request was made. Copes with the black magic that is needed to get the URI if the request was handled through a dispatcher. If no dispatcher was involved in the request, returns the request URI from the HTTP request.

Returns:
the URI to which the current request was made

isValid

public boolean isValid()
Return true if all the global and component state parameters extracted from the HTTP request were successfully validated against their parameter models in the Page.

Returns:
true if the values of all global and component state parameters are valid with respect to their parameter models.

getErrors

public Iterator getErrors()
Return an iterator over the errors that occurred in trying to validate the state parameters against their parameter models in Page.

Returns:
an iterator over validation errors
See Also:
FormData.getErrors(java.lang.String)

getErrorsString

public String getErrorsString()
Return a string with all the errors that occurred in trying to validate the state parameters against their parameter models in Page. The string consists simply of the concatenation of all error messages that the result of getErrors() iterates over.

Returns:
all validation errors concatenated into one string

forceValidate

public void forceValidate()
Force the validation of all global and component state parameters against their parameter models. This method only needs to be called if the values of the parameters have been changed with setValue or setGlobalValue and may now contain invalid values.


toString

public String toString()
Convert to a String.

Returns:
a human-readable representation of this.


Copyright (c) 2004 Red Hat, Inc. Corporation. All Rights Reserved. Generated at July 20 2004:2337 UTC