Controller Framework
The controller framework consists of Java™ classes and interfaces that provide the runtime environment for the components used within an application/page. It is responsible for handling application level events such as page switching, dispatching events to UI modules, log on, and log off. The controller framework base class is the abstract WcmController.
Features of the controller framework are as follows:
- Authentication. Authentication behavior is defined via a sign-in policy interface. Default, out-of-the-box behavior is provided which performs HTML form-based sign-in, and authenticates against the Content Engine and the Process Engine. Authentication also supports SSL sign-in.
- Phase notification. All of the UI modules and data providers on a page can implement callbacks to listen for phase notifications. The controller notifies the beans via these callbacks of which phase in the page execution is currently being executed.
- Event URLs. Events are implicitly defined, meaning that there is no XML configuration file in the framework where events must be registered. The framework supports both targeted and global event URLs. A targeted event URL is addressed to a specific, single UI module on a page, whereas a global event URL is addressed to multiple UI modules that have subscribed to the event. The base UI module provides methods for generating event URLs.
- State management. The framework provides access to user session state on the server. Session state can be scoped globally down to the Java bean level. The controller uses the data store to persist stateful data stored by UI modules and data providers.
- Window management. The framework provides a window ID mechanism that includes URL rewriting, stateful scoping of popup windows, and nested page invocations that support pages with object dependencies and pages that create objects.
- Context-sensitive help mapping. The controller framework generates help keys that map Java™ Server Pages (JSP) pages to corresponding HTML help pages. There's no need to hardcode help links in the source.
- HTML header configuration. As part of page execution, the controller framework instantiates an "HTML headers" UI module, which is made available to all other modules on the page. Any module can specify required resources such as JavaScript™ scripts, CSS stylesheets, and page title via this headers object.
- Error processing. The controller provides a mechanism to specify an exception to be displayed by a default or custom JSP page.
- Interface factories. Factories are provided for all customizable interfaces provided to module beans. This allows the controller framework to be easily adapted to custom application platforms and environments.
- Default controller implementation. The Toolkit provides an out-of-the-box implementation of WcmController. It is called ConfigurableController because its behavior is easily configured in Workplace/WEB-INF/p8controller.xml.
- Multiple controller support. You can implement multiple controllers in a single Web application by leveraging ConfigurableController features and implementation of the StaticInitializerInterface. ConfigurableController supports multiple named configurations in p8controller.xml. Each configuration can share a single static initializer which initializes all dependencies required by each defined controller configuration.
See Also
Framework Page
Preferences API
Toolkit Implementation of MVC
ConfigurableController
The Toolkit provides ConfigurableController, an easily customizable, fully implemented controller. To configure the controller's behavior, you simply edit the Workplace/WEB-INF/p8controller.xml file.
ConfigurableController supports multiple named configurations in p8controller.xml. Each configuration can share a single static initializer which initializes all dependencies required by each defined controller configuration.
You can also implement multiple controllers in a single Web application by leveraging ConfigurableController features and implementation of the StaticInitializerInterface. This can be useful if you have two independently developed custom applications, and you want to merge part or more of these multiple applications into a single Web application.
With Web Application Toolkit, you have the following controller development options:
- Use the implemented ConfigurableController and simply modify the default configuration. For a step-by-step description, see Step 2: Configure ConfigurableController.
-
Subclass ConfigurableController, if you need to extend its
functionality. The FileNet P8 Workplace application provides a case in
point. Its ConfigurableController subclass overrides the
initializeStaticClasses()method in order to load additional preferences. - Implement your own controller, if you need a greater degree of control over the level of customization available both in ConfigurableController and in its related interfaces -- such as preferences, sign-in policy, user token policy, and static initializer. The controller framework base class is the abstract WcmController. For details, see Implementing a Controller.
NOTE If you are migrating a 2.x Toolkit application to
Toolkit version 3.x or later libraries, set the backward compatibility options as
follows: windowIdCompatibility to "true" and
internalTokensEnabled to "false". If you implemented your own
controller in the 2.x application, set the options in WEB-INF/web.xml; if
you are using the ConfigurableController, set the options in
WEB-INF/p8controller.xml.
See Also
ConfigurableController Preferences
Classes
ConfigurableController Preferences
Page Cycle
A controller implementation is instantiated in the event JSP page. When the JSP page loads, the controller performs the following functions:
- Retrieves the current user session data store and initializes page specific values.
-
Registers modules as follows:
- Checks the module name for uniqueness.
- Adds the module to the controller's module list.
- Adds the module to the controller's init queue.
- Gives the module access to the controller.
- Gives the module access to the data store.
-
Verifies credentials as follows:
- Calls signInPolicy.isSignedIn() to verify the existence of valid credentials in the user session (in the data store).
- If credentials are not present, calls signInPolicy.doSignIn() to retrieve user credentials. Default behavior for doSignIn() is to redirect to the sign-in page.
- After user has entered credentials, it redirects back to the original page.
-
Calls initialize() on registered modules in the order that they were
registered as follows:
- Gets enumeration of modules in the init queue.
- Iterates and calls initialize() on each module until the init queue is empty. If a module registers children using this.addChild(...), initialize() is called immediately on these modules.
- If an event is specified on the request, the appropriate "on..." event
handler is looked up and invoked.
OR
If a global event is specified on the request, the appropriate "on..." global event handler is looked up and invoked on all modules that have subscribed to that global event, assuming that one of the event handlers did not perform a client-side redirect.
- Calls onStartPage() on registered UI modules in the order that they were registered. The onStartPage method signals to the modules that the UI will be displayed.
- Performs a server-side redirect to the UI jsp page.
The UI page makes calls to WcmUi.render(...) to render the registered UI modules onto the page, either by calling uiModule.render(...), running the XSL transform for XSL modules, or by a server-side include specifying the JSP for JSP-based modules.
Note that all registered UI modules contain an "active flag" property. By default, the flags are initialized to boolean "true". The module can be inactivated by calling uiModule.setActive(false).
When a UI module is inactivated, it means that the UI module and all of its descendants will not receive events and will not receive the onStartPage() call from the controller. It is then assumed that these modules will not be rendered onto the page.
-
Calls render(...) on registered modules.
See Also
Event URLs
Phase Notification
The controller framework routes an event to a UI module as part of a four-phase process:
- Initialize
- Route Event
- Start page
- Render
As shown in the following diagram, these phases correspond with the methods in a UI module.

- The Initialize( ) and onStartPage(...) methods are callbacks invoked on all registered UI modules during the controller.handleEvent(...) method, which is called from the event JSP page (Event JSP). The initialize and start page phases signal all UI modules to initialize themselves from their stateful information, and to prepare for rendering, respectively.
- If an event link specifies eventTarget and eventName parameters, then the controller will look up the named UI module, and look up the "on..." handler corresponding to the named event.
- The render phase delegates from the event JSP page to the UI JSP page (UI JSP Page) for rendering.
See Also
Event URLs
Phase Notification Examples
The examples that follow illustrate the four phases of the controller when it receives a request. Each example shows a set of UI modules that have been registered into the controller on an event JSP page. The controller works from a hash table that uses a UI module's fully qualified name as the key.
UI modules support containment, meaning that a UI module can register other UI modules as its children. When this is done, the child UI modules have the qualified parent UI module's name specified as a qualifier with an exclamation point ( ! ) as the delimiter. In the examples, therefore, the layout UI module is the parent of "banner", "tabbar", " treeview", "footer", "navigation" and "contentsListView". For example:
layout!navigation
A child UI module can also be a parent. The "layout!navigation" child contains path and navList, for example:
layout!navigation!navList
The eventTarget parameter in an event URL always specifies the fully qualified UI module name.
The following examples describe the controller's phases based on the event URL type:
- No Event Example
- Targeted Event Routing Example
- Child-to-Parent Event Routing Example
- Global Event Routing Example
- Event that Redirects Example
- Inactive UI Modules Example
See Also
Event URLs
This example shows the sequence of UI module callbacks that the controller makes when an event JSP page is requested with no event on the request. One phase (represented by the columns left to right) must complete before the next phase commences.
http://host:port/customApp/MyPage.jsp
controller.handleEvent(...):
UI module |
initialize() |
onClick(req, resp) |
onStartPage(req, resp) |
render(out) |
|---|---|---|---|---|
| headerModule | 1 | 1 | render | |
| layout | 2 | 2 | render | |
| layout!banner | 3 | 3 | render | |
| layout!tabbar | 4 | 4 | render | |
| layout!treeview | 5 | 5 | render | |
| layout!footer | 6 | 6 | render | |
| layout!navigation | 7 | 7 | render | |
| layout!navigation!path | 8 | 8 | render | |
| layout!navigation!navList | 9 | 9 | render | |
| layout!contentsListView | 10 | 10 | render |
See Also
Phase Notification Examples
This example shows the sequence of UI module callbacks that the controller makes when a click event is targeted to a UI module. One phase (represented by the columns left to right) must complete before the next phase commences.
http://host:port/customApp/MyPage.jsp?eventTarget=layout!navigation&eventName=Click&otherParam=otherValue controller.handleEvent(...):
UI module |
initialize() |
onClick(req, resp) |
onStartPage(req, resp) |
render(out) |
|---|---|---|---|---|
| headerModule | 1 | 1 | render | |
| layout | 2 | 2 | render | |
| layout!banner | 3 | 3 | render | |
| layout!tabbar | 4 | 4 | render | |
| layout!treeview | 5 | 5 | render | |
| layout!footer | 6 | 6 | render | |
| layout!navigation | 7 | 1 | 7 | render |
| layout!navigation!path | 8 | 8 | render | |
| layout!navigation!navList | 9 | 9 | render | |
| layout!contentsListView | 10 | 10 | render |
See Also
Phase Notification Examples
This example shows the sequence of UI module callbacks that the controller makes when a click event is targeted to a child UI module, which then routes the event to its parent. One phase (represented by the columns left to right) must complete before the next phase commences.
http://host:port/customApp/MyPage.jsp?eventTarget=layout!navigation&eventName=Click&otherParam=otherValue controller.handleEvent(...):
UI module |
initialize() |
onClick(req, resp) |
onStartPage(req, resp) |
render(out) |
|---|---|---|---|---|
| headerModule | 1 | 1 | render | |
| layout | 2 | 2 | 2 | render |
| layout!banner | 3 | 3 | render | |
| layout!tabbar | 4 | 4 | render | |
| layout!treeview | 5 | 5 | render | |
| layout!footer | 6 | 6 | render | |
| layout!navigation | 7 | 1 | 7 | render |
| layout!navigation!path | 8 | 8 | render | |
| layout!navigation!navList | 9 | 9 | render | |
| layout!contentsListView | 10 | 10 | render |
See Also
Phase Notification Examples
This example shows the sequence of UI module callbacks that the controller makes when a global click event is targeted to multiple UI modules. One phase (represented by the columns left to right) must complete before the next phase commences.
NOTE Event methods are invoked in the order that UI modules subscribed to the global event.
http://host:port/customApp/MyPage.jsp?eventName=Click&otherParam=otherValue
controller.handleEvent(...):
UI module |
initialize() |
onClick(req, resp) |
onStartPage(req, resp) |
render(out) |
|---|---|---|---|---|
| headerModule | 1 | 1 | render | |
| layout | 2 | 2 | render | |
| layout!banner | 3 | 3 | render | |
| layout!tabbar | 4 | 4 | render | |
| layout!treeview | 5 | 1 | 5 | render |
| layout!footer | 6 | 6 | render | |
| layout!navigation | 7 | 2 | 7 | render |
| layout!navigation!path | 8 | 3 | 8 | render |
| layout!navigation!navList | 9 | 9 | render | |
| layout!contentsListView | 10 | 4 | 10 | render |
This example shows the sequence of UI module callbacks that the controller makes when a click event is targeted to a UI module, and the event handler redirects to another event JSP page. One phase (represented by the columns left to right) must complete before the next phase commences.
The controller detects that a redirect call was made, and skips the start page and render phases. In the controller framework, redirect calls automatically cancel all further operation on a page, thus reducing overhead.
http://host:port/customApp/MyPage.jsp?eventTarget=layout!navigation&eventName=Click&otherParam=Redirect controller.handleEvent(...):
UI module |
initialize() |
onClick(req, resp) |
onStartPage(req, resp) |
render(out) |
|---|---|---|---|---|
| headerModule | 1 | skipped | skipped | |
| layout | 2 | skipped | skipped | |
| layout!banner | 3 | skipped | skipped | |
| layout!tabbar | 4 | skipped | skipped | |
| layout!treeview | 5 | skipped | skipped | |
| layout!footer | 6 | skipped | skipped | |
| layout!navigation | 7 | 1 | skipped | skipped |
| layout!navigation!path | 8 | skipped | skipped | |
| layout!navigation!navList | 9 | skipped | skipped | |
| layout!contentsListView | 10 | skipped | skipped |
See Also
Phase Notification Examples
This example shows the sequence of UI module callbacks that the controller makes when a click event is targeted to a UI module, and one of the UI modules is no longer active. One phase (represented by the columns left to right) must complete before the next phase commences.
All UI modules in the framework include an "active" attribute, which can be set to true or false.
http://host:port/customApp/MyPage.jsp?eventTarget=layout!navigation&eventName=Click&otherParam=otherValue controller.handleEvent(...):
UI module |
initialize() |
onClick(req, resp) |
onStartPage(req, resp) |
render(out) |
|---|---|---|---|---|
| headerModule | 1 | 1 | render | |
| layout | 2 | 2 | render | |
| layout!banner | 3 | 3 | render | |
| layout!tabbar | 4 | 4 | render | |
| layout!treeview | 5 | 5 | render | |
| layout!footer | 6 | 6 | render | |
| layout!navigation | 7 | 1 | 7 | render |
| layout!navigation!path | 8 | 8 | render | |
| layout!navigation!navList | 9 | 9 | render | |
| layout!contentsListView | 10 | skipped | skipped |
See Also
Phase Notification Examples
Event URLs
The framework supports targeted and global event URLs. A targeted event URL is addressed to a specific, single UI module on a page, whereas a global event URL is addressed to multiple UI modules that have subscribed to the same event.
A targeted event URL specifies eventTarget and eventName parameters that identify the UI module that the event is targeted for, and the name of the event being triggered. When a user clicks a link with a targeted event URL, the controller detects the eventTarget and eventName, and routes the event to the appropriate handler in the targeted UI module, if defined.
The following example shows an event link targeted to a UI module. The event target is "layout!navigation", in the event JSP page WcmBrowse.jsp. The event target is the fully qualified name of the UI module as bound to the JSP variables "layout" and "navigation". (The concatenation of the two JSP variables indicates a containment relationship, where "layout" is the containing UI module, and "navigation" is a contained UI module.) The name of the event is "Select", and the controller routes this event to the onSelect method in the targeted UI module.
href="http://comstock:8080/customApp/WcmBrowse.jsp?eventTarget=layout!navigation&eventName=Select&library=&label=Choose+Library&lid="
The next example shows an event link targeted to the controller. The name of the event is ChangePage, and it is handled by the controller's onChangePage method, which directs the controller to redirect to a new event JSP page specified in the targetUrl parameter (WcmSearch.jsp).
href="http://comstock:8080/customApp/WcmBrowse.jsp?eventTarget=WcmController&eventName=ChangePage&targetUrl=http://comstock:8080/customApp/WcmSearch.jsp"
Global event links differ only by excluding the eventTarget parameter. For example:
href="http://comstock:8080/customApp/WcmBrowse.jsp?eventName=Select&library=&label=Choose+Library&lid="
In this case, all UI modules that have subscribed to the "Select" global event will have their onSelect global event handler called, if defined.
Note that the base UI module class,
WcmUiModule,
provides methods that generate URLs for you. For example,
getEventUrl(...) is for straight click events, and
getFormSubmitUrl(...) is for events that will be accompanied
by form data. For a containment relationship, WcmUiModule includes methods
for routing an event from a child UI module to its parent. See
Containment: Routing an Event to the
Parent.
Data Store
All stateful data for a user session is stored in the data store (WcmDataStore). Scoped to the duration of a JSP session, the data store is cleared when a session expires or ends.
Information stored in the data store can be accessed directly, or can be accessed via a variety of set...Property methods as listed below:
| Method | Scoping |
|---|---|
|
Module.setModuleProperty(key, value) Module.getModuleProperty(key) |
Scoped to an instance of a module on a page. |
|
Module.setClassProperty(key, value) Module.getClassProperty(key) |
Scoped to all instances of a module of a specific class. |
|
Module.setWindowProperty(key, value) Module.getWindowProperty(key) |
Scoped to an instance of a module on a page referenced in a popup window. |
|
Controller.setProperty(key, value) Controller.getProperty(key) |
Scoped to a particular controller instance on a page (page scoping). |
Any modules, utility classes, or JSP pages may optionally use the data store to cache some temporary data or state that will be persisted across requests. As shown in the diagram below, a data provider can cache its data, initially retrieved from the Java API, to the data store. A UI module can use the data store to cache current user settings. For example, if a user changes the default list view style from Magazine to Detail, the list UI module can cache that setting to the data store. Later, when the page reloads, the list UI module will check the data store for the current user settings and overwrite the site preferences settings.
Data store clients should determine when it is best to cache data and state information to the data store, and what is the most efficient representation of cached data (object, XML, and so on) Algorithms for data store caching should balance the factors of memory consumption, scalability, and performance.
Several utility classes are provided, as well as features in the data store to aid in caching. These leverage Java soft referencing and MRU data structures. Two examples are the WcmSoftReferenceMap and the WcmMRUMap classes.

See Also
Toolkit Implementation of MVC
Data Providers
Base UI Modules
Utilities
Window Management
Prior to the 3.0 version of Web Application Toolkit, the framework provided a window ID mechanism for managing pages that appeared in popup (secondary) windows from the main browser window of an application. A window ID was simply a token to indicate that the browser window where the ID was present was a popup window. In response to a window ID, the framework provided stateful scoping for each popup window, with the capability to differentiate between the same page in different browser windows.
While this version of the Toolkit includes full backward compatibility with window ID behavior in previous releases, it also extends the window ID mechanism in the following ways.
- Provides stateful scoping that allows invocation of a page from within itself. For an example of this behavior, see a Document Info Page in the FileNet P8 Workplace application.
- Provides a mechanism for stacking of window IDs. This helps keep track of how many layers deep a page has called into itself.
- Allows a window ID to contain one or more flags which can be set on creation. This tracks how a window ID was created, and information on desired controller behavior with it.
- Implements a URL rewriting mechanism for window IDs, minimizing the possibility of a window ID being dropped from the URL.
- Implements an inactivity timeout on pages that are using window IDs. This provides automatic cleanup to minimize memory usage of the user session. The timeout is the same as the configured Java Web app server session timeout.
This section describes the window ID mechanism that provides the above-listed features. It also discusses propagation, return/refresh window ID encoding, and window ID use cases in the FileNet P8 Workplace application.
NOTE If you are migrating a 2.x Toolkit application to Toolkit version 3.x or later libraries, set the backward compatibility options as follows: windowIdCompatibility to "true" and internalTokensEnabled to "false". If you implemented your own controller in the 2.x application, set the options in WEB-INF/web.xml; if you are using the ConfigurableController, set the options in WEB-INF/p8controller.xml.
Window ID Mechanism
The window ID mechanism consists of the following parts:
URL RewritingThe controller can detect when a window ID has been dropped from a request. When this happens, the controller will rewrite the request with the window ID. How the controller rewrites the request depends on the request type:
-
GET Request Rewriting (immediate). When rewriting is required onto a
GET request, the controller performs a redirect to the URL with the
window ID included during the event JSPs call to
controller.configurePage(...). This occurs before the page cycle begins. -
POST Request Rewriting (deferred). For POST requests, the parameters
are not specified in a request string carried on the request URI.
Instead the request parameters are included within the request
content.
In this scenario, when the controller has a window ID not included on the request, it sets a defer flag at the point where it would typically do a redirect for a GET request.
The page cycle is then executed up to event routing, at which point a redirect is done to the URI with the window ID included. This allows the POST request parameters to be processed by the Model prior to their being lost by the redirect, which is a GET request.
If a redirect is performed within the event processing part of the page cycle, this new URL becomes the URL that is rewritten with the window ID. This prevents deferral of the rewriting to interfere with the application behavior.
Toolkit provides the
com.filenet.toolkit.server.util.WindowID
class, an instance of which represents a window ID. WindowID objects are
constructed in one of two possible ways: either by the constructor
WindowID(String value), or by the static method WindowID,
createFlaggedWindowID(String value).
The format of the String passed to the WindowID constructor determines whether the WindowID object is constructed in default (flagged) mode or compatibility mode. When the window ID is formatted with an encode prefix ( _ ), the WindowID constructor constructs the object in default mode; otherwise, it constructs the object in compatibility mode. In compatibility mode, the WindowID object identifies itself as a popup window ID via the "popup" flag, described in the next section.
The static createFlaggedWindowID method constructs a new WindowID object in default mode, which allows for the setting and retrieval of up to 30 flags.
Window ID Flags
A WindowID object defines one or more internal use flags. The flags set depend on the usage of the window ID. The only flag currently defined is "popup" (WindowID.POPUP_FLAG).
Window ID Serialization
If a WindowID object is in compatibility mode, calling its toString() method will output exactly the same string that was passed in the constructor.
In default (flagged) mode, when WindowID.toString() is called, the window
ID is serialized out with its flags encoded in a specific format:
_<<flags>>.<<value>>
So, for example, if WindowID.createFlaggedWindowID("1234567")
were called, and then setFlag(WindowID.POPUP_FLAG, true) were
called on it, WindowID.toString would produce this:
_1.1234567
Window ID Stacking
The WindowID class also provides a simple stacking mechanism via its setPrevId and getPrevId methods. For example:
WindowID wid1 = WindowID.createFlaggedWindowID("12345");
WindowID wid2 = WindowID.createFlaggedWindowID("98765");
wid1.setPrevId(wid2.toString());
In this case, wid1.toString() will generate this:
_0.12345/_0.98765
The "/" delimiter is used to delimit the current window ID from the previous. This serialized form can also be passed into setPrevId, allowing for multiple levels of stacking.
When a new WindowID is constructed with a stacked window ID, it is deserialized such that the first window ID in the stack is taken as the current windowID, and the string to the right of the first slash is taken as the previous window ID, so that getPrevId() returns the correct value.
Modes of BehaviorThe event JSP for a framework page can configure itself to generate a new popup window ID when new page parameters are present on the page. This is done by calling the controller.configurePage, specifying a third boolean parameter as "true". For example:
controller.configurePage(application, request, true);
For Toolkit version 3.0 and later, several window ID modes of behavior are required. In addition to the above configurePage signature, two additional configurePage signatures are included. One signature has a third parameter of type long, which specifies a window ID mode. The other signature also includes the third parameter of type long, plus a fourth parameter of type String[], for specifying window ID parameters. For example:
controller.configurePage(application, request, windowIdMode);
The windowIDMode parameter extends the two possible boolean values of
true/false to specify one of many possible window ID modes. This
configurePage method calls into controller.configureWindowId, which
creates a WindowID object and configures how it will be used based on the
window ID-related values passed into configurePage.
Alternatively, the windowIdMode can be specified dynamically by passing
"windowIdMode=" (WcmParameter.WINDOW_ID_MODE) as a request parameter, for
example, "...&windowIdMode=CREATE_INLINE&...".
The window ID modes, defined as symbolic constants in WcmController, are
summarized in the following table. For new application development that
requires the use of windowIds, the use of the dynamic parameters
CREATE_POPUP or CREATE_INLINE are recommended for creating window IDs.
More details are provided on windowIdMode and other override options in
the next section.
| Description | Window ID Mode |
|---|---|
NO_WINDOW_ID
|
The page never tracks a window ID.
If called with a window ID it will be dropped from the URL via rewriting. |
PROPOGATE_WINDOW_ID (default)
|
If a window ID is found, and it has only the "popup" flag set
on it, propagate it. Rewrite it if it is not present on the current
URL request.
If the window ID has the "object" flag set, pop window IDs off of its stack, if any, until either a window ID with the "object" flag unset is found, or there are no previous window IDs left. This is equivalent, though not identical, to default controller behavior in Toolkit releases earlier than 3.0. |
REQUIRE_WINDOW_ID
|
Behavior of PROPOGATE_WINDOW_ID + ...
When there are new page parameters on the request, and there is no window ID on the request, generate a new popup window ID. This is equivalent, though not identical, to popup mode window ID behavior in Toolkit releases earlier than 3.0 (that is, with configurePage called with the third boolean parameter set to "true"). |
CREATE_POPUP
|
This mode must be passed dynamically as a windowIdMode parameter.
This mode tells the server to create a new WindowID and use it, replacing any window ID that may have been on the request already. Use this mode on any URL that is being opened in a new window (popup). |
CREATE_INLINE
|
This mode must be passed dynamically as a windowIdMode parameter.
This mode tells the server to create a new WindowID and use it, stacking on top of the previous window ID, if defined. Use this mode on any URL representing a page that can launch a second copy of itself (within the same browser window) either directly or indirectly through a set of intermediate pages. |
As mentioned in the previous section, the
controller.configureWindowId method configures how a WindowID
object is created, and the purpose it will serve -- based on window
ID-related values passed into configurePage. To override the WindowID
configuration performed by the configureWindowId method, the Toolkit
provides the following request parameters:
-
WcmParameter.SET_WINDOW_ID. The WcmParameter.SET_WINDOW_ID
parameter can be used to force setting of the window ID to a specific
value. This overrides any window ID generation that's based on the
mode passed into configureWindowId.
The window ID specified can be in either the encoded or popup format generated by the WindowID class. If it is not in the encoded format, it is assumed to be a popup window ID.
-
WcmParameter.WINDOW_ID_MODE. The WcmParameter.WINDOW_ID_MODE
parameter allows you to specify the window ID mode to use, overriding
how it may be configured in configureWindowId. In this way, the window
ID generating behavior can be modified for a single request.
The symbolic constant name found in WcmController corresponding to the desired mode is used. For example:
...&windowIdMode=CREATE_POPUP&...WcmController uses introspection to determine the actual mode value to use based on the symbolic name.
This request parameter is particularly useful for nested "create object" wizards.
Propagation
Window IDs will automatically propagate from one page to the next. By using getEventUrl and getFormSubmitUrl signatures of WcmUiModule, and through the use of WcmUi.encodeWindowId, it is possible for an application to maintain the windowId on URLs within a browser window.
If for some reason, however, the windowId is not passed forward, the controller's autorecovery logic will attempt to fix the problem by looking at the browser referer. If a recoverable windowId is found, it will rewrite the URL to the browser with the recovered windowId.
Return/Refresh windowId Encoding
In most cases, return and/or refresh URLs are desirable. The exception is when returning from a page where the caller had one windowId, and the called page is using a different windowId.
When passing return and/or refresh URLs to pages opened with new popup or stacked windowIds, it is up to the developer to ensure that the returnUrl passed into the called page is encoded with its windowId so that context is maintained on return.
Window ID Use Cases
The Web Application Toolkit window ID mechanism broadly addresses two kinds of window ID uses. The first is the mapping of a window ID to a particular browser window. These are called popup window IDs. The second is the mapping of a window ID to a particular object, for example, a Document object stored in the Content Engine.
This section shows both kinds of window ID uses in Workplace and FileNet P8 Portlets, versions 3.0 and later. It starts with an overview of Workplace management of window IDs, then describes the following specific page implementations of window IDs:
- Workplace Bookmark Pages
- Workplace Info Pages
- Workplace Actions
- FileNet P8 Portlets - Portlet Popups
The following diagram shows how the window ID mechanism is used by Workplace. Note that custom Toolkit-based applications should use the window ID mechanism in the same way.

The arrow labeled 1 indicates a link to an Info page. Because the Info page can contain a link to itself, it is required to have a new inline window ID to distinguish the successive invocations of itself. Therefore, any link to ObjectInfo.jsp to view a new or different object must contain "windowIdMode=CREATE_INLINE" so that each invocation of the page gets its own unique windowId (or context).
The arrow labeled 2 indicates a link that opens a new (popup) window. A page loaded in a new popup window must contain a new popup window ID. The recommended best practice for accomplishing this is to include "windowIdMode=CREATE_POPUP" as a request parameter on the URL being loaded in the popup browser window.
The arrows labeled 3 indicate scenarios where control is being returned to either a refresh URL or a return URL. In either case, the return/refresh URL passed to another page must contain its windowId so that the context being referenced is fully qualified.
For example, let's say "WcmObjectBookmark.jsp?windowId=_1.T123" contains a link to ObjectInfo.jsp. Since ObjectInfo.jsp is dependent on a unique context each time it is newly opened to view a certain object's properties, the link to it must contain "windowIdMode=CREATE_INLINE". This will result in the ObjectInfo.jsp being defined as something like "ObjectInfo.jsp?windowId=_1.S5/_1.T123".
Since ObjectInfo.jsp provides a return link to get back, its link, in addition to "windowIdMode=CREATE_INLINE" must contain "returnUrl=[WcmObjectBookmark.jsp?windowId=_1.T123]" (brackets indicate URL encoded). This way, when the user clicks return on the ObjectInfo.jsp page, the browser loads "WcmObjectBookmark.jsp?windowId=_T.123", rather than just "WcmObjectBookmark.jsp".
If, in the above example, no windowId were defined on the returnUrl, the controller's autorecovery logic would attempt to use the referer's windowId, which would cause the page to be loaded as WcmObjectBookmark.jsp?windowId=_1.S5/_1.T123. This is not the context (windowId) that ObjectInfo.jsp was launched from. At this point, the application would crash because UI modules' module properties and window properties were maintained under the context corresponding to "_1.T123" and not "_1.S5/_1.T123". The properties would no longer be visible.
Workplace Bookmark PagesIn the Workplace browse and search pages, when navigated to a folder, stored search or search template, a link is provided that allows the user to open a "bookmarkable" or URL addressable version of the page.
When the bookmark link is clicked, a second browser window is opened containing the bookmarkable version of the page. For example:

The bookmark page uses REQUIRE_WINDOW_ID mode, which generates a new window ID when new page parameters are present. The new window ID will have its popup flag set, and will therefore be interpreted by the framework as a popup window ID. Certain UI modules in Workplace key off of this fact and adjust their UI accordingly. For example, the page banner UI module shows only "help | close" links instead of "help | home | preferences | signout" links.
Alternatively, the main page can have the bookmark link include "windowIdMode=CREATE_POPUP" to achieve the same behavior.
From either the main browse page or the bookmarkable version of the browse page, the user can click links and access the same pages within Workplace. The popup window ID on the bookmark window keeps separate contexts for each browser window. Therefore, if from each browser window the user clicks to the same page, the two browser windows do not interfere with one another in their module or window properties.
Workplace Info PagesFrom Workplace, it is possible to launch an Info page as either a popup or inline, depending on how it is configured in <app_root>/WEB-INF/InfoPages.xml. When launched as a popup, it is launched using the dynamic mode CREATE_POPUP.
When launched within the same browser window, it is launched using the dynamic mode CREATE_INLINE.
The return URL passed into the Info page will be required to specify its windowId if defined, since it is required to fully address the return page.
If the Info page is accessed inline from a popup (containing a popup window ID), the window ID is created as before, but the generated window ID that is stacked on top propagates the "popup" flag. By propagating the popup flag up the stack, the fact that the window is a popup is never lost.
Workplace ActionsIn Workplace, actions may also be configured to operate as popups, or inline. These are handled similarly to Info pages as described in the previous section.
When launched in a new browser window, the action is launched using the dynamic CREATE_POPUP mode. When launched inline, the action is launched using the dynamic CREATE_INLINE mode.
FileNet P8 Portlets - Portlet PopupsIn the FileNet P8 Portlets integration, most clicks in the Workplace portlets result in a popup window being opened. For example, when you click the "more..." link from the browse portlet, a popup window is opened that shows the folder bookmark view corresponding to the selected folder.

To prevent the user's desktop from getting needlessly cluttered, portlets are designed so that links that open these popup windows open a named browser window through JavaScript. When the named browser window already exists, the JavaScript pops it to the foreground.
The URL that is loaded in these named popups contains the setWindowId request parameter. When the JavaScript executes, it opens a named browser window and passes the browser window name as the value of the setWindowId request parameter. No hashing is needed, since there is a one-to-one relationship between the window ID and the browser window, and the portlet, in context is able to create its own unique window ID to be used.
Feedback