List of usage examples for org.springframework.core.convert TypeDescriptor nested
@Nullable private static TypeDescriptor nested(TypeDescriptor typeDescriptor, int nestingLevel)
From source file:org.springjutsu.validation.util.PathUtils.java
/** * Determine the class of each step in the selected path on the target class. * @param clazz Class to check // w w w. j a v a 2s . c om * @param path Path to check * @param unwrapCollectionTypes if true returns the parameterized collection type * @return array of classes for each step of path. */ public static Class<?>[] getClassesForPathTokens(Class<?> clazz, String path, boolean unwrapCollectionTypes) { if (path == null || path.trim().isEmpty()) { return null; } Class<?> intermediateClass = clazz; String[] pathTokens = path.split("\\."); Class<?>[] pathClasses = new Class<?>[pathTokens.length]; for (int i = 0; i < pathTokens.length; i++) { String token = pathTokens[i]; token = token.replaceAll("\\[[^\\]]+\\]$", ""); PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(intermediateClass, token); if (descriptor == null) { return null; } else if (List.class.isAssignableFrom(descriptor.getPropertyType())) { intermediateClass = TypeDescriptor.nested(ReflectionUtils.findField(intermediateClass, token), 1) .getObjectType(); } else if (descriptor.getPropertyType().isArray()) { intermediateClass = descriptor.getPropertyType().getComponentType(); } else { intermediateClass = descriptor.getPropertyType(); } if (unwrapCollectionTypes) { pathClasses[i] = intermediateClass; } else { pathClasses[i] = descriptor.getPropertyType(); } } return pathClasses; }
From source file:de.escalon.hypermedia.action.ActionInputParameter.java
/** * Creates input parameter descriptor./*from www .j av a 2s. c om*/ * * @param methodParameter to describe * @param value used during sample invocation * @param conversionService to apply to value */ public ActionInputParameter(MethodParameter methodParameter, Object value, ConversionService conversionService) { this.methodParameter = methodParameter; this.value = value; this.requestBody = methodParameter.getParameterAnnotation(RequestBody.class); this.requestParam = methodParameter.getParameterAnnotation(RequestParam.class); this.pathVariable = methodParameter.getParameterAnnotation(PathVariable.class); // always determine input constraints, // might be a nested property which is neither requestBody, requestParam nor pathVariable this.inputAnnotation = methodParameter.getParameterAnnotation(Input.class); if (inputAnnotation != null) { putInputConstraint(MIN, Integer.MIN_VALUE, inputAnnotation.min()); putInputConstraint(MAX, Integer.MAX_VALUE, inputAnnotation.max()); putInputConstraint(MIN_LENGTH, Integer.MIN_VALUE, inputAnnotation.minLength()); putInputConstraint(MAX_LENGTH, Integer.MAX_VALUE, inputAnnotation.maxLength()); putInputConstraint(STEP, 0, inputAnnotation.step()); putInputConstraint(PATTERN, "", inputAnnotation.pattern()); } this.conversionService = conversionService; this.typeDescriptor = TypeDescriptor.nested(methodParameter, 0); }
From source file:de.escalon.hypermedia.spring.ActionInputParameter.java
/** * Creates action input parameter./*w ww.j a va2 s .co m*/ * * @param methodParameter * to describe * @param value * used during sample invocation * @param conversionService * to apply to value */ public ActionInputParameter(MethodParameter methodParameter, Object value, ConversionService conversionService) { this.methodParameter = methodParameter; this.value = value; this.requestBody = methodParameter.getParameterAnnotation(RequestBody.class); this.requestParam = methodParameter.getParameterAnnotation(RequestParam.class); this.pathVariable = methodParameter.getParameterAnnotation(PathVariable.class); this.requestHeader = methodParameter.getParameterAnnotation(RequestHeader.class); // always determine input constraints, // might be a nested property which is neither requestBody, requestParam nor pathVariable this.inputAnnotation = methodParameter.getParameterAnnotation(Input.class); if (inputAnnotation != null) { putInputConstraint(Input.MIN, Integer.MIN_VALUE, inputAnnotation.min()); putInputConstraint(Input.MAX, Integer.MAX_VALUE, inputAnnotation.max()); putInputConstraint(Input.MIN_LENGTH, Integer.MIN_VALUE, inputAnnotation.minLength()); putInputConstraint(Input.MAX_LENGTH, Integer.MAX_VALUE, inputAnnotation.maxLength()); putInputConstraint(Input.STEP, 0, inputAnnotation.step()); putInputConstraint(Input.PATTERN, "", inputAnnotation.pattern()); } this.conversionService = conversionService; this.typeDescriptor = TypeDescriptor.nested(methodParameter, 0); }
From source file:de.escalon.hypermedia.spring.SpringActionInputParameter.java
/** * Creates action input parameter.//from w w w . ja v a 2s . c om * * @param methodParameter * to describe * @param value * used during sample invocation * @param conversionService * to apply to value */ public SpringActionInputParameter(MethodParameter methodParameter, Object value, ConversionService conversionService) { this.methodParameter = methodParameter; this.value = value; this.requestBody = methodParameter.getParameterAnnotation(RequestBody.class); this.requestParam = methodParameter.getParameterAnnotation(RequestParam.class); this.pathVariable = methodParameter.getParameterAnnotation(PathVariable.class); this.requestHeader = methodParameter.getParameterAnnotation(RequestHeader.class); // always determine input constraints, // might be a nested property which is neither requestBody, requestParam nor pathVariable this.inputAnnotation = methodParameter.getParameterAnnotation(Input.class); if (inputAnnotation != null) { putInputConstraint(Input.MIN, Integer.MIN_VALUE, inputAnnotation.min()); putInputConstraint(Input.MAX, Integer.MAX_VALUE, inputAnnotation.max()); putInputConstraint(Input.MIN_LENGTH, Integer.MIN_VALUE, inputAnnotation.minLength()); putInputConstraint(Input.MAX_LENGTH, Integer.MAX_VALUE, inputAnnotation.maxLength()); putInputConstraint(Input.STEP, 0, inputAnnotation.step()); putInputConstraint(Input.PATTERN, "", inputAnnotation.pattern()); } this.conversionService = conversionService; this.typeDescriptor = TypeDescriptor.nested(methodParameter, 0); }
From source file:de.escalon.hypermedia.action.ActionInputParameter.java
public Object[] getPossibleValues(ActionDescriptor actionDescriptor) { try {/* w ww .j a v a2 s . c o m*/ Class<?> parameterType = getParameterType(); Object[] possibleValues; Class<?> nested; if (Enum[].class.isAssignableFrom(parameterType)) { possibleValues = parameterType.getComponentType().getEnumConstants(); } else if (Enum.class.isAssignableFrom(parameterType)) { possibleValues = parameterType.getEnumConstants(); } else if (Collection.class.isAssignableFrom(parameterType) && Enum.class.isAssignableFrom(nested = TypeDescriptor.nested(methodParameter, 1).getType())) { possibleValues = nested.getEnumConstants(); } else { Select select = methodParameter.getParameterAnnotation(Select.class); if (select != null) { Class<? extends Options> options = select.options(); Options instance = options.newInstance(); List<Object> from = new ArrayList<Object>(); for (String paramName : select.args()) { ActionInputParameter parameterValue = actionDescriptor.getActionInputParameter(paramName); if (parameterValue != null) { from.add(parameterValue.getCallValue()); } } Object[] args = from.toArray(); possibleValues = instance.get(select.value(), args); } else { possibleValues = new Object[0]; } } return possibleValues; } catch (Exception e) { throw new RuntimeException(e); } }
From source file:de.escalon.hypermedia.action.ActionInputParameter.java
public Object[] getPossibleValues(Property property, ActionDescriptor actionDescriptor) { // TODO remove code duplication of getPossibleValues try {/*from w ww . j av a 2 s . com*/ Class<?> parameterType = property.getType(); Object[] possibleValues; Class<?> nested; if (Enum[].class.isAssignableFrom(parameterType)) { possibleValues = parameterType.getComponentType().getEnumConstants(); } else if (Enum.class.isAssignableFrom(parameterType)) { possibleValues = parameterType.getEnumConstants(); } else if (Collection.class.isAssignableFrom(parameterType) && Enum.class.isAssignableFrom(nested = TypeDescriptor.nested(property, 1).getType())) { possibleValues = nested.getEnumConstants(); } else { Annotation[][] parameterAnnotations = property.getWriteMethod().getParameterAnnotations(); // setter has exactly one param Select select = getSelectAnnotationFromFirstParam(parameterAnnotations[0]); if (select != null) { Class<? extends Options> optionsClass = select.options(); Options options = optionsClass.newInstance(); // collect call values to pass to options.get List<Object> from = new ArrayList<Object>(); for (String paramName : select.args()) { ActionInputParameter parameterValue = actionDescriptor.getActionInputParameter(paramName); if (parameterValue != null) { from.add(parameterValue.getCallValue()); } } Object[] args = from.toArray(); possibleValues = options.get(select.value(), args); } else { possibleValues = new Object[0]; } } return possibleValues; } catch (Exception e) { throw new RuntimeException(e); } }
From source file:de.escalon.hypermedia.spring.SpringActionInputParameter.java
public Object[] getPossibleValues(MethodParameter methodParameter, ActionDescriptor actionDescriptor) { try {//from w w w . ja v a 2 s . c om Class<?> parameterType = methodParameter.getNestedParameterType(); Object[] possibleValues; Class<?> nested; if (Enum[].class.isAssignableFrom(parameterType)) { possibleValues = parameterType.getComponentType().getEnumConstants(); } else if (Enum.class.isAssignableFrom(parameterType)) { possibleValues = parameterType.getEnumConstants(); } else if (Collection.class.isAssignableFrom(parameterType) && Enum.class.isAssignableFrom(nested = TypeDescriptor.nested(methodParameter, 1).getType())) { possibleValues = nested.getEnumConstants(); } else { Select select = methodParameter.getParameterAnnotation(Select.class); if (select != null) { Class<? extends Options> optionsClass = select.options(); Options options = optionsClass.newInstance(); // collect call values to pass to options.get List<Object> from = new ArrayList<Object>(); for (String paramName : select.args()) { ActionInputParameter parameterValue = actionDescriptor.getActionInputParameter(paramName); if (parameterValue != null) { from.add(parameterValue.getValue()); } } Object[] args = from.toArray(); possibleValues = options.get(select.value(), args); } else { possibleValues = new Object[0]; } } return possibleValues; } catch (Exception e) { throw new RuntimeException(e); } }
From source file:de.escalon.hypermedia.spring.ActionInputParameter.java
private Object[] getPossibleValues(MethodParameter methodParameter, AnnotatedParameters actionDescriptor) { try {/*www . jav a 2 s .c om*/ Class<?> parameterType = methodParameter.getNestedParameterType(); Object[] possibleValues; Class<?> nested; if (Enum[].class.isAssignableFrom(parameterType)) { possibleValues = parameterType.getComponentType().getEnumConstants(); } else if (Enum.class.isAssignableFrom(parameterType)) { possibleValues = parameterType.getEnumConstants(); } else if (Collection.class.isAssignableFrom(parameterType) && Enum.class.isAssignableFrom(nested = TypeDescriptor.nested(methodParameter, 1).getType())) { possibleValues = nested.getEnumConstants(); } else { Select select = methodParameter.getParameterAnnotation(Select.class); if (select != null) { Class<? extends Options> optionsClass = select.options(); Options options = optionsClass.newInstance(); // collect call values to pass to options.get List<Object> from = new ArrayList<Object>(); for (String paramName : select.args()) { AnnotatedParameter parameterValue = actionDescriptor.getAnnotatedParameter(paramName); if (parameterValue != null) { from.add(parameterValue.getCallValue()); } } Object[] args = from.toArray(); possibleValues = options.get(select.value(), args); } else { possibleValues = new Object[0]; } } return possibleValues; } catch (Exception e) { throw new RuntimeException(e); } }
From source file:net.yasion.common.core.bean.wrapper.impl.ExtendedBeanWrapperImpl.java
@Override public TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException { try {//from w w w . j a va 2s .c o m ExtendedBeanWrapperImpl 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; }
From source file:net.yasion.common.core.bean.wrapper.impl.ExtendedBeanWrapperImpl.java
@SuppressWarnings("unchecked") private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv2) throws BeansException { net.yasion.common.core.bean.wrapper.PropertyValue pv = new net.yasion.common.core.bean.wrapper.PropertyValue( "", null); AfxBeanUtils.copySamePropertyValue(pv2, pv); String propertyName = tokens.canonicalName; String actualName = tokens.actualName; if (tokens.keys != null) { // Apply indexes and map keys: fetch value for all keys but the last one. PropertyTokenHolder getterTokens = new PropertyTokenHolder(); getterTokens.canonicalName = tokens.canonicalName; getterTokens.actualName = tokens.actualName; getterTokens.keys = new String[tokens.keys.length - 1]; System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1); Object propValue;//from www . java2 s . co m try { propValue = getPropertyValue(getterTokens); } catch (NotReadablePropertyException ex) { throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value in property referenced " + "in indexed property path '" + propertyName + "'", ex); } // Set value for last key. String key = tokens.keys[tokens.keys.length - 1]; if (propValue == null) { // null map value case if (isAutoGrowNestedPaths()) { // #TO#DO#: cleanup, this is pretty hacky int lastKeyIndex = tokens.canonicalName.lastIndexOf('['); getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex); propValue = setDefaultValue(getterTokens); } else { throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value in property referenced " + "in indexed property path '" + propertyName + "': returned null"); } } if (propValue.getClass().isArray()) { PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName); Class<?> requiredType = propValue.getClass().getComponentType(); int arrayIndex = Integer.parseInt(key); Object oldValue = null; try { if (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) { oldValue = Array.get(propValue, arrayIndex); } Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType, TypeDescriptor.nested(property(pd), tokens.keys.length)); Array.set(propValue, arrayIndex, convertedValue); } catch (IndexOutOfBoundsException ex) { throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, "Invalid array index in property path '" + propertyName + "'", ex); } } else if (propValue instanceof List) { PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName); Class<?> requiredType = GenericCollectionTypeResolver.getCollectionReturnType(pd.getReadMethod(), tokens.keys.length); List<Object> list = (List<Object>) propValue; int index = Integer.parseInt(key); Object oldValue = null; if (isExtractOldValueForEditor() && index < list.size()) { oldValue = list.get(index); } Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType, TypeDescriptor.nested(property(pd), tokens.keys.length)); int size = list.size(); if (index >= size && index < this.autoGrowCollectionLimit) { for (int i = size; i < index; i++) { try { list.add(null); } catch (NullPointerException ex) { throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, "Cannot set element with index " + index + " in List of size " + size + ", accessed using property path '" + propertyName + "': List does not support filling up gaps with null elements"); } } list.add(convertedValue); } else { try { list.set(index, convertedValue); } catch (IndexOutOfBoundsException ex) { throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, "Invalid list index in property path '" + propertyName + "'", ex); } } } else if (propValue instanceof Map) { PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName); Class<?> mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(pd.getReadMethod(), tokens.keys.length); Class<?> mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(pd.getReadMethod(), tokens.keys.length); Map<Object, Object> map = (Map<Object, Object>) propValue; // 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); Object oldValue = null; if (isExtractOldValueForEditor()) { oldValue = map.get(convertedMapKey); } // Pass full property name and old value in here, since we want full // conversion ability for map values. Object convertedMapValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), mapValueType, TypeDescriptor.nested(property(pd), tokens.keys.length)); map.put(convertedMapKey, convertedMapValue); } else { throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, "Property referenced in indexed property path '" + propertyName + "' is neither an array nor a List nor a Map; returned value was [" + pv.getValue() + "]"); } } else { PropertyDescriptor pd = pv.getResolvedDescriptor(); if (pd == null || !pd.getWriteMethod().getDeclaringClass().isInstance(this.object)) { pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName); if (pd == null || pd.getWriteMethod() == null) { if (pv.isOptional()) { logger.debug("Ignoring optional value for property '" + actualName + "' - property not found on bean class [" + getRootClass().getName() + "]"); return; } else { PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass()); throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName, matches.buildErrorMessage(), matches.getPossibleMatches()); } } pv.getOriginalPropertyValue().setResolvedDescriptor(pd); } Object oldValue = null; try { Object originalValue = pv.getValue(); Object valueToApply = originalValue; if (!Boolean.FALSE.equals(pv.getConversionNecessary())) { if (pv.isConverted()) { valueToApply = pv.getConvertedValue(); } else { if (isExtractOldValueForEditor() && pd.getReadMethod() != null) { final Method readMethod = pd.getReadMethod(); if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) && !readMethod.isAccessible()) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { readMethod.setAccessible(true); return null; } }); } else { readMethod.setAccessible(true); } } try { if (System.getSecurityManager() != null) { oldValue = AccessController .doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { return readMethod.invoke(object); } }, acc); } else { oldValue = readMethod.invoke(object); } } catch (Exception ex) { if (ex instanceof PrivilegedActionException) { ex = ((PrivilegedActionException) ex).getException(); } if (logger.isDebugEnabled()) { logger.debug("Could not read previous value of property '" + this.nestedPath + propertyName + "'", ex); } } } valueToApply = convertForProperty(propertyName, oldValue, originalValue, new TypeDescriptor(property(pd))); } pv.getOriginalPropertyValue().setConversionNecessary(valueToApply != originalValue); } final Method writeMethod = (pd instanceof GenericTypeAwarePropertyDescriptor ? ((GenericTypeAwarePropertyDescriptor) pd).getWriteMethodForActualAccess() : pd.getWriteMethod()); if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { writeMethod.setAccessible(true); return null; } }); } else { writeMethod.setAccessible(true); } } final Object value = valueToApply; if (System.getSecurityManager() != null) { try { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { writeMethod.invoke(object, value); return null; } }, acc); } catch (PrivilegedActionException ex) { throw ex.getException(); } } else { writeMethod.invoke(this.object, value); } } catch (TypeMismatchException ex) { throw ex; } catch (InvocationTargetException ex) { PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue()); if (ex.getTargetException() instanceof ClassCastException) { throw new TypeMismatchException(propertyChangeEvent, pd.getPropertyType(), ex.getTargetException()); } else { throw new MethodInvocationException(propertyChangeEvent, ex.getTargetException()); } } catch (Exception ex) { PropertyChangeEvent pce = new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue()); throw new MethodInvocationException(pce, ex); } } }