using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using Xsd2Code.Library.Helpers; namespace Xsd2Code.Library { /// /// Encapsulation of all generation process. /// /// /// Revision history: /// /// Modified 2009-02-20 by Ruslan Urban /// Changed signature of the GeneratorFacade class constructor /// Updated result types to /// /// public class GeneratorFacade { /// /// Instance of CodeDom provider /// private CodeDomProvider providerField; #region Class constructor /// /// Initializes a new instance of the class. /// /// The input file. /// The name space. /// The language. /// Type of the collection. /// if set to true [enable data binding]. /// if set to true [hide private]. /// if set to true [enable summary comment]. /// The custom usings. /// The collection base. /// if set to true [include serialize method]. /// Name of the serialize method. /// Name of the deserialize method. /// Name of the save to file method. /// Name of the load from file method. /// if set to true [disable debug]. /// /// [Obsolete("Do not use", true)] public GeneratorFacade(string inputFile, string nameSpace, GenerationLanguage language, CollectionType collectionType, bool enableDataBinding, bool hidePrivate, bool enableSummaryComment, List customUsings, string collectionBase, bool includeSerializeMethod, string serializeMethodName, string deserializeMethodName, string saveToFileMethodName, string loadFromFileMethodName, bool disableDebug, bool implementCloneMethod, TargetFramework targetFramework) { var provider = CodeDomProviderFactory.GetProvider(language); this.Init(inputFile, nameSpace, provider, collectionType, enableDataBinding, hidePrivate, enableSummaryComment, customUsings, collectionBase, includeSerializeMethod, serializeMethodName, deserializeMethodName, saveToFileMethodName, loadFromFileMethodName, disableDebug, implementCloneMethod, targetFramework); } /// /// Initializes a new instance of the class. /// /// The input file. /// The name space. /// The provider. /// Type of the collection. /// if set to true [enable data binding]. /// if set to true [hide private]. /// if set to true [enable summary comment]. /// The custom usings. /// The collection base. /// if set to true [include serialize method]. /// Name of the serialize method. /// Name of the deserialize method. /// Name of the save to file method. /// Name of the load from file method. /// if set to true [disable debug]. /// /// public GeneratorFacade(string inputFile, string nameSpace, CodeDomProvider provider, CollectionType collectionType, bool enableDataBinding, bool hidePrivate, bool enableSummaryComment, List customUsings, string collectionBase, bool includeSerializeMethod, string serializeMethodName, string deserializeMethodName, string saveToFileMethodName, string loadFromFileMethodName, bool disableDebug, bool implementCloneMethod, TargetFramework targetFramework) { this.Init(inputFile, nameSpace, provider, collectionType, enableDataBinding, hidePrivate, enableSummaryComment, customUsings, collectionBase, includeSerializeMethod, serializeMethodName, deserializeMethodName, saveToFileMethodName, loadFromFileMethodName, disableDebug, implementCloneMethod, targetFramework); } public GeneratorFacade(GeneratorParams generatorParams) { var provider = CodeDomProviderFactory.GetProvider(generatorParams.Language); this.Init(provider, generatorParams); } /// /// Generator facade class constructor /// /// Code DOM provider /// Generator parameters public GeneratorFacade(CodeDomProvider provider, GeneratorParams generatorParams) { this.Init(provider, generatorParams); } /// /// Generator parameters /// public GeneratorParams GeneratorParams { get { return GeneratorContext.GeneratorParams; } } /// /// Initialize generator /// /// /// public void Init(CodeDomProvider provider, GeneratorParams generatorParams) { this.providerField = provider; GeneratorContext.GeneratorParams = generatorParams.Clone(); if (string.IsNullOrEmpty(GeneratorContext.GeneratorParams.OutputFilePath)) { string outputFilePath = Utility.GetOutputFilePath(generatorParams.InputFilePath, provider); GeneratorContext.GeneratorParams.OutputFilePath = outputFilePath; } } /// /// Initializes a new instance of the class. /// /// The input file. /// The name space. /// The provider. /// Type of the collection. /// if set to true [enable data binding]. /// if set to true [hide private]. /// if set to true [enable summary comment]. /// The custom usings. /// The collection base. /// if set to true [include serialize method]. /// Name of the serialize method. /// Name of the deserialize method. /// Name of the save to file method. /// Name of the load from file method. /// if set to true [disable debug]. /// /// public void Init(string inputFile, string nameSpace, CodeDomProvider provider, CollectionType collectionType, bool enableDataBinding, bool hidePrivate, bool enableSummaryComment, List customUsings, string collectionBase, bool includeSerializeMethod, string serializeMethodName, string deserializeMethodName, string saveToFileMethodName, string loadFromFileMethodName, bool disableDebug, bool implementCloneMethod, TargetFramework targetFramework) { GeneratorContext.GeneratorParams.InputFilePath = inputFile; GeneratorContext.GeneratorParams.NameSpace = nameSpace; GeneratorContext.GeneratorParams.CollectionObjectType = collectionType; GeneratorContext.GeneratorParams.EnableDataBinding = enableDataBinding; GeneratorContext.GeneratorParams.HidePrivateFieldInIde = hidePrivate; GeneratorContext.GeneratorParams.EnableSummaryComment = enableSummaryComment; GeneratorContext.GeneratorParams.CustomUsings = customUsings; GeneratorContext.GeneratorParams.CollectionBase = collectionBase; GeneratorContext.GeneratorParams.IncludeSerializeMethod = includeSerializeMethod; GeneratorContext.GeneratorParams.GenerateCloneMethod = implementCloneMethod; GeneratorContext.GeneratorParams.TargetFramework = targetFramework; GeneratorContext.GeneratorParams.SerializeMethodName = serializeMethodName; GeneratorContext.GeneratorParams.DeserializeMethodName = deserializeMethodName; GeneratorContext.GeneratorParams.SaveToFileMethodName = saveToFileMethodName; GeneratorContext.GeneratorParams.LoadFromFileMethodName = loadFromFileMethodName; GeneratorContext.GeneratorParams.DisableDebug = disableDebug; this.providerField = provider; string outputFilePath = Utility.GetOutputFilePath(inputFile, provider); GeneratorContext.GeneratorParams.OutputFilePath = outputFilePath; } #endregion #region Methods /// /// Generates the specified buffer size. /// /// return generated code into byte array public Result GenerateBytes() { string outputFilePath = Path.GetTempFileName(); var processResult = this.Process(outputFilePath); if (processResult.Success) { byte[] result = FileToByte(outputFilePath); try { File.Delete(outputFilePath); } catch (Exception ex) { processResult.Messages.Add(MessageType.Error, ex.Message); } return new Result(result, true, processResult.Messages); } return new Result(null, false, processResult.Messages); } /// /// Processes the code generation. /// /// true if sucess or false. public Result Generate(GeneratorParams generatorParams) { GeneratorContext.GeneratorParams = generatorParams; var outputFileName = GeneratorContext.GeneratorParams.OutputFilePath; var processResult = this.Process(outputFileName); return new Result(outputFileName, processResult.Success, processResult.Messages); } /// /// Processes the code generation. /// /// true if sucess or false. public Result Generate() { var outputFileName = GeneratorContext.GeneratorParams.OutputFilePath; var processResult = this.Process(outputFileName); return new Result(outputFileName, processResult.Success, processResult.Messages); } /// /// Convert file into byte[]. /// /// The full file path to convert info byte[]. /// return file content info byte[]. private static byte[] FileToByte(string path) { var infoFile = new FileInfo(path); using (var fileSteram = infoFile.OpenRead()) { var arrayOfByte = new byte[fileSteram.Length]; fileSteram.Read(arrayOfByte, 0, (int)fileSteram.Length); fileSteram.Close(); return arrayOfByte; } } /// /// Processes the specified file name. /// /// The output file path. /// true if sucess else false private Result Process(string outputFilePath) { #region Change CurrentDir for include schema resolution. string savedCurrentDir = Directory.GetCurrentDirectory(); var inputFile = new FileInfo(GeneratorContext.GeneratorParams.InputFilePath); if (!inputFile.Exists) { var errorMessage = string.Format("XSD File not found at location {0}\n", GeneratorContext.GeneratorParams.InputFilePath); errorMessage += "Exception :\n"; errorMessage += string.Format("Input file {0} not exist", GeneratorContext.GeneratorParams.InputFilePath); return new Result(false, MessageType.Error, errorMessage); } if (inputFile.Directory != null) Directory.SetCurrentDirectory(inputFile.Directory.FullName); #endregion try { try { var result = Generator.Process(GeneratorContext.GeneratorParams); if (!result.Success) return result; var ns = result.Entity; using (var outputStream = new StreamWriter(outputFilePath + ".tmp", false)) this.providerField.GenerateCodeFromNamespace(ns, outputStream, new CodeGeneratorOptions()); } catch (Exception e) { var errorMessage = "Failed to generate code\n"; errorMessage += "Exception :\n"; errorMessage += e.Message; Debug.WriteLine(string.Empty); Debug.WriteLine("XSD2Code - ----------------------------------------------------------"); Debug.WriteLine("XSD2Code - " + e.Message); Debug.WriteLine("XSD2Code - ----------------------------------------------------------"); Debug.WriteLine(string.Empty); return new Result(false, MessageType.Error, errorMessage); } var outputFile = new FileInfo(outputFilePath); if (outputFile.Exists) { if ((outputFile.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { var errorMessage = "Failed to generate code\n"; errorMessage += outputFilePath + " is write protect"; return new Result(false, MessageType.Error, errorMessage); } } #region Insert tag for future generation using (var outputStream = new StreamWriter(outputFilePath, false)) { string commentStr = GeneratorContext.GeneratorParams.Language == GenerationLanguage.CSharp ? "// " : "'' "; Assembly currentAssembly = Assembly.GetExecutingAssembly(); AssemblyName currentAssemblyName = currentAssembly.GetName(); outputStream.WriteLine( "{0}------------------------------------------------------------------------------", commentStr); outputStream.WriteLine(string.Format("{0} ", commentStr)); outputStream.WriteLine(string.Format("{0} Generated by Xsd2Code. Version {1}", commentStr, currentAssemblyName.Version)); string optionsLine = string.Format("{0} {1}", commentStr, GeneratorContext.GeneratorParams.ToXmlTag()); outputStream.WriteLine(optionsLine); outputStream.WriteLine("{0} ", commentStr); outputStream.WriteLine( "{0}------------------------------------------------------------------------------", commentStr); #endregion using (TextReader streamReader = new StreamReader(outputFilePath + ".tmp")) { string line; //DCM TODO Will refactor this to Not perform this last loop after verification that it works. while ((line = streamReader.ReadLine()) != null) { /* DCM REMOVED Language Specific Attribute removal Moved to CodeDOM Style in CodeExtension.ProcessClass() if (line.Trim() == "[System.SerializableAttribute()]" || line.Trim() == "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]") continue; if (GeneratorContext.GeneratorParams.DisableDebug) outputStream.WriteLine(line); else { if (line.Trim() != "[System.Diagnostics.DebuggerStepThroughAttribute()]") outputStream.WriteLine(line); } DCM REMOVED */ outputStream.WriteLine(line); } } outputStream.Close(); } try { var tempFile = new FileInfo(outputFilePath + ".tmp"); tempFile.Delete(); } catch (Exception ex) { return new Result(false, MessageType.Error, ex.Message); } } finally { Directory.SetCurrentDirectory(savedCurrentDir); } return new Result(true); } #endregion } }