Here is one of the unit tests for reading a file:
@Test
void testParseExample03() throws Exception {
LinkOrObject object = mapper.readValue(refactorExample("example_03.json"), LinkOrObject.class);
switch(object) {
case Activity activity -> {
assertThat(activity.summary()).isEqualTo("Sally did something to a note");
switch (activity.actor()) {
case Person person -> assertThat(
person.name()).isEqualTo("Sally");
default -> fail("Did not get the expected type for activity.actor");
}
switch (activity.object()) {
case Note note -> assertThat(
note.name()).isEqualTo("A Note");
default -> fail("Did not get the expected type for activity.object");
}
}
default -> fail("Did not get the expected type when parsing");
}
}
Here is the LinkOrObject top level interface (the instantiatable values
are all records, the intermediates are interfaces):
@JsonTypeInfo(use=
JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type" )
@JsonSubTypes({
@Type(value = ActivityStreamObjectRecord.class, name = ActivityStreamObjectType.Names.OBJECT),
@Type(value = ActivityRecord.class, name = ActivityStreamObjectType.Names.ACTIVITY),
@Type(value = Accept.class, name = ActivityStreamObjectType.Names.ACCEPT),
@Type(value = Invite.class, name = ActivityStreamObjectType.Names.INVITE),
@Type(value = Travel.class, name =
ActivityStreamObjectType.Names.TRAVEL),
@Type(value = CollectionRecord.class, name = ActivityStreamObjectType.Names.COLLECTION),
@Type(value = OrderedCollectionRecord.class, name = ActivityStreamObjectType.Names.ORDERED_COLLECTION),
@Type(value = CollectionPage.class, name = ActivityStreamObjectType.Names.COLLECTION_PAGE),
@Type(value = OrderedCollectionPage.class, name = ActivityStreamObjectType.Names.ORDERED_COLLECTION_PAGE),
@Type(value = Person.class, name = ActivityStreamObjectType.Names.PERSON),
@Type(value = NoteRecord.class, name = ActivityStreamObjectType.Names.NOTE),
@Type(value = Place.class, name = ActivityStreamObjectType.Names.PLACE),
@Type(value = Link.class, name = ActivityStreamObjectType.Names.LINK)
})
public sealed interface LinkOrObject permits Link, ActivityStreamObject {
public ActivityStreamObjectType type();
}
ActivityStreamObjectType is an enum defined this way:
public enum ActivityStreamObjectType {
Object(Names.OBJECT),
Activity(Names.ACTIVITY),
Accept(Names.ACCEPT),
Invite(Names.INVITE),
Travel(Names.TRAVEL),
Collection(Names.COLLECTION),
OrderedCollection(Names.ORDERED_COLLECTION),
CollectionPage(Names.COLLECTION_PAGE),
OrderedCollectionPage(Names.ORDERED_COLLECTION_PAGE),
Application(Names.APPLICATION),
Group(Names.GROUP),
Organization(Names.ORGANIZATION),
Person(Names.PERSON),
Service(Names.SERVICE),
Note(Names.NOTE),
Place(Names.PLACE),
Link(Names.LINK);
public class Names {
public static final String OBJECT = "Object";
public static final String ACTIVITY = "Activity";
public static final String ACCEPT = "Accept";
public static final String INVITE = "Invite";
public static final String TRAVEL = "Travel";
public static final String COLLECTION = "Collection";
public static final String ORDERED_COLLECTION = "OrderedCollection";
public static final String COLLECTION_PAGE = "CollectionPage";
public static final String ORDERED_COLLECTION_PAGE = "OrderedCollectionPage";
public static final String APPLICATION = "Application";
public static final String GROUP = "Group";
public static final String ORGANIZATION = "Organization";
public static final String PERSON = "Person";
public static final String SERVICE = "Service";
public static final String NOTE = "Note";
public static final String PLACE = "Place";
public static final String LINK = "Link";
}
private final String label;
private ActivityStreamObjectType(String label) {
this.label = label;
}
public String toString() {
return label;
}
}
Here is an instantiable record type:
public record CollectionPage(
@JsonGetter("@context") Object context,
ActivityStreamObjectType type,
String id,
String name,
String summary,
int totalItems,
List<LinkOrObject> items,
String partOf
) implements Collection
{
}