LGTM :)

On Fri, 4 Jun 2021 at 19:47, Martin Grigorov <mgrigo...@apache.org> wrote:

> The other day while working on s/SpringBean/Inject/ I've faced a problem in
> org.apache.wicket.spring.SpringBeanLocator#getBeanDefinition() - it failed
> with ClassCastException that ApplicationContextMock is not an
> AbstractApplicationContext
>
> What do you think about this change ?
> It allows to implement almost all methods in ApplicationContextMock and to
> use it here [1] and here [2]
>
> 1.
>
> https://github.com/apache/wicket/blob/67165d1820d247286f5c12c1755fe11424a74046/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java#L233
> 2.
>
> https://github.com/apache/wicket/blob/67165d1820d247286f5c12c1755fe11424a74046/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java#L252
>
> On Fri, Jun 4, 2021 at 3:42 PM <mgrigo...@apache.org> wrote:
>
> > This is an automated email from the ASF dual-hosted git repository.
> >
> > mgrigorov pushed a commit to branch
> > make-spring-applicationcontextmock-smarter
> > in repository https://gitbox.apache.org/repos/asf/wicket.git
> >
> > commit 7839f8887184f5c19767c8e9b31d79dd896d45d1
> > Author: Martin Tzvetanov Grigorov <mgrigo...@apache.org>
> > AuthorDate: Fri Jun 4 15:36:06 2021 +0300
> >
> >     Use DefaultListableBeanFactory as a delegate in
> ApplicationContextMock
> >
> >     This way ApplicationContextMock could provide implementation for more
> > of its methods and more importantly
> SpringBeanLocation#getBeanDefinition()
> > [1] could work with it, also two more places in
> > org.apache.wicket.spring.injection.annot.AnnotProxyFieldValueFactory will
> > use it
> >
> >     1.
> >
> https://github.com/apache/wicket/blob/8d44c5b5094cccc9d5e05408e42ccc1bd0dd4da6/wicket-spring/src/main/java/org/apache/wicket/spring/SpringBeanLocator.java#L421
> > ---
> >  .../wicket/spring/test/ApplicationContextMock.java | 235
> > +++++----------------
> >  1 file changed, 57 insertions(+), 178 deletions(-)
> >
> > diff --git
> >
> a/wicket-spring/src/main/java/org/apache/wicket/spring/test/ApplicationContextMock.java
> >
> b/wicket-spring/src/main/java/org/apache/wicket/spring/test/ApplicationContextMock.java
> > index 5d285f7..d5a83f8 100644
> > ---
> >
> a/wicket-spring/src/main/java/org/apache/wicket/spring/test/ApplicationContextMock.java
> > +++
> >
> b/wicket-spring/src/main/java/org/apache/wicket/spring/test/ApplicationContextMock.java
> > @@ -19,45 +19,44 @@ package org.apache.wicket.spring.test;
> >  import java.io.IOException;
> >  import java.io.Serializable;
> >  import java.lang.annotation.Annotation;
> > -import java.util.ArrayList;
> > -import java.util.HashMap;
> > -import java.util.Iterator;
> >  import java.util.Locale;
> >  import java.util.Map;
> > -import java.util.Map.Entry;
> >
> >  import org.springframework.beans.BeansException;
> >  import org.springframework.beans.factory.BeanFactory;
> > -import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
> > -import org.springframework.beans.factory.FactoryBean;
> >  import org.springframework.beans.factory.NoSuchBeanDefinitionException;
> >  import org.springframework.beans.factory.ObjectProvider;
> >  import
> > org.springframework.beans.factory.config.AutowireCapableBeanFactory;
> > +import
> > org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
> > +import
> > org.springframework.beans.factory.support.DefaultListableBeanFactory;
> > +import org.springframework.beans.factory.support.RootBeanDefinition;
> >  import org.springframework.context.ApplicationContext;
> >  import org.springframework.context.ApplicationEvent;
> >  import org.springframework.context.MessageSourceResolvable;
> >  import org.springframework.context.NoSuchMessageException;
> > +import org.springframework.context.support.AbstractApplicationContext;
> >  import org.springframework.core.ResolvableType;
> > -import org.springframework.core.env.Environment;
> >  import org.springframework.core.io.Resource;
> >
> >  /**
> >   * Mock application context object. This mock context allows easy
> > creation of unit tests by allowing
> >   * the user to put bean instances into the context.
> >   *
> > - * Only {@link #getBean(String)}, {@link #getBean(String, Class)}, and
> > - * {@link #getBeansOfType(Class)
> > - * } are implemented so far. Any other method throws
> > - * {@link UnsupportedOperationException}.
> > - *
> >   * @author Igor Vaynberg (ivaynberg)
> >   *
> >   */
> > -public class ApplicationContextMock implements ApplicationContext,
> > Serializable
> > +public class ApplicationContextMock extends AbstractApplicationContext
> > implements Serializable
> >  {
> >         private static final long serialVersionUID = 1L;
> >
> > -       private final Map<String, Object> beans = new HashMap<>();
> > +       private final DefaultListableBeanFactory beanFactory;
> > +       private final long startupTime;
> > +
> > +       public ApplicationContextMock() {
> > +               this.beanFactory = new DefaultListableBeanFactory();
> > +
> >  beanFactory.setSerializationId(ApplicationContextMock.class.getName());
> > +               startupTime = System.currentTimeMillis();
> > +       }
> >
> >         /**
> >          * puts bean with the given name into the context
> > @@ -65,14 +64,9 @@ public class ApplicationContextMock implements
> > ApplicationContext, Serializable
> >          * @param name
> >          * @param bean
> >          */
> > -       public void putBean(final String name, final Object bean)
> > +       public <T extends Object> void putBean(final String name, final T
> > bean)
> >         {
> > -               if (beans.containsKey(name))
> > -               {
> > -                       throw new IllegalArgumentException("a bean with
> > name [" + name +
> > -                               "] has already been added to the
> context");
> > -               }
> > -               beans.put(name, bean);
> > +               beanFactory.registerBeanDefinition(name, new
> > RootBeanDefinition((Class<T>)bean.getClass(), () -> bean));
> >         }
> >
> >         /**
> > @@ -88,159 +82,82 @@ public class ApplicationContextMock implements
> > ApplicationContext, Serializable
> >         @Override
> >         public Object getBean(final String name) throws BeansException
> >         {
> > -               Object bean = beans.get(name);
> > -               if (bean == null)
> > -               {
> > -                       throw new NoSuchBeanDefinitionException(name);
> > -               }
> > -               return bean;
> > +               return beanFactory.getBean(name);
> >         }
> >
> >         @Override
> >         public Object getBean(final String name, final Object... args)
> > throws BeansException
> >         {
> > -               return getBean(name);
> > +               return beanFactory.getBean(name, args);
> >         }
> >
> > -       /**
> > -        * @see
> > org.springframework.beans.factory.BeanFactory#getBean(java.lang.String,
> > java.lang.Class)
> > -        */
> >         @Override
> >         @SuppressWarnings({ "unchecked" })
> >         public <T> T getBean(String name, Class<T> requiredType) throws
> > BeansException
> >         {
> > -               Object bean = getBean(name);
> > -               if (!(requiredType.isAssignableFrom(bean.getClass())))
> > -               {
> > -                       throw new BeanNotOfRequiredTypeException(name,
> > requiredType, bean.getClass());
> > -               }
> > -               return (T)bean;
> > +               return beanFactory.getBean(name, requiredType);
> >         }
> >
> > -       /**
> > -        * @see
> >
> org.springframework.beans.factory.ListableBeanFactory#getBeansOfType(java.lang.Class)
> > -        */
> >         @Override
> >         @SuppressWarnings({ "unchecked" })
> >         public <T> Map<String, T> getBeansOfType(Class<T> type) throws
> > BeansException
> >         {
> > -               final Map<String, T> found = new HashMap<>();
> > -
> > -               for (Entry<String, Object> entry : beans.entrySet())
> > -               {
> > -                       if
> > (type.isAssignableFrom(entry.getValue().getClass()))
> > -                       {
> > -                               found.put(entry.getKey(),
> > (T)entry.getValue());
> > -                       }
> > -               }
> > -
> > -               return found;
> > +               return beanFactory.getBeansOfType(type);
> >         }
> >
> >         @Override
> >         public <T> T getBean(Class<T> requiredType) throws BeansException
> >         {
> > -               Iterator<T> beans =
> > getBeansOfType(requiredType).values().iterator();
> > -
> > -               if (beans.hasNext() == false)
> > -               {
> > -                       throw new NoSuchBeanDefinitionException("bean of
> > required type " + requiredType +
> > -                               " not found");
> > -               }
> > -               final T bean = beans.next();
> > -
> > -               if (beans.hasNext() != false)
> > -               {
> > -                       throw new NoSuchBeanDefinitionException("more
> than
> > one bean of required type " +
> > -                               requiredType + " found");
> > -               }
> > -               return bean;
> > +               return beanFactory.getBean(requiredType);
> >         }
> >
> >         @Override
> >         public <T> T getBean(Class<T> requiredType, Object... objects)
> > throws BeansException
> >         {
> > -               return getBean(requiredType);
> > +               return beanFactory.getBean(requiredType, objects);
> >         }
> >
> >         @Override
> >         public <T> ObjectProvider<T> getBeanProvider(Class<T> aClass)
> >         {
> > -               return null;
> > +               return beanFactory.getBeanProvider(aClass);
> >         }
> >
> >         @Override
> >         public <T> ObjectProvider<T> getBeanProvider(ResolvableType
> > resolvableType)
> >         {
> > -               return null;
> > +               return beanFactory.getBeanProvider(resolvableType);
> >         }
> >
> >         @Override
> >         public Map<String, Object> getBeansWithAnnotation(Class<? extends
> > Annotation> annotationType)
> >                 throws BeansException
> >         {
> > -               final Map<String, Object> found = new HashMap<>();
> > -
> > -               for (Entry<String, Object> entry : beans.entrySet())
> > -               {
> > -                       if
> > (entry.getValue().getClass().isAnnotationPresent(annotationType))
> > -                       {
> > -                               found.put(entry.getKey(),
> > entry.getValue());
> > -                       }
> > -               }
> > -               return found;
> > +               return
> beanFactory.getBeansWithAnnotation(annotationType);
> >         }
> >
> >         @Override
> >         public <A extends Annotation> A findAnnotationOnBean(String
> > beanName, Class<A> annotationType)
> >         {
> > -               return
> findAnnotationOnClass(getBean(beanName).getClass(),
> > annotationType);
> > -       }
> > -
> > -       private <A extends Annotation> A findAnnotationOnClass(Class<?>
> > cls, Class<A> annotationType)
> > -       {
> > -               // lookup annotation type on class
> > -               A annotation = cls.getAnnotation(annotationType);
> > -
> > -               // lookup annotation type on superclass
> > -               if (annotation == null && cls.getSuperclass() != null)
> > -               {
> > -                       annotation =
> > findAnnotationOnClass(cls.getSuperclass(), annotationType);
> > -               }
> > -
> > -               // lookup annotation type on interfaces
> > -               if (annotation == null)
> > -               {
> > -                       for (Class<?> intfClass : cls.getInterfaces())
> > -                       {
> > -                               annotation =
> > findAnnotationOnClass(intfClass, annotationType);
> > -
> > -                               if (annotation != null)
> > -                               {
> > -                                       break;
> > -                               }
> > -                       }
> > -               }
> > -
> > -               return annotation;
> > +               return beanFactory.findAnnotationOnBean(beanName,
> > annotationType);
> >         }
> >
> >         @Override
> >         public ApplicationContext getParent()
> >         {
> > -               throw new UnsupportedOperationException();
> > +               return null;
> >         }
> >
> >         @Override
> >         public String getDisplayName()
> >         {
> > -               throw new UnsupportedOperationException();
> > +               return ApplicationContextMock.class.getSimpleName();
> >         }
> >
> >         @Override
> >         public long getStartupDate()
> >         {
> > -               throw new UnsupportedOperationException();
> > +               return startupTime;
> >         }
> >
> >         @Override
> > @@ -258,129 +175,103 @@ public class ApplicationContextMock implements
> > ApplicationContext, Serializable
> >         @Override
> >         public boolean containsBeanDefinition(final String beanName)
> >         {
> > -               return containsBean(beanName);
> > +               return beanFactory.containsBean(beanName);
> >         }
> >
> >         @Override
> >         public int getBeanDefinitionCount()
> >         {
> > -               return beans.size();
> > +               return beanFactory.getBeanDefinitionCount();
> >         }
> >
> >         @Override
> >         public String[] getBeanDefinitionNames()
> >         {
> > -               return beans.keySet().toArray(new String[0]);
> > +               return beanFactory.getBeanDefinitionNames();
> >         }
> >
> >         @Override
> >         public <T> ObjectProvider<T> getBeanProvider(final Class<T>
> > aClass, final boolean b) {
> > -               return null;
> > +               return beanFactory.getBeanProvider(aClass, b);
> >         }
> >
> >         @Override
> >         public <T> ObjectProvider<T> getBeanProvider(final ResolvableType
> > resolvableType, final boolean b) {
> > -               return null;
> > +               return beanFactory.getBeanProvider(resolvableType, b);
> >         }
> >
> >         @Override
> >         public String[] getBeanNamesForType(ResolvableType
> resolvableType)
> >         {
> > -               return new String[0];
> > +               return beanFactory.getBeanNamesForType(resolvableType);
> >         }
> >
> >         @Override
> >         public String[] getBeanNamesForType(ResolvableType
> resolvableType,
> > boolean includeNonSingletons, boolean allowEagerInit)
> >         {
> > -               return new String[0];
> > +               return beanFactory.getBeanNamesForType(resolvableType,
> > includeNonSingletons, allowEagerInit);
> >         }
> >
> >         @Override
> > -       @SuppressWarnings({ "unchecked" })
> >         public String[] getBeanNamesForType(final Class type)
> >         {
> > -               ArrayList<String> names = new ArrayList<>();
> > -               for (Entry<String, Object> entry : beans.entrySet())
> > -               {
> > -                       Object bean = entry.getValue();
> > -
> > -                       if (type.isAssignableFrom(bean.getClass()))
> > -                       {
> > -                               names.add(entry.getKey());
> > -                       }
> > -               }
> > -               return names.toArray(new String[names.size()]);
> > +               return beanFactory.getBeanNamesForType(type);
> >         }
> >
> >         @Override
> > -       @SuppressWarnings({ "unchecked" })
> >         public String[] getBeanNamesForType(Class type, boolean
> > includeNonSingletons,
> >                 boolean allowEagerInit)
> >         {
> > -               throw new UnsupportedOperationException();
> > +               return beanFactory.getBeanNamesForType(type,
> > includeNonSingletons, allowEagerInit);
> >         }
> >
> >         @Override
> >         public <T> Map<String, T> getBeansOfType(Class<T> type, boolean
> > includeNonSingletons,
> >                 boolean allowEagerInit) throws BeansException
> >         {
> > -               throw new UnsupportedOperationException();
> > +               return beanFactory.getBeansOfType(type,
> > includeNonSingletons, allowEagerInit);
> >         }
> >
> >         @Override
> >         public String[] getBeanNamesForAnnotation(Class<? extends
> > Annotation> aClass)
> >         {
> > -               throw new UnsupportedOperationException();
> > +               return beanFactory.getBeanNamesForAnnotation(aClass);
> >         }
> >
> >         @Override
> >         public boolean containsBean(final String name)
> >         {
> > -               return beans.containsKey(name);
> > +               return beanFactory.containsBean(name);
> >         }
> >
> >         @Override
> >         public boolean isSingleton(final String name) throws
> > NoSuchBeanDefinitionException
> >         {
> > -               return true;
> > +               return beanFactory.isSingleton(name);
> >         }
> >
> >         @Override
> >         public Class<?> getType(final String name) throws
> > NoSuchBeanDefinitionException
> >         {
> > -               return getType(name, true);
> > +               return beanFactory.getType(name);
> >         }
> >
> >         @Override
> >         public Class<?> getType(String name, boolean
> allowFactoryBeanInit)
> > throws NoSuchBeanDefinitionException
> >         {
> > -               Object bean = beans.get(name);
> > -               if (bean == null)
> > -               {
> > -                       throw new NoSuchBeanDefinitionException("No bean
> > with name '" + name + "'");
> > -               }
> > -
> > -               if (bean instanceof FactoryBean)
> > -               {
> > -                       return ((FactoryBean) bean).getObjectType();
> > -               }
> > -
> > -               return bean.getClass();
> > +               return beanFactory.getType(name, allowFactoryBeanInit);
> >         }
> >
> >         @Override
> >         public String[] getAliases(final String name) throws
> > NoSuchBeanDefinitionException
> >         {
> > -               throw new UnsupportedOperationException();
> > +               return beanFactory.getAliases(name);
> >         }
> >
> > -       /**
> > -        * @see
> org.springframework.beans.factory.HierarchicalBeanFactory#
> > getParentBeanFactory()
> > -        */
> >         @Override
> >         public BeanFactory getParentBeanFactory()
> >         {
> > -               return null;
> > +               return beanFactory.getParentBeanFactory();
> >         }
> >
> >         @Override
> > @@ -411,64 +302,52 @@ public class ApplicationContextMock implements
> > ApplicationContext, Serializable
> >         }
> >
> >         @Override
> > -       public Resource getResource(final String location)
> > -       {
> > -               throw new UnsupportedOperationException();
> > +       protected void refreshBeanFactory() throws BeansException,
> > IllegalStateException {
> >         }
> >
> >         @Override
> > -       public AutowireCapableBeanFactory getAutowireCapableBeanFactory()
> > throws IllegalStateException
> > -       {
> > -               throw new UnsupportedOperationException();
> > +       protected void closeBeanFactory() {
> >         }
> >
> >         @Override
> > -       public boolean containsLocalBean(final String arg0)
> > -       {
> > -               throw new UnsupportedOperationException();
> > +       public ConfigurableListableBeanFactory getBeanFactory() throws
> > IllegalStateException {
> > +               return beanFactory;
> >         }
> >
> >         @Override
> > -       public ClassLoader getClassLoader()
> > +       public Resource getResource(final String location)
> >         {
> >                 throw new UnsupportedOperationException();
> >         }
> >
> >         @Override
> > -       public String getId()
> > +       public AutowireCapableBeanFactory getAutowireCapableBeanFactory()
> > throws IllegalStateException
> >         {
> > -               return null;
> > +               return beanFactory;
> >         }
> >
> >         @Override
> > -       public String getApplicationName()
> > +       public boolean containsLocalBean(final String name)
> >         {
> > -               return "";
> > +               return beanFactory.containsLocalBean(name);
> >         }
> >
> >         @Override
> >         public boolean isPrototype(final String name) throws
> > NoSuchBeanDefinitionException
> >         {
> > -               return !isSingleton(name);
> > +               return beanFactory.isPrototype(name);
> >         }
> >
> >         @Override
> >         public boolean isTypeMatch(String s, ResolvableType
> > resolvableType) throws NoSuchBeanDefinitionException
> >         {
> > -               return false;
> > +               return beanFactory.isTypeMatch(s, resolvableType);
> >         }
> >
> >         @Override
> > -       @SuppressWarnings({ "unchecked" })
> >         public boolean isTypeMatch(final String name, final Class
> > targetType)
> >                 throws NoSuchBeanDefinitionException
> >         {
> > -               throw new UnsupportedOperationException();
> > -       }
> > -
> > -       @Override
> > -       public Environment getEnvironment()
> > -       {
> > -               return null;
> > +               return beanFactory.isTypeMatch(name, targetType);
> >         }
> >  }
> >
>


-- 
Best regards,
Maxim

Reply via email to