internal object Deserialize(Type nativeType)
        {
            if (nativeType == null)
            {
                throw Error.ArgumentNull(nameof(nativeType));
            }

            object primitiveValue = _current.Value;

            if (nativeType.IsEnum())
            {
                return(primitiveValue);
            }

            try
            {
                // The POCO's know nothing about the special partial date/time classes used by ITypedElement,
                // instead FhirDateTime, Time and FhirDate all represent these values as simple strings.
                if (primitiveValue is P.DateTime || primitiveValue is P.Time || primitiveValue is P.Date)
                {
                    return(PrimitiveTypeConverter.ConvertTo(primitiveValue.ToString(), nativeType));
                }
                else
                {
                    return(PrimitiveTypeConverter.ConvertTo(primitiveValue, nativeType));
                }
            }
            catch (NotSupportedException exc)
            {
                // thrown when an unsupported conversion was required
                ComplexTypeReader.RaiseFormatError("Not supported - " + exc.Message, _current.Location);
                throw;  // just to satisfy the compiler - RaiseFormatError throws.
            }
        }
        internal object Deserialize(Type nativeType)
        {
            if (nativeType == null)
            {
                throw Error.ArgumentNull(nameof(nativeType));
            }

            object primitiveValue = _current.Value;

            if (nativeType.IsEnum())
            {
                return(primitiveValue);
            }

            try
            {
                if (primitiveValue is PartialDateTime || primitiveValue is PartialTime)
                {
                    return(PrimitiveTypeConverter.ConvertTo(primitiveValue.ToString(), nativeType));
                }
                else
                {
                    return(PrimitiveTypeConverter.ConvertTo(primitiveValue, nativeType));
                }
            }
            catch (NotSupportedException exc)
            {
                // thrown when an unsupported conversion was required
                ComplexTypeReader.RaiseFormatError("Not supported - " + exc.Message, _current.Location);
                throw;  // just to satisfy the compiler - RaiseFormatError throws.
            }
        }
Beispiel #3
0
#pragma warning restore 612,618

        public object Deserialize(PropertyMapping prop, string memberName, object existing = null)
        {
            if (prop == null)
            {
                throw Error.ArgumentNull(nameof(prop));
            }

            // ArrayMode avoid the dispatcher making nested calls into the RepeatingElementReader again
            // when reading array elements. FHIR does not support nested arrays, and this avoids an endlessly
            // nesting series of dispatcher calls
            if (!_arrayMode && prop.IsCollection)
            {
                if (existing != null && !(existing is IList))
                {
                    throw Error.Argument(nameof(existing), "Can only read repeating elements into a type implementing IList");
                }
                var reader = new RepeatingElementReader(_inspector, _current, Settings);
                return(reader.Deserialize(prop, memberName, (IList)existing));
            }

            // If this is a primitive type, no classmappings and reflection is involved,
            // just parse the primitive from the input
            // NB: no choices for primitives!
            if (prop.IsPrimitive)
            {
                var reader = new PrimitiveValueReader(_current);
                return(reader.Deserialize(prop.ImplementingType));
            }

            // A Choice property that contains a choice of any resource
            // (as used in Resource.contained)
            if (prop.Choice == ChoiceType.ResourceChoice)
            {
                var reader = new ComplexTypeReader(_inspector, _current, Settings);
                return(reader.Deserialize(null));
            }

            if (_current.InstanceType is null)
            {
                ComplexTypeReader.RaiseFormatError(
                    "Underlying data source was not able to provide the actual instance type of the resource.", _current.Location);
            }

            ClassMapping mapping = prop.Choice == ChoiceType.DatatypeChoice
                ? getMappingForType(memberName, _current.InstanceType)
                : _inspector.ImportType(prop.ImplementingType);

            // Handle other Choices having any datatype or a list of datatypes

            if (existing != null && !(existing is Resource) && !(existing is Element))
            {
                throw Error.Argument(nameof(existing), "Can only read complex elements into types that are Element or Resource");
            }
            var cplxReader = new ComplexTypeReader(_inspector, _current, Settings);

            return(cplxReader.Deserialize(mapping, (Base)existing));
        }
        public object Deserialize(PropertyMapping prop, string memberName, object existing = null)
        {
            if (prop == null)
            {
                throw Error.ArgumentNull("prop");
            }

            // ArrayMode avoid the dispatcher making nested calls into the RepeatingElementReader again
            // when reading array elements. FHIR does not support nested arrays, and this avoids an endlessly
            // nesting series of dispatcher calls
            if (!_arrayMode && prop.IsCollection)
            {
                var reader = new RepeatingElementReader(_current);
                return(reader.Deserialize(prop, memberName, existing));
            }

            // If this is a primitive type, no classmappings and reflection is involved,
            // just parse the primitive from the input
            // NB: no choices for primitives!
            if (prop.IsPrimitive)
            {
                var reader = new PrimitiveValueReader(_current);
                return(reader.Deserialize(prop.ElementType));
            }

            // A Choice property that contains a choice of any resource
            // (as used in Resource.contained)
            if (prop.Choice == ChoiceType.ResourceChoice)
            {
                var reader = new ResourceReader(_current);
                return(reader.Deserialize(existing, nested: true));
            }

            ClassMapping mapping;

            // Handle other Choices having any datatype or a list of datatypes
            if (prop.Choice == ChoiceType.DatatypeChoice)
            {
                // For Choice properties, determine the actual type of the element using
                // the suffix of the membername (i.e. deceasedBoolean, deceasedDate)
                // This function implements type substitution.
                mapping = determineElementPropertyType(prop, memberName);
            }
            // Else use the actual return type of the property
            else
            {
                mapping = _inspector.ImportType(prop.ElementType);
            }

            var cplxReader = new ComplexTypeReader(_current);

            return(cplxReader.Deserialize(mapping, existing));
        }
        public object Deserialize(PropertyMapping prop, string memberName, object existing=null)
        {
            if (prop == null) throw Error.ArgumentNull("prop");

            // ArrayMode avoid the dispatcher making nested calls into the RepeatingElementReader again
            // when reading array elements. FHIR does not support nested arrays, and this avoids an endlessly
            // nesting series of dispatcher calls
            if (!_arrayMode && prop.IsCollection)
            {
                if (existing != null && !(existing is IList) ) throw Error.Argument("existing", "Can only read repeating elements into a type implementing IList");
                var reader = new RepeatingElementReader(_current);
                return reader.Deserialize(prop, memberName, (IList)existing);
            }

            // If this is a primitive type, no classmappings and reflection is involved,
            // just parse the primitive from the input
            // NB: no choices for primitives!
            if(prop.IsPrimitive)
            {
                var reader = new PrimitiveValueReader(_current);
                return reader.Deserialize(prop.ElementType);
            }

            // A Choice property that contains a choice of any resource
            // (as used in Resource.contained)
            if(prop.Choice == ChoiceType.ResourceChoice)
            {
                var reader = new ResourceReader(_current);
                return reader.Deserialize(null);
            }

            ClassMapping mapping;

            // Handle other Choices having any datatype or a list of datatypes
            if(prop.Choice == ChoiceType.DatatypeChoice)
            {
                // For Choice properties, determine the actual type of the element using
                // the suffix of the membername (i.e. deceasedBoolean, deceasedDate)
                // This function implements type substitution.
                mapping = determineElementPropertyType(prop, memberName);
            }   
            // Else use the actual return type of the property
            else
            {
                mapping = _inspector.ImportType(prop.ElementType);
            }

            if (existing != null && !(existing is Resource) && !(existing is Element) ) throw Error.Argument("existing", "Can only read complex elements into types that are Element or Resource");
            var cplxReader = new ComplexTypeReader(_current);
            return cplxReader.Deserialize(mapping, (Base)existing);
        }
Beispiel #6
0
        private ClassMapping getMappingForType(string memberName, string typeName)
        {
            // NB: this will return the latest type registered for that name, so supports type mapping/overriding
            // Maybe we should Import the types present on the choice, to make sure they are available. For now
            // assume the caller has Imported all types in the right (overriding) order.
            ClassMapping result = _inspector.FindClassMapping(typeName);

            if (result == null)
            {
                ComplexTypeReader.RaiseFormatError(
                    $"Encountered polymorph member {memberName}, which uses unknown datatype {typeName}", _current.Location);
            }

            return(result);
        }
Beispiel #7
0
        public Resource Deserialize(Resource existing=null)
        {
            // If there's no a priori knowledge of the type of Resource we will encounter,
            // we'll have to determine from the data itself. 
            var resourceTypeName = _reader.GetResourceTypeName();
            var mapping = _inspector.FindClassMappingForResource(resourceTypeName);

            if (mapping == null)
                throw Error.Format("Asked to deserialize unknown resource '" + resourceTypeName + "'", _reader);
             
            // Delegate the actual work to the ComplexTypeReader, since
            // the serialization of Resources and ComplexTypes are virtually the same
            var cplxReader = new ComplexTypeReader(_reader);
            return (Resource)cplxReader.Deserialize(mapping, existing);
        }
        public object Deserialize(object existing = null, bool nested = false)
        {
            if (_reader.CurrentToken == TokenType.Object)
            {
                // If there's no a priori knowledge of the type of Resource we will encounter,
                // we'll have to determine from the data itself.
                var resourceType = _reader.GetResourceTypeName(nested);
                var mappedType   = _inspector.FindClassMappingForResource(resourceType);

                if (mappedType == null)
                {
                    // Special courtesy case
                    if (resourceType == "feed" || resourceType == "Bundle")
                    {
                        throw Error.Format("Encountered a feed instead of a resource", _reader);
                    }
                    else
                    {
                        throw Error.Format("Encountered unknown resource type {0}", _reader, resourceType);
                    }
                }

                if (existing == null)
                {
                    var fac = new DefaultModelFactory();
                    existing = fac.Create(mappedType.NativeType);
                }
                else
                {
                    if (mappedType.NativeType != existing.GetType())
                    {
                        throw Error.Argument("existing", "Existing instance is of type {0}, but data indicates resource is a {1}", existing.GetType().Name, resourceType);
                    }
                }

                // Delegate the actual work to the ComplexTypeReader, since
                // the serialization of Resources and ComplexTypes are virtually the same
                var cplxReader = new ComplexTypeReader(_reader);
                return(cplxReader.Deserialize(mappedType, existing));
            }
            else
            {
                throw Error.Format("Trying to read a resource, but reader is not at the start of an object", _reader);
            }
        }
Beispiel #9
0
        public Resource Deserialize(Resource existing = null)
        {
            // If there's no a priori knowledge of the type of Resource we will encounter,
            // we'll have to determine from the data itself.
            var resourceTypeName = _reader.GetResourceTypeName();
            var mapping          = _inspector.FindClassMappingForResource(resourceTypeName);

            if (mapping == null)
            {
                throw Error.Format("Asked to deserialize unknown resource '" + resourceTypeName + "'", _reader);
            }

            // Delegate the actual work to the ComplexTypeReader, since
            // the serialization of Resources and ComplexTypes are virtually the same
            var cplxReader = new ComplexTypeReader(_reader, Settings);

            return((Resource)cplxReader.Deserialize(mapping, existing));
        }
Beispiel #10
0
#pragma warning restore 612,618

        public Resource Deserialize(Resource existing = null)
        {
            if (_reader.InstanceType is null)
            {
                ComplexTypeReader.RaiseFormatError(
                    "Underlying data source was not able to provide the actual instance type of the resource.", _reader.Location);
            }

            var mapping = _inspector.FindClassMappingForResource(_reader.InstanceType);

            if (mapping == null)
            {
                ComplexTypeReader.RaiseFormatError($"Asked to deserialize unknown resource '{_reader.InstanceType}'", _reader.Location);
            }

            // Delegate the actual work to the ComplexTypeReader, since
            // the serialization of Resources and ComplexTypes are virtually the same
            var cplxReader = new ComplexTypeReader(_reader, Settings);

            return((Resource)cplxReader.Deserialize(mapping, existing));
        }
        public object Deserialize(object existing=null, bool nested = false)
        {
            if (_reader.CurrentToken == TokenType.Object)
            {
                // If there's no a priori knowledge of the type of Resource we will encounter,
                // we'll have to determine from the data itself. 
                var resourceType = _reader.GetResourceTypeName(nested);
                var mappedType = _inspector.FindClassMappingForResource(resourceType);

                if (mappedType == null)
                {
                    // Special courtesy case
                    if (resourceType == "feed" || resourceType == "Bundle")
                        throw Error.Format("Encountered a feed instead of a resource", _reader);
                    else
                        throw Error.Format("Encountered unknown resource type {0}", _reader, resourceType);
                }

                if (existing == null)
                {
                    var fac = new DefaultModelFactory();
                    existing = fac.Create(mappedType.NativeType);
                }
                else
                {
                    if (mappedType.NativeType != existing.GetType())
                        throw Error.Argument("existing", "Existing instance is of type {0}, but data indicates resource is a {1}", existing.GetType().Name, resourceType);
                }
               
                // Delegate the actual work to the ComplexTypeReader, since
                // the serialization of Resources and ComplexTypes are virtually the same
                var cplxReader = new ComplexTypeReader(_reader);
                return cplxReader.Deserialize(mappedType, existing);
            }
            else
                throw Error.Format("Trying to read a resource, but reader is not at the start of an object", _reader);
        }