Author: nbelaevski
Date: 2010-07-22 08:51:30 -0400 (Thu, 22 Jul 2010)
New Revision: 18195
Added:
root/core/trunk/impl/src/main/java/org/richfaces/skin/AbstractSkin.java
root/core/trunk/impl/src/main/java/org/richfaces/skin/CompositeSkinImpl.java
root/core/trunk/impl/src/main/java/org/richfaces/skin/SkinImpl.java
Removed:
root/core/trunk/impl/src/main/java/org/richfaces/skin/AbstractChainableSkinImpl.java
root/core/trunk/impl/src/main/java/org/richfaces/skin/BaseSkinImpl.java
root/core/trunk/impl/src/main/java/org/richfaces/skin/BasicSkinImpl.java
root/core/trunk/impl/src/main/java/org/richfaces/skin/DefaultSkinImpl.java
root/core/trunk/impl/src/main/java/org/richfaces/skin/SkinImpl.java
Modified:
root/core/trunk/api/src/main/java/org/richfaces/skin/SkinFactory.java
root/core/trunk/impl/src/main/java/org/ajax4jsf/context/ContextInitParameters.java
root/core/trunk/impl/src/main/java/org/richfaces/skin/SkinFactoryImpl.java
root/core/trunk/impl/src/test/java/org/richfaces/skin/SkinTestCase.java
Log:
https://jira.jboss.org/browse/RF-8968
Skins refactoring
Modified: root/core/trunk/api/src/main/java/org/richfaces/skin/SkinFactory.java
===================================================================
--- root/core/trunk/api/src/main/java/org/richfaces/skin/SkinFactory.java 2010-07-22
12:45:33 UTC (rev 18194)
+++ root/core/trunk/api/src/main/java/org/richfaces/skin/SkinFactory.java 2010-07-22
12:51:30 UTC (rev 18195)
@@ -21,10 +21,10 @@
package org.richfaces.skin;
-import org.richfaces.application.ServiceTracker;
-
import javax.faces.context.FacesContext;
+import org.richfaces.application.ServiceTracker;
+
/**
* Base factory class ( implement Singleton design pattern ). Produce self
* instance to build current skin configuration. At present, realised as lazy
@@ -35,18 +35,7 @@
*/
public abstract class SkinFactory {
- public static final String BASE_SKIN_PARAMETER =
"org.richfaces.BASE_SKIN";
-
/**
- * Name of web application init parameter for current skin . Can be simple
- * String for non-modified name, or EL-expression for calculate current
- * skin. If EL evaluated to <code>String</code> - used as skin name, if
to
- * instance of {@link Skin } - used this instance. by default -
- * "org.exadel.chameleon.SKIN"
- */
- public static final String SKIN_PARAMETER = "org.richfaces.SKIN";
-
- /**
* Initialize skin factory. TODO - make call from init() method of any
* servlet or custom faces element method ??? If exist resource
* META-INF/services/org.richfaces.skin.SkinFactory , create
@@ -55,10 +44,15 @@
* instance of default factory ( as usual in JSF ). If any error occurs in
* instantiate custom factory, return default.
*/
+ @Deprecated
public static final SkinFactory getInstance() {
- return ServiceTracker.getService(FacesContext.getCurrentInstance(),
SkinFactory.class);
+ return getInstance(FacesContext.getCurrentInstance());
}
+ public static final SkinFactory getInstance(FacesContext context) {
+ return ServiceTracker.getService(context, SkinFactory.class);
+ }
+
/**
* Get default {@link Skin} implementation.
*
@@ -89,4 +83,7 @@
* @return
*/
public abstract Theme getTheme(FacesContext facesContext, String name);
+
+ public abstract Skin getSkin(FacesContext context, String name);
+
}
Modified:
root/core/trunk/impl/src/main/java/org/ajax4jsf/context/ContextInitParameters.java
===================================================================
---
root/core/trunk/impl/src/main/java/org/ajax4jsf/context/ContextInitParameters.java 2010-07-22
12:45:33 UTC (rev 18194)
+++
root/core/trunk/impl/src/main/java/org/ajax4jsf/context/ContextInitParameters.java 2010-07-22
12:51:30 UTC (rev 18195)
@@ -30,6 +30,7 @@
import org.ajax4jsf.util.ELUtils;
import org.richfaces.application.ServiceTracker;
+import org.richfaces.skin.Skin;
/**
* This class hold all methods for get application init parameters. Created for
@@ -50,14 +51,24 @@
* If is it equals "true" , framework should proparate exception to
client-side.
*/
public static final String HANDLE_VIEW_EXPIRED_ON_CLIENT =
"org.ajax4jsf.handleViewExpiredOnClient";
- public static final String STD_CONTROLS_SKINNING_PARAM =
"org.richfaces.ENABLE_CONTROL_SKINNING";
- public static final String STD_CONTROLS_SKINNING_CLASSES_PARAM =
"org.richfaces.ENABLE_CONTROL_SKINNING_CLASSES";
+ public static final String STD_CONTROLS_SKINNING_PARAM =
"org.richfaces.enableControlSkinning";
+ public static final String STD_CONTROLS_SKINNING_CLASSES_PARAM =
"org.richfaces.enableControlSkinningClasses";
public static final String[] QUEUE_ENABLED =
{"org.richfaces.queue.enabled"};
//TODO - better name
- public static final String RESOURCES_TTL =
"org.richfaces.RESOURCE_DEFAULT_TTL";
- public static final String RESOURCES_CACHE_SIZE =
"org.richfaces.RESOURCE_CACHE_SIZE";
+ public static final String RESOURCES_TTL =
"org.richfaces.resourceDefaultTTL";
+ public static final String RESOURCES_CACHE_SIZE =
"org.richfaces.resourceCacheSize";
+ /**
+ * Name of web application init parameter for current skin . Can be simple
+ * String for non-modified name, or EL-expression for calculate current
+ * skin. If EL evaluated to <code>String</code> - used as skin name, if
to
+ * instance of {@link Skin } - used this instance. by default -
+ * "org.exadel.chameleon.SKIN"
+ */
+ public static final String SKIN = "org.richfaces.skin";
+ public static final String BASE_SKIN = "org.richfaces.baseSkin";
+
private static final String[] RESOURCES_TTL_ARRAY = { RESOURCES_TTL };
private static final String[] RESOURCES_CACHE_SIZE_ARRAY = { RESOURCES_CACHE_SIZE };
@@ -101,7 +112,7 @@
* @return value of STD_CONTROLS_SKINNING_PARAM parameter if present.
*/
public static boolean isStandardControlSkinningEnabled(FacesContext context) {
- String paramValue = evaluateInitParameter(context, STD_CONTROLS_SKINNING_PARAM);
+ Object paramValue = evaluateInitParameter(context, STD_CONTROLS_SKINNING_PARAM);
return getBooleanValue(paramValue, true);
}
@@ -120,10 +131,18 @@
* @return value of STD_CONTROLS_SKINNING_CLASSES_PARAM parameter if present.
*/
public static boolean isStandardControlSkinningClassesEnabled(FacesContext context)
{
- String paramValue = evaluateInitParameter(context,
STD_CONTROLS_SKINNING_CLASSES_PARAM);
+ Object paramValue = evaluateInitParameter(context,
STD_CONTROLS_SKINNING_CLASSES_PARAM);
return getBooleanValue(paramValue, false);
}
+ public static Object getSkin(FacesContext context) {
+ return evaluateInitParameter(context, SKIN);
+ }
+
+ public static Object getBaseSkin(FacesContext context) {
+ return evaluateInitParameter(context, BASE_SKIN);
+ }
+
static int getInteger(FacesContext context, String[] paramNames, int defaultValue) {
String initParameter = getInitParameter(context, paramNames);
@@ -193,7 +212,7 @@
return concurrentStorage;
}
- private static String evaluateInitParameter(FacesContext context, String
parameterName) {
+ private static Object evaluateInitParameter(FacesContext context, String
parameterName) {
InitParametersStorage expressionsMap = getExpressionsMap(context);
String parameterKey = INIT_PARAM_PREFIX + parameterName;
@@ -223,7 +242,7 @@
return evaluateInitParameterExpression(context, parameterValue);
}
- private static String evaluateInitParameterExpression(FacesContext context, Object
parameterValue) {
+ private static Object evaluateInitParameterExpression(FacesContext context, Object
parameterValue) {
if (parameterValue == NULL || parameterValue == null) {
return null;
} else if (parameterValue instanceof ValueExpression) {
Deleted:
root/core/trunk/impl/src/main/java/org/richfaces/skin/AbstractChainableSkinImpl.java
===================================================================
---
root/core/trunk/impl/src/main/java/org/richfaces/skin/AbstractChainableSkinImpl.java 2010-07-22
12:45:33 UTC (rev 18194)
+++
root/core/trunk/impl/src/main/java/org/richfaces/skin/AbstractChainableSkinImpl.java 2010-07-22
12:51:30 UTC (rev 18195)
@@ -1,159 +0,0 @@
-/**
- * License Agreement.
- *
- * JBoss RichFaces - Ajax4jsf Component Library
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package org.richfaces.skin;
-
-import java.util.Map;
-
-import javax.faces.FacesException;
-import javax.faces.context.FacesContext;
-
-import org.ajax4jsf.Messages;
-
-/**
- * @author nick belaevski
- * @since 3.2
- */
-public abstract class AbstractChainableSkinImpl extends BasicSkinImpl {
- private static final Operation RESOLVE = new Operation() {
- public Object doExternalCall(FacesContext context, Skin impl, String name) {
-
- // TODO add warning because substitution can work incorrect and cyclic
references
- // won't be caught
- return impl.getParameter(context, name);
- }
-
- public Object doLocalCall(FacesContext context, AbstractChainableSkinImpl impl,
String name) {
- return impl.localResolveSkinParameter(context, name);
- }
- };
- private static final Operation CONTAINS = new Operation() {
- private Object wrapBoolean(boolean value) {
- return value ? Boolean.TRUE : null;
- }
-
- public Object doExternalCall(FacesContext context, Skin impl, String name) {
- return wrapBoolean(impl.containsProperty(name));
- }
-
- public Object doLocalCall(FacesContext context, AbstractChainableSkinImpl impl,
String name) {
- return wrapBoolean(impl.localContainsProperty(context, name));
- }
- };
-
- AbstractChainableSkinImpl(Map<Object, Object> properties) {
- super(properties);
- }
-
- protected abstract Skin getBaseSkin(FacesContext context);
-
- protected Object localResolveSkinParameter(FacesContext context, String name) {
- return getSkinParams().get(name);
- }
-
- protected boolean localContainsProperty(FacesContext context, String name) {
- return getSkinParams().containsKey(name);
- }
-
- protected Object executeOperation(FacesContext context, Operation operation, String
name, int[] singleInt) {
- if (singleInt[0]++ > 1000) {
- throw new FacesException(Messages.getMessage(Messages.SKIN_CYCLIC_REFERENCE,
name));
- }
-
- Object object = operation.doLocalCall(context, this, name);
-
- if (object == null) {
- Skin baseSkin = getBaseSkin(context);
-
- if (baseSkin != null) {
- if (baseSkin instanceof AbstractChainableSkinImpl) {
- AbstractChainableSkinImpl skinImpl = (AbstractChainableSkinImpl)
baseSkin;
-
- object = operation.doChainedCall(context, skinImpl, name,
singleInt);
- } else {
- object = operation.doExternalCall(context, baseSkin, name);
- }
- }
- }
-
- return object;
- }
-
- protected Object resolveSkinParameter(FacesContext context, String name, int[]
singleInt) {
- return executeOperation(context, RESOLVE, name, singleInt);
- }
-
- protected boolean containsProperty(FacesContext context, String name, int[]
singleInt) {
- return Boolean.TRUE.equals(executeOperation(context, CONTAINS, name,
singleInt));
- }
-
- protected Object resolveSkinParameter(FacesContext context, String name) {
- int[] singleInt = new int[]{0};
- Object resolvedParameter = resolveSkinParameter(context, name, singleInt);
-
- while (resolvedParameter instanceof String) {
- String string = (String) resolvedParameter;
-
- if ((string.length() > 0) && (string.charAt(0) ==
'&')) {
- resolvedParameter = resolveSkinParameter(context, string.substring(1),
singleInt);
-
- if (resolvedParameter == null) {
- throw new
FacesException(Messages.getMessage(Messages.SKIN_ILLEGAL_REFERENCE, name));
- }
- } else {
- break;
- }
- }
-
- return resolvedParameter;
- }
-
- /*
- * (non-Javadoc)
- * @see org.richfaces.skin.Skin#containsProperty(java.lang.String)
- */
- public boolean containsProperty(String name) {
- return containsProperty(FacesContext.getCurrentInstance(), name, new int[]{0});
- }
-
- @Override
- public int hashCode(FacesContext context) {
- int hash = super.hashCode(context);
- Skin baseSkin = getBaseSkin(context);
-
- if (baseSkin != null) {
- hash = 31 * hash + baseSkin.hashCode(context);
- }
-
- return hash;
- }
-
- private abstract static class Operation {
- public Object doChainedCall(FacesContext context, AbstractChainableSkinImpl impl,
String name,
- int[] singleInt) {
- return impl.executeOperation(context, this, name, singleInt);
- }
-
- public abstract Object doLocalCall(FacesContext context,
AbstractChainableSkinImpl impl, String name);
-
- public abstract Object doExternalCall(FacesContext context, Skin impl, String
name);
- }
-}
Added: root/core/trunk/impl/src/main/java/org/richfaces/skin/AbstractSkin.java
===================================================================
--- root/core/trunk/impl/src/main/java/org/richfaces/skin/AbstractSkin.java
(rev 0)
+++ root/core/trunk/impl/src/main/java/org/richfaces/skin/AbstractSkin.java 2010-07-22
12:51:30 UTC (rev 18195)
@@ -0,0 +1,59 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.skin;
+
+import java.awt.Color;
+
+import javax.faces.context.FacesContext;
+
+import org.ajax4jsf.util.HtmlColor;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class AbstractSkin implements Skin {
+
+ protected Integer decodeColor(Object value) {
+ if (value instanceof Color) {
+ return ((Color) value).getRGB();
+ } else if (value instanceof Integer) {
+ return ((Integer) value).intValue();
+ } else {
+ String stringValue = (String) value;
+ if (stringValue != null && stringValue.length() != 0) {
+ return Integer.valueOf(HtmlColor.decode(stringValue).getRGB());
+ } else {
+ return null;
+ }
+ }
+ }
+
+ public Integer getColorParameter(FacesContext context, String name) {
+ return decodeColor(getParameter(context, name));
+ }
+
+ public Integer getColorParameter(FacesContext context, String name, Object
defaultValue) {
+ return decodeColor(getParameter(context, name, defaultValue));
+ }
+
+}
Deleted: root/core/trunk/impl/src/main/java/org/richfaces/skin/BaseSkinImpl.java
===================================================================
--- root/core/trunk/impl/src/main/java/org/richfaces/skin/BaseSkinImpl.java 2010-07-22
12:45:33 UTC (rev 18194)
+++ root/core/trunk/impl/src/main/java/org/richfaces/skin/BaseSkinImpl.java 2010-07-22
12:51:30 UTC (rev 18195)
@@ -1,58 +0,0 @@
-/**
- * License Agreement.
- *
- * JBoss RichFaces - Ajax4jsf Component Library
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package org.richfaces.skin;
-
-import java.util.Map;
-
-import javax.faces.context.FacesContext;
-
-/**
- * @author nick belaevski
- * @since 3.2
- */
-
-public class BaseSkinImpl extends AbstractChainableSkinImpl {
-
- private SkinFactoryImpl factoryImpl;
-
- BaseSkinImpl(Map<Object, Object> properties, SkinFactoryImpl factory) {
- super(properties);
-
- this.factoryImpl = factory;
- }
-
- protected Skin getBaseSkin(FacesContext context) {
- Object object = getLocalParameter(context, Skin.BASE_SKIN);
- Skin skin = null;
-
- if (object != null) {
- skin = factoryImpl.getSkinByName(context, object, true);
- }
-
- if (skin == null) {
- skin = factoryImpl.getDefaultSkin(context);
- }
-
- return skin;
- }
-
-}
Deleted: root/core/trunk/impl/src/main/java/org/richfaces/skin/BasicSkinImpl.java
===================================================================
--- root/core/trunk/impl/src/main/java/org/richfaces/skin/BasicSkinImpl.java 2010-07-22
12:45:33 UTC (rev 18194)
+++ root/core/trunk/impl/src/main/java/org/richfaces/skin/BasicSkinImpl.java 2010-07-22
12:51:30 UTC (rev 18195)
@@ -1,181 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package org.richfaces.skin;
-
-import java.awt.Color;
-import java.util.Map;
-
-import javax.el.Expression;
-import javax.el.ValueExpression;
-import javax.faces.context.FacesContext;
-
-import org.ajax4jsf.util.HtmlColor;
-
-/**
- * Singleton ( in respect as collection of different skins ) for produce
- * instances properties for all used skins.
- *
- * @author shura (latest modification by $Author: alexsmirnov $)
- * @version $Revision: 1.1.2.1 $ $Date: 2007/01/09 18:59:41 $
- */
-public abstract class BasicSkinImpl implements Skin {
-
- private int hashCode = 0;
-
- private final Map<Object, Object> skinParams;
-
- /**
- * Skin can instantiate only by factory method.
- *
- * @param skinName
- */
- BasicSkinImpl(Map<Object, Object> properties) {
- this.skinParams = properties;
- }
-
- protected Map<Object, Object> getSkinParams() {
- return skinParams;
- }
-
- /*
- * (non-Javadoc)
- * @see org.richfaces.skin.Skin#getParameter(javax.faces.context.FacesContext,
java.lang.String)
- */
- public Object getParameter(FacesContext context, String name) {
- return getValueReference(context, resolveSkinParameter(context, name));
- }
-
- /*
- * (non-Javadoc)
- * @see org.richfaces.skin.Skin#getParameter(javax.faces.context.FacesContext,
java.lang.String, java.lang.String, java.lang.Object)
- */
- public Object getParameter(FacesContext context, String name, Object defaultValue) {
- Object value = getValueReference(context, resolveSkinParameter(context, name));
-
- if (null == value) {
- value = defaultValue;
- }
-
- return value;
- }
-
- protected Integer decodeColor(Object value) {
- if (value instanceof Color) {
- return ((Color) value).getRGB();
- } else if (value instanceof Integer) {
- return ((Integer) value).intValue();
- } else {
- String stringValue = (String) value;
- if (stringValue != null && stringValue.length() != 0) {
- return Integer.valueOf(HtmlColor.decode(stringValue).getRGB());
- } else {
- return null;
- }
- }
- }
-
- public Integer getColorParameter(FacesContext context, String name) {
- return decodeColor(getParameter(context, name));
- }
-
- public Integer getColorParameter(FacesContext context, String name, Object
defaultValue) {
- return decodeColor(getParameter(context, name, defaultValue));
- }
-
- protected Object getLocalParameter(FacesContext context, String name) {
- return getValueReference(context, skinParams.get(name));
- }
-
- protected abstract Object resolveSkinParameter(FacesContext context, String name);
-
- /**
- * Calculate concrete value for property - if it stored as @see ValueBinding ,
- * return interpreted value.
- *
- * @param context
- * @param property
- * @return
- */
- protected Object getValueReference(FacesContext context, Object property) {
- if (property instanceof ValueExpression) {
- ValueExpression value = (ValueExpression) property;
-
- return value.getValue(context.getELContext());
- }
-
- return property;
- }
-
- public String toString() {
- return this.getClass().getSimpleName() + ": " + skinParams.toString();
- }
-
- protected int computeHashCode(FacesContext context) {
- int localHash = hashCode;
- if (localHash == 0) {
- boolean hasDynamicValues = false;
-
- for (Map.Entry<Object, Object> entry : skinParams.entrySet()) {
- String key = (String) entry.getKey();
- Object value = entry.getValue();
-
- if (value instanceof Expression) {
- hasDynamicValues = true;
- }
-
- Object parameter = getValueReference(context, value);
-
- localHash = 31 * localHash + key.hashCode();
- localHash = 31 * localHash + ((parameter != null) ? parameter.hashCode()
: 0);
- }
-
- if (!hasDynamicValues) {
- hashCode = localHash;
- }
- }
-
- return localHash;
- }
-
- /*
- * (non-Javadoc)
- * @see org.richfaces.skin.Skin#hashCode(javax.faces.context.FacesContext)
- */
- public int hashCode(FacesContext context) {
- if (hashCode != 0) {
- return hashCode;
- }
-
- Map<Object, Object> attributesMap = context.getAttributes();
-
- Integer requestCode = (Integer) attributesMap.get(this);
-
- if (null == requestCode) {
- requestCode = new Integer(computeHashCode(context));
-
- // store hash for this skin as request-skope parameter - not calculate on
next calls for same request
- attributesMap.put(this, requestCode);
- }
-
- return requestCode.intValue();
- }
-}
Added: root/core/trunk/impl/src/main/java/org/richfaces/skin/CompositeSkinImpl.java
===================================================================
--- root/core/trunk/impl/src/main/java/org/richfaces/skin/CompositeSkinImpl.java
(rev 0)
+++
root/core/trunk/impl/src/main/java/org/richfaces/skin/CompositeSkinImpl.java 2010-07-22
12:51:30 UTC (rev 18195)
@@ -0,0 +1,122 @@
+/**
+ * License Agreement.
+ *
+ * JBoss RichFaces - Ajax4jsf Component Library
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.skin;
+
+import javax.faces.context.FacesContext;
+
+/**
+ * @author nick belaevski
+ */
+final class CompositeSkinImpl implements Skin {
+
+ private int hashCode = 0;
+
+ private Skin[] skinsChain;
+
+ /**
+ * @param properties
+ */
+ CompositeSkinImpl(Skin... skinsChain) {
+ // TODO Auto-generated constructor stub
+
+ this.skinsChain = skinsChain;
+ }
+
+ public boolean containsProperty(String name) {
+ for (Skin skin : skinsChain) {
+ if (skin == null) {
+ continue;
+ }
+
+ if (skin.containsProperty(name)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public int hashCode(FacesContext context) {
+ int hash = hashCode;
+
+ if (hash == 0) {
+ for (Skin skin : skinsChain) {
+ if (skin == null) {
+ continue;
+ }
+
+ hash = 31 * hash + skin.hashCode(context);
+ }
+
+ hashCode = hash;
+ }
+
+ return hash;
+ }
+
+ //for unit tests
+ void resetCachedHashCode() {
+ hashCode = 0;
+ }
+
+ public Object getParameter(FacesContext context, String name) {
+ for (Skin skin : skinsChain) {
+ if (skin == null) {
+ continue;
+ }
+
+ Object value = skin.getParameter(context, name);
+ if (value != null) {
+ return value;
+ }
+ }
+
+ return null;
+ }
+
+ public Object getParameter(FacesContext context, String name, Object defaultValue) {
+ Object parameterValue = getParameter(context, name);
+
+ if (parameterValue == null) {
+ parameterValue = defaultValue;
+ }
+
+ return parameterValue;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.skin.Skin#getColorParameter(javax.faces.context.FacesContext,
java.lang.String)
+ */
+ public Integer getColorParameter(FacesContext context, String name) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.skin.Skin#getColorParameter(javax.faces.context.FacesContext,
java.lang.String, java.lang.Object)
+ */
+ public Integer getColorParameter(FacesContext context, String name, Object
defaultValue) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
Deleted: root/core/trunk/impl/src/main/java/org/richfaces/skin/DefaultSkinImpl.java
===================================================================
--- root/core/trunk/impl/src/main/java/org/richfaces/skin/DefaultSkinImpl.java 2010-07-22
12:45:33 UTC (rev 18194)
+++ root/core/trunk/impl/src/main/java/org/richfaces/skin/DefaultSkinImpl.java 2010-07-22
12:51:30 UTC (rev 18195)
@@ -1,41 +0,0 @@
-/**
- * License Agreement.
- *
- * JBoss RichFaces - Ajax4jsf Component Library
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package org.richfaces.skin;
-
-import java.util.Map;
-
-import javax.faces.context.FacesContext;
-
-/**
- * @author nick belaevski
- * @since 3.2
- */
-public class DefaultSkinImpl extends AbstractChainableSkinImpl {
-
- DefaultSkinImpl(Map<Object, Object> properties) {
- super(properties);
- }
-
- protected Skin getBaseSkin(FacesContext context) {
- return null;
- }
-}
Modified: root/core/trunk/impl/src/main/java/org/richfaces/skin/SkinFactoryImpl.java
===================================================================
--- root/core/trunk/impl/src/main/java/org/richfaces/skin/SkinFactoryImpl.java 2010-07-22
12:45:33 UTC (rev 18194)
+++ root/core/trunk/impl/src/main/java/org/richfaces/skin/SkinFactoryImpl.java 2010-07-22
12:51:30 UTC (rev 18195)
@@ -21,19 +21,6 @@
package org.richfaces.skin;
-import org.ajax4jsf.Messages;
-import org.ajax4jsf.resource.util.URLToStreamHelper;
-import org.ajax4jsf.util.ELUtils;
-import org.richfaces.log.RichfacesLogger;
-import org.slf4j.Logger;
-
-import javax.el.ELContext;
-import javax.el.ExpressionFactory;
-import javax.el.ValueExpression;
-import javax.faces.FactoryFinder;
-import javax.faces.application.Application;
-import javax.faces.application.ApplicationFactory;
-import javax.faces.context.FacesContext;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@@ -42,7 +29,24 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.faces.application.Application;
+import javax.faces.context.FacesContext;
+
+import org.ajax4jsf.Messages;
+import org.ajax4jsf.context.ContextInitParameters;
+import org.ajax4jsf.resource.util.URLToStreamHelper;
+import org.ajax4jsf.util.ELUtils;
+import org.richfaces.log.RichfacesLogger;
+import org.slf4j.Logger;
+
/**
* Implementation of {@link SkinFactory} with building skins from properties
* files.
@@ -50,15 +54,10 @@
* @author shura
*/
public class SkinFactoryImpl extends SkinFactory {
- /**
- * Name of web application init parameter for current default
- * {@link javax.faces.render.RenderKit } interaction. by default -
- * org.exadel.chameleon.RENDERKIT_DEFINITION . TODO Possible Values
- */
- public static final String RENDER_KIT_PARAMETER =
"org.ajax4jsf.RENDERKIT_DEFINITION";
- private static final String A4J_BASE_SKIN_PARAMETER =
"org.ajax4jsf.BASE_SKIN";
- private static final String A4J_SKIN_PARAMETER = "org.ajax4jsf.SKIN";
+ private static final String SKIN_KEY = SkinFactoryImpl.class.getName() +
":skin";
+
+ private static final String BASE_SKIN_KEY = SkinFactoryImpl.class.getName() +
":baseSkin";
// private static final String DEFAULT_CONFIGURATION_RESOURCE =
"META-INF/skins/DEFAULT.configuration.properties";
@@ -84,72 +83,86 @@
*/
private static final String[] SKINS_PATHS = {DEFAULT_SKIN_PATH, USER_SKIN_PATH};
private static final Logger LOG = RichfacesLogger.APPLICATION.getLogger();
- private ValueExpression baseSkinBinding = null;
- private String baseSkinName = null;
- private ValueExpression skinBinding = null;
// private Properties defaultSkinProperties = null;
- private String skinName = null;
// private static final String[] CONFIGURATIONS_PATHS = {
// "META-INF/skins/%s.configuration.properties",
// "%s.configuration.properties" };
// private static final String[] DEFAULT_CONFIGURATION_PATHS = {
"META-INF/skins/DEFAULT.configuration.properties" };
- private Map<String, Skin> skins = new HashMap<String, Skin>();
- private Map<String, Skin> baseSkins = new HashMap<String, Skin>();
- private Map<String, Properties> sourceProperties = new HashMap<String,
Properties>();
+ private ConcurrentMap<String, FutureTask<Skin>> skins = new
ConcurrentHashMap<String, FutureTask<Skin>>();
private Map<String, Theme> themes = new HashMap<String, Theme>();
- protected Skin getSkinByName(FacesContext facesContext, Object currentSkinOrName,
boolean isBase) {
- if (null == currentSkinOrName) {
- throw new
SkinNotFoundException(Messages.getMessage(Messages.NULL_SKIN_NAME_ERROR));
+ private final class SkinBuilder implements Callable<Skin> {
+
+ private String skinName;
+
+ SkinBuilder(String skinName) {
+ super();
+ this.skinName = skinName;
}
- Skin currentSkin = null;
-
- // user binding return skin instance.
- if (currentSkinOrName instanceof Skin) {
- currentSkin = (Skin) currentSkinOrName;
- } else {
- String currentSkinName = currentSkinOrName.toString();
- Map<String, Skin> skinsMap = isBase ? baseSkins : skins;
-
- synchronized (skinsMap) {
- currentSkin = skinsMap.get(currentSkinName);
-
- // LAZY creation for skins, since, in case of EL expressions
- // for skin name, we don't can know all names of existing skins.
- if (currentSkin == null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug(Messages.getMessage(Messages.CREATE_SKIN_INFO,
currentSkinName));
- }
-
- currentSkin = buildSkin(facesContext, currentSkinName, isBase);
- skinsMap.put(currentSkinName, currentSkin);
- }
+ public Skin call() throws Exception {
+ return buildSkin(FacesContext.getCurrentInstance(), skinName);
+ }
+
+ }
+
+ @Override
+ public Skin getSkin(FacesContext context, String name) {
+ if (null == name) {
+ throw new
SkinNotFoundException(Messages.getMessage(Messages.NULL_SKIN_NAME_ERROR));
+ }
+
+ FutureTask<Skin> skinFuture = skins.get(name);
+ if (skinFuture == null) {
+ FutureTask<Skin> newSkinFuture = new FutureTask<Skin>(new
SkinBuilder(name));
+ skinFuture = skins.putIfAbsent(name, newSkinFuture);
+
+ if (skinFuture == null) {
+ skinFuture = newSkinFuture;
}
}
-
- return currentSkin;
+
+ try {
+ skinFuture.run();
+ return skinFuture.get();
+ } catch (InterruptedException e) {
+ throw new
SkinNotFoundException(Messages.getMessage(Messages.SKIN_NOT_FOUND_ERROR), e);
+ } catch (ExecutionException e) {
+ throw new
SkinNotFoundException(Messages.getMessage(Messages.SKIN_NOT_FOUND_ERROR), e);
+ }
}
-
+
public Skin getDefaultSkin(FacesContext context) {
- return getSkinByName(context, DEFAULT_SKIN_NAME, false);
+ return getSkin(context, DEFAULT_SKIN_NAME);
}
public Skin getSkin(FacesContext context) {
-
- // TODO - cache skin for current thread ? or for current Faces Lifecycle
- // Phase ?
- Object currentSkinOrName = getSkinOrName(context, false);
-
- return getSkinByName(context, currentSkinOrName, false);
+ Skin skin = (Skin) context.getAttributes().get(SKIN_KEY);
+ if (skin == null) {
+ Skin mainSkin = getSkinOrName(context, false);
+ Skin baseSkin = getSkinOrName(context, true);
+ Skin defaultSkin = getDefaultSkin(context);
+
+ skin = new CompositeSkinImpl(mainSkin, baseSkin, defaultSkin);
+ context.getAttributes().put(SKIN_KEY, skin);
+ }
+
+ return skin;
}
public Skin getBaseSkin(FacesContext context) {
- Object currentSkinOrName = getSkinOrName(context, true);
-
- return getSkinByName(context, currentSkinOrName, true);
+ Skin skin = (Skin) context.getAttributes().get(BASE_SKIN_KEY);
+ if (skin == null) {
+ Skin baseSkin = getSkinOrName(context, true);
+ Skin defaultSkin = getDefaultSkin(context);
+
+ skin = new CompositeSkinImpl(baseSkin, defaultSkin);
+ context.getAttributes().put(BASE_SKIN_KEY, skin);
+ }
+
+ return skin;
}
// protected Properties getDefaultSkinProperties() {
@@ -169,78 +182,25 @@
* parameter ) or {@link Skin } as result of evaluation EL
* expression.
*/
- protected Object getSkinOrName(FacesContext context, boolean useBase) {
-
- // Detect skin name
- ValueExpression binding;
- String skin;
-
- synchronized (this) {
- if (useBase) {
- binding = baseSkinBinding;
- skin = baseSkinName;
- } else {
- binding = skinBinding;
- skin = skinName;
- }
-
- if ((binding == null) && (skin == null)) {
- String currentSkinName =
context.getExternalContext().getInitParameter(useBase
- ? BASE_SKIN_PARAMETER : SKIN_PARAMETER);
-
- if (null == currentSkinName) {
-
- // Check for a old ( deprecated ) parameter name.
- currentSkinName =
context.getExternalContext().getInitParameter(useBase
- ? A4J_BASE_SKIN_PARAMETER : A4J_SKIN_PARAMETER);
-
- if (null != currentSkinName) {
- LOG.warn("Init parameter for a skin name changed to "
- + (useBase ? BASE_SKIN_PARAMETER : SKIN_PARAMETER));
- }
- }
-
- if (currentSkinName == null) {
-
- // not set - usr default.
- return DEFAULT_SKIN_NAME;
- }
-
- if (ELUtils.isValueReference(currentSkinName)) {
-
- // For EL expression as skin name
- binding =
-
context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(),
- currentSkinName, Object.class);
- } else {
- skin = currentSkinName;
- }
-
- if (useBase) {
- baseSkinBinding = binding;
- baseSkinName = skin;
- } else {
- skinBinding = binding;
- skinName = skin;
- }
- }
-
- // }
+ protected Skin getSkinOrName(FacesContext context, boolean useBase) {
+ Object skinObject = useBase ? ContextInitParameters.getBaseSkin(context) :
ContextInitParameters.getSkin(context);
+
+ Skin result = null;
+
+ if (skinObject instanceof Skin) {
+ result = (Skin) skinObject;
+ } else if (skinObject != null) {
+ result = getSkin(context, (String) skinObject);
}
-
- if (binding != null) {
- return binding.getValue(context.getELContext());
- } else {
- return skin;
- }
+
+ return result;
}
private void processProperties(FacesContext context, Map<Object, Object>
properties) {
ELContext elContext = context.getELContext();
// replace all EL-expressions by prepared ValueBinding ?
- ApplicationFactory factory = (ApplicationFactory)
FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
- Application app = factory.getApplication();
+ Application app = context.getApplication();
for (Entry<Object, Object> entry : properties.entrySet()) {
Object propertyObject = entry.getValue();
@@ -272,32 +232,11 @@
* @throws SkinNotFoundException -
* if no skin properies found for name.
*/
- protected Skin buildSkin(FacesContext context, String name, boolean isBase) throws
SkinNotFoundException {
- Properties skinParams;
+ protected Skin buildSkin(FacesContext context, String name) throws
SkinNotFoundException {
+ Properties skinParams = loadProperties(name, SKINS_PATHS);
+ processProperties(context, skinParams);
- synchronized (sourceProperties) {
- skinParams = sourceProperties.get(name);
-
- if (skinParams == null) {
- skinParams = loadProperties(name, SKINS_PATHS);
- processProperties(context, skinParams);
-
- // skinParams = Collections.unmodifiableMap(skinParams);
- sourceProperties.put(name, skinParams);
- }
- }
-
- BasicSkinImpl skinImpl;
-
- if (DEFAULT_SKIN_NAME.equals(name)) {
- skinImpl = new DefaultSkinImpl(skinParams);
- } else if (isBase) {
- skinImpl = new BaseSkinImpl(skinParams, this);
- } else {
- skinImpl = new SkinImpl(skinParams, this);
- }
-
- return skinImpl;
+ return new SkinImpl(skinParams);
}
/**
Deleted: root/core/trunk/impl/src/main/java/org/richfaces/skin/SkinImpl.java
===================================================================
--- root/core/trunk/impl/src/main/java/org/richfaces/skin/SkinImpl.java 2010-07-22
12:45:33 UTC (rev 18194)
+++ root/core/trunk/impl/src/main/java/org/richfaces/skin/SkinImpl.java 2010-07-22
12:51:30 UTC (rev 18195)
@@ -1,56 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package org.richfaces.skin;
-
-import java.util.Map;
-
-import javax.faces.context.FacesContext;
-
-/**
- * @author nick belaevski
- * @since 3.2
- */
-public class SkinImpl extends AbstractChainableSkinImpl {
-
- private SkinFactoryImpl factoryImpl;
-
- SkinImpl(Map<Object, Object> properties, SkinFactoryImpl factoryImpl) {
- super(properties);
-
- this.factoryImpl = factoryImpl;
- }
-
- protected Skin getBaseSkin(FacesContext context) {
- Object object = getLocalParameter(context, Skin.BASE_SKIN);
- Skin skin = null;
-
- if (object != null) {
- skin = factoryImpl.getSkinByName(context, object, false);
- }
-
- if (skin == null) {
- skin = factoryImpl.getBaseSkin(context);
- }
-
- return skin;
- }
-}
Copied: root/core/trunk/impl/src/main/java/org/richfaces/skin/SkinImpl.java (from rev
18177, root/core/trunk/impl/src/main/java/org/richfaces/skin/BasicSkinImpl.java)
===================================================================
--- root/core/trunk/impl/src/main/java/org/richfaces/skin/SkinImpl.java
(rev 0)
+++ root/core/trunk/impl/src/main/java/org/richfaces/skin/SkinImpl.java 2010-07-22
12:51:30 UTC (rev 18195)
@@ -0,0 +1,247 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.skin;
+
+import java.util.Map;
+
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+
+import org.ajax4jsf.Messages;
+
+/**
+ * Singleton ( in respect as collection of different skins ) for produce
+ * instances properties for all used skins.
+ *
+ * @author shura (latest modification by $Author: alexsmirnov $)
+ * @version $Revision: 1.1.2.1 $ $Date: 2007/01/09 18:59:41 $
+ */
+final class SkinImpl extends AbstractSkin {
+
+ private static class MutableInteger {
+ private int value;
+
+ public int getAndIncrement() {
+ return value++;
+ }
+
+ public int getAndDecrement() {
+ return value--;
+ }
+ }
+
+ private MutableInteger getCounter(FacesContext context) {
+ Map<Object, Object> attr = context.getAttributes();
+
+ MutableInteger counter = (MutableInteger) attr.get(MutableInteger.class);
+ if (counter == null) {
+ counter = new MutableInteger();
+ attr.put(MutableInteger.class, counter);
+ }
+
+ return counter;
+ }
+
+ private abstract static class Operation {
+
+ public abstract Object executeLocal(FacesContext facesContext, SkinImpl skin,
String name);
+
+ public abstract Object executeBase(FacesContext facesContext, Skin skin, String
name);
+
+ }
+
+ private static final Operation RESOLVE = new Operation() {
+
+ public Object executeLocal(FacesContext facesContext, SkinImpl skin, String name)
{
+ Object resolvedParameter = skin.getLocalParameter(facesContext, name);
+
+ while (resolvedParameter instanceof String) {
+ String string = (String) resolvedParameter;
+
+ if ((string.length() > 0) && (string.charAt(0) ==
'&')) {
+ SkinFactory skinFactory = SkinFactory.getInstance(facesContext);
+ resolvedParameter =
skinFactory.getSkin(facesContext).getParameter(facesContext, string.substring(1));
+
+ if (resolvedParameter == null) {
+ throw new
FacesException(Messages.getMessage(Messages.SKIN_ILLEGAL_REFERENCE, name));
+ }
+ } else {
+ break;
+ }
+ }
+
+ return resolvedParameter;
+ }
+
+ @Override
+ public Object executeBase(FacesContext facesContext, Skin skin, String name) {
+ return skin.getParameter(facesContext, name);
+ }
+
+ };
+
+ private static final Operation CONTAINS = new Operation() {
+
+ public Object executeLocal(FacesContext facesContext, SkinImpl skin, String name)
{
+ return skin.localContainsProperty(facesContext, name) ? Boolean.TRUE :
Boolean.FALSE;
+ }
+
+ @Override
+ public Object executeBase(FacesContext facesContext, Skin skin, String name) {
+ return skin.containsProperty(name);
+ }
+
+ };
+
+ private final Map<Object, Object> skinParams;
+
+ /**
+ * Skin can instantiate only by factory method.
+ *
+ * @param skinName
+ */
+ SkinImpl(Map<Object, Object> properties) {
+ this.skinParams = properties;
+ }
+
+ protected Map<Object, Object> getSkinParams() {
+ return skinParams;
+ }
+
+ public Object getParameter(FacesContext context, String name) {
+ return getValueReference(context, resolveSkinParameter(context, name));
+ }
+
+ public Object getParameter(FacesContext context, String name, Object defaultValue) {
+ Object value = getValueReference(context, resolveSkinParameter(context, name));
+
+ if (null == value) {
+ value = defaultValue;
+ }
+
+ return value;
+ }
+
+ protected Object getLocalParameter(FacesContext context, String name) {
+ return getValueReference(context, skinParams.get(name));
+ }
+
+ /**
+ * Calculate concrete value for property - if it stored as @see ValueBinding ,
+ * return interpreted value.
+ *
+ * @param context
+ * @param property
+ * @return
+ */
+ protected Object getValueReference(FacesContext context, Object property) {
+ if (property instanceof ValueExpression) {
+ ValueExpression value = (ValueExpression) property;
+
+ return value.getValue(context.getELContext());
+ }
+
+ return property;
+ }
+
+ public String toString() {
+ return this.getClass().getSimpleName() + ": " + skinParams.toString();
+ }
+
+ protected Skin getBaseSkin(FacesContext context) {
+ String baseSkinName = (String) getLocalParameter(context, Skin.BASE_SKIN);
+ if (baseSkinName != null) {
+ SkinFactory skinFactory = SkinFactory.getInstance(context);
+ return skinFactory.getSkin(context, baseSkinName);
+ }
+ return null;
+ }
+
+ protected Object localResolveSkinParameter(FacesContext context, String name) {
+ return getSkinParams().get(name);
+ }
+
+ protected boolean localContainsProperty(FacesContext context, String name) {
+ return getSkinParams().containsKey(name);
+ }
+
+ protected Object executeOperation(FacesContext context, Operation operation, String
name) {
+ MutableInteger counter = getCounter(context);
+
+ try {
+ if (counter.getAndIncrement() > 100) {
+ throw new
FacesException(Messages.getMessage(Messages.SKIN_CYCLIC_REFERENCE, name));
+ }
+
+ Object result = operation.executeLocal(context, this, name);
+ if (result != null) {
+ return result;
+ }
+
+ Skin baseSkin = getBaseSkin(context);
+ if (baseSkin != null) {
+ return operation.executeBase(context, baseSkin, name);
+ }
+
+ } finally {
+ counter.getAndDecrement();
+ }
+
+ return null;
+ }
+
+ protected boolean containsProperty(FacesContext context, String name) {
+ return Boolean.TRUE.equals(executeOperation(context, CONTAINS, name));
+ }
+
+ protected Object resolveSkinParameter(FacesContext context, String name) {
+ return executeOperation(context, RESOLVE, name);
+ }
+
+ public boolean containsProperty(String name) {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ return containsProperty(facesContext, name);
+ }
+
+ public int hashCode(FacesContext context) {
+ int hash = 0;
+ for (Map.Entry<Object, Object> entry : skinParams.entrySet()) {
+ String key = (String) entry.getKey();
+ Object value = entry.getValue();
+
+ Object parameter = getValueReference(context, value);
+
+ hash = 31 * hash + key.hashCode();
+ hash = 31 * hash + ((parameter != null) ? parameter.hashCode() : 0);
+ }
+
+ Skin baseSkin = getBaseSkin(context);
+
+ if (baseSkin != null) {
+ hash = 31 * hash + baseSkin.hashCode(context);
+ }
+
+ return hash;
+ }
+
+}
Modified: root/core/trunk/impl/src/test/java/org/richfaces/skin/SkinTestCase.java
===================================================================
--- root/core/trunk/impl/src/test/java/org/richfaces/skin/SkinTestCase.java 2010-07-22
12:45:33 UTC (rev 18194)
+++ root/core/trunk/impl/src/test/java/org/richfaces/skin/SkinTestCase.java 2010-07-22
12:51:30 UTC (rev 18195)
@@ -31,6 +31,7 @@
import javax.faces.FacesException;
+import org.ajax4jsf.context.ContextInitParameters;
import org.jboss.test.faces.AbstractFacesTest;
/**
@@ -67,13 +68,13 @@
String skinName = skinParameters.skinName();
if (skinName != null && skinName.length() != 0) {
- facesServer.addInitParameter(SkinFactory.SKIN_PARAMETER, skinName);
+ facesServer.addInitParameter(ContextInitParameters.SKIN, skinName);
}
String baseSkinName = skinParameters.baseSkinName();
if (baseSkinName != null && baseSkinName.length() != 0) {
- facesServer.addInitParameter(SkinFactory.BASE_SKIN_PARAMETER,
baseSkinName);
+ facesServer.addInitParameter(ContextInitParameters.BASE_SKIN,
baseSkinName);
}
}
} catch (Exception e) {
@@ -248,22 +249,17 @@
});
Skin skin = factory.getSkin(facesContext);
- Map<Object, Object> attributesMap = facesContext.getAttributes();
// test properties
int hash = skin.hashCode(facesContext);
- assertTrue(attributesMap.containsKey(skin));
assertEquals(hash, skin.hashCode(facesContext));
- attributesMap.remove(skin);
- assertEquals(hash, skin.hashCode(facesContext));
- // setup Value binding mock for different value - hash must differ.
- attributesMap.remove(skin);
-
Map<String, Object> requestMap =
facesContext.getExternalContext().getRequestMap();
Map map = (Map) requestMap.get("test");
+ ((CompositeSkinImpl) skin).resetCachedHashCode();
+
map.put("bean", "other.test.value");
assertFalse(hash == skin.hashCode(facesContext));
}