Search in sources :

Example 11 with PropertyAccessor

use of org.springframework.expression.PropertyAccessor in project spring-cloud-stream by spring-cloud.

the class SpelExpressionConverterConfigurationTests method converterCorrectlyInstalled.

@Test
@SuppressWarnings("unchecked")
public void converterCorrectlyInstalled() {
    Expression expression = pojo.getExpression();
    assertThat(expression.getValue("{\"a\": {\"b\": 5}}").toString()).isEqualTo("5");
    List<PropertyAccessor> propertyAccessors = TestUtils.getPropertyValue(this.evaluationContext, "propertyAccessors", List.class);
    assertThat(propertyAccessors).hasAtLeastOneElementOfType(JsonPropertyAccessor.class);
    propertyAccessors = TestUtils.getPropertyValue(this.config.evaluationContext, "propertyAccessors", List.class);
    assertThat(propertyAccessors).hasAtLeastOneElementOfType(JsonPropertyAccessor.class);
}
Also used : JsonPropertyAccessor(org.springframework.integration.json.JsonPropertyAccessor) PropertyAccessor(org.springframework.expression.PropertyAccessor) Expression(org.springframework.expression.Expression) List(java.util.List) Test(org.junit.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest)

Example 12 with PropertyAccessor

use of org.springframework.expression.PropertyAccessor in project spring-integration by spring-projects.

the class ParentContextTests method testSpelBeanReferencesInChildAndParent.

/**
 * Verifies that beans in hierarchical contexts get an evaluation context that has the proper
 * BeanResolver. Verifies that the two Foos in the parent context get an evaluation context
 * with the same bean resolver. Verifies that the one Foo in the child context gets a different
 * bean resolver. Verifies that bean references in SpEL expressions to beans in the child
 * and parent contexts work. Verifies that PropertyAccessors are inherited in the child context
 * and the parent's ones are last in the propertyAccessors list of EvaluationContext.
 * Verifies that SpEL functions are inherited from parent context and overridden with the same 'id'.
 * Verifies that child and parent contexts can have different message builders.
 * <p>
 * Only single test method is allowed for 'ParentContext-context.xml',
 * since it relies on static 'evalContexts' variable.
 */
@Test
@SuppressWarnings("unchecked")
public void testSpelBeanReferencesInChildAndParent() throws Exception {
    AbstractApplicationContext parent = new ClassPathXmlApplicationContext("ParentContext-context.xml", this.getClass());
    Object parentEvaluationContextFactoryBean = parent.getBean(IntegrationEvaluationContextFactoryBean.class);
    Map<?, ?> parentFunctions = TestUtils.getPropertyValue(parentEvaluationContextFactoryBean, "functions", Map.class);
    assertEquals(4, parentFunctions.size());
    Object jsonPath = parentFunctions.get("jsonPath");
    assertNotNull(jsonPath);
    assertThat((Method) jsonPath, Matchers.isOneOf(JsonPathUtils.class.getMethods()));
    assertEquals(2, evalContexts.size());
    ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext(parent);
    child.setConfigLocation("org/springframework/integration/expression/ChildContext-context.xml");
    child.refresh();
    Object childEvaluationContextFactoryBean = child.getBean(IntegrationEvaluationContextFactoryBean.class);
    Map<?, ?> childFunctions = TestUtils.getPropertyValue(childEvaluationContextFactoryBean, "functions", Map.class);
    assertEquals(5, childFunctions.size());
    assertTrue(childFunctions.containsKey("barParent"));
    assertTrue(childFunctions.containsKey("fooFunc"));
    jsonPath = childFunctions.get("jsonPath");
    assertNotNull(jsonPath);
    assertThat((Method) jsonPath, Matchers.not(Matchers.isOneOf(JsonPathUtils.class.getMethods())));
    assertEquals(3, evalContexts.size());
    assertSame(evalContexts.get(0).getBeanResolver(), evalContexts.get(1).getBeanResolver());
    List<PropertyAccessor> propertyAccessors = evalContexts.get(0).getPropertyAccessors();
    assertEquals(4, propertyAccessors.size());
    PropertyAccessor parentPropertyAccessorOverride = parent.getBean("jsonPropertyAccessor", PropertyAccessor.class);
    PropertyAccessor parentPropertyAccessor = parent.getBean("parentJsonPropertyAccessor", PropertyAccessor.class);
    assertTrue(propertyAccessors.contains(parentPropertyAccessorOverride));
    assertTrue(propertyAccessors.contains(parentPropertyAccessor));
    assertTrue(propertyAccessors.indexOf(parentPropertyAccessorOverride) > propertyAccessors.indexOf(parentPropertyAccessor));
    Map<String, Object> variables = (Map<String, Object>) TestUtils.getPropertyValue(evalContexts.get(0), "variables");
    assertEquals(4, variables.size());
    assertTrue(variables.containsKey("bar"));
    assertTrue(variables.containsKey("barParent"));
    assertTrue(variables.containsKey("fooFunc"));
    assertTrue(variables.containsKey("jsonPath"));
    assertNotSame(evalContexts.get(1).getBeanResolver(), evalContexts.get(2).getBeanResolver());
    propertyAccessors = evalContexts.get(1).getPropertyAccessors();
    assertEquals(4, propertyAccessors.size());
    assertTrue(propertyAccessors.contains(parentPropertyAccessorOverride));
    variables = (Map<String, Object>) TestUtils.getPropertyValue(evalContexts.get(1), "variables");
    assertEquals(4, variables.size());
    assertTrue(variables.containsKey("bar"));
    assertTrue(variables.containsKey("barParent"));
    assertTrue(variables.containsKey("fooFunc"));
    assertTrue(variables.containsKey("jsonPath"));
    propertyAccessors = evalContexts.get(2).getPropertyAccessors();
    assertEquals(4, propertyAccessors.size());
    PropertyAccessor childPropertyAccessor = child.getBean("jsonPropertyAccessor", PropertyAccessor.class);
    assertTrue(propertyAccessors.contains(childPropertyAccessor));
    assertTrue(propertyAccessors.contains(parentPropertyAccessor));
    assertFalse(propertyAccessors.contains(parentPropertyAccessorOverride));
    assertTrue(propertyAccessors.indexOf(childPropertyAccessor) < propertyAccessors.indexOf(parentPropertyAccessor));
    variables = (Map<String, Object>) TestUtils.getPropertyValue(evalContexts.get(2), "variables");
    assertEquals(5, variables.size());
    assertTrue(variables.containsKey("bar"));
    assertTrue(variables.containsKey("barParent"));
    assertTrue(variables.containsKey("fooFunc"));
    assertTrue(variables.containsKey("barChild"));
    assertTrue(variables.containsKey("jsonPath"));
    // Test transformer expressions
    child.getBean("input", MessageChannel.class).send(new GenericMessage<String>("baz"));
    Message<?> out = child.getBean("output", QueueChannel.class).receive(0);
    assertNotNull(out);
    assertEquals("foobar", out.getPayload());
    child.getBean("parentIn", MessageChannel.class).send(MutableMessageBuilder.withPayload("bar").build());
    out = child.getBean("parentOut", QueueChannel.class).receive(0);
    assertNotNull(out);
    assertThat(out, instanceOf(GenericMessage.class));
    assertEquals("foo", out.getPayload());
    IntegrationEvaluationContextFactoryBean evaluationContextFactoryBean = child.getBean("&" + IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME, IntegrationEvaluationContextFactoryBean.class);
    try {
        evaluationContextFactoryBean.setPropertyAccessors(Collections.<String, PropertyAccessor>emptyMap());
        fail("IllegalArgumentException expected.");
    } catch (Exception e) {
        assertThat(e, Matchers.instanceOf(IllegalArgumentException.class));
    }
    parent.getBean("fromParentToChild", MessageChannel.class).send(new GenericMessage<String>("foo"));
    out = child.getBean("output", QueueChannel.class).receive(0);
    assertNotNull(out);
    assertEquals("org.springframework.integration.support.MutableMessage", out.getClass().getName());
    assertEquals("FOO", out.getPayload());
    assertTrue(parent.containsBean(IntegrationContextUtils.TO_STRING_FRIENDLY_JSON_NODE_TO_STRING_CONVERTER_BEAN_NAME));
    assertTrue(child.containsBean(IntegrationContextUtils.TO_STRING_FRIENDLY_JSON_NODE_TO_STRING_CONVERTER_BEAN_NAME));
    Object converterRegistrar = parent.getBean(IntegrationContextUtils.CONVERTER_REGISTRAR_BEAN_NAME);
    assertNotNull(converterRegistrar);
    Set<?> converters = TestUtils.getPropertyValue(converterRegistrar, "converters", Set.class);
    boolean toStringFriendlyJsonNodeToStringConverterPresent = false;
    for (Object converter : converters) {
        if ("ToStringFriendlyJsonNodeToStringConverter".equals(converter.getClass().getSimpleName())) {
            toStringFriendlyJsonNodeToStringConverterPresent = true;
            break;
        }
    }
    assertTrue(toStringFriendlyJsonNodeToStringConverterPresent);
    MessageChannel input = parent.getBean("testJsonNodeToStringConverterInputChannel", MessageChannel.class);
    PollableChannel output = parent.getBean("testJsonNodeToStringConverterOutputChannel", PollableChannel.class);
    TestPerson person = new TestPerson();
    person.setFirstName("John");
    input.send(new GenericMessage<Object>(person));
    Message<?> result = output.receive(1000);
    assertNotNull(result);
    assertEquals("JOHN", result.getPayload());
    child.close();
    parent.close();
}
Also used : PropertyAccessor(org.springframework.expression.PropertyAccessor) QueueChannel(org.springframework.integration.channel.QueueChannel) JsonPathUtils(org.springframework.integration.json.JsonPathUtils) BeansException(org.springframework.beans.BeansException) GenericMessage(org.springframework.messaging.support.GenericMessage) AbstractApplicationContext(org.springframework.context.support.AbstractApplicationContext) MessageChannel(org.springframework.messaging.MessageChannel) ClassPathXmlApplicationContext(org.springframework.context.support.ClassPathXmlApplicationContext) PollableChannel(org.springframework.messaging.PollableChannel) TestPerson(org.springframework.integration.json.TestPerson) Map(java.util.Map) IntegrationEvaluationContextFactoryBean(org.springframework.integration.config.IntegrationEvaluationContextFactoryBean) Test(org.junit.Test)

Example 13 with PropertyAccessor

use of org.springframework.expression.PropertyAccessor in project spring-integration by spring-projects.

the class IntegrationEvaluationContextFactoryBean method getObject.

@Override
public StandardEvaluationContext getObject() throws Exception {
    StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
    if (this.typeLocator != null) {
        evaluationContext.setTypeLocator(this.typeLocator);
    }
    evaluationContext.setBeanResolver(this.beanResolver);
    evaluationContext.setTypeConverter(getTypeConverter());
    for (PropertyAccessor propertyAccessor : getPropertyAccessors().values()) {
        evaluationContext.addPropertyAccessor(propertyAccessor);
    }
    evaluationContext.addPropertyAccessor(new MapAccessor());
    for (Entry<String, Method> functionEntry : getFunctions().entrySet()) {
        evaluationContext.registerFunction(functionEntry.getKey(), functionEntry.getValue());
    }
    return evaluationContext;
}
Also used : StandardEvaluationContext(org.springframework.expression.spel.support.StandardEvaluationContext) PropertyAccessor(org.springframework.expression.PropertyAccessor) MapAccessor(org.springframework.context.expression.MapAccessor) Method(java.lang.reflect.Method)

Example 14 with PropertyAccessor

use of org.springframework.expression.PropertyAccessor in project spring-integration by spring-projects.

the class AbstractEvaluationContextFactoryBean method initialize.

protected void initialize(String beanName) throws Exception {
    if (this.applicationContext != null) {
        ConversionService conversionService = IntegrationUtils.getConversionService(getApplicationContext());
        if (conversionService != null) {
            this.typeConverter = new StandardTypeConverter(conversionService);
        }
        Map<String, SpelFunctionFactoryBean> functionFactoryBeanMap = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.applicationContext, SpelFunctionFactoryBean.class);
        for (SpelFunctionFactoryBean spelFunctionFactoryBean : functionFactoryBeanMap.values()) {
            if (!getFunctions().containsKey(spelFunctionFactoryBean.getFunctionName())) {
                getFunctions().put(spelFunctionFactoryBean.getFunctionName(), spelFunctionFactoryBean.getObject());
            }
        }
        try {
            SpelPropertyAccessorRegistrar propertyAccessorRegistrar = this.applicationContext.getBean(SpelPropertyAccessorRegistrar.class);
            for (Entry<String, PropertyAccessor> entry : propertyAccessorRegistrar.getPropertyAccessors().entrySet()) {
                if (!getPropertyAccessors().containsKey(entry.getKey())) {
                    getPropertyAccessors().put(entry.getKey(), entry.getValue());
                }
            }
        } catch (NoSuchBeanDefinitionException e) {
        // There is no 'SpelPropertyAccessorRegistrar' bean in the application context.
        }
        ApplicationContext parent = this.applicationContext.getParent();
        if (parent != null && parent.containsBean(beanName)) {
            AbstractEvaluationContextFactoryBean parentFactoryBean = parent.getBean("&" + beanName, getClass());
            for (Entry<String, PropertyAccessor> entry : parentFactoryBean.getPropertyAccessors().entrySet()) {
                if (!getPropertyAccessors().containsKey(entry.getKey())) {
                    getPropertyAccessors().put(entry.getKey(), entry.getValue());
                }
            }
            for (Entry<String, Method> entry : parentFactoryBean.getFunctions().entrySet()) {
                if (!getFunctions().containsKey(entry.getKey())) {
                    getFunctions().put(entry.getKey(), entry.getValue());
                }
            }
        }
    }
    this.initialized = true;
}
Also used : SpelPropertyAccessorRegistrar(org.springframework.integration.expression.SpelPropertyAccessorRegistrar) PropertyAccessor(org.springframework.expression.PropertyAccessor) Method(java.lang.reflect.Method) StandardTypeConverter(org.springframework.expression.spel.support.StandardTypeConverter) ApplicationContext(org.springframework.context.ApplicationContext) ConversionService(org.springframework.core.convert.ConversionService) NoSuchBeanDefinitionException(org.springframework.beans.factory.NoSuchBeanDefinitionException)

Example 15 with PropertyAccessor

use of org.springframework.expression.PropertyAccessor in project spring-framework by spring-projects.

the class AstUtils method getPropertyAccessorsToTry.

/**
 * Determines the set of property resolvers that should be used to try and access a
 * property on the specified target type. The resolvers are considered to be in an
 * ordered list, however in the returned list any that are exact matches for the input
 * target type (as opposed to 'general' resolvers that could work for any type) are
 * placed at the start of the list. In addition, there are specific resolvers that
 * exactly name the class in question and resolvers that name a specific class but it
 * is a supertype of the class we have. These are put at the end of the specific resolvers
 * set and will be tried after exactly matching accessors but before generic accessors.
 * @param targetType the type upon which property access is being attempted
 * @return a list of resolvers that should be tried in order to access the property
 */
public static List<PropertyAccessor> getPropertyAccessorsToTry(@Nullable Class<?> targetType, List<PropertyAccessor> propertyAccessors) {
    List<PropertyAccessor> specificAccessors = new ArrayList<>();
    List<PropertyAccessor> generalAccessors = new ArrayList<>();
    for (PropertyAccessor resolver : propertyAccessors) {
        Class<?>[] targets = resolver.getSpecificTargetClasses();
        if (targets == null) {
            // generic resolver that says it can be used for any type
            generalAccessors.add(resolver);
        } else {
            if (targetType != null) {
                for (Class<?> clazz : targets) {
                    if (clazz == targetType) {
                        // put exact matches on the front to be tried first?
                        specificAccessors.add(resolver);
                    } else if (clazz.isAssignableFrom(targetType)) {
                        // put supertype matches at the end of the
                        // specificAccessor list
                        generalAccessors.add(resolver);
                    }
                }
            }
        }
    }
    List<PropertyAccessor> resolvers = new ArrayList<>(specificAccessors.size() + generalAccessors.size());
    resolvers.addAll(specificAccessors);
    resolvers.addAll(generalAccessors);
    return resolvers;
}
Also used : PropertyAccessor(org.springframework.expression.PropertyAccessor) ArrayList(java.util.ArrayList)

Aggregations

PropertyAccessor (org.springframework.expression.PropertyAccessor)17 ReflectivePropertyAccessor (org.springframework.expression.spel.support.ReflectivePropertyAccessor)7 Test (org.junit.Test)5 CompilablePropertyAccessor (org.springframework.expression.spel.CompilablePropertyAccessor)5 StandardEvaluationContext (org.springframework.expression.spel.support.StandardEvaluationContext)5 ArrayList (java.util.ArrayList)4 EvaluationContext (org.springframework.expression.EvaluationContext)4 Method (java.lang.reflect.Method)3 Test (org.junit.jupiter.api.Test)3 AccessException (org.springframework.expression.AccessException)3 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 MapAccessor (org.springframework.context.expression.MapAccessor)2 EvaluationException (org.springframework.expression.EvaluationException)2 SpelEvaluationException (org.springframework.expression.spel.SpelEvaluationException)2 List (java.util.List)1 Map (java.util.Map)1 BeansException (org.springframework.beans.BeansException)1 NoSuchBeanDefinitionException (org.springframework.beans.factory.NoSuchBeanDefinitionException)1 SpringBootTest (org.springframework.boot.test.context.SpringBootTest)1 ApplicationContext (org.springframework.context.ApplicationContext)1