IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
+ */
+package combined.api.api;
+
+import combined.api.model.Customer;
+import combined.api.model.CustomerCreate;
+import combined.api.model.CustomerUpdate;
+import io.smallrye.mutiny.Uni;
+import java.util.List;
+import java.util.Optional;
+
+public interface CustomersApi {
+ /** Create a new customer */
+ Uni createCustomer(CustomerCreate body);
+
+ /** Get customer by ID */
+ Uni getCustomer(Long customerId);
+
+ /** List all customers */
+ Uni> listCustomers(
+
+ /** Filter by active status */
+ Optional isActive);
+
+ /** Update customer */
+ Uni updateCustomer(Long customerId, CustomerUpdate body);
+}
diff --git a/testers/combined/java/generated-and-checked-in/api/combined/api/api/CustomersApiServer.java b/testers/combined/java/generated-and-checked-in/api/combined/api/api/CustomersApiServer.java
new file mode 100644
index 0000000000..a9050c1790
--- /dev/null
+++ b/testers/combined/java/generated-and-checked-in/api/combined/api/api/CustomersApiServer.java
@@ -0,0 +1,58 @@
+/**
+ * File has been automatically generated by `typo`.
+ *
+ *
IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
+ */
+package combined.api.api;
+
+import combined.api.model.Customer;
+import combined.api.model.CustomerCreate;
+import combined.api.model.CustomerUpdate;
+import io.smallrye.mutiny.Uni;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.PUT;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+import java.util.List;
+import java.util.Optional;
+
+@Path("/customers")
+public interface CustomersApiServer extends CustomersApi {
+ /** Create a new customer */
+ @Override
+ @POST
+ @Path("")
+ @Consumes(value = {MediaType.APPLICATION_JSON})
+ @Produces(value = {MediaType.APPLICATION_JSON})
+ Uni createCustomer(CustomerCreate body);
+
+ /** Get customer by ID */
+ @Override
+ @GET
+ @Path("/{customerId}")
+ @Produces(value = {MediaType.APPLICATION_JSON})
+ Uni getCustomer(@PathParam("customerId") Long customerId);
+
+ /** List all customers */
+ @Override
+ @GET
+ @Path("")
+ @Produces(value = {MediaType.APPLICATION_JSON})
+ Uni> listCustomers(
+
+ /** Filter by active status */
+ @QueryParam("isActive") Optional isActive);
+
+ /** Update customer */
+ @Override
+ @PUT
+ @Path("/{customerId}")
+ @Consumes(value = {MediaType.APPLICATION_JSON})
+ @Produces(value = {MediaType.APPLICATION_JSON})
+ Uni updateCustomer(@PathParam("customerId") Long customerId, CustomerUpdate body);
+}
diff --git a/testers/combined/java/generated-and-checked-in/api/combined/api/api/EmployeesApi.java b/testers/combined/java/generated-and-checked-in/api/combined/api/api/EmployeesApi.java
new file mode 100644
index 0000000000..3c2c627a9c
--- /dev/null
+++ b/testers/combined/java/generated-and-checked-in/api/combined/api/api/EmployeesApi.java
@@ -0,0 +1,22 @@
+/**
+ * File has been automatically generated by `typo`.
+ *
+ *
IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
+ */
+package combined.api.api;
+
+import combined.api.model.Employee;
+import io.smallrye.mutiny.Uni;
+import java.util.List;
+import java.util.Optional;
+
+public interface EmployeesApi {
+ /** Get employee by ID */
+ Uni getEmployee(Integer employeeId);
+
+ /** List all employees */
+ Uni> listEmployees(
+
+ /** Filter by active status */
+ Optional isActive);
+}
diff --git a/testers/combined/java/generated-and-checked-in/api/combined/api/api/EmployeesApiServer.java b/testers/combined/java/generated-and-checked-in/api/combined/api/api/EmployeesApiServer.java
new file mode 100644
index 0000000000..38e0c041e0
--- /dev/null
+++ b/testers/combined/java/generated-and-checked-in/api/combined/api/api/EmployeesApiServer.java
@@ -0,0 +1,37 @@
+/**
+ * File has been automatically generated by `typo`.
+ *
+ *
IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
+ */
+package combined.api.api;
+
+import combined.api.model.Employee;
+import io.smallrye.mutiny.Uni;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+import java.util.List;
+import java.util.Optional;
+
+@Path("/employees")
+public interface EmployeesApiServer extends EmployeesApi {
+ /** Get employee by ID */
+ @Override
+ @GET
+ @Path("/{employeeId}")
+ @Produces(value = {MediaType.APPLICATION_JSON})
+ Uni getEmployee(@PathParam("employeeId") Integer employeeId);
+
+ /** List all employees */
+ @Override
+ @GET
+ @Path("")
+ @Produces(value = {MediaType.APPLICATION_JSON})
+ Uni> listEmployees(
+
+ /** Filter by active status */
+ @QueryParam("isActive") Optional isActive);
+}
diff --git a/testers/combined/java/generated-and-checked-in/api/combined/api/api/ProductsApi.java b/testers/combined/java/generated-and-checked-in/api/combined/api/api/ProductsApi.java
new file mode 100644
index 0000000000..1deba2cda3
--- /dev/null
+++ b/testers/combined/java/generated-and-checked-in/api/combined/api/api/ProductsApi.java
@@ -0,0 +1,20 @@
+/**
+ * File has been automatically generated by `typo`.
+ *
+ *
IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
+ */
+package combined.api.api;
+
+import combined.api.model.Product;
+import io.smallrye.mutiny.Uni;
+import java.util.List;
+import java.util.Optional;
+
+public interface ProductsApi {
+ /** List all products from both databases */
+ Uni> listProducts(
+ /** Filter by data source */
+ Optional source,
+ /** Filter by active status */
+ Optional isActive);
+}
diff --git a/testers/combined/java/generated-and-checked-in/api/combined/api/api/ProductsApiServer.java b/testers/combined/java/generated-and-checked-in/api/combined/api/api/ProductsApiServer.java
new file mode 100644
index 0000000000..faa0521183
--- /dev/null
+++ b/testers/combined/java/generated-and-checked-in/api/combined/api/api/ProductsApiServer.java
@@ -0,0 +1,31 @@
+/**
+ * File has been automatically generated by `typo`.
+ *
+ *
IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
+ */
+package combined.api.api;
+
+import combined.api.model.Product;
+import io.smallrye.mutiny.Uni;
+import jakarta.ws.rs.DefaultValue;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+import java.util.List;
+import java.util.Optional;
+
+@Path("/products")
+public interface ProductsApiServer extends ProductsApi {
+ /** List all products from both databases */
+ @Override
+ @GET
+ @Path("")
+ @Produces(value = {MediaType.APPLICATION_JSON})
+ Uni> listProducts(
+ /** Filter by data source */
+ @QueryParam("source") @DefaultValue("all") Optional source,
+ /** Filter by active status */
+ @QueryParam("isActive") Optional isActive);
+}
diff --git a/testers/combined/java/generated-and-checked-in/api/combined/api/model/Customer.java b/testers/combined/java/generated-and-checked-in/api/combined/api/model/Customer.java
new file mode 100644
index 0000000000..79c4b69ea7
--- /dev/null
+++ b/testers/combined/java/generated-and-checked-in/api/combined/api/model/Customer.java
@@ -0,0 +1,74 @@
+/**
+ * File has been automatically generated by `typo`.
+ *
+ *
IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
+ */
+package combined.api.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import combined.shared.FirstName;
+import combined.shared.IsActive;
+import combined.shared.LastName;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import java.time.OffsetDateTime;
+import java.util.Optional;
+
+public record Customer(
+ /** When the customer was created */
+ @JsonProperty("createdAt") Optional createdAt,
+ /** Customer ID */
+ @JsonProperty("customerId") @NotNull Long customerId,
+ /** Customer's email address (matches Email type) */
+ @JsonProperty("email") @NotNull @Email String email,
+ /** Customer's first name (matches FirstName type) */
+ @JsonProperty("firstName") @NotNull @Size(max = 100) FirstName firstName,
+ /** Whether customer account is active (matches IsActive type) */
+ @JsonProperty("isActive") @NotNull IsActive isActive,
+ /** Customer's last name (matches LastName type) */
+ @JsonProperty("lastName") @NotNull @Size(max = 100) LastName lastName,
+ /** Customer loyalty tier */
+ @JsonProperty("tier") Optional tier) {
+ /** When the customer was created */
+ public Customer withCreatedAt(Optional createdAt) {
+ return new Customer(createdAt, customerId, email, firstName, isActive, lastName, tier);
+ }
+ ;
+
+ /** Customer ID */
+ public Customer withCustomerId(Long customerId) {
+ return new Customer(createdAt, customerId, email, firstName, isActive, lastName, tier);
+ }
+ ;
+
+ /** Customer's email address (matches Email type) */
+ public Customer withEmail(String email) {
+ return new Customer(createdAt, customerId, email, firstName, isActive, lastName, tier);
+ }
+ ;
+
+ /** Customer's first name (matches FirstName type) */
+ public Customer withFirstName(FirstName firstName) {
+ return new Customer(createdAt, customerId, email, firstName, isActive, lastName, tier);
+ }
+ ;
+
+ /** Whether customer account is active (matches IsActive type) */
+ public Customer withIsActive(IsActive isActive) {
+ return new Customer(createdAt, customerId, email, firstName, isActive, lastName, tier);
+ }
+ ;
+
+ /** Customer's last name (matches LastName type) */
+ public Customer withLastName(LastName lastName) {
+ return new Customer(createdAt, customerId, email, firstName, isActive, lastName, tier);
+ }
+ ;
+
+ /** Customer loyalty tier */
+ public Customer withTier(Optional tier) {
+ return new Customer(createdAt, customerId, email, firstName, isActive, lastName, tier);
+ }
+ ;
+}
diff --git a/testers/combined/java/generated-and-checked-in/api/combined/api/model/CustomerCreate.java b/testers/combined/java/generated-and-checked-in/api/combined/api/model/CustomerCreate.java
new file mode 100644
index 0000000000..7ed11491ab
--- /dev/null
+++ b/testers/combined/java/generated-and-checked-in/api/combined/api/model/CustomerCreate.java
@@ -0,0 +1,46 @@
+/**
+ * File has been automatically generated by `typo`.
+ *
+ *
IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
+ */
+package combined.api.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import combined.shared.FirstName;
+import combined.shared.LastName;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import java.util.Optional;
+
+public record CustomerCreate(
+ /** Customer's email address (matches Email type) */
+ @JsonProperty("email") @NotNull @Email String email,
+ /** Customer's first name (matches FirstName type) */
+ @JsonProperty("firstName") @NotNull @Size(max = 100) FirstName firstName,
+ /** Customer's last name (matches LastName type) */
+ @JsonProperty("lastName") @NotNull @Size(max = 100) LastName lastName,
+ @JsonProperty("tier") Optional tier) {
+ /** Customer's email address (matches Email type) */
+ public CustomerCreate withEmail(String email) {
+ return new CustomerCreate(email, firstName, lastName, tier);
+ }
+ ;
+
+ /** Customer's first name (matches FirstName type) */
+ public CustomerCreate withFirstName(FirstName firstName) {
+ return new CustomerCreate(email, firstName, lastName, tier);
+ }
+ ;
+
+ /** Customer's last name (matches LastName type) */
+ public CustomerCreate withLastName(LastName lastName) {
+ return new CustomerCreate(email, firstName, lastName, tier);
+ }
+ ;
+
+ public CustomerCreate withTier(Optional tier) {
+ return new CustomerCreate(email, firstName, lastName, tier);
+ }
+ ;
+}
diff --git a/testers/combined/java/generated-and-checked-in/api/combined/api/model/CustomerUpdate.java b/testers/combined/java/generated-and-checked-in/api/combined/api/model/CustomerUpdate.java
new file mode 100644
index 0000000000..1cfa75f845
--- /dev/null
+++ b/testers/combined/java/generated-and-checked-in/api/combined/api/model/CustomerUpdate.java
@@ -0,0 +1,54 @@
+/**
+ * File has been automatically generated by `typo`.
+ *
+ *
IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
+ */
+package combined.api.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import combined.shared.FirstName;
+import combined.shared.IsActive;
+import combined.shared.LastName;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.Size;
+import java.util.Optional;
+
+public record CustomerUpdate(
+ /** Customer's email address (matches Email type) */
+ @JsonProperty("email") @Email Optional email,
+ /** Customer's first name (matches FirstName type) */
+ @JsonProperty("firstName") @Size(max = 100) Optional firstName,
+ /** Whether customer account is active (matches IsActive type) */
+ @JsonProperty("isActive") Optional isActive,
+ /** Customer's last name (matches LastName type) */
+ @JsonProperty("lastName") @Size(max = 100) Optional lastName,
+ @JsonProperty("tier") Optional tier) {
+ /** Customer's email address (matches Email type) */
+ public CustomerUpdate withEmail(Optional email) {
+ return new CustomerUpdate(email, firstName, isActive, lastName, tier);
+ }
+ ;
+
+ /** Customer's first name (matches FirstName type) */
+ public CustomerUpdate withFirstName(Optional firstName) {
+ return new CustomerUpdate(email, firstName, isActive, lastName, tier);
+ }
+ ;
+
+ /** Whether customer account is active (matches IsActive type) */
+ public CustomerUpdate withIsActive(Optional isActive) {
+ return new CustomerUpdate(email, firstName, isActive, lastName, tier);
+ }
+ ;
+
+ /** Customer's last name (matches LastName type) */
+ public CustomerUpdate withLastName(Optional lastName) {
+ return new CustomerUpdate(email, firstName, isActive, lastName, tier);
+ }
+ ;
+
+ public CustomerUpdate withTier(Optional tier) {
+ return new CustomerUpdate(email, firstName, isActive, lastName, tier);
+ }
+ ;
+}
diff --git a/testers/combined/java/generated-and-checked-in/api/combined/api/model/Employee.java b/testers/combined/java/generated-and-checked-in/api/combined/api/model/Employee.java
new file mode 100644
index 0000000000..68ae979da6
--- /dev/null
+++ b/testers/combined/java/generated-and-checked-in/api/combined/api/model/Employee.java
@@ -0,0 +1,173 @@
+/**
+ * File has been automatically generated by `typo`.
+ *
+ *
IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
+ */
+package combined.api.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import combined.shared.FirstName;
+import combined.shared.IsActive;
+import combined.shared.IsSalaried;
+import combined.shared.LastName;
+import combined.shared.MiddleName;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import java.time.LocalDate;
+import java.util.Optional;
+
+public record Employee(
+ /** Employee's email address (matches Email type) */
+ @JsonProperty("email") @NotNull @Email String email,
+ /** Employee business entity ID */
+ @JsonProperty("employeeId") @NotNull Integer employeeId,
+ /** Employee's first name (matches FirstName type) */
+ @JsonProperty("firstName") @NotNull @Size(max = 50) FirstName firstName,
+ /** Date employee was hired */
+ @JsonProperty("hireDate") Optional hireDate,
+ /** Whether employee is currently active (matches IsActive type) */
+ @JsonProperty("isActive") @NotNull IsActive isActive,
+ /** Whether employee is salaried vs hourly (matches SalariedFlag type) */
+ @JsonProperty("isSalaried") @NotNull IsSalaried isSalaried,
+ /** Job title */
+ @JsonProperty("jobTitle") Optional jobTitle,
+ /** Employee's last name (matches LastName type) */
+ @JsonProperty("lastName") @NotNull @Size(max = 50) LastName lastName,
+ /** Employee's middle name (matches MiddleName type) */
+ @JsonProperty("middleName") @Size(max = 50) Optional middleName) {
+ /** Employee's email address (matches Email type) */
+ public Employee withEmail(String email) {
+ return new Employee(
+ email,
+ employeeId,
+ firstName,
+ hireDate,
+ isActive,
+ isSalaried,
+ jobTitle,
+ lastName,
+ middleName);
+ }
+ ;
+
+ /** Employee business entity ID */
+ public Employee withEmployeeId(Integer employeeId) {
+ return new Employee(
+ email,
+ employeeId,
+ firstName,
+ hireDate,
+ isActive,
+ isSalaried,
+ jobTitle,
+ lastName,
+ middleName);
+ }
+ ;
+
+ /** Employee's first name (matches FirstName type) */
+ public Employee withFirstName(FirstName firstName) {
+ return new Employee(
+ email,
+ employeeId,
+ firstName,
+ hireDate,
+ isActive,
+ isSalaried,
+ jobTitle,
+ lastName,
+ middleName);
+ }
+ ;
+
+ /** Date employee was hired */
+ public Employee withHireDate(Optional hireDate) {
+ return new Employee(
+ email,
+ employeeId,
+ firstName,
+ hireDate,
+ isActive,
+ isSalaried,
+ jobTitle,
+ lastName,
+ middleName);
+ }
+ ;
+
+ /** Whether employee is currently active (matches IsActive type) */
+ public Employee withIsActive(IsActive isActive) {
+ return new Employee(
+ email,
+ employeeId,
+ firstName,
+ hireDate,
+ isActive,
+ isSalaried,
+ jobTitle,
+ lastName,
+ middleName);
+ }
+ ;
+
+ /** Whether employee is salaried vs hourly (matches SalariedFlag type) */
+ public Employee withIsSalaried(IsSalaried isSalaried) {
+ return new Employee(
+ email,
+ employeeId,
+ firstName,
+ hireDate,
+ isActive,
+ isSalaried,
+ jobTitle,
+ lastName,
+ middleName);
+ }
+ ;
+
+ /** Job title */
+ public Employee withJobTitle(Optional jobTitle) {
+ return new Employee(
+ email,
+ employeeId,
+ firstName,
+ hireDate,
+ isActive,
+ isSalaried,
+ jobTitle,
+ lastName,
+ middleName);
+ }
+ ;
+
+ /** Employee's last name (matches LastName type) */
+ public Employee withLastName(LastName lastName) {
+ return new Employee(
+ email,
+ employeeId,
+ firstName,
+ hireDate,
+ isActive,
+ isSalaried,
+ jobTitle,
+ lastName,
+ middleName);
+ }
+ ;
+
+ /** Employee's middle name (matches MiddleName type) */
+ public Employee withMiddleName(Optional middleName) {
+ return new Employee(
+ email,
+ employeeId,
+ firstName,
+ hireDate,
+ isActive,
+ isSalaried,
+ jobTitle,
+ lastName,
+ middleName);
+ }
+ ;
+}
diff --git a/testers/combined/java/generated-and-checked-in/api/combined/api/model/Product.java b/testers/combined/java/generated-and-checked-in/api/combined/api/model/Product.java
new file mode 100644
index 0000000000..9e40af7067
--- /dev/null
+++ b/testers/combined/java/generated-and-checked-in/api/combined/api/model/Product.java
@@ -0,0 +1,61 @@
+/**
+ * File has been automatically generated by `typo`.
+ *
+ *
IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
+ */
+package combined.api.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import combined.shared.IsActive;
+import jakarta.validation.constraints.NotNull;
+import java.util.Optional;
+
+public record Product(
+ /** Product description */
+ @JsonProperty("description") Optional description,
+ /** Whether product is active/visible (matches IsActive type) */
+ @JsonProperty("isActive") @NotNull IsActive isActive,
+ /** Product name */
+ @JsonProperty("name") @NotNull String name,
+ /** Product price */
+ @JsonProperty("price") Optional price,
+ /** Product ID (prefixed with source, e.g., "pg-123" or "maria-456") */
+ @JsonProperty("productId") @NotNull String productId,
+ /** Which database this product comes from */
+ @JsonProperty("source") @NotNull String source) {
+ /** Product description */
+ public Product withDescription(Optional description) {
+ return new Product(description, isActive, name, price, productId, source);
+ }
+ ;
+
+ /** Whether product is active/visible (matches IsActive type) */
+ public Product withIsActive(IsActive isActive) {
+ return new Product(description, isActive, name, price, productId, source);
+ }
+ ;
+
+ /** Product name */
+ public Product withName(String name) {
+ return new Product(description, isActive, name, price, productId, source);
+ }
+ ;
+
+ /** Product price */
+ public Product withPrice(Optional price) {
+ return new Product(description, isActive, name, price, productId, source);
+ }
+ ;
+
+ /** Product ID (prefixed with source, e.g., "pg-123" or "maria-456") */
+ public Product withProductId(String productId) {
+ return new Product(description, isActive, name, price, productId, source);
+ }
+ ;
+
+ /** Which database this product comes from */
+ public Product withSource(String source) {
+ return new Product(description, isActive, name, price, productId, source);
+ }
+ ;
+}
diff --git a/testers/combined/java/generated-and-checked-in/mariadb/combined/mariadb/DefaultedDeserializer.java b/testers/combined/java/generated-and-checked-in/mariadb/combined/mariadb/DefaultedDeserializer.java
new file mode 100644
index 0000000000..ff7d41fcf0
--- /dev/null
+++ b/testers/combined/java/generated-and-checked-in/mariadb/combined/mariadb/DefaultedDeserializer.java
@@ -0,0 +1,64 @@
+/**
+ * File has been automatically generated by `typo`.
+ *
+ *
IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
+ */
+package combined.mariadb;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
+import combined.mariadb.customtypes.Defaulted;
+import combined.mariadb.customtypes.Defaulted.Provided;
+import combined.mariadb.customtypes.Defaulted.UseDefault;
+import java.io.IOException;
+
+/** Jackson deserializer for Defaulted types */
+public class DefaultedDeserializer extends JsonDeserializer>
+ implements ContextualDeserializer {
+ JavaType valueType;
+
+ Class> defaultedClass;
+
+ public DefaultedDeserializer(JavaType valueType, Class> defaultedClass) {
+ this.valueType = valueType;
+ this.defaultedClass = defaultedClass;
+ }
+
+ @Override
+ public JsonDeserializer> createContextual(DeserializationContext ctxt, BeanProperty property) {
+ JavaType contextType = ctxt.getContextualType();
+ JavaType type = (contextType == null && property != null ? property.getType() : contextType);
+ if (type != null && type.containedTypeCount() > 0) {
+ return new DefaultedDeserializer(type.containedType(0), type.getRawClass());
+ }
+ ;
+ throw new RuntimeException("unexpected");
+ }
+
+ @Override
+ public Defaulted> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
+ if (p.currentToken() == JsonToken.VALUE_STRING) {
+ String text = p.getText();
+ if ("defaulted".equals(text)) {
+ return new UseDefault