diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/CheJsonProvider.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/CheJsonProvider.java index f204ea7247a..5e26ccd17fa 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/CheJsonProvider.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/CheJsonProvider.java @@ -11,6 +11,7 @@ */ package org.eclipse.che.api.core.rest; +import com.google.gson.reflect.TypeToken; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -56,6 +57,8 @@ public class CheJsonProvider implements MessageBodyReader, MessageBodyWriter { private Set ignoredClasses; private final JsonEntityProvider delegate = new JsonEntityProvider<>(); + private final Type listOfJsonSerializableType = + new TypeToken>() {}.getType(); @Inject public CheJsonProvider(@Nullable @Named("che.json.ignored_classes") Set ignoredClasses) { @@ -95,6 +98,10 @@ public void writeTo( try (Writer w = new OutputStreamWriter(entityStream, StandardCharsets.UTF_8)) { ((JsonSerializable) t).toJson(w); } + } else if (isDtoList(type, genericType, t)) { + try (Writer w = new OutputStreamWriter(entityStream, StandardCharsets.UTF_8)) { + DtoFactory.getInstance().getGson().toJson(t, listOfJsonSerializableType, w); + } } else { delegate.writeTo(t, type, genericType, annotations, mediaType, httpHeaders, entityStream); } @@ -121,15 +128,10 @@ public T readFrom( throws IOException, WebApplicationException { if (type.isAnnotationPresent(DTO.class)) { return DtoFactory.getInstance().createDtoFromJson(entityStream, type); - } else if (type.isAssignableFrom(List.class) && genericType instanceof ParameterizedType) { + } else if (isDtoList(type, genericType, null)) { ParameterizedType parameterizedType = (ParameterizedType) genericType; Type elementType = parameterizedType.getActualTypeArguments()[0]; - if (elementType instanceof Class) { - Class elementClass = (Class) elementType; - if (elementClass.isAnnotationPresent(DTO.class)) { - return (T) DtoFactory.getInstance().createListDtoFromJson(entityStream, elementClass); - } - } + return (T) DtoFactory.getInstance().createListDtoFromJson(entityStream, (Class) elementType); } return (T) delegate.readFrom(type, genericType, annotations, mediaType, httpHeaders, entityStream); @@ -142,4 +144,20 @@ public T readFrom( public Set getIgnoredClasses() { return ignoredClasses; } + + /** Checks if provided object is a list of DTO or serializable objects. */ + private static boolean isDtoList(Class type, Type genericType, T t) { + if (!List.class.isAssignableFrom(type)) { + return false; + } + if (genericType instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) genericType; + Type elementType = parameterizedType.getActualTypeArguments()[0]; + return elementType instanceof Class && ((Class) elementType).isAnnotationPresent(DTO.class); + } else if (t instanceof List && type.equals(genericType)) { + List list = (List) t; + return !list.isEmpty() && list.iterator().next() instanceof JsonSerializable; + } + return false; + } } diff --git a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java index f338176d824..7b2b8e5bd5b 100644 --- a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java +++ b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java @@ -44,6 +44,7 @@ import com.google.gson.reflect.TypeToken; import com.jayway.restassured.response.Response; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -59,6 +60,7 @@ import org.eclipse.che.api.core.model.workspace.runtime.Server; import org.eclipse.che.api.core.model.workspace.runtime.ServerStatus; import org.eclipse.che.api.core.rest.ApiExceptionMapper; +import org.eclipse.che.api.core.rest.CheJsonProvider; import org.eclipse.che.api.core.rest.shared.dto.ServiceError; import org.eclipse.che.api.workspace.server.devfile.DevfileManager; import org.eclipse.che.api.workspace.server.devfile.URLFetcher; @@ -126,6 +128,9 @@ public class WorkspaceServiceTest { @SuppressWarnings("unused") private static final EnvironmentFilter FILTER = new EnvironmentFilter(); + @SuppressWarnings("unused") // is declared for deploying by everrest-assured + private CheJsonProvider jsonProvider = new CheJsonProvider(Collections.emptySet()); + @Mock private WorkspaceManager wsManager; @Mock private MachineTokenProvider machineTokenProvider; @Mock private WorkspaceLinksGenerator linksGenerator;