mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-20 17:24:00 -05:00
@@ -0,0 +1,387 @@
|
||||
<#@ template debug="false" hostspecific="true" language="C#" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#@ assembly name="System.Xml.dll" #>
|
||||
<#@ import namespace="System" #>
|
||||
<#@ import namespace="System.Globalization" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Xml" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ import namespace="System.IO" #>
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Composition;
|
||||
using Microsoft.SqlTools.ServiceLayer;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
|
||||
<#
|
||||
var directory = Path.GetDirectoryName(Host.TemplateFile);
|
||||
string xmlFile = Path.Combine(directory, "TreeNodeDefinition.xml");
|
||||
|
||||
/////////
|
||||
// TODO - is Generate all the ReverseDependencies needed?
|
||||
/////////
|
||||
// var allReverseDependencies = GetReverseDependencies(xmlFile);
|
||||
// WriteLine(" internal static class TreeNodeRules");
|
||||
// WriteLine(" {");
|
||||
// WriteLine(" internal static Dictionary<Type, IList<Type>> TypeReverseDependencyMap = new Dictionary<Type, IList<Type>>()");
|
||||
// WriteLine(" {");
|
||||
// foreach (var reverseDependencyKey in allReverseDependencies.Keys)
|
||||
// {
|
||||
// bool isFirstDependentType = true;
|
||||
// StringBuilder dependentListBuilder = new StringBuilder("{");
|
||||
// foreach (var dependentType in allReverseDependencies[reverseDependencyKey])
|
||||
// {
|
||||
// if (isFirstDependentType)
|
||||
// {
|
||||
// isFirstDependentType = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// dependentListBuilder.Append(",");
|
||||
// }
|
||||
//
|
||||
// dependentListBuilder.Append(string.Format(CultureInfo.InvariantCulture, " typeof({0})", dependentType));
|
||||
// }
|
||||
// dependentListBuilder.Append(" }");
|
||||
//
|
||||
// WriteLine(string.Format(CultureInfo.InvariantCulture, " {{ typeof({0}), new List<Type> {1} }}", reverseDependencyKey, dependentListBuilder.ToString()));
|
||||
// }
|
||||
// WriteLine(" };");
|
||||
// WriteLine(" }");
|
||||
// WriteLine("");
|
||||
|
||||
/////////
|
||||
// First generate all the TreeNodes
|
||||
/////////
|
||||
var allTreeNodes = GetUniqueTreeNodes(xmlFile);
|
||||
foreach (var TreeNode in allTreeNodes)
|
||||
{
|
||||
var name = TreeNode.GetAttribute("Name");
|
||||
WriteLine(string.Format(" internal sealed partial class {0} : SmoTreeNode", name));
|
||||
WriteLine(" {");
|
||||
WriteLine(string.Format(" public {0}() : base()", name));
|
||||
WriteLine(" {");
|
||||
WriteLine(" NodeValue = string.Empty;");
|
||||
WriteLine(string.Format(" this.NodeType = \"{0}\";", name.Replace("TreeNode", string.Empty)));
|
||||
WriteLine(string.Format(" this.NodeTypeId = NodeTypes.{0};", name.Replace("TreeNode", string.Empty)));
|
||||
WriteLine(" OnInitialize();");
|
||||
WriteLine(" }");
|
||||
WriteLine(" }");
|
||||
WriteLine("");
|
||||
}
|
||||
|
||||
/////////
|
||||
// Now generate all the ChildFactories
|
||||
/////////
|
||||
var allNodes = GetNodes(xmlFile);
|
||||
foreach (var type in allNodes)
|
||||
{
|
||||
XmlElement nodeElement = GetNodeElement(xmlFile, type);
|
||||
var imageAttr = nodeElement.GetAttribute("Image");
|
||||
var isAlwaysLeaf = nodeElement.GetAttributeNode("IsAlwaysLeaf");
|
||||
var baseClass = nodeElement.GetAttribute("BaseClass");
|
||||
var strategy = nodeElement.GetAttribute("Strategy");
|
||||
var ChildQuerierTypes = nodeElement.GetAttribute("ChildQuerierTypes");
|
||||
var TreeNode = nodeElement.GetAttribute("TreeNode");
|
||||
var isAsync = nodeElement.GetAttributeNode("IsAsyncLoad");
|
||||
var disableSort = nodeElement.GetAttributeNode("DisableSort");
|
||||
|
||||
string childFactoryBaseClass = "SmoChildFactoryBase";
|
||||
|
||||
// TODO Will we need alternative child factories? If so, add code here to support this
|
||||
|
||||
if (isAlwaysLeaf == null)
|
||||
{
|
||||
WriteLine(" [Export(typeof(ChildFactory))]");
|
||||
WriteLine(" [Shared]");
|
||||
|
||||
WriteLine(string.Format(" internal partial class {0}ChildFactory : {1}", type, childFactoryBaseClass));
|
||||
|
||||
WriteLine(" {");
|
||||
WriteLine(string.Format(" public override IEnumerable<string> ApplicableParents() {{ return new[] {{ \"{0}\" }}; }}", type));
|
||||
|
||||
List<XmlElement> children = GetChildren(xmlFile, type);
|
||||
if (children.Count > 0)
|
||||
{
|
||||
WriteLine("");
|
||||
WriteLine(" protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent)");
|
||||
WriteLine(" {");
|
||||
foreach (var child in children)
|
||||
{
|
||||
XmlElement childAsXmlElement = GetNodeElement(xmlFile, child.GetAttribute("Name"));
|
||||
if (childAsXmlElement == null)
|
||||
{
|
||||
// TODO SHould we error with clear message that this needs to be fixed?
|
||||
continue;
|
||||
}
|
||||
string childImage = childAsXmlElement.GetAttribute("Image");
|
||||
var msShippedOwned = childAsXmlElement.GetAttributeNode("IsMsShippedOwned");
|
||||
var validFor = childAsXmlElement.GetAttribute("ValidFor");
|
||||
|
||||
if (TreeNodeExists(xmlFile, child.GetAttribute("Name") + "TreeNode"))
|
||||
{
|
||||
WriteLine(string.Format(" currentChildren.Add(new {0}TreeNode {{ SortPriority = SmoTreeNode.NextSortPriority }} );", child.GetAttribute("Name")));
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine(" currentChildren.Add(new FolderNode {");
|
||||
WriteLine(string.Format(" NodeValue = {0},", childAsXmlElement.GetAttribute("LocLabel")));
|
||||
WriteLine(string.Format(" NodeType = \"{0}\",", "Folder"));
|
||||
WriteLine(string.Format(" NodeTypeId = NodeTypes.{0},", child.GetAttribute("Name")));
|
||||
|
||||
if (msShippedOwned != null)
|
||||
{
|
||||
WriteLine(" IsMsShippedOwned = true,");
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(validFor))
|
||||
{
|
||||
WriteLine(string.Format(" ValidFor = {0},", GetValidForFlags(validFor)));
|
||||
}
|
||||
WriteLine(" SortPriority = SmoTreeNode.NextSortPriority,");
|
||||
WriteLine(" });");
|
||||
}
|
||||
}
|
||||
WriteLine(" }");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(strategy))
|
||||
{
|
||||
string[] allTypes = ChildQuerierTypes.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
WriteLine("");
|
||||
WriteLine(" internal override Type[] ChildQuerierTypes");
|
||||
WriteLine(" {");
|
||||
WriteLine(" get");
|
||||
WriteLine(" {");
|
||||
if (!string.IsNullOrWhiteSpace(ChildQuerierTypes))
|
||||
{
|
||||
Write(" return new [] {");
|
||||
foreach (var typeToRe in allTypes)
|
||||
{
|
||||
Write(string.Format(" typeof({0}Querier),", typeToRe));
|
||||
}
|
||||
WriteLine(" };");
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(" return new Type[0];");
|
||||
}
|
||||
WriteLine(" }");
|
||||
WriteLine(" }");
|
||||
|
||||
WriteLine("");
|
||||
|
||||
WriteLine(" public override TreeNode CreateChild(TreeNode parent, object context)");
|
||||
WriteLine(" {");
|
||||
if (string.IsNullOrWhiteSpace(TreeNode))
|
||||
{
|
||||
WriteLine(" var child = new SmoTreeNode();");
|
||||
WriteLine(" child.IsAlwaysLeaf = true;");
|
||||
}
|
||||
else
|
||||
{
|
||||
var modelNodeChildren = GetNodeElement(xmlFile, TreeNode.Replace("TreeNode",string.Empty));
|
||||
WriteLine(string.Format(" var child = new {0}();", TreeNode));
|
||||
if (modelNodeChildren.ChildNodes.Count == 0)
|
||||
{
|
||||
WriteLine(" child.IsAlwaysLeaf = true;");
|
||||
}
|
||||
}
|
||||
if (disableSort != null)
|
||||
{
|
||||
WriteLine(" child.SortPriority = SmoTreeNode.NextSortPriority;");
|
||||
}
|
||||
WriteLine(" InitializeChild(child, context);");
|
||||
WriteLine(" return child;");
|
||||
WriteLine(" }");
|
||||
}
|
||||
else if (baseClass == "ModelBased")
|
||||
{
|
||||
WriteLine("");
|
||||
WriteLine(" internal override Type[] ChildQuerierTypes { get {return null;} }");
|
||||
WriteLine("");
|
||||
// TODO Is reverse engineering strategy every needed?
|
||||
// WriteLine(" protected override ReverseEngineeringStrategy Strategy { get {return ReverseEngineeringStrategy.None;} }");
|
||||
WriteLine("");
|
||||
WriteLine(" public override TreeNode CreateChild(TreeNode parent, object context)");
|
||||
WriteLine(" {");
|
||||
WriteLine(" return null;");
|
||||
WriteLine(" }");
|
||||
}
|
||||
|
||||
WriteLine(" }");
|
||||
WriteLine("");
|
||||
}
|
||||
}
|
||||
#>
|
||||
}
|
||||
|
||||
<#+
|
||||
public static string GetValidForFlags(string validForStr)
|
||||
{
|
||||
List<string> flags = new List<string>();
|
||||
if (validForStr.Contains("Sql2005"))
|
||||
{
|
||||
flags.Add("ValidForFlag.Sql2005");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("Sql2008"))
|
||||
{
|
||||
flags.Add("ValidForFlag.Sql2008");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("Sql2012"))
|
||||
{
|
||||
flags.Add("ValidForFlag.Sql2012");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("Sql2014"))
|
||||
{
|
||||
flags.Add("ValidForFlag.Sql2014");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("Sql2016"))
|
||||
{
|
||||
flags.Add("ValidForFlag.Sql2016");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("AzureV11"))
|
||||
{
|
||||
flags.Add("ValidForFlag.Azure");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("AzureV12"))
|
||||
{
|
||||
flags.Add("ValidForFlag.AzureV12");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("NotDebugInstance"))
|
||||
{
|
||||
flags.Add("ValidForFlag.NotDebugInstance");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("NotContainedUser"))
|
||||
{
|
||||
flags.Add("ValidForFlag.NotContainedUser");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("CanConnectToMaster"))
|
||||
{
|
||||
flags.Add("ValidForFlag.CanConnectToMaster");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("CanViewSecurity"))
|
||||
{
|
||||
flags.Add("ValidForFlag.CanViewSecurity");
|
||||
}
|
||||
|
||||
return string.Join("|", flags);
|
||||
}
|
||||
public static string[] GetNodes(string xmlFile)
|
||||
{
|
||||
List<string> typesList = new List<string>();
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
XmlNodeList treeTypes = doc.SelectNodes("/ServerExplorerTree/Node");
|
||||
if (treeTypes != null)
|
||||
{
|
||||
foreach (var type in treeTypes)
|
||||
{
|
||||
XmlElement element = type as XmlElement;
|
||||
if (element != null)
|
||||
{
|
||||
typesList.Add(element.GetAttribute("Name"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return typesList.ToArray();
|
||||
}
|
||||
|
||||
public static Dictionary<string, List<string>> GetReverseDependencies(string xmlFile)
|
||||
{
|
||||
Dictionary<string, List<string>> dependencyMap = new Dictionary<string, List<string>>();
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
XmlNodeList treeTypes = doc.SelectNodes("/ServerExplorerTree/ReverseDependencyList/ReverseDependency");
|
||||
if (treeTypes != null)
|
||||
{
|
||||
foreach (var type in treeTypes)
|
||||
{
|
||||
XmlElement element = type as XmlElement;
|
||||
if (element != null)
|
||||
{
|
||||
string typeName = element.GetAttribute("Type");
|
||||
string dependency = element.GetAttribute("DependsOn");
|
||||
List<string> dependenciesForType;
|
||||
if (dependencyMap.TryGetValue(typeName, out dependenciesForType))
|
||||
{
|
||||
dependenciesForType.Add(dependency);
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] allDepedencies = dependency.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
dependenciesForType = new List<string>();
|
||||
dependenciesForType.AddRange(allDepedencies);
|
||||
dependencyMap.Add(typeName, dependenciesForType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return dependencyMap;
|
||||
}
|
||||
|
||||
public static XmlElement GetNodeElement(string xmlFile, string nodeName)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
return (XmlElement)doc.SelectSingleNode(string.Format("/ServerExplorerTree/Node[@Name='{0}']", nodeName));
|
||||
}
|
||||
|
||||
public static bool TreeNodeExists(string xmlFile, string TreeNode)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
var found = (XmlElement)doc.SelectSingleNode(string.Format("/ServerExplorerTree/CodeGenOptions/UniqueTreeNode[@Name='{0}']", TreeNode));
|
||||
|
||||
return (found != null);
|
||||
}
|
||||
|
||||
public static List<XmlElement> GetUniqueTreeNodes(string xmlFile)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
|
||||
List<XmlElement> retElements = new List<XmlElement>();
|
||||
XmlNodeList nodeList = doc.SelectNodes("/ServerExplorerTree/CodeGenOptions/UniqueTreeNode");
|
||||
foreach (var item in nodeList)
|
||||
{
|
||||
XmlElement itemAsElement = item as XmlElement;
|
||||
if (itemAsElement != null)
|
||||
{
|
||||
retElements.Add(itemAsElement);
|
||||
}
|
||||
}
|
||||
return retElements;
|
||||
}
|
||||
|
||||
public static List<XmlElement> GetChildren(string xmlFile, string parentName)
|
||||
{
|
||||
XmlElement nodeElement = GetNodeElement(xmlFile, parentName);
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
|
||||
List<XmlElement> retElements = new List<XmlElement>();
|
||||
XmlNodeList nodeList = doc.SelectNodes(string.Format("/ServerExplorerTree/Node[@Name='{0}']/Child", parentName));
|
||||
foreach (var item in nodeList)
|
||||
{
|
||||
XmlElement itemAsElement = item as XmlElement;
|
||||
if (itemAsElement != null)
|
||||
{
|
||||
retElements.Add(itemAsElement);
|
||||
}
|
||||
}
|
||||
return retElements;
|
||||
}
|
||||
#>
|
||||
Reference in New Issue
Block a user