Пример #1
0
        /// <summary>
        /// Save the applications topic, all subsequent child topics; also saves the Sandcastle content,
        /// token and project files.
        /// </summary>
        public override void Save()
        {
            TimerStart();
            SaveTopic();

            foreach (var topic in topics)
            {
                if (topic != null)
                {
                    topic.Save();
                }
            }

            //loopResult = Parallel.ForEach(topics, SaveAllTopics);
            base.Save();
            //save content file and add to the project
            ContentFile.GetContentFile().AddApplicationTopic(GetContentLayout());
            ContentFile.GetContentFile().Save(contentFile);
            ProjectFile.GetProjectFile().AddContentLayoutFile(contentFile);

            OrchestrationImage.Instance().StartSavingImages();
            OrchestrationImage.Instance().CancelToken.Cancel();

            //save token file and add to the project
            TokenFile.GetTokenFile().Save(tokenFile);
            ProjectFile.GetProjectFile().AddTokenFile(tokenFile);

            //save the project file
            ProjectFile.GetProjectFile().Save(projectFile);

            TimerStop();
        }
Пример #2
0
 public SendPortTopic(string btsAppName, string btsBaseDir, string btsSendPortName)
 {
     tokenId = CleanAndPrep(btsAppName + ".SendPorts." + btsSendPortName);
     TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
     appName           = btsAppName;
     topicRelativePath = btsBaseDir;
     sendPortName      = btsSendPortName;
 }
Пример #3
0
 public ReceivePortTopic(string btsAppName, string btsBaseDir, string btsReceivePortName)
 {
     rpName  = btsReceivePortName;
     appName = btsAppName;
     tokenId = btsAppName + ".ReceivePorts." + btsReceivePortName;
     TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
     topicRelativePath = btsBaseDir;
 }
Пример #4
0
 /// <summary>
 /// Create a new Sandcastle schemas topic.
 /// </summary>
 /// <param name="btsAppName">The BizTalk application name.</param>
 /// <param name="topicPath">The path to save the topic in.</param>
 /// <param name="schemaNames">A list of the full names of schemas to generate.</param>
 public SchemasTopic(string btsAppName, string topicPath, string[] schemaNames)
 {
     topicRelativePath = topicPath;
     appName           = btsAppName;
     schemas           = schemaNames;
     tokenId           = CleanAndPrep(btsAppName + ".Schemas");
     TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
     topics = new List <SchemaTopic>();
 }
Пример #5
0
 /// <summary>
 /// Creates a new Sandcastle topic for a BizTalk application.
 /// </summary>
 /// <param name="topicPath">The base path for the application topic.</param>
 /// <param name="btsAppName">The BizTalk application name.</param>
 public AppTopic(string topicPath, string btsAppName)
 {
     appName           = btsAppName;
     topicRelativePath = Path.Combine(topicPath, appName);
     buildTree();
     tokenId = CleanAndPrep(btsAppName);
     topics  = new List <TopicFile>();
     TokenFile.GetTokenFile().AddTopicToken(CleanAndPrep(tokenId), id);
 }
Пример #6
0
        public static TokenFile GetTokenFile()
        {
            if (tokenFile == null)
            {
                tokenFile = new TokenFile();
            }

            return(tokenFile);
        }
Пример #7
0
 public BusinessRulesTopic(string btsAppName, string baseDir, string[] rules)
 {
     policies          = rules;
     appName           = btsAppName;
     topicRelativePath = baseDir;
     topics            = new List <BusinessRuleTopic>();
     tokenId           = appName + ".BusinessRules";
     TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
 }
Пример #8
0
 public BusinessRuleTopic(string btsAppName, string basePath, string btsRuleName)
 {
     appName           = btsAppName;
     topicRelativePath = basePath;
     tokenId           = CleanAndPrep(appName + ".Policies." + btsRuleName);
     TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
     ruleName = btsRuleName;
     rulesDb  = ProjectConfiguration.RulesDatabase;
 }
 public ReceiveLocationsTopic(string btsAppName, string basePath, string[][] receiveLocations)
 {
     names             = receiveLocations;
     appName           = btsAppName;
     topicRelativePath = basePath;
     tokenId           = CleanAndPrep(btsAppName + ".ReceiveLocations");
     TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
     root = CreateDeveloperOrientationElement();
 }
Пример #10
0
 /// <summary>
 /// Creates a new Sandcastle orientation topic for BizTalk assemblies.
 /// </summary>
 /// <param name="basePath">The path to save the topic files.</param>
 /// <param name="btsAppName">The BizTalk application name.</param>
 /// <param name="assemblies">The BizTalk assemblies to document.</param>
 public AssembliesTopic(string basePath, string btsAppName, string[] assemblies)
 {
     resources = assemblies;
     tokenId   = CleanAndPrep(appName + ".Resources");
     TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
     assemblyTopics    = new List <AssemblyTopic>();
     appName           = btsAppName;
     topicRelativePath = basePath;
 }
Пример #11
0
 /// <summary>
 /// Creates a new Sandcastle schema documentation topic.
 /// </summary>
 /// <param name="btsAppName">The BizTalk application name.</param>
 /// <param name="topicPath">The path to where the topic should be saved.</param>
 /// <param name="btsSchemaName">The name of the schema to document.</param>
 public SchemaTopic(string btsAppName, string topicPath, string btsSchemaName)
 {
     appName           = btsAppName;
     schemaName        = btsSchemaName;
     topicRelativePath = topicPath;
     tokenId           = CleanAndPrep(appName + ".Schemas." + btsSchemaName);
     TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
     sb = new StringBuilder();
 }
Пример #12
0
 public ReceivePortsTopic(string btsAppName, string topicPath, string[] receivePorts)
 {
     ports             = receivePorts;
     tokenId           = CleanAndPrep(btsAppName + ".ReceivePorts");
     topicRelativePath = topicPath;
     appName           = btsAppName;
     TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
     topics = new List <ReceivePortTopic>();
 }
Пример #13
0
 public SendPortsTopic(string btsAppName, string btsBaseDir, string[] sendPortNames)
 {
     sendPorts         = sendPortNames;
     appName           = btsAppName;
     topicRelativePath = btsBaseDir;
     tokenId           = CleanAndPrep(btsAppName + ".SendPorts");
     TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
     topics = new List <SendPortTopic>();
     root   = CreateDeveloperOrientationElement();
 }
Пример #14
0
 /// <summary>
 /// Creates a new Sandcastle document for a BizTalk map artifact (transform).
 /// </summary>
 /// <param name="btsAppName">The BizTalk application name.</param>
 /// <param name="topicPath">The path to save the topic.</param>
 /// <param name="transforms">The full name of the BizTalk transforms to save.</param>
 public TransformsTopic(string btsAppName, string topicPath, string[] transforms)
 {
     maps = transforms;
     topicRelativePath = topicPath;
     appName           = btsAppName;
     tokenId           = CleanAndPrep(btsAppName + ".Transforms");
     TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
     topics        = new List <TransformTopic>();
     UsingParallel = true;
 }
Пример #15
0
 public TransformTopic(string btsAppName, string topicPath, string btsTransformName)
 {
     UsingParallel     = false;
     appName           = btsAppName;
     transformName     = btsTransformName;
     topicRelativePath = topicPath;
     tokenId           = CleanAndPrep(appName + ".Transforms." + btsTransformName);
     TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
     sb = new StringBuilder();
 }
Пример #16
0
 /// <summary>
 /// Creates a new instance of the <see cref="OrchestrationTopic"/> class.
 /// </summary>
 /// <param name="basePath">The base path of the Orchestration documentation folder.</param>
 /// <param name="btsAppName">The BizTalk application name.</param>
 /// <param name="btsOrchName">The orchestration to document in the BizTalk application.</param>
 public OrchestrationTopic(string basePath, string btsAppName, string btsOrchName)
 {
     try
     {
         topicRelativePath = basePath;
         appName           = btsAppName;
         tokenId           = CleanAndPrep(btsAppName + ".Orchestrations." + btsOrchName);
         TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
         orchName = btsOrchName;
     }
     catch (Exception ex)
     {
         PrintLine("[OrchestrationTopic] {0}: {1}", ex.GetType(), ex.Message);
     }
 }
Пример #17
0
 /// <summary>
 /// Creates a new instance of the <see cref="OrchestrationsTopic"/> class.
 /// </summary>
 /// <param name="topicPath">The base path of the Orchestrations documentation folder.</param>
 /// <param name="btsAppName">The BizTalk application name.</param>
 /// <param name="orchestrationNames">The <see cref="BtsOrchestration.FullName"/> of all of the orchestrations.</param>
 public OrchestrationsTopic(string topicPath, string btsAppName, string[] orchestrationNames)
 {
     try
     {
         topics            = new List <OrchestrationTopic>();
         orchNames         = orchestrationNames;
         topicRelativePath = topicPath;
         appName           = btsAppName;
         tokenId           = CleanAndPrep(appName + ".Orchestrations");
         //add token
         TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
         ReadyToSave = false;
     }
     catch (Exception ex)
     {
         HandleException("OrchestrationsTopic constructor", ex);
     }
 }
Пример #18
0
        private void SaveTopic()
        {
            //var bce = CatalogExplorerFactory.CatalogExplorer();
            try
            {
                //bce.ConnectionString = CatalogExplorerFactory.CatalogExplorer().ConnectionString;
                //get the object
                var assy = CatalogExplorerFactory.CatalogExplorer().Assemblies[assyName];
                tokenId = CleanAndPrep(appName + ".Assemblies." + assy.DisplayName);
                TokenFile.GetTokenFile().AddTopicToken(tokenId, id);
                displayName = assy.Name;
                var root = CreateDeveloperConceptualElement();

                //build the document structure

                #region assembly info

                root.Add(new XElement(xmlns + "section",
                                      new XElement(xmlns + "title", new XText("Assembly Information")),
                                      new XElement(xmlns + "content",
                                                   new XElement(xmlns + "table",
                                                                new XElement(xmlns + "tableHeader",
                                                                             new XElement(xmlns + "row",
                                                                                          new XElement(xmlns + "entry",
                                                                                                       new XText("Property")),
                                                                                          new XElement(xmlns + "entry",
                                                                                                       new XText("Value")))),
                                                                new XElement(xmlns + "row",
                                                                             new XElement(xmlns + "entry", new XText("Name")),
                                                                             new XElement(xmlns + "entry", new XText(assy.Name))),
                                                                new XElement(xmlns + "row",
                                                                             new XElement(xmlns + "entry", new XText("Display Name")),
                                                                             new XElement(xmlns + "entry",
                                                                                          new XText(assy.DisplayName))),
                                                                new XElement(xmlns + "row",
                                                                             new XElement(xmlns + "entry", new XText("Version")),
                                                                             new XElement(xmlns + "entry", new XText(assy.Version))),
                                                                new XElement(xmlns + "row",
                                                                             new XElement(xmlns + "entry",
                                                                                          new XText("Public Key Token")),
                                                                             new XElement(xmlns + "entry", assy.PublicKeyToken))))
                                      ));

                #endregion

                var elems = new List <XElement>();

                #region list orchestrations

                if (assy.Orchestrations.Count > 0)
                {
                    foreach (BtsOrchestration orchestration in assy.Orchestrations)
                    {
                        elems.Add(new XElement(xmlns + "listItem", new XElement(xmlns + "token", CleanAndPrep(appName + ".Orchestrations." + orchestration.FullName))));
                    }
                    var list = new XElement(xmlns + "list", new XAttribute("class", "bullet"), elems.ToArray());

                    root.Add(new XElement(xmlns + "section",
                                          new XElement(xmlns + "title", new XText("Orchestrations")),
                                          new XElement(xmlns + "content",
                                                       new XElement(xmlns + "para",
                                                                    new XText(
                                                                        "This assembly contains the following orchestrations:")),
                                                       list)));
                }

                #endregion

                #region list pipelines

                if (assy.Pipelines != null && assy.Pipelines.Count > 0)
                {
                    elems.Clear();
                    foreach (Pipeline pipeline in assy.Pipelines)
                    {
                        elems.Add(new XElement(xmlns + "listItem",
                                               new XElement(xmlns + "token", CleanAndPrep(pipeline.AssemblyQualifiedName))));
                    }
                    var list = new XElement(xmlns + "list", new XAttribute("class", "bullet"), elems.ToArray());
                    root.Add(AddListSection("Pipelines", "This assembly defines the following pipelines:", list));
                }

                #endregion

                #region port types

                //if (assy.PortTypes != null && assy.PortTypes.Count > 0)
                //{
                //    XElement list = new XElement(xmlns + "list", new XAttribute("class", "bullet"));
                //    foreach (PortType portType in assy.PortTypes)
                //    {
                //        list.Add(new XElement(xmlns + "listItem",
                //                              new XElement(xmlns + "token", CleanAndPrep(appName + ".PortTypes." + portType.FullName))));
                //    }
                //    root.Add(AddListSection("Port Types", "This assembly defines the following port types:", list));
                //}

                #endregion

                #region list schemas

                if (assy.Schemas != null && assy.Schemas.Count > 0)
                {
                    elems.Clear();
                    foreach (Schema schema in assy.Schemas)
                    {
                        elems.Add(new XElement(xmlns + "listItem", new XElement(xmlns + "token", CleanAndPrep(appName + ".Schemas." + schema.FullName))));
                    }

                    var list = new XElement(xmlns + "list", new XAttribute("class", "bullet"), elems.ToArray());
                    root.Add(AddListSection("Schemas", "This assembly contains the following schemas:", list));
                }

                #endregion list schemas

                #region list transforms

                if (assy.Transforms != null && assy.Transforms.Count > 0)
                {
                    foreach (Transform trans in assy.Transforms)
                    {
                        elems.Add(new XElement(xmlns + "listItem", new XElement(xmlns + "token", CleanAndPrep(appName + ".Transforms." + trans.FullName))));
                    }

                    var list = new XElement(xmlns + "list", new XAttribute("class", "bullet"), elems.ToArray());
                    root.Add(AddListSection("Transforms", "This assembly contains the following maps:", list));
                }

                #endregion

                if (doc.Root != null)
                {
                    doc.Root.Add(root);
                }
            }
            catch (Exception ex)
            {
                HandleException("BtsAssemblyTopic.DoWork", ex);
            }
        }
Пример #19
0
        private void SaveOrchestrationImages()
        {
            do
            {
                if (Orchestrations.Count == 0)
                {
                    Thread.Sleep(100);
                    continue;
                }
                try
                {
                    BtsOrch orch;
                    if (!Orchestrations.TryDequeue(out orch))
                    {
                        continue;
                    }
                    if (orch == null)
                    {
                        continue;
                    }

                    // notify the observer that we're working on the next image

                    if (_observer != null)
                    {
                        _observer.OnNext(this);
                    }

                    if (string.IsNullOrEmpty(orch.ApplicationName))
                    {
                        throw new NullReferenceException("Orchestration " + orch.Name + " has no BizTalk application assigned to it.");
                    }

                    if (string.IsNullOrEmpty(ProjectConfiguration.ImagesPath))
                    {
                        throw new NullReferenceException("ProjectConfiguration contains a null or empty image path.");
                    }

                    //make the image token closely match the orchestration token
                    var tokenId = CleanAndPrep(orch.ApplicationName + ".Orchestrations." + orch.Name);

                    var imageToken = tokenId + "Image";
                    var orn        = orch.Name.Replace(" ", string.Empty).Replace(",", string.Empty);

                    //set image ID
                    var imgGuid = Guid.NewGuid();

                    //set image path
                    var bmpFileName = orn + ".jpg";
                    var bmpPath     = Path.Combine(ProjectConfiguration.ImagesPath, bmpFileName);

                    //save the orchestration bitmap
                    using (var odv = new ODViewCtrl())
                    {
                        odv.AllowDrop = false;
                        odv.BackColor = Color.White;
                        odv.Size      = new Size(1024, 768);
                        odv.ShowSchedule(orch.ViewData.OuterXml);
                        odv.ResumeLayout(true);
                        odv.Controls.RemoveAt(0);
                        using (var pv = (ProcessView)odv.Controls[0].Controls[0])
                        {
                            var s = pv.PreferredSize;
                            odv.Size = s;

                            using (var bmp = new Bitmap(s.Width, s.Height))
                            {
                                lock (odv)
                                {
                                    odv.DrawToBitmap(bmp, new Rectangle(0, 0, s.Width, s.Height));
                                    using (var fs = new FileStream(bmpPath, FileMode.Create))
                                    {
                                        bmp.Save(fs, ImageFormat.Jpeg);
                                        fs.Close();
                                    }
                                }
                            }
                        }
                    }

                    //Save the new orchestration image info to the project
                    TokenFile.GetTokenFile().AddImageToken(imageToken, orch.Name, TokenFile.CaptionPlacement.after,
                                                           imgGuid.ToString(), TokenFile.ImagePlacement.center);
                    ProjectFile.GetProjectFile().AddImageItem(Path.Combine("images", bmpFileName), imgGuid.ToString());
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            } while (!CancelToken.IsCancellationRequested && Orchestrations.Count > 0);
        }
Пример #20
0
        void SaveTopic()
        {
            //var bce = CatalogExplorerFactory.CatalogExplorer();

            try
            {
                //bce.ConnectionString = CatalogExplorerFactory.CatalogExplorer().ConnectionString;
                ReceiveLocation rl = null;
                foreach (ReceivePort port in CatalogExplorerFactory.CatalogExplorer().Applications[appName].ReceivePorts)
                {
                    foreach (ReceiveLocation rloc in port.ReceiveLocations)
                    {
                        if (!rloc.Name.Equals(recLocName))
                        {
                            continue;
                        }
                        rl = rloc;
                        break;
                    }
                }

                root = CreateDeveloperConceptualElement();
                if (null == rl)
                {
                    return;
                }

                tokenId = CleanAndPrep(appName + ".ReceiveLocations." + rl.ReceivePort.Name + rl.Name);
                TokenFile.GetTokenFile().AddTopicToken(tokenId, id);

                var intro = new XElement(xmlns + "introduction",
                                         new XElement(xmlns + "para", new XText(string.IsNullOrEmpty(rl.Description) ? "No description was available for this receive location." : rl.Description)));

                var section = new XElement(xmlns + "section",
                                           new XElement(xmlns + "title", new XText("Receive Location Properties")),
                                           new XElement(xmlns + "content",
                                                        new XElement(xmlns + "table",
                                                                     new XElement(xmlns + "tableHeader",
                                                                                  new XElement(xmlns + "row",
                                                                                               new XElement(xmlns + "entry", new XText("Property")),
                                                                                               new XElement(xmlns + "entry", new XText("Value")))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Address")),
                                                                                  new XElement(xmlns + "entry", new XText(string.IsNullOrEmpty(rl.Address) ? "N/A" : rl.Address))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Custom Data")),
                                                                                  new XElement(xmlns + "entry", new XText(string.IsNullOrEmpty(rl.CustomData) ? "N/A" : rl.CustomData))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Enabled")),
                                                                                  new XElement(xmlns + "entry", new XText(rl.Enable.ToString()))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("End Date")),
                                                                                  new XElement(xmlns + "entry", new XText(rl.EndDate.ToString()))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("End Date Enabled")),
                                                                                  new XElement(xmlns + "entry", new XText(rl.EndDateEnabled.ToString()))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Fragment Messages")),
                                                                                  new XElement(xmlns + "entry", new XText(rl.FragmentMessages.ToString()))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("From Time")),
                                                                                  new XElement(xmlns + "entry", new XText(rl.FromTime.ToString()))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Public Address")),
                                                                                  new XElement(xmlns + "entry", new XText(string.IsNullOrEmpty(rl.PublicAddress) ? "N/A" : rl.PublicAddress))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Receive Handler Transport")),
                                                                                  new XElement(xmlns + "entry", new XText(null == rl.ReceiveHandler ? "N/A" : rl.ReceiveHandler.TransportType.Name))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Receive Pipeline")),
                                                                                  GetPipelineEntry(rl.ReceivePipeline)),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Receive Pipeline Data")),
                                                                                  new XElement(xmlns + "entry", new XText(string.IsNullOrEmpty(rl.ReceivePipelineData) ? "N/A" : rl.ReceivePipelineData))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Receive Port")),
                                                                                  new XElement(xmlns + "entry", new XElement(xmlns + "token", new XText(CleanAndPrep(appName + ".ReceivePorts." + rl.ReceivePort.Name))))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Send Pipeline")),
                                                                                  GetPipelineEntry(rl.SendPipeline)),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Send Pipeline Data")),
                                                                                  new XElement(xmlns + "entry", new XText(string.IsNullOrEmpty(rl.SendPipelineData) ? "N/A" : rl.SendPipelineData))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Service Window Enabled")),
                                                                                  new XElement(xmlns + "entry", new XText(rl.ServiceWindowEnabled.ToString()))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Start Date")),
                                                                                  new XElement(xmlns + "entry", new XText(rl.StartDate.ToString()))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Start Date Enabled")),
                                                                                  new XElement(xmlns + "entry", new XText(rl.StartDateEnabled.ToString()))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Transport Type Name")),
                                                                                  new XElement(xmlns + "entry", new XText(null == rl.TransportType ? "N/A" : rl.TransportType.Name))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Transport Type Capabilities")),
                                                                                  new XElement(xmlns + "entry", new XText(null == rl.TransportType ? "N/A" : rl.TransportType.Capabilities.ToString()))),
                                                                     new XElement(xmlns + "row",
                                                                                  new XElement(xmlns + "entry", new XText("Transport Type Data")),
                                                                                  new XElement(xmlns + "entry", new XText(string.IsNullOrEmpty(rl.TransportTypeData) ? "N/A" : rl.TransportTypeData)))
                                                                     )));

                root.Add(intro, section);
                if (doc.Root != null)
                {
                    doc.Root.Add(root);
                }
            }
            catch (Exception ex)
            {
                HandleException("ReceiveLocationTopic.DoWork", ex);
            }
        }
Пример #21
0
        /// <summary>
        /// Save a topic to the file system.
        /// </summary>
        /// <remarks>This method must be implemented in all inherited classes.</remarks>
        private void SaveTopic()
        {
            //var bce = CatalogExplorerFactory.CatalogExplorer();
            try
            {
                //bce.ConnectionString = CatalogExplorerFactory.CatalogExplorer().ConnectionString;

                var orch = CatalogExplorerFactory.CatalogExplorer().Applications[appName].Orchestrations[orchName];

                TokenFile.GetTokenFile().AddTopicToken(CleanAndPrep(appName + ".Orchestrations." + orchName), id);

                var root = CreateDeveloperConceptualElement();

                root.Add(new XElement(xmlns + "introduction",
                                      new XElement(xmlns + "para",
                                                   new XText(!string.IsNullOrEmpty(orch.Description)
                                                                 ? orch.Description
                                                                 : "No description was available from the orchestration."))));

                var orchSection = new XElement(xmlns + "section");

                #region content
                var content    = new XElement(xmlns + "content");
                var imageToken = CleanAndPrep(appName + ".Orchestrations." + orchName + "Image");
                content.Add(new XElement(xmlns + "token", imageToken),
                            new XElement(xmlns + "table", new XElement(xmlns + "title", new XText("Orchestration Properties")),
                                         new XElement(xmlns + "tableHeader",
                                                      new XElement(xmlns + "row",
                                                                   new XElement(xmlns + "entry",
                                                                                new XText(
                                                                                    "Property")),
                                                                   new XElement(xmlns + "entry",
                                                                                new XText("Value")))),
                                         new XElement(xmlns + "row",
                                                      new XElement(xmlns + "entry",
                                                                   new XText(
                                                                       "Application")),
                                                      new XElement(xmlns + "entry",
                                                                   new XElement(
                                                                       xmlns + "token",
                                                                       new XText(
                                                                           appName)))),
                                         new XElement(xmlns + "row",
                                                      new XElement(xmlns + "entry",
                                                                   new XText(
                                                                       "Assembly Qualified Name")),
                                                      new XElement(xmlns + "entry",
                                                                   new XElement(
                                                                       xmlns + "token",
                                                                       new XText(
                                                                           CleanAndPrep
                                                                               (orch.AssemblyQualifiedName))))),
                                         new XElement(xmlns + "row",
                                                      new XElement(xmlns + "entry",
                                                                   new XText(
                                                                       "Auto Resume Suspended Instances")),
                                                      new XElement(xmlns + "entry",
                                                                   new XText(
                                                                       orch.
                                                                       AutoResumeSuspendedInstances
                                                                       .ToString()))),
                                         new XElement(xmlns + "row",
                                                      new XElement(xmlns + "entry",
                                                                   new XText(
                                                                       "Auto Suspend Running Instances")),
                                                      new XElement(xmlns + "entry",
                                                                   new XText(
                                                                       orch.
                                                                       AutoSuspendRunningInstances
                                                                       .ToString()))),
                                         new XElement(xmlns + "row",
                                                      new XElement(xmlns + "entry",
                                                                   new XText(
                                                                       "Auto Terminate Instances (when unenlisting)")),
                                                      new XElement(xmlns + "entry",
                                                                   new XText(
                                                                       orch.
                                                                       AutoTerminateInstances
                                                                       .ToString()))),
                                         new XElement(xmlns + "row",
                                                      new XElement(xmlns + "entry",
                                                                   new XText(
                                                                       "Full Name")),
                                                      new XElement(xmlns + "entry",
                                                                   new XText(
                                                                       orch.FullName))),
                                         new XElement(xmlns + "row",
                                                      new XElement(xmlns + "entry",
                                                                   new XText("Host")),
                                                      GetNullable(orch.Host, "Name", appName + ".Host.")),
                                         new XElement(xmlns + "row",
                                                      new XElement(xmlns + "entry",
                                                                   new XText(
                                                                       "Tracking")),
                                                      new XElement(xmlns + "entry",
                                                                   new XText(
                                                                       orch.Tracking.
                                                                       ToString())))));
                orchSection.Add(content);
                #endregion

                root.Add(orchSection);

                #region port section
                var portSections = new List <XElement>();
                var opsList      = new XElement(xmlns + "list", new XAttribute("class", "bullet"));

                foreach (OrchestrationPort port in orch.Ports)
                {
                    if (port.Orchestration.FullName != orchName)
                    {
                        continue;
                    }
                    foreach (PortTypeOperation operation in port.PortType.Operations)
                    {
                        opsList.Add(new XElement(xmlns + "listItem",
                                                 new XText(string.Format("{0} ({1})", operation.Name, operation.Type))));
                    }

                    var ps = new XElement(xmlns + "section",
                                          new XElement(xmlns + "title", new XText(port.Name)),
                                          new XElement(xmlns + "content",
                                                       new XElement(xmlns + "para",
                                                                    new XText(
                                                                        "This port contains the following properties:")),
                                                       new XElement(xmlns + "table",
                                                                    new XElement(xmlns + "title",
                                                                                 new XText("Port Properties")),
                                                                    new XElement(xmlns + "tableHeader",
                                                                                 new XElement(xmlns + "row",
                                                                                              new XElement(
                                                                                                  xmlns +
                                                                                                  "entry",
                                                                                                  new XText
                                                                                                      ("Property")),
                                                                                              new XElement(
                                                                                                  xmlns +
                                                                                                  "entry",
                                                                                                  new XText
                                                                                                      ("Value")))),
                                                                    new XElement(xmlns + "row",
                                                                                 new XElement(xmlns + "entry",
                                                                                              new XText(
                                                                                                  "Binding")),
                                                                                 new XElement(xmlns + "entry",
                                                                                              new XText(
                                                                                                  port.Binding.
                                                                                                  ToString()))),
                                                                    new XElement(xmlns + "row",
                                                                                 new XElement(xmlns + "entry",
                                                                                              new XText(
                                                                                                  "Modifier")),
                                                                                 new XElement(xmlns + "entry",
                                                                                              new XText(
                                                                                                  port.Modifier
                                                                                                  .ToString
                                                                                                      ()))),
                                                                    new XElement(xmlns + "row",
                                                                                 new XElement(xmlns + "entry",
                                                                                              new XText
                                                                                                  ("Receive Port")),
                                                                                 GetNullable(port.ReceivePort,
                                                                                             "Name",
                                                                                             appName +
                                                                                             ".ReceivePorts.")),
                                                                    new XElement(xmlns + "row",
                                                                                 new XElement(xmlns + "entry",
                                                                                              new XText(
                                                                                                  "Send Port")),
                                                                                 GetNullable(port.SendPort,
                                                                                             "Name",
                                                                                             appName +
                                                                                             ".SendPorts.")),
                                                                    new XElement(xmlns + "row",
                                                                                 new XElement(xmlns + "entry",
                                                                                              new XText(
                                                                                                  "Send Port Group")),
                                                                                 GetNullable(
                                                                                     port.SendPortGroup, "Name",
                                                                                     appName +
                                                                                     ".SendPortGroups."))),
                                                       new XElement(xmlns + "para", new XText("This port definition performs the following operations:")),
                                                       opsList));
                    portSections.Add(ps);
                }

                #endregion

                root.Add(new XElement(xmlns + "section",
                                      new XElement(xmlns + "title", new XText("Orchestration Ports")),
                                      new XElement(xmlns + "content",
                                                   new XElement(xmlns + "sections", portSections.ToArray()))));

                if (doc.Root != null)
                {
                    doc.Root.Add(root);
                }
                OrchestrationImage.Instance().Orchestrations.Enqueue(new BtsOrch(orch.Application.Name, orch.FullName));
            }
            catch (Exception ex)
            {
                PrintLine("{0}: {1}", ex.GetType(), ex.Message);
            }
        }