uPortal 3 Contexts
Writing and wiring uPortal3 context components
Fellow developers,
For those who are interested in up3 work, a few words of explanation regarding rendering contexts and components. Please refer to the attached diagram. First of all some background: a rendering context can define everything about the portal presentation (how content is generated, how request parameters are processed, etc.). Throughout a session, user might switch between different contexts. Contexts can be arbitrarily simple. For our purposes (which, at this moment are to build uP2-like context) it's convenient to use CompoundContext, which separates the parameter processing (IURLController) and rendering (IPortalRenderer) responsibilities.
For rendering, we can use a TreeRenderer implementation, which restricts us to rendering trees while still allowing arbitrary components. Rendering components are managed by the IRenderingComponentManager implementation (which, in uP2 will be a subclass of PipelineComponentManager, which restricts us to linear rendering pipelines). So that's where the rendering components are.
On the parameter processing side, we have a UrlProcessorListController, which is a url controller composed of a ordered list of url processors.
The purpose of this whole illustration is to show how to add rendering components and appropriate request parameter processors to this kind of a setup.
As an example of a component, we took LegacyLayoutSource (which wraps uP2's user layout managers to feed layouts into the rendering pipelines). That component happens to be the first in the rendering pipeline, but the details of that are only visible to the component manager implementation. The important thing is that LegacyLayoutSource, as any other rendering component is referenced from a component manager. There is a number of operations that LegacyLayoutSource can perform, such as adding/removing channels, etc. These operations are described by the ILegacyLayoutSourceCommands interface. The commands interface is implemented by two classes:
1. LegacyLayoutSourceCommandsUrlConstructor allows one to create URLs with parameters that (when sent in a request) would activate appropriate commands.
2. LegacyLayoutSourceUrlParameterProcessor analyzes request parameters and executes commands specified in the request by invoking methods on the LegacyLayoutSource (hence the association between the two).
This pattern (of a component, command interface and implementing url constructor + processor) is what I wanted to emphasize. Most uPortal2 functionality can be implemented this way. For example TransformationFilter (in the xslt package) follows the same pattern to implement flexible XSLT transformer component and provides url constructor/processor that implement parameter syntax used in the uPortal2 stylesheets.
A couple of other things on the diagram: components often need access to other session and user information, for example user profile. In this case, LegacyLayoutSource is configured with a reference to a IProfileController implementation, which is able to report on current profile and notify component about profile changes. The profile controller implementation also processes request information (to select profiles based on request headers, or parameters). Similarly, components can enlist help of other controllers (i.e. persistence, user id, directory information, etc.)