2010-05-28 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Dispatcher / BaseRequestProcessor.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ServiceModel;
4 using System.ServiceModel.Channels;
5 using System.ServiceModel.Security;
6 using System.ServiceModel.Security.Tokens;
7 using System.Text;
8
9 namespace System.ServiceModel.Dispatcher
10 {
11         internal class BaseRequestProcessor
12         {
13                 HandlersChain initialize_handlers_chain = new HandlersChain();
14                 HandlersChain process_handlers_chain = new HandlersChain ();
15                 HandlersChain error_handlers_chain = new HandlersChain ();
16                 HandlersChain finalize_handlers_chain = new HandlersChain ();
17
18                 protected BaseRequestProcessor () { }
19
20                 protected virtual void ProcessRequest (MessageProcessingContext mrc)
21                 {
22                         initialize_handlers_chain.ProcessRequestChain (mrc);
23
24                         using (new OperationContextScope (mrc.OperationContext)) {
25                                 try {
26                                         process_handlers_chain.ProcessRequestChain (mrc);
27                                 }
28                                 catch (Exception e) {
29                                         // FIXME: this is not really expected use of ChannelDispatcher.ErrorHandlers.
30                                         // They are now correctly used in process_handler_chain (namely OperationInvokerHandler).
31                                         // For this kind of "outsider" exceptions are actually left thrown
32                                         // (and could even cause server loop crash in .NET).
33
34                                         Console.WriteLine ("Exception " + e.Message + " " + e.StackTrace);
35                                         mrc.ProcessingException = e;
36                                         error_handlers_chain.ProcessRequestChain (mrc);
37                                 }
38                                 finally {
39                                         finalize_handlers_chain.ProcessRequestChain (mrc);
40                                 }
41                         }
42                 }
43
44                 public HandlersChain InitializeChain
45                 {
46                         get { return initialize_handlers_chain; }
47                 }
48
49                 public HandlersChain ProcessingChain
50                 {
51                         get { return process_handlers_chain; }
52                 }
53
54                 public HandlersChain ErrorChain
55                 {
56                         get { return error_handlers_chain; }
57                 }
58
59                 public HandlersChain FinalizationChain
60                 {
61                         get { return finalize_handlers_chain; }
62                 }               
63         }
64
65         internal class HandlersChain
66         {
67                 BaseRequestProcessorHandler chain;
68
69                 public void ProcessRequestChain (MessageProcessingContext mrc)
70                 {
71                         if (chain != null)
72                                 chain.ProcessRequestChain (mrc);
73                 }
74
75                 public HandlersChain AddHandler (BaseRequestProcessorHandler handler)
76                 {
77                         if (chain == null) {
78                                 chain = handler;
79                         }
80                         else {
81                                 BaseRequestProcessorHandler current = chain;
82                                 while (current.Next != null)
83                                         current = current.Next;
84                                 current.Next = handler;
85                         }
86                         return this;
87                 }
88         }
89 }