Thomas Vachuska

Added initial sketch of JSON codec abstraction and related codec tracking service.

1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +package org.onlab.onos.codec;
20 +
21 +import java.util.Set;
22 +
23 +/**
24 + * Service for registering and retrieving JSON codecs for various entities.
25 + */
26 +public interface CodecService {
27 +
28 + /**
29 + * Returns the set of classes with currently registered codecs.
30 + *
31 + * @return set of entity classes
32 + */
33 + Set<Class<?>> getCodecs();
34 +
35 + /**
36 + * Returns the JSON codec for the specified entity class.
37 + *
38 + * @param entityClass entity class
39 + * @return JSON codec; null if no codec available for the class
40 + */
41 + JsonCodec getCodec(Class<?> entityClass);
42 +
43 + /**
44 + * Registers the specified JSON codec for the given entity class.
45 + *
46 + * @param entityClass entity class
47 + * @param codec JSON codec
48 + */
49 + void registerCodec(Class<?> entityClass, JsonCodec codec);
50 +
51 + /**
52 + * Unregisters the JSON codec for the specified entity class.
53 + *
54 + * @param entityClass entity class
55 + */
56 + void unregisterCodec(Class<?> entityClass);
57 +
58 +}
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +package org.onlab.onos.codec;
20 +
21 +import com.fasterxml.jackson.databind.JsonNode;
22 +import com.fasterxml.jackson.databind.ObjectMapper;
23 +import com.fasterxml.jackson.databind.node.ArrayNode;
24 +import com.fasterxml.jackson.databind.node.ObjectNode;
25 +
26 +import java.util.ArrayList;
27 +import java.util.List;
28 +
29 +/**
30 + * Abstraction of a codec capable for encoding/decoding arbitrary objects to/from JSON.
31 + */
32 +public abstract class JsonCodec<T> {
33 +
34 + /**
35 + * Encodes the specified entity into JSON.
36 + *
37 + * @param entity entity to encode
38 + * @param mapper object mapper
39 + * @return JSON node
40 + * @throws java.lang.UnsupportedOperationException if the codec does not
41 + * support encode operations
42 + */
43 + public abstract ObjectNode encode(T entity, ObjectMapper mapper);
44 +
45 + /**
46 + * Decodes the specified entity from JSON.
47 + *
48 + * @param json JSON to decode
49 + * @return decoded entity
50 + * @throws java.lang.UnsupportedOperationException if the codec does not
51 + * support decode operations
52 + */
53 + public abstract T decode(ObjectNode json);
54 +
55 + /**
56 + * Encodes the collection of the specified entities.
57 + *
58 + * @param entities collection of entities to encode
59 + * @param mapper object mapper
60 + * @return JSON array
61 + * @throws java.lang.UnsupportedOperationException if the codec does not
62 + * support encode operations
63 + */
64 + public ArrayNode encode(Iterable<T> entities, ObjectMapper mapper) {
65 + ArrayNode result = mapper.createArrayNode();
66 + for (T entity : entities) {
67 + result.add(encode(entity, mapper));
68 + }
69 + return result;
70 + }
71 +
72 + /**
73 + * Decodes the specified JSON array into a collection of entities.
74 + *
75 + * @param json JSON array to decode
76 + * @return collection of decoded entities
77 + * @throws java.lang.UnsupportedOperationException if the codec does not
78 + * support decode operations
79 + */
80 + public List<T> decode(ArrayNode json) {
81 + List<T> result = new ArrayList<>();
82 + for (JsonNode node : json) {
83 + result.add(decode((ObjectNode) node));
84 + }
85 + return result;
86 + }
87 +
88 +}
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +
20 +/**
21 + * Base JSON codec abstraction and a service for tracking various JSON codecs.
22 + */
23 +package org.onlab.onos.codec;
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +package org.onlab.onos.codec;
20 +
21 +import com.fasterxml.jackson.databind.ObjectMapper;
22 +import com.fasterxml.jackson.databind.node.ArrayNode;
23 +import com.fasterxml.jackson.databind.node.ObjectNode;
24 +import com.google.common.collect.ImmutableList;
25 +import org.junit.Test;
26 +
27 +import java.util.List;
28 +import java.util.Objects;
29 +
30 +import static org.junit.Assert.assertEquals;
31 +
32 +/**
33 + * Test of the base JSON codec abstraction.
34 + */
35 +public class JsonCodecTest {
36 +
37 + private static class Foo {
38 + final String name;
39 +
40 + Foo(String name) {
41 + this.name = name;
42 + }
43 +
44 + @Override
45 + public int hashCode() {
46 + return Objects.hash(name);
47 + }
48 +
49 + @Override
50 + public boolean equals(Object obj) {
51 + if (this == obj) {
52 + return true;
53 + }
54 + if (obj == null || getClass() != obj.getClass()) {
55 + return false;
56 + }
57 + final Foo other = (Foo) obj;
58 + return Objects.equals(this.name, other.name);
59 + }
60 + }
61 +
62 + private static class FooCodec extends JsonCodec<Foo> {
63 + @Override
64 + public ObjectNode encode(Foo entity, ObjectMapper mapper) {
65 + return mapper.createObjectNode().put("name", entity.name);
66 + }
67 +
68 + @Override
69 + public Foo decode(ObjectNode json) {
70 + return new Foo(json.get("name").asText());
71 + }
72 + }
73 +
74 + @Test
75 + public void encode() {
76 + Foo f1 = new Foo("foo");
77 + Foo f2 = new Foo("bar");
78 + FooCodec codec = new FooCodec();
79 + ImmutableList<Foo> entities = ImmutableList.of(f1, f2);
80 + ArrayNode json = codec.encode(entities, new ObjectMapper());
81 + List<Foo> foos = codec.decode(json);
82 + assertEquals("incorrect encode/decode", entities, foos);
83 + }
84 +
85 +}
...\ No newline at end of file ...\ No newline at end of file