Пример #1
0
        /// <summary>
        /// Executes the custom runtime task component to process the input message and returns the result message.
        /// </summary>
        /// <param name="pContext">A reference to <see cref="Microsoft.BizTalk.Component.Interop.IPipelineContext"/> object that contains the current pipeline context.</param>
        /// <param name="pInMsg">A reference to <see cref="Microsoft.BizTalk.Message.Interop.IBaseMessage"/> object that contains the message to process.</param>
        /// <returns>A reference to the returned <see cref="Microsoft.BizTalk.Message.Interop.IBaseMessage"/> object which will contain the output message.</returns>
        public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
        {
            Guard.ArgumentNotNull(pContext, "pContext");
            Guard.ArgumentNotNull(pInMsg, "pInMsg");

            var callToken = TraceManager.PipelineComponent.TraceIn();

            // It is OK to load the entire message into XML DOM. The size of these requests is anticipated to be very small.
            XDocument request = XDocument.Load(pInMsg.BodyPart.GetOriginalDataStream());

            string transformName = (from childNode in request.Root.Descendants() where childNode.Name.LocalName == WellKnownContractMember.MessageParameters.TransformName select childNode.Value).FirstOrDefault <string>();

            TraceManager.PipelineComponent.TraceInfo(TraceLogMessages.GetXslTransformRequest, transformName);

            IBaseMessagePart  responsePart = BizTalkUtility.CreateResponsePart(pContext.GetMessageFactory(), pInMsg);
            XmlWriterSettings settings     = new XmlWriterSettings();

            MemoryStream dataStream = new MemoryStream();

            pContext.ResourceTracker.AddResource(dataStream);

            settings.CloseOutput       = false;
            settings.CheckCharacters   = false;
            settings.ConformanceLevel  = ConformanceLevel.Fragment;
            settings.NamespaceHandling = NamespaceHandling.OmitDuplicates;

            using (XmlWriter responseWriter = XmlWriter.Create(dataStream, settings))
            {
                responseWriter.WriteResponseStartElement("r", WellKnownContractMember.MethodNames.GetXslTransformMetadata, WellKnownNamespace.ServiceContracts.General);

                try
                {
                    Type transformType = ResolveTransformType(transformName);

                    if (transformType != null)
                    {
                        // Get the actual map from the BizTalk metadata cache.
                        BtsTransformMetadata btsTransform = BtsTransformMetadata.For(transformType);

                        if (btsTransform != null)
                        {
                            // Map existence confirmed, now it's safe to instantiate the transform type.
                            TransformBase transform = Activator.CreateInstance(transformType) as TransformBase;

                            // Is this really a valid map that implements TransformBase?
                            if (transform != null)
                            {
                                XslTransformMetadata transformMetadata = new XslTransformMetadata(transform.XmlContent, transform.XsltArgumentListContent, transform.SourceSchemas, transform.TargetSchemas);

                                DataContractSerializer dcSerializer = new DataContractSerializer(typeof(XslTransformMetadata), String.Concat(WellKnownContractMember.MethodNames.GetXslTransformMetadata, WellKnownContractMember.ResultMethodSuffix), WellKnownNamespace.ServiceContracts.General);
                                dcSerializer.WriteObject(responseWriter, transformMetadata);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Log but do not pass the exception to the caller.
                    TraceManager.PipelineComponent.TraceError(ex);
                }

                responseWriter.WriteEndElement();
                responseWriter.Flush();
            }

            dataStream.Seek(0, SeekOrigin.Begin);
            responsePart.Data = dataStream;

            TraceManager.PipelineComponent.TraceOut(callToken);
            return(pInMsg);
        }
Пример #2
0
        /// <summary>
        /// Returns an object carrying the XSLT transformation metadata, XSLT transformation engine and its arguments.
        /// </summary>
        /// <param name="transformName">Either partial or fully qualified name of the transformation object.</param>
        /// <returns>An instance of the object carrying the XSLT transformation metadata, XSLT transformation engine and its arguments, or null if the specified transform was not found.</returns>
        public XslTransformSet GetXslTransform(string transformName)
        {
            var callToken = TraceManager.WorkerRoleComponent.TraceIn(transformName);

            try
            {
                ICollection <IXslTransformCacheExtension> transformCacheCollection = this.owner.Extensions.FindAll <IXslTransformCacheExtension>();
                XslTransformSet transformSet = null;

                // If cache is enabled, try to get from the cache first.
                if (transformCacheCollection != null)
                {
                    // Find a cached transform instance in all registered cache extensions, break at the first match.
                    foreach (var transformCache in transformCacheCollection)
                    {
                        if ((transformSet = transformCache.Get(transformName)) != null)
                        {
                            break;
                        }
                    }
                }

                // Reason 1: cache miss or no caching functionality is provided via extensions.
                // Reason 2: transform set doesn't have the XSLT transform engine instance.
                // Reason 3: XSLT transform engine in the transform set doesn't have a loaded template.
                if (null == transformSet || null == transformSet.Transform || null == transformSet.Transform.OutputSettings)
                {
                    // Try to re-use the transform metadata (if available), otherwise
                    XslTransformMetadata metadata = transformSet != null && transformSet.Metadata != null ? transformSet.Metadata : this.metadataProvider.GetXslTransformMetadata(transformName);

                    if (metadata != null)
                    {
                        XslCompiledTransform transform    = new XslCompiledTransform();
                        XsltArgumentList     arguments    = new XsltArgumentList();
                        XsltSettings         xsltSettings = new XsltSettings()
                        {
                            EnableDocumentFunction = true, EnableScript = true
                        };
                        XmlReaderSettings readerSettings = new XmlReaderSettings()
                        {
                            CheckCharacters = false, IgnoreComments = true, IgnoreProcessingInstructions = true, IgnoreWhitespace = true, ValidationType = ValidationType.None
                        };

                        // Read the XSLT template from the metadata and load it into XSLT transformation engine.
                        using (StringReader rawDataReader = new StringReader(metadata.XsltContentRaw))
                            using (XmlReader xsltReader = XmlReader.Create(rawDataReader, readerSettings))
                            {
                                transform.Load(xsltReader, xsltSettings, null);
                            }

                        // Check if XSLT arguments are provided.
                        if (!String.IsNullOrEmpty(metadata.XsltArgumentsRaw))
                        {
                            // Read the XSLT argument list from the metadata and load it into a XsltArgumentList collection.
                            using (StringReader argDataReader = new StringReader(metadata.XsltArgumentsRaw))
                                using (XmlReader argContentReader = XmlReader.Create(argDataReader, readerSettings))
                                {
                                    XDocument xsltArgs = XDocument.Load(argContentReader);

                                    var extObjects = (from x in xsltArgs.Root.Descendants()
                                                      select new
                                    {
                                        Namespace = x.Attribute(Resources.ExtensionObjectNamespaceAttributeName).Value,
                                        AssemblyName = x.Attribute(Resources.ExtensionObjectAssemblyAttributeName).Value,
                                        ClassName = x.Attribute(Resources.ExtensionObjectClassAttributeName).Value
                                    });

                                    foreach (var extObjectInfo in extObjects)
                                    {
                                        Type   extObjectType = Type.GetType(String.Concat(extObjectInfo.ClassName, ", ", extObjectInfo.AssemblyName), false);
                                        object extObject     = null;

                                        if (extObjectType != null && (extObject = Activator.CreateInstance(extObjectType)) != null)
                                        {
                                            arguments.AddExtensionObject(extObjectInfo.Namespace, extObject);
                                        }
                                    }
                                }
                        }

                        transformSet = new XslTransformSet(metadata, transform, arguments);

                        // If cache is enabled, place the transform instance and its metadata to the cache.
                        if (transformCacheCollection != null)
                        {
                            foreach (var transformCache in transformCacheCollection)
                            {
                                transformCache.Put(transformName, transformSet);
                            }
                        }
                    }
                }

                return(transformSet);
            }
            finally
            {
                TraceManager.WorkerRoleComponent.TraceOut(callToken);
            }
        }