public interface IModuleBuilder
Instances of this interface are created by the eclipse extension framework
for Aggregator extensions that implement the
com.ibm.jaggr.core.modulebuilder
extension point.
Aggregator extensions may also register module builders by calling
IExtensionInitializer.IExtensionRegistrar.registerExtension(java.lang.Object, java.util.Properties, com.ibm.jaggr.core.InitParams, java.lang.String, java.lang.String, com.ibm.jaggr.core.IAggregatorExtension)
when the extension's
IExtensionInitializer.initialize(com.ibm.jaggr.core.IAggregator, com.ibm.jaggr.core.IAggregatorExtension, com.ibm.jaggr.core.IExtensionInitializer.IExtensionRegistrar)
method is called (assuming the
extension implements the IExtensionInitializer
interface).
The extension point defines the plugin
and extension
attributes which are used by the aggregator to select the extension
implementation based on the module being built. See
IAggregator.getModuleBuilder(java.lang.String, com.ibm.jaggr.core.resource.IResource)
for a description of how the aggregator
selects an IMoudleBuilder
for a module.
Module builders provide the processed and minified (built) content for the
type of module being requested. The built output may vary depending on
request parameters. In this case, implementors need to provide a
ICacheKeyGenerator
which will be used to obtain a unique identifier
for a build with the given request parameters. The keys from this object will
be used by the module cache manager to locate cached builds that can satisfy
the current request, and by the layer cache manager to identify cached
layers.
Module builds are provided as javascript code that defines an AMD module. For non-javascript types of content, the content must be provided as a javascript string wrapped in a define function similar to the following:
define([], 'Content goes here');
The above example is for an anonymous module. If the request attribute
specified by IHttpTransport.EXPORTMODULENAMES_REQATTRNAME
is true,
then a named module must be provided with the module name specified as the
first parameter of the define function.
define("foo/bar", [], 'Content goes here');
It is assumed that there is a loader plugin on the client that requested the
module which knows how to extract the content from the module and work with
it, or transform it if necessary. For many non-javascript resources, the text
plugin provided by the IHttpTransport
extension can be relied upon to
handle the content on the client.
Each of the methods in this interface can be called concurrently for the same
or different requests, so implementors must take appropriate steps to guard
against race conditions and other threading issues common in multi-threaded
programs. In particular, module builders must not set request attributes
directly since this operation is not thread-safe. Instead, module builders
may set properties in the ConcurrentMap which may be retrieved from the
request attribute named IAggregator.CONCURRENTMAP_REQATTRNAME
.
Modifier and Type | Method and Description |
---|---|
ModuleBuild |
build(String mid,
IResource resource,
javax.servlet.http.HttpServletRequest request,
List<ICacheKeyGenerator> keyGens)
Returns a
ModuleBuild object containing the processed (built)
output for the requested module. |
List<ICacheKeyGenerator> |
getCacheKeyGenerators(IAggregator aggregator)
This method may be called, before
build(String, IResource, HttpServletRequest, List)
is called by a separate worker thread, to obtain a cache key generator
for this builder. |
boolean |
handles(String mid,
IResource resource)
Returns true if this module builder handles the specified resource
|
boolean |
isScript(javax.servlet.http.HttpServletRequest request) |
ModuleBuild build(String mid, IResource resource, javax.servlet.http.HttpServletRequest request, List<ICacheKeyGenerator> keyGens) throws Exception
ModuleBuild
object containing the processed (built)
output for the requested module.
If an error occurs, this method can throw an exception, or else let an exception that occurs at a lower level propagate up. How the exception gets handled depends largely on whether or not development mode is enabled.
If development mode is not enabled, then the exception is converted to a ServletException and allowed to propagate to the servlet container. This will result in an error response being returned to the client.
If development mode is enabled, then exceptions thrown by this method are handled by creating a module build containing code to invoke console.error() on the client, specifying the exception message as the error text, and the aggregated response is flagged as an error response to prevent caching of the response either on the server or on the client. The content value which is returned by the define function is an empty string.
If a builder would like to handle errors in development mode differently,
either by providing partial content or to have more control over what is
displayed in the client console, then this method can return the error
content in the build output and use the ModuleBuild
constructor
that allows you to specify an error flag. Specifying true for the error
flag will cause the aggregated response containing this module build to
be flagged as an error and the build output will not be cached either on
the server or on the client.
If the request attribute specified by
IHttpTransport.EXPORTMODULENAMES_REQATTRNAME
is false, then this
method SHOULD return an anonymous module, however, if the request
attribute is true, then this method MUST return a named module (the first
parameter of the define function for the module must be the value
specified by mid
).
If, for some reason, a module builder is unable to provide named modules
for a request, then the module builder should register a
ILayerListener
service with the OSGi service registry,
specifying the name of the aggregator as the name
property of the
service, and then set the value of the
IHttpTransport.EXPORTMODULENAMES_REQATTRNAME
request attribute to
false in the
ILayerListener.layerBeginEndNotifier(ILayerListener.EventType, HttpServletRequest, List, Set)
method.
This method may choose to return a build containing multiple named
modules if the request attribute specified by
IHttpTransport.EXPORTMODULENAMES_REQATTRNAME
is true. A builder
that provides i18n resource modules, for example, may choose to include
additional, locale specific, resource modules based on the request
locale(s), however, this may only be done if all the modules in a
response are named. If anonymous modules are being requested (i.e. the
request attribute specified by
IHttpTransport.EXPORTMODULENAMES_REQATTRNAME
is false), then only
the requested module may be included in the build output, regardless of
whether or not the module builds provided by this builder are named.
The module builder may update one or more of the cache key generators in
keyGens
by specifying a new list of cache key generators in
the returned ModuleBuild
object. When a new list is provided,
the cached cache key generator list for this module, and any layers
containing this module, are updated. If this method returns the same list
object specified by keyGens
in the ModuleBuild
, then no updates of the cached key generators are performed. Most module
builders will have no need to update a cached key generator list once it
has been created and should just return
keyGens
in the ModuleBuild
object, however, if
keyGens
is null,
then a new cache key generator list containing only non-provisional
cache key generators MUST be provided in the returned ModuleBuild
.
A module builder should always return the same sized cache key generator
list for any given resource, and the cache key generators in the list
must be the same class, and in the same sequence, for all responses for
the same resource. Note that subclasses of this class may add their own
cache key generators to the result list, so keyGens
may be
larger than what this method previously returned because it contains
contributions from the subclasses. If this class wishes to update the
cache key generator list, it should not try to include any of these
added cache key generators in the new list. It should only include its
own cache key generators. Subclasses are responsible for detecting that
the superclass has updated the list in the result and then adding their
own cache key generators to the new result.
mid
- The module idresource
- The resource object for the source module.request
- The HTTP request objectkeyGens
- List of cache key generators for this module that was
obtained by a previous call to this method or
getCacheKeyGenerators(IAggregator)
. If null,
then the ModuleBuild
returned by this method must
specify a new list of non-provisional cache key generators,
otherwise, this method may return a ModuleBuild
object
that specifies keyGen
for the cache key generator.ModuleBuild
objectException
List<ICacheKeyGenerator> getCacheKeyGenerators(IAggregator aggregator)
build(String, IResource, HttpServletRequest, List)
is called by a separate worker thread, to obtain a cache key generator
for this builder. If cache keys for this builder depend on module
content, then this method should return a provisional cache key
generator, which generates cache keys based on information in the request
only. Provisional cache keys may be more exclusive than non-provisional
cache keys in matching requests to module builds.
If this method returns a provisional cache key generator, then
build(String, IResource, HttpServletRequest, List)
will be called with a null cache key generator list and that method
MUST return a
ModuleBuild
object with a new immutable list of non-provisional cache key
generators when subsequently called for the same request.
aggregator
- The aggregator instanceboolean handles(String mid, IResource resource)
mid
- the module idresource
- the resource for the module idboolean isScript(javax.servlet.http.HttpServletRequest request)
request
- the request objectCopyright © 2011-2015 IBM. All Rights Reserved.