internal TransformMetaData FindFirstMapMatch(string message) { string[] mapsArray = _mapName.Split(new char[] { '|' }, StringSplitOptions.None); TransformMetaData mapMatch = null; for (int i = 0; i < mapsArray.Length; i++) { try { Type mapType = Type.GetType(mapsArray[i], true); TransformMetaData map = TransformMetaData.For(mapType); SchemaMetadata sourceSchema = map.SourceSchemas[0]; if (sourceSchema.SchemaName == message) { mapMatch = map; break; } } catch (Exception ex) { throw new ApplicationException(string.Format("Error while trying to load MapType specification: {0}", mapsArray[i]), ex); } } return(mapMatch); }
internal TransformMetaData(Type transformBaseType) { this.mapAssembly = transformBaseType.Assembly.ToString(); this._transformBase = (TransformBase)Activator.CreateInstance(transformBaseType); this._mapType = transformBaseType; this._xmlDecl = TransformMetaData._getXmlDeclaration(this._transformBase); }
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { string stageID = pContext.StageID.ToString("D"); m_portDirection = PortDirection.send; if (stageID == CategoryTypes.CATID_Decoder || stageID == CategoryTypes.CATID_Validate || stageID == CategoryTypes.CATID_PartyResolver) { m_portDirection = PortDirection.receive; } if (!string.IsNullOrEmpty(_mapName)) { MarkableForwardOnlyEventingReadStream stream = new MarkableForwardOnlyEventingReadStream( pInMsg.BodyPart.GetOriginalDataStream()); string messageType = (string)pInMsg.Context.Read("MessageType", _systemPropertiesNamespace); if (messageType == String.Empty) { stream.MarkPosition(); //Thanks to http://maximelabelle.wordpress.com/2010/07/08/determining-the-type-of-an-xml-message-in-a-custom-pipeline-component/ messageType = Microsoft.BizTalk.Streaming.Utils.GetDocType(stream); stream.ResetPosition(); } TransformMetaData _map = FindFirstMapMatch(messageType); if (_map == null) { System.Diagnostics.Debug.WriteLine("No match for map could be made for message type: " + messageType); } else { pInMsg.BodyPart.Data = TransformMessage(stream, _map, pInMsg); pContext.ResourceTracker.AddResource(stream); } } return(pInMsg); }
/// <summary> /// Transforms original stream using streaming scalable transformation from BizTalk API. /// </summary> /// <param name="inputStream"></param> /// <returns></returns> internal Stream TransformMessage(Stream inputStream, TransformMetaData map, IBaseMessage pInMsg) { XsltArgumentList args = null; Context ext = null; SchemaMetadata targetSchema = targetSchema = map.TargetSchemas[0]; string portname = String.Empty; //It is possible to add a param but then you you need to work arounds in the map // map.ArgumentList.AddParam //The statement bellow caused me some problems that was solved by creating the XsltArgumentList instead //args = map.ArgumentList; try { ext = new Context(pInMsg.Context, pInMsg.MessageID.ToString()); args = map.ArgumentList;//Include BizTalk extensions //args.AddExtensionObject("http://www.w3.org/1999/XSL/Transform", ext); strangely it seams i cannot use this namespace in vs 2012, but it worked in vs 2010 args.RemoveExtensionObject("urn:schemas-microsoft-com:xslt"); args.AddExtensionObject("urn:schemas-microsoft-com:xslt", ext); AddParameters(args); //2017-08-23 Added intermidiate stream as Transform kills the original stream, //this is a problem if the incomming message is a enveloped message. // XmlTranslatorStream stm = new XmlTranslatorStream(XmlReader.Create(inputStream)); //Opted to use non disposable stream instead NonDisposableStream stm = new NonDisposableStream(inputStream); VirtualStream outputStream = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk); //TODO test to add declaration and see what happens with params!!!!!!!!!!!!!!!!!!!!!!!! BTSXslTransform btsXslTransform = null; if (Transforms.ContainsKey(map)) { btsXslTransform = Transforms[map]; } else { btsXslTransform = new BTSXslTransform(); XmlTextReader xmlTextReader = new XmlTextReader((TextReader) new StringReader(map.XmlContent)); btsXslTransform.Load((XmlReader)xmlTextReader, new MemoryResourceResolver(map.Assembly), (System.Security.Policy.Evidence)null); Transforms.TryAdd(map, btsXslTransform); } btsXslTransform.Transform(stm, args, outputStream, null); outputStream.Seek(0, SeekOrigin.Begin); if (_dynamicMap) { pInMsg.Context.Write("XSLTransform", "PipelineComponents.XSLTransform", map.AssemblyQualifiedName); } pInMsg.Context.Promote("MessageType", _systemPropertiesNamespace, targetSchema.SchemaName); //Changed to Write as SchemaStrongName could exceed 255 chars pInMsg.Context.Write("SchemaStrongName", _systemPropertiesNamespace, targetSchema.ReflectedType.AssemblyQualifiedName); //pInMsg.MessageID.ToString() return(outputStream); } catch (Exception ex) { throw new ApplicationException($"Error while trying to transform using MapType specification: {_mapName}\nMap Assembly {map.AssemblyQualifiedName} used\nError {ex.Message}", ex); } }
internal TransformMetaData FindFirstMapMatch(ContextProperty property, string messageType) { string[] mapsArray = _mapName.Split(new char[] { '|' }, StringSplitOptions.None); TransformMetaData mapMatch = null; //Check Cache if (Maps.ContainsKey(messageType)) { for (int i = 0; i < mapsArray.Length; i++) { if (Maps[messageType].TryGetValue(mapsArray[i], out mapMatch) == true) { return(mapMatch); } } } else { //Add cache for this messagetype Maps.TryAdd(messageType, new ConcurrentDictionary <string, TransformMetaData>()); } //Check MapCache for (int i = 0; i < mapsArray.Length; i++) { try { //When map exists in the same assembly as the pipeline you do not need to specify assembly if (mapsArray[i].Contains(",") == false) { mapsArray[i] = String.Format("{0}, {1}", mapsArray[i], pipelineAssembly); } Type mapType = Type.GetType(mapsArray[i], true); mapMatch = TransformMetaData.For(mapType); SchemaMetadata sourceSchema = mapMatch.SourceSchemas[0]; if (property.PropertyName == "SchemaStrongName") { if (sourceSchema.ReflectedType.AssemblyQualifiedName == messageType) { Maps[messageType].TryAdd(mapsArray[i], mapMatch); break; } } else if (property.PropertyName == "MessageType" && sourceSchema.SchemaName == messageType) { Maps[messageType].TryAdd(mapsArray[i], mapMatch); break; } mapMatch = null; } catch (Exception ex) { throw new ApplicationException(string.Format("Error while trying to load MapType specification: {0}", mapsArray[i]), ex); } } return(mapMatch); }
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { pipelineAssembly = pContext.PipelineName.Substring(pContext.PipelineName.IndexOf(",") + 1).TrimStart(); /* * string stageID = pContext.StageID.ToString("D"); * m_portDirection = PortDirection.send; * if(stageID == CategoryTypes.CATID_Decoder || stageID == CategoryTypes.CATID_Validate || stageID == CategoryTypes.CATID_PartyResolver) * m_portDirection = PortDirection.receive; */ /*2019-05-20 Add map dynamically*/ //Microsoft.XLANGs.BaseTypes.XmlQName TransformHint = new BTS.SendPortTransformHint().QName; -- Could not use SendPortTransformHint as this would run the map in a "normal mode" and IsDynamic did not need to be set. _mapName = _mapName.Trim(); string map = GetContextTransform(pInMsg.Context); if (string.IsNullOrEmpty(map) == false) { _dynamicMap = true; if (string.IsNullOrEmpty(_mapName)) { _mapName = map; } else { _mapName = String.Format("{0}|{1}", _mapName, map);//Add the map last } } if (string.IsNullOrEmpty(_mapName)) { if (_mapRequired) { throw new ArgumentNullException("MapName"); } else { return(pInMsg); } } else { MarkableForwardOnlyEventingReadStream stream = new MarkableForwardOnlyEventingReadStream( pInMsg.BodyPart.GetOriginalDataStream()); string schemaStrongName = null; string messageType = null; ContextProperty property = null; if ((schemaStrongName = (string)pInMsg.Context.Read("SchemaStrongName", _systemPropertiesNamespace)) != null) { if (schemaStrongName.StartsWith("Microsoft.XLANGs.BaseTypes.Any") == false) { property = new ContextProperty("SchemaStrongName", _systemPropertiesNamespace); messageType = schemaStrongName; } } if (messageType == null) { messageType = (string)pInMsg.Context.Read("MessageType", _systemPropertiesNamespace); //In cases where XmlDocument is used in orchestration, revert to check MessageType property = new ContextProperty("MessageType", _systemPropertiesNamespace); } if (messageType == null) { property = new ContextProperty("MessageType", _systemPropertiesNamespace); stream.MarkPosition(); //Thanks to http://maximelabelle.wordpress.com/2010/07/08/determining-the-type-of-an-xml-message-in-a-custom-pipeline-component/ messageType = Microsoft.BizTalk.Streaming.Utils.GetDocType(stream); stream.ResetPosition(); } TransformMetaData _map = FindFirstMapMatch(property, messageType); if (_map == null) { System.Diagnostics.Debug.WriteLine("No match for map could be made for message type: " + messageType); } else { pInMsg.BodyPart.Data = TransformMessage(stream, _map, pInMsg); pContext.ResourceTracker.AddResource(stream); } } return(pInMsg); }
/// <summary> /// Transforms original stream using streaming scalable transformation from BizTalk API. /// </summary> /// <param name="inputStream"></param> /// <returns></returns> internal Stream TransformMessage(Stream inputStream, TransformMetaData map, IBaseMessage pInMsg) { XsltArgumentList args = null; Context ext = null; SchemaMetadata targetSchema = targetSchema = map.TargetSchemas[0]; string portname = String.Empty; //It is possible to add a param but then you you need to work arounds in the map // map.ArgumentList.AddParam //The statement bellow caused me some problems that was solved by creating the XsltArgumentList instead //args = map.ArgumentList; try { ext = new Context(); for (int i = 0; i < pInMsg.Context.CountProperties; i++) { string name; string ns; string value = pInMsg.Context.ReadAt(i, out name, out ns).ToString(); ext.Add(name, value, ns); if (m_portDirection == PortDirection.receive && name == "ReceivePortName") { portname = value; } else if (m_portDirection == PortDirection.send && name == "SPName") { portname = value; } } //It is possible to add any information that should be available from the map ext.Add("MessageID", pInMsg.MessageID.ToString()); args = new XsltArgumentList(); //args.AddExtensionObject("http://www.w3.org/1999/XSL/Transform", ext); strangely it seams i cannot use this namespace in vs 2012, but it worked in vs 2010 args.AddExtensionObject("urn:schemas-microsoft-com:xslt", ext); AddParameters(args); //2017-08-23 Added intermidiate stream as Transform kills the original stream, //this is a problem if the incomming message is a enveloped message. XmlTranslatorStream stm = new XmlTranslatorStream(XmlReader.Create(inputStream)); VirtualStream outputStream = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk); XmlTextReader xmlTextReader = new XmlTextReader((TextReader) new StringReader(map.XmlContent)); BTSXslTransform btsXslTransform = new BTSXslTransform(); btsXslTransform.Load((XmlReader)xmlTextReader, new MemoryResourceResolver(portname, m_portDirection), (System.Security.Policy.Evidence)null); btsXslTransform.Transform(stm, args, outputStream, null); outputStream.Seek(0, SeekOrigin.Begin); pInMsg.Context.Promote("MessageType", _systemPropertiesNamespace, targetSchema.SchemaName); pInMsg.Context.Promote("SchemaStrongName", _systemPropertiesNamespace, targetSchema.ReflectedType.AssemblyQualifiedName); //pInMsg.MessageID.ToString() return(outputStream); } catch (Exception ex) { throw new ApplicationException(string.Format("Error while trying to transform using MapType specification: {0}", _mapName), ex); } }
internal TransformMetaData(Type transformBaseType) { this._transformBase = (TransformBase)Activator.CreateInstance(transformBaseType); this._xmlDecl = TransformMetaData._getXmlDeclaration(this._transformBase); }
public bool Equals(TransformMetaData obj) { return(obj != null && obj.AssemblyQualifiedName == this.AssemblyQualifiedName); }