| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.felix.serializer.impl.json; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.apache.felix.serializer.impl.json.MyDTO.Count; |
| import org.apache.felix.serializer.impl.json.MyEmbeddedDTO.Alpha; |
| import org.apache.sling.commons.json.JSONException; |
| import org.apache.sling.commons.json.JSONObject; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.osgi.util.converter.Converter; |
| import org.osgi.util.converter.Converters; |
| import org.osgi.util.converter.TypeReference; |
| import org.osgi.util.converter.TypeRule; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertTrue; |
| |
| public class JsonSerializerTest { |
| private Converter converter; |
| |
| @Before |
| public void setUp() { |
| converter = Converters.standardConverter(); |
| } |
| |
| @After |
| public void tearDown() { |
| converter = null; |
| } |
| |
| @Test |
| public void testJSONCodec() throws Exception { |
| Map<Object, Object> m1 = new HashMap<>(); |
| m1.put("x", true); |
| m1.put("y", null); |
| Map<Object, Object> m = new HashMap<>(); |
| m.put(1, 11L); |
| m.put("ab", "cd"); |
| m.put(true, m1); |
| |
| JsonSerializerImpl jsonCodec = new JsonSerializerImpl(); |
| String json = jsonCodec.serialize(m).toString(); |
| |
| JSONObject jo = new JSONObject(json); |
| assertEquals(11, jo.getInt("1")); |
| assertEquals("cd", jo.getString("ab")); |
| JSONObject jo2 = jo.getJSONObject("true"); |
| assertEquals(true, jo2.getBoolean("x")); |
| assertTrue(jo2.isNull("y")); |
| |
| @SuppressWarnings("rawtypes") |
| Map m2 = jsonCodec.deserialize(Map.class).from(json); |
| // m2 is not exactly equal to m, as the keys are all strings now, this is unavoidable with JSON |
| assertEquals(m.size(), m2.size()); |
| assertEquals(m.get(1), m2.get("1")); |
| assertEquals(m.get("ab"), m2.get("ab")); |
| assertEquals(m.get(true), m2.get("true")); |
| } |
| |
| @Test |
| public void testCodecWithAdapter() throws JSONException { |
| Map<String, Foo> m1 = new HashMap<>(); |
| m1.put("f", new Foo("fofofo")); |
| Map<String, Map<String,Foo>> m = new HashMap<>(); |
| m.put("submap", m1); |
| |
| Converter ca = converter.newConverterBuilder(). |
| rule(new TypeRule<Foo, String>(Foo.class, String.class, Foo::tsFun)). |
| rule(new TypeRule<String, Foo>(String.class, Foo.class, v -> Foo.fsFun(v))).build(); |
| |
| JsonSerializerImpl jsonCodec = new JsonSerializerImpl(); |
| String json = jsonCodec.serialize(m).convertWith(ca).toString(); |
| |
| JSONObject jo = new JSONObject(json); |
| assertEquals(1, jo.length()); |
| JSONObject jo1 = jo.getJSONObject("submap"); |
| assertEquals("<fofofo>", jo1.getString("f")); |
| |
| // And convert back |
| Map<String,Map<String,Foo>> m2 = jsonCodec.deserialize(new TypeReference<Map<String,Map<String,Foo>>>(){}). |
| convertWith(ca).from(json); |
| assertEquals(m, m2); |
| } |
| |
| @Test |
| public void testDTO() { |
| MyDTO dto = new MyDTO(); |
| dto.count = Count.ONE; |
| dto.ping = "'"; |
| dto.pong = Long.MIN_VALUE; |
| |
| MyEmbeddedDTO embedded = new MyEmbeddedDTO(); |
| embedded.alpha = Alpha.B; |
| embedded.marco = "jo !"; |
| embedded.polo = 327; |
| dto.embedded = embedded; |
| |
| JsonSerializerImpl jsonCodec = new JsonSerializerImpl(); |
| String json = jsonCodec.serialize(dto).toString(); |
| // NOTE: cannot predict ordering, so test fails intermittently |
| // assertEquals( |
| // "{\"count\":\"ONE\",\"ping\":\"'\"," |
| // + "\"embedded\":{\"polo\":327,\"alpha\":\"B\",\"marco\":\"jo !\"}," |
| // + "\"pong\":-9223372036854775808}", |
| // json); |
| |
| MyDTO dto2 = jsonCodec.deserialize(MyDTO.class).from(json); |
| assertEquals(Count.ONE, dto2.count); |
| assertEquals("'", dto2.ping); |
| assertEquals(Long.MIN_VALUE, dto2.pong); |
| MyEmbeddedDTO embedded2 = dto2.embedded; |
| assertEquals(Alpha.B, embedded2.alpha); |
| assertEquals("jo !", embedded2.marco); |
| assertEquals(327, embedded2.polo); |
| } |
| |
| static class Foo { |
| private final String val; |
| |
| public Foo(String s) { |
| val = s; |
| } |
| |
| public String tsFun() { |
| return "<" + val + ">"; |
| } |
| |
| public static Foo fsFun(String s) { |
| return new Foo(s.substring(1, s.length() - 1)); |
| } |
| |
| @Override |
| public int hashCode() { |
| return val.hashCode(); |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (obj == this) |
| return true; |
| if (!(obj instanceof Foo)) |
| return false; |
| |
| Foo f = (Foo) obj; |
| return f.val.equals(val); |
| } |
| } |
| } |