//Manager class records the various blocks so it can split them up
classManager {private classBlock {publicString Name;public intStart, Length;
}privateBlock currentBlock;private List files = new List();private Block footer = newBlock();private Block header = newBlock();privateITextTemplatingEngineHost host;privateStringBuilder template;protected List generatedFileNames = new List();public staticManager Create(ITextTemplatingEngineHost host, StringBuilder template) {return (host is IServiceProvider) ? new VSManager(host, template) : newManager(host, template);
}public voidStartNewFile(String name) {if (name == null)throw new ArgumentNullException("name");
CurrentBlock= new Block { Name =name };
}public voidStartFooter() {
CurrentBlock=footer;
}public voidStartHeader() {
CurrentBlock=header;
}public voidEndBlock() {if (CurrentBlock == null)return;
CurrentBlock.Length= template.Length -CurrentBlock.Start;if (CurrentBlock != header && CurrentBlock !=footer)
files.Add(CurrentBlock);
currentBlock= null;
}public virtual void Process(boolsplit) {if(split) {
EndBlock();
String headerText=template.ToString(header.Start, header.Length);
String footerText=template.ToString(footer.Start, footer.Length);
String outputPath=Path.GetDirectoryName(host.TemplateFile);
files.Reverse();foreach(Block block infiles) {
String fileName=Path.Combine(outputPath, block.Name);
String content= headerText + template.ToString(block.Start, block.Length) +footerText;
generatedFileNames.Add(fileName);
CreateFile(fileName, content);
template.Remove(block.Start, block.Length);
}
}
}protected virtual voidCreateFile(String fileName, String content) {if(IsFileContentDifferent(fileName, content))
File.WriteAllText(fileName, content);
}public virtualString GetCustomToolNamespace(String fileName) {return null;
}public virtualString DefaultProjectNamespace {get { return null; }
}protected boolIsFileContentDifferent(String fileName, String newContent) {return !(File.Exists(fileName) && File.ReadAllText(fileName) ==newContent);
}privateManager(ITextTemplatingEngineHost host, StringBuilder template) {this.host =host;this.template =template;
}privateBlock CurrentBlock {get { returncurrentBlock; }set{if (CurrentBlock != null)
EndBlock();if (value != null)
value.Start=template.Length;
currentBlock=value;
}
}private classVSManager: Manager {privateEnvDTE.ProjectItem templateProjectItem;privateEnvDTE.DTE dte;private ActioncheckOutAction;private Action>projectSyncAction;public overrideString DefaultProjectNamespace {get{return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString();
}
}public override String GetCustomToolNamespace(stringfileName) {return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
}public override void Process(boolsplit) {if (templateProjectItem.ProjectItems == null)return;base.Process(split);
projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames,null, null));
}protected override voidCreateFile(String fileName, String content) {if(IsFileContentDifferent(fileName, content)) {
CheckoutFileIfRequired(fileName);
File.WriteAllText(fileName, content);
}
}internalVSManager(ITextTemplatingEngineHost host, StringBuilder template)
:base(host, template) {var hostServiceProvider =(IServiceProvider) host;if (hostServiceProvider == null)throw new ArgumentNullException("Could not obtain IServiceProvider");
dte= (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE));if (dte == null)throw new ArgumentNullException("Could not obtain DTE from host");
templateProjectItem=dte.Solution.FindProjectItem(host.TemplateFile);
checkOutAction= (String fileName) =>dte.SourceControl.CheckOutItem(fileName);
projectSyncAction= (IEnumerable keepFileNames) =>ProjectSync(templateProjectItem, keepFileNames);
}private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerablekeepFileNames) {var keepFileNameSet = new HashSet(keepFileNames);var projectFiles = new Dictionary();var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.get_FileNames(0)) + ".";foreach(EnvDTE.ProjectItem projectItem intemplateProjectItem.ProjectItems)
projectFiles.Add(projectItem.get_FileNames(0), projectItem);//Remove unused items from the project
foreach(var pair inprojectFiles)if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix))
pair.Value.Delete();//Add missing files to the project
foreach(String fileName inkeepFileNameSet)if (!projectFiles.ContainsKey(fileName))
templateProjectItem.ProjectItems.AddFromFile(fileName);
}private voidCheckoutFileIfRequired(String fileName) {var sc =dte.SourceControl;if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName,null, null));
}
}
} #>