UnionPropertyAccessor.java
package pro.verron.officestamper.core;
import org.jspecify.annotations.Nullable;
import org.springframework.expression.AccessException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
import java.util.List;
record UnionPropertyAccessor(List<PropertyAccessor> accessors)
implements PropertyAccessor {
@Override
public Class<?>[] getSpecificTargetClasses() {
return new Class[]{ContextBranch.class};
}
@Override
public boolean canRead(EvaluationContext context, @Nullable Object target, String name)
throws AccessException {
if (!(target instanceof ContextBranch branch)) return false;
for (Object subTarget : branch.list())
for (PropertyAccessor accessor : accessors)
if (accessor.canRead(context, subTarget, name)) return true;
return false;
}
@Override
public TypedValue read(EvaluationContext context, @Nullable Object target, String name)
throws AccessException {
if (!(target instanceof ContextBranch branch))
throw new AccessException("Target is not a ContextBranch");
for (Object subTarget : branch.list()) {
for (PropertyAccessor accessor : accessors) {
if (accessor.canRead(context, subTarget, name)) {
return accessor.read(context, subTarget, name);
}
}
}
throw new AccessException("Unable to read property '" + name + "' from any context object");
}
@Override
public boolean canWrite(EvaluationContext context, @Nullable Object target, String name)
throws AccessException {
if (!(target instanceof ContextBranch branch)) return false;
for (Object subTarget : branch.list())
for (PropertyAccessor accessor : accessors)
if (accessor.canWrite(context, subTarget, name)) return true;
return false;
}
@Override
public void write(EvaluationContext context, @Nullable Object target, String name, @Nullable Object newValue)
throws AccessException {
if (!(target instanceof ContextBranch branch))
throw new AccessException("Target is not a ContextBranch");
AccessException lastException = null;
for (Object subTarget : branch.list()) {
for (PropertyAccessor accessor : accessors) {
if (accessor.canWrite(context, subTarget, name)) {
try {
accessor.write(context, subTarget, name, newValue);
return;
} catch (AccessException e) {
lastException = e;
}
}
}
}
throw lastException != null
? lastException
: new AccessException("Unable to write property '" + name + "' to any context object");
}
}