Esempio n. 1
0
        /// <summary>
        /// Create method to set element at indicated path to passed value.
        /// </summary>
        public bool GenerateSetElements(CodeBlockNested block,
                                        ElementDefinitionNode node,
                                        String baseName,
                                        String path,
                                        String leafNodeValue = null)
        {
            const String    fcn = nameof(GenerateSetElements);
            CodeBlockNested childBlock;

            if (block is null)
            {
                throw new ArgumentNullException(nameof(block));
            }
            if (node is null)
            {
                throw new ArgumentNullException(nameof(node));
            }
            if (path is null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            void GenerateSetChildCode(ref string containerName,
                                      Type containerType,
                                      string itemName,
                                      Type itemType,
                                      String value)
            {
                if (containerName is null)
                {
                    throw new ArgumentNullException(nameof(containerName));
                }
                if (itemName is null)
                {
                    throw new ArgumentNullException(nameof(itemName));
                }

                String containerTypeName = containerType.FriendlyName();
                String itemTypeName      = itemType.FriendlyName();

                if (value == null)
                {
                    value = $"new {itemTypeName}()";
                }

                if (containerType.IsList())
                {
                    childBlock
                    .AppendCode($"if ({containerName}.Count == 0)")
                    .AppendCode($"    {containerName}.Add({value});")
                    ;
                    containerName = $"{containerName}[0].{itemName}";
                }
                else
                {
                    childBlock
                    .AppendCode($"if ({containerName}.{itemName} == null)")
                    .AppendCode($"    {containerName}.{itemName} = {value};")
                    ;
                    containerName = $"{containerName}.{itemName}";
                }
            }

            String[] pathItems = path.Split('.');
            Int32    i         = 0;

            if (pathItems[0] == node.Name)
            {
                i += 1;
            }

            childBlock = block.AppendBlock();
            String fullName = baseName;

            while (i < pathItems.Length)
            {
                String pathItem = pathItems[i];
                if (pathItem.StartsWith("resolve("))
                {
                    this.Gen.ConversionError(this.GetType().Name, fcn, $"TODO: FhirPath operator {pathItem} not implemented");
                    return(false);
                }
                else if (pathItem.StartsWith("extension(\""))
                {
                    this.Gen.ConversionError(this.GetType().Name, fcn, $"TODO: FhirPath operator {pathItem} not implemented");
                    return(false);
                }
                else if (pathItem.StartsWith("ofType("))
                {
                    this.Gen.ConversionError(this.GetType().Name, fcn, $"TODO: FhirPath operator {pathItem} not implemented");
                    return(false);
                }
                else
                {
                    if (node.TryGetAnyChild(pathItem, out ElementDefinitionNode next) == false)
                    {
                        this.Gen.ConversionError(this.GetType().Name, fcn, $"Child {pathItem} not found");
                        return(false);
                    }

                    PropertyInfo childProperty = node.FhirItemType.GetPropertyByFhirName(pathItem);
                    String       value         = null;
                    if (i == pathItems.Length - 1)
                    {
                        value = leafNodeValue;
                    }
                    GenerateSetChildCode(ref fullName, node.FhirItemType, childProperty.Name, next.FhirType, value);
                    node = next;
                }
                i += 1;
            }
            return(true);
        }
Esempio n. 2
0
        //$$$ Delete
        /// <summary>
        /// Traverse children using simple fhir path query.
        /// Return selected elements, or null if not found.
        /// </summary>
        public bool Generate(CodeBlockNested block,
                             String methodModifiers,
                             String methodName,
                             ElementDefinitionNode node,
                             String path,
                             out Type leafType)
        {
            const String fcn = nameof(Generate);

            if (block is null)
            {
                throw new ArgumentNullException(nameof(block));
            }
            if (methodModifiers is null)
            {
                throw new ArgumentNullException(nameof(methodModifiers));
            }
            if (methodName is null)
            {
                throw new ArgumentNullException(nameof(methodName));
            }
            if (node is null)
            {
                throw new ArgumentNullException(nameof(node));
            }
            if (path is null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            //String fhirTypeName = node.FhirType.FriendlyName();
            String fhirItemTypeName = node.FhirItemType.FriendlyName();
            // we need to write header after we determine leaf node type.
            CodeBlockNested methodHeaderBlock = block.AppendBlock();

            block
            .OpenBrace()
            .BlankLine()
            ;

            childBlock = block.AppendBlock();

            String[] pathItems = path.Split('.');
            Int32    i         = 0;

            if (pathItems[0] == node.Name)
            {
                i += 1;
            }

            Int32 resultCounter = 0;

            leafType = null;
            String resultThis = "head";

            while (i < pathItems.Length)
            {
                resultCounter += 1;
                String resultNext = $"result{resultCounter}";

                String pathItem = pathItems[i++];
                if (pathItem.StartsWith("resolve("))
                {
                    this.gen.ConversionError(this.GetType().Name, fcn, $"TODO: FhirPath operator {pathItem} not implemented");
                    return(false);
                }
                else if (pathItem.StartsWith("extension(\""))
                {
                    this.gen.ConversionError(this.GetType().Name, fcn, $"TODO: FhirPath operator {pathItem} not implemented");
                    return(false);
                }
                else if (pathItem.StartsWith("ofType("))
                {
                    this.gen.ConversionError(this.GetType().Name, fcn, $"TODO: FhirPath operator {pathItem} not implemented");
                    return(false);
                }
                else
                {
                    if (node.TryGetAnyChild(pathItem, out ElementDefinitionNode next) == false)
                    {
                        this.gen.ConversionError(this.GetType().Name, fcn, $"Child {pathItem} not found");
                        return(false);
                    }

                    Type         nodeType          = node.FhirItemType;
                    PropertyInfo childProperty     = nodeType.GetPropertyByFhirName(pathItem);
                    String       childPropertyName = childProperty.Name;
                    String       childMethodName   = GenerateGetChild(childPropertyName, nodeType, childProperty.PropertyType);

                    block.AppendCode($"IEnumerable<{next.FhirItemType.FriendlyName()}> {resultNext} = {childMethodName}({resultThis});");
                    resultThis = resultNext;
                    node       = next;
                }
            }

            block
            .AppendCode($"return {resultThis};")
            .CloseBrace()
            ;

            leafType = node.FhirItemType;

            methodHeaderBlock
            .AppendCode($"{methodModifiers} IEnumerable<{leafType.FriendlyName()}> {methodName}(IEnumerable<{fhirItemTypeName}> head)")
            ;
            return(true);
        }