Skip to content

Commit

Permalink
Fix devfile component preferences deserialization through GSON
Browse files Browse the repository at this point in the history
Signed-off-by: Max Shaposhnik <mshaposh@redhat.com>
  • Loading branch information
mkuznyetsov authored and mshaposhnik committed Sep 10, 2019
1 parent 154d668 commit ec76c53
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
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;
Expand Down Expand Up @@ -511,6 +512,8 @@ private static Gson buildDtoParser(
builder.registerTypeHierarchyAdapter(Map.class, new NullOrEmptyMapAdapter());
}

builder.registerTypeAdapterFactory(new SerializableInterfaceAdapterFactory());

return builder.create();
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
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;
Expand Down Expand Up @@ -435,4 +436,36 @@ public void shouldThrowExceptionWhenThereIsClassType() {
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));
}
}
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit ec76c53

Please sign in to comment.