1 package com.fasterxml.jackson.databind.ser.impl; 2 3 import java.io.IOException; 4 5 import com.fasterxml.jackson.annotation.ObjectIdGenerator; 6 7 import com.fasterxml.jackson.core.JsonGenerator; 8 import com.fasterxml.jackson.core.SerializableString; 9 10 import com.fasterxml.jackson.databind.SerializerProvider; 11 12 /** 13 * Simple value container used to keep track of Object Ids during 14 * serialization. 15 */ 16 public final class WritableObjectId 17 { 18 public final ObjectIdGenerator<?> generator; 19 20 public Object id; 21 22 /** 23 * Marker to denote whether Object Id value has been written as part of an Object, 24 * to be referencible. Remains false when forward-reference is written. 25 */ 26 protected boolean idWritten = false; 27 WritableObjectId(ObjectIdGenerator<?> generator)28 public WritableObjectId(ObjectIdGenerator<?> generator) { 29 this.generator = generator; 30 } 31 writeAsId(JsonGenerator gen, SerializerProvider provider, ObjectIdWriter w)32 public boolean writeAsId(JsonGenerator gen, SerializerProvider provider, ObjectIdWriter w) throws IOException 33 { 34 if ((id != null) && (idWritten || w.alwaysAsId)) { 35 // 03-Aug-2013, tatu: Prefer Native Object Ids if available 36 if (gen.canWriteObjectId()) { 37 gen.writeObjectRef(String.valueOf(id)); 38 } else { 39 w.serializer.serialize(id, gen, provider); 40 } 41 return true; 42 } 43 return false; 44 } 45 generateId(Object forPojo)46 public Object generateId(Object forPojo) { 47 // 04-Jun-2016, tatu: As per [databind#1255], need to consider possibility of 48 // id being generated for "alwaysAsId", but not being written as POJO; regardless, 49 // need to use existing id if there is one: 50 if (id == null) { 51 id = generator.generateId(forPojo); 52 } 53 return id; 54 } 55 56 /** 57 * Method called to output Object Id as specified. 58 */ writeAsField(JsonGenerator gen, SerializerProvider provider, ObjectIdWriter w)59 public void writeAsField(JsonGenerator gen, SerializerProvider provider, 60 ObjectIdWriter w) throws IOException 61 { 62 idWritten = true; 63 64 // 03-Aug-2013, tatu: Prefer Native Object Ids if available 65 if (gen.canWriteObjectId()) { 66 // Need to assume String(ified) ids, for now... could add 'long' variant? 67 // 05-Feb-2019, tatu: But in special case of `null` we should not coerce -- whether 68 // we should even call is an open question, but for now do pass to let generator 69 // decide what to do, if anything. 70 String idStr = (id == null) ? null : String.valueOf(id); 71 gen.writeObjectId(idStr); 72 return; 73 } 74 75 SerializableString name = w.propertyName; 76 if (name != null) { 77 // 05-Feb-2019, tatu: How about `null` id? For now, write 78 gen.writeFieldName(name); 79 w.serializer.serialize(id, gen, provider); 80 } 81 } 82 } 83