Skip to content

Commit

Permalink
Invert creation of datatype coder to avoid issue with modularization …
Browse files Browse the repository at this point in the history
…without needing to export org.firebirdsql.gds.ng.jna
  • Loading branch information
mrotteveel committed Jul 7, 2023
1 parent 4635594 commit 4589a7f
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public final class BigEndianDatatypeCoder extends DefaultDatatypeCoder {
* @return datatype coder, this might be a cached instance
*/
public static BigEndianDatatypeCoder forEncodingFactory(IEncodingFactory encodingFactory) {
return encodingFactory.getOrCreateDatatypeCoder(BigEndianDatatypeCoder.class);
return encodingFactory.getOrCreateDatatypeCoder(BigEndianDatatypeCoder.class, BigEndianDatatypeCoder::new);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public final class LittleEndianDatatypeCoder extends DefaultDatatypeCoder {
* @return datatype coder, this might be a cached instance
*/
public static LittleEndianDatatypeCoder forEncodingFactory(IEncodingFactory encodingFactory) {
return encodingFactory.getOrCreateDatatypeCoder(LittleEndianDatatypeCoder.class);
return encodingFactory
.getOrCreateDatatypeCoder(LittleEndianDatatypeCoder.class, LittleEndianDatatypeCoder::new);
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/docs/asciidoc/release_notes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,9 @@ use `StringArgument(int, ArgumentType, String, Encoding)`
* `FBConnection`
** `checkClientInfoSupport()` was removed;
there is no replacement
* `IEncodingFactory`
** `<T extends DatatypeCoder> T getOrCreateDatatypeCoder(Class<T>)` was removed;
its replacements is `<T extends DatatypeCoder> T getOrCreateDatatypeCoder(Class<T>, Function<IEncodingFactory, T>)` where the function is a factory for the desired `DatatypeCoder` instance if it doesn't already exist.

[#breaking-changes-unlikely]
=== Unlikely breaking changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.nio.charset.Charset;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;

/**
* Implementation of {@link IEncodingFactory} that wraps an {@link EncodingFactory} to
Expand Down Expand Up @@ -176,13 +177,11 @@ public IEncodingFactory withDefaultEncodingDefinition(Charset charset) {
return withDefaultEncodingDefinition(getEncodingDefinitionByCharset(charset));
}

@SuppressWarnings("unchecked")
@Override
public <T extends DatatypeCoder> T getOrCreateDatatypeCoder(Class<T> datatypeCoderClass) {
return (T) datatypeCoderCache.computeIfAbsent(datatypeCoderClass, this::createNewDatatypeCoder);
public <T extends DatatypeCoder> T getOrCreateDatatypeCoder(Class<T> datatypeCoderClass,
Function<IEncodingFactory, T> datatypeCoderFactory) {
return datatypeCoderClass.cast(
datatypeCoderCache.computeIfAbsent(datatypeCoderClass, clazz -> datatypeCoderFactory.apply(this)));
}

private <T extends DatatypeCoder> T createNewDatatypeCoder(Class<T> datatypeCoderClass) {
return EncodingFactory.createNewDatatypeCoder(datatypeCoderClass, this);
}
}
31 changes: 5 additions & 26 deletions src/main/org/firebirdsql/encodings/EncodingFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@

import org.firebirdsql.gds.ISCConstants;
import org.firebirdsql.gds.ng.DatatypeCoder;
import org.firebirdsql.gds.ng.DefaultDatatypeCoder;
import org.firebirdsql.jaybird.util.PluginLoader;

import java.lang.reflect.Constructor;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;

import static java.lang.System.Logger.Level.DEBUG;
import static java.lang.System.Logger.Level.WARNING;
Expand Down Expand Up @@ -314,31 +313,11 @@ public IEncodingFactory withDefaultEncodingDefinition(Charset charset) {
return withDefaultEncodingDefinition(getEncodingDefinitionByCharset(charset));
}

@SuppressWarnings("unchecked")
@Override
public <T extends DatatypeCoder> T getOrCreateDatatypeCoder(Class<T> datatypeCoderClass) {
return (T) datatypeCoderCache.computeIfAbsent(datatypeCoderClass, this::createNewDatatypeCoder);
}

private <T extends DatatypeCoder> T createNewDatatypeCoder(Class<T> datatypeCoderClass) {
return createNewDatatypeCoder(datatypeCoderClass, this);
}

@SuppressWarnings({ "unchecked" })
static <T extends DatatypeCoder> T createNewDatatypeCoder(Class<T> datatypeCoderClass,
IEncodingFactory encodingFactory) {
// Avoid reflection if we can:
if (datatypeCoderClass == DefaultDatatypeCoder.class) {
return (T) new DefaultDatatypeCoder(encodingFactory);
} else {
try {
Constructor<T> datatypeCoderConstructor = datatypeCoderClass.getConstructor(IEncodingFactory.class);
return datatypeCoderConstructor.newInstance(encodingFactory);
} catch (ReflectiveOperationException e) {
throw new IllegalArgumentException("Type " + datatypeCoderClass +
" has no single arg constructor accepting an IEncodingFactory");
}
}
public <T extends DatatypeCoder> T getOrCreateDatatypeCoder(Class<T> datatypeCoderClass,
Function<IEncodingFactory, T> datatypeCoderFactory) {
return datatypeCoderClass.cast(
datatypeCoderCache.computeIfAbsent(datatypeCoderClass, clazz -> datatypeCoderFactory.apply(this)));
}

/**
Expand Down
12 changes: 9 additions & 3 deletions src/main/org/firebirdsql/encodings/IEncodingFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.firebirdsql.gds.ng.DatatypeCoder;

import java.nio.charset.Charset;
import java.util.function.Function;

/**
* Interface for the EncodingFactory.
Expand Down Expand Up @@ -228,10 +229,15 @@ public interface IEncodingFactory {
* </p>
*
* @param datatypeCoderClass
* Type of datatype coder, needs to have a single-arg constructor accepting an {@code IEncodingFactory}.
* type of datatype coder
* @param datatypeCoderFactory
* function for creating the datatype coder if it doesn't already exist
* @param <T>
* Type parameter of type {@link DatatypeCoder}
* type parameter of type {@link DatatypeCoder}
* @return New or cached instance of datatype coder
* @since 6
*/
<T extends DatatypeCoder> T getOrCreateDatatypeCoder(Class<T> datatypeCoderClass);
<T extends DatatypeCoder> T getOrCreateDatatypeCoder(Class<T> datatypeCoderClass,
Function<IEncodingFactory, T> datatypeCoderFactory);

}
2 changes: 1 addition & 1 deletion src/main/org/firebirdsql/gds/ng/DefaultDatatypeCoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public class DefaultDatatypeCoder implements DatatypeCoder {
* @return datatype coder, this might be a cached instance
*/
public static DefaultDatatypeCoder forEncodingFactory(IEncodingFactory encodingFactory) {
return encodingFactory.getOrCreateDatatypeCoder(DefaultDatatypeCoder.class);
return encodingFactory.getOrCreateDatatypeCoder(DefaultDatatypeCoder.class, DefaultDatatypeCoder::new);
}

/**
Expand Down

0 comments on commit 4589a7f

Please sign in to comment.