All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fasterxml.jackson.annotation.ObjectIdGenerators Maven / Gradle / Ivy

The newest version!
/*
 * Copyright © 2019 Dominokit
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.fasterxml.jackson.annotation;

import java.util.UUID;

/**
 * Container class for standard {@link ObjectIdGenerator} implementations:
 *
 * 
    *
  • {@link IntSequenceGenerator} *
  • {@link PropertyGenerator} *
  • {@link StringIdGenerator} (since 2.7) *
  • {@link UUIDGenerator} *
* *

NOTE: {@link PropertyGenerator} applicability is limited in one case: it can only be used on * polymorphic base types (ones indicated using {@link JsonTypeInfo} or default typing) via class * annotations: property annotation will fail due to lack of access to property, needed to determine * type of Object Id for deserialization. This limitation may be lifted in future versions but it is * the limitation at least up to and including Jackson 2.9. */ public class ObjectIdGenerators { /** Shared base class for concrete implementations. */ @SuppressWarnings("serial") private abstract static class Base extends ObjectIdGenerator { 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. */ @SuppressWarnings("serial") public abstract static class None extends ObjectIdGenerator {} /** * 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. * *

Actual implementation class is part of databind package. */ public abstract static class PropertyGenerator extends Base { private static final long serialVersionUID = 1L; protected PropertyGenerator(Class scope) { super(scope); } } /** * Simple sequence-number based generator, which uses basic Java ints (starting with * value 1) as Object Identifiers. */ public static final class IntSequenceGenerator extends Base { private static final long serialVersionUID = 1L; protected transient 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 forScope(Class scope) { return (_scope == scope) ? this : new IntSequenceGenerator(scope, _nextValue); } @Override public ObjectIdGenerator newForSerialization(Object context) { return new IntSequenceGenerator(_scope, initialValue()); } @Override public IdKey key(Object key) { // 02-Apr-2015, tatu: As per [annotations#56], should check for null if (key == null) { return null; } return new IdKey(getClass(), _scope, key); } @Override public Integer generateId(Object forPojo) { // 02-Apr-2015, tatu: As per [annotations#56], should check for null if (forPojo == null) { return null; } 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. * *

One difference to other generators is that scope is always set as Object.class * (regardless of arguments): this because UUIDs are globally unique, and scope has no meaning. */ public static final class UUIDGenerator extends Base { private static final long serialVersionUID = 1L; 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 forScope(Class scope) { return this; } /** Can just return base instance since this is essentially scopeless */ @Override public ObjectIdGenerator newForSerialization(Object context) { return this; } @Override public UUID generateId(Object forPojo) { return UUID.randomUUID(); } @Override public IdKey key(Object key) { // 02-Apr-2015, tatu: As per [annotations#56], should check for null if (key == null) { return null; } 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()); } } /** * Implementation that will accept arbitrary (but unique) String Ids on deserialization, and (by * default) use random UUID generation similar to {@link UUIDGenerator} for generation ids. * *

This generator is most useful for cases where another system creates String Ids (of * arbitrary structure, if any), and Jackson only needs to keep track of id-to-Object mapping. * Generation also works, although if UUIDs are always used, {@link UUIDGenerator} is a better * match as it will also validate ids being used. * * @since 2.7 */ public static final class StringIdGenerator extends Base { private static final long serialVersionUID = 1L; public StringIdGenerator() { this(Object.class); } private StringIdGenerator(Class scope) { super(Object.class); } // Can just return base instance since this is essentially scopeless @Override public ObjectIdGenerator forScope(Class scope) { return this; } // Can just return base instance since this is essentially scopeless @Override public ObjectIdGenerator newForSerialization(Object context) { return this; } @Override public String generateId(Object forPojo) { return UUID.randomUUID().toString(); } @Override public IdKey key(Object key) { if (key == null) { return null; } return new IdKey(getClass(), null, key); } // Should be usable for generic Opaque String ids? @Override public boolean canUseFor(ObjectIdGenerator gen) { return (gen instanceof StringIdGenerator); } } }