Skip to content

Commit

Permalink
fix(model): use SettableBeanProperty.Delegating for jackson delegatio…
Browse files Browse the repository at this point in the history
…n (6343)

fix(model): Use SettableBeanProperty.Delegating for jackson delegation

Changes the delegation in SettableBeanPropertyDelegate from
a custom implementation to the standard way of implementing
a delegating property in jackson. This way, if some jackson
module overrides methods that are not delegated explicitely
here, they will continue to work.

Fixes: #6342
---
fix: SettableBeanProperty.deserializeSetAndReturn should return instance instead of null

Signed-off-by: Marc Nuri <[email protected]>
---
test:refactor: SettableBeanPropertyDelegateTest doesn't rely on mocks

Signed-off-by: Marc Nuri <[email protected]>
---
fix: SettableBeanPropertyDelegate implements all methods from SettableBeanProperty

Includes tests to ensure all methods are implemented in future
Jackson versions too.

Signed-off-by: Marc Nuri <[email protected]>

Co-authored-by: Marc Nuri <[email protected]>
Signed-off-by: Marc Nuri <[email protected]>
  • Loading branch information
fxshlein and manusa committed Sep 25, 2024
1 parent 9e105cb commit 928d356
Show file tree
Hide file tree
Showing 3 changed files with 479 additions and 133 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#### Bugs
* Fix #6247: Support for proxy authentication from proxy URL user info

* Fix #6342: UnmatchedFieldTypeModule prevents certain jackson features from working

### 6.13.3 (2024-08-13)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,36 @@
package io.fabric8.kubernetes.model.jackson;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.NullValueProvider;
import com.fasterxml.jackson.databind.deser.SettableAnyProperty;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.ObjectIdInfo;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.function.BooleanSupplier;

/**
* This concrete sub-class encapsulates a {@link SettableBeanProperty} delegate that is always tried first.
* This concrete subclass encapsulates a {@link SettableBeanProperty} delegate that is always tried first.
*
* <p>
* A fall-back mechanism is implemented in the deserializeAndSet methods to allow field values that don't match the
* target type to be preserved in the anySetter method if exists.
*/
public class SettableBeanPropertyDelegate extends SettableBeanProperty {
public class SettableBeanPropertyDelegate extends SettableBeanProperty.Delegating {

private final SettableBeanProperty delegate;
private final SettableAnyProperty anySetter;
private final transient BooleanSupplier useAnySetter;

SettableBeanPropertyDelegate(SettableBeanProperty delegate, SettableAnyProperty anySetter, BooleanSupplier useAnySetter) {
super(delegate);
this.delegate = delegate;
this.anySetter = anySetter;
this.useAnySetter = useAnySetter;
}
Expand All @@ -54,64 +54,113 @@ public class SettableBeanPropertyDelegate extends SettableBeanProperty {
* {@inheritDoc}
*/
@Override
public SettableBeanProperty withValueDeserializer(JsonDeserializer<?> deser) {
return new SettableBeanPropertyDelegate(delegate.withValueDeserializer(deser), anySetter, useAnySetter);
protected SettableBeanProperty withDelegate(SettableBeanProperty d) {
return new SettableBeanPropertyDelegate(d, anySetter, useAnySetter);
}

/**
* {@inheritDoc}
*/
@Override
public SettableBeanProperty withName(PropertyName newName) {
return new SettableBeanPropertyDelegate(delegate.withName(newName), anySetter, useAnySetter);
public void markAsIgnorable() {
delegate.markAsIgnorable();
}

/**
* {@inheritDoc}
*/
@Override
public SettableBeanProperty withNullProvider(NullValueProvider nva) {
return new SettableBeanPropertyDelegate(delegate.withNullProvider(nva), anySetter, useAnySetter);
public boolean isIgnorable() {
return delegate.isIgnorable();
}

/**
* {@inheritDoc}
*/
@Override
public AnnotatedMember getMember() {
return delegate.getMember();
public void setViews(Class<?>[] views) {
delegate.setViews(views);
}

/**
* {@inheritDoc}
*/
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return delegate.getAnnotation(acls);
public <A extends Annotation> A getContextAnnotation(Class<A> acls) {
return delegate.getContextAnnotation(acls);
}

/**
* {@inheritDoc}
*/
@Override
public void fixAccess(DeserializationConfig config) {
delegate.fixAccess(config);
public PropertyName getWrapperName() {
return delegate.getWrapperName();
}

/**
* {@inheritDoc}
*/
@Override
public void markAsIgnorable() {
delegate.markAsIgnorable();
public NullValueProvider getNullValueProvider() {
return delegate.getNullValueProvider();
}

/**
* {@inheritDoc}
*/
@Override
public boolean isIgnorable() {
return delegate.isIgnorable();
public void depositSchemaProperty(JsonObjectFormatVisitor objectVisitor, SerializerProvider provider)
throws JsonMappingException {
delegate.depositSchemaProperty(objectVisitor, provider);
}

/**
* {@inheritDoc}
*/
@Override
public JavaType getType() {
return delegate.getType();
}

/**
* {@inheritDoc}
*/
@Override
public PropertyName getFullName() {
return delegate.getFullName();
}

/**
* {@inheritDoc}
*/
@Override
public void setManagedReferenceName(String n) {
delegate.setManagedReferenceName(n);
}

/**
* {@inheritDoc}
*/
@Override
public SettableBeanProperty withSimpleName(String simpleName) {
return _with(delegate.withSimpleName(simpleName));
}

/**
* {@inheritDoc}
*/
@Override
public void setObjectIdInfo(ObjectIdInfo objectIdInfo) {
delegate.setObjectIdInfo(objectIdInfo);
}

/**
* {@inheritDoc}
*/
@Override
public String toString() {
return delegate.toString();
}

/**
Expand Down Expand Up @@ -151,23 +200,7 @@ public Object deserializeSetAndReturn(JsonParser p, DeserializationContext ctxt,
} catch (MismatchedInputException ex) {
deserializeAndSet(p, ctxt, instance);
}
return null;
}

/**
* {@inheritDoc}
*/
@Override
public void set(Object instance, Object value) throws IOException {
delegate.set(instance, value);
}

/**
* {@inheritDoc}
*/
@Override
public Object setAndReturn(Object instance, Object value) throws IOException {
return delegate.setAndReturn(instance, value);
return instance;
}

private boolean shouldUseAnySetter() {
Expand Down
Loading

0 comments on commit 928d356

Please sign in to comment.