001package org.conqat.engine.service.shared.client;
002
003import java.io.IOException;
004import java.util.List;
005import java.util.Map;
006import java.util.Optional;
007
008import org.conqat.engine.commons.util.JsonUtils;
009import org.conqat.engine.core.core.ConQATException;
010import org.conqat.engine.service.shared.EMimeType;
011import org.conqat.engine.service.shared.XmlSerializationUtils;
012
013/**
014 * Provides a deserialization strategy for service calls.
015 */
016public interface IDeserializationFormat<T> {
017
018        /**
019         * Returns the MIME type that should be sent to the server as "Accept" header.
020         * May return empty to indicate that the Accept header should not be set.
021         */
022        Optional<EMimeType> getMimeType();
023
024        /** Deserializes the given data to an object. */
025        T deserialize(String serializedData) throws IOException;
026
027        /** Constructs a deserializer for the given data type from XML. */
028        static <T> IDeserializationFormat<T> fromXml(Class<T> type) {
029                return new IDeserializationFormat<T>() {
030                        @Override
031                        public Optional<EMimeType> getMimeType() {
032                                return Optional.of(EMimeType.XML);
033                        }
034
035                        @Override
036                        public T deserialize(String serializedData) throws IOException {
037                                return XmlSerializationUtils.deserializeFromXML(serializedData, type);
038                        }
039                };
040        }
041
042        /**
043         * Constructs a deserializer for the given data type from XML using the aliases
044         * for deserialization.
045         */
046        static <T> IDeserializationFormat<T> fromXml(Class<T> type, Map<String, Class<?>> aliases) {
047                return new IDeserializationFormat<T>() {
048                        @Override
049                        public Optional<EMimeType> getMimeType() {
050                                return Optional.of(EMimeType.XML);
051                        }
052
053                        @Override
054                        public T deserialize(String serializedData) throws IOException {
055                                return XmlSerializationUtils.deserializeFromXMLWithAliases(serializedData, type, aliases);
056                        }
057                };
058        }
059
060        /** Constructs a deserializer for the given data type from JSON. */
061        static <T> IDeserializationFormat<T> fromJson(Class<T> elementType) {
062                return new IDeserializationFormat<T>() {
063                        @Override
064                        public Optional<EMimeType> getMimeType() {
065                                return Optional.of(EMimeType.JSON);
066                        }
067
068                        @Override
069                        public T deserialize(String serializedData) throws IOException {
070                                try {
071                                        return JsonUtils.deserializeFromJson(serializedData, elementType);
072                                } catch (ConQATException e) {
073                                        throw new IOException(e.getMessage(), e);
074                                }
075                        }
076                };
077        }
078
079        /** Constructs a deserializer for a list of the given data type from JSON. */
080        static <T> IDeserializationFormat<List<T>> fromJsonList(Class<T> elementType) {
081                return new IDeserializationFormat<List<T>>() {
082                        @Override
083                        public Optional<EMimeType> getMimeType() {
084                                return Optional.of(EMimeType.JSON);
085                        }
086
087                        @Override
088                        public List<T> deserialize(String serializedData) throws IOException {
089                                try {
090                                        return JsonUtils.deserializeFromJson(serializedData, JsonUtils.getJavaListType(elementType));
091                                } catch (ConQATException e) {
092                                        throw new IOException(e.getMessage(), e);
093                                }
094                        }
095                };
096        }
097
098        /** Constructs a deserializer for plain text responses. */
099        static IDeserializationFormat<String> asPlainText() {
100                return new IDeserializationFormat<String>() {
101                        @Override
102                        public Optional<EMimeType> getMimeType() {
103                                return Optional.of(EMimeType.PLAIN);
104                        }
105
106                        @Override
107                        public String deserialize(String serializedData) {
108                                return serializedData;
109                        }
110                };
111        }
112
113        /**
114         * Constructs a deserializer for a request without setting the Accept header.
115         * The response is returned as a plain string.
116         */
117        static IDeserializationFormat<String> asUnspecifiedPlainText() {
118                return new IDeserializationFormat<String>() {
119                        @Override
120                        public Optional<EMimeType> getMimeType() {
121                                return Optional.empty();
122                        }
123
124                        @Override
125                        public String deserialize(String serializedData) {
126                                return serializedData;
127                        }
128                };
129        }
130}