myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Anand V Nath (JIRA)" <>
Subject [jira] [Commented] (TRINIDAD-2406) externalize skin repositories by using SkinProvider SPI
Date Wed, 09 Oct 2013 07:54:42 GMT


Anand V Nath commented on TRINIDAD-2406:

API and internal changes for implementing this are:

1.  Create an object to capture metadata about skin:
        public final class SkinMetadata
          SkinMetadata(id, family, renderKit, parentSkin, ... )
          public String getBaseSkinId()
          public String getId()
          public String getFamily()
          public String getRenderKit()
          public SkinVersion getVersion()
          public SkinFeatures getFeatures()
          public CustomMetadata getMetadata()
          public String getStyleSheetName()
          public String getResourceBundleName()
          public ValueExpression getTranslationSource()

Include a static inner builder class for:,
for easy instantiation of the SkinMetadata. Since we have too many parameters to be captured
for SkinMetadata, we use a builder.

public final class SkinMetadata {
  private SkinMetadata(Builder b) 
  public static final class Builder
    public Builder()

    // setters for optional items
    public Builder id(String id)
    public Builder family(String family)
    public Builder parent(String parent)
    public Builder version(SkinVersion version)
    public Builder styleSheetName(String styleSheetName)
    public Builder resourceBundleName(String resourceBundleName)
    public Builder translationSource(ValueExpression translationSource)
    public Builder baseSkinId(String baseSkinId)
    public Builder feature(SkinFeatures features)
    public Builder metadata(CustomMetadata metadata)

    // build method to create SkinMetadata object
    public SkinMetadata build()


For example the client code would look like:

new SkinMetadata.Builder().id(skinId).family(family).renderKitId(renderKitId).version(version).build();

2. Create SPI

public abstract class SkinProvider
   * Returns the Skin for the given skin ID.
   * The returned skin is not cached by the framework and thus it
   * is the responsibility of the provider to return the same instance
   * of the skin should it desire so.
  public abstract Skin getSkin(FacesContext context, SkinMetadata metadata)

   * A provider can optionally return information about some or all of the skins it provides.
   * Typically this information is generated without loading the skins
   * as this is a quick way to find out about the Skins in the provider and also thereby
   * supporting lazy loading of Skins.
   * SkinMetadata for a Skin should contain only features and metadata that it
   * explicitly supports. It should not contain the features and metadata that
   * belongs only to its parent skins.
   * @param context
   * @return
  public Collection<SkinMetadata> getSkinMetadata(FacesContext context)
    return Collections.emptyList();

3. extends
to abstract all common functionality of trinidad internal providers.

public abstract class BaseSkinProvider extends SkinProvider
  public Skin getSkin(FacesContext context, SkinMetadata skinMetadata)
    // common implementation shared between the internal trinidad skin providers.

  public Collection<SkinMetadata> getSkinMetadata(FacesContext context)
    // common implementation shared between the internal trinidad skin providers.

4. Implement extends
BaseSkinProvider to load all trinidad base skins and to be consistent with the SPI - This
extracts logic from SkinUtils.registerBaseSkins

public final class TrinidadBaseSkinProvider extends BaseSkinProvider
  // Implement the methods for handling all base trinidad skins currently registered using

5. Implement extends
BaseSkinProvider to read all the trinidad-skins.xml - This will consolidate code from SkinUtils.registerSkinExtensions

public final class TrinidadSkinProvider extends BaseSkinProvider
  // Implement the methods for handling all skins defined using trinidad-skins.xml
  // use this class as a wrapper on top on SkinFactory
  // remove any pre caching done in SkinFactory
  // load skins from SkinFactory only on need basis

  public Collection<SkinMetadata> getSkinMetadata()
    // return the information inside trinidad-skins.xml

6. Implement extends
BaseSkinProvider to handle all externally registered skins using SkinFactory.addSkin and SkinFactory.reload

public final class ExternalSkinProviderextends BaseSkinProvider
  // this provider supports reload and addSkin as required by SkinFactory.
  // SkinFactoryImpl will now call this class for its operations.
  // and SkinFactoryImpl will serve only such externally registered skins.
  // all other skins like trinidad-skins.xml and base skins will be served by 
  // their respective providers.

7. Implement which is a one point API
to load all kinds of SkinProviders - This API will query the SPIs to return the requested

public final class SkinProviderRegistry implementes SkinProvider
  public static SkinProvider getInstance();

  // for any getSkin API, query the registered SPIs followed by TrinidadSkinProvider and TrinidadBaseSkinProvider
  // This gives a chance for the registered SPIs to return their skin in front of the default
  // current implementation assumes that there will not be any collision for getSkin API based
on skin-id, family, name, renderkit etc
  // solve this problem as an when it arises

  public Collection<SkinMetadata> getSkinMetadata()
    // return the consolidated information from all registered SkinProvider SPIs 

8. Expose SkinExtension creation via SkinFactory

   * Creates a skin extension based on the supplied baseSkin and the information from supplied
   * The base skin supplied should be one that is queried out of SkinProvider.
   * @param context
   * @param baseSkinMetadata search criteria for the base skin
   * @param skinMetadata metadata to create new skin extension
   * @return a new SkinExtension object created using the skinMetadata supplied
   * @throws IllegalArgumentException if the baseSkinId contained in the supplied skinMetadata
did not match the id of the supplied baseSkin
   * @throws ClassCastException if the base skin supplied is not one queried out of SkinProvider.
  public Skin createSkin(FacesContext context, SkinMetadata baseSkinMetadata, SkinMetadata

   * Creates a skin extension based on the information from supplied skinMetadata. Id of the
base skin for the new
   * skin extension has to be set in the metadata.
   * @param context
   * @param skinMetadata metadata to create new skin extension
   * @return a new SkinExtension object createed using the skinMetadata supplied
   * @throws IllegalArgumentException if the baseSkinId contained in the supplied skinMetadata
did not match the id of the supplied baseSkin
  public Skin createSkin(FacesContext context, SkinMetadata skinMetadata)

9. Modify org.apache.myfaces.trinidadinternal.config.GlobalConfiguratorImpl not to init the
skins using
10. Modify the callers which uses to query skins
to use the new SkinProvider.
11.  Deprecate all methods in execpt for the
new createSkin methods
12. Modify to fall back on SkinProvider and ExternalSkinProvide
for all its operations.
13. Deprecate org.apache.myfaces.trinidadinternal.config.GlobalConfiguratorImpl.reloadSkins
since reloading of a skin is SkinProvider internal implementation.
14. Remove APIs like registerBaseSkins,
registerSkinExtensions which are moved.
15. Add APIs to to return the parsed information
from trinidad-skins.xml. This will be used by internal trinidad SkinProvider.
16. Remove duplication in parsing code by using SkinMetadata, SkinAddition, SkinVersion etc
which are already part of public API instead of SkinVersionNode, SkinAdditionNode, SkinNode

> externalize skin repositories by using SkinProvider SPI
> -------------------------------------------------------
>                 Key: TRINIDAD-2406
>                 URL:
>             Project: MyFaces Trinidad
>          Issue Type: Improvement
>          Components: Skinning
>    Affects Versions: 2.1.0-core
>            Reporter: Anand V Nath
> Introduce SkinProvider SPI. Users can use this to create their own skip repositories
and expose their skins to the skinning framework.
> Provide an API to query skin using skin family, skin id, render kit - This will make
use of the existing SkinFactory APIs. Only change here is that it should go over all the available
SkinProvider SPIs to find a match.
> Create internal SkinProvider SPIs to handle the Trinidad and RCF skins (or skins defined
using trinidad-skins.xml).
> Provide an API to list all the available skins from all SkinProvider SPIs and make the
skin metadata thus available.
> Make SkinExtension part of public API so that users can use this class to create the
Skin objects which they expose through their SkinProvider SPIs

This message was sent by Atlassian JIRA

View raw message