Search in sources :

Example 1 with FlatPath

use of org.ehrbase.webtemplate.parser.FlatPath in project openEHR_SDK by ehrbase.

the class PathMatcher method matchesPath.

String matchesPath(Context<?> context, WebTemplateNode child, Map.Entry<String, ?> e) {
    String aqlPath = FlatPath.removeStart(new FlatPath(child.getAqlPath()), new FlatPath(context.getNodeDeque().peek().getAqlPath())).toString();
    if (StringUtils.startsWith(e.getKey(), aqlPath)) {
        return remove(e, aqlPath, child);
    } else {
        FlatPath childPath = new FlatPath(aqlPath);
        FlatPath pathLast = childPath.getLast();
        FlatPath pathWithoutLastName = FlatPath.addEnd(FlatPath.removeEnd(childPath, pathLast), new FlatPath(pathLast.format(false)));
        if (StringUtils.startsWith(e.getKey(), pathWithoutLastName.toString()) && context.getNodeDeque().peek().getChildren().stream().filter(n -> Objects.equals(n.getNodeId(), child.getNodeId())).count() == 1) {
            logger.warn("name/value not set in dto for {}", child.getAqlPath());
            return remove(e, pathWithoutLastName.toString(), child);
        } else {
            return null;
        }
    }
}
Also used : Objects(java.util.Objects) Context(org.ehrbase.serialisation.walker.Context) FlatPath(org.ehrbase.webtemplate.parser.FlatPath) Logger(org.slf4j.Logger) Map(java.util.Map) LoggerFactory(org.slf4j.LoggerFactory) WebTemplateNode(org.ehrbase.webtemplate.model.WebTemplateNode) StringUtils(org.apache.commons.lang3.StringUtils) FlatPath(org.ehrbase.webtemplate.parser.FlatPath)

Example 2 with FlatPath

use of org.ehrbase.webtemplate.parser.FlatPath in project openEHR_SDK by ehrbase.

the class WebTemplateSkeletonBuilder method insert.

public static void insert(WebTemplateNode parentNode, RMObject parentObject, WebTemplateNode childNode, Object childObject) {
    String attributeName = FlatPath.removeStart(new FlatPath(childNode.getAqlPath(true)), new FlatPath(parentNode.getAqlPath(true))).getLast().getName();
    RM_OBJECT_CREATOR.addElementToListOrSetSingleValues(parentObject, attributeName, Collections.singletonList(childObject));
}
Also used : FlatPath(org.ehrbase.webtemplate.parser.FlatPath)

Example 3 with FlatPath

use of org.ehrbase.webtemplate.parser.FlatPath 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;
}
Also used : Arrays(java.util.Arrays) Language(org.ehrbase.client.classgenerator.shareddefinition.Language) Composition(com.nedap.archie.rm.composition.Composition) Modifier(javax.lang.model.element.Modifier) MathFunction(org.ehrbase.client.classgenerator.shareddefinition.MathFunction) VersionUid(org.ehrbase.client.openehrclient.VersionUid) ArchieRMInfoLookup(com.nedap.archie.rminfo.ArchieRMInfoLookup) LoggerFactory(org.slf4j.LoggerFactory) ClassName(com.squareup.javapoet.ClassName) StringUtils(org.apache.commons.lang3.StringUtils) Pair(org.apache.commons.lang3.tuple.Pair) Generated(javax.annotation.processing.Generated) Map(java.util.Map) Category(org.ehrbase.client.classgenerator.shareddefinition.Category) Locatable(com.nedap.archie.rm.archetyped.Locatable) Transition(org.ehrbase.client.classgenerator.shareddefinition.Transition) CodePhrase(com.nedap.archie.rm.datatypes.CodePhrase) RMEntity(org.ehrbase.client.classgenerator.interfaces.RMEntity) Path(org.ehrbase.client.annotations.Path) Entry(com.nedap.archie.rm.composition.Entry) ReflectionHelper(org.ehrbase.util.reflection.ReflectionHelper) IntervalEventEntity(org.ehrbase.client.classgenerator.interfaces.IntervalEventEntity) FilteredWebTemplate(org.ehrbase.webtemplate.model.FilteredWebTemplate) WebTemplateInput(org.ehrbase.webtemplate.model.WebTemplateInput) Set(java.util.Set) Collectors(java.util.stream.Collectors) Template(org.ehrbase.client.annotations.Template) WebTemplateInputValue(org.ehrbase.webtemplate.model.WebTemplateInputValue) List(java.util.List) OffsetDateTime(java.time.OffsetDateTime) Type(java.lang.reflect.Type) TypeName(com.squareup.javapoet.TypeName) Optional(java.util.Optional) WebTemplateNode(org.ehrbase.webtemplate.model.WebTemplateNode) TermDefinition(org.ehrbase.terminology.client.terminology.TermDefinition) Territory(org.ehrbase.client.classgenerator.shareddefinition.Territory) FieldSpec(com.squareup.javapoet.FieldSpec) Id(org.ehrbase.client.annotations.Id) HashMap(java.util.HashMap) Deque(java.util.Deque) CompositionEntity(org.ehrbase.client.classgenerator.interfaces.CompositionEntity) CollectionUtils(org.apache.commons.collections4.CollectionUtils) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) PointEventEntity(org.ehrbase.client.classgenerator.interfaces.PointEventEntity) WebTemplateFilter(org.ehrbase.webtemplate.filter.WebTemplateFilter) SetUtils(org.apache.commons.collections4.SetUtils) FieldUtils(org.apache.commons.lang3.reflect.FieldUtils) OptionFor(org.ehrbase.client.annotations.OptionFor) EntryEntity(org.ehrbase.client.classgenerator.interfaces.EntryEntity) Logger(org.slf4j.Logger) MethodSpec(com.squareup.javapoet.MethodSpec) Walker(org.ehrbase.serialisation.walker.Walker) Archetype(org.ehrbase.client.annotations.Archetype) NullFlavour(org.ehrbase.client.classgenerator.shareddefinition.NullFlavour) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeSpec(com.squareup.javapoet.TypeSpec) Field(java.lang.reflect.Field) PointEvent(com.nedap.archie.rm.datastructures.PointEvent) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) RmClassGeneratorConfig(org.ehrbase.client.classgenerator.config.RmClassGeneratorConfig) WebTemplate(org.ehrbase.webtemplate.model.WebTemplate) SnakeCase(org.ehrbase.serialisation.util.SnakeCase) FlatPath(org.ehrbase.webtemplate.parser.FlatPath) LocatableEntity(org.ehrbase.client.classgenerator.interfaces.LocatableEntity) AnnotationSpec(com.squareup.javapoet.AnnotationSpec) Entity(org.ehrbase.client.annotations.Entity) Choice(org.ehrbase.client.annotations.Choice) ValueSet(org.ehrbase.terminology.client.terminology.ValueSet) IntervalEvent(com.nedap.archie.rm.datastructures.IntervalEvent) Collections(java.util.Collections) Setting(org.ehrbase.client.classgenerator.shareddefinition.Setting) TypeName(com.squareup.javapoet.TypeName) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) OptionFor(org.ehrbase.client.annotations.OptionFor) WebTemplateNode(org.ehrbase.webtemplate.model.WebTemplateNode) ArrayList(java.util.ArrayList) Walker(org.ehrbase.serialisation.walker.Walker) AnnotationSpec(com.squareup.javapoet.AnnotationSpec) FieldSpec(com.squareup.javapoet.FieldSpec) List(java.util.List) ArrayList(java.util.ArrayList) ValueSet(org.ehrbase.terminology.client.terminology.ValueSet) TypeSpec(com.squareup.javapoet.TypeSpec) Pair(org.apache.commons.lang3.tuple.Pair) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) FlatPath(org.ehrbase.webtemplate.parser.FlatPath)

Example 4 with FlatPath

use of org.ehrbase.webtemplate.parser.FlatPath in project openEHR_SDK by ehrbase.

the class LinkedTreeMapAdapter method writeNode.

@SuppressWarnings("unchecked")
private void writeNode(LinkedTreeMap<String, Object> map, JsonWriter writer) throws IOException {
    // some hacking for some specific entries...
    reformatMapForCanonical(map);
    for (Map.Entry<String, Object> entry : map.entrySet()) {
        Object value = entry.getValue();
        if (value == null)
            continue;
        String key = entry.getKey();
        if (new OptOut(key).skipIt())
            continue;
        String jsonKey = new RawJsonKey(key).toRawJson();
        final String archetypeNodeId = new NodeId(key).predicate();
        // required to deal with DV_MULTIMEDIA embedded document in data
        if (value instanceof ArrayList && key.equals("data") && map.get("_type").equals(ArchieRMInfoLookup.getInstance().getTypeInfo(DvMultimedia.class).getRmName())) {
            // prepare a store for the value
            Double[] dataStore = new Double[((ArrayList) value).size()];
            value = ((ArrayList<Double>) value).toArray(dataStore);
        }
        if (value instanceof ArrayList) {
            if (key.equals(CompositionSerializer.TAG_NAME)) {
                new ValueArrayList(writer, value, key).write();
            } else if (key.equals(TAG_CLASS)) {
                writer.name(AT_TYPE).value(new SnakeCase((String) ((ArrayList) value).get(0)).camelToUpperSnake());
            } else if (key.equals(CompositionSerializer.TAG_ARCHETYPE_NODE_ID)) {
                // same as name above, this is due to usage of MultiValueMap which is backed by ArrayList
                new ValueArrayList(writer, value, key).write();
            } else {
                // make sure we service a non empty array list value
                if (!new ArrayChildren((ArrayList) value).isNull()) {
                    writer.name(jsonKey);
                    writer.beginArray();
                    if (isNodePredicate(key)) {
                        ((ArrayList<Object>) value).stream().filter(o -> Map.class.isAssignableFrom(o.getClass())).forEach(m -> ((Map<String, Object>) m).put(I_DvTypeAdapter.ARCHETYPE_NODE_ID, archetypeNodeId));
                    }
                    new ArrayListAdapter().write(writer, (ArrayList) value);
                    writer.endArray();
                }
            }
        } else if (value instanceof LinkedTreeMap) {
            LinkedTreeMap<String, Object> valueMap = (LinkedTreeMap<String, Object>) value;
            String elementType = new ElementType(valueMap).type();
            if (elementType.equals("History")) {
                // promote events[...]
                LinkedTreeMap<String, Object> eventMap = (LinkedTreeMap<String, Object>) valueMap.get(CompositionSerializer.TAG_EVENTS);
                valueMap.remove(CompositionSerializer.TAG_EVENTS);
                valueMap.putAll(eventMap);
                valueMap.put(AT_TYPE, new SnakeCase(elementType).camelToUpperSnake());
            } else if (archetypeNodeId.equals(CompositionSerializer.TAG_TIMING) && elementType.equals("DvParsable")) {
                // promote value and formalism
                LinkedTreeMap<String, Object> timingValueMap = (LinkedTreeMap<String, Object>) valueMap.get(CompositionSerializer.TAG_VALUE);
                if (timingValueMap != null) {
                    valueMap.put(CompositionSerializer.TAG_VALUE, timingValueMap.get("value"));
                    valueMap.put("/formalism", timingValueMap.get("formalism"));
                }
            }
            if (key.equals(CompositionSerializer.TAG_VALUE)) {
                // get the class and add it to the value map
                String type = (String) map.get(TAG_CLASS);
                if (type != null && !type.isEmpty()) {
                    // pushed into the value map for the next recursion
                    valueMap.put(AT_TYPE, new SnakeCase(type).camelToUpperSnake());
                    // the value structure
                    if (new GenericRmType(type).isSpecialized()) {
                        // composite
                        valueMap = new GenericRmType(new SnakeCase(type).camelToUpperSnake()).inferSpecialization(valueMap);
                    }
                }
            }
            // get the value point type and add it to the value map
            if (valueMap.containsKey(TAG_CLASS)) {
                valueMap.put(AT_TYPE, new SnakeCase(elementType).camelToUpperSnake());
                valueMap.remove(TAG_CLASS);
                if (key.contains("/time")) {
                    valueMap.remove(CompositionSerializer.TAG_NAME);
                }
            }
            if (// contains an archetype node predicate
            isNodePredicate(key)) {
                valueMap.put(ARCHETYPE_NODE_ID, archetypeNodeId);
            } else if (key.equals(CompositionSerializer.TAG_ORIGIN) || key.equals(CompositionSerializer.TAG_TIME)) {
                // compact time expression
                valueMap = compactTimeMap(valueMap);
            }
            writer.name(jsonKey);
            new LinkedTreeMapAdapter().write(writer, valueMap);
        } else if (value instanceof String) {
            switch(key) {
                case TAG_CLASS:
                    if (Arrays.asList(structuralClasses).contains(value))
                        writer.name(AT_TYPE).value(new SnakeCase(((String) value)).camelToUpperSnake());
                    break;
                case // this is an element
                CompositionSerializer.TAG_PATH:
                    String archetypeNodeId2 = new FlatPath((String) value).getLast().getAtCode();
                    if (archetypeNodeId2 != null)
                        writer.name(AT_TYPE).value(ELEMENT);
                    // CHC 20191003: removed writer for archetype_node_id as it was not applicable here
                    break;
                case CompositionSerializer.TAG_NAME:
                    new NameValue(writer, value.toString()).write();
                    break;
                default:
                    writer.name(jsonKey).value((String) value);
                    break;
            }
        } else if (value instanceof Double) {
            writer.name(new SnakeCase(key).camelToSnake()).value((Double) value);
        } else if (value instanceof Long) {
            writer.name(new SnakeCase(key).camelToSnake()).value((Long) value);
        } else if (value instanceof Number) {
            writer.name(new SnakeCase(key).camelToSnake()).value((Number) value);
        } else if (value instanceof Boolean) {
            writer.name(new SnakeCase(key).camelToSnake()).value((Boolean) value);
        } else if (value instanceof Double[]) {
            writer.name(new SnakeCase(key).camelToSnake());
            writer.beginArray();
            for (Double pix : (Double[]) value) {
                writer.value(pix.byteValue());
            }
            writer.endArray();
        } else
            throw new IllegalArgumentException("Could not handle value type for key:" + key + ", value:" + value);
    }
}
Also used : Arrays(java.util.Arrays) ArchieRMInfoLookup(com.nedap.archie.rminfo.ArchieRMInfoLookup) IOException(java.io.IOException) CompositionSerializer(org.ehrbase.serialisation.dbencoding.CompositionSerializer) TypeAdapter(com.google.gson.TypeAdapter) JsonReader(com.google.gson.stream.JsonReader) ArrayList(java.util.ArrayList) SnakeCase(org.ehrbase.serialisation.util.SnakeCase) FlatPath(org.ehrbase.webtemplate.parser.FlatPath) List(java.util.List) I_DvTypeAdapter(org.ehrbase.serialisation.dbencoding.wrappers.json.I_DvTypeAdapter) Map(java.util.Map) Locatable(com.nedap.archie.rm.archetyped.Locatable) LinkedTreeMap(com.google.gson.internal.LinkedTreeMap) JsonWriter(com.google.gson.stream.JsonWriter) DvMultimedia(com.nedap.archie.rm.datavalues.encapsulated.DvMultimedia) SnakeCase(org.ehrbase.serialisation.util.SnakeCase) ArrayList(java.util.ArrayList) FlatPath(org.ehrbase.webtemplate.parser.FlatPath) LinkedTreeMap(com.google.gson.internal.LinkedTreeMap) DvMultimedia(com.nedap.archie.rm.datavalues.encapsulated.DvMultimedia) Map(java.util.Map) LinkedTreeMap(com.google.gson.internal.LinkedTreeMap)

Example 5 with FlatPath

use of org.ehrbase.webtemplate.parser.FlatPath in project openEHR_SDK by ehrbase.

the class DefaultNamingStrategy method isEntityAttribute.

private boolean isEntityAttribute(ClassGeneratorContext context, WebTemplateNode node) {
    FlatPath relativPath = new FlatPath(context.nodeDeque.peek().buildRelativePath(node));
    RMTypeInfo typeInfo = RM_INFO_LOOKUP.getTypeInfo(context.nodeDeque.peek().getRmType());
    return relativPath.getChild() == null && typeInfo != null && typeInfo.getAttributes().containsKey(relativPath.getName());
}
Also used : RMTypeInfo(com.nedap.archie.rminfo.RMTypeInfo) FlatPath(org.ehrbase.webtemplate.parser.FlatPath)

Aggregations

FlatPath (org.ehrbase.webtemplate.parser.FlatPath)12 Locatable (com.nedap.archie.rm.archetyped.Locatable)5 StringUtils (org.apache.commons.lang3.StringUtils)5 SnakeCase (org.ehrbase.serialisation.util.SnakeCase)5 List (java.util.List)4 Map (java.util.Map)4 ArchieRMInfoLookup (com.nedap.archie.rminfo.ArchieRMInfoLookup)3 ArrayList (java.util.ArrayList)3 Collectors (java.util.stream.Collectors)3 WebTemplateNode (org.ehrbase.webtemplate.model.WebTemplateNode)3 LinkedTreeMap (com.google.gson.internal.LinkedTreeMap)2 RMTypeInfo (com.nedap.archie.rminfo.RMTypeInfo)2 AnnotationSpec (com.squareup.javapoet.AnnotationSpec)2 ClassName (com.squareup.javapoet.ClassName)2 FieldSpec (com.squareup.javapoet.FieldSpec)2 MethodSpec (com.squareup.javapoet.MethodSpec)2 ParameterizedTypeName (com.squareup.javapoet.ParameterizedTypeName)2 TypeName (com.squareup.javapoet.TypeName)2 TypeSpec (com.squareup.javapoet.TypeSpec)2 Arrays (java.util.Arrays)2