In Chefsculinar we transform all A12 DocumentModel JSON files into real Java POJO Classes + Builder at compile time. The reason is, in our project is performance is very important.
POJO(generated at compile time).
@Data
@NoArgsConstructor
@AllArgsConstructor
@Model("Announcement")
public class AnnouncementModel implements UIModel {
@JsonProperty("id")
@Mapping(name = "id", path = "id", field = true)
private Long id;
@JsonProperty("root")
@Mapping(name = "Root", path = "/Root", group = true)
private final RootModel root = new RootModel();
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class RootModel implements UIModel {
@JsonProperty("title")
@Mapping(name = "Title", path = "/Root/Title", field = true)
private String title;
@JsonProperty("content")
@Mapping(name = "Content", path = "/Root/Content", field = true)
private String content;
@JsonProperty("type")
@Mapping(name = "Type", path = "/Root/Type", field = true)
private String type;
@JsonProperty("start")
@Mapping(name = "Start", path = "/Root/Start", field = true)
private LocalDate start;
@JsonProperty("end")
@Mapping(name = "End", path = "/Root/End", field = true)
private LocalDate end;
}
}
Class To create IDocument (generated at compile time).
public class AnnouncementModelDocumentBuilder extends AbstractDocumentBuilder<AnnouncementModel> {
public AnnouncementModelDocumentBuilder(final IDocumentFactory documentFactory, final IDocumentRtService documentRtService) {
super(documentFactory, documentRtService, "Announcement", false);
}
@Override
public AnnouncementModel create() {
return new AnnouncementModel();
}
@Override
protected void apply(final IDocument document, final AnnouncementModel model, final int[] repetitions) {
if (model.getId() != null) {
document.setId(model.getId().toString());
}
final int[] repetitionsRootRepetitions = createFieldRepetition(repetitions, 1);
document.addEntityInstance(createGroupInstance("/Root", repetitionsRootRepetitions));
final com.mgmtp.chefsculinar.epsap.models.ui.model.announcement.AnnouncementModel.RootModel modelRoot = model.getRoot();
if (modelRoot.getTitle() != null) {
document.addEntityInstance(createFieldInstance("/Root/Title", modelRoot.getTitle(), String.class, repetitionsRootRepetitions));
}
if (modelRoot.getContent() != null) {
document.addEntityInstance(createFieldInstance("/Root/Content", modelRoot.getContent(), String.class, repetitionsRootRepetitions));
}
if (modelRoot.getType() != null) {
document.addEntityInstance(createFieldInstance("/Root/Type", modelRoot.getType(), String.class, repetitionsRootRepetitions));
}
if (modelRoot.getStart() != null) {
document.addEntityInstance(createFieldInstance("/Root/Start", modelRoot.getStart(), LocalDate.class, repetitionsRootRepetitions));
}
if (modelRoot.getEnd() != null) {
document.addEntityInstance(createFieldInstance("/Root/End", modelRoot.getEnd(), LocalDate.class, repetitionsRootRepetitions));
}
}
}
Class to create AnnouncementModel(generated at compile time).
public class AnnouncementDocumentToModelBuilder extends AbstractModelBuilder<AnnouncementModel> {
public AnnouncementDocumentToModelBuilder() {
super(getElementInfoMap());
}
private static Map<String, ElementInfo> getElementInfoMap() {
final Map<String, ElementInfo> elementInfoMap = new HashMap<>();
elementInfoMap.put("/Root", new GroupInfo<>(AnnouncementModel::getRoot));
elementInfoMap.put("/Root/Title", new FieldInfo<>(String.class, com.mgmtp.chefsculinar.epsap.models.ui.model.announcement.AnnouncementModel.RootModel::setTitle, false));
elementInfoMap.put("/Root/Content", new FieldInfo<>(String.class, com.mgmtp.chefsculinar.epsap.models.ui.model.announcement.AnnouncementModel.RootModel::setContent, false));
elementInfoMap.put("/Root/Type", new FieldInfo<>(String.class, com.mgmtp.chefsculinar.epsap.models.ui.model.announcement.AnnouncementModel.RootModel::setType, false));
elementInfoMap.put("/Root/Start", new FieldInfo<>(LocalDate.class, com.mgmtp.chefsculinar.epsap.models.ui.model.announcement.AnnouncementModel.RootModel::setStart, true));
elementInfoMap.put("/Root/End", new FieldInfo<>(LocalDate.class, com.mgmtp.chefsculinar.epsap.models.ui.model.announcement.AnnouncementModel.RootModel::setEnd, true));
return elementInfoMap;
}
@Override
protected AnnouncementModel createInstance(final IDocument document) {
final AnnouncementModel model = new AnnouncementModel();
model.setId(getIdFromDocument(document));
return model;
}
}
Typescript description file(generated at compile time).
import { A12Document } from "../A12Document";
export interface Root {
Title: string;
Content?: string;
Type: "ERROR" | "WARNING" | "INFO";
Start: string;
End: string;
}
export interface Announcement extends A12Document {
Root: Root;
}
PS: We dont use the Dataservice.
PPS: If you are interessetest, you can contact me, would be happy to share.
Also we have a development a solr gradle plugin/solr-api what generated Solr Documents at compile time from POJO classes. It would make it possible to save generated POJO classes as flat structure into solr and our solr-api supports delta/partial updates. That would mean, all A12 Documents can be saved as a real SorlDocuments without serialization into json. The solr api supports also delta updates.