| 
1 | 1 | /*  | 
2 |  | - * Copyright 2002-2024 the original author or authors.  | 
 | 2 | + * Copyright 2002-2025 the original author or authors.  | 
3 | 3 |  *  | 
4 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License");  | 
5 | 5 |  * you may not use this file except in compliance with the License.  | 
 | 
62 | 62 |  *  | 
63 | 63 |  * @param <A> the annotation to search for and synthesize  | 
64 | 64 |  * @author Josh Cummings  | 
 | 65 | + * @author DingHao  | 
65 | 66 |  * @since 6.4  | 
66 | 67 |  */  | 
67 | 68 | final class ExpressionTemplateSecurityAnnotationScanner<A extends Annotation>  | 
@@ -116,27 +117,35 @@ private MergedAnnotation<A> resolvePlaceholders(MergedAnnotation<A> mergedAnnota  | 
116 | 117 | 		PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("{", "}", null, null,  | 
117 | 118 | 				this.templateDefaults.isIgnoreUnknown());  | 
118 | 119 | 		Map<String, Object> properties = new HashMap<>(mergedAnnotation.asMap());  | 
119 |  | -		Map<String, Object> metaAnnotationProperties = mergedAnnotation.getMetaSource().asMap();  | 
120 |  | -		Map<String, String> stringProperties = new HashMap<>();  | 
121 |  | -		for (Map.Entry<String, Object> property : metaAnnotationProperties.entrySet()) {  | 
122 |  | -			String key = property.getKey();  | 
123 |  | -			Object value = property.getValue();  | 
124 |  | -			String asString = (value instanceof String) ? (String) value  | 
125 |  | -					: conversionService.convert(value, String.class);  | 
126 |  | -			stringProperties.put(key, asString);  | 
127 |  | -		}  | 
128 |  | -		Map<String, Object> annotationProperties = mergedAnnotation.asMap();  | 
129 |  | -		for (Map.Entry<String, Object> annotationProperty : annotationProperties.entrySet()) {  | 
 | 120 | +		Map<String, String> metaAnnotationProperties = extractMetaAnnotationProperties(mergedAnnotation);  | 
 | 121 | +		for (Map.Entry<String, Object> annotationProperty : mergedAnnotation.asMap().entrySet()) {  | 
130 | 122 | 			if (!(annotationProperty.getValue() instanceof String expression)) {  | 
131 | 123 | 				continue;  | 
132 | 124 | 			}  | 
133 |  | -			String value = helper.replacePlaceholders(expression, stringProperties::get);  | 
 | 125 | +			String value = helper.replacePlaceholders(expression, metaAnnotationProperties::get);  | 
134 | 126 | 			properties.put(annotationProperty.getKey(), value);  | 
135 | 127 | 		}  | 
136 | 128 | 		AnnotatedElement annotatedElement = (AnnotatedElement) mergedAnnotation.getSource();  | 
137 | 129 | 		return MergedAnnotation.of(annotatedElement, this.type, properties);  | 
138 | 130 | 	}  | 
139 | 131 | 
 
  | 
 | 132 | +	private Map<String, String> extractMetaAnnotationProperties(MergedAnnotation<A> mergedAnnotation) {  | 
 | 133 | +		Map<String, String> stringProperties = new HashMap<>();  | 
 | 134 | +		Map<String, Object> metaAnnotationProperties = new HashMap<>();  | 
 | 135 | +		MergedAnnotation<?> metaSource = mergedAnnotation.getMetaSource();  | 
 | 136 | +		while (metaSource != null) {  | 
 | 137 | +			metaAnnotationProperties.putAll(metaSource.asMap());  | 
 | 138 | +			metaSource = metaSource.getMetaSource();  | 
 | 139 | +		}  | 
 | 140 | +		for (Map.Entry<String, Object> property : metaAnnotationProperties.entrySet()) {  | 
 | 141 | +			Object value = property.getValue();  | 
 | 142 | +			String valueString = (value instanceof String) ? (String) value  | 
 | 143 | +					: conversionService.convert(value, String.class);  | 
 | 144 | +			stringProperties.put(property.getKey(), valueString);  | 
 | 145 | +		}  | 
 | 146 | +		return stringProperties;  | 
 | 147 | +	}  | 
 | 148 | + | 
140 | 149 | 	static class ClassToStringConverter implements GenericConverter {  | 
141 | 150 | 
 
  | 
142 | 151 | 		@Override  | 
 | 
0 commit comments