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);
}
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();
}
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;
}
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;
}
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;
}
Aggregations