Skip to content

Commit

Permalink
Match ObjectReader factory functions more generously
Browse files Browse the repository at this point in the history
  • Loading branch information
falkreon committed Jul 26, 2024
1 parent b9fd634 commit b587dfe
Showing 1 changed file with 38 additions and 4 deletions.
42 changes: 38 additions & 4 deletions src/main/java/blue/endless/jankson/api/io/ObjectReaderFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.function.Function;

import blue.endless.jankson.api.document.ValueElement;
import blue.endless.jankson.impl.TypeMagic;
import blue.endless.jankson.impl.io.objectreader.ObjectStructuredDataReader;

/**
Expand All @@ -39,7 +40,23 @@
* readers externally.
*/
public class ObjectReaderFactory {
private Map<Type, Function<Object, StructuredDataReader>> functionMap = new HashMap<>();
private final Map<Type, Function<Object, StructuredDataReader>> functionMap = new HashMap<>();
/** If true, only match exact types given **/
private boolean precise = false;

/**
* When precise is true, only exact matches will be used to generate readers. When precise is
* false, exact matches are preferred, but if an exact match cannot be found, a serializer or
* reader factory function for a superclass will be selected if available.
*
* <p>Note that fuzzy matching of classes requires a full traversal of the registrations, so the
* more registrations there are, the larger the speed gain precise mode will have.
*
* @param value true to put this factory in precise mode, false to match loosely. Defaults to false.
*/
public void setPrecise(boolean value) {
this.precise = value;
}

/**
* Registers a "classic" serializer for the specified type.
Expand Down Expand Up @@ -110,9 +127,18 @@ public StructuredDataReader getReader(Type type, final Object objectOfType) {
}

Function<Object, StructuredDataReader> function = functionMap.get(type);
return (function == null) ?
ObjectStructuredDataReader.of(objectOfType, this) :
function.apply(objectOfType);
if (function != null) return function.apply(objectOfType);

if (!precise) {
Class<?> targetClass = TypeMagic.getErasedClass(type);
for(Map.Entry<Type, Function<Object, StructuredDataReader>> entry : functionMap.entrySet()) {
Class<?> curClass = TypeMagic.getErasedClass(entry.getKey());
if (curClass.isAssignableFrom(targetClass)) return entry.getValue().apply(objectOfType);
entry.getKey().getClass().isAssignableFrom(type.getClass());
}
}

return ObjectStructuredDataReader.of(objectOfType, this);
}

/**
Expand All @@ -124,4 +150,12 @@ public StructuredDataReader getReader(Type type, final Object objectOfType) {
public StructuredDataReader getReader(Object object) {
return getReader(object.getClass(), object);
}

public ObjectReaderFactory copy() {
ObjectReaderFactory result = new ObjectReaderFactory();
result.functionMap.putAll(this.functionMap);
result.precise = this.precise;

return result;
}
}

0 comments on commit b587dfe

Please sign in to comment.