001/* 002 * Copyright 2002-2019 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.http.converter.feed; 018 019import java.io.IOException; 020import java.io.InputStreamReader; 021import java.io.OutputStreamWriter; 022import java.io.Reader; 023import java.io.Writer; 024import java.nio.charset.Charset; 025import java.nio.charset.StandardCharsets; 026 027import com.rometools.rome.feed.WireFeed; 028import com.rometools.rome.io.FeedException; 029import com.rometools.rome.io.WireFeedInput; 030import com.rometools.rome.io.WireFeedOutput; 031 032import org.springframework.http.HttpInputMessage; 033import org.springframework.http.HttpOutputMessage; 034import org.springframework.http.MediaType; 035import org.springframework.http.converter.AbstractHttpMessageConverter; 036import org.springframework.http.converter.HttpMessageNotReadableException; 037import org.springframework.http.converter.HttpMessageNotWritableException; 038import org.springframework.util.StringUtils; 039 040/** 041 * Abstract base class for Atom and RSS Feed message converters, using the 042 * <a href="https://github.com/rometools/rome">ROME tools</a> project. 043 * 044 * <p><b>NOTE: As of Spring 4.1, this is based on the {@code com.rometools} 045 * variant of ROME, version 1.5. Please upgrade your build dependency.</b> 046 * 047 * @author Arjen Poutsma 048 * @since 3.0.2 049 * @param <T> the converted object type 050 * @see AtomFeedHttpMessageConverter 051 * @see RssChannelHttpMessageConverter 052 */ 053public abstract class AbstractWireFeedHttpMessageConverter<T extends WireFeed> 054 extends AbstractHttpMessageConverter<T> { 055 056 /** 057 * The default charset used by the converter. 058 */ 059 public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; 060 061 062 protected AbstractWireFeedHttpMessageConverter(MediaType supportedMediaType) { 063 super(supportedMediaType); 064 } 065 066 067 @Override 068 @SuppressWarnings("unchecked") 069 protected T readInternal(Class<? extends T> clazz, HttpInputMessage inputMessage) 070 throws IOException, HttpMessageNotReadableException { 071 072 WireFeedInput feedInput = new WireFeedInput(); 073 MediaType contentType = inputMessage.getHeaders().getContentType(); 074 Charset charset = (contentType != null && contentType.getCharset() != null ? 075 contentType.getCharset() : DEFAULT_CHARSET); 076 try { 077 Reader reader = new InputStreamReader(inputMessage.getBody(), charset); 078 return (T) feedInput.build(reader); 079 } 080 catch (FeedException ex) { 081 throw new HttpMessageNotReadableException("Could not read WireFeed: " + ex.getMessage(), ex, inputMessage); 082 } 083 } 084 085 @Override 086 protected void writeInternal(T wireFeed, HttpOutputMessage outputMessage) 087 throws IOException, HttpMessageNotWritableException { 088 089 Charset charset = (StringUtils.hasLength(wireFeed.getEncoding()) ? 090 Charset.forName(wireFeed.getEncoding()) : DEFAULT_CHARSET); 091 MediaType contentType = outputMessage.getHeaders().getContentType(); 092 if (contentType != null) { 093 contentType = new MediaType(contentType, charset); 094 outputMessage.getHeaders().setContentType(contentType); 095 } 096 097 WireFeedOutput feedOutput = new WireFeedOutput(); 098 try { 099 Writer writer = new OutputStreamWriter(outputMessage.getBody(), charset); 100 feedOutput.output(wireFeed, writer); 101 } 102 catch (FeedException ex) { 103 throw new HttpMessageNotWritableException("Could not write WireFeed: " + ex.getMessage(), ex); 104 } 105 } 106 107}