Skip to content

Commit

Permalink
Merge branch '2.18'
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Jun 7, 2024
2 parents 8a85e54 + 28fa3cf commit 4d77236
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import tools.jackson.core.util.RecyclerPool;
import tools.jackson.core.util.RecyclerPool.BoundedPoolBase;
import tools.jackson.core.util.RecyclerPool.ConcurrentDequePoolBase;
import tools.jackson.core.util.RecyclerPool.LockFreePoolBase;

public final class AvroRecyclerPools
{
Expand Down Expand Up @@ -58,24 +57,6 @@ public static RecyclerPool<ApacheCodecRecycler> newConcurrentDequePool() {
return ConcurrentDequePool.construct();
}

/**
* Accessor for getting the shared/global {@link LockFreePool} instance.
*
* @return Globally shared instance of {@link LockFreePool}.
*/
public static RecyclerPool<ApacheCodecRecycler> sharedLockFreePool() {
return LockFreePool.GLOBAL;
}

/**
* Accessor for constructing a new, non-shared {@link LockFreePool} instance.
*
* @return Globally shared instance of {@link LockFreePool}.
*/
public static RecyclerPool<ApacheCodecRecycler> newLockFreePool() {
return LockFreePool.construct();
}

/**
* Accessor for getting the shared/global {@link BoundedPool} instance.
*
Expand Down Expand Up @@ -195,42 +176,6 @@ protected Object readResolve() {
}
}

/**
* {@link RecyclerPool} implementation that uses
* a lock free linked list for recycling instances.
*<p>
* Pool is unbounded: see {@link RecyclerPool} for
* details on what this means.
*/
public static class LockFreePool extends LockFreePoolBase<ApacheCodecRecycler>
{
private static final long serialVersionUID = 1L;

protected static final LockFreePool GLOBAL = new LockFreePool(SERIALIZATION_SHARED);

// // // Life-cycle (constructors, factory methods)

protected LockFreePool(int serialization) {
super(serialization);
}

public static LockFreePool construct() {
return new LockFreePool(SERIALIZATION_NON_SHARED);
}

@Override
public ApacheCodecRecycler createPooled() {
return new ApacheCodecRecycler();
}

// // // JDK serialization support

// Make sure to re-link to global/shared or non-shared.
protected Object readResolve() {
return _resolveToShared(GLOBAL).orElseGet(() -> construct());
}
}

/**
* {@link RecyclerPool} implementation that uses
* a bounded queue ({@link ArrayBlockingQueue} for recycling instances.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,17 @@ public AvroSchemaGenerator disableLogicalTypes() {
super.disableLogicalTypes();
return this;
}

@Override
public AvroSchemaGenerator enableWriteEnumAsString() {
super.enableWriteEnumAsString();
return this;
}

@Override
public AvroSchemaGenerator disableWriteEnumAsString() {
super.disableWriteEnumAsString();
return this;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package tools.jackson.dataformat.avro.schema;

import tools.jackson.databind.*;
import tools.jackson.databind.introspect.AnnotatedClass;
import tools.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;

import org.apache.avro.Schema;

import java.util.ArrayList;
import java.util.Set;

/**
* Specific visitor for Java Enum types that are to be exposed as
* Avro Enums. Used unless Java Enums are to be mapped to Avro Strings.
*/
public class EnumVisitor extends JsonStringFormatVisitor.Base
implements SchemaBuilder
{
protected final SerializerProvider _provider;
protected final JavaType _type;
protected final DefinedSchemas _schemas;

protected Set<String> _enums;

public EnumVisitor(SerializerProvider provider, DefinedSchemas schemas, JavaType t) {
_schemas = schemas;
_type = t;
_provider = provider;
}

@Override
public void enumTypes(Set<String> enums) {
_enums = enums;
}

@Override
public Schema builtAvroSchema() {
if (_enums == null) {
throw new IllegalStateException("Possible enum values cannot be null");
}

AnnotatedClass annotations = _provider.introspectClassAnnotations(_type);
Schema s = AvroSchemaHelper.createEnumSchema(_provider.getConfig(), _type,
annotations, new ArrayList<>(_enums));
_schemas.addSchema(_type, s);
return s;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package tools.jackson.dataformat.avro.schema;

import java.util.ArrayList;
import java.util.Set;
import java.util.*;

import org.apache.avro.Schema;

Expand All @@ -19,13 +18,9 @@ public class StringVisitor extends JsonStringFormatVisitor.Base
{
protected final SerializerProvider _provider;
protected final JavaType _type;
protected final DefinedSchemas _schemas;

protected Set<String> _enums;

public StringVisitor(SerializerProvider provider, DefinedSchemas schemas, JavaType t) {
_schemas = schemas;
_type = t;
public StringVisitor(SerializerProvider provider, JavaType type) {
_type = type;
_provider = provider;
}

Expand All @@ -36,7 +31,7 @@ public void format(JsonValueFormat format) {

@Override
public void enumTypes(Set<String> enums) {
_enums = enums;
// Do nothing
}

@Override
Expand All @@ -51,12 +46,6 @@ public Schema builtAvroSchema() {
return AvroSchemaHelper.createUUIDSchema();
}
AnnotatedClass annotations = _provider.introspectClassAnnotations(_type);
if (_enums != null) {
Schema s = AvroSchemaHelper.createEnumSchema(_provider.getConfig(), _type,
annotations, new ArrayList<>(_enums));
_schemas.addSchema(_type, s);
return s;
}
Schema schema = Schema.create(Schema.Type.STRING);
// Stringable classes need to include the type
if (AvroSchemaHelper.isStringable(annotations) && !_type.hasRawClass(String.class)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package tools.jackson.dataformat.avro.schema;

import java.time.temporal.Temporal;

import tools.jackson.core.JsonGenerator;

import tools.jackson.databind.JavaType;
Expand All @@ -10,20 +12,17 @@

import org.apache.avro.Schema;

import java.time.temporal.Temporal;

public class VisitorFormatWrapperImpl
implements JsonFormatVisitorWrapper
{
protected SerializerProvider _provider;

protected final DefinedSchemas _schemas;

/**
* @since 2.13
*/
protected boolean _logicalTypesEnabled = false;

protected boolean _writeEnumAsString = false;

/**
* Visitor used for resolving actual Schema, if structured type
* (or one with complex configuration)
Expand Down Expand Up @@ -97,6 +96,8 @@ public Schema getAvroSchema() {

/**
* Enables Avro schema with Logical Types generation.
*
* @since 2.13
*/
public VisitorFormatWrapperImpl enableLogicalTypes() {
_logicalTypesEnabled = true;
Expand All @@ -105,6 +106,8 @@ public VisitorFormatWrapperImpl enableLogicalTypes() {

/**
* Disables Avro schema with Logical Types generation.
*
* @since 2.13
*/
public VisitorFormatWrapperImpl disableLogicalTypes() {
_logicalTypesEnabled = false;
Expand All @@ -115,6 +118,31 @@ public boolean isLogicalTypesEnabled() {
return _logicalTypesEnabled;
}

/**
* Enable Java enum to Avro string mapping.
*
* @since 2.18
*/
public VisitorFormatWrapperImpl enableWriteEnumAsString() {
_writeEnumAsString = true;
return this;
}

/**
* Disable Java enum to Avro string mapping.
*
* @since 2.18
*/
public VisitorFormatWrapperImpl disableWriteEnumAsString() {
_writeEnumAsString = false;
return this;
}

// @since 2.18
public boolean isWriteEnumAsStringEnabled() {
return _writeEnumAsString;
}

/*
/**********************************************************************
/* Callbacks
Expand Down Expand Up @@ -169,7 +197,16 @@ public JsonStringFormatVisitor expectStringFormat(JavaType type)
_valueSchema = s;
return null;
}
StringVisitor v = new StringVisitor(_provider, _schemas, type);

// 06-Jun-2024: [dataformats-binary#494] Enums may be exposed either
// as native Avro Enums, or as Avro Strings:
if (type.isEnumType() && !isWriteEnumAsStringEnabled()) {
EnumVisitor v = new EnumVisitor(_provider, _schemas, type);
_builder = v;
return v;
}

StringVisitor v = new StringVisitor(_provider, type);
_builder = v;
return v;
}
Expand Down
Loading

0 comments on commit 4d77236

Please sign in to comment.