internal static CodeNamespaceCollection GenerateCodeFromXomlDocument(Activity rootActivity, string filePath, string rootNamespace, SupportedLanguages language, IServiceProvider serviceProvider) { CodeNamespaceCollection codeNamespaces = new CodeNamespaceCollection(); CodeDomProvider codeDomProvider = CompilerHelpers.GetCodeDomProvider(language); // generate activity class string activityFullClassName = rootActivity.GetValue(WorkflowMarkupSerializer.XClassProperty) as string; CodeTypeDeclaration activityTypeDeclaration = null; if (codeDomProvider != null && !string.IsNullOrEmpty(activityFullClassName)) { // get class and namespace names string activityNamespaceName, activityClassName; Helpers.GetNamespaceAndClassName(activityFullClassName, out activityNamespaceName, out activityClassName); if (codeDomProvider.IsValidIdentifier(activityClassName)) { DesignerSerializationManager designerSerializationManager = new DesignerSerializationManager(serviceProvider); using (designerSerializationManager.CreateSession()) { ActivityCodeDomSerializationManager codeDomSerializationManager = new ActivityCodeDomSerializationManager(designerSerializationManager); TypeCodeDomSerializer typeCodeDomSerializer = codeDomSerializationManager.GetSerializer(rootActivity.GetType(), typeof(TypeCodeDomSerializer)) as TypeCodeDomSerializer; // get all activities bool generateCode = true; ArrayList allActivities = new ArrayList(); allActivities.Add(rootActivity); if (rootActivity is CompositeActivity) { foreach (Activity activity in Helpers.GetNestedActivities((CompositeActivity)rootActivity)) { if (Helpers.IsActivityLocked(activity)) continue; if (codeDomProvider.IsValidIdentifier(codeDomSerializationManager.GetName(activity))) { // WinOE Bug 14561. This is to fix a performance problem. When an activity is added to the activity // tree at the runtime, it's much faster if the ID of the activity is already set. The code that // the CodeDomSerializer generates will add the activity first before it sets the ID for the child // activity. We can change that order by always serializing the children first. Therefore, we // construct a list where we guarantee that the child will be serialized before its parent. allActivities.Insert(0, activity); } else { generateCode = false; break; } } } if (generateCode) { // Work around!! TypeCodeDomSerializer checks that root component has a site or not, otherwise it // does not serialize it look at ComponentTypeCodeDomSerializer.cs DummySite dummySite = new DummySite(); foreach (Activity nestedActivity in allActivities) ((IComponent)nestedActivity).Site = dummySite; ((IComponent)rootActivity).Site = dummySite; // create activity partial class activityTypeDeclaration = typeCodeDomSerializer.Serialize(codeDomSerializationManager, rootActivity, allActivities); activityTypeDeclaration.IsPartial = true; // add checksum attribute if (filePath != null && filePath.Length > 0) { MD5 md5 = new MD5CryptoServiceProvider(); byte[] checksumBytes = null; using (StreamReader streamReader = new StreamReader(filePath)) checksumBytes = md5.ComputeHash(streamReader.BaseStream); string checksum = string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}", new object[] { checksumBytes[0].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[1].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[2].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[3].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[4].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[5].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[6].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[7].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[8].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[9].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[10].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[11].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[12].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[13].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[14].ToString("X2", CultureInfo.InvariantCulture), checksumBytes[15].ToString("X2", CultureInfo.InvariantCulture) }); CodeAttributeDeclaration xomlSourceAttribute = new CodeAttributeDeclaration(typeof(WorkflowMarkupSourceAttribute).FullName); xomlSourceAttribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(filePath))); xomlSourceAttribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(checksum))); activityTypeDeclaration.CustomAttributes.Add(xomlSourceAttribute); } // create a new namespace and add activity class into that CodeNamespace activityCodeNamespace = new CodeNamespace(activityNamespaceName); activityCodeNamespace.Types.Add(activityTypeDeclaration); codeNamespaces.Add(activityCodeNamespace); } } } } // generate code for x:Code if (activityTypeDeclaration != null) { Queue activitiesQueue = new Queue(new object[] { rootActivity }); while (activitiesQueue.Count > 0) { Activity activity = (Activity)activitiesQueue.Dequeue(); if (Helpers.IsActivityLocked(activity)) continue; Queue childActivities = new Queue(new object[] { activity }); while (childActivities.Count > 0) { Activity childActivity = (Activity)childActivities.Dequeue(); if (childActivity is CompositeActivity) { foreach (Activity nestedChildActivity in ((CompositeActivity)childActivity).Activities) { childActivities.Enqueue(nestedChildActivity); } } // generate x:Code CodeTypeMemberCollection codeSegments = childActivity.GetValue(WorkflowMarkupSerializer.XCodeProperty) as CodeTypeMemberCollection; if (codeSegments != null) { foreach (CodeSnippetTypeMember codeSegmentMember in codeSegments) activityTypeDeclaration.Members.Add(codeSegmentMember); } } } if (language == SupportedLanguages.CSharp) activityTypeDeclaration.LinePragma = new CodeLinePragma((string)rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty), Math.Max((int)rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty), 1)); //Now make sure we that we also emit line pragma around the constructor CodeConstructor constructor = null; CodeMemberMethod method = null; foreach (CodeTypeMember typeMember in activityTypeDeclaration.Members) { if (constructor == null && typeMember is CodeConstructor) constructor = typeMember as CodeConstructor; if (method == null && typeMember is CodeMemberMethod && typeMember.Name.Equals("InitializeComponent", StringComparison.Ordinal)) method = typeMember as CodeMemberMethod; if (constructor != null && method != null) break; } if (constructor != null) constructor.LinePragma = new CodeLinePragma((string)rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty), Math.Max((int)rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty), 1)); if (method != null && language == SupportedLanguages.CSharp) method.LinePragma = new CodeLinePragma((string)rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty), Math.Max((int)rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty), 1)); } // generate mappings List<String> clrNamespaces = rootActivity.GetValue(WorkflowMarkupSerializer.ClrNamespacesProperty) as List<String>; if (clrNamespaces != null) { // foreach namespace add these mappings foreach (CodeNamespace codeNamespace in codeNamespaces) { foreach (string clrNamespace in clrNamespaces) { if (!String.IsNullOrEmpty(clrNamespace)) { CodeNamespaceImport codeNamespaceImport = new CodeNamespaceImport(clrNamespace); codeNamespaceImport.LinePragma = new CodeLinePragma((string)rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty), Math.Max((int)rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty), 1)); codeNamespace.Imports.Add(codeNamespaceImport); } } } } // return namespaces return codeNamespaces; }
internal static CodeNamespaceCollection GenerateCodeFromXomlDocument(Activity rootActivity, string filePath, string rootNamespace, SupportedLanguages language, IServiceProvider serviceProvider) { CodeNamespaceCollection namespaces = new CodeNamespaceCollection(); CodeDomProvider codeDomProvider = CompilerHelpers.GetCodeDomProvider(language); string str = rootActivity.GetValue(WorkflowMarkupSerializer.XClassProperty) as string; CodeTypeDeclaration declaration = null; if ((codeDomProvider != null) && !string.IsNullOrEmpty(str)) { string str2; string str3; Helpers.GetNamespaceAndClassName(str, out str2, out str3); if (codeDomProvider.IsValidIdentifier(str3)) { DesignerSerializationManager manager = new DesignerSerializationManager(serviceProvider); using (manager.CreateSession()) { ActivityCodeDomSerializationManager manager2 = new ActivityCodeDomSerializationManager(manager); TypeCodeDomSerializer serializer = manager2.GetSerializer(rootActivity.GetType(), typeof(TypeCodeDomSerializer)) as TypeCodeDomSerializer; bool flag = true; ArrayList list = new ArrayList(); list.Add(rootActivity); if (rootActivity is CompositeActivity) { foreach (Activity activity in Helpers.GetNestedActivities((CompositeActivity) rootActivity)) { if (!Helpers.IsActivityLocked(activity)) { if (codeDomProvider.IsValidIdentifier(manager2.GetName(activity))) { list.Insert(0, activity); } else { flag = false; break; } } } } if (flag) { DummySite site = new DummySite(); foreach (Activity activity2 in list) { activity2.Site = site; } rootActivity.Site = site; declaration = serializer.Serialize(manager2, rootActivity, list); declaration.IsPartial = true; if ((filePath != null) && (filePath.Length > 0)) { MD5 md = new MD5CryptoServiceProvider(); byte[] buffer = null; using (StreamReader reader = new StreamReader(filePath)) { buffer = md.ComputeHash(reader.BaseStream); } string str4 = string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}", new object[] { buffer[0].ToString("X2", CultureInfo.InvariantCulture), buffer[1].ToString("X2", CultureInfo.InvariantCulture), buffer[2].ToString("X2", CultureInfo.InvariantCulture), buffer[3].ToString("X2", CultureInfo.InvariantCulture), buffer[4].ToString("X2", CultureInfo.InvariantCulture), buffer[5].ToString("X2", CultureInfo.InvariantCulture), buffer[6].ToString("X2", CultureInfo.InvariantCulture), buffer[7].ToString("X2", CultureInfo.InvariantCulture), buffer[8].ToString("X2", CultureInfo.InvariantCulture), buffer[9].ToString("X2", CultureInfo.InvariantCulture), buffer[10].ToString("X2", CultureInfo.InvariantCulture), buffer[11].ToString("X2", CultureInfo.InvariantCulture), buffer[12].ToString("X2", CultureInfo.InvariantCulture), buffer[13].ToString("X2", CultureInfo.InvariantCulture), buffer[14].ToString("X2", CultureInfo.InvariantCulture), buffer[15].ToString("X2", CultureInfo.InvariantCulture) }); CodeAttributeDeclaration declaration2 = new CodeAttributeDeclaration(typeof(WorkflowMarkupSourceAttribute).FullName); declaration2.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(filePath))); declaration2.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(str4))); declaration.CustomAttributes.Add(declaration2); } CodeNamespace namespace2 = new CodeNamespace(str2); namespace2.Types.Add(declaration); namespaces.Add(namespace2); } } } } if (declaration != null) { Queue queue = new Queue(new object[] { rootActivity }); while (queue.Count > 0) { Activity activity3 = (Activity) queue.Dequeue(); if (!Helpers.IsActivityLocked(activity3)) { Queue queue2 = new Queue(new object[] { activity3 }); while (queue2.Count > 0) { Activity activity4 = (Activity) queue2.Dequeue(); if (activity4 is CompositeActivity) { foreach (Activity activity5 in ((CompositeActivity) activity4).Activities) { queue2.Enqueue(activity5); } } CodeTypeMemberCollection members = activity4.GetValue(WorkflowMarkupSerializer.XCodeProperty) as CodeTypeMemberCollection; if (members != null) { foreach (CodeSnippetTypeMember member in members) { declaration.Members.Add(member); } } } } } if (language == SupportedLanguages.CSharp) { declaration.LinePragma = new CodeLinePragma((string) rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty), Math.Max((int) rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty), 1)); } CodeConstructor constructor = null; CodeMemberMethod method = null; foreach (CodeTypeMember member2 in declaration.Members) { if ((constructor == null) && (member2 is CodeConstructor)) { constructor = member2 as CodeConstructor; } if (((method == null) && (member2 is CodeMemberMethod)) && member2.Name.Equals("InitializeComponent", StringComparison.Ordinal)) { method = member2 as CodeMemberMethod; } if ((constructor != null) && (method != null)) { break; } } if (constructor != null) { constructor.LinePragma = new CodeLinePragma((string) rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty), Math.Max((int) rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty), 1)); } if ((method != null) && (language == SupportedLanguages.CSharp)) { method.LinePragma = new CodeLinePragma((string) rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty), Math.Max((int) rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty), 1)); } } List<string> list2 = rootActivity.GetValue(WorkflowMarkupSerializer.ClrNamespacesProperty) as List<string>; if (list2 != null) { foreach (CodeNamespace namespace3 in namespaces) { foreach (string str5 in list2) { if (!string.IsNullOrEmpty(str5)) { CodeNamespaceImport import = new CodeNamespaceImport(str5) { LinePragma = new CodeLinePragma((string) rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty), Math.Max((int) rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty), 1)) }; namespace3.Imports.Add(import); } } } } return namespaces; }