/** * Go through the list of registered constructor resolvers and see if any can find a constructor that takes the * specified set of arguments. * @param typename the type trying to be constructed * @param argumentTypes the types of the arguments supplied that the constructor must take * @param state the current state of the expression * @return a reusable ConstructorExecutor that can be invoked to run the constructor or null * @throws SpelEvaluationException if there is a problem locating the constructor */ private ConstructorExecutor findExecutorForConstructor(String typename, List<TypeDescriptor> argumentTypes, ExpressionState state) throws SpelEvaluationException { EvaluationContext eContext = state.getEvaluationContext(); List<ConstructorResolver> cResolvers = eContext.getConstructorResolvers(); if (cResolvers != null) { for (ConstructorResolver ctorResolver : cResolvers) { try { ConstructorExecutor cEx = ctorResolver.resolve(state.getEvaluationContext(), typename, argumentTypes); if (cEx != null) { return cEx; } } catch (AccessException ex) { throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM, typename, FormatHelper.formatMethodForMessage("", argumentTypes)); } } } throw new SpelEvaluationException(getStartPosition(), SpelMessage.CONSTRUCTOR_NOT_FOUND, typename, FormatHelper .formatMethodForMessage("", argumentTypes)); }
/** * 创建配置Bean * * @param propertyName 属性名 * @param beanType 配置Bean类型 * @param converterType 转换器类型 * @param configBeanPropertyResolver 属性解析器 * @param conversionService 转换服务 * @param <T> * @return */ public static <T> T createConfigBean(String propertyName, Class<T> beanType, Class<? extends ConfigBeanConverter> converterType, ConfigPropertyResolver configBeanPropertyResolver, ConfigBeanConversionService conversionService) { PropertyResolver propertyResolver = configBeanPropertyResolver.getObject(); String propertyValue = propertyResolver.getRequiredProperty(propertyName); if (converterType != null && !converterType.isInterface()) { ConfigBeanConverter converter = BeanUtils.instantiate(converterType); return (T) converter.convert(propertyName, propertyValue, TypeDescriptor.valueOf(beanType)); } else { return (T) conversionService.convert(propertyName, propertyValue, TypeDescriptor.valueOf(beanType)); } }
@SuppressWarnings("unchecked") @Nullable private Object convertListElements(TypeDescriptor td, @Nullable Object convertedValue) { if (convertedValue != null) { if (List.class.isAssignableFrom(convertedValue.getClass()) && td.isCollection() && td.getElementTypeDescriptor() != null) { Class<?> elementType = td.getElementTypeDescriptor().getType(); Collection<Object> convertedList = new ArrayList<>(); for (Object record : (List<Object>) convertedValue) { Object convertedObject = this.objectMapper.convertValue(record, elementType); convertedList.add(convertedObject); } return convertedList; } } return convertedValue; }
/** * Formats the field value based on registered PropertyEditors. * @see #getCustomEditor */ @Override protected Object formatFieldValue(String field, Object value) { String fixedField = fixedField(field); // Try custom editor... PropertyEditor customEditor = getCustomEditor(fixedField); if (customEditor != null) { customEditor.setValue(value); String textValue = customEditor.getAsText(); // If the PropertyEditor returned null, there is no appropriate // text representation for this value: only use it if non-null. if (textValue != null) { return textValue; } } if (this.conversionService != null) { // Try custom converter... TypeDescriptor fieldDesc = getPropertyAccessor().getPropertyTypeDescriptor(fixedField); TypeDescriptor strDesc = TypeDescriptor.valueOf(String.class); if (fieldDesc != null && this.conversionService.canConvert(fieldDesc, strDesc)) { return this.conversionService.convert(value, fieldDesc, strDesc); } } return value; }
@Override public void contributeMethodArgument(MethodParameter parameter, Object value, UriComponentsBuilder builder, Map<String, Object> uriVariables, ConversionService conversionService) { Class<?> paramType = parameter.getNestedParameterType(); if (Map.class.isAssignableFrom(paramType)) { return; } WxApiParam wxApiParam = parameter.getParameterAnnotation(WxApiParam.class); String name = (wxApiParam == null || StringUtils.isEmpty(wxApiParam.name()) ? parameter.getParameterName() : wxApiParam.name()); WxAppAssert.notNull(name, "请添加编译器的-parameter或者为参数添加注解名称"); if (value == null) { if (wxApiParam != null) { if (!wxApiParam.required() || !wxApiParam.defaultValue().equals(ValueConstants.DEFAULT_NONE)) { return; } } builder.queryParam(name); } else if (value instanceof Collection) { for (Object element : (Collection<?>) value) { element = formatUriValue(conversionService, TypeDescriptor.nested(parameter, 1), element); builder.queryParam(name, element); } } else { builder.queryParam(name, formatUriValue(conversionService, new TypeDescriptor(parameter), value)); } }
@Override public TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException { try { BeanWrapperImpl nestedBw = getBeanWrapperForPropertyPath(propertyName); String finalPath = getFinalPath(nestedBw, propertyName); PropertyTokenHolder tokens = getPropertyNameTokens(finalPath); PropertyDescriptor pd = nestedBw.getCachedIntrospectionResults().getPropertyDescriptor(tokens.actualName); if (pd != null) { if (tokens.keys != null) { if (pd.getReadMethod() != null || pd.getWriteMethod() != null) { return TypeDescriptor.nested(property(pd), tokens.keys.length); } } else { if (pd.getReadMethod() != null || pd.getWriteMethod() != null) { return new TypeDescriptor(property(pd)); } } } } catch (InvalidPropertyException ex) { // Consider as not determinable. } return null; }
/** * Determines if there is a type converter available in the specified context and * attempts to use it to convert the supplied value to the specified type. Throws an * exception if conversion is not possible. * @param context the evaluation context that may define a type converter * @param typedValue the value to convert and a type descriptor describing it * @param targetType the type to attempt conversion to * @return the converted value * @throws EvaluationException if there is a problem during conversion or conversion * of the value to the specified type is not supported */ @SuppressWarnings("unchecked") public static <T> T convertTypedValue(EvaluationContext context, TypedValue typedValue, Class<T> targetType) { Object value = typedValue.getValue(); if (targetType == null) { return (T) value; } if (context != null) { return (T) context.getTypeConverter().convertValue( value, typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(targetType)); } if (ClassUtils.isAssignableValue(targetType, value)) { return (T) value; } throw new EvaluationException("Cannot convert value '" + value + "' to type '" + targetType.getName() + "'"); }
private MethodExecutor findAccessorForMethod(String name, List<TypeDescriptor> argumentTypes, Object targetObject, EvaluationContext evaluationContext) throws SpelEvaluationException { List<MethodResolver> methodResolvers = evaluationContext.getMethodResolvers(); if (methodResolvers != null) { for (MethodResolver methodResolver : methodResolvers) { try { MethodExecutor methodExecutor = methodResolver.resolve( evaluationContext, targetObject, name, argumentTypes); if (methodExecutor != null) { return methodExecutor; } } catch (AccessException ex) { throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.PROBLEM_LOCATING_METHOD, name, targetObject.getClass()); } } } throw new SpelEvaluationException(getStartPosition(), SpelMessage.METHOD_NOT_FOUND, FormatHelper.formatMethodForMessage(name, argumentTypes), FormatHelper.formatClassNameForMessage( targetObject instanceof Class ? ((Class<?>) targetObject) : targetObject.getClass())); }
/** * Produce a nice string for a given method name with specified arguments. * @param name the name of the method * @param argumentTypes the types of the arguments to the method * @return nicely formatted string, eg. foo(String,int) */ public static String formatMethodForMessage(String name, List<TypeDescriptor> argumentTypes) { StringBuilder sb = new StringBuilder(); sb.append(name); sb.append("("); for (int i = 0; i < argumentTypes.size(); i++) { if (i > 0) { sb.append(","); } TypeDescriptor typeDescriptor = argumentTypes.get(i); if (typeDescriptor != null) { sb.append(formatClassNameForMessage(typeDescriptor.getType())); } else { sb.append(formatClassNameForMessage(null)); } } sb.append(")"); return sb.toString(); }
private Class<?> getType(TypeDescriptor typeDescriptor) { if (typeDescriptor == null) { return null; } else if (typeDescriptor.isArray() || typeDescriptor.isCollection()) { TypeDescriptor elementTypeDesc = typeDescriptor.getElementTypeDescriptor(); if (elementTypeDesc != null) { return elementTypeDesc.getType(); } else { return null; } } else { return typeDescriptor.getObjectType(); } }
public static Object normaliseValueForPut(Object value, ConversionService conversionService) { if (value instanceof Document) { return conversionService.convert(value, TypeDescriptor.forObject(value), TypeDescriptor.valueOf(IData.class)); } else if (value instanceof Document[]) { return conversionService.convert(value, TypeDescriptor.forObject(value), TypeDescriptor.valueOf(IData[].class)); } else if (value instanceof Iterable<?>) { if (CollectionUtil.areAllElementsOfType((Collection<?>) value, Document.class)) { return conversionService.convert(value, TypeDescriptor.forObject(value), TypeDescriptor.valueOf(IData[].class)); } else { return value; } } else { return value; } }
@Test public void shouldSaveSession() throws Exception { // given MongoSession session = new MongoSession(); BasicDBObject dbSession = new BasicDBObject(); given(this.converter.convert(session, TypeDescriptor.valueOf(MongoSession.class), TypeDescriptor.valueOf(DBObject.class))).willReturn(dbSession); given(this.mongoOperations.save(dbSession, "sessions")).willReturn(Mono.just(dbSession)); // when StepVerifier.create(this.repository.save(session)) .expectNextMatches(aVoid -> { // then verify(this.mongoOperations).save(dbSession, ReactiveMongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME); return true; }); }
@Test public void shouldHandleExpiredSession() throws Exception { // given String sessionId = UUID.randomUUID().toString(); Document sessionDocument = new Document(); given(this.mongoOperations.findById(sessionId, Document.class, ReactiveMongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME)).willReturn(Mono.just(sessionDocument)); MongoSession session = mock(MongoSession.class); given(session.isExpired()).willReturn(true); given(this.converter.convert(sessionDocument, TypeDescriptor.valueOf(Document.class), TypeDescriptor.valueOf(MongoSession.class))).willReturn(session); // when StepVerifier.create(this.repository.findById(sessionId)) .expectNextMatches(mongoSession -> { // then verify(this.mongoOperations).remove(any(Document.class), eq(ReactiveMongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME)); return true; }); }
@Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { Base64 annotation = targetType.getAnnotation(Base64.class); String value = (String) source; if (value == null) { return null; } else { try { java.util.Base64.Decoder decoder = annotation.decoder() == Base64.Decoder.BASIC ? java.util.Base64.getDecoder() : java.util.Base64.getUrlDecoder(); byte[] bytes = decoder.decode(value); return new String(bytes, annotation.charset()); } catch (IllegalArgumentException | UnsupportedEncodingException e) { throw new IllegalStateException("Failed to base64-decode value " + value, e); } } }
@Override public Object convert(String propertyName, String propertyValue, TypeDescriptor targetType) { Class<?> targetClass = targetType.getType(); Serializer serializer = new Persister(new AnnotationStrategy()); try { return serializer.read(targetClass, propertyValue, false); } catch (Exception e) { LOGGER.error("Convert xml to " + targetClass + " error", e); } return null; }
/** * 将配置属性转换成Bean * * @param propertyName * @param propertyValue * @param targetType * @return */ public Object convert(String propertyName, String propertyValue, TypeDescriptor targetType) { for (ConfigBeanConverter converter : converters) { if (converter.matches(propertyName, propertyValue, targetType)) { return converter.convert(propertyName, propertyValue, targetType); } } throw new ConverterNotFoundException(propertyName, propertyValue, targetType); }
@Test public void shouldSaveSession() throws Exception { // given MongoSession session = new MongoSession(); BasicDBObject dbSession = new BasicDBObject(); given(this.converter.convert(session, TypeDescriptor.valueOf(MongoSession.class), TypeDescriptor.valueOf(DBObject.class))).willReturn(dbSession); // when this.repository.save(session); // then verify(this.mongoOperations).save(dbSession, MongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME); }
private static List<ReifiedType> getArguments(TypeDescriptor type) { List<ReifiedType> arguments; if (type == null) { return Collections.emptyList(); } // is it a collection or an array if (type.isCollection() || type.isArray()) { arguments = new ArrayList<ReifiedType>(1); Class<?> elementType = type.getElementTypeDescriptor() == null ? null : type.getElementTypeDescriptor().getType(); arguments.add(elementType != null ? new GenericsReifiedType(elementType) : OBJECT); return arguments; } // is it a map if (type.isMap()) { arguments = new ArrayList<ReifiedType>(2); Class<?> keyType = type.getMapKeyTypeDescriptor() == null ? null : type.getMapKeyTypeDescriptor().getType(); arguments.add(keyType != null ? new GenericsReifiedType(keyType) : OBJECT); Class<?> valueType = type.getMapValueTypeDescriptor() == null ? null : type.getMapValueTypeDescriptor().getType(); arguments.add(valueType != null ? new GenericsReifiedType(valueType) : OBJECT); return arguments; } // some other generic type @SuppressWarnings("rawtypes") TypeVariable[] tvs = type.getType().getTypeParameters(); arguments = new ArrayList<ReifiedType>(tvs.length); for (@SuppressWarnings("rawtypes") TypeVariable tv : tvs) { ReifiedType rType = getReifiedType(tv, new ArrayList<Type>()); arguments.add(rType); } return arguments; }
@Test public void testMultiBoundedGenericType() throws Exception { ReifiedType reifiedA = TypeFactory.getType(TypeDescriptor.valueOf(A.class)); assertNotNull(reifiedA); ReifiedType reifiedB = TypeFactory.getType(TypeDescriptor.valueOf(B.class)); assertNotNull(reifiedB); }
@Override public void contributeMethodArgument(MethodParameter parameter, Object value, UriComponentsBuilder builder, Map<String, Object> uriVariables, ConversionService conversionService) { if (Map.class.isAssignableFrom(parameter.nestedIfOptional().getNestedParameterType())) { return; } WxApiPath wx = parameter.getParameterAnnotation(WxApiPath.class); String name = (wx != null && !StringUtils.isEmpty(wx.value()) ? wx.value() : parameter.getParameterName()); WxAppAssert.notNull(name, "请添加编译器的-parameter或者为参数添加注解名称"); value = formatUriValue(conversionService, new TypeDescriptor(parameter.nestedIfOptional()), value); uriVariables.put(name, value); }
public PrinterConverter(Class<?> fieldType, Printer<?> printer, ConversionService conversionService) { this.fieldType = fieldType; this.printerObjectType = TypeDescriptor.valueOf(resolvePrinterObjectType(printer)); this.printer = printer; this.conversionService = conversionService; }
@Override @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return ""; } if (!sourceType.isAssignableTo(this.printerObjectType)) { source = this.conversionService.convert(source, sourceType, this.printerObjectType); } return this.printer.print(source, LocaleContextHolder.getLocale()); }
@Override @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { AnnotationConverterKey converterKey = new AnnotationConverterKey(sourceType.getAnnotation(annotationType), sourceType.getObjectType()); GenericConverter converter = cachedPrinters.get(converterKey); if (converter == null) { Printer<?> printer = annotationFormatterFactory.getPrinter( converterKey.getAnnotation(), converterKey.getFieldType()); converter = new PrinterConverter(fieldType, printer, FormattingConversionService.this); cachedPrinters.put(converterKey, converter); } return converter.convert(source, sourceType, targetType); }
@Override @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { AnnotationConverterKey converterKey = new AnnotationConverterKey(targetType.getAnnotation(annotationType), targetType.getObjectType()); GenericConverter converter = cachedParsers.get(converterKey); if (converter == null) { Parser<?> parser = annotationFormatterFactory.getParser( converterKey.getAnnotation(), converterKey.getFieldType()); converter = new ParserConverter(fieldType, parser, FormattingConversionService.this); cachedParsers.put(converterKey, converter); } return converter.convert(source, sourceType, targetType); }
private void throwIfNotNullSafe(List<TypeDescriptor> argumentTypes) { if (!this.nullSafe) { throw new SpelEvaluationException(getStartPosition(), SpelMessage.METHOD_CALL_ON_NULL_OBJECT_NOT_ALLOWED, FormatHelper.formatMethodForMessage(this.name, argumentTypes)); } }
private List<TypeDescriptor> getArgumentTypes(Object... arguments) { List<TypeDescriptor> descriptors = new ArrayList<TypeDescriptor>(arguments.length); for (Object argument : arguments) { descriptors.add(TypeDescriptor.forObject(argument)); } return Collections.unmodifiableList(descriptors); }
public CachedMethodExecutor(MethodExecutor methodExecutor, Class<?> staticClass, TypeDescriptor target, List<TypeDescriptor> argumentTypes) { this.methodExecutor = methodExecutor; this.staticClass = staticClass; this.target = target; this.argumentTypes = argumentTypes; }
@Before public void setUp() throws Exception { compiler = new QueryFragmentCompiler(TestSearchEntity.class, searchMetadata, conversionService); when(searchMetadata.encodeFieldName(TestSearchEntity.class, "field")).thenReturn("field"); when(conversionService.convert(anyString(), eq(String.class))).thenAnswer(invocation -> invocation.getArgumentAt(0, String.class)); when(conversionService.convert(any(String[].class), any(TypeDescriptor.class), any(TypeDescriptor.class))) .thenAnswer(invocation -> Arrays.asList(invocation.getArgumentAt(0, String[].class))); }
public CollectionIndexingValueRef(Collection collection, int index, TypeDescriptor collectionEntryTypeDescriptor, TypeConverter typeConverter, boolean growCollection, int maximumSize) { this.collection = collection; this.index = index; this.collectionEntryDescriptor = collectionEntryTypeDescriptor; this.typeConverter = typeConverter; this.growCollection = growCollection; this.maximumSize = maximumSize; }
@Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { for (ConversionService conversionService : allButLast) { if (conversionService.canConvert(sourceType, targetType)) { return conversionService.convert(source, sourceType, targetType); } } return last.convert(source, sourceType, targetType); }
@Override public MethodExecutor resolve( EvaluationContext context, Object targetObject, String name, List<TypeDescriptor> argumentTypes ) throws AccessException { return Martini.class.isInstance(targetObject) ? resolve(name, argumentTypes) : null; }
/** * Based on {@link MethodInvoker#getTypeDifferenceWeight(Class[], Object[])} but operates on TypeDescriptors. */ public static int getTypeDifferenceWeight(List<TypeDescriptor> paramTypes, List<TypeDescriptor> argTypes) { int result = 0; for (int i = 0; i < paramTypes.size(); i++) { TypeDescriptor paramType = paramTypes.get(i); TypeDescriptor argType = argTypes.get(i); if (argType == null) { if (paramType.isPrimitive()) { return Integer.MAX_VALUE; } } else { Class<?> paramTypeClazz = paramType.getType(); if (!ClassUtils.isAssignable(paramTypeClazz, argType.getType())) { return Integer.MAX_VALUE; } if (paramTypeClazz.isPrimitive()) { paramTypeClazz = Object.class; } Class<?> superClass = argType.getType().getSuperclass(); while (superClass != null) { if (paramTypeClazz.equals(superClass)) { result = result + 2; superClass = null; } else if (ClassUtils.isAssignable(paramTypeClazz, superClass)) { result = result + 2; superClass = superClass.getSuperclass(); } else { superClass = null; } } if (paramTypeClazz.isInterface()) { result = result + 1; } } } return result; }
private TypeDescriptor getTypeDescriptor(EvaluationContext context, Object target, String name) { if (target == null) { return null; } Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); if (type.isArray() && name.equals("length")) { return TypeDescriptor.valueOf(Integer.TYPE); } CacheKey cacheKey = new CacheKey(type, name, target instanceof Class); TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey); if (typeDescriptor == null) { // attempt to populate the cache entry try { if (canRead(context, target, name)) { typeDescriptor = this.typeDescriptorCache.get(cacheKey); } else if (canWrite(context, target, name)) { typeDescriptor = this.typeDescriptorCache.get(cacheKey); } } catch (AccessException ex) { // continue with null type descriptor } } return typeDescriptor; }
@Override public Object convertValue(Object value, TypeDescriptor sourceType, TypeDescriptor targetType) { try { return this.conversionService.convert(value, sourceType, targetType); } catch (ConversionException ex) { throw new SpelEvaluationException( ex, SpelMessage.TYPE_CONVERSION_ERROR, sourceType.toString(), targetType.toString()); } }
private boolean isDescriptorOK(TypeDescriptor typeDescriptor) { if (typeDescriptor == null) { return false; } else if (typeDescriptor.isArray() || typeDescriptor.isCollection()) { TypeDescriptor elementTypeDesc = typeDescriptor.getElementTypeDescriptor(); if (elementTypeDesc != null) { return isClassAcceptable(elementTypeDesc.getType()); } else { return true; } } else { return isClassAcceptable(typeDescriptor.getType()); } }
protected final A convertAndNormaliseValForGet(Object value, TypeDescriptor accessorType) { A convertedValue = getConvertedValue(value, accessorType); A normalised; if (normaliseOption.isDontNormalise()) { normalised = convertedValue; } else { normalised = EntryUtil.normaliseValueForGet(convertedValue, getConversionService()); } return normalised; }
public SplitEntryImpl(DocumentImpl document, String key, TypeDescriptor accessorType, TypeDescriptor mutatorType, NormaliseOption normaliseOption) { super(document, key, normaliseOption); this.accessorType = Preconditions.checkNotNull(accessorType); this.mutatorType = mutatorType; }
@Test public void shouldGetSessionsMapByPrincipal() throws Exception { // given String principalNameIndexName = FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME; Document document = new Document(); given(this.converter.getQueryForIndex(anyString(), any(Object.class))).willReturn(mock(Query.class)); given(this.mongoOperations.find(any(Query.class), eq(Document.class), eq(MongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME))) .willReturn(Collections.singletonList(document)); String sessionId = UUID.randomUUID().toString(); MongoSession session = new MongoSession(sessionId, 1800); given(this.converter.convert(document, TypeDescriptor.valueOf(Document.class), TypeDescriptor.valueOf(MongoSession.class))).willReturn(session); // when Map<String, MongoSession> sessionsMap = this.repository.findByIndexNameAndIndexValue(principalNameIndexName, "john"); // then assertThat(sessionsMap).containsOnlyKeys(sessionId); assertThat(sessionsMap).containsValues(session); }
@Override public boolean matches(String propertyName, String propertyValue, TypeDescriptor targetType) { return propertyName != null && propertyName.endsWith(".xml"); }