1 package com.fasterxml.jackson.annotation;
2 
3 import java.util.UUID;
4 
5 /**
6  * Container class for standard {@link ObjectIdGenerator} implementations:
7  *<ul>
8  *  <li>{@link IntSequenceGenerator}
9  *  <li>{@link PropertyGenerator}
10  *  <li>{@link StringIdGenerator} (since 2.7)
11  *  <li>{@link UUIDGenerator}
12  *</ul>
13  *<p>
14  * NOTE: {@link PropertyGenerator} applicability is limited in one case: it can only
15  * be used on polymorphic base types (ones indicated using {@link JsonTypeInfo} or
16  * default typing) via class annotations: property annotation will fail due to lack
17  * of access to property, needed to determine type of Object Id for deserialization.
18  * This limitation may be lifted in future versions but it is the limitation at least
19  * up to and including Jackson 2.9.
20  */
21 public class ObjectIdGenerators
22 {
23     /**
24      * Shared base class for concrete implementations.
25      */
26     @SuppressWarnings("serial")
27     private abstract static class Base<T> extends ObjectIdGenerator<T>
28     {
29         protected final Class<?> _scope;
30 
Base(Class<?> scope)31         protected Base(Class<?> scope) {
32             _scope = scope;
33         }
34 
35         @Override
getScope()36         public final Class<?> getScope() {
37             return _scope;
38         }
39 
40         @Override
canUseFor(ObjectIdGenerator<?> gen)41         public boolean canUseFor(ObjectIdGenerator<?> gen) {
42             return (gen.getClass() == getClass()) && (gen.getScope() == _scope);
43         }
44 
45         @Override
generateId(Object forPojo)46         public abstract T generateId(Object forPojo);
47     }
48 
49     /*
50     /**********************************************************
51     /* Implementation classes
52     /**********************************************************
53      */
54 
55     /**
56      * Abstract marker class used to allow explicitly specifying
57      * that no generator is used; which also implies that no
58      * Object Id is to be included or used.
59      */
60     @SuppressWarnings("serial")
61     public abstract static class None extends ObjectIdGenerator<Object> { }
62 
63     /**
64      * Abstract place-holder class which is used to denote case
65      * where Object Identifier to use comes from a POJO property
66      * (getter method or field). If so, value is written directly
67      * during serialization, and used as-is during deserialization.
68      *<p>
69      * Actual implementation class is part of <code>databind</code>
70      * package.
71      */
72     public abstract static class PropertyGenerator extends Base<Object> {
73         private static final long serialVersionUID = 1L;
74 
PropertyGenerator(Class<?> scope)75         protected PropertyGenerator(Class<?> scope) { super(scope); }
76     }
77 
78     /**
79      * Simple sequence-number based generator, which uses basic Java
80      * <code>int</code>s (starting with value 1) as Object Identifiers.
81      */
82     public final static class IntSequenceGenerator extends Base<Integer>
83     {
84         private static final long serialVersionUID = 1L;
85 
86         protected transient int _nextValue;
87 
IntSequenceGenerator()88         public IntSequenceGenerator() { this(Object.class, -1); }
IntSequenceGenerator(Class<?> scope, int fv)89         public IntSequenceGenerator(Class<?> scope, int fv) {
90             super(scope);
91             _nextValue = fv;
92         }
93 
initialValue()94         protected int initialValue() { return 1; }
95 
96         @Override
forScope(Class<?> scope)97         public ObjectIdGenerator<Integer> forScope(Class<?> scope) {
98             return (_scope == scope) ? this : new IntSequenceGenerator(scope, _nextValue);
99         }
100 
101         @Override
newForSerialization(Object context)102         public ObjectIdGenerator<Integer> newForSerialization(Object context) {
103             return new IntSequenceGenerator(_scope, initialValue());
104         }
105 
106         @Override
key(Object key)107         public IdKey key(Object key) {
108             // 02-Apr-2015, tatu: As per [annotations#56], should check for null
109             if (key == null) {
110                 return null;
111             }
112             return new IdKey(getClass(), _scope, key);
113         }
114 
115         @Override
generateId(Object forPojo)116         public Integer generateId(Object forPojo) {
117             // 02-Apr-2015, tatu: As per [annotations#56], should check for null
118             if (forPojo == null)  {
119                 return null;
120             }
121             int id = _nextValue;
122             ++_nextValue;
123             return id;
124         }
125     }
126 
127     /**
128      * Implementation that just uses {@link java.util.UUID}s as reliably
129      * unique identifiers: downside is that resulting String is
130      * 36 characters long.
131      *<p>
132      * One difference to other generators is that scope is always
133      * set as <code>Object.class</code> (regardless of arguments): this
134      * because UUIDs are globally unique, and scope has no meaning.
135      */
136     public final static class UUIDGenerator extends Base<UUID>
137     {
138         private static final long serialVersionUID = 1L;
139 
UUIDGenerator()140         public UUIDGenerator() { this(Object.class); }
UUIDGenerator(Class<?> scope)141         private UUIDGenerator(Class<?> scope) {
142             super(Object.class);
143         }
144 
145         /**
146          * Can just return base instance since this is essentially scopeless
147          */
148         @Override
forScope(Class<?> scope)149         public ObjectIdGenerator<UUID> forScope(Class<?> scope) {
150             return this;
151         }
152 
153         /**
154          * Can just return base instance since this is essentially scopeless
155          */
156         @Override
newForSerialization(Object context)157         public ObjectIdGenerator<UUID> newForSerialization(Object context) {
158             return this;
159         }
160 
161         @Override
generateId(Object forPojo)162         public UUID generateId(Object forPojo) {
163             return UUID.randomUUID();
164         }
165 
166         @Override
key(Object key)167         public IdKey key(Object key) {
168             // 02-Apr-2015, tatu: As per [annotations#56], should check for null
169             if (key == null) {
170                 return null;
171             }
172             return new IdKey(getClass(), null, key);
173         }
174 
175         /**
176          * Since UUIDs are always unique, let's fully ignore scope definition
177          */
178         @Override
canUseFor(ObjectIdGenerator<?> gen)179         public boolean canUseFor(ObjectIdGenerator<?> gen) {
180             return (gen.getClass() == getClass());
181         }
182     }
183 
184     /**
185      * Implementation that will accept arbitrary (but unique) String Ids on
186      * deserialization, and (by default) use random UUID generation similar
187      * to {@link UUIDGenerator} for generation ids.
188      *<p>
189      * This generator is most useful for cases where another system creates
190      * String Ids (of arbitrary structure, if any), and Jackson only needs to
191      * keep track of id-to-Object mapping. Generation also works, although if
192      * UUIDs are always used, {@link UUIDGenerator} is a better match as it
193      * will also validate ids being used.
194      *
195      * @since 2.7
196      */
197     public final static class StringIdGenerator extends Base<String>
198     {
199         private static final long serialVersionUID = 1L;
200 
StringIdGenerator()201         public StringIdGenerator() { this(Object.class); }
StringIdGenerator(Class<?> scope)202         private StringIdGenerator(Class<?> scope) {
203             super(Object.class);
204         }
205 
206         // Can just return base instance since this is essentially scopeless
207         @Override
forScope(Class<?> scope)208         public ObjectIdGenerator<String> forScope(Class<?> scope) {
209             return this;
210         }
211 
212         // Can just return base instance since this is essentially scopeless
213         @Override
newForSerialization(Object context)214         public ObjectIdGenerator<String> newForSerialization(Object context) {
215             return this;
216         }
217 
218         @Override
generateId(Object forPojo)219         public String generateId(Object forPojo) {
220             return UUID.randomUUID().toString();
221         }
222 
223         @Override
key(Object key)224         public IdKey key(Object key) {
225             if (key == null) {
226                 return null;
227             }
228             return new IdKey(getClass(), null, key);
229         }
230 
231         // Should be usable for generic Opaque String ids?
232         @Override
canUseFor(ObjectIdGenerator<?> gen)233         public boolean canUseFor(ObjectIdGenerator<?> gen) {
234             return (gen instanceof StringIdGenerator);
235         }
236     }
237 }
238