/// <summary> /// Graphs <paramref name="o"/> onto the <see cref="T:System.Xml.XmlWriter"/> <paramref name="s"/> /// </summary> /// <param name="s">The <see cref="T:System.Xml.XmlWriter"/> that should be used to graph the object</param> /// <param name="o">The <see cref="T:MARC.Everest.Interfaces.IGraphable"/> that should be graphed</param> /// <returns>A <see cref="T:MARC.Everest.Formatters.XML.ITS1.Its1FormatterGraphResult"/> containing the results of the graph</returns> /// <remarks> /// <para> /// This particular overload of the Graph method can be used to graph objects into a <see cref="T:System.Xml.XmlWriter"/> and can provide /// an opportunity to use Everest as an assistant (or XmlSerializerSurrogate) for more complex systems like WCF. /// </para> /// <example> /// <code lang="cs" title="Using Everest as a Serializer Assistant"> /// <![CDATA[ /// StringWriter sw = new StringWriter(); /// XmlWriter writer = XmlWriter.Create(sw); /// writer.WriteStartElement("hello", "urn:my-org"); /// /// Formatter f = new Formatter(); /// f.GraphAides.Add(typeof(MARC.Everest.Formatters.XML.DataTypes.R1.Formatter)); /// f.ValidateConformance = false; /// f.Graph(writer, new MCCI_IN000002CA()); /// /// writer.WriteEndElement(); /// writer.Close(); /// Console.WriteLine(sw.ToString()); /// /// ]]> /// </code> /// outputs /// <code lang="xml" title="Output of example"> /// <![CDATA[ /// <hello xmlns="urn:my-org"> /// <MCCI_IN000002CA xmlns="urn:hl7-org:v3"/> /// </hello> /// ]]> /// </code> /// </example> /// <para> /// When using this method, it is recommended that you pass a <see cref="T:MARC.Everest.Xml.XmlStateWriter"/> as it /// will allow the formatter to give additional location information when reporting issues. /// </para> /// </remarks> public IFormatterGraphResult Graph(XmlWriter s, IGraphable o) { ThrowIfDisposed(); var resultContext = new XmlIts1FormatterGraphResult(ResultCode.Accepted, null); IGraphable context = null; // Clear out result cache if (s.WriteState == WriteState.Start || String.IsNullOrEmpty(s.ToString()) || o is IInteraction) context = o; if (!(s is XmlStateWriter)) s = new XmlStateWriter(s); if (o == null) resultContext.Code = ResultCode.AcceptedNonConformant; else { GraphObject(s, o, o.GetType(), context, resultContext); resultContext.Code = CalculateResultCode(resultContext.Details); } return resultContext; }
protected virtual void GraphObject(XmlWriter s, IGraphable o, Type useType, IGraphable context, XmlIts1FormatterGraphResult resultContext) { // Find the HL7 alias for the type and build the cache for the type string typeName = GetStructureName(useType); // Find a helper IXmlStructureFormatter ixsf = (IXmlStructureFormatter)this.GraphAides.Find(t => t.HandleStructure.Contains(typeName)); // Does the helper graph aide have a handler? if (ixsf != null) { ixsf.Host = this; var rv = ixsf.Graph(s, o); resultContext.AddResultDetail(rv.Details); return; } #if WINDOWS_PHONE ITypeFormatter formatter = m_codeGeneratorFormatter.GetFormatter(useType); if (formatter == null) formatter = new ReflectFormatter(); #else ITypeFormatter formatter = m_codeGeneratorFormatter.GetFormatter(useType); // Is there a formatter and if there is not a formatter // can we create one? if (formatter == null && (Settings & SettingsType.UseGeneratorFormat) == SettingsType.UseGeneratorFormat) s_threadPool.QueueUserWorkItem((WaitCallback)delegate(object state) { BuildCache(new Type[] { (Type)state }); }, useType); // If there is no connector can we use reflection? if (formatter == null && (Settings & SettingsType.UseReflectionFormat) == SettingsType.UseReflectionFormat) formatter = new ReflectFormatter(); else if (formatter == null && (Settings & SettingsType.UseGeneratorFormat) == SettingsType.UseGeneratorFormat) { s_threadPool.WaitOne(); formatter = m_codeGeneratorFormatter.GetFormatter(useType); } #endif if(formatter == null) throw new InvalidOperationException(string.Format("Couldn't format '{0}' at {1}, verify formatter settings!", useType.FullName, s.ToString())); // Validate the instance formatter.Host = this; // Graph using helper formatter.Graph(s, o, context, resultContext); }
public void ValidateHelper(XmlWriter s, IGraphable o, ITypeFormatter formatter, XmlIts1FormatterGraphResult resultContext) { IResultDetail[] details = null; if (ValidateConformance && (!formatter.Validate(o, s.ToString(), out details))) resultContext.AddResultDetail(details.Length > 0 ? details : new IResultDetail[] { new DatatypeValidationResultDetail(ValidateConformance ? ResultDetailType.Error : ResultDetailType.Warning, o.GetType().ToString(), s.ToString()) }); }
public virtual void WriteElementUtil(XmlWriter s, string namespaceUri, string elementName, IGraphable g, Type propType, IGraphable context, XmlIts1FormatterGraphResult resultContext) { ThrowIfDisposed(); // Graph is nothing if (g == null) return; // Normalize if (g is INormalizable) g = (g as INormalizable).Normalize(); // Write start of element s.WriteStartElement(elementName, namespaceUri); // JF: Output XSI:Type if (!g.GetType().Equals(propType) ) { // TODO: This may cause issue when assigning a QSET to an R1 or // SXPR to R2 instance as the XSI:TYPE will be inappropriately // assigned. string xsiType = String.Empty; if (typeof(ANY).IsAssignableFrom(g.GetType())) { xsiType += s.LookupPrefix("urn:hl7-org:v3"); if (!String.IsNullOrEmpty(xsiType)) xsiType += ":"; xsiType += Util.CreateXSITypeName(g.GetType()); } else if (propType != null && g.GetType().Assembly.FullName != propType.Assembly.FullName) { string typeName = this.CreateXSITypeName(g.GetType(), context != null ? context.GetType() : null, s as IXmlNamespaceResolver); // If there is no different then don't output if (typeName != String.Format("{0}.{1}", this.GetModelName(propType), this.GetStructureName(propType))) { lock (this.m_syncRoot) if (!this.s_typeNameMaps.ContainsKey(typeName)) this.RegisterXSITypeName(typeName, g.GetType()); } xsiType = typeName; } if(!String.IsNullOrEmpty(xsiType)) s.WriteAttributeString("xsi", "type", XmlIts1Formatter.NS_XSI, xsiType); //string xsdTypeName = String.Empty; //object[] sa = g.GetType().GetCustomAttributes(typeof(StructureAttribute), false); //if (sa.Length > 0 && (sa[0] as StructureAttribute).StructureType == StructureAttribute.StructureAttributeType.DataType) // s.WriteAttributeString("xsi", "type", null, (sa[0] as StructureAttribute).Name); } // Result code of the GraphObject(s, g, g.GetType(), context, resultContext); s.WriteEndElement(); }