use of org.ehrbase.terminology.client.terminology.ValueSet in project openEHR_SDK by ehrbase.
the class ClassGenerator method addSimpleField.
private void addSimpleField(ClassGeneratorContext context, TypeSpec.Builder classBuilder, String path, WebTemplateNode endNode) {
Class<?> clazz = extractClass(endNode);
if (clazz == null) {
logger.warn("No class for path {} ", path);
return;
}
ValueSet valueSet = buildValueSet(endNode);
RmClassGeneratorConfig classGeneratorConfig = configMap.get(clazz);
if (classGeneratorConfig == null && !clazz.getName().contains("java.lang")) {
logger.debug("No ClassGenerator for {}", clazz);
}
boolean expand = classGeneratorConfig != null && classGeneratorConfig.isExpandField();
if (endNode.getRmType().equals("DV_CODED_TEXT") && !List.of("transition", "language", "setting", "category", "territory", "math_function", "null_flavour").contains(endNode.getId(false))) {
expand = expand && endNode.getInputs().stream().filter(i -> i.getType().equals("CODED_TEXT")).map(WebTemplateInput::getList).flatMap(List::stream).findAny().isPresent();
}
if (!expand) {
TypeName className = Optional.ofNullable(clazz).map(ClassName::get).orElse(ClassName.get(Object.class));
if (endNode.isMulti() && !context.nodeDeque.peek().getRmType().equals("ELEMENT")) {
className = ParameterizedTypeName.get(ClassName.get(List.class), className);
}
addField(context, classBuilder, path, endNode, className, valueSet, false);
} else {
Map<String, Field> fieldMap = Arrays.stream(FieldUtils.getAllFields(clazz)).filter(f -> !f.isSynthetic()).collect(Collectors.toMap(Field::getName, f -> f));
Set<String> expandFields = classGeneratorConfig.getExpandFields();
expandFields.forEach(fieldName -> addField(context, classBuilder, path + "|" + new SnakeCase(fieldName).camelToSnake(), endNode, ClassName.get(fieldMap.get(fieldName).getType()), valueSet, false));
}
}
use of org.ehrbase.terminology.client.terminology.ValueSet in project openEHR_SDK by ehrbase.
the class ClassGenerator method build.
private TypeSpec.Builder build(ClassGeneratorContext context, WebTemplateNode next) {
String className = defaultNamingStrategy.buildClassName(context, next, false, false);
context.currentFieldNameMap.push(new HashMap<>());
context.nodeDeque.push(next);
context.unFilteredNodeDeque.push(next);
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className);
if (StringUtils.isBlank(context.currentMainClass)) {
context.currentMainClass = className;
}
classBuilder.addModifiers(Modifier.PUBLIC);
classBuilder.addAnnotation(AnnotationSpec.builder(Entity.class).build());
if (next.isArchetype()) {
AnnotationSpec archetypeAnnotation = AnnotationSpec.builder(Archetype.class).addMember(Archetype.VALUE, "$S", next.getNodeId()).build();
classBuilder.addAnnotation(archetypeAnnotation);
}
AnnotationSpec generatedAnnotation = buildGeneratedAnnotation();
classBuilder.addAnnotation(generatedAnnotation);
classBuilder.addSuperinterface(findRMInterface(next));
if (next.getChildren().stream().anyMatch(n -> n.getRmType().equals("EVENT"))) {
WebTemplateNode event = next.getChildren().stream().filter(n -> n.getRmType().equals("EVENT")).findAny().orElseThrow();
Walker.EventHelper eventHelper = new Walker.EventHelper(event).invoke();
WebTemplateNode pointEvent = eventHelper.getPointEvent();
WebTemplateNode intervalEvent = eventHelper.getIntervalEvent();
next.getChildren().add(intervalEvent);
next.getChildren().add(pointEvent);
next.getChildren().remove(event);
}
Map<String, List<WebTemplateNode>> choices = next.getChoicesInChildren();
List<WebTemplateNode> children = next.getChildren().stream().filter(c -> choices.values().stream().flatMap(List::stream).noneMatch(l -> l.equals(c))).collect(Collectors.toList());
for (WebTemplateNode child : children) {
Deque<WebTemplateNode> filtersNodes = pushToUnfiltered(context, child);
String relativPath = context.nodeDeque.peek().buildRelativePath(child);
if (child.getChildren().isEmpty() && !choices.containsKey(child.getAqlPath())) {
addSimpleField(context, classBuilder, relativPath, child);
} else if (!choices.containsKey(child.getAqlPath())) {
addComplexField(context, classBuilder, relativPath, child);
}
if (!CollectionUtils.isEmpty(filtersNodes)) {
filtersNodes.forEach(n -> context.unFilteredNodeDeque.poll());
}
}
for (List<WebTemplateNode> choice : choices.values()) {
WebTemplateNode node = choice.get(0);
WebTemplateNode relativeNode = buildRelativeNode(context, node);
Deque<WebTemplateNode> filtersNodes = pushToUnfiltered(context, node);
TypeSpec interfaceSpec;
TypeName interfaceClassName;
if (context.currentTypeSpec.containsKey(relativeNode)) {
interfaceSpec = context.currentTypeSpec.get(relativeNode);
String interfacePackage = context.currentPackageName + "." + context.currentMainClass.toLowerCase() + DEFINITION_PACKAGE;
context.classes.put(interfacePackage, interfaceSpec);
interfaceClassName = ClassName.get(interfacePackage, interfaceSpec.name);
} else {
List<Pair<TypeSpec.Builder, WebTemplateNode>> builders = new ArrayList<>();
for (WebTemplateNode child : choice) {
TypeSpec.Builder build = build(context, child);
builders.add(new ImmutablePair<>(build, child));
}
TypeSpec.Builder interfaceBuilder = TypeSpec.interfaceBuilder(defaultNamingStrategy.buildClassName(context, choice.get(0), true, false)).addModifiers(Modifier.PUBLIC);
interfaceBuilder.addAnnotation(buildGeneratedAnnotation());
Set<FieldSpec> cowmenField = null;
for (Set<FieldSpec> fields : builders.stream().map(Pair::getLeft).map(s -> s.fieldSpecs).map(HashSet::new).collect(Collectors.toList())) {
if (cowmenField == null) {
cowmenField = fields;
} else {
cowmenField = SetUtils.intersection(cowmenField, fields);
}
}
if (cowmenField == null) {
cowmenField = Collections.emptySet();
}
cowmenField.forEach(f -> {
interfaceBuilder.addMethod(buildGetter(f, true));
interfaceBuilder.addMethod(buildSetter(f, true));
});
interfaceSpec = interfaceBuilder.build();
context.currentTypeSpec.put(relativeNode, interfaceSpec);
String interfacePackage = context.currentPackageName + "." + context.currentMainClass.toLowerCase() + DEFINITION_PACKAGE;
context.classes.put(interfacePackage, interfaceSpec);
interfaceClassName = ClassName.get(interfacePackage, interfaceSpec.name);
TypeName finalInterfaceClassName = interfaceClassName;
builders.forEach(pair -> {
TypeSpec.Builder builder = pair.getKey().addSuperinterface(finalInterfaceClassName).addAnnotation(AnnotationSpec.builder(OptionFor.class).addMember(OptionFor.VALUE, "$S", pair.getRight().getRmType()).build());
context.classes.put(interfacePackage, builder.build());
});
}
if (choice.stream().anyMatch(WebTemplateNode::isMulti)) {
interfaceClassName = ParameterizedTypeName.get(ClassName.get(List.class), interfaceClassName);
}
String relativPath = FlatPath.removeStart(new FlatPath(node.getAqlPath()), new FlatPath(next.getAqlPath())).toString();
addField(context, classBuilder, relativPath, node, interfaceClassName, new ValueSet(ValueSet.LOCAL, ValueSet.LOCAL, Collections.emptySet()), true);
if (!CollectionUtils.isEmpty(filtersNodes)) {
filtersNodes.forEach(n -> context.unFilteredNodeDeque.poll());
}
}
if (next.isArchetype()) {
context.currentArchetypeName.poll();
}
if (children.isEmpty() && choices.isEmpty()) {
addSimpleField(context, classBuilder, "", next);
}
context.currentFieldNameMap.poll();
context.nodeDeque.poll();
context.unFilteredNodeDeque.poll();
return classBuilder;
}
use of org.ehrbase.terminology.client.terminology.ValueSet in project openEHR_SDK by ehrbase.
the class OPTParser method parseCDOMAINTYPE.
private WebTemplateNode parseCDOMAINTYPE(CDOMAINTYPE cdomaintype, String aqlPath, Map<String, Map<String, TermDefinition>> termDefinitionMap, String rmAttributeName) {
WebTemplateNode node = buildNode(cdomaintype, rmAttributeName, termDefinitionMap, null);
node.setAqlPath(aqlPath);
if (cdomaintype instanceof CDVSTATE) {
throw new SdkException(String.format("Unexpected class: %s", cdomaintype.getClass().getSimpleName()));
} else if (cdomaintype instanceof CDVQUANTITY) {
WebTemplateInput magnitude = new WebTemplateInput();
magnitude.setSuffix("magnitude");
magnitude.setType("DECIMAL");
Optional.of((CDVQUANTITY) cdomaintype).map(CDVQUANTITY::getAssumedValue).map(DVQUANTITY::getMagnitude).map(d -> Double.toString(d)).ifPresent(magnitude::setDefaultValue);
inputHandler.findDefaultValue(node, "magnitude").ifPresent(magnitude::setDefaultValue);
node.getInputs().add(magnitude);
WebTemplateInput unit = new WebTemplateInput();
unit.setSuffix("unit");
unit.setType(CODED_TEXT);
Optional.of((CDVQUANTITY) cdomaintype).map(CDVQUANTITY::getAssumedValue).map(DVQUANTITY::getUnits).ifPresent(unit::setDefaultValue);
inputHandler.findDefaultValue(node, "units").ifPresent(unit::setDefaultValue);
node.getInputs().add(unit);
Arrays.stream(((CDVQUANTITY) cdomaintype).getListArray()).forEach(o -> {
WebTemplateInputValue value = new WebTemplateInputValue();
value.setLabel(o.getUnits());
value.setValue(o.getUnits());
WebTemplateValidation validation = new WebTemplateValidation();
boolean addValidation = false;
if (o.getMagnitude() != null) {
addValidation = true;
validation.setRange(inputHandler.extractInterval(o.getMagnitude()));
}
if (o.getPrecision() != null) {
addValidation = true;
validation.setPrecision(inputHandler.extractInterval(o.getPrecision()));
}
if (addValidation) {
value.setValidation(validation);
}
value.getLocalizedLabels().putAll(termDefinitionMap.getOrDefault(o.getUnits(), Collections.emptyMap()).entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getValue())));
unit.getList().add(value);
});
if (unit.getList().size() == 1) {
magnitude.setValidation(unit.getList().get(0).getValidation());
}
} else if (cdomaintype instanceof CDVORDINAL) {
WebTemplateInput code = new WebTemplateInput();
inputHandler.findDefaultValue(node, "defining_code").ifPresent(code::setDefaultValue);
code.setType(CODED_TEXT);
node.getInputs().add(code);
Optional.of((CDVORDINAL) cdomaintype).map(CDVORDINAL::getAssumedValue).map(DVORDINAL::getSymbol).map(DVCODEDTEXT::getDefiningCode).map(CODEPHRASE::getCodeString).ifPresent(code::setDefaultValue);
Arrays.stream(((CDVORDINAL) cdomaintype).getListArray()).forEach(o -> {
WebTemplateInputValue value = new WebTemplateInputValue();
value.setOrdinal(o.getValue());
value.setValue(o.getSymbol().getDefiningCode().getCodeString());
value.getLocalizedLabels().putAll(Optional.ofNullable(termDefinitionMap.get(value.getValue())).map(Map::entrySet).stream().flatMap(Set::stream).collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getValue())));
value.getLocalizedDescriptions().putAll(Optional.ofNullable(termDefinitionMap.get(value.getValue())).map(Map::entrySet).stream().flatMap(Set::stream).collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getDescription())));
value.setLabel(value.getLocalizedLabels().get(defaultLanguage));
if (!value.getLocalizedDescriptions().containsKey(defaultLanguage)) {
value.getLocalizedDescriptions().put(defaultLanguage, "");
}
code.getList().add(value);
});
} else if (cdomaintype instanceof CCODEPHRASE) {
WebTemplateInput code = new WebTemplateInput();
inputHandler.findDefaultValue(node, "defining_code").ifPresent(code::setDefaultValue);
code.setSuffix("code");
node.getInputs().add(code);
Optional.of((CCODEPHRASE) cdomaintype).map(CCODEPHRASE::getAssumedValue).map(CODEPHRASE::getCodeString).ifPresent(code::setDefaultValue);
if (cdomaintype instanceof CCODEREFERENCE) {
code.setTerminology(Optional.of((CCODEREFERENCE) cdomaintype).map(CCODEREFERENCE::getReferenceSetUri).map(s -> StringUtils.removeStart(s, "terminology:")).orElse(null));
} else {
code.setTerminology(Optional.of((CCODEPHRASE) cdomaintype).map(CCODEPHRASE::getTerminologyId).map(OBJECTID::getValue).orElse(null));
}
if (code.getTerminology().equals(OPENEHR)) {
ValueSet valueSet = TerminologyProvider.findOpenEhrValueSet(code.getTerminology(), ((CCODEPHRASE) cdomaintype).getCodeListArray(), defaultLanguage);
Map<String, ValueSet> collect = languages.stream().collect(Collectors.toMap(Function.identity(), l -> TerminologyProvider.findOpenEhrValueSet(code.getTerminology(), ((CCODEPHRASE) cdomaintype).getCodeListArray(), l)));
valueSet.getTherms().forEach(t -> {
WebTemplateInputValue value = new WebTemplateInputValue();
value.setValue(t.getCode());
value.setLabel(t.getValue());
value.getLocalizedLabels().putAll(collect.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getTherms().stream().filter(x -> x.getCode().equals(t.getCode())).findAny().map(TermDefinition::getValue).orElse(""))));
code.getList().add(value);
});
} else {
Arrays.stream(((CCODEPHRASE) cdomaintype).getCodeListArray()).map(o -> StringUtils.isBlank(code.getTerminology()) || "local".equals(code.getTerminology()) ? o : code.getTerminology() + "::" + o).forEach(o -> {
WebTemplateInputValue value = new WebTemplateInputValue();
Optional<TermDefinition> termDefinition = Optional.ofNullable(termDefinitionMap.get(o)).map(e -> e.get(defaultLanguage));
if (termDefinition.isEmpty()) {
o = o.replace(code.getTerminology() + "::", "");
termDefinition = Optional.ofNullable(termDefinitionMap.get(o)).map(e -> e.get(defaultLanguage));
}
if (termDefinition.isPresent()) {
value.setValue(termDefinition.get().getCode());
if (StringUtils.isNotBlank((code.getTerminology()))) {
value.setValue(value.getValue().replace(code.getTerminology() + "::", ""));
}
value.setLabel(termDefinition.get().getValue());
value.getLocalizedLabels().putAll(termDefinitionMap.getOrDefault(o, Collections.emptyMap()).entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getValue())));
value.getLocalizedDescriptions().putAll(termDefinitionMap.getOrDefault(o, Collections.emptyMap()).entrySet().stream().filter(e -> StringUtils.isNotBlank(e.getValue().getDescription())).collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getDescription())));
if (!value.getLocalizedDescriptions().containsKey(defaultLanguage)) {
value.getLocalizedDescriptions().put(defaultLanguage, "");
}
code.getList().add(value);
}
});
}
if (code.getList().isEmpty()) {
code.setType("TEXT");
WebTemplateInput value = inputHandler.buildWebTemplateInput("value", "TEXT");
value.setTerminology(code.getTerminology());
node.getInputs().add(value);
} else {
code.setType(CODED_TEXT);
}
} else {
throw new SdkException(String.format("Unexpected class: %s", cdomaintype.getClass().getSimpleName()));
}
return node;
}
use of org.ehrbase.terminology.client.terminology.ValueSet in project openEHR_SDK by ehrbase.
the class ClassGenerator method addComplexField.
private void addComplexField(ClassGeneratorContext context, TypeSpec.Builder classBuilder, String path, WebTemplateNode node) {
final TypeSpec subSpec;
WebTemplateNode relativeNode = buildRelativeNode(context, node);
if (context.currentTypeSpec.containsKey(relativeNode)) {
subSpec = context.currentTypeSpec.get(relativeNode);
} else {
subSpec = build(context, node).build();
context.currentTypeSpec.put(relativeNode, subSpec);
}
String subSpecPackage = context.currentPackageName + "." + context.currentMainClass.toLowerCase() + DEFINITION_PACKAGE;
context.classes.put(subSpecPackage, subSpec);
TypeName className = ClassName.get(subSpecPackage, subSpec.name);
if (node.isMulti()) {
className = ParameterizedTypeName.get(ClassName.get(List.class), className);
}
addField(context, classBuilder, path, node, className, new ValueSet(ValueSet.LOCAL, ValueSet.LOCAL, Collections.emptySet()), false);
}
use of org.ehrbase.terminology.client.terminology.ValueSet in project openEHR_SDK by ehrbase.
the class ClassGenerator method addField.
private void addField(ClassGeneratorContext context, TypeSpec.Builder classBuilder, String path, WebTemplateNode node, TypeName className, ValueSet valueSet, boolean addChoiceAnnotation) {
if (CodePhrase.class.getName().equals(className.toString()))
switch(node.getName()) {
case "language":
className = ClassName.get(Language.class);
break;
case "setting":
className = ClassName.get(Setting.class);
break;
case "category":
className = ClassName.get(Category.class);
break;
case "territory":
className = ClassName.get(Territory.class);
break;
case "math_function":
className = ClassName.get(MathFunction.class);
break;
case "transition":
className = ClassName.get(Transition.class);
break;
case "null_flavour":
className = ClassName.get(NullFlavour.class);
break;
default:
if (CollectionUtils.isNotEmpty(valueSet.getTherms())) {
final TypeSpec enumValueSet = context.currentEnums.computeIfAbsent(valueSet, vs -> buildEnumValueSet(context, node, vs));
String enumPackage = context.currentPackageName + "." + context.currentMainClass.toLowerCase() + DEFINITION_PACKAGE;
context.classes.put(enumPackage, enumValueSet);
className = ClassName.get(enumPackage, enumValueSet.name);
}
}
String fieldName = defaultNamingStrategy.buildFieldName(context, path, node);
FieldSpec.Builder builder = FieldSpec.builder(className, fieldName).addAnnotation(AnnotationSpec.builder(Path.class).addMember(Path.VALUE, "$S", path).build()).addModifiers(Modifier.PRIVATE).addJavadoc(defaultNamingStrategy.buildFieldJavadoc(context, node));
if (addChoiceAnnotation) {
builder.addAnnotation(Choice.class);
}
FieldSpec fieldSpec = builder.build();
classBuilder.addField(fieldSpec);
classBuilder.addMethod(buildSetter(fieldSpec, false));
classBuilder.addMethod(buildGetter(fieldSpec, false));
}
Aggregations