use of org.springframework.core.convert.TypeDescriptor in project spring-framework by spring-projects.
the class ReflectivePropertyAccessor method read.
@Override
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
if (target == null) {
throw new AccessException("Cannot read property of null target");
}
Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass());
if (type.isArray() && name.equals("length")) {
if (target instanceof Class) {
throw new AccessException("Cannot access length on array class itself");
}
return new TypedValue(Array.getLength(target));
}
PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class);
InvokerPair invoker = this.readerCache.get(cacheKey);
lastReadInvokerPair = invoker;
if (invoker == null || invoker.member instanceof Method) {
Method method = (Method) (invoker != null ? invoker.member : null);
if (method == null) {
method = findGetterForProperty(name, type, target);
if (method != null) {
// TODO remove the duplication here between canRead and read
// Treat it like a property...
// The readerCache will only contain gettable properties (let's not worry about setters for now).
Property property = new Property(type, method, null);
TypeDescriptor typeDescriptor = new TypeDescriptor(property);
invoker = new InvokerPair(method, typeDescriptor);
lastReadInvokerPair = invoker;
this.readerCache.put(cacheKey, invoker);
}
}
if (method != null) {
try {
ReflectionUtils.makeAccessible(method);
Object value = method.invoke(target);
return new TypedValue(value, invoker.typeDescriptor.narrow(value));
} catch (Exception ex) {
throw new AccessException("Unable to access property '" + name + "' through getter method", ex);
}
}
}
if (invoker == null || invoker.member instanceof Field) {
Field field = (Field) (invoker == null ? null : invoker.member);
if (field == null) {
field = findField(name, type, target);
if (field != null) {
invoker = new InvokerPair(field, new TypeDescriptor(field));
lastReadInvokerPair = invoker;
this.readerCache.put(cacheKey, invoker);
}
}
if (field != null) {
try {
ReflectionUtils.makeAccessible(field);
Object value = field.get(target);
return new TypedValue(value, invoker.typeDescriptor.narrow(value));
} catch (Exception ex) {
throw new AccessException("Unable to access field '" + name + "'", ex);
}
}
}
throw new AccessException("Neither getter method nor field found for property '" + name + "'");
}
use of org.springframework.core.convert.TypeDescriptor in project spring-framework by spring-projects.
the class SpelExpression method getValueType.
@Override
public Class<?> getValueType(EvaluationContext context, Object rootObject) throws EvaluationException {
ExpressionState expressionState = new ExpressionState(context, toTypedValue(rootObject), this.configuration);
TypeDescriptor typeDescriptor = this.ast.getValueInternal(expressionState).getTypeDescriptor();
return (typeDescriptor != null ? typeDescriptor.getType() : null);
}
use of org.springframework.core.convert.TypeDescriptor in project spring-framework by spring-projects.
the class FormattingConversionServiceFactoryBeanTests method testCustomFormatter.
@Test
public void testCustomFormatter() throws Exception {
FormattingConversionServiceFactoryBean factory = new FormattingConversionServiceFactoryBean();
Set<Object> formatters = new HashSet<>();
formatters.add(new TestBeanFormatter());
formatters.add(new SpecialIntAnnotationFormatterFactory());
factory.setFormatters(formatters);
factory.afterPropertiesSet();
FormattingConversionService fcs = factory.getObject();
TestBean testBean = fcs.convert("5", TestBean.class);
assertEquals(5, testBean.getSpecialInt());
assertEquals("5", fcs.convert(testBean, String.class));
TypeDescriptor descriptor = new TypeDescriptor(TestBean.class.getDeclaredField("specialInt"));
Object value = fcs.convert(":5", TypeDescriptor.valueOf(String.class), descriptor);
assertEquals(5, value);
value = fcs.convert(5, descriptor, TypeDescriptor.valueOf(String.class));
assertEquals(":5", value);
}
use of org.springframework.core.convert.TypeDescriptor in project spring-framework by spring-projects.
the class FormattingConversionServiceFactoryBeanTests method testDefaultFormattersOn.
@Test
public void testDefaultFormattersOn() throws Exception {
FormattingConversionServiceFactoryBean factory = new FormattingConversionServiceFactoryBean();
factory.afterPropertiesSet();
FormattingConversionService fcs = factory.getObject();
TypeDescriptor descriptor = new TypeDescriptor(TestBean.class.getDeclaredField("pattern"));
LocaleContextHolder.setLocale(Locale.GERMAN);
try {
Object value = fcs.convert("15,00", TypeDescriptor.valueOf(String.class), descriptor);
assertEquals(15.0, value);
value = fcs.convert(15.0, descriptor, TypeDescriptor.valueOf(String.class));
assertEquals("15", value);
} finally {
LocaleContextHolder.resetLocaleContext();
}
}
use of org.springframework.core.convert.TypeDescriptor in project spring-framework by spring-projects.
the class FormattingConversionServiceFactoryBeanTests method testDefaultFormattersOff.
@Test
public void testDefaultFormattersOff() throws Exception {
FormattingConversionServiceFactoryBean factory = new FormattingConversionServiceFactoryBean();
factory.setRegisterDefaultFormatters(false);
factory.afterPropertiesSet();
FormattingConversionService fcs = factory.getObject();
TypeDescriptor descriptor = new TypeDescriptor(TestBean.class.getDeclaredField("pattern"));
try {
fcs.convert("15,00", TypeDescriptor.valueOf(String.class), descriptor);
fail("This format should not be parseable");
} catch (ConversionFailedException ex) {
assertTrue(ex.getCause() instanceof NumberFormatException);
}
}
Aggregations