Author: nbelaevski
Date: 2010-12-23 14:24:00 -0500 (Thu, 23 Dec 2010)
New Revision: 20788
Added:
trunk/core/api/src/main/java/org/richfaces/el/GenericsIntrospectionService.java
trunk/core/impl/src/main/java/org/richfaces/el/CapturingELResolver.java
trunk/core/impl/src/main/java/org/richfaces/el/GenericsIntrospectionServiceImpl.java
Removed:
trunk/core/api/src/main/java/org/richfaces/el/util/CapturingELResolver.java
trunk/core/api/src/main/java/org/richfaces/el/util/GenericsIntrospectionCache.java
trunk/core/api/src/main/java/org/richfaces/el/util/ReferenceMap.java
Modified:
trunk/core/api/src/main/java/org/richfaces/el/util/ELUtils.java
trunk/core/impl/src/main/java/org/richfaces/application/DefaultModule.java
trunk/ui/input/ui/src/main/java/org/richfaces/component/AbstractAutocomplete.java
Log:
Legacy 3.x code removal
ELUtils refactoring
Added: trunk/core/api/src/main/java/org/richfaces/el/GenericsIntrospectionService.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/el/GenericsIntrospectionService.java
(rev 0)
+++
trunk/core/api/src/main/java/org/richfaces/el/GenericsIntrospectionService.java 2010-12-23
19:24:00 UTC (rev 20788)
@@ -0,0 +1,35 @@
+/*
+ * 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.el;
+
+import javax.el.ValueExpression;
+import javax.faces.context.FacesContext;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface GenericsIntrospectionService {
+
+ public Class<?> getContainerClass(FacesContext facesContext, ValueExpression
expression);
+
+}
Deleted: trunk/core/api/src/main/java/org/richfaces/el/util/CapturingELResolver.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/el/util/CapturingELResolver.java 2010-12-23
17:32:10 UTC (rev 20787)
+++ trunk/core/api/src/main/java/org/richfaces/el/util/CapturingELResolver.java 2010-12-23
19:24:00 UTC (rev 20788)
@@ -1,68 +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.el.util;
-
-import javax.el.ELContext;
-import javax.el.ELResolver;
-
-import org.richfaces.el.ELResolverWrapper;
-
-/**
- * @author Nick Belaevski
- * @since 3.3.0
- */
-public class CapturingELResolver extends ELResolverWrapper {
- private Object base;
- private Object property;
-
- public CapturingELResolver(ELResolver resolver) {
- super(resolver);
- }
-
- @Override
- public Object getValue(ELContext context, Object base, Object property) {
- if ((base != null) && (property != null)) {
- this.base = base;
- this.property = property;
- }
-
- return super.getValue(context, base, property);
- }
-
- @Override
- public Class<?> getType(ELContext context, Object base, Object property) {
- if ((base != null) && (property != null)) {
- this.base = base;
- this.property = property;
- }
-
- return super.getType(context, base, property);
- }
-
- public Object getBase() {
- return base;
- }
-
- public Object getProperty() {
- return property;
- }
-}
Modified: trunk/core/api/src/main/java/org/richfaces/el/util/ELUtils.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/el/util/ELUtils.java 2010-12-23 17:32:10
UTC (rev 20787)
+++ trunk/core/api/src/main/java/org/richfaces/el/util/ELUtils.java 2010-12-23 19:24:00
UTC (rev 20788)
@@ -21,27 +21,7 @@
package org.richfaces.el.util;
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.ResourceBundle;
-import javax.el.ELContext;
-import javax.el.ValueExpression;
-import javax.faces.FacesException;
-import javax.faces.context.FacesContext;
-
-import org.richfaces.el.ELContextWrapper;
-import org.richfaces.el.util.GenericsIntrospectionCache.GenericsCacheEntry;
-
/**
* @author asmirnov
*/
@@ -79,130 +59,4 @@
return false;
}
- public static Object evaluateValueExpression(ValueExpression expression, ELContext
elContext) {
-
- if (expression.isLiteralText()) {
- return expression.getExpressionString();
- } else {
- return expression.getValue(elContext);
- }
-
- }
-
- public static ValueExpression createValueExpression(String expression) {
-
- return createValueExpression(expression, Object.class);
-
- }
-
- public static ValueExpression createValueExpression(String expression, Class<?>
expectedType) {
- FacesContext context = FacesContext.getCurrentInstance();
- return
context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(),
expression, expectedType);
- }
-
- private static Class<?> resolveType(Type type) {
- Class<?> result = Object.class;
-
- if (type instanceof ParameterizedType) {
- ParameterizedType parameterizedType = (ParameterizedType) type;
- Type[] types = parameterizedType.getActualTypeArguments();
-
- if ((types != null) && (types.length != 0)) {
- Type actualType = types[0];
-
- if (actualType instanceof Class) {
- result = (Class<?>) actualType;
- }
- }
- }
-
- return result;
- }
-
- private static BeanInfo getBeanInfo(Class<?> beanClass, GenericsCacheEntry
entry) {
- BeanInfo beanInfo = null;
- SoftReference<BeanInfo> beanInfoReference = entry.beanInfoReference;
-
- if (beanInfoReference != null) {
- beanInfo = beanInfoReference.get();
- }
-
- if (beanInfo == null) {
- try {
- beanInfo = Introspector.getBeanInfo(beanClass);
- entry.beanInfoReference = new SoftReference<BeanInfo>(beanInfo);
- } catch (IntrospectionException e) {
- throw new FacesException(e.getMessage(), e);
- }
- }
-
- return beanInfo;
- }
-
- private static Class<?> getGenericCollectionType(FacesContext context, Object
base, String propertyName) {
- Class<?> genericPropertyClass = null;
-
- if ((base != null) && (propertyName != null)) {
- Class<? extends Object> beanClass = base.getClass();
-
- // Map and ResourceBundle have special resolvers that we doesn't support
- if (!Map.class.isAssignableFrom(beanClass) &&
!ResourceBundle.class.isAssignableFrom(beanClass)) {
- GenericsIntrospectionCache introspectionCache =
GenericsIntrospectionCache.getInstance(context);
-
- synchronized (introspectionCache) {
- GenericsCacheEntry cacheEntry =
introspectionCache.getGenericCacheEntry(beanClass);
-
- if (cacheEntry.genericPropertiesClasses == null) {
- cacheEntry.genericPropertiesClasses = new HashMap<String,
Class<?>>();
- } else {
- genericPropertyClass =
cacheEntry.genericPropertiesClasses.get(propertyName);
- }
-
- if (genericPropertyClass == null) {
- if
(!cacheEntry.genericPropertiesClasses.containsKey(propertyName)) {
- BeanInfo beanInfo = getBeanInfo(beanClass, cacheEntry);
- PropertyDescriptor[] descriptors =
beanInfo.getPropertyDescriptors();
-
- for (PropertyDescriptor pd : descriptors) {
- if (propertyName.equals(pd.getName())) {
- Method readMethod = pd.getReadMethod();
-
- genericPropertyClass =
resolveType(readMethod.getGenericReturnType());
-
- break;
- }
- }
-
- cacheEntry.genericPropertiesClasses.put(propertyName,
genericPropertyClass);
- } else {
-
- // property Class has been already resolved as null
- }
- }
- }
- }
- }
-
- return genericPropertyClass;
- }
-
- public static Class<?> getContainerClass(FacesContext facesContext,
ValueExpression expression) {
- ELContext initialELContext = facesContext.getELContext();
- CapturingELResolver capturingELResolver = new
CapturingELResolver(initialELContext.getELResolver());
- Class<?> type = expression.getType(new ELContextWrapper(initialELContext,
capturingELResolver));
- Class<?> containerType = type.getComponentType();
-
- if ((containerType == null) && (type != null)) {
- if (Collection.class.isAssignableFrom(type)) {
- Object base = capturingELResolver.getBase();
- Object property = capturingELResolver.getProperty();
-
- if ((base != null) && (property != null)) {
- containerType = getGenericCollectionType(facesContext, base,
property.toString());
- }
- }
- }
-
- return containerType;
- }
}
Deleted:
trunk/core/api/src/main/java/org/richfaces/el/util/GenericsIntrospectionCache.java
===================================================================
---
trunk/core/api/src/main/java/org/richfaces/el/util/GenericsIntrospectionCache.java 2010-12-23
17:32:10 UTC (rev 20787)
+++
trunk/core/api/src/main/java/org/richfaces/el/util/GenericsIntrospectionCache.java 2010-12-23
19:24:00 UTC (rev 20788)
@@ -1,99 +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.el.util;
-
-import java.beans.BeanInfo;
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
-import java.util.Collections;
-import java.util.Map;
-
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-
-import org.richfaces.util.LRUMap;
-
-/**
- * @author Nick Belaevski
- * @since 3.3.0
- */
-final class GenericsIntrospectionCache {
- private static final String CACHE_SIZE_PARAMETER =
"org.richfaces.GenericsIntrospectionCacheSize";
- private static final int DEFAULT_CACHE_SIZE = 256;
- private static final String INSTANCE_ATTRIBUTE_NAME =
GenericsIntrospectionCache.class.getName();
- private Map<Class<?>, GenericsCacheEntry> genericsCache;
-
- private GenericsIntrospectionCache(int cacheSize) {
- genericsCache = new ReferenceMap<Class<?>,
- GenericsCacheEntry>(Collections.synchronizedMap(new
LRUMap<Class<?>,
- Reference<GenericsCacheEntry>>(cacheSize)));
- }
-
- private static int getSize(ExternalContext externalContext) {
- int cacheSize = DEFAULT_CACHE_SIZE;
- String cacheSizeParameter =
externalContext.getInitParameter(CACHE_SIZE_PARAMETER);
-
- if (cacheSizeParameter != null && cacheSizeParameter.length() != 0) {
- try {
- cacheSize = Integer.valueOf(cacheSizeParameter);
- } catch (NumberFormatException e) {
- externalContext.log("Error converting " + CACHE_SIZE_PARAMETER
+ " init parameter to int: "
- + e.getMessage(), e);
- }
- }
-
- return cacheSize;
- }
-
- public GenericsCacheEntry getGenericCacheEntry(Class<?> beanClass) {
- GenericsCacheEntry cacheEntry = genericsCache.get(beanClass);
-
- if (cacheEntry == null) {
- cacheEntry = new GenericsCacheEntry();
- genericsCache.put(beanClass, cacheEntry);
- }
-
- return cacheEntry;
- }
-
- static GenericsIntrospectionCache getInstance(FacesContext facesContext) {
- ExternalContext externalContext = facesContext.getExternalContext();
- Map<String, Object> applicationMap = externalContext.getApplicationMap();
- GenericsIntrospectionCache instance;
-
- synchronized (applicationMap) {
- instance = (GenericsIntrospectionCache)
applicationMap.get(INSTANCE_ATTRIBUTE_NAME);
-
- if (instance == null) {
- instance = new GenericsIntrospectionCache(getSize(externalContext));
- applicationMap.put(INSTANCE_ATTRIBUTE_NAME, instance);
- }
- }
-
- return instance;
- }
-
- static final class GenericsCacheEntry {
- SoftReference<BeanInfo> beanInfoReference;
- Map<String, Class<?>> genericPropertiesClasses;
- }
-}
Deleted: trunk/core/api/src/main/java/org/richfaces/el/util/ReferenceMap.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/el/util/ReferenceMap.java 2010-12-23
17:32:10 UTC (rev 20787)
+++ trunk/core/api/src/main/java/org/richfaces/el/util/ReferenceMap.java 2010-12-23
19:24:00 UTC (rev 20788)
@@ -1,177 +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.el.util;
-
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Created 17.03.2008
- *
- * @author Nick Belaevski
- * @since 3.2
- */
-public class ReferenceMap<K, V> implements Map<K, V> {
- private ReferenceQueue<V> queue = new ReferenceQueue<V>();
- private Map<K, Reference<V>> map;
-
- public ReferenceMap() {
- this(Collections.synchronizedMap(new HashMap<K, Reference<V>>()));
- }
-
- public ReferenceMap(Map<K, Reference<V>> map) {
- super();
- this.map = map;
- }
-
- private void purge() {
- Reference<? extends V> reference = null;
-
- while ((reference = queue.poll()) != null) {
- ReferenceMapSoftReference<?, ?> entry =
(ReferenceMapSoftReference<?, ?>) reference;
-
- entry.clear();
- map.remove(entry.getKey());
- }
- }
-
- public void clear() {
- map.clear();
-
- Reference<? extends V> reference = null;
-
- while ((reference = queue.poll()) != null) {
-
- // release queue entries
- reference.clear();
- }
- }
-
- public boolean containsKey(Object key) {
- purge();
-
- return map.containsKey(key);
- }
-
- public boolean containsValue(Object value) {
- throw new UnsupportedOperationException();
- }
-
- public Set<java.util.Map.Entry<K, V>> entrySet() {
- throw new UnsupportedOperationException();
- }
-
- public V get(Object key) {
- purge();
-
- Reference<V> reference = map.get(key);
-
- if (reference != null) {
- return reference.get();
- }
-
- return null;
- }
-
- public boolean isEmpty() {
- purge();
-
- return map.isEmpty();
- }
-
- public Set<K> keySet() {
- purge();
-
- return map.keySet();
- }
-
- private V doPut(K key, V value) {
- Reference<V> reference = map.put(key, new ReferenceMapSoftReference<K,
V>(key, value, queue));
-
- if (reference != null) {
- return reference.get();
- }
-
- return null;
- }
-
- public V put(K key, V value) {
- purge();
-
- V v = doPut(key, value);
-
- purge();
-
- return v;
- }
-
- public void putAll(Map<? extends K, ? extends V> t) {
- purge();
-
- for (Map.Entry<? extends K, ? extends V> entry : t.entrySet()) {
- doPut(entry.getKey(), entry.getValue());
- }
-
- purge();
- }
-
- public V remove(Object key) {
- purge();
-
- Reference<V> reference = map.remove(key);
-
- if (reference != null) {
- return reference.get();
- }
-
- return null;
- }
-
- public int size() {
- purge();
-
- return map.size();
- }
-
- public Collection<V> values() {
- throw new UnsupportedOperationException();
- }
-
- protected static class ReferenceMapSoftReference<K, V> extends
SoftReference<V> {
- private K key;
-
- public ReferenceMapSoftReference(K key, V value, ReferenceQueue<? super V>
queue) {
- super(value, queue);
- this.key = key;
- }
-
- public K getKey() {
- return key;
- }
- }
-}
Modified: trunk/core/impl/src/main/java/org/richfaces/application/DefaultModule.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/DefaultModule.java 2010-12-23
17:32:10 UTC (rev 20787)
+++ trunk/core/impl/src/main/java/org/richfaces/application/DefaultModule.java 2010-12-23
19:24:00 UTC (rev 20788)
@@ -5,6 +5,8 @@
import org.richfaces.application.push.PushContextFactory;
import org.richfaces.application.push.impl.jms.PushContextFactoryImpl;
import org.richfaces.cache.Cache;
+import org.richfaces.el.GenericsIntrospectionService;
+import org.richfaces.el.GenericsIntrospectionServiceImpl;
import org.richfaces.javascript.JavaScriptService;
import org.richfaces.javascript.JavaScriptServiceImpl;
import org.richfaces.l10n.BundleLoader;
@@ -31,7 +33,7 @@
factory.setInstance(ResourceLibraryFactory.class, new
ResourceLibraryFactoryImpl());
factory.setInstance(PushContextFactory.class,
ServiceLoader.loadService(PushContextFactory.class, PushContextFactoryImpl.class));
factory.setInstance(JavaScriptService.class, new JavaScriptServiceImpl());
-
+ factory.setInstance(GenericsIntrospectionService.class, new
GenericsIntrospectionServiceImpl());
}
}
Copied: trunk/core/impl/src/main/java/org/richfaces/el/CapturingELResolver.java (from rev
20785, trunk/core/api/src/main/java/org/richfaces/el/util/CapturingELResolver.java)
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/el/CapturingELResolver.java
(rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/el/CapturingELResolver.java 2010-12-23
19:24:00 UTC (rev 20788)
@@ -0,0 +1,66 @@
+/**
+ * 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.el;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+
+/**
+ * @author Nick Belaevski
+ * @since 3.3.0
+ */
+public class CapturingELResolver extends ELResolverWrapper {
+ private Object base;
+ private Object property;
+
+ public CapturingELResolver(ELResolver resolver) {
+ super(resolver);
+ }
+
+ @Override
+ public Object getValue(ELContext context, Object base, Object property) {
+ if ((base != null) && (property != null)) {
+ this.base = base;
+ this.property = property;
+ }
+
+ return super.getValue(context, base, property);
+ }
+
+ @Override
+ public Class<?> getType(ELContext context, Object base, Object property) {
+ if ((base != null) && (property != null)) {
+ this.base = base;
+ this.property = property;
+ }
+
+ return super.getType(context, base, property);
+ }
+
+ public Object getBase() {
+ return base;
+ }
+
+ public Object getProperty() {
+ return property;
+ }
+}
Added:
trunk/core/impl/src/main/java/org/richfaces/el/GenericsIntrospectionServiceImpl.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/el/GenericsIntrospectionServiceImpl.java
(rev 0)
+++
trunk/core/impl/src/main/java/org/richfaces/el/GenericsIntrospectionServiceImpl.java 2010-12-23
19:24:00 UTC (rev 20788)
@@ -0,0 +1,170 @@
+/*
+ * 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.el;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+
+import com.google.common.base.Function;
+import com.google.common.collect.MapMaker;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class GenericsIntrospectionServiceImpl implements GenericsIntrospectionService {
+
+ private static final class GenericsCacheEntry {
+
+ private Class<?> beanClass;
+
+ private Map<String, Class<?>> containerClassesMap = new
MapMaker().initialCapacity(2).makeComputingMap(new Function<String,
Class<?>>() {
+
+ public Class<?> apply(String input) {
+ PropertyDescriptor propertyDescriptor = getPropertyDescriptor(input);
+ return getGenericContainerClass(propertyDescriptor);
+ }
+
+ });
+
+ public GenericsCacheEntry(Class<?> beanClass) {
+ this.beanClass = beanClass;
+ }
+
+ private Class<?> resolveType(Type type) {
+ Class<?> result = Object.class;
+
+ if (type instanceof ParameterizedType) {
+ ParameterizedType parameterizedType = (ParameterizedType) type;
+ Type[] types = parameterizedType.getActualTypeArguments();
+
+ if (types != null && types.length != 0) {
+ Type actualType = types[0];
+
+ if (actualType instanceof Class) {
+ result = (Class<?>) actualType;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private Class<?> getGenericContainerClass(PropertyDescriptor pd) {
+ if (pd == null) {
+ return null;
+ }
+
+ Method readMethod = pd.getReadMethod();
+ if (readMethod == null) {
+ return null;
+ }
+
+ return resolveType(readMethod.getGenericReturnType());
+ }
+
+ private PropertyDescriptor getPropertyDescriptor(String propertyName) {
+ BeanInfo beanInfo = null;
+ try {
+ beanInfo = Introspector.getBeanInfo(beanClass);
+ } catch (IntrospectionException e) {
+ throw new FacesException(e.getMessage(), e);
+ } finally {
+ Introspector.flushFromCaches(beanClass);
+ }
+
+ if (beanInfo == null) {
+ return null;
+ }
+
+ PropertyDescriptor[] propertyDescriptorsArray =
beanInfo.getPropertyDescriptors();
+ for (PropertyDescriptor pd : propertyDescriptorsArray) {
+ if (propertyName.equals(pd.getName())) {
+ return pd;
+ }
+ }
+
+ return null;
+ }
+
+ public Class<?> getContainerClass(String propertyName) {
+ return containerClassesMap.get(propertyName);
+ }
+
+ }
+
+ private final Map<Class<?>, GenericsCacheEntry> cache = new
MapMaker().weakKeys().softValues().makeComputingMap(new Function<Class<?>,
GenericsCacheEntry>() {
+ public GenericsCacheEntry apply(java.lang.Class<?> input) {
+ return new GenericsCacheEntry(input);
+ };
+ });
+
+ private Class<?> getGenericCollectionType(FacesContext context, Object base,
String propertyName) {
+ Class<?> genericPropertyClass = null;
+
+ if ((base != null) && (propertyName != null)) {
+ Class<? extends Object> beanClass = base.getClass();
+
+ // Map and ResourceBundle have special resolvers that we doesn't support
+ if (!Map.class.isAssignableFrom(beanClass) &&
!ResourceBundle.class.isAssignableFrom(beanClass)) {
+ return cache.get(beanClass).getContainerClass(propertyName);
+ }
+ }
+
+ return genericPropertyClass;
+ }
+
+ public Class<?> getContainerClass(FacesContext facesContext, ValueExpression
expression) {
+ ELContext initialELContext = facesContext.getELContext();
+ CapturingELResolver capturingELResolver = new
CapturingELResolver(initialELContext.getELResolver());
+ Class<?> type = expression.getType(new ELContextWrapper(initialELContext,
capturingELResolver));
+ Class<?> containerType = type.getComponentType();
+
+ if ((containerType == null) && (type != null)) {
+ if (Collection.class.isAssignableFrom(type)) {
+ Object base = capturingELResolver.getBase();
+ Object property = capturingELResolver.getProperty();
+
+ if ((base != null) && (property != null)) {
+ containerType = getGenericCollectionType(facesContext, base,
property.toString());
+ }
+ }
+ }
+
+ return containerType;
+ }
+
+}
Modified:
trunk/ui/input/ui/src/main/java/org/richfaces/component/AbstractAutocomplete.java
===================================================================
---
trunk/ui/input/ui/src/main/java/org/richfaces/component/AbstractAutocomplete.java 2010-12-23
17:32:10 UTC (rev 20787)
+++
trunk/ui/input/ui/src/main/java/org/richfaces/component/AbstractAutocomplete.java 2010-12-23
19:24:00 UTC (rev 20788)
@@ -34,6 +34,7 @@
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
+import org.richfaces.application.ServiceTracker;
import org.richfaces.cdk.annotations.Attribute;
import org.richfaces.cdk.annotations.EventName;
import org.richfaces.cdk.annotations.JsfComponent;
@@ -43,7 +44,7 @@
import org.richfaces.cdk.annotations.TagType;
import org.richfaces.context.ExtendedVisitContext;
import org.richfaces.context.ExtendedVisitContextMode;
-import org.richfaces.el.util.ELUtils;
+import org.richfaces.el.GenericsIntrospectionService;
import org.richfaces.renderkit.MetaComponentRenderer;
/**
@@ -221,7 +222,7 @@
ValueExpression expression = this.getValueExpression("value");
if (expression != null) {
- Class<?> containerClass = ELUtils.getContainerClass(context,
expression);
+ Class<?> containerClass = ServiceTracker.getService(context,
GenericsIntrospectionService.class).getContainerClass(context, expression);
converter = getConverterForType(context, containerClass);
}