Extension du composant de pipeline Désassembleur de fichier plat
L'exemple suivant montre comment créer un désassembleur personnalisé pour analyser les documents de fichier plat codés en UTF-7. Pour traiter des documents UTF-7, le composant hérite de la classe FFDasmComp , puis remplace sa méthode GetDataReader .
using System;
using System.Text;
using System.IO;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using Microsoft.BizTalk.ParsingEngine;
using Microsoft.BizTalk.Component;
using System.Runtime.InteropServices;
namespace Microsoft.BizTalk.Test
{
/// <summary>
/// Implements FF disassembler which always uses UTF-7 encoding.
/// </summary>
[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
[ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]
[ComponentCategory(CategoryTypes.CATID_Streamer)]
[Guid("A6E5F54F-7902-4e1a-84D8-5C7584F0ECF2")]
public class Utf7FFDasm :
FFDasmComp,
IBaseComponent
{
/// <summary>
/// Initializes a Utf7FFAsmDasm instance.
/// </summary>
public Utf7FFDasm()
{
}
/// <summary>
/// Name property
/// </summary>
public new string Name
{
get
{
return "UTF-7 FlatFile Disassembler";
}
}
/// <summary>
/// Version property
/// </summary>
public new string Version
{
get
{
return "1.0";
}
}
/// <summary>
/// Description property
/// </summary>
public new string Description
{
get
{
return "UTF-7 FlatFile Disassembler";
}
}
/// <summary>
/// Gets a data reader instance
/// </summary>
/// <param name="dataStream">Data stream</param>
/// <param name="dataEncoding">Data encoding</param>
/// <param name="detectEncodingFromByteOrderMarks">Detect encoding from a byte order mark</param>
/// <returns>IDataReader instance</returns>
protected override IDataReader GetDataReader(Stream dataStream, Encoding dataEncoding, bool detectEncodingFromByteOrderMarks)
{
// Delegate call to the base implementation passing fixed UTF-7 encoding
return base.GetDataReader(dataStream, Encoding.UTF7, false);
}
}
}
Exemple
L'exemple suivant montre comment créer un désassembleur personnalisé pour le traitement transactionnel des échanges de fichiers plats. Il diffère du désassembleur de fichier plat standard dans la mesure où il ne produit aucun document désassemblé avant le traitement complet de l'échange d'entrée. Cette implémentation de composant hérite de la classe FFDasmComp et remplace la méthode GetNext . Lors du premier appel à la méthode GetNext , il traite tous les messages de l’échange, les stocke dans une arrayList et retourne le premier message de arrayList. Lors des appels suivants, il retourne le message suivant à partir de ArrayList.
Notes
L'implémentation de la méthode GetNext() décrite dans l'exemple de code ci-après ne conviendrait pas en cas de documents volumineux, car l'échange est entièrement conservé en mémoire. En cas de documents volumineux, elle saturerait la mémoire et entraînerait une dégradation des performances ou un comportement instable.
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using Microsoft.BizTalk.Component;
namespace Microsoft.BizTalk.Component
{
/// <summary>
/// Summary description for Class1.
/// </summary>
[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
[ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]
[Guid("EB4714A8-FD97-43de-84E2-E011648F349B")]
public class TransactionalFFDasm :
FFDasmComp,
IBaseComponent,
IDisassemblerComponent
{
public TransactionalFFDasm()
{
}
#region IBaseComponent Members
public new string Description
{
get
{
return "Transactional Flat File Disassembler";
}
}
public new string Name
{
get
{
return "Transactional Flat File Disassembler";
}
}
public new string Version
{
get
{
return "1.0";
}
}
#endregion
#region IDisassemblerComponent Members
public new void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
{
base.Disassemble(pContext, pInMsg);
}
public new IBaseMessage GetNext(IPipelineContext pContext)
{
// Check if don't need to stop collecting messages
if (currentMessage == 0)
{
messageInterchange = new ArrayList();
currentMessage = 0;
// Collect messages from the standard disassembler
IBaseMessage disassembledMessage = null;
while ((disassembledMessage = base.GetNext(pContext)) != null)
{
byte[] buffer = new byte[4096];
int count = 0;
// Create a new memory stream to contain the disassembled message.
MemoryStream messageStream = new MemoryStream();
// Get a stream pointer to the disassembled stream.
Stream disassembledStream = disassembledMessage.BodyPart.GetOriginalDataStream();
// Write the disassembled message to the memory stream
while (0 != (count == disassembledStream.Read(buffer, 0, 4096)))
{
messageStream.Write(buffer, 0, count);
} // end-while
// Rewind the stream to the beginning
messageStream.Seek(0, SeekOrigin.Begin);
// Replace the stream on the disassembled message with the memory stream.
disassembledMessage.BodyPart.data = messageStream;
// Add this message to the ArrayList of messages.
messageInterchange.Add(disassembledMessage);
} // end-while
// Check if no messages were collected, just return nothing
if (0 == messageInterchange.Count)
return null;
} // end-if
// Check if all collected messages are returned
if (currentMessage == messageInterchange.Count)
return null;
// Return the current collected message
return (IBaseMessage)messageInterchange[currentMessage++];
} // end-method GetNext()
#endregion
private ArrayList messageInterchange = null;
private int currentMessage = 0;
}
}