package com.fasterxml.jackson.annotation; import java.util.UUID; /** * Container class for standard {@link ObjectIdGenerator} implementations. */ public class ObjectIdGenerators { /* /********************************************************** /* Shared base class for concrete implementations /********************************************************** */ /** * Helper class for implementations contained. */ private abstract static class Base<T> extends ObjectIdGenerator<T> { protected final Class<?> _scope; protected Base(Class<?> scope) { _scope = scope; } @Override public final Class<?> getScope() { return _scope; } @Override public boolean canUseFor(ObjectIdGenerator<?> gen) { return (gen.getClass() == getClass()) && (gen.getScope() == _scope); } @Override public abstract T generateId(Object forPojo); } /* /********************************************************** /* Implementation classes /********************************************************** */ /** * Abstract marker class used to allow explicitly specifying * that no generator is used; which also implies that no * Object Id is to be included or used. */ public abstract static class None extends ObjectIdGenerator<Object> { } /** * Abstract place-holder class which is used to denote case * where Object Identifier to use comes from a POJO property * (getter method or field). If so, value is written directly * during serialization, and used as-is during deserialization. *<p> * Actual implementation class is part of <code>databind</code> * package. */ public abstract static class PropertyGenerator extends Base<Object> { protected PropertyGenerator(Class<?> scope) { super(scope); } } /** * Simple sequence-number based generator, which uses basic Java * <code>int</code>s (starting with value 1) as Object Identifiers. */ public final static class IntSequenceGenerator extends Base<Integer> { protected int _nextValue; public IntSequenceGenerator() { this(Object.class, -1); } public IntSequenceGenerator(Class<?> scope, int fv) { super(scope); _nextValue = fv; } protected int initialValue() { return 1; } @Override public ObjectIdGenerator<Integer> forScope(Class<?> scope) { return (_scope == scope) ? this : new IntSequenceGenerator(scope, _nextValue); } @Override public ObjectIdGenerator<Integer> newForSerialization(Object context) { return new IntSequenceGenerator(_scope, initialValue()); } @Override public IdKey key(Object key) { return new IdKey(getClass(), _scope, key); } @Override public Integer generateId(Object forPojo) { int id = _nextValue; ++_nextValue; return id; } } /** * Implementation that just uses {@link java.util.UUID}s as reliably * unique identifiers: downside is that resulting String is * 36 characters long. *<p> * One difference to other generators is that scope is always * set as <code>Object.class</code> (regardless of arguments): this * because UUIDs are globally unique, and scope has no meaning. */ public final static class UUIDGenerator extends Base<UUID> { public UUIDGenerator() { this(Object.class); } private UUIDGenerator(Class<?> scope) { super(Object.class); } /** * Can just return base instance since this is essentially scopeless */ @Override public ObjectIdGenerator<UUID> forScope(Class<?> scope) { return this; } /** * Can just return base instance since this is essentially scopeless */ @Override public ObjectIdGenerator<UUID> newForSerialization(Object context) { return this; } @Override public UUID generateId(Object forPojo) { return UUID.randomUUID(); } @Override public IdKey key(Object key) { return new IdKey(getClass(), null, key); } /** * Since UUIDs are always unique, let's fully ignore scope definition */ @Override public boolean canUseFor(ObjectIdGenerator<?> gen) { return (gen.getClass() == getClass()); } } }