made getName() public; added isNullSafe() accessor (SPR-6980)

This commit is contained in:
Juergen Hoeller 2010-03-14 22:19:56 +00:00
parent 2e5f1c22f6
commit 0cb7e4dcb3
1 changed files with 56 additions and 33 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2010 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -41,20 +41,31 @@ import org.springframework.expression.spel.support.ReflectivePropertyAccessor;
*/ */
public class PropertyOrFieldReference extends SpelNodeImpl { public class PropertyOrFieldReference extends SpelNodeImpl {
private final boolean nullSafe;
private final String name; private final String name;
private volatile PropertyAccessor cachedReadAccessor; private volatile PropertyAccessor cachedReadAccessor;
private volatile PropertyAccessor cachedWriteAccessor; private volatile PropertyAccessor cachedWriteAccessor;
private final boolean nullSafe;
public PropertyOrFieldReference(boolean nullSafe, String propertyOrFieldName, int pos) { public PropertyOrFieldReference(boolean nullSafe, String propertyOrFieldName, int pos) {
super(pos); super(pos);
name = propertyOrFieldName;
this.nullSafe = nullSafe; this.nullSafe = nullSafe;
this.name = propertyOrFieldName;
} }
public boolean isNullSafe() {
return this.nullSafe;
}
public String getName() {
return this.name;
}
@Override @Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException { public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
TypedValue result = readProperty(state, this.name); TypedValue result = readProperty(state, this.name);
@ -70,28 +81,38 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
try { try {
if (isWritable(state)) { if (isWritable(state)) {
List newList = ArrayList.class.newInstance(); List newList = ArrayList.class.newInstance();
writeProperty(state, name, newList); writeProperty(state, this.name, newList);
result = readProperty(state, this.name); result = readProperty(state, this.name);
} }
} catch (InstantiationException e) {
throw new SpelEvaluationException(getStartPosition(), e, SpelMessage.UNABLE_TO_CREATE_LIST_FOR_INDEXING);
} catch (IllegalAccessException e) {
throw new SpelEvaluationException(getStartPosition(), e, SpelMessage.UNABLE_TO_CREATE_LIST_FOR_INDEXING);
} }
} else { catch (InstantiationException ex) {
throw new SpelEvaluationException(getStartPosition(), ex,
SpelMessage.UNABLE_TO_CREATE_LIST_FOR_INDEXING);
}
catch (IllegalAccessException ex) {
throw new SpelEvaluationException(getStartPosition(), ex,
SpelMessage.UNABLE_TO_CREATE_LIST_FOR_INDEXING);
}
}
else {
try { try {
if (isWritable(state)) { if (isWritable(state)) {
Map newMap = HashMap.class.newInstance(); Map newMap = HashMap.class.newInstance();
writeProperty(state, name, newMap); writeProperty(state, name, newMap);
result = readProperty(state, this.name); result = readProperty(state, this.name);
} }
} catch (InstantiationException e) { }
throw new SpelEvaluationException(getStartPosition(), e, SpelMessage.UNABLE_TO_CREATE_MAP_FOR_INDEXING); catch (InstantiationException ex) {
} catch (IllegalAccessException e) { throw new SpelEvaluationException(getStartPosition(), ex,
throw new SpelEvaluationException(getStartPosition(), e, SpelMessage.UNABLE_TO_CREATE_MAP_FOR_INDEXING); SpelMessage.UNABLE_TO_CREATE_MAP_FOR_INDEXING);
}
catch (IllegalAccessException ex) {
throw new SpelEvaluationException(getStartPosition(), ex,
SpelMessage.UNABLE_TO_CREATE_MAP_FOR_INDEXING);
} }
} }
} else { }
else {
// 'simple' object // 'simple' object
try { try {
if (isWritable(state)) { if (isWritable(state)) {
@ -99,10 +120,14 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
writeProperty(state, name, newObject); writeProperty(state, name, newObject);
result = readProperty(state, this.name); result = readProperty(state, this.name);
} }
} catch (InstantiationException e) { }
throw new SpelEvaluationException(getStartPosition(), e, SpelMessage.UNABLE_TO_DYNAMICALLY_CREATE_OBJECT,result.getTypeDescriptor().getType()); catch (InstantiationException ex) {
} catch (IllegalAccessException e) { throw new SpelEvaluationException(getStartPosition(), ex,
throw new SpelEvaluationException(getStartPosition(), e, SpelMessage.UNABLE_TO_DYNAMICALLY_CREATE_OBJECT,result.getTypeDescriptor().getType()); SpelMessage.UNABLE_TO_DYNAMICALLY_CREATE_OBJECT, result.getTypeDescriptor().getType());
}
catch (IllegalAccessException ex) {
throw new SpelEvaluationException(getStartPosition(), ex,
SpelMessage.UNABLE_TO_DYNAMICALLY_CREATE_OBJECT, result.getTypeDescriptor().getType());
} }
} }
} }
@ -176,7 +201,8 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
} }
if (contextObject.getValue() == null) { if (contextObject.getValue() == null) {
throw new SpelEvaluationException(SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL, name); throw new SpelEvaluationException(SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL, name);
} else { }
else {
throw new SpelEvaluationException(getStartPosition(),SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE, name, throw new SpelEvaluationException(getStartPosition(),SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE, name,
FormatHelper.formatClassNameForMessage(contextObjectClass)); FormatHelper.formatClassNameForMessage(contextObjectClass));
} }
@ -215,33 +241,34 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
return; return;
} }
} }
} catch (AccessException ae) { }
catch (AccessException ae) {
throw new SpelEvaluationException(getStartPosition(), ae, SpelMessage.EXCEPTION_DURING_PROPERTY_WRITE, throw new SpelEvaluationException(getStartPosition(), ae, SpelMessage.EXCEPTION_DURING_PROPERTY_WRITE,
name, ae.getMessage()); name, ae.getMessage());
} }
} }
if (contextObject.getValue()==null) { if (contextObject.getValue()==null) {
throw new SpelEvaluationException(getStartPosition(),SpelMessage.PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL, name); throw new SpelEvaluationException(getStartPosition(), SpelMessage.PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL, name);
} else { }
throw new SpelEvaluationException(getStartPosition(),SpelMessage.PROPERTY_OR_FIELD_NOT_WRITABLE, name, FormatHelper else {
.formatClassNameForMessage(contextObjectClass)); throw new SpelEvaluationException(getStartPosition(), SpelMessage.PROPERTY_OR_FIELD_NOT_WRITABLE, name,
FormatHelper.formatClassNameForMessage(contextObjectClass));
} }
} }
public boolean isWritableProperty(String name, ExpressionState state) throws SpelEvaluationException { public boolean isWritableProperty(String name, ExpressionState state) throws SpelEvaluationException {
Object contextObject = state.getActiveContextObject().getValue(); Object contextObject = state.getActiveContextObject().getValue();
// TypeDescriptor td = state.getActiveContextObject().getTypeDescriptor(); // TypeDescriptor td = state.getActiveContextObject().getTypeDescriptor();
EvaluationContext eContext = state.getEvaluationContext(); EvaluationContext eContext = state.getEvaluationContext();
List<PropertyAccessor> resolversToTry = getPropertyAccessorsToTry(getObjectClass(contextObject), state);
List<PropertyAccessor> resolversToTry = getPropertyAccessorsToTry(getObjectClass(contextObject),state);
if (resolversToTry != null) { if (resolversToTry != null) {
for (PropertyAccessor pfResolver : resolversToTry) { for (PropertyAccessor pfResolver : resolversToTry) {
try { try {
if (pfResolver.canWrite(eContext, contextObject, name)) { if (pfResolver.canWrite(eContext, contextObject, name)) {
return true; return true;
} }
} catch (AccessException ae) { }
catch (AccessException ae) {
// let others try // let others try
} }
} }
@ -288,9 +315,5 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
resolvers.addAll(generalAccessors); resolvers.addAll(generalAccessors);
return resolvers; return resolvers;
} }
String getName() {
return name;
}
} }