This is an automated email from the ASF dual-hosted git repository.
tandraschko pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/openwebbeans.git
The following commit(s) were added to refs/heads/main by this push:
new 6cac859c6 OWB-1436
org.apache.webbeans.el22.WrappedValueExpressionNode'does not have the property
'xxx'
6cac859c6 is described below
commit 6cac859c6194d9a8a7eba9d382b2c4cf75537f54
Author: Thomas Andraschko <[email protected]>
AuthorDate: Tue Jan 9 13:58:11 2024 +0100
OWB-1436 org.apache.webbeans.el22.WrappedValueExpressionNode'does not have
the property 'xxx'
---
.../apache/webbeans/el22/WebBeansELResolver.java | 63 +++++++----
.../apache/webbeans/el/test/DotNamedBeansTest.java | 119 ++++++++++++++++++++-
2 files changed, 154 insertions(+), 28 deletions(-)
diff --git
a/webbeans-el22/src/main/java/org/apache/webbeans/el22/WebBeansELResolver.java
b/webbeans-el22/src/main/java/org/apache/webbeans/el22/WebBeansELResolver.java
index c4dc5622f..6c6510bc1 100644
---
a/webbeans-el22/src/main/java/org/apache/webbeans/el22/WebBeansELResolver.java
+++
b/webbeans-el22/src/main/java/org/apache/webbeans/el22/WebBeansELResolver.java
@@ -18,21 +18,22 @@
*/
package org.apache.webbeans.el22;
-import org.apache.webbeans.component.OwbBean;
-import org.apache.webbeans.config.WebBeansContext;
-import org.apache.webbeans.container.BeanManagerImpl;
-import org.apache.webbeans.el.ELContextStore;
-
import jakarta.el.ELContext;
import jakarta.el.ELException;
import jakarta.el.ELResolver;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.context.spi.CreationalContext;
import jakarta.enterprise.inject.spi.Bean;
+import org.apache.webbeans.component.OwbBean;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.container.BeanManagerImpl;
+import org.apache.webbeans.el.ELContextStore;
+
import java.beans.FeatureDescriptor;
import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
import java.util.stream.Collectors;
/**
@@ -55,17 +56,19 @@ import java.util.stream.Collectors;
public class WebBeansELResolver extends ELResolver
{
private final WebBeansContext webBeansContext;
+ private Set<String> dotNamedBeansNegativeCache;
public WebBeansELResolver()
{
webBeansContext = WebBeansContext.getInstance();
+ dotNamedBeansNegativeCache = new CopyOnWriteArraySet<>();
}
/**
* {@inheritDoc}
*/
@Override
- public Class<?> getCommonPropertyType(ELContext arg0, Object arg1)
+ public Class<?> getCommonPropertyType(ELContext context, Object base)
{
return null;
}
@@ -74,7 +77,7 @@ public class WebBeansELResolver extends ELResolver
* {@inheritDoc}
*/
@Override
- public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext arg0,
Object arg1)
+ public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext
context, Object base)
{
return null;
}
@@ -83,7 +86,7 @@ public class WebBeansELResolver extends ELResolver
* {@inheritDoc}
*/
@Override
- public Class<?> getType(ELContext arg0, Object arg1, Object arg2) throws
ELException
+ public Class<?> getType(ELContext context, Object base, Object property)
throws ELException
{
return null;
}
@@ -95,9 +98,15 @@ public class WebBeansELResolver extends ELResolver
@SuppressWarnings({"unchecked","deprecation"})
public Object getValue(ELContext context, Object base, Object property)
throws ELException
{
- final BeanManagerImpl beanManager =
webBeansContext.getBeanManagerImpl();
+ // we only check root beans
+ // or if its wrapped because of dot-names
+ if (base != null && !(base instanceof WrappedValueExpressionNode))
+ {
+ return null;
+ }
// Check if the OWB actually got used in this application
+ final BeanManagerImpl beanManager =
webBeansContext.getBeanManagerImpl();
if (!beanManager.isInUse())
{
return null;
@@ -160,25 +169,33 @@ public class WebBeansELResolver extends ELResolver
private Object findDottedName(final ELContext context, final Object base,
final BeanManagerImpl beanManager,
final ELContextStore elContextStore, final
String beanName)
{
-
final String fqBeanName = base == null ? beanName : base + "." +
beanName;
+ if (dotNamedBeansNegativeCache.contains(fqBeanName))
+ {
+ return null;
+ }
+
final Set<Bean<?>> anyBeanName = beanManager.getBeans().stream()
- .filter(b -> b.getName()
!= null)
- .filter(b ->
b.getName().startsWith(fqBeanName))
-
.collect(Collectors.toSet());
+ .filter(b -> b.getName() != null)
+ .filter(b -> b.getName().equals(fqBeanName) ||
b.getName().startsWith(fqBeanName + "."))
+ .collect(Collectors.toSet());
- // looks like a good candidate
- if (anyBeanName.size() == 1 &&
fqBeanName.equals(anyBeanName.iterator().next().getName()))
+ // no exact and no startsWith match
+ if (anyBeanName.isEmpty())
{
- return getBeanWithScope(context, beanManager, beanName,
elContextStore, anyBeanName);
+ dotNamedBeansNegativeCache.add(fqBeanName);
+ return null;
}
- // more than one bean with the same beginning or name not matching
- else if (!anyBeanName.isEmpty())
+
+ // exact match
+ if (anyBeanName.size() == 1 &&
fqBeanName.equals(anyBeanName.iterator().next().getName()))
{
- context.setPropertyResolved(true);
- return new WrappedValueExpressionNode(fqBeanName);
+ return getBeanWithScope(context, beanManager, fqBeanName,
elContextStore, anyBeanName);
}
- return null;
+
+ // more than one bean with the same beginning
+ context.setPropertyResolved(true);
+ return new WrappedValueExpressionNode(fqBeanName);
}
protected Object getNormalScopedContextualInstance(BeanManagerImpl
manager, ELContextStore store, ELContext context,
@@ -242,7 +259,7 @@ public class WebBeansELResolver extends ELResolver
* {@inheritDoc}
*/
@Override
- public boolean isReadOnly(ELContext arg0, Object arg1, Object arg2) throws
ELException
+ public boolean isReadOnly(ELContext context, Object base, Object property)
throws ELException
{
return false;
}
@@ -251,7 +268,7 @@ public class WebBeansELResolver extends ELResolver
* {@inheritDoc}
*/
@Override
- public void setValue(ELContext arg0, Object arg1, Object arg2, Object
arg3) throws ELException
+ public void setValue(ELContext context, Object base, Object property,
Object value) throws ELException
{
}
diff --git
a/webbeans-el22/src/test/java/org/apache/webbeans/el/test/DotNamedBeansTest.java
b/webbeans-el22/src/test/java/org/apache/webbeans/el/test/DotNamedBeansTest.java
index 638d7a5bb..276f71413 100644
---
a/webbeans-el22/src/test/java/org/apache/webbeans/el/test/DotNamedBeansTest.java
+++
b/webbeans-el22/src/test/java/org/apache/webbeans/el/test/DotNamedBeansTest.java
@@ -18,16 +18,25 @@
*/
package org.apache.webbeans.el.test;
+import jakarta.el.ArrayELResolver;
+import jakarta.el.BeanELResolver;
+import jakarta.el.CompositeELResolver;
import jakarta.el.ELContext;
import jakarta.el.ELResolver;
import jakarta.el.FunctionMapper;
+import jakarta.el.ListELResolver;
+import jakarta.el.MapELResolver;
import jakarta.el.PropertyNotFoundException;
+import jakarta.el.StaticFieldELResolver;
import jakarta.el.ValueExpression;
import jakarta.el.VariableMapper;
import jakarta.enterprise.context.Dependent;
+import jakarta.enterprise.context.RequestScoped;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.inject.Named;
import org.apache.el.ExpressionFactoryImpl;
+import org.apache.el.lang.FunctionMapperImpl;
+import org.apache.el.lang.VariableMapperImpl;
import org.apache.webbeans.el22.WrappedExpressionFactory;
import org.apache.webbeans.el22.WrappedValueExpressionNode;
import org.apache.webbeans.exception.WebBeansConfigurationException;
@@ -99,6 +108,49 @@ public class DotNamedBeansTest extends AbstractUnitTest
shutDownContainer();
}
+ @Test
+ public void testNonDottedChildren() throws Exception
+ {
+ Collection<Class<?>> classes = new ArrayList<Class<?>>();
+
+ classes.add(Dogs.class);
+ classes.add(Dog.class);
+ classes.add(BlueGoldenFish.class);
+ classes.add(GoldenFish.class);
+
+ startContainer(classes);
+
+ Dog dog = evaluateValueExpression(getBeanManager(), "#{dog}",
Dog.class);
+ dog.setParent(new Parent());
+ dog.getParent().setName("Hans");
+
+ String parentName = evaluateValueExpression(getBeanManager(),
"#{dog.parent.name}", String.class);
+ Assert.assertEquals("Hans", parentName);
+
+ shutDownContainer();
+ }
+
+ @Test
+ public void testChildren() throws Exception
+ {
+ Collection<Class<?>> classes = new ArrayList<Class<?>>();
+
+ classes.add(Dog.class);
+ classes.add(BlueGoldenFish.class);
+ classes.add(GoldenFish.class);
+
+ startContainer(classes);
+
+ GoldenFish goldenFish = evaluateValueExpression(getBeanManager(),
"#{magic.golden.fish}", GoldenFish.class);
+ goldenFish.setParent(new Parent());
+ goldenFish.getParent().setName("Hans");
+
+ String parentName = evaluateValueExpression(getBeanManager(),
"#{magic.golden.fish.parent.name}", String.class);
+ Assert.assertEquals("Hans", parentName);
+
+ shutDownContainer();
+ }
+
@Test(expected = WebBeansConfigurationException.class)
public void testConflictingName() throws Exception
{
@@ -146,19 +198,41 @@ public class DotNamedBeansTest extends AbstractUnitTest
final WrappedExpressionFactory wrappedExpressionFactory = new
WrappedExpressionFactory(new ExpressionFactoryImpl());
final ELContext elContext = new ELContext() {
+ private CompositeELResolver elResolver;
+ private FunctionMapper functionMapper;
+ private VariableMapper variableMapper;
+
@Override
public ELResolver getELResolver() {
- return beanManager.getELResolver();
+ if (elResolver == null)
+ {
+ elResolver = new CompositeELResolver();
+ elResolver.add(beanManager.getELResolver());
+ elResolver.add(new StaticFieldELResolver());
+ elResolver.add(new MapELResolver());
+ elResolver.add(new ListELResolver());
+ elResolver.add(new ArrayELResolver());
+ elResolver.add(new BeanELResolver());
+ }
+ return elResolver;
}
@Override
public FunctionMapper getFunctionMapper() {
- return null;
+ if (functionMapper == null)
+ {
+ functionMapper = new FunctionMapperImpl();
+ }
+ return functionMapper;
}
@Override
public VariableMapper getVariableMapper() {
- return null;
+ if (variableMapper == null)
+ {
+ variableMapper = new VariableMapperImpl();
+ }
+ return variableMapper;
}
};
final ValueExpression valueExpression =
wrappedExpressionFactory.createValueExpression(elContext, expression,
expectedType);
@@ -168,8 +242,17 @@ public class DotNamedBeansTest extends AbstractUnitTest
}
@Named("magic.golden.fish")
- @Dependent
+ @RequestScoped
public static class GoldenFish {
+ private Parent parent;
+
+ public Parent getParent() {
+ return parent;
+ }
+
+ public void setParent(Parent parent) {
+ this.parent = parent;
+ }
}
@Named("magic.golden")
@@ -182,9 +265,35 @@ public class DotNamedBeansTest extends AbstractUnitTest
public static class BlueGoldenFish {
}
+ @Named("dogs")
+ @RequestScoped
+ public static class Dogs {
+
+ }
+
@Named("dog")
- @Dependent
+ @RequestScoped
public static class Dog {
+ private Parent parent;
+
+ public Parent getParent() {
+ return parent;
+ }
+
+ public void setParent(Parent parent) {
+ this.parent = parent;
+ }
}
+ public static class Parent {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
}