You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by an...@apache.org on 2014/10/16 12:31:26 UTC
svn commit: r1632268 [1/2] - in /myfaces/trinidad/trunk:
trinidad-api/src/test/java/org/apache/myfaces/trinidadbuild/test/
trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/
trinidad-impl/src/main/java/org/apache/myfaces/tri...
Author: andys
Date: Thu Oct 16 10:31:25 2014
New Revision: 1632268
URL: http://svn.apache.org/r1632268
Log:
Setting el-style to native for new files from previous commit.
Modified:
myfaces/trinidad/trunk/trinidad-api/src/test/java/org/apache/myfaces/trinidadbuild/test/ConcurrentMapTestCase.java (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/BaseSkinProvider.java (contents, props changed)
myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/SkinProviderRegistry.java (contents, props changed)
myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadSkinProvider.java (contents, props changed)
myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/CopyOnWriteArrayMap.java (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/skin/custom/CustomSkinProvider1.java (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/skin/custom/CustomSkinProvider2.java (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/skin/provider/SkinProviderTest.java (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/util/CopyOnWriteArrayMapTest.java (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/util/LRUCopyOnWriteArrayMapTest.java (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/resources/META-INF/services/org.apache.myfaces.trinidad.skin.SkinProvider (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/resources/META-INF/trinidad-skins.xml (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/skin/beach/CustomStyles.css (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/skin/beach/beach.css (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/skin/purple/purpleBigFontSkin.css (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/skin/purple/purpleBigFontSkinFour.css (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/skin/purple/purpleBigFontSkinThree.css (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/skin/purple/purpleBigFontSkinTwo.css (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/skin/purple/purpleSkin.css (props changed)
myfaces/trinidad/trunk/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/skin/suede/suede.css (props changed)
Propchange: myfaces/trinidad/trunk/trinidad-api/src/test/java/org/apache/myfaces/trinidadbuild/test/ConcurrentMapTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/BaseSkinProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/BaseSkinProvider.java?rev=1632268&r1=1632267&r2=1632268&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/BaseSkinProvider.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/BaseSkinProvider.java Thu Oct 16 10:31:25 2014
@@ -1,480 +1,480 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.myfaces.trinidadinternal.skin.provider;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.faces.context.ExternalContext;
-
-import org.apache.myfaces.trinidad.logging.TrinidadLogger;
-import org.apache.myfaces.trinidad.skin.Skin;
-import org.apache.myfaces.trinidad.skin.SkinMetadata;
-import org.apache.myfaces.trinidad.skin.SkinProvider;
-import org.apache.myfaces.trinidad.skin.SkinVersion;
-
-/**
- * This is the common base class for Trinidad SkinProviders. This class abstracts out some common
- * code that is useful across Trinidad internal SkinProviders. One such example worth mentioning is
- * the code to finding a Skin match for a given SkinMetadata search criteria.
- *
- * @See TrinidadBaseSkinProvider
- * @See TrinidadSkinProvider
- * @See ExternalSkinProvider
- */
-abstract class BaseSkinProvider extends SkinProvider
-{
- public BaseSkinProvider()
- {
- initSkins();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Skin getSkin(ExternalContext context, SkinMetadata skinMetadata)
- {
- synchronized (this)
- {
- return _getMatchingSkin(context, skinMetadata);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Collection<SkinMetadata> getSkinMetadata(ExternalContext context)
- {
- synchronized (this)
- {
- return Collections.unmodifiableCollection(_skins.keySet());
- }
- }
-
- /**
- * add method used to register a skin with the provider.
- *
- * @param metadata
- * @param skin
- * @return Any previously registered skins existing with the same metadata
- */
- public Skin addSkin(SkinMetadata metadata, Skin skin)
- {
- if (metadata == null || skin == null)
- {
- _LOG.warning("CANNOT_ADD_SKIN");
- return null;
- }
-
- if (_LOG.isFine())
- _LOG.fine("Adding skin to cache [metadata: {0}, skin: {1}]", new Object[] {metadata, skin});
-
- synchronized (this)
- {
- return _skins.put(metadata, skin);
- }
- }
-
- /**
- * template method to be implemented by subclasses with logic to load a skin that base class knows
- * as available with the current skin provider being asked to load the skin
- *
- * @param context
- * @param skinMetadata
- */
- protected abstract Skin loadAvailableSkin(ExternalContext context, SkinMetadata skinMetadata);
-
- /**
- * getter for the skins, only used by ExternalSkinProvider.reload to cache and restore the skins
- * if reload fails
- *
- * @return
- */
- protected Map<SkinMetadata, Skin> getSkins()
- {
- synchronized (this)
- {
- return _skins;
- }
- }
-
- /**
- * setter for the skins, only used by ExternalSkinProvider.reload to cache and restore the skins
- * if reload fails
- *
- * @param skins
- */
- protected void setSkins(Map<SkinMetadata, Skin> skins)
- {
- synchronized (this)
- {
- // do not allow a null to be set.
- if (skins == null)
- skins = new HashMap<SkinMetadata, Skin>();
-
- _skins = skins;
- }
- }
-
- /**
- * initialize a new HashMap for the skins, used by constructor and ExternalSkinProvider.reload
- */
- protected void initSkins()
- {
- synchronized (this)
- {
- _skins = new HashMap<SkinMetadata, Skin>();
- }
- }
-
- /**
- * Hook to do any kind of initialization before loading a skin or skin metadata sub classes can
- * choose to implement
- *
- * @param context
- */
- protected void initialize(ExternalContext context)
- {
- }
-
- /**
- * one point method for searching skins
- *
- * @param context
- * @param searchMetadata to search for
- * @return matching skin
- */
- private final Skin _getMatchingSkin(ExternalContext context, SkinMetadata searchMetadata)
- {
- if (searchMetadata == null)
- throw new NullPointerException("SkinMetadata passed for search is null");
-
- // find a skin that is already loaded using the exact search metadata passed.
- Skin availableSkin = _skins.get(searchMetadata);
- if (availableSkin != null)
- return availableSkin;
-
- // there is no skin already available, so find a skin which matches the search criteria
- // verify that either id or family is set for the search
- if (null == searchMetadata.getId() && null == searchMetadata.getFamily())
- {
- if (_LOG.isWarning())
- _LOG.warning("SP_CANNOT_FIND_SKIN_WITHOUT_FAMILY_OR_ID");
-
- throw new NullPointerException(_LOG.getMessage("SP_CANNOT_FIND_SKIN_WITHOUT_FAMILY_OR_ID"));
- }
-
- initialize(context);
-
- if (_LOG.isFine())
- _LOG.fine("SP_FINDING_SKIN_FOR", new Object[]{searchMetadata.toString()});
-
- // first check if a skin matching the requirement is present in this provider
-
- SkinMetadata availableMetadata = _findSkinMetadata(context, searchMetadata);
- if (availableMetadata == null)
- {
- if (_LOG.isFine())
- _LOG.fine(this + " Cannot find skin in this provider: " + searchMetadata);
-
- return null;
- }
-
- // find a skin that is already loaded
- // this is different from doing it at the beginning of the method
- // because the metadata with which the skin is added into _skins
- // may not have matched completely, since searchMetadata can provide
- // only certain conditions.
- availableSkin = _skins.get(availableMetadata);
- if (availableSkin != null)
- return availableSkin;
-
- // now we know that there is a skin available but not loaded
- // so load the skin
- availableSkin = loadAvailableSkin(context, availableMetadata);
- assert (availableSkin != null);
-
- _skins.put(availableMetadata, availableSkin);
-
- return availableSkin;
- }
-
- /**
- * find if there is a skin with the search condition supported by the current SkinProvider
- *
- * @param search
- * @return
- */
- private SkinMetadata _findSkinMetadata(ExternalContext context, SkinMetadata search)
- {
- SkinMetadata matchingSkinMetadata = null;
- String skinId = search.getId();
-
- Collection<SkinMetadata> skinMetadata = getSkinMetadata(context);
-
- if (skinMetadata == null || skinMetadata.isEmpty())
- return null;
-
- // search is with either id or (family, renderkit, version)
- // we have ensure that either id or family is passed in the search
- if (skinId != null)
- {
- // Id is available then search using ID
- for (SkinMetadata m : skinMetadata)
- if (skinId.equals(m.getId()))
- {
- matchingSkinMetadata = m;
- }
-
- if (matchingSkinMetadata == null)
- {
- if (_LOG.isFine())
- {
- _LOG.fine("SP_CANNOT_FIND_MATCHING_SKIN_ID", new Object[]{skinId});
- }
- }
- }
- else
- {
- // search using family, renderkit, version
- String family = search.getFamily();
-
- // we need at least the family to go on with the search
- if (family == null)
- return null;
-
- // renderkit id cannot be null, we initialize it to APACHE_TRINIDAD_DESKTOP
- String renderKit = search.getRenderKitId();
-
- // version cannot be null as we initialize it to SkinVersion.EMPTY_SKIN_VERSION
- SkinVersion version = search.getVersion();
-
- List<SkinMetadata> familyRenderKitMatches = new ArrayList<SkinMetadata>(2);
-
- // search using family and renderkit id
- for (SkinMetadata m : skinMetadata)
- if (family.equalsIgnoreCase(m.getFamily()) &&
- renderKit.equalsIgnoreCase(m.getRenderKitId()))
- familyRenderKitMatches.add(m);
-
- if (familyRenderKitMatches.isEmpty())
- {
- // if we get here, that means we couldn't find an exact
- // family/renderKitId match, so return the simple skin
- // that matches the renderKitId.
- if (_LOG.isFine())
- {
- _LOG.fine("SP_CANNOT_FIND_MATCHING_SKIN", new Object[]{family, renderKit});
- }
-
- return null;
- }
-
- // at this point we know we have something in the familyRenderKitMatches
- // which is a list of matching family and renderKitId skins. Now match the version
- // to find the best matched skin.
- String versionName = version.getName();
- boolean versionIsDefault = version.isDefault();
- boolean foundMatchingSkin = false;
-
- // if the user didn't ask for the 'default' version, then look for the exact match
- if (!versionIsDefault)
- {
- matchingSkinMetadata = _findSkinMetadataForVersionName(familyRenderKitMatches, version);
- }
-
- // matchingSkinMetadata will be null if an exact version match (family+renderKitId+version)
- // was not found;
- // or if user was asking for a default version
- // we can have an exact version match if the user asks for null version,
- // and we find a skin with no
- // version set.
- if (matchingSkinMetadata == null || versionIsDefault)
- {
- // at this point either user is looking for default skin
- // or did not find the exact version match specified
- // so we find the default skin
- matchingSkinMetadata = _findSkinMetadataWithDefaultVersion(familyRenderKitMatches);
-
- if (matchingSkinMetadata == null)
- {
- // if we fail to find a default skin then
- // get the latest skin in the matchingSkinList if there is no skin marked default.
- if (_LOG.isFine())
- _LOG.fine(this + " did not find default / version skinMetadata. so getting leaf skin");
-
- matchingSkinMetadata = _findLeafSkinMetadata(familyRenderKitMatches);
- }
- else if ((matchingSkinMetadata != null) && versionIsDefault)
- {
- // found the default skin the user wanted
- if (_LOG.isFine())
- _LOG.fine(this + " found default skinMetadata");
-
- foundMatchingSkin = true;
- }
- }
-
- // log messages
- if (foundMatchingSkin)
- {
- if (_LOG.isFine())
- _LOG.fine("GET_SKIN_FOUND_SKIN_VERSION",
- new Object[]{family, version, matchingSkinMetadata.getId()});
- }
- else if (matchingSkinMetadata != null)
- {
- if (_LOG.isFine())
- {
- if ("".equals(versionName))
- {
- _LOG.fine("GET_SKIN_CANNOT_FIND_NO_VERSION",
- new Object[]{family, matchingSkinMetadata.getId()});
- }
- else
- {
- _LOG.fine("GET_SKIN_CANNOT_FIND_SKIN_VERSION",
- new Object[]{family, version, matchingSkinMetadata.getId()});
- }
- }
- }
-
- if (matchingSkinMetadata == null)
- {
- matchingSkinMetadata = familyRenderKitMatches.get(familyRenderKitMatches.size() - 1);
- }
- }
-
-
- if (matchingSkinMetadata != null)
- if (_LOG.isFine())
- _LOG.fine(this + " found matching metadata: " + matchingSkinMetadata);
-
- return matchingSkinMetadata;
- }
-
- /**
- * find a skin with version passed
- *
- * @param skins
- * @param version
- * @return
- */
- private SkinMetadata _findSkinMetadataForVersionName(Collection<SkinMetadata> skins,
- SkinVersion version)
- {
- if (version == null)
- throw new IllegalArgumentException("skin version cannot be null");
-
- if (version.getName() == null || version.getName().isEmpty())
- return null;
-
- for (SkinMetadata metadata : skins)
- {
- // metadata cannot be null and also version inside it cannot be null
- if (version.getName().equals(metadata.getVersion().getName()))
- {
- if (_LOG.isFine())
- _LOG.fine("Found version match skinMetadata: " + metadata);
-
- return metadata;
- }
- }
-
- return null;
- }
-
- /**
- * Latest skin is the one which is last in the family hierarchy eg: fusion-v1 -> fusion-v2 ->
- * fusion-v3 Among this fusion-v3 is the latest. So we look for a skin that is not extended by any
- * other skin in the family.
- *
- * @param skins
- * @return
- */
- private SkinMetadata _findLeafSkinMetadata(Collection<SkinMetadata> skins)
- {
- List<SkinMetadata> leafSkinMetadata = new ArrayList<SkinMetadata>();
- List<String> parentIds = new ArrayList<String>();
-
- // collect parents skins among the list
- for (SkinMetadata metadata : skins)
- {
- String parentId = metadata.getBaseSkinId();
- if (parentId != null)
- parentIds.add(metadata.getBaseSkinId());
- }
-
- // find leaf skins, which is not in parent list
- for (SkinMetadata metadata : skins)
- {
- String skinId = metadata.getId();
- if (skinId != null && !parentIds.contains(skinId))
- {
- leafSkinMetadata.add(metadata);
- }
- }
-
- // if there are no leaves, return null
- // this is a rare case, almost impossible since there will be
- // at least one skin which is not parent of another
- // but let us cover the corner case if any
- if (leafSkinMetadata.isEmpty())
- return null;
-
- // if there is one leaf skin return that
- // if there are many, return the last one among the leaves
- return leafSkinMetadata.get(leafSkinMetadata.size() - 1);
- }
-
- /**
- * find a skin that has its SkinVersion set to 'default', if it exists.
- *
- * @param matchingSkinList A list of Skins that we will look through to find the 'default'.
- * @return Skin with SkinVersion isDefault true, otherwise, null.
- */
- private SkinMetadata _findSkinMetadataWithDefaultVersion(
- Collection<SkinMetadata> matchingSkinList)
- {
- for (SkinMetadata metadata : matchingSkinList)
- {
- SkinVersion skinVersion = metadata.getVersion();
-
- if (skinVersion != null && skinVersion.isDefault())
- {
- if (_LOG.isFine())
- _LOG.fine("Found default skinMetadata: " + metadata);
-
- return metadata;
- }
- }
-
- return null;
- }
-
- private Map<SkinMetadata, Skin> _skins;
- private final static TrinidadLogger _LOG =
- TrinidadLogger.createTrinidadLogger(BaseSkinProvider.class);
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.trinidadinternal.skin.provider;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.ExternalContext;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidad.skin.SkinMetadata;
+import org.apache.myfaces.trinidad.skin.SkinProvider;
+import org.apache.myfaces.trinidad.skin.SkinVersion;
+
+/**
+ * This is the common base class for Trinidad SkinProviders. This class abstracts out some common
+ * code that is useful across Trinidad internal SkinProviders. One such example worth mentioning is
+ * the code to finding a Skin match for a given SkinMetadata search criteria.
+ *
+ * @See TrinidadBaseSkinProvider
+ * @See TrinidadSkinProvider
+ * @See ExternalSkinProvider
+ */
+abstract class BaseSkinProvider extends SkinProvider
+{
+ public BaseSkinProvider()
+ {
+ initSkins();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Skin getSkin(ExternalContext context, SkinMetadata skinMetadata)
+ {
+ synchronized (this)
+ {
+ return _getMatchingSkin(context, skinMetadata);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<SkinMetadata> getSkinMetadata(ExternalContext context)
+ {
+ synchronized (this)
+ {
+ return Collections.unmodifiableCollection(_skins.keySet());
+ }
+ }
+
+ /**
+ * add method used to register a skin with the provider.
+ *
+ * @param metadata
+ * @param skin
+ * @return Any previously registered skins existing with the same metadata
+ */
+ public Skin addSkin(SkinMetadata metadata, Skin skin)
+ {
+ if (metadata == null || skin == null)
+ {
+ _LOG.warning("CANNOT_ADD_SKIN");
+ return null;
+ }
+
+ if (_LOG.isFine())
+ _LOG.fine("Adding skin to cache [metadata: {0}, skin: {1}]", new Object[] {metadata, skin});
+
+ synchronized (this)
+ {
+ return _skins.put(metadata, skin);
+ }
+ }
+
+ /**
+ * template method to be implemented by subclasses with logic to load a skin that base class knows
+ * as available with the current skin provider being asked to load the skin
+ *
+ * @param context
+ * @param skinMetadata
+ */
+ protected abstract Skin loadAvailableSkin(ExternalContext context, SkinMetadata skinMetadata);
+
+ /**
+ * getter for the skins, only used by ExternalSkinProvider.reload to cache and restore the skins
+ * if reload fails
+ *
+ * @return
+ */
+ protected Map<SkinMetadata, Skin> getSkins()
+ {
+ synchronized (this)
+ {
+ return _skins;
+ }
+ }
+
+ /**
+ * setter for the skins, only used by ExternalSkinProvider.reload to cache and restore the skins
+ * if reload fails
+ *
+ * @param skins
+ */
+ protected void setSkins(Map<SkinMetadata, Skin> skins)
+ {
+ synchronized (this)
+ {
+ // do not allow a null to be set.
+ if (skins == null)
+ skins = new HashMap<SkinMetadata, Skin>();
+
+ _skins = skins;
+ }
+ }
+
+ /**
+ * initialize a new HashMap for the skins, used by constructor and ExternalSkinProvider.reload
+ */
+ protected void initSkins()
+ {
+ synchronized (this)
+ {
+ _skins = new HashMap<SkinMetadata, Skin>();
+ }
+ }
+
+ /**
+ * Hook to do any kind of initialization before loading a skin or skin metadata sub classes can
+ * choose to implement
+ *
+ * @param context
+ */
+ protected void initialize(ExternalContext context)
+ {
+ }
+
+ /**
+ * one point method for searching skins
+ *
+ * @param context
+ * @param searchMetadata to search for
+ * @return matching skin
+ */
+ private final Skin _getMatchingSkin(ExternalContext context, SkinMetadata searchMetadata)
+ {
+ if (searchMetadata == null)
+ throw new NullPointerException("SkinMetadata passed for search is null");
+
+ // find a skin that is already loaded using the exact search metadata passed.
+ Skin availableSkin = _skins.get(searchMetadata);
+ if (availableSkin != null)
+ return availableSkin;
+
+ // there is no skin already available, so find a skin which matches the search criteria
+ // verify that either id or family is set for the search
+ if (null == searchMetadata.getId() && null == searchMetadata.getFamily())
+ {
+ if (_LOG.isWarning())
+ _LOG.warning("SP_CANNOT_FIND_SKIN_WITHOUT_FAMILY_OR_ID");
+
+ throw new NullPointerException(_LOG.getMessage("SP_CANNOT_FIND_SKIN_WITHOUT_FAMILY_OR_ID"));
+ }
+
+ initialize(context);
+
+ if (_LOG.isFine())
+ _LOG.fine("SP_FINDING_SKIN_FOR", new Object[]{searchMetadata.toString()});
+
+ // first check if a skin matching the requirement is present in this provider
+
+ SkinMetadata availableMetadata = _findSkinMetadata(context, searchMetadata);
+ if (availableMetadata == null)
+ {
+ if (_LOG.isFine())
+ _LOG.fine(this + " Cannot find skin in this provider: " + searchMetadata);
+
+ return null;
+ }
+
+ // find a skin that is already loaded
+ // this is different from doing it at the beginning of the method
+ // because the metadata with which the skin is added into _skins
+ // may not have matched completely, since searchMetadata can provide
+ // only certain conditions.
+ availableSkin = _skins.get(availableMetadata);
+ if (availableSkin != null)
+ return availableSkin;
+
+ // now we know that there is a skin available but not loaded
+ // so load the skin
+ availableSkin = loadAvailableSkin(context, availableMetadata);
+ assert (availableSkin != null);
+
+ _skins.put(availableMetadata, availableSkin);
+
+ return availableSkin;
+ }
+
+ /**
+ * find if there is a skin with the search condition supported by the current SkinProvider
+ *
+ * @param search
+ * @return
+ */
+ private SkinMetadata _findSkinMetadata(ExternalContext context, SkinMetadata search)
+ {
+ SkinMetadata matchingSkinMetadata = null;
+ String skinId = search.getId();
+
+ Collection<SkinMetadata> skinMetadata = getSkinMetadata(context);
+
+ if (skinMetadata == null || skinMetadata.isEmpty())
+ return null;
+
+ // search is with either id or (family, renderkit, version)
+ // we have ensure that either id or family is passed in the search
+ if (skinId != null)
+ {
+ // Id is available then search using ID
+ for (SkinMetadata m : skinMetadata)
+ if (skinId.equals(m.getId()))
+ {
+ matchingSkinMetadata = m;
+ }
+
+ if (matchingSkinMetadata == null)
+ {
+ if (_LOG.isFine())
+ {
+ _LOG.fine("SP_CANNOT_FIND_MATCHING_SKIN_ID", new Object[]{skinId});
+ }
+ }
+ }
+ else
+ {
+ // search using family, renderkit, version
+ String family = search.getFamily();
+
+ // we need at least the family to go on with the search
+ if (family == null)
+ return null;
+
+ // renderkit id cannot be null, we initialize it to APACHE_TRINIDAD_DESKTOP
+ String renderKit = search.getRenderKitId();
+
+ // version cannot be null as we initialize it to SkinVersion.EMPTY_SKIN_VERSION
+ SkinVersion version = search.getVersion();
+
+ List<SkinMetadata> familyRenderKitMatches = new ArrayList<SkinMetadata>(2);
+
+ // search using family and renderkit id
+ for (SkinMetadata m : skinMetadata)
+ if (family.equalsIgnoreCase(m.getFamily()) &&
+ renderKit.equalsIgnoreCase(m.getRenderKitId()))
+ familyRenderKitMatches.add(m);
+
+ if (familyRenderKitMatches.isEmpty())
+ {
+ // if we get here, that means we couldn't find an exact
+ // family/renderKitId match, so return the simple skin
+ // that matches the renderKitId.
+ if (_LOG.isFine())
+ {
+ _LOG.fine("SP_CANNOT_FIND_MATCHING_SKIN", new Object[]{family, renderKit});
+ }
+
+ return null;
+ }
+
+ // at this point we know we have something in the familyRenderKitMatches
+ // which is a list of matching family and renderKitId skins. Now match the version
+ // to find the best matched skin.
+ String versionName = version.getName();
+ boolean versionIsDefault = version.isDefault();
+ boolean foundMatchingSkin = false;
+
+ // if the user didn't ask for the 'default' version, then look for the exact match
+ if (!versionIsDefault)
+ {
+ matchingSkinMetadata = _findSkinMetadataForVersionName(familyRenderKitMatches, version);
+ }
+
+ // matchingSkinMetadata will be null if an exact version match (family+renderKitId+version)
+ // was not found;
+ // or if user was asking for a default version
+ // we can have an exact version match if the user asks for null version,
+ // and we find a skin with no
+ // version set.
+ if (matchingSkinMetadata == null || versionIsDefault)
+ {
+ // at this point either user is looking for default skin
+ // or did not find the exact version match specified
+ // so we find the default skin
+ matchingSkinMetadata = _findSkinMetadataWithDefaultVersion(familyRenderKitMatches);
+
+ if (matchingSkinMetadata == null)
+ {
+ // if we fail to find a default skin then
+ // get the latest skin in the matchingSkinList if there is no skin marked default.
+ if (_LOG.isFine())
+ _LOG.fine(this + " did not find default / version skinMetadata. so getting leaf skin");
+
+ matchingSkinMetadata = _findLeafSkinMetadata(familyRenderKitMatches);
+ }
+ else if ((matchingSkinMetadata != null) && versionIsDefault)
+ {
+ // found the default skin the user wanted
+ if (_LOG.isFine())
+ _LOG.fine(this + " found default skinMetadata");
+
+ foundMatchingSkin = true;
+ }
+ }
+
+ // log messages
+ if (foundMatchingSkin)
+ {
+ if (_LOG.isFine())
+ _LOG.fine("GET_SKIN_FOUND_SKIN_VERSION",
+ new Object[]{family, version, matchingSkinMetadata.getId()});
+ }
+ else if (matchingSkinMetadata != null)
+ {
+ if (_LOG.isFine())
+ {
+ if ("".equals(versionName))
+ {
+ _LOG.fine("GET_SKIN_CANNOT_FIND_NO_VERSION",
+ new Object[]{family, matchingSkinMetadata.getId()});
+ }
+ else
+ {
+ _LOG.fine("GET_SKIN_CANNOT_FIND_SKIN_VERSION",
+ new Object[]{family, version, matchingSkinMetadata.getId()});
+ }
+ }
+ }
+
+ if (matchingSkinMetadata == null)
+ {
+ matchingSkinMetadata = familyRenderKitMatches.get(familyRenderKitMatches.size() - 1);
+ }
+ }
+
+
+ if (matchingSkinMetadata != null)
+ if (_LOG.isFine())
+ _LOG.fine(this + " found matching metadata: " + matchingSkinMetadata);
+
+ return matchingSkinMetadata;
+ }
+
+ /**
+ * find a skin with version passed
+ *
+ * @param skins
+ * @param version
+ * @return
+ */
+ private SkinMetadata _findSkinMetadataForVersionName(Collection<SkinMetadata> skins,
+ SkinVersion version)
+ {
+ if (version == null)
+ throw new IllegalArgumentException("skin version cannot be null");
+
+ if (version.getName() == null || version.getName().isEmpty())
+ return null;
+
+ for (SkinMetadata metadata : skins)
+ {
+ // metadata cannot be null and also version inside it cannot be null
+ if (version.getName().equals(metadata.getVersion().getName()))
+ {
+ if (_LOG.isFine())
+ _LOG.fine("Found version match skinMetadata: " + metadata);
+
+ return metadata;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Latest skin is the one which is last in the family hierarchy eg: fusion-v1 -> fusion-v2 ->
+ * fusion-v3 Among this fusion-v3 is the latest. So we look for a skin that is not extended by any
+ * other skin in the family.
+ *
+ * @param skins
+ * @return
+ */
+ private SkinMetadata _findLeafSkinMetadata(Collection<SkinMetadata> skins)
+ {
+ List<SkinMetadata> leafSkinMetadata = new ArrayList<SkinMetadata>();
+ List<String> parentIds = new ArrayList<String>();
+
+ // collect parents skins among the list
+ for (SkinMetadata metadata : skins)
+ {
+ String parentId = metadata.getBaseSkinId();
+ if (parentId != null)
+ parentIds.add(metadata.getBaseSkinId());
+ }
+
+ // find leaf skins, which is not in parent list
+ for (SkinMetadata metadata : skins)
+ {
+ String skinId = metadata.getId();
+ if (skinId != null && !parentIds.contains(skinId))
+ {
+ leafSkinMetadata.add(metadata);
+ }
+ }
+
+ // if there are no leaves, return null
+ // this is a rare case, almost impossible since there will be
+ // at least one skin which is not parent of another
+ // but let us cover the corner case if any
+ if (leafSkinMetadata.isEmpty())
+ return null;
+
+ // if there is one leaf skin return that
+ // if there are many, return the last one among the leaves
+ return leafSkinMetadata.get(leafSkinMetadata.size() - 1);
+ }
+
+ /**
+ * find a skin that has its SkinVersion set to 'default', if it exists.
+ *
+ * @param matchingSkinList A list of Skins that we will look through to find the 'default'.
+ * @return Skin with SkinVersion isDefault true, otherwise, null.
+ */
+ private SkinMetadata _findSkinMetadataWithDefaultVersion(
+ Collection<SkinMetadata> matchingSkinList)
+ {
+ for (SkinMetadata metadata : matchingSkinList)
+ {
+ SkinVersion skinVersion = metadata.getVersion();
+
+ if (skinVersion != null && skinVersion.isDefault())
+ {
+ if (_LOG.isFine())
+ _LOG.fine("Found default skinMetadata: " + metadata);
+
+ return metadata;
+ }
+ }
+
+ return null;
+ }
+
+ private Map<SkinMetadata, Skin> _skins;
+ private final static TrinidadLogger _LOG =
+ TrinidadLogger.createTrinidadLogger(BaseSkinProvider.class);
}
\ No newline at end of file
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/BaseSkinProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/SkinProviderRegistry.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/SkinProviderRegistry.java?rev=1632268&r1=1632267&r2=1632268&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/SkinProviderRegistry.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/SkinProviderRegistry.java Thu Oct 16 10:31:25 2014
@@ -1,547 +1,547 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.myfaces.trinidadinternal.skin.provider;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-
-import org.apache.myfaces.trinidad.logging.TrinidadLogger;
-import org.apache.myfaces.trinidad.skin.Skin;
-import org.apache.myfaces.trinidad.skin.SkinMetadata;
-import org.apache.myfaces.trinidad.skin.SkinProvider;
-import org.apache.myfaces.trinidad.skin.SkinVersion;
-import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
-import org.apache.myfaces.trinidadinternal.skin.SkinUtils;
-
-/**
- * Internal implementation of SkinProvider which is exposed using SkinProvider.getCurrentInstance()
- * This class collates all SkinProvider SPIs, Trinidad SkinProviders and SkinFactory to return the
- * best match for a Skin requested This class reads all registered SPIs using
- * org.apache.myfaces.trinidad.skin.SkinProvider
- * <p/>
- * Instance of this class is created and put into the ExternalContext during bootstrap in
- * GlobalConfiguratorImpl and retrieved in the static factory inside SkinProvider
- * <p/>
- */
-public class SkinProviderRegistry extends SkinProvider
-{
-
- public SkinProviderRegistry()
- {
- ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
- List<SkinProvider> services = ClassLoaderUtils.getServices(SkinProvider.class.getName());
-
- if (_LOG.isFine())
- _LOG.fine("Adding providers from registered SPIs... " + services.size());
-
- List<SkinProvider> providers = new ArrayList<SkinProvider>(services.size() + 2);
- providers.addAll(services);
-
- // add internal skin providers at the end
- // this is to give the other SPIs a chance before the internal skin providers
- if (_LOG.isFine())
- _LOG.fine("Adding TrinidadSkinProvider... ");
-
- providers.add(TrinidadSkinProvider.getCurrentInstance(externalContext));
-
- if (_LOG.isFine())
- _LOG.fine("Adding TrinidadBaseSkinProvider... ");
-
- // this provider serves static base skins, so we can create a new instance here
- providers.add(new TrinidadBaseSkinProvider());
-
- if (_LOG.isFine())
- _LOG.fine("Adding ExternalSkinProvider... ");
-
- providers.add(ExternalSkinProvider.getCurrentInstance(externalContext));
-
- _providers = Collections.unmodifiableList(providers);
- }
-
- @Override
- public Collection<SkinMetadata> getSkinMetadata(ExternalContext externalContext)
- {
- Collection<SkinMetadata> metadata = new ArrayList<SkinMetadata>();
-
- for (SkinProvider provider : _providers)
- metadata.addAll(provider.getSkinMetadata(externalContext));
-
- return Collections.unmodifiableCollection(metadata);
- }
-
- /**
- * @param externalContext
- * @param skinMetadata search criteria object containing the information of skin to be queried id,
- * family, renderKit, version are the information used from skin metadata to
- * perform search for the skin requested. Other fields do not participate in
- * the search.
- * @return matching skin for the search criteria passed, if none found, return the simple skin for
- * the renderKit in search criteria if renderKit not specified in search criteria, skinMetadata
- * automatically assumes it as SkinMetadata.RenderKitId.DESKTOP
- */
- @Override
- public Skin getSkin(ExternalContext externalContext, SkinMetadata skinMetadata)
- {
- _handleCircularDependency(skinMetadata);
-
- List<Skin> matchingSkins = new ArrayList<Skin>();
- Skin matchingSkin = null;
-
- if (_LOG.isFine())
- _LOG.fine("Skin request for metadata: " + skinMetadata);
-
- for (SkinProvider provider : _providers)
- {
- matchingSkin = provider.getSkin(externalContext, skinMetadata);
-
- if (matchingSkin != null)
- {
- // log which provider got skin etc
- if (_LOG.isFine())
- _LOG.fine("Skin obtained for metadata: " + skinMetadata + " from provider: " + provider);
-
- matchingSkins.add(matchingSkin);
- }
- }
-
- if (_LOG.isFine())
- _LOG.fine("Matches obtained for " + skinMetadata + ": " + matchingSkins.size());
-
- // now we are done with asking all skin providers
- // ensure that the matching skins returned are indeed matching the search criteria
- // onus is on SkinProviderRegistry to serve the skin requested, even if a SkinProvider
- // returns a wrong skin.
-
- // filter the results obtained from skin providers based on id, family and renderKit
- // filtering on version is more complicated and taken up subsequently
- matchingSkins = _filterSkins(matchingSkins, skinMetadata);
-
- if (matchingSkins.isEmpty())
- {
- if (_LOG.isFine())
- _LOG.fine("NO MATCH. Will return a simple skin or null for skin metadata: " + skinMetadata);
-
- assert (skinMetadata.getRenderKitId() != null);
-
- // if renderKit is available return the simple skin for that renderKit
- // skinMetadata.getRenderKitId() can never be null, default renderKit will always be DESKTOP
- matchingSkin = SkinUtils.getDefaultSkinForRenderKitId(this,
- externalContext,
- skinMetadata.getRenderKitId());
- _processSkinForReturn(skinMetadata, matchingSkin);
- return matchingSkin;
- }
-
-
- // we have at least one match now
- // if we have only one match
- // return that skin
- if (matchingSkins.size() == 1)
- {
- if (_LOG.isFine())
- _LOG.fine("returning ONLY match for skin metadata: " + skinMetadata);
-
-
- matchingSkin = matchingSkins.get(0);
- _processSkinForReturn(skinMetadata, matchingSkin);
- return matchingSkin;
- }
-
- // at this point we have more than one matches for the search criteria passed
- // so, extract the best match based on version
- return _versionFilter(skinMetadata, matchingSkins);
- }
-
- /**
- * exposing providers for testability
- * @return
- */
- List<SkinProvider> getProviders()
- {
- return _providers;
- }
-
- /**
- * ensure sanity in the list of matches received by filtering the skins based on id, family and
- * renderKit
- *
- * @param skins
- * @param metadata
- * @return
- */
- private List<Skin> _filterSkins(List<Skin> skins, SkinMetadata metadata)
- {
- if (skins == null || skins.isEmpty() || metadata == null)
- return Collections.emptyList();
-
- List<Skin> filterList = _idFilter(skins, metadata.getId());
-
- // if the id based filtering resulted in only match then return that
- // provided id was mentioned in search criteria
- if (filterList.size() == 1 && metadata.getId() != null)
- {
- return filterList;
- }
-
- // if more than one match for id or if id is not specified, then filter by family
- filterList = _familyFilter(filterList, metadata.getFamily());
-
- // if the family based filtering resulted in only match then return that
- // provided family was mentioned in search criteria
- if (filterList.size() == 1 && metadata.getFamily() != null)
- {
- return filterList;
- }
-
- // if family based filtering resulted in multiple matches, or if family and id are not
- // specified,
- // proceed with renderKit based filtering.
- filterList = _renderKitFilter(filterList, metadata.getRenderKitId());
-
- return filterList;
- }
-
- /**
- * filter based on skin id, if mentioned. Otherwise return the list as is
- *
- * @param skins
- * @param id
- * @return
- */
- private List<Skin> _idFilter(List<Skin> skins, String id)
- {
- if (id == null || id.isEmpty())
- return skins;
-
- List<Skin> filterList = new ArrayList<Skin>(skins.size());
-
- for (Skin skin : skins)
- if (id.equals(skin.getId()))
- filterList.add(skin);
-
- return filterList;
- }
-
- /**
- * filter based on skin family, if mentioned. Otherwise return the list as is
- *
- * @param skins
- * @param family
- * @return
- */
- private List<Skin> _familyFilter(List<Skin> skins, String family)
- {
- if (family == null || family.isEmpty())
- return skins;
-
- List<Skin> filterList = new ArrayList<Skin>(skins.size());
-
- for (Skin skin : skins)
- if (family.equalsIgnoreCase(skin.getFamily()))
- filterList.add(skin);
-
- return filterList;
- }
-
- /**
- * filter based on skin renderkit id, if mentioned. Otherwise return the list as is
- *
- * @param skins
- * @param renderKitId
- * @return
- */
- private List<Skin> _renderKitFilter(List<Skin> skins, String renderKitId)
- {
- if (renderKitId == null || renderKitId.isEmpty())
- return skins;
-
- List<Skin> filterList = new ArrayList<Skin>(skins.size());
-
- for (Skin skin : skins)
- if (renderKitId.equalsIgnoreCase(skin.getRenderKitId()))
- filterList.add(skin);
-
- return filterList;
- }
-
- /**
- * filter based on version if version is mentioned try to return exact match else if version is
- * not mentioned or version is default try to return default skin else try to return leaf skin
- * else return first match
- *
- * @param searchCriteria
- * @param matchingSkins
- * @return
- */
- private Skin _versionFilter(SkinMetadata searchCriteria,
- List<Skin> matchingSkins)
- {
- SkinVersion version = searchCriteria.getVersion();
- Skin matchingSkin;
- // we can now find the best match based on version
- // now that there is a version mentioned and skins matching is > 1
- // look for exact name match
- matchingSkin = _findSkinForVersionName(matchingSkins, version);
-
- // if we found exact match in version, return it.
- if (matchingSkin != null)
- {
- if (_LOG.isFine())
- _LOG.fine("returning exact version match.");
-
- _processSkinForReturn(searchCriteria, matchingSkin);
- return matchingSkin;
- }
-
- // either user is looking for default version or did not find the version requested
- // try to find a default skin
- matchingSkin = _findSkinWithDefaultVersion(matchingSkins);
-
- // if we found the default version skin, return it.
- if (matchingSkin != null)
- {
- if (_LOG.isFine())
- _LOG.fine("returning DEFAULT version match.");
- _processSkinForReturn(searchCriteria, matchingSkin);
- return matchingSkin;
- }
-
- // the version that user asked for is not available
- // so find leaf skin
- matchingSkin = _findLeafSkin(matchingSkins);
-
- // if we found a leaf skin return that
- if (matchingSkin != null)
- {
- if (_LOG.isFine())
- _LOG.fine("return LEAF skin or one of the matches.");
-
- _processSkinForReturn(searchCriteria, matchingSkin);
- return matchingSkin;
- }
-
- // we failed to find any better result for the given version, so return first match
- if (_LOG.isFine())
- _LOG.fine("nothing worked so return first match.");
-
- matchingSkin = matchingSkins.get(0);
- _processSkinForReturn(searchCriteria, matchingSkins.get(0));
- return matchingSkin;
- }
-
- /**
- * This method processes a skin that is being returned from the provider.
- * 1. remove the skin from the context tracking
- * 2. add any missing skin additions to the skin
- * @param skinMetadata
- * @return
- */
- private void _processSkinForReturn(SkinMetadata skinMetadata,
- Skin skin)
- {
- FacesContext context = FacesContext.getCurrentInstance();
- _clearReturningSkinContext(context, skinMetadata);
-
- // before returning the skin, ensure that all skin additions defined in trinidad-skins.xml
- // are added.
- TrinidadSkinProvider.getCurrentInstance(context.getExternalContext()).ensureSkinAdditions(skin);
- }
-
- /**
- * We track the skin being requested to build the hierarchy so that we can identify circular
- * dependencies. This method clears the information for the present Skin that is being returned.
- * @param context
- * @param skinMetadata
- */
- private void _clearReturningSkinContext(FacesContext context, SkinMetadata skinMetadata)
- {
- Map attrMap = context.getAttributes();
- Object o = attrMap.get(_SKIN_PROVIDER_CONTEXT);
- List<SkinMetadata> requesters;
-
- if (o != null)
- {
- requesters = (List) o;
- // remove the skinMetadata
- requesters.remove(skinMetadata);
-
- if (_LOG.isFiner())
- {
- _LOG.finer("Removing " + skinMetadata + " from context");
- _LOG.finer("Context now is " + requesters);
- }
- }
- }
-
- /**
- * find a skin with version passed
- *
- * @param skins
- * @param version
- * @return
- */
- private Skin _findSkinForVersionName(Collection<Skin> skins, SkinVersion version)
- {
- if (version == null)
- throw new IllegalArgumentException("skin version cannot be null");
-
- if (version.getName() == null || version.getName().isEmpty())
- return null;
-
- for (Skin skin : skins)
- {
- // metadata cannot be null and also version inside it cannot be null
- if (version.getName().equals(skin.getVersion().getName()))
- {
- if (_LOG.isFine())
- _LOG.fine("Found version match skin: " + skin);
-
- return skin;
- }
- }
-
- return null;
- }
-
- /**
- * Latest skin is the one which is last in the family hierarchy eg: fusion-v1 -> fusion-v2 ->
- * fusion-v3 Among this fusion-v3 is the latest. So we look for a skin that is not extended by any
- * other skin in the family.
- *
- * @param skins
- * @return
- */
- private Skin _findLeafSkin(Collection<Skin> skins)
- {
- List<Skin> leafSkins = new ArrayList<Skin>();
- List<String> parentIds = new ArrayList<String>();
-
- // collect parents skins among the list
- for (Skin metadata : skins)
- {
- Skin baseSkin = metadata.getBaseSkin();
- if (baseSkin != null)
- {
- String parentId = baseSkin.getId();
- if (parentId != null)
- parentIds.add(parentId);
- }
- }
-
- // find leaf skins, which is not in parent list
- for (Skin skin : skins)
- {
- String skinId = skin.getId();
- if (skinId != null && !parentIds.contains(skinId))
- {
- leafSkins.add(skin);
- }
- }
-
- // if there are no leaves, return null
- // this is a rare case, almost impossible since there will be
- // at least one skin which is not parent of another
- // but let us cover the corner case if any
- if (leafSkins.isEmpty())
- return null;
-
- // if there is one leaf skin return that
- // if there are many, return the last one among the leaves
- return leafSkins.get(leafSkins.size() - 1);
- }
-
- /**
- * find a skin that has its SkinVersion set to 'default', if it exists.
- *
- * @param matchingSkinList A list of Skins that we will look through to find the 'default'.
- * @return Skin with SkinVersion isDefault true, otherwise, null.
- */
- private Skin _findSkinWithDefaultVersion(Collection<Skin> matchingSkinList)
- {
- for (Skin skin : matchingSkinList)
- {
- SkinVersion skinVersion = skin.getVersion();
-
- if (skinVersion != null && skinVersion.isDefault())
- {
- if (_LOG.isFine())
- _LOG.fine("Found default skin: " + skin);
-
- return skin;
- }
- }
-
- return null;
- }
-
- /**
- * We track the skin being requested to build the hierarchy so that we can identify circular
- * dependencies. This method adds the currently requested skin into the context. If a skin is
- * re-requested, then an exception will be thrown
- * @param skinMetadata
- * @throws IllegalStateException if a circular dependency is detected
- */
- private void _handleCircularDependency(SkinMetadata skinMetadata)
- {
- FacesContext context = FacesContext.getCurrentInstance();
- Map attrMap = context.getAttributes();
- Object o = attrMap.get(_SKIN_PROVIDER_CONTEXT);
- List<SkinMetadata> requesters = null;
-
- if (o == null)
- {
- requesters = new ArrayList<SkinMetadata>();
- attrMap.put(_SKIN_PROVIDER_CONTEXT, requesters);
- }
- else
- requesters = (List) o;
-
- if (requesters.contains(skinMetadata))
- {
- String message = "Circular dependency detected while loading skin: " + skinMetadata
- + ". Requesters are: " + requesters;
- if (_LOG.isSevere())
- _LOG.severe(message);
-
- throw new IllegalStateException(message);
- }
-
- // add the currently requested metadata into list
- requesters.add(skinMetadata);
-
- if (_LOG.isFiner())
- {
- _LOG.finer("Adding " + skinMetadata + " to context");
- _LOG.finer("Context now is " + requesters);
- }
- }
-
- private final List<SkinProvider> _providers;
-
- private static final String _SKIN_PROVIDER_CONTEXT =
- "org.apache.myfaces.trinidadinternal.skin.provider.SkinProviderRegistry.Context";
- private static final TrinidadLogger _LOG =
- TrinidadLogger.createTrinidadLogger(SkinProviderRegistry.class);
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.trinidadinternal.skin.provider;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidad.skin.SkinMetadata;
+import org.apache.myfaces.trinidad.skin.SkinProvider;
+import org.apache.myfaces.trinidad.skin.SkinVersion;
+import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
+import org.apache.myfaces.trinidadinternal.skin.SkinUtils;
+
+/**
+ * Internal implementation of SkinProvider which is exposed using SkinProvider.getCurrentInstance()
+ * This class collates all SkinProvider SPIs, Trinidad SkinProviders and SkinFactory to return the
+ * best match for a Skin requested This class reads all registered SPIs using
+ * org.apache.myfaces.trinidad.skin.SkinProvider
+ * <p/>
+ * Instance of this class is created and put into the ExternalContext during bootstrap in
+ * GlobalConfiguratorImpl and retrieved in the static factory inside SkinProvider
+ * <p/>
+ */
+public class SkinProviderRegistry extends SkinProvider
+{
+
+ public SkinProviderRegistry()
+ {
+ ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
+ List<SkinProvider> services = ClassLoaderUtils.getServices(SkinProvider.class.getName());
+
+ if (_LOG.isFine())
+ _LOG.fine("Adding providers from registered SPIs... " + services.size());
+
+ List<SkinProvider> providers = new ArrayList<SkinProvider>(services.size() + 2);
+ providers.addAll(services);
+
+ // add internal skin providers at the end
+ // this is to give the other SPIs a chance before the internal skin providers
+ if (_LOG.isFine())
+ _LOG.fine("Adding TrinidadSkinProvider... ");
+
+ providers.add(TrinidadSkinProvider.getCurrentInstance(externalContext));
+
+ if (_LOG.isFine())
+ _LOG.fine("Adding TrinidadBaseSkinProvider... ");
+
+ // this provider serves static base skins, so we can create a new instance here
+ providers.add(new TrinidadBaseSkinProvider());
+
+ if (_LOG.isFine())
+ _LOG.fine("Adding ExternalSkinProvider... ");
+
+ providers.add(ExternalSkinProvider.getCurrentInstance(externalContext));
+
+ _providers = Collections.unmodifiableList(providers);
+ }
+
+ @Override
+ public Collection<SkinMetadata> getSkinMetadata(ExternalContext externalContext)
+ {
+ Collection<SkinMetadata> metadata = new ArrayList<SkinMetadata>();
+
+ for (SkinProvider provider : _providers)
+ metadata.addAll(provider.getSkinMetadata(externalContext));
+
+ return Collections.unmodifiableCollection(metadata);
+ }
+
+ /**
+ * @param externalContext
+ * @param skinMetadata search criteria object containing the information of skin to be queried id,
+ * family, renderKit, version are the information used from skin metadata to
+ * perform search for the skin requested. Other fields do not participate in
+ * the search.
+ * @return matching skin for the search criteria passed, if none found, return the simple skin for
+ * the renderKit in search criteria if renderKit not specified in search criteria, skinMetadata
+ * automatically assumes it as SkinMetadata.RenderKitId.DESKTOP
+ */
+ @Override
+ public Skin getSkin(ExternalContext externalContext, SkinMetadata skinMetadata)
+ {
+ _handleCircularDependency(skinMetadata);
+
+ List<Skin> matchingSkins = new ArrayList<Skin>();
+ Skin matchingSkin = null;
+
+ if (_LOG.isFine())
+ _LOG.fine("Skin request for metadata: " + skinMetadata);
+
+ for (SkinProvider provider : _providers)
+ {
+ matchingSkin = provider.getSkin(externalContext, skinMetadata);
+
+ if (matchingSkin != null)
+ {
+ // log which provider got skin etc
+ if (_LOG.isFine())
+ _LOG.fine("Skin obtained for metadata: " + skinMetadata + " from provider: " + provider);
+
+ matchingSkins.add(matchingSkin);
+ }
+ }
+
+ if (_LOG.isFine())
+ _LOG.fine("Matches obtained for " + skinMetadata + ": " + matchingSkins.size());
+
+ // now we are done with asking all skin providers
+ // ensure that the matching skins returned are indeed matching the search criteria
+ // onus is on SkinProviderRegistry to serve the skin requested, even if a SkinProvider
+ // returns a wrong skin.
+
+ // filter the results obtained from skin providers based on id, family and renderKit
+ // filtering on version is more complicated and taken up subsequently
+ matchingSkins = _filterSkins(matchingSkins, skinMetadata);
+
+ if (matchingSkins.isEmpty())
+ {
+ if (_LOG.isFine())
+ _LOG.fine("NO MATCH. Will return a simple skin or null for skin metadata: " + skinMetadata);
+
+ assert (skinMetadata.getRenderKitId() != null);
+
+ // if renderKit is available return the simple skin for that renderKit
+ // skinMetadata.getRenderKitId() can never be null, default renderKit will always be DESKTOP
+ matchingSkin = SkinUtils.getDefaultSkinForRenderKitId(this,
+ externalContext,
+ skinMetadata.getRenderKitId());
+ _processSkinForReturn(skinMetadata, matchingSkin);
+ return matchingSkin;
+ }
+
+
+ // we have at least one match now
+ // if we have only one match
+ // return that skin
+ if (matchingSkins.size() == 1)
+ {
+ if (_LOG.isFine())
+ _LOG.fine("returning ONLY match for skin metadata: " + skinMetadata);
+
+
+ matchingSkin = matchingSkins.get(0);
+ _processSkinForReturn(skinMetadata, matchingSkin);
+ return matchingSkin;
+ }
+
+ // at this point we have more than one matches for the search criteria passed
+ // so, extract the best match based on version
+ return _versionFilter(skinMetadata, matchingSkins);
+ }
+
+ /**
+ * exposing providers for testability
+ * @return
+ */
+ List<SkinProvider> getProviders()
+ {
+ return _providers;
+ }
+
+ /**
+ * ensure sanity in the list of matches received by filtering the skins based on id, family and
+ * renderKit
+ *
+ * @param skins
+ * @param metadata
+ * @return
+ */
+ private List<Skin> _filterSkins(List<Skin> skins, SkinMetadata metadata)
+ {
+ if (skins == null || skins.isEmpty() || metadata == null)
+ return Collections.emptyList();
+
+ List<Skin> filterList = _idFilter(skins, metadata.getId());
+
+ // if the id based filtering resulted in only match then return that
+ // provided id was mentioned in search criteria
+ if (filterList.size() == 1 && metadata.getId() != null)
+ {
+ return filterList;
+ }
+
+ // if more than one match for id or if id is not specified, then filter by family
+ filterList = _familyFilter(filterList, metadata.getFamily());
+
+ // if the family based filtering resulted in only match then return that
+ // provided family was mentioned in search criteria
+ if (filterList.size() == 1 && metadata.getFamily() != null)
+ {
+ return filterList;
+ }
+
+ // if family based filtering resulted in multiple matches, or if family and id are not
+ // specified,
+ // proceed with renderKit based filtering.
+ filterList = _renderKitFilter(filterList, metadata.getRenderKitId());
+
+ return filterList;
+ }
+
+ /**
+ * filter based on skin id, if mentioned. Otherwise return the list as is
+ *
+ * @param skins
+ * @param id
+ * @return
+ */
+ private List<Skin> _idFilter(List<Skin> skins, String id)
+ {
+ if (id == null || id.isEmpty())
+ return skins;
+
+ List<Skin> filterList = new ArrayList<Skin>(skins.size());
+
+ for (Skin skin : skins)
+ if (id.equals(skin.getId()))
+ filterList.add(skin);
+
+ return filterList;
+ }
+
+ /**
+ * filter based on skin family, if mentioned. Otherwise return the list as is
+ *
+ * @param skins
+ * @param family
+ * @return
+ */
+ private List<Skin> _familyFilter(List<Skin> skins, String family)
+ {
+ if (family == null || family.isEmpty())
+ return skins;
+
+ List<Skin> filterList = new ArrayList<Skin>(skins.size());
+
+ for (Skin skin : skins)
+ if (family.equalsIgnoreCase(skin.getFamily()))
+ filterList.add(skin);
+
+ return filterList;
+ }
+
+ /**
+ * filter based on skin renderkit id, if mentioned. Otherwise return the list as is
+ *
+ * @param skins
+ * @param renderKitId
+ * @return
+ */
+ private List<Skin> _renderKitFilter(List<Skin> skins, String renderKitId)
+ {
+ if (renderKitId == null || renderKitId.isEmpty())
+ return skins;
+
+ List<Skin> filterList = new ArrayList<Skin>(skins.size());
+
+ for (Skin skin : skins)
+ if (renderKitId.equalsIgnoreCase(skin.getRenderKitId()))
+ filterList.add(skin);
+
+ return filterList;
+ }
+
+ /**
+ * filter based on version if version is mentioned try to return exact match else if version is
+ * not mentioned or version is default try to return default skin else try to return leaf skin
+ * else return first match
+ *
+ * @param searchCriteria
+ * @param matchingSkins
+ * @return
+ */
+ private Skin _versionFilter(SkinMetadata searchCriteria,
+ List<Skin> matchingSkins)
+ {
+ SkinVersion version = searchCriteria.getVersion();
+ Skin matchingSkin;
+ // we can now find the best match based on version
+ // now that there is a version mentioned and skins matching is > 1
+ // look for exact name match
+ matchingSkin = _findSkinForVersionName(matchingSkins, version);
+
+ // if we found exact match in version, return it.
+ if (matchingSkin != null)
+ {
+ if (_LOG.isFine())
+ _LOG.fine("returning exact version match.");
+
+ _processSkinForReturn(searchCriteria, matchingSkin);
+ return matchingSkin;
+ }
+
+ // either user is looking for default version or did not find the version requested
+ // try to find a default skin
+ matchingSkin = _findSkinWithDefaultVersion(matchingSkins);
+
+ // if we found the default version skin, return it.
+ if (matchingSkin != null)
+ {
+ if (_LOG.isFine())
+ _LOG.fine("returning DEFAULT version match.");
+ _processSkinForReturn(searchCriteria, matchingSkin);
+ return matchingSkin;
+ }
+
+ // the version that user asked for is not available
+ // so find leaf skin
+ matchingSkin = _findLeafSkin(matchingSkins);
+
+ // if we found a leaf skin return that
+ if (matchingSkin != null)
+ {
+ if (_LOG.isFine())
+ _LOG.fine("return LEAF skin or one of the matches.");
+
+ _processSkinForReturn(searchCriteria, matchingSkin);
+ return matchingSkin;
+ }
+
+ // we failed to find any better result for the given version, so return first match
+ if (_LOG.isFine())
+ _LOG.fine("nothing worked so return first match.");
+
+ matchingSkin = matchingSkins.get(0);
+ _processSkinForReturn(searchCriteria, matchingSkins.get(0));
+ return matchingSkin;
+ }
+
+ /**
+ * This method processes a skin that is being returned from the provider.
+ * 1. remove the skin from the context tracking
+ * 2. add any missing skin additions to the skin
+ * @param skinMetadata
+ * @return
+ */
+ private void _processSkinForReturn(SkinMetadata skinMetadata,
+ Skin skin)
+ {
+ FacesContext context = FacesContext.getCurrentInstance();
+ _clearReturningSkinContext(context, skinMetadata);
+
+ // before returning the skin, ensure that all skin additions defined in trinidad-skins.xml
+ // are added.
+ TrinidadSkinProvider.getCurrentInstance(context.getExternalContext()).ensureSkinAdditions(skin);
+ }
+
+ /**
+ * We track the skin being requested to build the hierarchy so that we can identify circular
+ * dependencies. This method clears the information for the present Skin that is being returned.
+ * @param context
+ * @param skinMetadata
+ */
+ private void _clearReturningSkinContext(FacesContext context, SkinMetadata skinMetadata)
+ {
+ Map attrMap = context.getAttributes();
+ Object o = attrMap.get(_SKIN_PROVIDER_CONTEXT);
+ List<SkinMetadata> requesters;
+
+ if (o != null)
+ {
+ requesters = (List) o;
+ // remove the skinMetadata
+ requesters.remove(skinMetadata);
+
+ if (_LOG.isFiner())
+ {
+ _LOG.finer("Removing " + skinMetadata + " from context");
+ _LOG.finer("Context now is " + requesters);
+ }
+ }
+ }
+
+ /**
+ * find a skin with version passed
+ *
+ * @param skins
+ * @param version
+ * @return
+ */
+ private Skin _findSkinForVersionName(Collection<Skin> skins, SkinVersion version)
+ {
+ if (version == null)
+ throw new IllegalArgumentException("skin version cannot be null");
+
+ if (version.getName() == null || version.getName().isEmpty())
+ return null;
+
+ for (Skin skin : skins)
+ {
+ // metadata cannot be null and also version inside it cannot be null
+ if (version.getName().equals(skin.getVersion().getName()))
+ {
+ if (_LOG.isFine())
+ _LOG.fine("Found version match skin: " + skin);
+
+ return skin;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Latest skin is the one which is last in the family hierarchy eg: fusion-v1 -> fusion-v2 ->
+ * fusion-v3 Among this fusion-v3 is the latest. So we look for a skin that is not extended by any
+ * other skin in the family.
+ *
+ * @param skins
+ * @return
+ */
+ private Skin _findLeafSkin(Collection<Skin> skins)
+ {
+ List<Skin> leafSkins = new ArrayList<Skin>();
+ List<String> parentIds = new ArrayList<String>();
+
+ // collect parents skins among the list
+ for (Skin metadata : skins)
+ {
+ Skin baseSkin = metadata.getBaseSkin();
+ if (baseSkin != null)
+ {
+ String parentId = baseSkin.getId();
+ if (parentId != null)
+ parentIds.add(parentId);
+ }
+ }
+
+ // find leaf skins, which is not in parent list
+ for (Skin skin : skins)
+ {
+ String skinId = skin.getId();
+ if (skinId != null && !parentIds.contains(skinId))
+ {
+ leafSkins.add(skin);
+ }
+ }
+
+ // if there are no leaves, return null
+ // this is a rare case, almost impossible since there will be
+ // at least one skin which is not parent of another
+ // but let us cover the corner case if any
+ if (leafSkins.isEmpty())
+ return null;
+
+ // if there is one leaf skin return that
+ // if there are many, return the last one among the leaves
+ return leafSkins.get(leafSkins.size() - 1);
+ }
+
+ /**
+ * find a skin that has its SkinVersion set to 'default', if it exists.
+ *
+ * @param matchingSkinList A list of Skins that we will look through to find the 'default'.
+ * @return Skin with SkinVersion isDefault true, otherwise, null.
+ */
+ private Skin _findSkinWithDefaultVersion(Collection<Skin> matchingSkinList)
+ {
+ for (Skin skin : matchingSkinList)
+ {
+ SkinVersion skinVersion = skin.getVersion();
+
+ if (skinVersion != null && skinVersion.isDefault())
+ {
+ if (_LOG.isFine())
+ _LOG.fine("Found default skin: " + skin);
+
+ return skin;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * We track the skin being requested to build the hierarchy so that we can identify circular
+ * dependencies. This method adds the currently requested skin into the context. If a skin is
+ * re-requested, then an exception will be thrown
+ * @param skinMetadata
+ * @throws IllegalStateException if a circular dependency is detected
+ */
+ private void _handleCircularDependency(SkinMetadata skinMetadata)
+ {
+ FacesContext context = FacesContext.getCurrentInstance();
+ Map attrMap = context.getAttributes();
+ Object o = attrMap.get(_SKIN_PROVIDER_CONTEXT);
+ List<SkinMetadata> requesters = null;
+
+ if (o == null)
+ {
+ requesters = new ArrayList<SkinMetadata>();
+ attrMap.put(_SKIN_PROVIDER_CONTEXT, requesters);
+ }
+ else
+ requesters = (List) o;
+
+ if (requesters.contains(skinMetadata))
+ {
+ String message = "Circular dependency detected while loading skin: " + skinMetadata
+ + ". Requesters are: " + requesters;
+ if (_LOG.isSevere())
+ _LOG.severe(message);
+
+ throw new IllegalStateException(message);
+ }
+
+ // add the currently requested metadata into list
+ requesters.add(skinMetadata);
+
+ if (_LOG.isFiner())
+ {
+ _LOG.finer("Adding " + skinMetadata + " to context");
+ _LOG.finer("Context now is " + requesters);
+ }
+ }
+
+ private final List<SkinProvider> _providers;
+
+ private static final String _SKIN_PROVIDER_CONTEXT =
+ "org.apache.myfaces.trinidadinternal.skin.provider.SkinProviderRegistry.Context";
+ private static final TrinidadLogger _LOG =
+ TrinidadLogger.createTrinidadLogger(SkinProviderRegistry.class);
}
\ No newline at end of file
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/SkinProviderRegistry.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadSkinProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadSkinProvider.java?rev=1632268&r1=1632267&r2=1632268&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadSkinProvider.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadSkinProvider.java Thu Oct 16 10:31:25 2014
@@ -1,217 +1,217 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.myfaces.trinidadinternal.skin.provider;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import javax.faces.context.ExternalContext;
-
-import org.apache.myfaces.trinidad.logging.TrinidadLogger;
-import org.apache.myfaces.trinidad.skin.Skin;
-import org.apache.myfaces.trinidad.skin.SkinAddition;
-import org.apache.myfaces.trinidad.skin.SkinMetadata;
-import org.apache.myfaces.trinidad.skin.SkinProvider;
-import org.apache.myfaces.trinidadinternal.skin.SkinExtension;
-import org.apache.myfaces.trinidadinternal.skin.SkinUtils;
-import org.apache.myfaces.trinidadinternal.skin.parse.SkinsNode;
-
-/**
- * This is the Trinidad's SkinProvider for loading skins from trinidad-skins.xml. This provider
- * reads and caches trinidad-skins.xml from various sources like META-INF, WEB-INF and
- * SkinResourceLoader API during its initialization. Subsequently the Skin objects are created
- * lazily using the cached metadata, only when it is first requested for.
- */
-public final class TrinidadSkinProvider extends BaseSkinProvider
-{
- /**
- * Key for the TrinidadSkinProvider stored in ExternalContext
- */
- public static final String TRINDIAD_SKIN_PROVIDER_KEY =
- "org.apache.myfaces.trinidad.skin.TRINIDAD_SKIN_PROVIDER_INSTANCE";
-
- /**
- * static factory method to get hold of a TrinidadSkinProvider object This can be used for easy
- * creation of Skin object without having to implement the abstract class
- *
- * @param ec
- * @return
- */
- public static TrinidadSkinProvider getCurrentInstance(ExternalContext ec)
- {
- if (ec == null)
- throw new NullPointerException("ExternalContext is passed as null");
-
- TrinidadSkinProvider trinidadSkinProvider =
- (TrinidadSkinProvider) ec.getApplicationMap().get(TRINDIAD_SKIN_PROVIDER_KEY);
- return trinidadSkinProvider;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Collection<SkinMetadata> getSkinMetadata(ExternalContext context)
- {
- initialize(context);
- return _skinMetadata;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected Skin loadAvailableSkin(ExternalContext context, SkinMetadata skinMetadata)
- {
- SkinMetadata matchingNode = null;
-
- for (SkinMetadata node : _skinMetadata)
- {
- if (skinMetadata.getId().equals(node.getId()))
- {
- matchingNode = node;
- break;
- }
- }
-
- if (matchingNode == null)
- {
- // This cannot happen because base class checks for availability before it calls for the
- // skin to be loaded
- String message = _LOG.getMessage("SP_LOADING_UNKNOWN_SKIN", skinMetadata.getId());
- _LOG.severe(message);
- throw new IllegalArgumentException(message);
- }
-
- String id = matchingNode.getId();
- String family = matchingNode.getFamily();
- String renderKitId = matchingNode.getRenderKitId();
- Skin baseSkin = null;
- String baseSkinId = matchingNode.getBaseSkinId();
- SkinProvider provider = SkinProvider.getCurrentInstance(context);
-
- if (provider != null && baseSkinId != null)
- baseSkin = provider.getSkin(context, new SkinMetadata.Builder().id(baseSkinId).build());
-
- // if there is no base skin then use the default base skin for the renderKit
- if (baseSkin == null)
- {
- baseSkin = SkinUtils.getDefaultSkinForRenderKitId(provider, context, renderKitId);
- }
-
- if (id == null)
- throw new NullPointerException(_LOG.getMessage("NULL_SKIN_ID"));
-
- if (family == null)
- throw new NullPointerException("Null family");
-
- _LOG.fine("Creating skin extension for skin metadata {0}", skinMetadata);
- return new SkinExtension(baseSkin, matchingNode, true);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void initialize(ExternalContext extCtxt)
- {
- if (extCtxt == null)
- {
- throw new NullPointerException("ExternalContext is passed as null");
- }
-
- if (_skinMetadata == null)
- {
- if (_LOG.isFine())
- _LOG.fine("init provider.");
-
- // only now do initialization
- List<SkinsNode> skinsNodes = SkinUtils.buildSkinsNodes(extCtxt);
- List<SkinMetadata> skinNodes = new ArrayList<SkinMetadata>();
- List<SkinAddition> skinAdditionNodes = new ArrayList<SkinAddition>();
-
- for (SkinsNode node : skinsNodes)
- {
- if (node != null)
- {
- skinNodes.addAll(node.getSkinNodes());
- skinAdditionNodes.addAll(node.getSkinAdditionNodes());
- }
- }
-
- if (skinNodes.isEmpty())
- _skinMetadata = Collections.emptyList();
- else
- _skinMetadata = Collections.unmodifiableList(skinNodes);
-
- if (skinAdditionNodes.isEmpty())
- _skinAdditionNodes = Collections.emptyList();
- else
- _skinAdditionNodes = Collections.unmodifiableList(skinAdditionNodes);
-
- if (_LOG.isFine())
- {
- _LOG.fine("Number of skin metadata loaded from trinidad-skins.xml: {0}", _skinMetadata.size());
- _LOG.fine("Number of skin additions loaded from trinidad-skins.xml: {0}", _skinAdditionNodes.size());
- }
- }
- }
-
- /**
- * used to ensure that the skin and its base skin additions are added correctly
- * This is called at the exit point of SkinProviderRegistry
- * @param skin
- */
- void ensureSkinAdditions(Skin skin)
- {
- if (_skinAdditionNodes == null || _skinAdditionNodes.isEmpty())
- return;
-
- for (SkinAddition addition : _skinAdditionNodes)
- {
- // skin additions in _skinAdditionNodes will not be null
- _checkAndAddInHierarchy(skin, addition);
- }
- }
-
- private void _checkAndAddInHierarchy(Skin skin, SkinAddition addition)
- {
- // exit condition for the recursive call
- if (skin == null)
- return;
-
- String skinId = addition.getSkinId();
-
- if (skinId != null && skinId.equals(skin.getId()))
- {
- skin.addSkinAddition(addition);
- }
-
- _checkAndAddInHierarchy(skin.getBaseSkin(), addition);
- }
-
- private List<SkinMetadata> _skinMetadata;
- private List<SkinAddition> _skinAdditionNodes;
-
- private final static TrinidadLogger _LOG =
- TrinidadLogger.createTrinidadLogger(TrinidadSkinProvider.class);
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.trinidadinternal.skin.provider;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.faces.context.ExternalContext;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidad.skin.SkinAddition;
+import org.apache.myfaces.trinidad.skin.SkinMetadata;
+import org.apache.myfaces.trinidad.skin.SkinProvider;
+import org.apache.myfaces.trinidadinternal.skin.SkinExtension;
+import org.apache.myfaces.trinidadinternal.skin.SkinUtils;
+import org.apache.myfaces.trinidadinternal.skin.parse.SkinsNode;
+
+/**
+ * This is the Trinidad's SkinProvider for loading skins from trinidad-skins.xml. This provider
+ * reads and caches trinidad-skins.xml from various sources like META-INF, WEB-INF and
+ * SkinResourceLoader API during its initialization. Subsequently the Skin objects are created
+ * lazily using the cached metadata, only when it is first requested for.
+ */
+public final class TrinidadSkinProvider extends BaseSkinProvider
+{
+ /**
+ * Key for the TrinidadSkinProvider stored in ExternalContext
+ */
+ public static final String TRINDIAD_SKIN_PROVIDER_KEY =
+ "org.apache.myfaces.trinidad.skin.TRINIDAD_SKIN_PROVIDER_INSTANCE";
+
+ /**
+ * static factory method to get hold of a TrinidadSkinProvider object This can be used for easy
+ * creation of Skin object without having to implement the abstract class
+ *
+ * @param ec
+ * @return
+ */
+ public static TrinidadSkinProvider getCurrentInstance(ExternalContext ec)
+ {
+ if (ec == null)
+ throw new NullPointerException("ExternalContext is passed as null");
+
+ TrinidadSkinProvider trinidadSkinProvider =
+ (TrinidadSkinProvider) ec.getApplicationMap().get(TRINDIAD_SKIN_PROVIDER_KEY);
+ return trinidadSkinProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<SkinMetadata> getSkinMetadata(ExternalContext context)
+ {
+ initialize(context);
+ return _skinMetadata;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Skin loadAvailableSkin(ExternalContext context, SkinMetadata skinMetadata)
+ {
+ SkinMetadata matchingNode = null;
+
+ for (SkinMetadata node : _skinMetadata)
+ {
+ if (skinMetadata.getId().equals(node.getId()))
+ {
+ matchingNode = node;
+ break;
+ }
+ }
+
+ if (matchingNode == null)
+ {
+ // This cannot happen because base class checks for availability before it calls for the
+ // skin to be loaded
+ String message = _LOG.getMessage("SP_LOADING_UNKNOWN_SKIN", skinMetadata.getId());
+ _LOG.severe(message);
+ throw new IllegalArgumentException(message);
+ }
+
+ String id = matchingNode.getId();
+ String family = matchingNode.getFamily();
+ String renderKitId = matchingNode.getRenderKitId();
+ Skin baseSkin = null;
+ String baseSkinId = matchingNode.getBaseSkinId();
+ SkinProvider provider = SkinProvider.getCurrentInstance(context);
+
+ if (provider != null && baseSkinId != null)
+ baseSkin = provider.getSkin(context, new SkinMetadata.Builder().id(baseSkinId).build());
+
+ // if there is no base skin then use the default base skin for the renderKit
+ if (baseSkin == null)
+ {
+ baseSkin = SkinUtils.getDefaultSkinForRenderKitId(provider, context, renderKitId);
+ }
+
+ if (id == null)
+ throw new NullPointerException(_LOG.getMessage("NULL_SKIN_ID"));
+
+ if (family == null)
+ throw new NullPointerException("Null family");
+
+ _LOG.fine("Creating skin extension for skin metadata {0}", skinMetadata);
+ return new SkinExtension(baseSkin, matchingNode, true);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void initialize(ExternalContext extCtxt)
+ {
+ if (extCtxt == null)
+ {
+ throw new NullPointerException("ExternalContext is passed as null");
+ }
+
+ if (_skinMetadata == null)
+ {
+ if (_LOG.isFine())
+ _LOG.fine("init provider.");
+
+ // only now do initialization
+ List<SkinsNode> skinsNodes = SkinUtils.buildSkinsNodes(extCtxt);
+ List<SkinMetadata> skinNodes = new ArrayList<SkinMetadata>();
+ List<SkinAddition> skinAdditionNodes = new ArrayList<SkinAddition>();
+
+ for (SkinsNode node : skinsNodes)
+ {
+ if (node != null)
+ {
+ skinNodes.addAll(node.getSkinNodes());
+ skinAdditionNodes.addAll(node.getSkinAdditionNodes());
+ }
+ }
+
+ if (skinNodes.isEmpty())
+ _skinMetadata = Collections.emptyList();
+ else
+ _skinMetadata = Collections.unmodifiableList(skinNodes);
+
+ if (skinAdditionNodes.isEmpty())
+ _skinAdditionNodes = Collections.emptyList();
+ else
+ _skinAdditionNodes = Collections.unmodifiableList(skinAdditionNodes);
+
+ if (_LOG.isFine())
+ {
+ _LOG.fine("Number of skin metadata loaded from trinidad-skins.xml: {0}", _skinMetadata.size());
+ _LOG.fine("Number of skin additions loaded from trinidad-skins.xml: {0}", _skinAdditionNodes.size());
+ }
+ }
+ }
+
+ /**
+ * used to ensure that the skin and its base skin additions are added correctly
+ * This is called at the exit point of SkinProviderRegistry
+ * @param skin
+ */
+ void ensureSkinAdditions(Skin skin)
+ {
+ if (_skinAdditionNodes == null || _skinAdditionNodes.isEmpty())
+ return;
+
+ for (SkinAddition addition : _skinAdditionNodes)
+ {
+ // skin additions in _skinAdditionNodes will not be null
+ _checkAndAddInHierarchy(skin, addition);
+ }
+ }
+
+ private void _checkAndAddInHierarchy(Skin skin, SkinAddition addition)
+ {
+ // exit condition for the recursive call
+ if (skin == null)
+ return;
+
+ String skinId = addition.getSkinId();
+
+ if (skinId != null && skinId.equals(skin.getId()))
+ {
+ skin.addSkinAddition(addition);
+ }
+
+ _checkAndAddInHierarchy(skin.getBaseSkin(), addition);
+ }
+
+ private List<SkinMetadata> _skinMetadata;
+ private List<SkinAddition> _skinAdditionNodes;
+
+ private final static TrinidadLogger _LOG =
+ TrinidadLogger.createTrinidadLogger(TrinidadSkinProvider.class);
+}
+
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadSkinProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/CopyOnWriteArrayMap.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/skin/custom/CustomSkinProvider1.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/skin/custom/CustomSkinProvider2.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/skin/provider/SkinProviderTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/util/CopyOnWriteArrayMapTest.java
------------------------------------------------------------------------------
svn:eol-style = native