public NavigatorPosition(ISourceNode current, IElementDefinitionSummary info, string name, string instanceType) { SerializationInfo = info; Node = current ?? throw Error.ArgumentNull(nameof(current)); InstanceType = instanceType; Name = name ?? throw Error.ArgumentNull(nameof(name)); }
private static string determineInstanceType(object instance, IElementDefinitionSummary summary) { var typeName = !summary.IsChoiceElement && !summary.IsResource ? summary.Type.Single().GetTypeName() : ((Base)instance).TypeName; return(ModelInfo.IsProfiledQuantity(typeName) ? "Quantity" : typeName); }
internal ElementNode(string name, object value, string instanceType, IElementDefinitionSummary definition) { Name = name ?? throw new ArgumentNullException(nameof(name)); InstanceType = instanceType; Value = value; Definition = definition; }
private TypedElementOnSourceNode(TypedElementOnSourceNode parent, ISourceNode source, IElementDefinitionSummary definition, string instanceType, string prettyPath) { _source = source; ShortPath = prettyPath; Provider = parent.Provider; ExceptionHandler = parent.ExceptionHandler; Definition = definition; InstanceType = instanceType; _settings = parent._settings; }
private PocoElementNode(Base instance, PocoElementNode parent, IElementDefinitionSummary definition, string location, string shortPath) { Current = instance; _mySD = new Lazy <PocoComplexTypeSerializationInfo>(() => (PocoComplexTypeSerializationInfo)PocoStructureDefinitionSummaryProvider.Provide(Current.GetType())); InstanceType = determineInstanceType(Current, definition); Definition = definition ?? throw Error.ArgumentNull(nameof(definition)); ExceptionHandler = parent.ExceptionHandler; Location = location; ShortPath = shortPath; }
private PocoElementNode(object instance, PocoElementNode parent, string location, string shortPath, int arrayIndex, IElementDefinitionSummary summary) { Current = instance; InstanceType = determineInstanceType(instance, summary); Provider = parent.Provider; ExceptionHandler = parent.ExceptionHandler; Definition = summary; Location = location; ShortPath = shortPath; ArrayIndex = arrayIndex; Provider = parent.Provider; }
public ElementDefinitionSummary(IElementDefinitionSummary source) { ElementName = source.ElementName; IsCollection = source.IsCollection; IsChoiceElement = source.IsChoiceElement; IsResource = source.IsResource; Representation = source.Representation; Type = source.Type; Order = source.Order; NonDefaultNamespace = source.NonDefaultNamespace; InSummary = source.InSummary; IsRequired = source.IsRequired; }
private string deriveInstanceType(ISourceNode current, IElementDefinitionSummary info) { string instanceType = null; var resourceTypeIndicator = current.GetResourceTypeIndicator(); if (info.IsResource) { instanceType = resourceTypeIndicator; if (instanceType == null) { raiseTypeError($"Element '{current.Name}' should contain a resource, but does not actually contain one", current, location: current.Location); } } else if (!info.IsResource && resourceTypeIndicator != null) { raiseTypeError($"Element '{current.Name}' is not a contained resource, but seems to contain a resource of type '{resourceTypeIndicator}'.", current, location: current.Location); instanceType = resourceTypeIndicator; } else if (info.IsChoiceElement) { var suffix = current.Name.Substring(info.ElementName.Length); if (string.IsNullOrEmpty(suffix)) { raiseTypeError($"Choice element '{current.Name}' is not suffixed with a type.", current, location: current.Location); instanceType = null; } else { instanceType = info.Type .OfType <IStructureDefinitionReference>() .Select(t => t.ReferredType) .FirstOrDefault(t => string.Compare(t, suffix, StringComparison.OrdinalIgnoreCase) == 0); if (string.IsNullOrEmpty(instanceType)) { raiseTypeError($"Choice element '{current.Name}' is suffixed with unexpected type '{suffix}'", current, location: current.Location); } } } else { var tp = info.Type.Single(); instanceType = tp.GetTypeName(); } return(instanceType); }
private static void compareJson(string filename, Func <string, object> navCreator, string expected) { var nav = navCreator(expected); var outputBuilder = new StringBuilder(); IElementDefinitionSummary serInfo = null; switch (nav) { case ISourceNode isn: serInfo = null; break; case ITypedElement ien: serInfo = ien.Definition; break; default: throw Error.InvalidOperation("Fix unit test"); } var serializer = new FhirJsonBuilder(new FhirJsonSerializationSettings { }); string output = null; if (nav is ISourceNode isn2) { output = isn2.ToJson(); } else if (nav is ITypedElement ien2) { output = ien2.ToJson(); } else { throw Error.InvalidOperation("Fix unit test"); } List <string> errors = new List <string>(); JsonAssert.AreSame(filename, expected, output, errors); Console.WriteLine(String.Join("\r\n", errors)); Assert.AreEqual(0, errors.Count, "Errors were encountered comparing converted content"); }
public static void RoundtripXml(Func <string, object> navCreator) { var tp = File.ReadAllText(@"TestData\fp-test-patient.xml"); // will allow whitespace and comments to come through var nav = navCreator(tp); var outputBuilder = new StringBuilder(); IElementDefinitionSummary serInfo = null; switch (nav) { case ISourceNode isn: serInfo = null; break; case ITypedElement ien: serInfo = ien.Definition; break; default: throw Error.InvalidOperation("Fix unit test"); } string output = null; if (nav is ISourceNode isn2) { output = isn2.ToXml(); } else if (nav is ITypedElement ien2) { output = ien2.ToXml(); } else { throw Error.InvalidOperation("Fix unit test"); } XmlAssert.AreSame("fp-test-patient.xml", tp, output); }
private static void compareJson(Func <string, object> navCreator, string expected) { var nav = navCreator(expected); var outputBuilder = new StringBuilder(); IElementDefinitionSummary serInfo = null; switch (nav) { case ISourceNode isn: serInfo = null; break; case ITypedElement ien: serInfo = ien.Definition; break; default: throw Error.InvalidOperation("Fix unit test"); } var serializer = new FhirJsonBuilder(new FhirJsonSerializationSettings { }); string output = null; if (nav is ISourceNode isn2) { output = isn2.ToJson(); } else if (nav is ITypedElement ien2) { output = ien2.ToJson(); } else { throw Error.InvalidOperation("Fix unit test"); } JsonAssert.AreSame(expected, output); }
public static ElementNode Root(IStructureDefinitionSummaryProvider provider, string type, string name = null, object value = null) { if (provider == null) { throw Error.ArgumentNull(nameof(provider)); } if (type == null) { throw Error.ArgumentNull(nameof(type)); } var sd = provider.Provide(type); IElementDefinitionSummary definition = null; // Should we throw if type is not found? if (sd != null) { definition = ElementDefinitionSummary.ForRoot(sd); } return(new ElementNode(name ?? type, value, type, definition)); }
internal bool MustSerializeMember(ITypedElement source, out IElementDefinitionSummary info) { info = source.Definition; if (info == null && !_roundtripMode) { var message = $"Element '{source.Location}' is missing type information."; if (_settings.IgnoreUnknownElements) { ExceptionHandler.NotifyOrThrow(source, ExceptionNotification.Warning( new MissingTypeInformationException(message))); } else { ExceptionHandler.NotifyOrThrow(source, ExceptionNotification.Error( new MissingTypeInformationException(message))); } return(false); } return(true); }
private bool tryGetBySuffixedName(Dictionary <string, IElementDefinitionSummary> dis, string name, out IElementDefinitionSummary info) { // Simplest case, one on one match between name and element name if (dis.TryGetValue(name, out info)) { return(true); } // Now, check the choice elements for a match // (this should actually be the longest match, but that's kind of expensive, // so as long as we don't add stupid ambiguous choices to a single type, this will work. info = dis.Where(kvp => name.StartsWith(kvp.Key) && kvp.Value.IsChoiceElement) .Select(kvp => kvp.Value).FirstOrDefault(); return(info != null); }
private string deriveInstanceType(ISourceNode current, IElementDefinitionSummary info) { string instanceType = null; var resourceTypeIndicator = current.GetResourceTypeIndicator(); if (info.IsResource) { instanceType = resourceTypeIndicator; if (instanceType == null) { raiseTypeError($"Element '{current.Name}' should contain a resource, but does not actually contain one", current, location: current.Location); } } else if (!info.IsResource && resourceTypeIndicator != null) { raiseTypeError($"Element '{current.Name}' is not a contained resource, but seems to contain a resource of type '{resourceTypeIndicator}'.", current, location: current.Location); instanceType = resourceTypeIndicator; } else if (info.IsChoiceElement) { var suffix = current.Name.Substring(info.ElementName.Length); if (string.IsNullOrEmpty(suffix)) { raiseTypeError($"Choice element '{current.Name}' is not suffixed with a type.", current, location: current.Location); instanceType = null; } else { instanceType = info.Type .OfType <IStructureDefinitionReference>() .Select(t => t.ReferredType) .FirstOrDefault(t => string.Compare(t, suffix, System.StringComparison.OrdinalIgnoreCase) == 0); if (string.IsNullOrEmpty(instanceType)) { raiseTypeError($"Choice element '{current.Name}' is suffixed with unexpected type '{suffix}'", current, location: current.Location); } } } else if (info.Representation == XmlRepresentation.TypeAttr) // May be used by models other then FHIR, e.g. CCDA represented by a StructureDefinition { if (info.Type.Count() == 1) { instanceType = info.Type.Single().GetTypeName(); } else { var typeName = current.Children("type").FirstOrDefault()?.Text; if (typeName != null) { instanceType = info.Type.Where(type => typeFromLogicalModelCanonical(type).Equals(typeName)).FirstOrDefault()?.GetTypeName(); } else { instanceType = info.DefaultTypeName; } } } else { var tp = info.Type.Single(); instanceType = tp.GetTypeName(); } return(instanceType); }
private string deriveInstanceType(ISourceNode current, IElementDefinitionSummary info) { var resourceTypeIndicator = current.GetResourceTypeIndicator(); // First, handle the case where this (appears to be) a resource. if (info.IsResource) { if (resourceTypeIndicator == null) { raiseTypeError($"Element '{current.Name}' should contain a resource, but does not actually contain one", current, location: current.Location); } return(resourceTypeIndicator); } else if (resourceTypeIndicator != null) { raiseTypeError($"Element '{current.Name}' is not a contained resource, but seems to contain a resource of type '{resourceTypeIndicator}'.", current, location: current.Location); return(resourceTypeIndicator); } // Now, it's a data element. But is a choice, so we need to take // a look at the suffix on the element's name to figure out what we // are dealing with. if (info.IsChoiceElement) { var suffix = current.Name.Substring(info.ElementName.Length); if (string.IsNullOrEmpty(suffix)) { raiseTypeError($"Choice element '{current.Name}' is not suffixed with a type.", current, location: current.Location); return(null); } suffix = normalizeSuffix(suffix); // If any of the types is the abstract 'DataType' type, we'll just // accept whatever type is mentioned, we have no real list to go on => // An example of where this happens is Extension.value[x], which is // a POCO that is common to all (FHIR) datamodels, and since value[x] is an // "open" types, we have no idea which types are allowed. if (info.Type.Any(t => t.GetTypeName() == "DataType")) { return(suffix); } else { var isListed = info.Type .OfType <IStructureDefinitionReference>() .Select(t => t.ReferredType) .Any(t => t == suffix); if (!isListed) { raiseTypeError($"Choice element '{current.Name}' is suffixed with unexpected type '{suffix}'", current, location: current.Location); } return(suffix); } string normalizeSuffix(string s) { // Unfortunately, we decided to nicely capitalize the suffix, even for // primitives - luckily then, there's just a single list of primitives, // so we can "correct" them return(_suffixMap.TryGetValue(s, out var corrected) ? corrected : s); }; } else if (info.Representation == XmlRepresentation.TypeAttr) // May be used by models other then FHIR, e.g. CCDA represented by a StructureDefinition { if (info.Type.Count() == 1) { return(info.Type.Single().GetTypeName()); } else { var typeName = current.Children("type").FirstOrDefault()?.Text; return(typeName != null ? info.Type.Where(type => typeFromLogicalModelCanonical(type).Equals(typeName)).FirstOrDefault()?.GetTypeName() : info.DefaultTypeName); } } var tp = info.Type.Single(); return(tp.GetTypeName()); }