This section provides an overview of the Assembler. It describes the Assembler processing model and core interfaces as well as how to implement a cartridge handler.
A cartridge handler takes a content item representing the cartridge instance configuration as input and is responsible for returning the response as a content item.
The
CartridgeHandler
interface defines three methods:
initialize()
,
preprocess()
, and
process()
.
The
initialize()
method provides an opportunity for the
cartridge handler to augment the cartridge instance configuration specified in
Experience Manager with configuration from other sources. This can be used to
define default behavior for a cartridge in the case where there is no
Experience Manager configuration, or to override the Experience Manager
configuration for the current query. The
initialize()
method should return a content item
containing the complete configuration for the cartridge from all possible
configuration sources. This augmented configuration item can either be the
mutated input content item or a new instance of
ContentItem
, and is used as input to both the
preprocess()
and
process()
methods.
Because the
preprocess()
method is called on all cartridges before
process()
is called on any cartridges, it provides an
opportunity to coordinate processing between cartridges. Many of the core
cartridges make use of this mechanism in order to consoldiate queries to an
MDEX Engine among several cartridges during the course of a single assembly
cycle.
The
process()
method is responsible for returning a
ContentItem
that represents the cartridge response.
A cartridge handler need not define any behavior for
initialize()
or
preprocess()
. The
AbstractCartridgeHandler
class exists to simplify the
task of implementing the
CartridgeHandler
interface. It provides empty
implementations for
initialize()
and
preprocess()
. Subclasses of
AbstractCartridgeHandler
need only implement the
process()
method to return the response object. They can
optionally override the
initialize()
and
preprocess()
methods.
The
initialize()
phase in the cartridge processing life cycle
enables the cartridge handler to synthesize the complete configuration for the
cartridge from several sources.
The configuration content item that is passed in to the assembly process is the cartridge instance configuration from Experience Manager, however, any given cartridge may also have other configuration sources.
In a typical scenario, a cartridge has some default behavior that can be specified as a property value in a Spring context file. A business user can specify a value for a specific instance of a cartridge using Experience Manager. The site visitor may also have the ability to override either the default or the cartridge instance setting from the client application. For example, in the Results List cartridge, the default value for records per page is 10. The business user can set this value to 25 in Experience Manager, and the site visitor can choose to display 50 records by selecting the appropriate option on the site.
The Assembler API includes the
ConfigInitializer
utility class with the method
initialize()
. The default implementation of
initialize()
layers the cartridge configuration in the
following order (from lowest to highest):
Default configuration, typically defined in the Spring configuration for the cartridge handler
Cartridge instance configuration, typically created in Experience Manager and passed in as the configuration content item
Request-based configuration parsed from the HTTP request parameters, using the
RequestParamMarshaller
helper class
The
ConfigInitializer
class also provides methods for
additional layering of configuration. Subclasses can override
ConfigInitializer
to define custom layering behavior,
for example, to incorporate configuration saved in the session state.
The core cartridges that make queries to an MDEX Engine use
cartridge handlers that extend from
NavigationCartridgeHandler
.
The
NavigationCartridgeHandler
makes use of the two-pass
Assembler processing model to consolidate MDEX Engine queries across
cartridges.
In the
preprocess()
phase, the cartridge handler calls
createMdexRequest()
but does not execute the request. In
subsequent calls to
createMdexRequest()
by other handlers, the MDEX resource
broker determines whether the new request can be consolidated with an existing
request in order to minimize the number of queries to the MDEX Engine for a
single assembly cycle.
During the
process()
phase, the handler calls
executeMdexRequest()
to retrieve the results. The actual
query to the MDEX Engine is executed when the first handler in the assembly
cycle calls
executeMdexRequest()
and the results are cached for all
subsequent handlers that try to execute the same request.
You can use a similar approach if you have multiple cartridges that need to make requests to the same external resource and can achieve efficiencies by consolidating requests across cartridges.
For further information about the
NavigationCartridgeHandler
class, refer to the
Assembler API Reference (Javadoc).
You add a cartridge handler by writing a Java class that
implements the
CartridgeHandler
interface and configuring the Assembler
to use the new handler in the Spring context file.
In this
example, we update our "Hello, World" cartridge to do some simple string
manipulation on the message that was specified in Experience Manager. Because
this cartridge does not use any configuration other than the cartridge instance
configuration from Experience Manager and does not need to do any
preprocessing, we can extend
AbstractCartridgeHandler
.
To add a cartridge handler to the example cartridge:
Create a new Java class in the package
com.endeca.sample.cartridges
and type or copy the following:package com.endeca.sample.cartridges; import com.endeca.infront.assembler.AbstractCartridgeHandler; import com.endeca.infront.assembler.CartridgeHandlerException; import com.endeca.infront.assembler.ContentItem; public class UppercaseCartridgeHandler extends AbstractCartridgeHandler { //==================================================================== // The cartridge handler 'process' method public ContentItem process(ContentItem pContentItem) throws CartridgeHandlerException { // Get the message property off of the content item. final String message = (String) pContentItem.get("message"); // If the message is non-null, uppercase it. if (null != message) { pContentItem.put("message", message.toUpperCase()); } return pContentItem; } }
Compile the cartridge handler and add the compiled class to your application, for example, by saving it in
%ENDECA_TOOLS_ROOT%\reference\discover-electronics-authoring\WEB-INF\classes
.Configure the Assembler to use the
UppercaseCartridgeHandler
for the Hello cartridge.Navigate to the
WEB-INF
directory of your application, for example,%ENDECA_TOOLS_ROOT%\reference\discover-electronics-authoring\WEB-INF
.Add the following in the
CARTRIDGE HANDLERS
section:<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ BEAN: CartridgeHandler_Hello --> <bean id="CartridgeHandler_Hello" class="com.endeca.sample.cartridges.UppercaseCartridgeHandler" scope="prototype" />
The message now appears in all-uppercase letters.
You should write a cartridge handler in cases where you need to perform some processing on the cartridge instance configuration before sending the response to the client application.
It is always possible to do processing in the client application, but encapsulating the business logic in an extension to the Assembler provides several advantages:
It centralizes the processing in one place so that the results can be consumed by multiple client applications including across multiple channels such as desktop, mobile, and others.
It provides an opportunity for coordinating processing across multiple cartridges before returning the response to the client application.
Depending on what the cartridge handler needs to accomplish, your
implementation approach may vary. Cartridge handlers must always implement the
process()
method to return the response model.
Scenario |
Implementation approach |
Example cartridge |
---|---|---|
Update properties from the cartridge instance configuration in place (data cleansing or manipulation scenario) |
Extend
|
"Hello, World" with UppercaseCartridgeHandler |
Use information from the cartridge instance configuration to query an external resource for the information to display |
Extend
|
RSS Feed cartridge |
Query an external resource, consolidating queries between cartridges within a single assembly cycle for improved performance |
Take advantage of the two-pass assembly model
with
|
NavigationCartridgeHandler |
Augment the results from a core cartridge with additional information from a non-MDEX resource |
Extend the core cartridge and override
|
Custom Record Details with availability information |
Customize a core cartridge to modify the MDEX Engine query parameters |
Extend the core cartridge and override either
|
Custom Results List with recommendations |
Combine multiple sources of cartridge configuration before processing results |
Extend
|
"Hello, World" with layered color configuration |