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}