Search in sources :

Example 1 with TypeDescriptor

use of org.springframework.core.convert.TypeDescriptor in project centipede by paulhoule.

the class OptionParser method parse.

public HasOptions parse(Iterable<String> args) throws IllegalAccessException {
    HasOptions options;
    try {
        options = (HasOptions) that.getConstructor().newInstance();
    } catch (NoSuchMethodException ex) {
        throw new IllegalArgumentException("Class " + that + " doesn't have a zero argument constructor", ex);
    } catch (IllegalAccessException ex) {
        throw new IllegalArgumentException("Class " + that + " has a non-public zero argument constructor", ex);
    } catch (InstantiationException ex) {
        throw new IllegalArgumentException("Class " + that + " cannot be abstract", ex);
    } catch (InvocationTargetException ex) {
        throw new IllegalArgumentException("Class " + that + " threw an exception during construction", ex);
    }
    Map<String, RWOption> lookup = getStringAnnotationMap(that);
    for (RWOption o : lookup.values()) {
        if (isSomeKindOfBoolean(o)) {
            o.getField().setBoolean(options, false);
        } else {
            Object defaultValue = null;
            if (!o.getDefaultValue().isEmpty()) {
                try {
                    defaultValue = conversionService.convert(o.getDefaultValue(), TypeDescriptor.valueOf(String.class), new TypeDescriptor(o.getField()));
                } catch (ConversionFailedException x) {
                    throw new UnparsableDefaultException(o.getName(), o.getDefaultValue(), o.getType(), x);
                }
            } else {
                defaultValue = defaultValueFor(o.getType());
            }
            o.getField().set(options, defaultValue);
        }
    }
    Set<Field> sawOption = new HashSet<>();
    Iterator<String> p = args.iterator();
    String peek = null;
    while (p.hasNext()) {
        peek = p.next();
        if (!peek.startsWith("-"))
            break;
        String name = peek.substring(1);
        if (!lookup.containsKey(name))
            throw new InvalidOptionException("invalid option :" + name);
        RWOption field = lookup.get(name);
        sawOption.add(field.getField());
        if (isSomeKindOfBoolean(field)) {
            field.getField().setBoolean(options, true);
        } else {
            String value = p.next();
            try {
                if (field.isList()) {
                    String[] parts = value.split(",");
                    Class elementType = field.getElementType();
                    for (String part : parts) {
                        final Object innerValue = field.convertFrom(options, conversionService, part);
                        ((List) field.getField().get(options)).add(innerValue);
                    }
                } else {
                    final Object innerValue = field.convertFrom(options, conversionService, value);
                    field.getField().set(options, innerValue);
                }
            } catch (ConversionFailedException x) {
                throw new UnparsableOptionException(name, value, field.getType(), x);
            }
        }
        peek = null;
    }
    for (RWOption o : lookup.values()) {
        if (o.isRequired() && !sawOption.contains(o.getField()))
            throw new MissingOptionException("Required option -" + o.getName() + " is missing");
    }
    List<String> positional = new ArrayList<String>();
    if (peek != null)
        positional.add(peek);
    while (p.hasNext()) positional.add(p.next());
    Field positionalField = findPositionalParameter(that);
    if (positionalField != null)
        positionalField.set(options, positional);
    return options;
}
Also used : Field(java.lang.reflect.Field) InvocationTargetException(java.lang.reflect.InvocationTargetException) TypeDescriptor(org.springframework.core.convert.TypeDescriptor) ConversionFailedException(org.springframework.core.convert.ConversionFailedException)

Example 2 with TypeDescriptor

use of org.springframework.core.convert.TypeDescriptor in project spring-boot by spring-projects.

the class RelaxedDataBinder method extendMapIfNecessary.

private void extendMapIfNecessary(BeanWrapper wrapper, BeanPath path, int index) {
    String name = path.prefix(index);
    TypeDescriptor parent = wrapper.getPropertyTypeDescriptor(name);
    if (parent == null) {
        return;
    }
    TypeDescriptor descriptor = parent.getMapValueTypeDescriptor();
    if (descriptor == null) {
        descriptor = TypeDescriptor.valueOf(Object.class);
    }
    if (!descriptor.isMap() && !descriptor.isCollection() && !descriptor.getType().equals(Object.class)) {
        return;
    }
    String extensionName = path.prefix(index + 1);
    if (wrapper.isReadableProperty(extensionName)) {
        Object currentValue = wrapper.getPropertyValue(extensionName);
        if ((descriptor.isCollection() && currentValue instanceof Collection) || (!descriptor.isCollection() && currentValue instanceof Map)) {
            return;
        }
    }
    Object extend = new LinkedHashMap<String, Object>();
    if (descriptor.isCollection()) {
        extend = new ArrayList<>();
    }
    if (descriptor.getType().equals(Object.class) && path.isLastNode(index)) {
        extend = BLANK;
    }
    wrapper.setPropertyValue(extensionName, extend);
}
Also used : TypeDescriptor(org.springframework.core.convert.TypeDescriptor) Collection(java.util.Collection) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) MultiValueMap(org.springframework.util.MultiValueMap) LinkedMultiValueMap(org.springframework.util.LinkedMultiValueMap) LinkedHashMap(java.util.LinkedHashMap)

Example 3 with TypeDescriptor

use of org.springframework.core.convert.TypeDescriptor in project spring-boot by spring-projects.

the class RelaxedDataBinder method extendCollectionIfNecessary.

private void extendCollectionIfNecessary(BeanWrapper wrapper, BeanPath path, int index) {
    String name = path.prefix(index);
    TypeDescriptor elementDescriptor = wrapper.getPropertyTypeDescriptor(name).getElementTypeDescriptor();
    if (!elementDescriptor.isMap() && !elementDescriptor.isCollection() && !elementDescriptor.getType().equals(Object.class)) {
        return;
    }
    Object extend = new LinkedHashMap<String, Object>();
    if (!elementDescriptor.isMap() && path.isArrayIndex(index)) {
        extend = new ArrayList<>();
    }
    wrapper.setPropertyValue(path.prefix(index + 1), extend);
}
Also used : TypeDescriptor(org.springframework.core.convert.TypeDescriptor) LinkedHashMap(java.util.LinkedHashMap)

Example 4 with TypeDescriptor

use of org.springframework.core.convert.TypeDescriptor in project spring-framework by spring-projects.

the class AbstractPropertyBindingResult method findEditor.

/**
	 * This implementation exposes a PropertyEditor adapter for a Formatter,
	 * if applicable.
	 */
@Override
public PropertyEditor findEditor(String field, Class<?> valueType) {
    Class<?> valueTypeForLookup = valueType;
    if (valueTypeForLookup == null) {
        valueTypeForLookup = getFieldType(field);
    }
    PropertyEditor editor = super.findEditor(field, valueTypeForLookup);
    if (editor == null && this.conversionService != null) {
        TypeDescriptor td = null;
        if (field != null) {
            TypeDescriptor ptd = getPropertyAccessor().getPropertyTypeDescriptor(fixedField(field));
            if (valueType == null || valueType.isAssignableFrom(ptd.getType())) {
                td = ptd;
            }
        }
        if (td == null) {
            td = TypeDescriptor.valueOf(valueTypeForLookup);
        }
        if (this.conversionService.canConvert(TypeDescriptor.valueOf(String.class), td)) {
            editor = new ConvertingPropertyEditorAdapter(this.conversionService, td);
        }
    }
    return editor;
}
Also used : ConvertingPropertyEditorAdapter(org.springframework.core.convert.support.ConvertingPropertyEditorAdapter) TypeDescriptor(org.springframework.core.convert.TypeDescriptor) PropertyEditor(java.beans.PropertyEditor)

Example 5 with TypeDescriptor

use of org.springframework.core.convert.TypeDescriptor in project spring-framework by spring-projects.

the class AbstractNestablePropertyAccessor method getPropertyValue.

@SuppressWarnings("unchecked")
protected Object getPropertyValue(PropertyTokenHolder tokens) throws BeansException {
    String propertyName = tokens.canonicalName;
    String actualName = tokens.actualName;
    PropertyHandler ph = getLocalPropertyHandler(actualName);
    if (ph == null || !ph.isReadable()) {
        throw new NotReadablePropertyException(getRootClass(), this.nestedPath + propertyName);
    }
    try {
        Object value = ph.getValue();
        if (tokens.keys != null) {
            if (value == null) {
                if (isAutoGrowNestedPaths()) {
                    value = setDefaultValue(tokens.actualName);
                } else {
                    throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value of property referenced in indexed " + "property path '" + propertyName + "': returned null");
                }
            }
            String indexedPropertyName = tokens.actualName;
            // apply indexes and map keys
            for (int i = 0; i < tokens.keys.length; i++) {
                String key = tokens.keys[i];
                if (value == null) {
                    throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value of property referenced in indexed " + "property path '" + propertyName + "': returned null");
                } else if (value.getClass().isArray()) {
                    int index = Integer.parseInt(key);
                    value = growArrayIfNecessary(value, index, indexedPropertyName);
                    value = Array.get(value, index);
                } else if (value instanceof List) {
                    int index = Integer.parseInt(key);
                    List<Object> list = (List<Object>) value;
                    growCollectionIfNecessary(list, index, indexedPropertyName, ph, i + 1);
                    value = list.get(index);
                } else if (value instanceof Set) {
                    // Apply index to Iterator in case of a Set.
                    Set<Object> set = (Set<Object>) value;
                    int index = Integer.parseInt(key);
                    if (index < 0 || index >= set.size()) {
                        throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, "Cannot get element with index " + index + " from Set of size " + set.size() + ", accessed using property path '" + propertyName + "'");
                    }
                    Iterator<Object> it = set.iterator();
                    for (int j = 0; it.hasNext(); j++) {
                        Object elem = it.next();
                        if (j == index) {
                            value = elem;
                            break;
                        }
                    }
                } else if (value instanceof Map) {
                    Map<Object, Object> map = (Map<Object, Object>) value;
                    Class<?> mapKeyType = ph.getResolvableType().getNested(i + 1).asMap().resolveGeneric(0);
                    // IMPORTANT: Do not pass full property name in here - property editors
                    // must not kick in for map keys but rather only for map values.
                    TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(mapKeyType);
                    Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType, typeDescriptor);
                    value = map.get(convertedMapKey);
                } else {
                    throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, "Property referenced in indexed property path '" + propertyName + "' is neither an array nor a List nor a Set nor a Map; returned value was [" + value + "]");
                }
                indexedPropertyName += PROPERTY_KEY_PREFIX + key + PROPERTY_KEY_SUFFIX;
            }
        }
        return value;
    } catch (IndexOutOfBoundsException ex) {
        throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, "Index of out of bounds in property path '" + propertyName + "'", ex);
    } catch (NumberFormatException ex) {
        throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, "Invalid index in property path '" + propertyName + "'", ex);
    } catch (TypeMismatchException ex) {
        throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, "Invalid index in property path '" + propertyName + "'", ex);
    } catch (InvocationTargetException ex) {
        throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, "Getter for property '" + actualName + "' threw exception", ex);
    } catch (Exception ex) {
        throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, "Illegal attempt to get property '" + actualName + "' threw exception", ex);
    }
}
Also used : Set(java.util.Set) InvocationTargetException(java.lang.reflect.InvocationTargetException) ConverterNotFoundException(org.springframework.core.convert.ConverterNotFoundException) PrivilegedActionException(java.security.PrivilegedActionException) ConversionException(org.springframework.core.convert.ConversionException) UndeclaredThrowableException(java.lang.reflect.UndeclaredThrowableException) InvocationTargetException(java.lang.reflect.InvocationTargetException) TypeDescriptor(org.springframework.core.convert.TypeDescriptor) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

TypeDescriptor (org.springframework.core.convert.TypeDescriptor)114 Test (org.junit.Test)61 ArrayList (java.util.ArrayList)35 List (java.util.List)20 Map (java.util.Map)16 HashMap (java.util.HashMap)14 LinkedHashMap (java.util.LinkedHashMap)13 LinkedList (java.util.LinkedList)12 MethodParameter (org.springframework.core.MethodParameter)12 Collection (java.util.Collection)11 ConversionFailedException (org.springframework.core.convert.ConversionFailedException)10 Method (java.lang.reflect.Method)9 AccessException (org.springframework.expression.AccessException)9 ConverterNotFoundException (org.springframework.core.convert.ConverterNotFoundException)8 TypedValue (org.springframework.expression.TypedValue)8 StandardEvaluationContext (org.springframework.expression.spel.support.StandardEvaluationContext)8 LinkedMultiValueMap (org.springframework.util.LinkedMultiValueMap)8 MultiValueMap (org.springframework.util.MultiValueMap)8 AbstractList (java.util.AbstractList)7 Field (java.lang.reflect.Field)6