Java tutorial
/* * Copyright 2002-2013 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.messaging.support.converter; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.Assert; import org.springframework.util.MimeType; /** * Abstract base class for {@link MessageConverter} implementations including support for * common properties and a partial implementation of the conversion methods mainly to * check if the converter supports the conversion based on the payload class and MIME * type. * * @author Rossen Stoyanchev * @since 4.0 */ public abstract class AbstractMessageConverter implements MessageConverter { protected final Log logger = LogFactory.getLog(getClass()); private final List<MimeType> supportedMimeTypes; private Class<?> serializedPayloadClass = byte[].class; private ContentTypeResolver contentTypeResolver; /** * Construct an {@code AbstractMessageConverter} with one supported MIME type. * @param supportedMimeType the supported MIME type */ protected AbstractMessageConverter(MimeType supportedMimeType) { this.supportedMimeTypes = Collections.<MimeType>singletonList(supportedMimeType); } /** * Construct an {@code AbstractMessageConverter} with multiple supported MIME type. * @param supportedMimeTypes the supported MIME types */ protected AbstractMessageConverter(Collection<MimeType> supportedMimeTypes) { Assert.notNull(supportedMimeTypes, "'supportedMimeTypes' is required"); this.supportedMimeTypes = new ArrayList<MimeType>(supportedMimeTypes); } /** * Return the configured supported MIME types. */ public List<MimeType> getSupportedMimeTypes() { return Collections.unmodifiableList(this.supportedMimeTypes); } /** * Configure the {@link ContentTypeResolver} to use. * <p> * The default value is {@code null}. However when {@link CompositeMessageConverter} * is used it configures all of its delegates with a default resolver. */ public void setContentTypeResolver(ContentTypeResolver resolver) { this.contentTypeResolver = resolver; } /** * Return the default {@link ContentTypeResolver}. */ public ContentTypeResolver getContentTypeResolver() { return this.contentTypeResolver; } /** * Configure the preferred serialization class to use (byte[] or String) when * converting an Object payload to a {@link Message}. * <p> * The default value is byte[]. * * @param clazz either byte[] or String */ public void setSerializedPayloadClass(Class<?> clazz) { Assert.isTrue(byte[].class.equals(clazz) || String.class.equals(clazz), "Payload class must be byte[] or String: " + clazz); this.serializedPayloadClass = clazz; } /** * Return the configured preferred serialization payload class. */ public Class<?> getSerializedPayloadClass() { return this.serializedPayloadClass; } /** * Returns the default content type for the payload. Called when * {@link #toMessage(Object, MessageHeaders)} is invoked without message headers or * without a content type header. * <p> * By default, this returns the first element of the {@link #getSupportedMimeTypes() * supportedMimeTypes}, if any. Can be overridden in sub-classes. * * @param payload the payload being converted to message * @return the content type, or {@code null} if not known */ protected MimeType getDefaultContentType(Object payload) { List<MimeType> mimeTypes = getSupportedMimeTypes(); return (!mimeTypes.isEmpty() ? mimeTypes.get(0) : null); } /** * Whether the given class is supported by this converter. * * @param clazz the class to test for support * @return {@code true} if supported; {@code false} otherwise */ protected abstract boolean supports(Class<?> clazz); @Override public final Object fromMessage(Message<?> message, Class<?> targetClass) { if (!canConvertFrom(message, targetClass)) { return null; } return convertFromInternal(message, targetClass); } protected boolean canConvertFrom(Message<?> message, Class<?> targetClass) { return (supports(targetClass) && supportsMimeType(message.getHeaders())); } /** * Convert the message payload from serialized form to an Object. */ public abstract Object convertFromInternal(Message<?> message, Class<?> targetClass); @Override public final Message<?> toMessage(Object payload, MessageHeaders headers) { if (!canConvertTo(payload, headers)) { return null; } payload = convertToInternal(payload, headers); MessageBuilder<?> builder = MessageBuilder.withPayload(payload); if (headers != null) { builder.copyHeaders(headers); } MimeType mimeType = getDefaultContentType(payload); if (mimeType != null) { builder.setHeaderIfAbsent(MessageHeaders.CONTENT_TYPE, mimeType); } return builder.build(); } protected boolean canConvertTo(Object payload, MessageHeaders headers) { Class<?> clazz = (payload != null) ? payload.getClass() : null; return (supports(clazz) && supportsMimeType(headers)); } /** * Convert the payload object to serialized form. */ public abstract Object convertToInternal(Object payload, MessageHeaders headers); protected boolean supportsMimeType(MessageHeaders headers) { MimeType mimeType = getMimeType(headers); if (mimeType == null) { return true; } if (getSupportedMimeTypes().isEmpty()) { return true; } for (MimeType supported : getSupportedMimeTypes()) { if (supported.getType().equals(mimeType.getType()) && supported.getSubtype().equals(mimeType.getSubtype())) { return true; } } return false; } protected MimeType getMimeType(MessageHeaders headers) { return (this.contentTypeResolver != null) ? this.contentTypeResolver.resolve(headers) : null; } }