File: MsmqIntegrationChannelFactory.cs

package info (click to toggle)
mono 4.6.2.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 778,148 kB
  • ctags: 914,052
  • sloc: cs: 5,779,509; xml: 2,773,713; ansic: 432,645; sh: 14,749; makefile: 12,361; perl: 2,488; python: 1,434; cpp: 849; asm: 531; sql: 95; sed: 16; php: 1
file content (178 lines) | stat: -rw-r--r-- 6,774 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//------------------------------------------------------------  
// Copyright (c) Microsoft Corporation.  All rights reserved.   
//------------------------------------------------------------  
namespace System.ServiceModel.MsmqIntegration
{
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Runtime.Serialization.Formatters.Binary; // for BinaryFormatter
    using System.Xml.Serialization; // for XmlSerializer 
    using System.IO; // for Stream
    using System.Collections.Specialized; //For HybridDictionary
    using System.ServiceModel.Channels;

    sealed class MsmqIntegrationChannelFactory : MsmqChannelFactoryBase<IOutputChannel>
    {
        ActiveXSerializer activeXSerializer;
        BinaryFormatter binaryFormatter;
        MsmqMessageSerializationFormat serializationFormat;
        HybridDictionary xmlSerializerTable;
        const int maxSerializerTableSize = 1024;

        internal MsmqIntegrationChannelFactory(MsmqIntegrationBindingElement bindingElement, BindingContext context)
            : base(bindingElement, context, null)
        {
            this.serializationFormat = bindingElement.SerializationFormat;
        }

        BinaryFormatter BinaryFormatter
        {
            get
            {
                if (this.binaryFormatter == null)
                {
                    lock (ThisLock)
                    {
                        if (this.binaryFormatter == null)
                            this.binaryFormatter = new BinaryFormatter();
                    }
                }

                return this.binaryFormatter;
            }
        }


        ActiveXSerializer ActiveXSerializer
        {
            get
            {
                if (this.activeXSerializer == null)
                {
                    lock (ThisLock)
                    {
                        if (this.activeXSerializer == null)
                            this.activeXSerializer = new ActiveXSerializer();
                    }
                }

                return this.activeXSerializer;
            }
        }


        XmlSerializer GetXmlSerializerForType(Type serializedType)
        {
            if (this.xmlSerializerTable == null)
            {
                lock (ThisLock)
                {
                    if (this.xmlSerializerTable == null)
                        this.xmlSerializerTable = new HybridDictionary();
                }
            }

            XmlSerializer serializer = (XmlSerializer)this.xmlSerializerTable[serializedType];
            if (serializer != null)
            {
                return serializer;
            }

            lock (ThisLock)
            {
                if (this.xmlSerializerTable.Count >= maxSerializerTableSize)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new CommunicationException(SR.GetString(SR.MsmqSerializationTableFull, maxSerializerTableSize)));
                // double-locking
                serializer = (XmlSerializer)this.xmlSerializerTable[serializedType];
                if (serializer != null)
                {
                    return serializer;
                }

                serializer = new XmlSerializer(serializedType);
                this.xmlSerializerTable[serializedType] = serializer;

                return serializer;
            }
        }


        public MsmqMessageSerializationFormat SerializationFormat
        {
            get
            {
                ThrowIfDisposed();
                return this.serializationFormat;
            }
        }

        protected override IOutputChannel OnCreateChannel(EndpointAddress to, Uri via)
        {
            base.ValidateScheme(via);
            return new MsmqIntegrationOutputChannel(this, to, via, ManualAddressing);
        }

        //
        // Returns stream containing serialized body
        // In case of MsmqMessageSerializationFormat.Stream,
        // returns body as Stream, and throws exception if body is not a Stream
        //
        internal Stream Serialize(MsmqIntegrationMessageProperty property)
        {
            Stream stream;
            switch (this.SerializationFormat)
            {
                case MsmqMessageSerializationFormat.Xml:
                    stream = new MemoryStream();
                    XmlSerializer serializer = GetXmlSerializerForType(property.Body.GetType());
                    serializer.Serialize(stream, property.Body);
                    return stream;

                case MsmqMessageSerializationFormat.Binary:
                    stream = new MemoryStream();
                    BinaryFormatter.Serialize(stream, property.Body);
                    // need to set BodyType to a magic number used by System.Messaging
                    property.BodyType = 0x300;
                    return stream;

                case MsmqMessageSerializationFormat.ActiveX:
                    if (property.BodyType.HasValue)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MsmqCannotUseBodyTypeWithActiveXSerialization)));
                    }

                    stream = new MemoryStream();
                    int bodyType = 0;
                    ActiveXSerializer.Serialize(stream as MemoryStream, property.Body, ref bodyType);
                    property.BodyType = bodyType;
                    return stream;

                case MsmqMessageSerializationFormat.ByteArray:
                    // body MUST be byte array
                    byte[] byteArray = property.Body as byte[];
                    if (byteArray == null)
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqByteArrayBodyExpected)));

                    stream = new MemoryStream();
                    stream.Write(byteArray, 0, byteArray.Length);
                    return stream;

                case MsmqMessageSerializationFormat.Stream:
                    // body MUST be a stream
                    Stream bodyStream = property.Body as Stream;
                    if (bodyStream == null)
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqStreamBodyExpected)));

                    // NOTE: we don't copy here as a perf optimization, but this might be dangerous
                    return bodyStream;

                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqUnsupportedSerializationFormat, this.SerializationFormat)));
            }

        }

    }
}