/// <summary> /// Checks whether the resource referenced by <paramref name="reference"/> is type of <paramref name="resourceType"/>. /// </summary> /// <param name="reference">The reference to check.</param> /// <param name="resourceType">The resource type to match.</param> /// <returns><c>true</c> if the resource referenced by <paramref name="reference"/> is type of <paramref name="resourceType"/>; <c>false</c> otherwise.</returns> public static bool IsReferenceTypeOf(this ResourceReference reference, FHIRAllTypes resourceType) { EnsureArg.IsNotNull(reference, nameof(reference)); // TODO: This does not work with external reference. return(reference?.Reference?.StartsWith(ModelInfo.FhirTypeToFhirTypeName(resourceType), StringComparison.Ordinal) ?? false); }
void ConstructDataType(CodeBlockNested methods, CodeBlockNested construct, FHIRAllTypes fhirType) { if (GenerateCommon.Ignore(fhirType)) { return; } this.tempCounter = 0; String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType); Type csType = ModelInfo.GetTypeForFhirType(fhirTypeName); String csTypeName = csType.FriendlyName(); construct .AppendCode($"case \"{fhirTypeName}\": // {fhirType} - DataType") .OpenBrace() .AppendCode($"propertyType = \"{fhirTypeName}\";") .AppendCode($"return Construct(block, ({csTypeName})fix, varName);") .CloseBrace() .BlankLine() ; CodeBlockNested m = methods.AppendBlock(); m .BlankLine() .AppendLine($"/// <summary>") .AppendLine($"/// Return c# text to create indicated element.") .AppendLine($"/// </summary>") .AppendCode($"static public bool Construct(CodeBlockNested block,") .AppendCode($" {csTypeName} fix,") .AppendCode($" String varName)") .OpenBrace() //.AppendCode($"const String fcn = \"Construct({fhirTypeName})\";") .BlankLine() .AppendCode($"if (block is null)") .AppendCode($" throw new ArgumentNullException(nameof(block));") .AppendCode($"block") .AppendCode($" .OpenBrace()") .AppendCode($" .AppendCode(\"{csTypeName} temp = new {csTypeName}();\")") .AppendCode($" ;") .AppendCode($"if (fix != null)") .OpenBrace() ; FixElements(m, csType, "fix", "temp"); m .CloseBrace() .AppendCode($"block") .AppendCode($" .AppendCode($\"{{varName}} = temp;\")") .AppendCode($" .CloseBrace()") .AppendCode($" ;") .AppendCode($"return true;") .CloseBrace() ; }
void ConstructDataType(CodeBlockNested methods, CodeBlockNested construct, FHIRAllTypes fhirType) { if (Ignore(fhirType)) { return; } String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType); Type csType = ModelInfo.GetTypeForFhirType(fhirTypeName); String csTypeName = csType.FriendlyName(); construct .AppendCode($"case \"{fhirTypeName}\": // {fhirType} - DataType") .OpenBrace() .AppendCode($"propertyType = \"{fhirTypeName}\";") .AppendCode($"return Construct(block, ({csTypeName})fix, methodName, methodAccess);") .CloseBrace() .BlankLine() ; CodeBlockNested m = methods.AppendBlock(); m .BlankLine() .AppendLine($"/// <summary>") .AppendLine($"/// Return c# text to create indicated element.") .AppendLine($"/// </summary>") .AppendCode($"static public bool Construct(CodeBlockNested block,") .AppendCode($" {csTypeName} fix,") .AppendCode($" String methodName,") .AppendCode($" String methodAccess = \"public\")") .OpenBrace() //.AppendCode($"const String fcn = \"Construct({fhirTypeName})\";") .BlankLine() .AppendCode($"block") .AppendCode($" .AppendCode($\"{{methodAccess}} {csTypeName} {{methodName}}()\")") .AppendCode($" .OpenBrace()") .AppendCode($" .AppendCode(\"{csTypeName} retVal = new {csTypeName}();\")") .AppendCode($" ;") .AppendCode($"if (fix != null)") .OpenBrace() ; FixElements(m, csType, "fix", "retVal"); m .CloseBrace() .AppendCode($"block") .AppendCode($" .AppendCode(\"return retVal;\")") .AppendCode($" .CloseBrace()") .AppendCode($" ;") .AppendCode($"return true;") .CloseBrace() ; }
public PyroSearchParameters GetSearchParameters(string Compartment, string CompartmentId, string ResourceName) { //I need to check that Compartment and ResourceName are actual FHIR Resource Types, the two lines //below do that and throw Pyro Exception if they are not. FHIRAllTypes CompartmentType = ResourceNameResolutionSupport.GetResourceFhirAllType(Compartment); FHIRAllTypes ResourceNameType = ResourceNameResolutionSupport.GetResourceFhirAllType(ResourceName); //Now to contruct the Container search parameters, these are cached from the database Conatiner Resource DtoServiceCompartmentResourceCached ServiceCompartmentResource = IServiceCompartmentCache.GetServiceCompartmentResourceForCompartmentCodeAndResource(Compartment, ResourceName); string ConatinerSerachString = string.Empty; if (ServiceCompartmentResource != null) { var CompartmentParamQuery = new List <string>(); foreach (var CompartmentSearchParameter in ServiceCompartmentResource.ParamList) { if (CompartmentSearchParameter.Param == "*") { // if the param="*" then all instances of this Resource Type are in the container and there are no // actualy parameters that it needs to be restricted by. So the ConatinerSerachString remains as empty string. break; } else { CompartmentParamQuery.Add($"{CompartmentSearchParameter.Param}:{Compartment}={CompartmentId}"); } } ConatinerSerachString = String.Join("&", CompartmentParamQuery.ToArray()); } else { DtoServiceCompartmentCached ServiceCompartment = IServiceCompartmentCache.GetServiceCompartmentForCompartmentCode(Compartment); if (ServiceCompartment == null) { string Message = $"No active {Compartment} Compartment exist in this server. Perhaps you could create one using a {FHIRAllTypes.CompartmentDefinition.GetLiteral()} resource and the resource instance ${Pyro.Common.Enum.FhirOperationEnum.OperationType.xSetCompartmentActive} Operation. " + $"For example: '[base]/{FHIRAllTypes.CompartmentDefinition.GetLiteral()}/[id]/${Pyro.Common.Enum.FhirOperationEnum.OperationType.xSetCompartmentActive}' "; var OpOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, Message); throw new PyroException(System.Net.HttpStatusCode.BadRequest, OpOutcome, Message); } else { string Message = $"The {Compartment} Compartment defined by the {FHIRAllTypes.CompartmentDefinition.GetLiteral()} with the resource id of '{ServiceCompartment.CompartmentDefinitionResourceId}' does not allow access to any {ResourceName} resource type instances."; var OpOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, Message); throw new PyroException(System.Net.HttpStatusCode.BadRequest, OpOutcome, Message); } } ISearchParameterGeneric ContainerSearchParameterGeneric = ISearchParameterGenericFactory.CreateDtoSearchParameterGeneric().Parse(ConatinerSerachString); ISearchParameterService SearchService = ISearchParameterServiceFactory.CreateSearchParameterService(); ISearchParametersServiceOutcome ContainerSearchParametersServiceOutcome = SearchService.ProcessSearchParameters(ContainerSearchParameterGeneric, SearchParameterService.SearchParameterServiceType.Resource, ResourceNameType, null); return(ContainerSearchParametersServiceOutcome.SearchParameters); }
public static bool Ignore(FHIRAllTypes fhirType) { switch (fhirType) { case FHIRAllTypes.Resource: case FHIRAllTypes.DomainResource: case FHIRAllTypes.BackboneElement: case FHIRAllTypes.Element: return(true); default: return(false); } }
public IResourceRepository Create <ResCurrentType, ResIndexStringType, ResIndexTokenType, ResIndexUriType, ResIndexReferenceType, ResIndexQuantityType, ResIndexDateTimeType>(FHIRAllTypes FHIRAllTypes) { var CommonResourceRepository = (ICommonResourceRepository <ResCurrentType, ResIndexStringType, ResIndexTokenType, ResIndexUriType, ResIndexReferenceType, ResIndexQuantityType, ResIndexDateTimeType>)Container.GetInstance(typeof(ICommonResourceRepository <ResCurrentType, ResIndexStringType, ResIndexTokenType, ResIndexUriType, ResIndexReferenceType, ResIndexQuantityType, ResIndexDateTimeType>)); CommonResourceRepository.RepositoryResourceType = FHIRAllTypes; return(CommonResourceRepository); }
public static DtoResource SetDtoResource <ResourceBaseType>(ResourceBaseType ResourceBase, FHIRAllTypes ResourceType) where ResourceBaseType : ResourceBase { var DtoResource = new DtoResource(); DtoResource.FhirId = ResourceBase.FhirId; DtoResource.FhirReleaseId = ResourceBase.FhirReleaseId; DtoResource.IsCurrent = ResourceBase.IsCurrent; DtoResource.IsDeleted = ResourceBase.IsDeleted; DtoResource.Received = ResourceBase.LastUpdated; DtoResource.Version = ResourceBase.VersionId; DtoResource.Resource = ResourceBase.Resource; DtoResource.Method = ResourceBase.Method; DtoResource.ResourceType = ResourceType; return(DtoResource); }
void GenerateCIMPLDataType(CodeBlockNested entryBlock, CodeBlockNested mapBlock, FHIRAllTypes fhirType) { String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType); Type fhirCSType = ModelInfo.GetTypeForFhirType(fhirTypeName); entryBlock .BlankLine() .AppendLine($"// Fhir data element {fhirTypeName} definition") .AppendCode($"Entry: {fhirTypeName}") ; CodeBlockNested item = entryBlock.AppendBlock(); CodeBlockNested vars = entryBlock.AppendBlock(); foreach (PropertyInfo pi in fhirCSType.GetProperties()) { FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>(); if (attribute != null) { String min; String max; Type csType; if (pi.PropertyType.IsList()) { min = "0"; max = "*"; csType = pi.PropertyType.GenericTypeArguments[0]; } if (pi.PropertyType.IsNullable()) { min = "0"; max = "1"; csType = pi.PropertyType.GenericTypeArguments[0]; } else { csType = pi.PropertyType; min = "1"; max = "1"; } String name = attribute.Name.ToMachineName(); item .AppendCode($"Property: {name} {min}..{max}") ; String typeName = null; String csTypeName = csType.FriendlyName(); switch (csTypeName) { case "string": OutputProperty(attribute, item, min, max); break; default: typeName = ModelInfo.GetFhirTypeNameForType(pi.PropertyType); if (String.IsNullOrEmpty(typeName)) { throw new Exception($"Can not determine fhir type for c# type {csTypeName}"); } break; } vars .BlankLine() .AppendCode($"Element: {name}") .AppendCode($"Value: {typeName}") ; // methods // .AppendCode($"case \"{attribute.Name}\":") // .OpenBrace() // .AppendCode($"ElementDefinition e = new ElementDefinition") // .OpenBrace() // .AppendCode($"Path = $\"{{parentPath}}.{attribute.Name}\",") // .AppendCode($"Short = \"{fhirType}.{attribute.Name} common attribute\",") // .AppendCode($"Min = {min},") // .AppendCode($"Max = \"{max}\"") // .CloseBrace(";") // .AppendCode($"retVal = new ElementNode(this, e, typeof({pi.PropertyType.FriendlyName()}), nameof({fhirCSType.FriendlyName()}.{pi.Name}));") // .AppendCode($"retVal.AutoGeneratedFlag = true;") // .AppendCode($"break;") // .CloseBrace(";") // ; } } }
/// <summary> /// Primarily used for Delete actions as their is no Resource given in the API call /// However services can scource the resource being deleted from the database /// </summary> /// <param name="CrudOperationType"></param> /// <param name="ResourceId"></param> /// <param name="ResourceType"></param> public ITriggerOutcome Trigger(RestEnum.CrudOperationType CrudOperationType, TriggerRaisedType TriggerRaised, string ResourceId, FHIRAllTypes ResourceType) { return(ProcessTrigger(CrudOperationType, TriggerRaised, ResourceId, ResourceType)); }
/// <summary> /// FHIR Resource /// </summary> public static ResourceDescription CreateDescription(this FHIRAllTypes me) { return(new ResourceDescription(me.ToString(), $"FHIR Resource {me}")); }
private ITriggerOutcome ProcessTrigger(RestEnum.CrudOperationType CrudOperationType, TriggerRaisedType TriggerRaised, string ResourceId, FHIRAllTypes ResourceType, Resource Resource = null) { switch (ResourceType) { case FHIRAllTypes.CompartmentDefinition: return(ITriggerCompartmentDefinition.ProcessTrigger(CrudOperationType, TriggerRaised, ResourceId, ResourceType, Resource)); default: //Return Contiune if no trigger processing required. return(new TriggerOutcome() { TriggerOutcomeResult = TriggerOutcome.TriggerOutcomeType.Contiune }); } }
public ITriggerOutcome ProcessTrigger(RestEnum.CrudOperationType CrudOperationType, ResourceTriggerService.TriggerRaisedType TriggerRaised, string ResourceId, FHIRAllTypes ResourceType, Resource Resource = null) { if ((CrudOperationType == RestEnum.CrudOperationType.Update || CrudOperationType == RestEnum.CrudOperationType.Delete) && TriggerRaised == ResourceTriggerService.TriggerRaisedType.BeforeCommit) { return(ProcessUpdateOrDelete(CrudOperationType, TriggerRaised, ResourceId, ResourceType, Resource)); } else if (CrudOperationType == RestEnum.CrudOperationType.Create && TriggerRaised == ResourceTriggerService.TriggerRaisedType.BeforeCommit) { RemoveActiveCompartmentTag(Resource); return(new TriggerOutcome() { TriggerOutcomeResult = TriggerOutcome.TriggerOutcomeType.Contiune }); } else { return(new TriggerOutcome() { TriggerOutcomeResult = TriggerOutcome.TriggerOutcomeType.Contiune }); } }
private ITriggerOutcome ProcessUpdateOrDelete(RestEnum.CrudOperationType crudOperationType, ResourceTriggerService.TriggerRaisedType triggerRaised, string resourceId, FHIRAllTypes resourceType, Resource resource) { //Get any Compartment with the same FhirId var ServiceCompartment = IServiceCompartmentRepository.GetServiceCompartmentByFhirId(resourceId); if (ServiceCompartment != null) { string Message = "Error Message Not Set"; if (crudOperationType == RestEnum.CrudOperationType.Update) { //If so do not allow the update Message = $"The {FHIRAllTypes.CompartmentDefinition.GetLiteral()} resource cannot be updated because it is an active Compartment in the server. " + $"You must first set this compartment to Inactive before you can updated this resource. " + $"To do this you will need to call the server Operation ${FhirOperationEnum.OperationType.xSetCompartmentInActive.GetPyroLiteral()} on this resource instance. " + $"For example '[base]/{FHIRAllTypes.CompartmentDefinition.GetLiteral()}/{resourceId}/${FhirOperationEnum.OperationType.xSetCompartmentInActive.GetPyroLiteral()}' " + $"Once Inactive you will then be able to update this resource in the server. " + $"Caution should be taken as active Compartments affect how users interact with the server and the resources they have access to. " + $"To re-activate the Compartment after updating you must call the Operation ${FhirOperationEnum.OperationType.xSetCompartmentActive.GetPyroLiteral()}. " + $"For example '[base]/{FHIRAllTypes.CompartmentDefinition.GetLiteral()}/{resourceId}/${FhirOperationEnum.OperationType.xSetCompartmentActive.GetPyroLiteral()}' "; } else if (crudOperationType == RestEnum.CrudOperationType.Delete) { Message = $"The {FHIRAllTypes.CompartmentDefinition.GetLiteral()} resource cannot be deleted because it is an active Compartment in the server. " + $"You must first set this compartment to Inactive before you can delete this resource. " + $"To do this you will need to call the server Operation ${FhirOperationEnum.OperationType.xSetCompartmentInActive.GetPyroLiteral()} on this resource instance. " + $"For example '[base]/{FHIRAllTypes.CompartmentDefinition.GetLiteral()}/{resourceId}/${FhirOperationEnum.OperationType.xSetCompartmentInActive.GetPyroLiteral()}' " + $"Once Inactive you will then be able to delete this resource from the server. " + $"Caution should be taken as active Compartments affect how users interact with the server and the resources they have access to."; } var ReturnOperationOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.BusinessRule, Message); var TriggerOutcome = new TriggerOutcome(); TriggerOutcome.HttpStatusCode = System.Net.HttpStatusCode.Conflict; TriggerOutcome.TriggerOutcomeResult = TriggerOutcome.TriggerOutcomeType.Report; TriggerOutcome.Resource = ReturnOperationOutcome; return(TriggerOutcome); } else { //the Compartmentdefinition is not active so can be Updated or deleted, if updating then ensure //the active tags are not present and remove if they are RemoveActiveCompartmentTag(resource); } return(new TriggerOutcome() { TriggerOutcomeResult = TriggerOutcome.TriggerOutcomeType.Contiune }); }
public IResourceRepository GetRepository(FHIRAllTypes ResourceType) { switch (ResourceType) { case FHIRAllTypes.Account: return(IUnitOfWork.AccountRepository); case FHIRAllTypes.ActivityDefinition: return(IUnitOfWork.ActivityDefinitionRepository); case FHIRAllTypes.AdverseEvent: return(IUnitOfWork.AdverseEventRepository); case FHIRAllTypes.AllergyIntolerance: return(IUnitOfWork.AllergyIntoleranceRepository); case FHIRAllTypes.Appointment: return(IUnitOfWork.AppointmentRepository); case FHIRAllTypes.AppointmentResponse: return(IUnitOfWork.AppointmentResponseRepository); case FHIRAllTypes.AuditEvent: return(IUnitOfWork.AuditEventRepository); case FHIRAllTypes.Basic: return(IUnitOfWork.BasicRepository); case FHIRAllTypes.Binary: return(IUnitOfWork.BinaryRepository); case FHIRAllTypes.BodySite: return(IUnitOfWork.BodySiteRepository); case FHIRAllTypes.Bundle: return(IUnitOfWork.BundleRepository); case FHIRAllTypes.CapabilityStatement: return(IUnitOfWork.CapabilityStatementRepository); case FHIRAllTypes.CarePlan: return(IUnitOfWork.CarePlanRepository); case FHIRAllTypes.CareTeam: return(IUnitOfWork.CareTeamRepository); case FHIRAllTypes.ChargeItem: return(IUnitOfWork.ChargeItemRepository); case FHIRAllTypes.Claim: return(IUnitOfWork.ClaimRepository); case FHIRAllTypes.ClaimResponse: return(IUnitOfWork.ClaimResponseRepository); case FHIRAllTypes.ClinicalImpression: return(IUnitOfWork.ClinicalImpressionRepository); case FHIRAllTypes.CodeSystem: return(IUnitOfWork.CodeSystemRepository); case FHIRAllTypes.Communication: return(IUnitOfWork.CommunicationRepository); case FHIRAllTypes.CommunicationRequest: return(IUnitOfWork.CommunicationRequestRepository); case FHIRAllTypes.CompartmentDefinition: return(IUnitOfWork.CompartmentDefinitionRepository); case FHIRAllTypes.Composition: return(IUnitOfWork.CompositionRepository); case FHIRAllTypes.ConceptMap: return(IUnitOfWork.ConceptMapRepository); case FHIRAllTypes.Condition: return(IUnitOfWork.ConditionRepository); case FHIRAllTypes.Consent: return(IUnitOfWork.ConsentRepository); case FHIRAllTypes.Contract: return(IUnitOfWork.ContractRepository); case FHIRAllTypes.Coverage: return(IUnitOfWork.CoverageRepository); case FHIRAllTypes.DataElement: return(IUnitOfWork.DataElementRepository); case FHIRAllTypes.DetectedIssue: return(IUnitOfWork.DetectedIssueRepository); case FHIRAllTypes.Device: return(IUnitOfWork.DeviceRepository); case FHIRAllTypes.DeviceComponent: return(IUnitOfWork.DeviceComponentRepository); case FHIRAllTypes.DeviceMetric: return(IUnitOfWork.DeviceMetricRepository); case FHIRAllTypes.DeviceRequest: return(IUnitOfWork.DeviceRequestRepository); case FHIRAllTypes.DeviceUseStatement: return(IUnitOfWork.DeviceUseStatementRepository); case FHIRAllTypes.DiagnosticReport: return(IUnitOfWork.DiagnosticReportRepository); case FHIRAllTypes.DocumentManifest: return(IUnitOfWork.DocumentManifestRepository); case FHIRAllTypes.DocumentReference: return(IUnitOfWork.DocumentReferenceRepository); case FHIRAllTypes.EligibilityRequest: return(IUnitOfWork.EligibilityRequestRepository); case FHIRAllTypes.EligibilityResponse: return(IUnitOfWork.EligibilityResponseRepository); case FHIRAllTypes.Encounter: return(IUnitOfWork.EncounterRepository); case FHIRAllTypes.Endpoint: return(IUnitOfWork.EndpointRepository); case FHIRAllTypes.EnrollmentRequest: return(IUnitOfWork.EnrollmentRequestRepository); case FHIRAllTypes.EnrollmentResponse: return(IUnitOfWork.EnrollmentResponseRepository); case FHIRAllTypes.EpisodeOfCare: return(IUnitOfWork.EpisodeOfCareRepository); case FHIRAllTypes.ExpansionProfile: return(IUnitOfWork.ExpansionProfileRepository); case FHIRAllTypes.ExplanationOfBenefit: return(IUnitOfWork.ExplanationOfBenefitRepository); case FHIRAllTypes.FamilyMemberHistory: return(IUnitOfWork.FamilyMemberHistoryRepository); case FHIRAllTypes.Flag: return(IUnitOfWork.FlagRepository); case FHIRAllTypes.Goal: return(IUnitOfWork.GoalRepository); case FHIRAllTypes.GraphDefinition: return(IUnitOfWork.GraphDefinitionRepository); case FHIRAllTypes.Group: return(IUnitOfWork.GroupRepository); case FHIRAllTypes.GuidanceResponse: return(IUnitOfWork.GuidanceResponseRepository); case FHIRAllTypes.HealthcareService: return(IUnitOfWork.HealthcareServiceRepository); case FHIRAllTypes.ImagingManifest: return(IUnitOfWork.ImagingManifestRepository); case FHIRAllTypes.ImagingStudy: return(IUnitOfWork.ImagingStudyRepository); case FHIRAllTypes.Immunization: return(IUnitOfWork.ImmunizationRepository); case FHIRAllTypes.ImmunizationRecommendation: return(IUnitOfWork.ImmunizationRecommendationRepository); case FHIRAllTypes.ImplementationGuide: return(IUnitOfWork.ImplementationGuideRepository); case FHIRAllTypes.Library: return(IUnitOfWork.LibraryRepository); case FHIRAllTypes.Linkage: return(IUnitOfWork.LinkageRepository); case FHIRAllTypes.List: return(IUnitOfWork.ListRepository); case FHIRAllTypes.Location: return(IUnitOfWork.LocationRepository); case FHIRAllTypes.Measure: return(IUnitOfWork.MeasureRepository); case FHIRAllTypes.MeasureReport: return(IUnitOfWork.MeasureReportRepository); case FHIRAllTypes.Media: return(IUnitOfWork.MediaRepository); case FHIRAllTypes.Medication: return(IUnitOfWork.MedicationRepository); case FHIRAllTypes.MedicationAdministration: return(IUnitOfWork.MedicationAdministrationRepository); case FHIRAllTypes.MedicationDispense: return(IUnitOfWork.MedicationDispenseRepository); case FHIRAllTypes.MedicationRequest: return(IUnitOfWork.MedicationRequestRepository); case FHIRAllTypes.MedicationStatement: return(IUnitOfWork.MedicationStatementRepository); case FHIRAllTypes.MessageDefinition: return(IUnitOfWork.MessageDefinitionRepository); case FHIRAllTypes.MessageHeader: return(IUnitOfWork.MessageHeaderRepository); case FHIRAllTypes.NamingSystem: return(IUnitOfWork.NamingSystemRepository); case FHIRAllTypes.NutritionOrder: return(IUnitOfWork.NutritionOrderRepository); case FHIRAllTypes.Observation: return(IUnitOfWork.ObservationRepository); case FHIRAllTypes.OperationDefinition: return(IUnitOfWork.OperationDefinitionRepository); case FHIRAllTypes.OperationOutcome: return(IUnitOfWork.OperationOutcomeRepository); case FHIRAllTypes.Organization: return(IUnitOfWork.OrganizationRepository); case FHIRAllTypes.Parameters: return(IUnitOfWork.ParametersRepository); case FHIRAllTypes.Patient: return(IUnitOfWork.PatientRepository); case FHIRAllTypes.PaymentNotice: return(IUnitOfWork.PaymentNoticeRepository); case FHIRAllTypes.PaymentReconciliation: return(IUnitOfWork.PaymentReconciliationRepository); case FHIRAllTypes.Person: return(IUnitOfWork.PersonRepository); case FHIRAllTypes.PlanDefinition: return(IUnitOfWork.PlanDefinitionRepository); case FHIRAllTypes.Practitioner: return(IUnitOfWork.PractitionerRepository); case FHIRAllTypes.PractitionerRole: return(IUnitOfWork.PractitionerRoleRepository); case FHIRAllTypes.Procedure: return(IUnitOfWork.ProcedureRepository); case FHIRAllTypes.ProcedureRequest: return(IUnitOfWork.ProcedureRequestRepository); case FHIRAllTypes.ProcessRequest: return(IUnitOfWork.ProcessRequestRepository); case FHIRAllTypes.ProcessResponse: return(IUnitOfWork.ProcessResponseRepository); case FHIRAllTypes.Provenance: return(IUnitOfWork.ProvenanceRepository); case FHIRAllTypes.Questionnaire: return(IUnitOfWork.QuestionnaireRepository); case FHIRAllTypes.QuestionnaireResponse: return(IUnitOfWork.QuestionnaireResponseRepository); case FHIRAllTypes.ReferralRequest: return(IUnitOfWork.ReferralRequestRepository); case FHIRAllTypes.RelatedPerson: return(IUnitOfWork.RelatedPersonRepository); case FHIRAllTypes.RequestGroup: return(IUnitOfWork.RequestGroupRepository); case FHIRAllTypes.ResearchStudy: return(IUnitOfWork.ResearchStudyRepository); case FHIRAllTypes.ResearchSubject: return(IUnitOfWork.ResearchSubjectRepository); case FHIRAllTypes.RiskAssessment: return(IUnitOfWork.RiskAssessmentRepository); case FHIRAllTypes.Schedule: return(IUnitOfWork.ScheduleRepository); case FHIRAllTypes.SearchParameter: return(IUnitOfWork.SearchParameterRepository); case FHIRAllTypes.Sequence: return(IUnitOfWork.SequenceRepository); case FHIRAllTypes.ServiceDefinition: return(IUnitOfWork.ServiceDefinitionRepository); case FHIRAllTypes.Slot: return(IUnitOfWork.SlotRepository); case FHIRAllTypes.Specimen: return(IUnitOfWork.SpecimenRepository); case FHIRAllTypes.StructureDefinition: return(IUnitOfWork.StructureDefinitionRepository); case FHIRAllTypes.StructureMap: return(IUnitOfWork.StructureMapRepository); case FHIRAllTypes.Subscription: return(IUnitOfWork.SubscriptionRepository); case FHIRAllTypes.Substance: return(IUnitOfWork.SubstanceRepository); case FHIRAllTypes.SupplyDelivery: return(IUnitOfWork.SupplyDeliveryRepository); case FHIRAllTypes.SupplyRequest: return(IUnitOfWork.SupplyRequestRepository); case FHIRAllTypes.Task: return(IUnitOfWork.TaskRepository); case FHIRAllTypes.TestReport: return(IUnitOfWork.TestReportRepository); case FHIRAllTypes.TestScript: return(IUnitOfWork.TestScriptRepository); case FHIRAllTypes.ValueSet: return(IUnitOfWork.ValueSetRepository); case FHIRAllTypes.VisionPrescription: return(IUnitOfWork.VisionPrescriptionRepository); default: { string Message = $"The Resource name given: '{ResourceType.GetLiteral()}' has no matching server repository. "; var OpOutCome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.Invalid, Message); throw new PyroException(HttpStatusCode.BadRequest, OpOutCome, Message); } } }
private void ChainSearchProcessing(Tuple <string, string> Parameter) { _DtoSupportedSearchParametersList = GetSupportedSearchParameters(_SearchParameterServiceType, _OperationClass, _ResourceType); ISearchParameterBase ParentChainSearchParameter = null; ISearchParameterBase PreviousChainSearchParameter = null; string[] ChaimedParameterSplit = Parameter.Item1.Split(SearchParams.SEARCH_CHAINSEPARATOR); bool ErrorInSearchParameterProcessing = false; for (int i = 0; i < ChaimedParameterSplit.Length; i++) { DtoServiceSearchParameterLight oSupportedSearchParameter = null; string ParameterName = Parameter.Item1.Split(SearchParams.SEARCH_CHAINSEPARATOR)[i]; string ParameterValue = string.Empty; //There is no valid Value for a chained reference parameter unless it is the last in a series //of chains, so don't set it. //Only set the last parameter if (i == ChaimedParameterSplit.Count() - 1) { ParameterValue = Parameter.Item2; } var SingleChainedParameter = new Tuple <string, string>(ParameterName, ParameterValue); string ParameterNameNoModifier = ParameterName; string ParameterModifierTypedResource = string.Empty; //Check for and deal with modifiers e.g 'Patient' in th example: subject:Patient.family=millar if (ParameterName.Contains(SearchParams.SEARCH_MODIFIERSEPARATOR)) { string[] ParameterModifierSplit = ParameterName.Split(SearchParams.SEARCH_MODIFIERSEPARATOR); ParameterNameNoModifier = ParameterModifierSplit[0].Trim(); if (ParameterModifierSplit.Length > 1) { Type ModifierResourceType = ModelInfo.GetTypeForFhirType(ParameterModifierSplit[1].Trim()); if (ModifierResourceType != null && ModelInfo.IsKnownResource(ModifierResourceType)) { ParameterModifierTypedResource = ParameterModifierSplit[1].Trim(); } } } if (PreviousChainSearchParameter == null) { oSupportedSearchParameter = _DtoSupportedSearchParametersList.SingleOrDefault(x => x.Name == ParameterNameNoModifier); } else { if (string.IsNullOrWhiteSpace(PreviousChainSearchParameter.TypeModifierResource)) { if (PreviousChainSearchParameter.TargetResourceTypeList != null) { if (PreviousChainSearchParameter.TargetResourceTypeList.Count == 1) { List <DtoServiceSearchParameterLight> _DtoSupportedSearchParametersListForTarget = GetSupportedSearchParameters(_SearchParameterServiceType, _OperationClass, PreviousChainSearchParameter.TargetResourceTypeList[0].ResourceType.GetLiteral()); DtoServiceSearchParameterLight oSupportedSearchParameterForTarget = _DtoSupportedSearchParametersListForTarget.SingleOrDefault(x => x.Name == ParameterNameNoModifier); PreviousChainSearchParameter.TypeModifierResource = oSupportedSearchParameterForTarget.Resource; oSupportedSearchParameter = oSupportedSearchParameterForTarget; } else { List <DtoServiceSearchParameterLight> oMultiChainedSupportedSearchParameter = new List <DtoServiceSearchParameterLight>(); foreach (var TargetResourceType in PreviousChainSearchParameter.TargetResourceTypeList) { FHIRAllTypes TargetResource = Tools.ResourceNameResolutionSupport.GetResourceFhirAllType(TargetResourceType.ResourceType); List <DtoServiceSearchParameterLight> _DtoSupportedSearchParametersListForTarget = GetSupportedSearchParameters(SearchParameterServiceType.Resource, null, TargetResource); DtoServiceSearchParameterLight oSupportedSearchParameterForTarget = _DtoSupportedSearchParametersListForTarget.SingleOrDefault(x => x.Name == ParameterNameNoModifier); if (oSupportedSearchParameterForTarget != null) { oMultiChainedSupportedSearchParameter.Add(oSupportedSearchParameterForTarget); } } if (oMultiChainedSupportedSearchParameter.Count() == 1) { PreviousChainSearchParameter.TypeModifierResource = oMultiChainedSupportedSearchParameter[0].Resource; oSupportedSearchParameter = oMultiChainedSupportedSearchParameter[0]; } else { //Need to do work here!! //oSupportedSearchParameter this needs to be set but we now have many! //the many is the list in oMultiChainedSupportedSearchParameter //PreviousChainSearchParameter.Modifier = SearchParameter.SearchModifierCode.Type; //PreviousChainSearchParameter.TypeModifierResource = oMultiChainedSupportedSearchParameter[0].Resource; string RefResources = string.Empty; oMultiChainedSupportedSearchParameter.ForEach(x => RefResources += ", " + x.Resource); //var DtoUnspportedSearchParameter = new UnspportedSearchParameter(); //DtoUnspportedSearchParameter.RawParameter = $"{Parameter.Item1}={Parameter.Item2}"; string ResourceName = string.Empty; if (_ResourceType.HasValue) { ResourceName = _ResourceType.Value.ToString(); } string Message = string.Empty; Message = $"The chained search parameter '{Parameter.Item1}' is ambiguous. "; Message += $"Additional information: "; Message += $"The search parameter '{oMultiChainedSupportedSearchParameter[0].Name}' can referance the following resource types ({RefResources.TrimStart(',').Trim()}). "; Message += $"To correct this you must prefix the search parameter with a Type modifier, for example: '{PreviousChainSearchParameter.Name}:{oMultiChainedSupportedSearchParameter[0].Resource}.{oMultiChainedSupportedSearchParameter[0].Name}' "; Message += $"If the '{oMultiChainedSupportedSearchParameter[0].Resource}' resource was the intended referance for the search parameter '{oMultiChainedSupportedSearchParameter[0].Name}'."; if (_SearchParametersServiceOutcome.FhirOperationOutcome == null) { _SearchParametersServiceOutcome.FhirOperationOutcome = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Processing, Message); } else { Common.Tools.FhirOperationOutcomeSupport.Append(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Processing, Message, _SearchParametersServiceOutcome.FhirOperationOutcome); } _SearchParametersServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.BadRequest; ErrorInSearchParameterProcessing = true; } } } else { //Error that we have no target resource list on the previous parameter, must have not been a references type? var DtoUnspportedSearchParameter = new UnspportedSearchParameter(); DtoUnspportedSearchParameter.RawParameter = $"{Parameter.Item1}={Parameter.Item2}"; string ResourceName = string.Empty; if (_ResourceType.HasValue) { ResourceName = _ResourceType.Value.ToString(); } DtoUnspportedSearchParameter.ReasonMessage = $"The search parameter '{Parameter.Item1}' is not supported by this server for the resource type '{ResourceName}'. "; DtoUnspportedSearchParameter.ReasonMessage += $"Additional information: "; DtoUnspportedSearchParameter.ReasonMessage += $"This search parameter was a chained search parameter. The part that was not recognised was '{PreviousChainSearchParameter.Name}.{ParameterName}'"; _SearchParametersServiceOutcome.SearchParameters.UnspportedSearchParameterList.Add(DtoUnspportedSearchParameter); ErrorInSearchParameterProcessing = true; break; } } else if (CheckModifierTypeResourceValidForSearchParameter(PreviousChainSearchParameter.TypeModifierResource, PreviousChainSearchParameter.TargetResourceTypeList)) { _DtoSupportedSearchParametersList = GetSupportedSearchParameters(_SearchParameterServiceType, _OperationClass, PreviousChainSearchParameter.TypeModifierResource); oSupportedSearchParameter = _DtoSupportedSearchParametersList.SingleOrDefault(x => x.Name == ParameterNameNoModifier); if (oSupportedSearchParameter.Resource == FHIRAllTypes.Resource.GetLiteral()) { oSupportedSearchParameter.Resource = PreviousChainSearchParameter.TypeModifierResource; } PreviousChainSearchParameter.TypeModifierResource = oSupportedSearchParameter.Resource; } else { //The modifier target resource provided is not valid for the previous reference, e.g subject:DiagnosticReport.family=millar var DtoUnspportedSearchParameter = new UnspportedSearchParameter(); DtoUnspportedSearchParameter.RawParameter = $"{Parameter.Item1}={Parameter.Item2}"; string ResourceName = string.Empty; if (_ResourceType.HasValue) { ResourceName = _ResourceType.Value.ToString(); } DtoUnspportedSearchParameter.ReasonMessage = $"The search parameter '{Parameter.Item1}' is not supported by this server for the resource type '{ResourceName}'. "; DtoUnspportedSearchParameter.ReasonMessage += $"Additional information: "; DtoUnspportedSearchParameter.ReasonMessage += $"This search parameter was a chained search parameter. The part that was not recognised was '{PreviousChainSearchParameter.Name}.{ParameterName}', The search parameter modifier given '{PreviousChainSearchParameter.TypeModifierResource}' is not valid for the search parameter {PreviousChainSearchParameter.Name}. "; _SearchParametersServiceOutcome.SearchParameters.UnspportedSearchParameterList.Add(DtoUnspportedSearchParameter); ErrorInSearchParameterProcessing = true; break; } } _DtoSupportedSearchParametersList.Clear(); if (oSupportedSearchParameter != null) { ISearchParameterBase oSearchParameter = null; if (i >= ChaimedParameterSplit.Length - 1) { oSearchParameter = ISearchParameterFactory.CreateSearchParameter(oSupportedSearchParameter, SingleChainedParameter, false); } else { oSearchParameter = ISearchParameterFactory.CreateSearchParameter(oSupportedSearchParameter, SingleChainedParameter, true); } var UnspportedSearchParameterList = new List <UnspportedSearchParameter>(); if (ValidateSearchParameterSupported(oSupportedSearchParameter, oSearchParameter, UnspportedSearchParameterList)) { if (!IsSingularSearchParameter(oSearchParameter, _SearchParametersServiceOutcome)) { ISearchParameterBase Temp = oSearchParameter.CloneDeep() as ISearchParameterBase; if (ParentChainSearchParameter == null) { ParentChainSearchParameter = Temp; } else { if (ParentChainSearchParameter.ChainedSearchParameter == null) { ParentChainSearchParameter.ChainedSearchParameter = Temp; } PreviousChainSearchParameter.ChainedSearchParameter = Temp; } PreviousChainSearchParameter = Temp; if (i != ChaimedParameterSplit.Count() - 1) { PreviousChainSearchParameter.Modifier = SearchParameter.SearchModifierCode.Type; } } } else { var DtoUnspportedSearchParameter = new UnspportedSearchParameter(); DtoUnspportedSearchParameter.RawParameter = $"{Parameter.Item1}={Parameter.Item2}"; string ResourceName = string.Empty; if (_ResourceType.HasValue) { ResourceName = _ResourceType.Value.ToString(); } DtoUnspportedSearchParameter.ReasonMessage = $"The parameter '{Parameter.Item1}' is not supported by this server for the resource type '{ResourceName}', the whole parameter was : '{DtoUnspportedSearchParameter.RawParameter}'. "; DtoUnspportedSearchParameter.ReasonMessage += $"Additional information: "; foreach (var UnspportedSearchParameter in UnspportedSearchParameterList) { DtoUnspportedSearchParameter.ReasonMessage += UnspportedSearchParameter.ReasonMessage; } _SearchParametersServiceOutcome.SearchParameters.UnspportedSearchParameterList.Add(DtoUnspportedSearchParameter); ErrorInSearchParameterProcessing = true; break; } } else { var DtoUnspportedSearchParameter = new UnspportedSearchParameter(); DtoUnspportedSearchParameter.RawParameter = $"{Parameter.Item1}={Parameter.Item2}"; string ResourceName = string.Empty; if (_ResourceType.HasValue) { ResourceName = _ResourceType.Value.ToString(); } DtoUnspportedSearchParameter.ReasonMessage = $"The search parameter '{Parameter.Item1}' is not supported by this server for the resource type '{ResourceName}', the whole parameter was : '{DtoUnspportedSearchParameter.RawParameter}'. "; DtoUnspportedSearchParameter.ReasonMessage += $"Additional information: "; DtoUnspportedSearchParameter.ReasonMessage += $"This search parameter was a chained search parameter. The part that was not recognised was '{ParameterNameNoModifier}'"; _SearchParametersServiceOutcome.SearchParameters.UnspportedSearchParameterList.Add(DtoUnspportedSearchParameter); ErrorInSearchParameterProcessing = true; break; } } if (!ErrorInSearchParameterProcessing) { _SearchParametersServiceOutcome.SearchParameters.SearchParametersList.Add(ParentChainSearchParameter); } }
public ISmartScopeOutcome ProcessScopes(PyroSearchParameters PyroSearchParameters, FHIRAllTypes ServiceResourceType, bool Read, bool Write) { ISmartScopeOutcome SmartScopeOutcome = new SmartScopeOutcome() { ScopesOK = false }; // If FHIRApiAuthentication = false then no need to check and scopes, ScopesOK! if (!IGlobalProperties.FHIRApiAuthentication) { SmartScopeOutcome.ScopesOK = true; return(SmartScopeOutcome); } SmartEnum.Action SmartAction = GetActionEnum(Read, Write); if (System.Threading.Thread.CurrentPrincipal != null && System.Threading.Thread.CurrentPrincipal is ClaimsPrincipal Principal) { //Get Client Id, we need to log this somewere, maybe FHIR AuditEventy? System.Security.Claims.Claim ClientClaim = Principal.Claims.SingleOrDefault(x => x.Type == ClientIdName); //Get tye scopes List <System.Security.Claims.Claim> ScopeClaim = Principal.Claims.Where(x => x.Type == ScopeName).ToList(); //This should be injected ScopeParse ScopeParse = new ScopeParse(); List <ISmartScope> ScopeList = new List <ISmartScope>(); foreach (var ScopeString in ScopeClaim) { ISmartScope SmartScope = new SmartScope(); if (ScopeParse.Parse(ScopeString.Value, out SmartScope)) { ScopeList.Add(SmartScope); } else { string Message = $"Unable to parse the SMART on FHIR scope given. Scope was {ScopeString.Value}"; var OpOut = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Exception, Message); throw new Common.Exceptions.PyroException(System.Net.HttpStatusCode.InternalServerError, OpOut, Message); } } IEnumerable <ISmartScope> FoundScopesList = ScopeList.Where(x => x.Resource == ServiceResourceType && (x.Action == SmartAction || x.Action == SmartEnum.Action.All)); if (FoundScopesList.Count() > 0) { if (PyroSearchParameters.IncludeList != null && PyroSearchParameters.IncludeList.Count > 0) { foreach (var Include in PyroSearchParameters.IncludeList) { FoundScopesList = ScopeList.Where(x => x.Resource == Include.SourceResourceType && (x.Action == SmartAction || x.Action == SmartEnum.Action.All)); if (FoundScopesList.Count() == 0) { //Reject string Message = $"You do not have permission to access the {Include.SourceResourceType.GetLiteral()} Resource type found within your include or revinclude search parameters."; var OpOut = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Forbidden, Message); SmartScopeOutcome.OperationOutcome = OpOut; SmartScopeOutcome.ScopesOK = false; return(SmartScopeOutcome); } } } var SearchParametersThatHaveChainParametersList = PyroSearchParameters.SearchParametersList.Where(x => x.ChainedSearchParameter != null); if (SearchParametersThatHaveChainParametersList != null && SearchParametersThatHaveChainParametersList.Count() > 0) { foreach (ISearchParameterBase Chain in SearchParametersThatHaveChainParametersList) { string ResourceWithNoScopeAccess = RecursiveChainScoped(Chain, ScopeList, SmartAction); if (!string.IsNullOrWhiteSpace(ResourceWithNoScopeAccess)) { //Reject string Message = $"You do not have permission to access {ResourceWithNoScopeAccess} resources types which was one of the resources types within your chained search parameter."; var OpOut = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Forbidden, Message); SmartScopeOutcome.OperationOutcome = OpOut; SmartScopeOutcome.ScopesOK = false; return(SmartScopeOutcome); } } } //ALL GOOD! We have a scope for the resource and action. all ok. SmartScopeOutcome.ScopesOK = true; return(SmartScopeOutcome); } else { string Message = string.Empty; if (SmartAction == SmartEnum.Action.All) { Message = $"You do not have permission to access Resources {ServiceResourceType.GetLiteral()} types for Read or Write."; } else if (SmartAction == SmartEnum.Action.Read) { Message = $"You do not have permission to access Resources {ServiceResourceType.GetLiteral()} types for Read."; } else if (SmartAction == SmartEnum.Action.Read) { Message = $"You do not have permission to access Resources {ServiceResourceType.GetLiteral()} types for Write."; } var OpOut = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Forbidden, Message); SmartScopeOutcome.OperationOutcome = OpOut; SmartScopeOutcome.ScopesOK = false; return(SmartScopeOutcome); } } else { //System.Threading.Thread.CurrentPrincipal was null string Message = "Internal Server Error: System.Threading.Thread.CurrentPrincipal was null"; var OpOut = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Exception, Message); throw new Common.Exceptions.PyroException(System.Net.HttpStatusCode.InternalServerError, OpOut, Message); } }
void GenerateFindCommonChild(CodeBlockNested construct, CodeBlockNested methods, FHIRAllTypes fhirType) { String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType); Type fhirCSType = ModelInfo.GetTypeForFhirType(fhirTypeName); String methodName = $"FindChild{fhirTypeName}"; construct .AppendCode($"case \"{fhirCSType.FriendlyName()}\": return {methodName}(parentPath, childName);") ; methods .BlankLine() .SummaryOpen() .Summary($"Manually add the children of a Coding element.") .SummaryClose() .AppendCode($"ElementDefinitionNode {methodName}(String parentPath, String childName)") .OpenBrace() .AppendCode($"ElementDefinitionNode retVal;") .AppendCode($"switch (childName)") .OpenBrace() ; foreach (PropertyInfo pi in fhirCSType.GetProperties()) { FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>(); if (attribute != null) { String min; String max; if (pi.PropertyType.IsList()) { min = "0"; max = "*"; } if (pi.PropertyType.IsNullable()) { min = "0"; max = "1"; } else { min = "1"; max = "1"; } String varName = $"{attribute.Name}Var"; methods .AppendCode($"case \"{attribute.Name}\":") .OpenBrace() .AppendCode($"ElementDefinition e = new ElementDefinition") .OpenBrace() .AppendCode($"Path = $\"{{parentPath}}.{attribute.Name}\",") .AppendCode($"Short = \"{fhirType}.{attribute.Name} common attribute\",") .AppendCode($"Min = {min},") .AppendCode($"Max = \"{max}\"") .CloseBrace(";") .AppendCode($"retVal = new ElementDefinitionNode(this, e, typeof({pi.PropertyType.FriendlyName()}), nameof({fhirCSType.FriendlyName()}.{pi.Name}));") .AppendCode($"retVal.AutoGeneratedFlag = true;") .AppendCode($"break;") .CloseBrace(";") ; } } methods .AppendCode($"default: return null;") .CloseBrace() .AppendCode($"this.childNodeDictionary.Add(childName, retVal);") .AppendCode($"return retVal;") .CloseBrace() ; }
void GenerateComplex(FHIRAllTypes fhirType, String genDir) { String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType); Type csType = ModelInfo.GetTypeForFhirType(fhirTypeName); if (csType == null) { return; } Trace.WriteLine($"Generating fhir complex '{fhirType}'"); CodeEditor instanceEditor = new CodeEditor(); CodeBlockNested instanceBlock = instanceEditor.Blocks.AppendBlock(); String instanceName = $"{fhirType.ToString()}_Item"; instanceBlock .AppendLine("using System;") .AppendLine("using System.Diagnostics;") .AppendLine("using System.IO;") .AppendLine("using System.Linq;") .AppendLine("using Hl7.Fhir.Model;") .BlankLine() .AppendCode("namespace FhirKhit.Maker.Common") .OpenBrace() .AppendCode($"public class {instanceName} : Complex_Item") .OpenBrace() .DefineBlock(out CodeBlockNested fields) .CloseBrace() .CloseBrace() ; foreach (PropertyInfo pi in csType.GetProperties()) { FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>(); if (attribute != null) { //String min; //String max; //Type csType; if (pi.PropertyType.IsList()) { //min = "0"; //max = "*"; //csType = pi.PropertyType.GenericTypeArguments[0]; } if (pi.PropertyType.IsNullable()) { //min = "0"; //max = "1"; //csType = pi.PropertyType.GenericTypeArguments[0]; } else { //csType = pi.PropertyType; //min = "1"; //max = "1"; } } ; } //fields //; instanceEditor.Save(Path.Combine(genDir, $"{instanceName}.cs")); }