private static AnswerFileDataSource DefineAnswerFileDataSource(string dataSourceId, string templateLocator, string templateName) { Debug.Assert(s_readerWriterLock.IsWriteLockHeld); try { Template template = Template.Locate(templateLocator); TemplateManifest templateManifest = template.GetManifest(ManifestParseFlags.ParseDataSources); DataSource dataSource = templateManifest.DataSources.Single(ds => string.CompareOrdinal(ds.Id, dataSourceId) == 0); string dataSourcePath = Path.Combine(template.Location.GetTemplateDirectory(), dataSource.Name); AnswerFileDataSource answerFileDataSource = new AnswerFileDataSource(dataSourceId, dataSource.Name, dataSourcePath); // Create the metadata for the answer file data source. ResourceType resourceType = s_metadata.AddEntityType(answerFileDataSource.ResourceId); // All resources need a key property. s_metadata.AddKeyProperty(resourceType, "ID", typeof(int)); answerFileDataSource.PropertyNameToSourceNameMap["ID"] = "ID"; Type propType; foreach (var dataSourceField in dataSource.Fields) { switch (dataSourceField.FieldType) { case DataSourceFieldType.Text: propType = typeof(string); break; case DataSourceFieldType.Number: propType = typeof(double?); break; case DataSourceFieldType.Date: propType = typeof(DateTime?); break; case DataSourceFieldType.TrueFalse: propType = typeof(bool?); break; default: propType = null; break; } if (propType != null) { string sourceFieldName = dataSourceField.SourceName; string propertyName = "Prop" + MakeValidIdent(sourceFieldName); s_metadata.AddPrimitiveProperty(resourceType, propertyName, propType); answerFileDataSource.PropertyNameToSourceNameMap[propertyName] = sourceFieldName; } } resourceType.SetReadOnly(); // Create a resource set for the resource type. ResourceSet resourceSet = s_metadata.AddResourceSet(answerFileDataSource.ResourceId, resourceType); resourceSet.SetReadOnly(); return(answerFileDataSource); } catch (Exception e) { throw new DataServiceException(string.Format("Failed to read the metadata for the data source Id '{0}' from the template manifest file for the " + "template '{1}'.", dataSourceId, templateName), e); } }
private static void LoadAnswerFileDataSource(AnswerFileDataSource answerFileDataSource) { Debug.Assert(s_readerWriterLock.IsWriteLockHeld); Stream answerFileStream = null; try { answerFileStream = new FileStream(answerFileDataSource.AnswerFilePath, FileMode.Open, FileAccess.Read); AnswerCollection answerSet = new AnswerCollection(); answerSet.ReadXml(answerFileStream); ResourceSet resourceSet = s_metadata.ResourceSets.Single(rs => rs.Name == answerFileDataSource.ResourceId); ResourceType resourceType = resourceSet.ResourceType; List <Answer> answers = new List <Answer>(resourceType.Properties.Count); int repeatCount = 0; Answer answer; foreach (var property in resourceType.Properties) { if (((property.Kind & ResourcePropertyKind.Key) != ResourcePropertyKind.Key) && answerSet.TryGetAnswer(answerFileDataSource.PropertyNameToSourceNameMap[property.Name], out answer)) { // Sanity check to be sure the property type the metadata is expecting is the same as the values in the answer file. Type type; switch (answer.Type) { case ValueType.Text: case ValueType.MultipleChoice: type = typeof(string); break; case ValueType.Number: type = typeof(double?); break; case ValueType.Date: type = typeof(DateTime?); break; case ValueType.TrueFalse: type = typeof(bool?); break; default: throw new Exception(string.Format("The value type '{0}' is not supported.", answer.Type.ToString())); } if (property.ResourceType.InstanceType != type) { throw new Exception(string.Format("The type of the metadata property '{0}' does not match the type of the " + "corresponding answer '{1}'.", answerFileDataSource.PropertyNameToSourceNameMap[property.Name], answer.Name)); } repeatCount = Math.Max(repeatCount, answer.GetChildCount()); answers.Add(answer); } else { answers.Add(null); } } // Populate the data source with data. IList <DSPResource> resourceList = s_context.GetResourceSetEntities(resourceSet.Name); resourceList.Clear(); for (int repeatIndex = 0; repeatIndex < repeatCount; repeatIndex++) { var resource = new DSPResource(resourceSet.ResourceType, s_readerWriterLock); for (int propertyIndex = 0; propertyIndex < resourceType.Properties.Count; propertyIndex++) { ResourceProperty property = resourceType.Properties[propertyIndex]; object value; if ((property.Kind & ResourcePropertyKind.Key) == ResourcePropertyKind.Key) { value = repeatIndex + 1; } else { IValue iValue = null; answer = answers[propertyIndex]; if ((answer != null) && (repeatIndex <= answer.GetChildCount())) { iValue = answer.GetValue(repeatIndex); } if (property.ResourceType.InstanceType == typeof(string)) { value = ((iValue != null) && iValue.IsAnswered) ? iValue.ToString(null) : string.Empty; } else if (property.ResourceType.InstanceType == typeof(double?)) { if ((iValue != null) && iValue.IsAnswered) { value = iValue.ToDouble(null); } else { value = null; } } else if (property.ResourceType.InstanceType == typeof(DateTime?)) { if ((iValue != null) && iValue.IsAnswered) { value = iValue.ToDateTime(null); } else { value = null; } } else { Debug.Assert(property.ResourceType.InstanceType == typeof(bool?)); if ((iValue != null) && iValue.IsAnswered) { value = iValue.ToBoolean(null); } else { value = null; } } } resource.SetValue(property.Name, value); } resourceList.Add(resource); } } catch (Exception e) { throw new DataServiceException(string.Format("Failed to read the answers for the data source key '{0}' from the answer file '{1}'.", answerFileDataSource.DataSourceId, answerFileDataSource.DataSourceName), e); } finally { if (answerFileStream != null) { answerFileStream.Close(); } } }
private static void LoadAnswerFileDataSource(AnswerFileDataSource answerFileDataSource) { Debug.Assert(s_readerWriterLock.IsWriteLockHeld); Stream answerFileStream = null; try { answerFileStream = new FileStream(answerFileDataSource.AnswerFilePath, FileMode.Open, FileAccess.Read); AnswerCollection answerSet = new AnswerCollection(); answerSet.ReadXml(answerFileStream); ResourceSet resourceSet = s_metadata.ResourceSets.Single(rs => rs.Name == answerFileDataSource.ResourceId); ResourceType resourceType = resourceSet.ResourceType; List <Answer> answers = new List <Answer>(resourceType.Properties.Count); int repeatCount = 0; Answer answer; foreach (var property in resourceType.Properties) { if ((property.Kind & ResourcePropertyKind.Key) != ResourcePropertyKind.Key) { ValueType valueType = ValueType.Unknown; // Infer from the CLR type what the ValueType is of the answer to be fetched. if (property.ResourceType.InstanceType == typeof(string)) { valueType = ValueType.Text; } else if (property.ResourceType.InstanceType == typeof(double?)) { valueType = ValueType.Number; } else if (property.ResourceType.InstanceType == typeof(DateTime?)) { valueType = ValueType.Date; } else if (property.ResourceType.InstanceType == typeof(bool?)) { valueType = ValueType.TrueFalse; } if (valueType == ValueType.Unknown) { throw new Exception(string.Format("The metadata property '{0}' with a CLR type of '{1}' does not correspond to a supported " + "HotDocs ValueType.", answerFileDataSource.PropertyNameToSourceNameMap[property.Name], property.ResourceType.InstanceType.FullName)); } if (answerSet.TryGetAnswer(answerFileDataSource.PropertyNameToSourceNameMap[property.Name], valueType, out answer) || ((valueType == ValueType.Text) && answerSet.TryGetAnswer(answerFileDataSource.PropertyNameToSourceNameMap[property.Name], ValueType.MultipleChoice, out answer))) { repeatCount = Math.Max(repeatCount, answer.GetChildCount()); answers.Add(answer); } else { answers.Add(null); } } } // Populate the data source with data. IList <DSPResource> resourceList = s_context.GetResourceSetEntities(resourceSet.Name); resourceList.Clear(); for (int repeatIndex = 0; repeatIndex < repeatCount; repeatIndex++) { var resource = new DSPResource(resourceSet.ResourceType, s_readerWriterLock); int answerIndex = 0; for (int propertyIndex = 0; propertyIndex < resourceType.Properties.Count; propertyIndex++) { ResourceProperty property = resourceType.Properties[propertyIndex]; object value; if ((property.Kind & ResourcePropertyKind.Key) == ResourcePropertyKind.Key) { value = repeatIndex + 1; } else { IValue iValue = null; answer = answers[answerIndex++]; if ((answer != null) && (repeatIndex <= answer.GetChildCount())) { iValue = answer.GetValue(repeatIndex); } if (property.ResourceType.InstanceType == typeof(string)) { value = ((iValue != null) && iValue.IsAnswered) ? iValue.ToString(null) : string.Empty; } else if (property.ResourceType.InstanceType == typeof(double?)) { if ((iValue != null) && iValue.IsAnswered) { value = iValue.ToDouble(null); } else { value = null; } } else if (property.ResourceType.InstanceType == typeof(DateTime?)) { if ((iValue != null) && iValue.IsAnswered) { value = iValue.ToDateTime(null); } else { value = null; } } else { Debug.Assert(property.ResourceType.InstanceType == typeof(bool?)); if ((iValue != null) && iValue.IsAnswered) { value = iValue.ToBoolean(null); } else { value = null; } } } resource.SetValue(property.Name, value); } resourceList.Add(resource); } } catch (Exception e) { throw new DataServiceException(string.Format("Failed to read the answers for the data source key '{0}' from the answer file '{1}'.", answerFileDataSource.DataSourceId, answerFileDataSource.DataSourceName), e); } finally { if (answerFileStream != null) { answerFileStream.Close(); } } }