1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4 
5 namespace System.ServiceModel.Activities.Tracking
6 {
7     using System.Runtime.Remoting.Messaging;
8     using System.Runtime;
9     using System.Activities.Tracking;
10     using System.Collections.Specialized;
11     using System.Collections.ObjectModel;
12     using System.Configuration;
13     using System.ServiceModel.Configuration;
14     using System.ServiceModel.Activities.Tracking.Configuration;
15 
16     class DefaultProfileManager : TrackingProfileManager
17     {
18         ConfigFileProfileStore profileStore;
19 
DefaultProfileManager()20         public DefaultProfileManager()
21         {
22         }
23 
24         ConfigFileProfileStore ProfileStore
25         {
26             get
27             {
28                 if (this.profileStore == null)
29                 {
30                     this.profileStore = new ConfigFileProfileStore();
31                 }
32                 return this.profileStore;
33             }
34         }
35 
36 
Load(string profileName, string activityDefinitionId, TimeSpan timeout)37         public override TrackingProfile Load(string profileName, string activityDefinitionId, TimeSpan timeout)
38         {
39             if (profileName == null)
40             {
41                 throw FxTrace.Exception.ArgumentNull("profileName");
42             }
43             return this.GetProfile(profileName, activityDefinitionId);
44         }
45 
GetProfile(string profileName, string activityDefinitionId)46         internal TrackingProfile GetProfile(string profileName, string activityDefinitionId)
47         {
48             // Get all profiles from the store
49             Collection<TrackingProfile> profiles = this.ProfileStore.ReadProfiles();
50 
51             TrackingProfile bestMatch = null;
52             if (profiles != null)
53             {
54                 // Go through all the profiles in the data store and find a match to the requested profile
55                 foreach (TrackingProfile profile in profiles)
56                 {
57                     // Check the profile matches the requested name, and scope type
58                     if (string.Compare(profileName, profile.Name, StringComparison.OrdinalIgnoreCase) == 0)
59                     {
60                         // If we find a global scope profile, use it as the default profile
61                         if (string.Compare("*", profile.ActivityDefinitionId, StringComparison.OrdinalIgnoreCase) == 0)
62                         {
63                             if (bestMatch == null)
64                             {
65                                 bestMatch = profile;
66                             }
67                         }
68                         else if (string.Compare(activityDefinitionId, profile.ActivityDefinitionId, StringComparison.OrdinalIgnoreCase) == 0)
69                         {
70                             //specific profile for scopetarget found.
71                             bestMatch = profile;
72                             break;
73                         }
74                     }
75                 }
76             }
77             if (bestMatch == null)
78             {
79                 //Add a trace message indicating tracking profile with activity definiton id is not found
80                 if (TD.TrackingProfileNotFoundIsEnabled())
81                 {
82                     TD.TrackingProfileNotFound(profileName, activityDefinitionId);
83                 }
84 
85                 //If the profile is not found in config, return an empty profile to suppress
86                 //events. If .config does not have profiles, return null.
87                 bestMatch = new TrackingProfile()
88                 {
89                     ActivityDefinitionId = activityDefinitionId
90                 };
91             }
92 
93             return bestMatch;
94         }
95 
96 
97         class ConfigFileProfileStore
98         {
99             Collection<TrackingProfile> trackingProfiles;
100 
ReadProfiles()101             public Collection<TrackingProfile> ReadProfiles()
102             {
103                 if (this.trackingProfiles != null)
104                 {
105                     return this.trackingProfiles;
106                 }
107 
108                 TrackingSection trackingSection = null;
109 
110                 try
111                 {
112                     trackingSection =
113                         (TrackingSection)ConfigurationHelpers.GetSection(ConfigurationHelpers.GetSectionPath(TrackingConfigurationStrings.Tracking));
114                 }
115                 catch (ConfigurationErrorsException e)
116                 {
117                     if (!Fx.IsFatal(e))
118                     {
119                         FxTrace.Exception.TraceUnhandledException(e);
120                     }
121 
122                     throw;
123                 }
124 
125                 if (trackingSection == null)
126                 {
127                     return null;
128                 }
129 
130                 // Configuration elements are never null, collections are empty
131                 // and single elements are constructed with the property IsPresent=false
132                 this.trackingProfiles = new Collection<TrackingProfile>();
133 
134                 foreach (ProfileElement profileElement in trackingSection.Profiles)
135                 {
136                     if (profileElement.Workflows != null)
137                     {
138                         foreach (ProfileWorkflowElement workflowElement in profileElement.Workflows)
139                         {
140                             TrackingProfile profile = new TrackingProfile()
141                             {
142                                 Name = profileElement.Name,
143                                 ImplementationVisibility = profileElement.ImplementationVisibility,
144                                 ActivityDefinitionId = workflowElement.ActivityDefinitionId
145                             };
146 
147                             workflowElement.AddQueries(profile.Queries);
148 
149                             this.trackingProfiles.Add(profile);
150                         }
151                     }
152                 }
153 
154                 return this.trackingProfiles;
155             }
156 
157         }
158     }
159 }
160