Anand V Nath created TRINIDAD-2515:
--------------------------------------
Summary: Avoid caching skins from external SkinProviders and make
LRU cache concurrent
Key: TRINIDAD-2515
URL: https://issues.apache.org/jira/browse/TRINIDAD-2515
Project: MyFaces Trinidad
Issue Type: Bug
Components: Skinning
Affects Versions: 2.1.0-core
Reporter: Anand V Nath
Problem statement:
SkinProvider SPI allows creation of external skin repositories and plug it into
trinidad skin framework. Skin framework should allow such skins to be managed
(created, cached, destroyed) by the SkinProvider. Currently this is not
happening.
Internal problem description:
When user requests a Skin, skin framework creates a StyleProvider for it. This
StyleProvider is cached at application level and reused for subsequent requests
for the same Skin. Since the StyleProvider contains the Skin, it effectively
caches the Skin also.
Solution:
Don't cache StyleProvider associated with Skins served from external
SkinProviders. For achieveing this introduce isCacheable API on SkinImpl and
implement it in SkinExtension:
{code}
/**
* Used by SkinStyleProvider to decide whether to cache the StyleProvider or
not.
* @return true if skin is internal to the framework.
*/
public abstract boolean isCacheable();
{code}
In SkinExtension introduce overloaded constructor for handling internal Skin
creation and external Skin creation (through SkinFactory.createSkin)
{code}
/**
* Creates SkinExtension from SkinMetadata and base Skin
* This constructor is used for creating skins for external SkinProvider
implementations.
* We keep skins thus created as not-cacheable.
* @see org.apache.myfaces.trinidadinternal.skin.SkinFactoryImpl
* @param baseSkin
* @param skinMetadata
*/
public SkinExtension(Skin baseSkin, SkinMetadata skinMetadata)
{
this(baseSkin, skinMetadata, false);
}
/**
* Creates SkinExtension from SkinMetadata, base Skin and cacheability
* This constructor is used only for INTERNAL skins
* @see org.apache.myfaces.trinidadinternal.skin.provider.TrinidadSkinProvider
* @param baseSkin
* @param skinMetadata
*/
public SkinExtension(Skin baseSkin, SkinMetadata skinMetadata, boolean
isCacheable)
{
// existing code:
// read values from skinMetadata and set
_isCacheable = isCacheable;
}
{code}
Check SkinImpl.isCacheable() before caching the StyleProvider.
For solving the concurrency issue in LRU cache used for caching StyleProviders,
introduce new CopyOnWriteArrayMap and use it.
For testing add SkinProvider test cases, CopyOnWriteArrayMap test cases.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)