MATSIM
IdAnnotations.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * IdAnnotations.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2023 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.api.core.v01;
22 
23 import java.io.IOException;
24 import java.lang.annotation.Retention;
25 import java.lang.annotation.RetentionPolicy;
26 import java.util.HashMap;
27 import java.util.Map;
28 
29 import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
30 import com.fasterxml.jackson.core.JacksonException;
31 import com.fasterxml.jackson.core.JsonGenerator;
32 import com.fasterxml.jackson.core.JsonParser;
33 import com.fasterxml.jackson.databind.BeanProperty;
34 import com.fasterxml.jackson.databind.DeserializationContext;
35 import com.fasterxml.jackson.databind.JavaType;
36 import com.fasterxml.jackson.databind.JsonDeserializer;
37 import com.fasterxml.jackson.databind.JsonMappingException;
38 import com.fasterxml.jackson.databind.JsonNode;
39 import com.fasterxml.jackson.databind.SerializerProvider;
40 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
41 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
42 import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
43 import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
44 import com.fasterxml.jackson.databind.ser.std.StdSerializer;
45 
46 public interface IdAnnotations {
47 
48  @Retention(RetentionPolicy.RUNTIME)
49  @JacksonAnnotationsInside
50  @JsonSerialize(using = JsonIdSerializer.class)
51  @JsonDeserialize(using = JsonIdContextualDeserializer.class)
52  public @interface JsonId {
53 
54  }
55 
56  class JsonIdSerializer<T> extends StdSerializer<T> {
57 
58  protected JsonIdSerializer() {
59  this(null);
60  }
61 
62  protected JsonIdSerializer(Class<T> vc) {
63  super(vc);
64  }
65 
66  @Override
67  public void serialize(T value, JsonGenerator gen, SerializerProvider provider) throws IOException {
68  gen.writeString(value.toString());
69  }
70 
71  }
72 
73  class JsonIdContextualDeserializer<T> extends StdDeserializer<Id<T>> implements ContextualDeserializer {
74 
75  private Class<T> idClass;
76 
78  this(null);
79  }
80 
81  protected JsonIdContextualDeserializer(Class<T> idClass) {
82  super(Object.class);
83  this.idClass = idClass;
84  }
85 
86  @Override
87  public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
88  throws JsonMappingException {
89 
90  final Class<? extends Object> idClass;
91  {
92  final JavaType type;
93  if (property != null)
94  type = property.getType();
95  else {
96  type = ctxt.getContextualType();
97  }
98  idClass = type.containedType(0).getRawClass();
99  }
100 
101  return JsonIdDeserializer.getInstance(idClass);
102  }
103 
104  @Override
105  public Id<T> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JacksonException {
106  JsonNode node = jp.getCodec().readTree(jp);
107  return Id.create(node.asText(), idClass);
108  }
109 
110  }
111 
112  class JsonIdDeserializer<T> extends StdDeserializer<Id<T>> {
113 
114  private static final Map<Class<?>, JsonIdDeserializer<?>> CACHE = new HashMap<>();
115 
116  public static JsonIdDeserializer<?> getInstance(Class<?> clazz) {
117  return CACHE.computeIfAbsent(clazz, k -> new JsonIdDeserializer<>(k));
118  }
119 
120  private final Class<T> idClass;
121 
122  private JsonIdDeserializer() {
123  this(null);
124  }
125 
126  private JsonIdDeserializer(Class<T> idClass) {
127  super(Object.class);
128  this.idClass = idClass;
129  }
130 
131  @Override
132  public Id<T> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
133  JsonNode node = jp.getCodec().readTree(jp);
134  return Id.create(node.asText(), idClass);
135  }
136 
137  }
138 
139 }
void serialize(T value, JsonGenerator gen, SerializerProvider provider)
Id< T > deserialize(JsonParser jp, DeserializationContext ctxt)
static< T > Id< T > create(final long key, final Class< T > type)
Definition: Id.java:68
static JsonIdDeserializer<?> getInstance(Class<?> clazz)
JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
Id< T > deserialize(JsonParser jp, DeserializationContext ctxt)