Fix devfile component preferences deserialization through GSON

Signed-off-by: Max Shaposhnik <mshaposh@redhat.com>
7.20.x
Mykhailo Kuznietsov 2019-09-10 15:25:09 +03:00 committed by Max Shaposhnik
parent 154d668505
commit ec76c532ff
4 changed files with 136 additions and 0 deletions

View File

@ -22,6 +22,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
@ -511,6 +512,8 @@ public final class DtoFactory {
builder.registerTypeHierarchyAdapter(Map.class, new NullOrEmptyMapAdapter());
}
builder.registerTypeAdapterFactory(new SerializableInterfaceAdapterFactory());
return builder.create();
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.dto.server;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.io.Serializable;
/**
* This adapter is required for fields of {@link java.io.Serializable} type to be treated as {@link
* Object}
*/
public class SerializableInterfaceAdapterFactory implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (Serializable.class.equals(type.getRawType())) {
return (TypeAdapter<T>) new SerializableAdapter(gson.getAdapter(Object.class));
}
return null;
}
private static class SerializableAdapter extends TypeAdapter<Object> {
TypeAdapter objectAdapter;
public SerializableAdapter(TypeAdapter objectAdapter) {
this.objectAdapter = objectAdapter;
}
@Override
public void write(JsonWriter out, Object value) throws IOException {
objectAdapter.write(out, value);
}
@Override
public Object read(JsonReader in) throws IOException {
JsonToken token = in.peek();
if (token.equals(JsonToken.NUMBER)) {
try {
return in.nextLong();
} catch (NumberFormatException e) {
return in.nextDouble();
}
}
return objectAdapter.read(in);
}
}
}

View File

@ -31,6 +31,7 @@ import org.eclipse.che.dto.definitions.DTOHierarchy.GrandchildDto;
import org.eclipse.che.dto.definitions.DtoWithAny;
import org.eclipse.che.dto.definitions.DtoWithDelegate;
import org.eclipse.che.dto.definitions.DtoWithFieldNames;
import org.eclipse.che.dto.definitions.DtoWithSerializable;
import org.eclipse.che.dto.definitions.SimpleDto;
import org.eclipse.che.dto.definitions.model.Model;
import org.eclipse.che.dto.definitions.model.ModelComponentDto;
@ -435,4 +436,36 @@ public class ServerDtoTest {
public void shouldThrowExceptionWhenInterfaceIsNotAnnotatedAsDto() {
DtoFactory.newDto(DTOHierarchy.GrandchildWithoutDto.class);
}
@Test
public void checkDtoDeserializationWithSerializableFields() {
final int fooId = 1;
final String fooString = "some string";
final long fooLong = 1234514362645634611L;
final double fooDouble = 1.2345;
final double fooRoundingDouble = 6.00;
JsonObject jsonMap = new JsonObject();
jsonMap.add("fooLong", new JsonPrimitive(fooLong));
jsonMap.add("fooBoolean", new JsonPrimitive(true));
jsonMap.add("fooDouble", new JsonPrimitive(fooDouble));
jsonMap.add("fooRoundingDouble", new JsonPrimitive(fooRoundingDouble));
jsonMap.add("fooString", new JsonPrimitive(fooString));
JsonObject json = new JsonObject();
json.add("id", new JsonPrimitive(fooId));
json.add("object", new JsonPrimitive(fooString));
json.add("objectMap", jsonMap);
DtoWithSerializable dto =
dtoFactory.createDtoFromJson(json.toString(), DtoWithSerializable.class);
assertEquals(dto.getId(), fooId);
assertEquals(dto.getObject(), fooString);
assertEquals(dto.getObjectMap().get("fooLong"), fooLong);
assertEquals(dto.getObjectMap().get("fooBoolean"), true);
assertEquals(dto.getObjectMap().get("fooDouble"), fooDouble);
assertEquals(dto.getObjectMap().get("fooString"), fooString);
assertEquals(dto.getObjectMap().get("fooRoundingDouble"), Math.round(fooRoundingDouble));
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.dto.definitions;
import java.io.Serializable;
import java.util.Map;
import org.eclipse.che.dto.shared.DTO;
/** DTO for testing serialization of fields with {@link java.io.Serializable} type */
@DTO
public interface DtoWithSerializable {
int getId();
DtoWithSerializable withId(int id);
Serializable getObject();
void setObject(Serializable object);
DtoWithSerializable withObject(Serializable object);
Map<String, Serializable> getObjectMap();
void setObjectMap(Map<String, Serializable> map);
DtoWithSerializable withObjectMap(Map<String, Serializable> map);
}