diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.java index 84ab48f7a9e..89297057d28 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.java @@ -64,7 +64,8 @@ public class TypeDescriptor { typeDescriptorCache.put(Double.class, new TypeDescriptor(Double.class)); typeDescriptorCache.put(String.class, new TypeDescriptor(String.class)); } - + + private Class type; private MethodParameter methodParameter; @@ -81,6 +82,7 @@ public class TypeDescriptor { private Annotation[] annotations; + /** * Create a new type descriptor from a method or constructor parameter. *

Use this constructor when a target conversion point originates from a method parameter, @@ -127,38 +129,36 @@ public class TypeDescriptor { this.type = type; } - // static factory methods + /** + * Internal constructor for a NULL descriptor. + */ + private TypeDescriptor() { + } /** - * Create a new type descriptor for the class of the given object. - * @param object the object - * @return the type descriptor + * Create a new descriptor for the type of the given value. + *

Use this constructor when a conversion point comes from a source such as a Map or + * Collection, where no additional context is available but elements can be introspected. + * @param type the actual type to wrap */ - public static TypeDescriptor forObject(Object object) { - if (object == null) { - return NULL; - } - else if (object instanceof Collection || object instanceof Map) { - return new TypeDescriptor(object); - } - else { - return valueOf(object.getClass()); - } + private TypeDescriptor(Object value) { + Assert.notNull(value, "Value must not be null"); + this.value = value; + this.type = value.getClass(); } - + /** - * Create a new type descriptor for the given class. - * @param type the class - * @return the type descriptor + * Create a new descriptor for the given type. + *

Use this constructor when a conversion point comes from a plain source type, + * where no additional context is available. + * @param type the actual type to wrap */ - public static TypeDescriptor valueOf(Class type) { - if (type == null) { - return TypeDescriptor.NULL; - } - TypeDescriptor desc = typeDescriptorCache.get(type); - return (desc != null ? desc : new TypeDescriptor(type)); + private TypeDescriptor(Class type) { + Assert.notNull(type, "Type must not be null"); + this.type = type; } + /** * Return the wrapped MethodParameter, if any. *

Note: Either MethodParameter or Field is available. @@ -255,13 +255,14 @@ public class TypeDescriptor { } /** - * Return the element type as a type descriptor; if the element type is null (cannot be determined), the type descriptor is derived from the element argument. + * Return the element type as a type descriptor; if the element type is null (cannot be determined), + * the type descriptor is derived from the element argument. * @param element the element * @return the element type descriptor */ public TypeDescriptor getElementTypeDescriptor(Object element) { TypeDescriptor elementType = getElementTypeDescriptor(); - return elementType != TypeDescriptor.NULL ? elementType : TypeDescriptor.forObject(element); + return (elementType != TypeDescriptor.NULL ? elementType : forObject(element)); } /** @@ -318,20 +319,21 @@ public class TypeDescriptor { * Returns map value type as a type descriptor. */ public synchronized TypeDescriptor getMapValueTypeDescriptor() { - if (mapValueType == null) { + if (this.mapValueType == null) { mapValueType = forElementType(resolveMapValueType()); } - return mapValueType; + return this.mapValueType; } /** - * Return the map value type as a type descriptor; if the value type is null (cannot be determined), the type descriptor is derived from the value argument. + * Return the map value type as a type descriptor; if the value type is null + * (cannot be determined), the type descriptor is derived from the value argument. * @param value the value * @return the map value type descriptor */ public TypeDescriptor getMapValueTypeDescriptor(Object value) { TypeDescriptor valueType = getMapValueTypeDescriptor(); - return valueType != TypeDescriptor.NULL ? valueType : TypeDescriptor.forObject(value); + return (valueType != TypeDescriptor.NULL ? valueType : TypeDescriptor.forObject(value)); } /** @@ -366,10 +368,15 @@ public class TypeDescriptor { return true; } if (isCollection() && targetType.isCollection() || isArray() && targetType.isArray()) { - return targetType.getType().isAssignableFrom(getType()) && getElementTypeDescriptor().isAssignableTo(targetType.getElementTypeDescriptor()); - } else if (isMap() && targetType.isMap()) { - return targetType.getType().isAssignableFrom(getType()) && getMapKeyTypeDescriptor().isAssignableTo(targetType.getMapKeyTypeDescriptor()) && getMapValueTypeDescriptor().isAssignableTo(targetType.getMapValueTypeDescriptor()); - } else { + return targetType.getType().isAssignableFrom(getType()) && + getElementTypeDescriptor().isAssignableTo(targetType.getElementTypeDescriptor()); + } + else if (isMap() && targetType.isMap()) { + return targetType.getType().isAssignableFrom(getType()) && + getMapKeyTypeDescriptor().isAssignableTo(targetType.getMapKeyTypeDescriptor()) && + getMapValueTypeDescriptor().isAssignableTo(targetType.getMapValueTypeDescriptor()); + } + else { return targetType.getObjectType().isAssignableFrom(getObjectType()); } } @@ -383,14 +390,17 @@ public class TypeDescriptor { public TypeDescriptor forElementType(Class elementType) { if (getType().equals(elementType)) { return this; - } else if (elementType == null) { + } + else if (elementType == null) { return TypeDescriptor.NULL; - } else if (this.methodParameter != null) { + } + else if (this.methodParameter != null) { return new TypeDescriptor(this.methodParameter, elementType); } else if (this.field != null) { return new TypeDescriptor(this.field, elementType); - } else { + } + else { return TypeDescriptor.valueOf(elementType); } } @@ -403,12 +413,16 @@ public class TypeDescriptor { if (this == td) { return true; } - boolean annotatedTypeEquals = getType().equals(td.getType()) && ObjectUtils.nullSafeEquals(getAnnotations(), td.getAnnotations()); + boolean annotatedTypeEquals = + getType().equals(td.getType()) && ObjectUtils.nullSafeEquals(getAnnotations(), td.getAnnotations()); if (isCollection()) { return annotatedTypeEquals && ObjectUtils.nullSafeEquals(getElementType(), td.getElementType()); - } else if (isMap()) { - return annotatedTypeEquals && ObjectUtils.nullSafeEquals(getMapKeyType(), td.getMapKeyType()) && ObjectUtils.nullSafeEquals(getMapValueType(), td.getMapValueType()); - } else { + } + else if (isMap()) { + return annotatedTypeEquals && ObjectUtils.nullSafeEquals(getMapKeyType(), td.getMapKeyType()) && + ObjectUtils.nullSafeEquals(getMapValueType(), td.getMapValueType()); + } + else { return annotatedTypeEquals; } } @@ -439,8 +453,11 @@ public class TypeDescriptor { if (isMap()) { Class mapKeyType = getMapKeyType(); Class valueKeyType = getMapValueType(); - builder.append("<").append(mapKeyType != null ? ClassUtils.getQualifiedName(mapKeyType) : "?").append(", ").append(valueKeyType != null ? ClassUtils.getQualifiedName(valueKeyType) : "?").append(">"); - } else if (isCollection()) { + builder.append("<").append(mapKeyType != null ? ClassUtils.getQualifiedName(mapKeyType) : "?"); + builder.append(", ").append(valueKeyType != null ? ClassUtils.getQualifiedName(valueKeyType) : "?"); + builder.append(">"); + } + else if (isCollection()) { Class elementType = getElementType(); builder.append("<").append(elementType != null ? ClassUtils.getQualifiedName(elementType) : "?").append(">"); } @@ -481,7 +498,7 @@ public class TypeDescriptor { } } } - return type != null ? GenericCollectionTypeResolver.getCollectionType((Class) this.type) : null; + return (this.type != null ? GenericCollectionTypeResolver.getCollectionType((Class) this.type) : null); } @SuppressWarnings("unchecked") @@ -501,7 +518,7 @@ public class TypeDescriptor { } } } - return type != null && isMap() ? GenericCollectionTypeResolver.getMapKeyType((Class) this.type) : null; + return (this.type != null && isMap() ? GenericCollectionTypeResolver.getMapKeyType((Class) this.type) : null); } @SuppressWarnings("unchecked") @@ -521,7 +538,7 @@ public class TypeDescriptor { } } } - return isMap() && type != null ? GenericCollectionTypeResolver.getMapValueType((Class) this.type) : null; + return (isMap() && this.type != null ? GenericCollectionTypeResolver.getMapValueType((Class) this.type) : null); } private Annotation[] resolveAnnotations() { @@ -540,34 +557,38 @@ public class TypeDescriptor { return EMPTY_ANNOTATION_ARRAY; } } - + + + // static factory methods + /** - * Internal constructor for a NULL descriptor. + * Create a new type descriptor for the class of the given object. + * @param object the object + * @return the type descriptor */ - private TypeDescriptor() { + public static TypeDescriptor forObject(Object object) { + if (object == null) { + return NULL; + } + else if (object instanceof Collection || object instanceof Map) { + return new TypeDescriptor(object); + } + else { + return valueOf(object.getClass()); + } } /** - * Create a new descriptor for the type of the given value. - *

Use this constructor when a conversion point comes from a source such as a Map or - * Collection, where no additional context is available but elements can be introspected. - * @param type the actual type to wrap + * Create a new type descriptor for the given class. + * @param type the class + * @return the type descriptor */ - private TypeDescriptor(Object value) { - Assert.notNull(value, "Value must not be null"); - this.value = value; - this.type = value.getClass(); - } - - /** - * Create a new descriptor for the given type. - *

Use this constructor when a conversion point comes from a plain source type, - * where no additional context is available. - * @param type the actual type to wrap - */ - private TypeDescriptor(Class type) { - Assert.notNull(type, "Type must not be null"); - this.type = type; + public static TypeDescriptor valueOf(Class type) { + if (type == null) { + return TypeDescriptor.NULL; + } + TypeDescriptor desc = typeDescriptorCache.get(type); + return (desc != null ? desc : new TypeDescriptor(type)); } } diff --git a/org.springframework.core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java b/org.springframework.core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java index 12d2768ad60..9ec877213f6 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java +++ b/org.springframework.core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java @@ -71,8 +71,10 @@ public class PropertyPlaceholderHelper { /** * Creates a new PropertyPlaceholderHelper that uses the supplied prefix and suffix. - * @param placeholderPrefix the prefix that denotes the start of a placeholder. - * @param placeholderSuffix the suffix that denotes the end of a placeholder. + * @param placeholderPrefix the prefix that denotes the start of a placeholder + * @param placeholderSuffix the suffix that denotes the end of a placeholder + * @param valueSeparator the separating character between the placeholder variable + * and the associated default value, if any * @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should be ignored * (true) or cause an exception (false). */ @@ -158,11 +160,9 @@ public class PropertyPlaceholderHelper { // previously resolved placeholder value. propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders); buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal); - if (logger.isTraceEnabled()) { logger.trace("Resolved placeholder '" + placeholder + "'"); } - startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length()); } else if (this.ignoreUnresolvablePlaceholders) { diff --git a/org.springframework.core/src/main/java/org/springframework/util/StringUtils.java b/org.springframework.core/src/main/java/org/springframework/util/StringUtils.java index 6864c83e468..f2505f21c44 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/StringUtils.java +++ b/org.springframework.core/src/main/java/org/springframework/util/StringUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -550,7 +550,7 @@ public abstract class StringUtils { /** * Apply the given relative path to the given path, - * assuming standard Java folder separation (i.e. "/" separators); + * assuming standard Java folder separation (i.e. "/" separators). * @param path the path to start from (usually a full file path) * @param relativePath the relative path to apply * (relative to the full file path above) diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/CommonsClientHttpRequest.java b/org.springframework.web/src/main/java/org/springframework/http/client/CommonsClientHttpRequest.java index 22080b99cad..268b435994e 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/CommonsClientHttpRequest.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/CommonsClientHttpRequest.java @@ -53,13 +53,14 @@ final class CommonsClientHttpRequest extends AbstractClientHttpRequest { this.httpMethod = httpMethod; } + public HttpMethod getMethod() { - return HttpMethod.valueOf(httpMethod.getName()); + return HttpMethod.valueOf(this.httpMethod.getName()); } public URI getURI() { try { - return URI.create(httpMethod.getURI().getEscapedURI()); + return URI.create(this.httpMethod.getURI().getEscapedURI()); } catch (URIException ex) { throw new IllegalStateException("Could not get HttpMethod URI: " + ex.getMessage(), ex); @@ -74,13 +75,13 @@ final class CommonsClientHttpRequest extends AbstractClientHttpRequest { httpMethod.addRequestHeader(headerName, headerValue); } } - if (httpMethod instanceof EntityEnclosingMethod) { - EntityEnclosingMethod entityEnclosingMethod = (EntityEnclosingMethod) httpMethod; + if (this.httpMethod instanceof EntityEnclosingMethod) { + EntityEnclosingMethod entityEnclosingMethod = (EntityEnclosingMethod) this.httpMethod; RequestEntity requestEntity = new ByteArrayRequestEntity(output); entityEnclosingMethod.setRequestEntity(requestEntity); } - httpClient.executeMethod(httpMethod); - return new CommonsClientHttpResponse(httpMethod); + this.httpClient.executeMethod(this.httpMethod); + return new CommonsClientHttpResponse(this.httpMethod); } } diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/CommonsClientHttpResponse.java b/org.springframework.web/src/main/java/org/springframework/http/client/CommonsClientHttpResponse.java index c2b2e550ea3..0cc7d28417f 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/CommonsClientHttpResponse.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/CommonsClientHttpResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ import org.apache.commons.httpclient.HttpMethod; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.client.ClientHttpResponse; /** * {@link org.springframework.http.client.ClientHttpResponse} implementation that uses @@ -42,34 +41,36 @@ final class CommonsClientHttpResponse implements ClientHttpResponse { private HttpHeaders headers; + CommonsClientHttpResponse(HttpMethod httpMethod) { this.httpMethod = httpMethod; } + public HttpStatus getStatusCode() { - return HttpStatus.valueOf(httpMethod.getStatusCode()); + return HttpStatus.valueOf(this.httpMethod.getStatusCode()); } public String getStatusText() { - return httpMethod.getStatusText(); + return this.httpMethod.getStatusText(); } public HttpHeaders getHeaders() { - if (headers == null) { - headers = new HttpHeaders(); - for (Header header : httpMethod.getResponseHeaders()) { - headers.add(header.getName(), header.getValue()); + if (this.headers == null) { + this.headers = new HttpHeaders(); + for (Header header : this.httpMethod.getResponseHeaders()) { + this.headers.add(header.getName(), header.getValue()); } } - return headers; + return this.headers; } public InputStream getBody() throws IOException { - return httpMethod.getResponseBodyAsStream(); + return this.httpMethod.getResponseBodyAsStream(); } public void close() { - httpMethod.releaseConnection(); + this.httpMethod.releaseConnection(); } } \ No newline at end of file diff --git a/org.springframework.web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java b/org.springframework.web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java index b2deea30b06..35a4717b54a 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java +++ b/org.springframework.web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java @@ -97,6 +97,7 @@ public class FormHttpMessageConverter implements HttpMessageConverter> partConverters = new ArrayList>(); + public FormHttpMessageConverter() { this.partConverters.add(new ByteArrayHttpMessageConverter()); StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(); @@ -106,6 +107,7 @@ public class FormHttpMessageConverter implements HttpMessageConverter clazz, MediaType mediaType) { if (!MultiValueMap.class.isAssignableFrom(clazz)) { return false; @@ -151,8 +154,8 @@ public class FormHttpMessageConverter implements HttpMessageConverter read(Class> clazz, - HttpInputMessage inputMessage) - throws IOException, HttpMessageNotReadableException { + HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { + MediaType contentType = inputMessage.getHeaders().getContentType(); Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : this.charset; String body = FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset)); @@ -201,9 +204,7 @@ public class FormHttpMessageConverter implements HttpMessageConverter form, HttpOutputMessage outputMessage) throws IOException { - outputMessage.getHeaders().setContentType(MediaType.APPLICATION_FORM_URLENCODED); - StringBuilder builder = new StringBuilder(); for (Iterator nameIterator = form.keySet().iterator(); nameIterator.hasNext();) { String name = nameIterator.next(); @@ -225,8 +226,7 @@ public class FormHttpMessageConverter implements HttpMessageConverter parts, HttpOutputMessage outputMessage) - throws IOException { + private void writeMultipart(MultiValueMap parts, HttpOutputMessage outputMessage) throws IOException { byte[] boundary = generateMultipartBoundary(); Map parameters = Collections.singletonMap("boundary", new String(boundary, "US-ASCII")); @@ -304,7 +304,6 @@ public class FormHttpMessageConverter implements HttpMessageConverterDefault implementation returns a random boundary. Can be overridden in subclasses. */ protected byte[] generateMultipartBoundary() { @@ -316,11 +315,9 @@ public class FormHttpMessageConverter implements HttpMessageConverterDefault implementation returns {@link Resource#getFilename()} if the part is a {@code Resource}, and * {@code null} in other cases. Can be overridden in subclasses. - * * @param part the part to determine the file name for * @return the filename, or {@code null} if not known */ @@ -334,10 +331,10 @@ public class FormHttpMessageConverter implements HttpMessageConverter

The name of the request parameter defaults to _method, but can be - * changed via the {@link #setMethodParam(String) methodParam} property. + * adapted via the {@link #setMethodParam(String) methodParam} property. * *

NOTE: This filter needs to run after multipart processing in case of a multipart * POST request, due to its inherent need for checking a POST body parameter. @@ -70,7 +70,7 @@ public class HiddenHttpMethodFilter extends OncePerRequestFilter { String paramValue = request.getParameter(this.methodParam); if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) { String method = paramValue.toUpperCase(Locale.ENGLISH); - HttpServletRequest wrapper = new HttpMethodRequestWrapper(method, request); + HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method); filterChain.doFilter(wrapper, response); } else { @@ -87,7 +87,7 @@ public class HiddenHttpMethodFilter extends OncePerRequestFilter { private final String method; - public HttpMethodRequestWrapper(String method, HttpServletRequest request) { + public HttpMethodRequestWrapper(HttpServletRequest request, String method) { super(request); this.method = method; }