Actually I would prefer the same for the add/get/removeWindowListener
Regards,
~ Simon
On Fri, May 15, 2009 at 3:09 PM, Blake Sullivan <blake.sulli...@oracle.com
> wrote:
Here is the proposed api:
package org.apache.myfaces.trinidad.context;
/**
* Represents a Window in the current user's Session. Windows are
created and vended
* by the Session's WindowManager and the Window for the current
request is
* available from <code>WindowManager.getCurrentWindow</code>
* @see WindowManager#getCurrentWindow
*/
public abstract class Window implements Serializable
{
/**
* <p>
* Represents the current state of the Window. Windows start out
<code>OPEN</code>,
* when the current window's document is being unloaded, they move
to the <code>UNLOADING</code>
* state and then either move back to the <code>OPEN</code> state if
the Window's content
* is populated with a new document from the same application, or to
the <code>CLOSED</code>
* state if it is not.
* </p><p>
* This represents the framework's best guess at the current status
of the Window.
* </p>
*/
public enum LifecycleState
{
/** The Window is currently open */
OPEN,
/** The Window is being unloaded */
UNLOADING,
/** The Window is believed to be closed, either because the window
was explicitly closed
* or because the window is suspected to have been closed
*/
CLOSED
}
/**
* Represents how the window is used in the application
*/
public enum Usage
{
/** Used as a top-level application window */
FRAME,
/** Used as a dialog */
DIALOG
}
/**
* @return The unique identifier for this Window within the Session
*/
public abstract String getId();
/**
* @return The current state of the Window
*/
public abstract LifecycleState getLifecycleState();
/**
* Returns the Usage of the Window--either a top-level frame or a
dialog
* @return how the window is used
*/
public abstract Usage getUsage();
}
/**
* <p>
* Manages the set of Windows currently in the Session and allows
listeners on the Windows'
* lifecycles to be registered.
* </p>
* @see
org.apache.myfaces.trinidad.context.RequestContext#getWindowManager
*/
abstract public class WindowManager
{
/**
* @param extContext ExternalContext so that the WindowManager may
be called before the
* FacesContext is available
* @return The Window that contains the document making the current
request
*/
public abstract Window getCurrentWindow(ExternalContext extContext);
/**
* @param extContext ExternalContext so that the WindowManager may
be called before the
* FacesContext is available
* @return <code>true</code> if the Window making the current
request is newly created.
*/
public abstract boolean isCurrentWindowNew(ExternalContext
extContext);
/**
* @param extContext ExternalContext so that the WindowManager may
be called before the
* FacesContext is available
* @return The Unmodifiable Map of WindowIds to Windows
*/
public abstract Map<String, ? extends Window>
getWindows(ExternalContext extContext);
/**
* <p>
* Registers a listener that will be informed of changes to the
Lifecylce state of any of
* the known Windows.
* </p>
* <p>
* Window listeners may be registered automatically by adding a file
* containing the names of the classes implementing the
WindowListener in a file named
* <code>org.apache.myfaces.trinidad.event.WindowListener</code>
inside of
* the <code>META_INF/services</code> directory.
* </p>
* @param extContext ExternalContext so that the WindowManager may
be called before the
* FacesContext is available
* @param windowListener
*/
public abstract void addWindowListener(ExternalContext extContext,
WindowListener windowListener);
/**
* Removes a listener that will be informed of changes to the
Lifecylce state of any of
* the known Windows
* @param extContext ExternalContext so that the WindowManager may
be called before the
* FacesContext is available
* @param windowListener
*/
public abstract void removeWindowListener(ExternalContext
extContext, WindowListener windowListener);
/**
* Performs any necessary action to embed the current window
identifier into the output
* @param context FacesContext to use to write the output
* @throws IOException if an output exception occurs
*/
public abstract void writeState(FacesContext context) throws
IOException;
}
/**
* <p>
* Application-scoped factory for creating per-Session WindowManager
instances. It is the
* WindowManagerFactory implementation's responsibility to ensure
that only one
* WindowManager instance is created per-session. The
WindowManagerFactory is also responsible
* for ensuring that any mutable state in the WindowManager instances
will be successfully failed
* over.
* </p>
* <p>
* The factory is usually specified by placing the name of the
WindowManagerFactory
* implementation class in a file named
* <code>org.apache.myfaces.trinidad.context.WindowManagerFactory</
code>
* in the <code>META-INF/services</code> directory
* </p>
* @see org.apache.myfaces.trinidad.context.WindowManager
* @see
org.apache.myfaces.trinidad.context.RequestContext#getWindowManager
*/
abstract public class WindowManagerFactory
{
/**
* Returns the WindowManager to use for this session, creating a new
instance if one doesn't
* already exist.
* @param extContext ExternalContext
* @return WindowManager to use for this Session
*/
public abstract WindowManager getWindowManager(ExternalContext
extContext);
}
To RequestContext add;
/**
* <p>
* Returns the WindowManager for this request. A non-null
WindowManager
* will always be returned.
* </p><p>
* The default implementation uses the first WindowManagerFactory
specified
* implementation class in a file named
* <code>org.apache.myfaces.trinidad.context.WindowManagerFactory</
code>
* in the <code>META-INF/services</code> directory and uses the
WindowManagerFactory
* to create the WindowManager for this Session. If no
WindowManagerFactory is
* found, a default WindowManager that never returns any Windows is
used.
* </p>
* @return the WindowManager used for this Session.
*/
public WindowManager getWindowManager()
In package:
package org.apache.myfaces.trinidad.event;
/**
* Represents an event delivered with a Window as the source.
* @see org.apache.myfaces.trinidad.context.Window
* @see org.apache.myfaces.trinidad.event.WindowListener
*/
public abstract class WindowEvent extends EventObject
{ /**
* @return the Window that this event ocurred on.
*/
public Window getSource()
}
/**
* Event delivered when the LifecycleState of a Window changes. The
<code>cause</code>
* indicates the cause ot the state change. The state diagram for
theWindow LifecycleStates
* is
<pre>
+-----------load---------------+
| | ---
expire---
V /---unload----\
| / \
<start> ---open--->OPEN----- -----
>UNLOADED-- -->CLOSED
| \--navigate---/ ^
\ /
| | ---
close----
+---------closing--------------+
</pre>
* The new LifecycleStates can be retrieved by calling
<code>getLifecycleState</code> on the
* source Window or by calling the <code>getNewLifecycleState</code>
convenience function
* on the WindowLifecycleEvent
* @see org.apache.myfaces.trinidad.context.Window
* @see org.apache.myfaces.trinidad.context.Window.LifecycleState
*/
public class WindowLifecycleEvent extends WindowEvent
{
/**
* What caused the delivery of the WindowLifecycleEvent.
*/
public enum Cause
{
/**
* Delivered when a new Window is open
*/
OPEN,
/**
* Delivered when the content of a Window have been unloaded but
cause of the unloading
* isn't known.
*/
UNLOAD,
/**
* Delivered when the content of a Window have been unloaded as a
result of
* navigating within the application
*/
NAVIGATE,
/**
* Delivered when the content of a Window have been unloaded in
order to
* close the window
*/
CLOSING,
/**
* The contents of an existing Window are being reloaded
*/
RELOAD,
/**
* The Window is believed to have been closed by the user
*/
EXPIRE,
/**
* The Window is believed to have been closed by the user
*/
CLOSE
}
/**
* Creates a WindowOpenEvent event for the specified Window and cause.
*/
public WindowLifecycleEvent(Window source, Cause cause)
/**
* @return the cause of the WindowOpen event.
*/
public Cause getCause()
/**
* Returns the new LifecycleState that the Window has moved to.
*/
public final LifecycleState getNewLifecycleState()
}
/**
* WindowLifecycleEvent delivered when the current window is being
unloaded
* in order to navigate to a new location
*/
public final class WindowNavigateEvent extends WindowLifecycleEvent
{
public WindowNavigateEvent(Window source, String destination)
/**
* Returns the URL to which the page is navigating.
* <p>
* The destination is not guaranteed to be normalized; it may
* be absolute, page-relative, or server-relative. It is also
* not guaranteed to be correct, as a browser
* may be redirected to an alternate destination.
*/
public String getDestination()
}
/**
* <p>
* A listener called when the Lifecyle of a Window changes.
* </p>
* <p>
* Window listeners may be registered automatically by adding a file
* containing the names of the classes implementing the
WindowListener in a file named
* <code>org.apache.myfaces.trinidad.event.WindowListener</code>
inside of
* the <code>META_INF/services</code> directory or manually by calling
* <code>WindowManager.addWindowListener</code>
* @see org.apache.myfaces.trinidad.context.WindowManager
*/
public abstract class WindowListener
{
/**
* <p>
* Called when the LifecycleState of a Window changes.
* </p>
* <p>
* The current lifecycle state of a Window is the framework's best
guess and may not be accurate.
* In particular, the last remaining open window may never move into
the <code>CLOSED</code> state
* once it has moved into the <code>UNLOADED</code> state. In
addition, no Window lifecycle events
* are delivered if the Session ceases to exist.
* </p>
* <p>
* The FacesContext may not be available at the time that this event
is delivered.
* </p>
* @param extContext ExternalContext available for this event
* @param event WindowLifecycleEvent indicating the cause of the
change to the Window's
* LifecycleState
*/
public abstract void processLifecylceEvent(ExternalContext
extContext, WindowLifecycleEvent event);
}
Blake Sullivan (JIRA) said the following On 5/15/2009 11:41 AM PT:
Add Window abstraction to Trinidad
----------------------------------
Key: TRINIDAD-1474
URL: https://issues.apache.org/jira/browse/TRINIDAD-1474
Project: MyFaces Trinidad
Issue Type: New Feature
Components: Archetype
Affects Versions: 1.2.12-core
Environment: All
Reporter: Blake Sullivan
Add Window abstraction to Trinidad. Currently, Trinidad knows
nothing of the separate browser Windows that make up a browser
session. This causes weird problems. For example, the state
management token cache is shared across all of the active windows
with a simple LRU. If the user opens up two windows and operates on
one window long enough, he will cause the token state for the
original window to be purged. When the user switches back to the
original window and POSTs back, the token won't be found, Trinidad
will assume that this is because the session expired, and the user
will be given an error.
Adding the concept of a Window and a Window lifecyle opens up the
following capabilities:
1) Correct handling of per-window UI state by segregating tokens by
window
2) Early clean-up of UI state by aggressively purging state for
closed windows
3) Applications can manager per-window state by listening for window
lifecycle events
4) Sessions can be cleaned up earlier by terminating the session
when the last window in the session is closed
5) A window scope can be implemented to ease using per-window state
with EL
6) A window manager implementation can hide the details of handling
control-N in the browser
ws
3) Applications can manager per-window state by listening for window
lifecycle events
4) Sessions can be cleaned up earlier by terminating the session
when the last window in the session is closed
5) A window scope can be implemented to ease using per-window state
with EL
6) A window manager implementation can hide the details of handling
control-N in the browser
e>