Hello Yair Zaslavsky,

I'd like you to do a code review.  Please visit

    http://gerrit.ovirt.org/21303

to review the following change.

Change subject: core: Adding deserialization resolver
......................................................................

core: Adding deserialization resolver

The following patch adds the json
deserialization resolver that will help deserailization
in case that class names and fields got changed.
At this stage it supports only class names changing.

Change-Id: Id719e2148975e48780d3eab01cab63baaa1246a4
Signed-off-by: Yair Zaslavsky <yzasl...@redhat.com>
---
A 
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/DeserializationResolver.java
A 
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/DeserializationResolverTest.java
M 
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/JsonObjectDeserializer.java
3 files changed, 172 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/03/21303/1

diff --git 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/DeserializationResolver.java
 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/DeserializationResolver.java
new file mode 100644
index 0000000..eb9e174
--- /dev/null
+++ 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/DeserializationResolver.java
@@ -0,0 +1,59 @@
+package org.ovirt.engine.core.utils.serialization.json;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.ovirt.engine.core.common.utils.Pair;
+
+public class DeserializationResolver {
+    private static DeserializationResolver instance = new 
DeserializationResolver();
+    
+    private Map<Pair<String, String>, Pair<String, String>> classResolvingMap 
= new HashMap<>();
+
+    public static DeserializationResolver getInstance() {
+        return instance;
+    }
+    
+    public void add(String oldClassName, String oldClassVer, String className, 
String classVer) {
+        classResolvingMap.put(new Pair<String, String>(oldClassVer, 
oldClassName),
+                new Pair<String, String>(classVer, className));
+        
+    }
+
+    public String reolveClassName(String className, String originalVer, String 
resolvingVer) {
+
+        Pair<String, String> pair = classResolvingMap.get(new Pair<String, 
String>(originalVer, className));
+        if (pair != null) {
+            while (pair.getFirst().compareTo(resolvingVer) >= 0) {
+                Pair<String, String> auxPair = classResolvingMap.get(pair);
+                if (auxPair == null || 
auxPair.getFirst().compareTo(resolvingVer) >= 0) {
+                    break;
+                }
+                pair = auxPair;
+            }
+        }
+        if (pair == null) {
+            return null;
+        }
+        return pair.getSecond();
+    }
+
+    public String reolveClassName(String className, String originalVer) {
+
+        Pair<String, String> pair = classResolvingMap.get(new Pair<String, 
String>(originalVer, className));
+        if (pair != null) {
+            // while (pair.getFirst().compareTo(resolvingVer) >= 0) {
+            while (true) {
+                Pair<String, String> auxPair = classResolvingMap.get(pair);
+                if (auxPair == null || 
auxPair.getSecond().equals(pair.getSecond())) {
+                    return pair.getSecond();
+                }
+            }
+        }
+        return null;
+    }
+
+    public void add(String className, String ver) {
+        add(className, ver, className, ver);
+    }
+}
diff --git 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/DeserializationResolverTest.java
 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/DeserializationResolverTest.java
new file mode 100644
index 0000000..6d42cbb
--- /dev/null
+++ 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/DeserializationResolverTest.java
@@ -0,0 +1,58 @@
+package org.ovirt.engine.core.utils.serialization.json;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.ovirt.engine.core.common.businessentities.Role;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.utils.RandomUtils;
+
+
+
+public class DeserializationResolverTest {
+
+    private DeserializationResolver res;
+
+    @Before
+    public void setup() {
+        res = new DeserializationResolver();
+        res.add("org.ovirt.engine.core.common.businessentities.Rule", "3.1");
+        res.add("org.ovirt.engine.core.common.businessentities.Rule",
+                "3.1",
+                "org.ovirt.engine.core.common.businessentities.Role",
+                "3.2");
+    }
+
+    // @Test
+    public void testResolveClassName() {
+        assertEquals("org.ovirt.engine.core.common.businessentities.Role",
+                
res.reolveClassName("org.ovirt.engine.core.common.businessentities.Rule", 
"3.1", "3.2"));
+    }
+
+    private Role randomRole() {
+        RandomUtils random = RandomUtils.instance();
+        Role role = new Role();
+        role.setdescription(random.nextString(10));
+        role.setId(Guid.newGuid());
+        role.setname(random.nextString(10));
+        return role;
+    }
+
+    @Test
+    public void testClassResolving() {
+        Role role = randomRole();
+        JsonObjectSerializer ser = new JsonObjectSerializer();
+        String serialized = ser.serialize(role);
+        serialized = serialized.replace("Role", "Rule");
+        JsonObjectDeserializer der = new JsonObjectDeserializer("3.1");
+        der = spy(der);
+        doReturn(res).when(der).getDeserializationReolver();
+        Role derRole = der.deserialize(serialized, Role.class);
+        assertEquals(role, derRole);
+
+    }
+
+}
diff --git 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/JsonObjectDeserializer.java
 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/JsonObjectDeserializer.java
index 867a99d..c190589 100644
--- 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/JsonObjectDeserializer.java
+++ 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/serialization/json/JsonObjectDeserializer.java
@@ -26,6 +26,9 @@
  */
 public class JsonObjectDeserializer implements Deserializer {
 
+    private static final String CLASS_TOKEN = "\"@class\"";
+    private static final char QUOTES_TOKEN = '\"';
+
     private static final ObjectMapper formattedMapper;
     static {
         formattedMapper = new ObjectMapper();
@@ -47,12 +50,24 @@
         formattedMapper.enableDefaultTyping();
     }
 
+
+    public JsonObjectDeserializer(String version) {
+        this.version = version;
+    }
+
+    public JsonObjectDeserializer() {
+    }
+
     @Override
     public <T extends Serializable> T deserialize(Object source, Class<T> 
type) throws SerializationExeption {
         if (source == null) {
             return null;
         }
-        return readJsonString(source, type, formattedMapper);
+        String src = source.toString();
+        if (version != null) {
+            src = adjustClasses(src);
+        }
+        return readJsonString(src, type, formattedMapper);
     }
 
     /**
@@ -79,11 +94,50 @@
         }
     }
 
+    protected DeserializationResolver getDeserializationReolver() {
+        return DeserializationResolver.getInstance();
+    }
+
+    private String adjustClasses(String s) {
+
+        if (version == null) {
+            return s;
+        }
+        DeserializationResolver dr = getDeserializationReolver();
+        int lastIndex = 0;
+        StringBuilder sb = new StringBuilder();
+        while (true) {
+            if (lastIndex > s.length()) {
+                break;
+            }
+            int classTokenIndex = s.indexOf(CLASS_TOKEN, lastIndex);
+            if (classTokenIndex < 0) {
+                sb.append(s.substring(lastIndex));
+                break;
+            }
+            int startClassIndex = s.indexOf(QUOTES_TOKEN, classTokenIndex + 
CLASS_TOKEN.length()) + 1;
+            if (startClassIndex > s.length()) {
+                break;
+            }
+            sb.append(s.substring(lastIndex, startClassIndex));
+            int endClassIndex = s.indexOf(QUOTES_TOKEN, startClassIndex + 
CLASS_TOKEN.length());
+            String classToResolve = s.substring(startClassIndex, 
endClassIndex);
+            String resolvedClass = dr.reolveClassName(classToResolve, version);
+            sb.append(resolvedClass).append(QUOTES_TOKEN);
+            lastIndex = endClassIndex + 1;
+        }
+        return sb.toString();
+    }
+
     private <T> T readJsonString(Object source, Class<T> type, ObjectMapper 
mapper) {
         try {
             return mapper.readValue(source.toString(), type);
         } catch (IOException e) {
+            e.printStackTrace();
             throw new SerializationException(e);
         }
     }
+
+    private String version;
+
 }


-- 
To view, visit http://gerrit.ovirt.org/21303
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id719e2148975e48780d3eab01cab63baaa1246a4
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Ravi Nori <rn...@redhat.com>
Gerrit-Reviewer: Yair Zaslavsky <yzasl...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to