9fe9b031e77727a6d8e075ea99cb93fe12f3d537
[policy/api.git] / main / src / main / java / org / onap / policy / api / main / config / converter / YamlHttpMessageConverter.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2022 Bell Canada. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.api.main.config.converter;
22
23 import java.io.IOException;
24 import java.io.InputStreamReader;
25 import java.io.OutputStreamWriter;
26 import java.io.Reader;
27 import java.io.Writer;
28 import java.lang.reflect.Type;
29 import java.nio.charset.Charset;
30 import java.nio.charset.StandardCharsets;
31 import org.onap.policy.common.utils.coder.YamlJsonTranslator;
32 import org.springframework.core.GenericTypeResolver;
33 import org.springframework.http.HttpHeaders;
34 import org.springframework.http.HttpInputMessage;
35 import org.springframework.http.HttpOutputMessage;
36 import org.springframework.http.MediaType;
37 import org.springframework.http.converter.AbstractGenericHttpMessageConverter;
38 import org.springframework.http.converter.HttpMessageNotReadableException;
39 import org.springframework.http.converter.HttpMessageNotWritableException;
40 import org.springframework.lang.Nullable;
41
42 /**
43  * Custom converter to marshal/unmarshall data structured with YAML media type.
44  */
45 public class YamlHttpMessageConverter extends AbstractGenericHttpMessageConverter<Object> {
46
47     public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
48
49     private static final YamlJsonTranslator TRANSLATOR = new YamlJsonTranslator();
50
51     public YamlHttpMessageConverter() {
52         super(new MediaType("application", "yaml"));
53         setDefaultCharset(DEFAULT_CHARSET);
54     }
55
56     @Override
57     public final Object read(Type type, @Nullable Class<?> contextClass, HttpInputMessage inputMessage)
58         throws IOException {
59         return readResolved(GenericTypeResolver.resolveType(type, contextClass), inputMessage);
60     }
61
62     @Override
63     protected final Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException {
64         return readResolved(clazz, inputMessage);
65     }
66
67     private Object readInternal(Type resolvedType, Reader reader) {
68         Class<?> clazz = (Class<?>) resolvedType;
69         return TRANSLATOR.fromYaml(reader, clazz);
70     }
71
72     @Override
73     protected final void writeInternal(Object object, @Nullable Type type, HttpOutputMessage outputMessage)
74         throws IOException {
75         Writer writer = getWriter(outputMessage);
76         try {
77             writeInternal(object, type, writer);
78         } catch (Exception ex) {
79             throw new HttpMessageNotWritableException("Could not write YAML: " + ex.getMessage(), ex);
80         }
81         writer.flush();
82     }
83
84     private void writeInternal(Object object, @Nullable Type type, Writer writer) {
85         TRANSLATOR.toYaml(writer, object);
86     }
87
88     private Object readResolved(Type resolvedType, HttpInputMessage inputMessage) throws IOException {
89         Reader reader = getReader(inputMessage);
90         try {
91             return readInternal(resolvedType, reader);
92         } catch (Exception ex) {
93             throw new HttpMessageNotReadableException("Could not read YAML: " + ex.getMessage(), ex, inputMessage);
94         }
95     }
96
97     private static Reader getReader(HttpInputMessage inputMessage) throws IOException {
98         return new InputStreamReader(inputMessage.getBody(), getCharset(inputMessage.getHeaders()));
99     }
100
101     private static Writer getWriter(HttpOutputMessage outputMessage) throws IOException {
102         return new OutputStreamWriter(outputMessage.getBody(), getCharset(outputMessage.getHeaders()));
103     }
104
105     private static Charset getCharset(HttpHeaders headers) {
106         Charset charset = (headers.getContentType() == null ? null : headers.getContentType().getCharset());
107         return (charset != null ? charset : DEFAULT_CHARSET);
108     }
109 }