/// <summary> /// Entry point for SpMetal. /// </summary> /// <param name="args">Command-line arguments.</param> static void Main(string[] args) { // // Title including assembly version number. // Console.WriteLine("Bart De Smet SpMetal SharePoint List Definition Export version {0}", Assembly.GetEntryAssembly().GetName().Version); Console.WriteLine("Copyright (C) Bart De Smet 2007. All rights reserved.\n"); // // Parse arguments. // Args a = Args.Parse(args); // // Invalid arguments: display help information and exit. // if (a == null) { Console.WriteLine("No inputs specified\n"); string file = Assembly.GetEntryAssembly().GetName().Name + ".exe"; Console.WriteLine("Usage: {0} -url:<url> -list:<list> [-out:<file>]", file); Console.WriteLine(" {0} [-user:<user> -password:<password> [-domain:<domain>]]", new string(' ', file.Length)); Console.WriteLine(); Console.WriteLine(" -url:<url> URL to the root of the SharePoint site"); Console.WriteLine(" -list:<list> Name of the list"); Console.WriteLine(" -out:<file> Output file"); Console.WriteLine(); Console.WriteLine(" -user:<user> User name for connection to SharePoint site"); Console.WriteLine(" -password:<password> Password for connection to SharePoint site"); Console.WriteLine(" -domain:<domain> Domain for connection to SharePoint site"); return; } // // List definition XML; will be downloaded from server. // XmlNode lst; // // Try to connect to server. // try { Console.Write("Connecting to server... "); // // Create proxy object referring to the SharePoint lists.asmx service on the specified server. // Lists l = new Lists(); l.Url = a.Url.TrimEnd('/') + "/_vti_bin/lists.asmx"; // // Integrated authentication using current network credentials. // if (a.User == null) { l.Credentials = CredentialCache.DefaultNetworkCredentials; } // // Use specified credentials. // else { if (a.Domain == null) { l.Credentials = new NetworkCredential(a.User, a.Password); } else { l.Credentials = new NetworkCredential(a.User, a.Password, a.Domain); } } Console.WriteLine("Done"); // // Load schema from server using lists.asmx web service. // Console.Write("Loading schema... "); lst = l.GetList(a.List); Console.WriteLine("Done\n"); } catch (Exception ex) { Console.WriteLine("Failed\n"); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(ex.Message); Console.ResetColor(); Environment.Exit(-1); return; } // // Get general information of the list. // string listName = GetFriendlyName((string)lst.Attributes["Title"].Value); string listDescription = (string)lst.Attributes["Description"].Value; if (listDescription == "") { listDescription = null; } Guid listID = new Guid((string)lst.Attributes["ID"].Value); int version = int.Parse(lst.Attributes["Version"].Value); string path = (string)lst.Attributes["RootFolder"].Value; Console.Write("Processing list {0} ({1}) version {2}... ", listName, listID, version); // // Get fields. // XmlElement fields = lst["Fields"]; StringBuilder props = new StringBuilder(); int n = 0; foreach (XmlNode c in fields.ChildNodes) { // // Field ID (GUID). // XmlAttribute aID = c.Attributes["ID"]; string id = ""; if (aID != null) { id = new Guid(aID.Value).ToString(); } // // Field name. // string name = (string)c.Attributes["Name"].Value; string displayName = (string)c.Attributes["DisplayName"].Value; // // Field description. // XmlAttribute aDescription = c.Attributes["Description"]; string description = null; if (aDescription != null) { description = (string)aDescription.Value; } // // Field hidden? // XmlAttribute aHidden = c.Attributes["Hidden"]; bool hidden = false; if (aHidden != null) { hidden = bool.Parse(aHidden.Value); } // // Field read-only? // XmlAttribute aReadOnly = c.Attributes["ReadOnly"]; bool readOnly = false; if (aReadOnly != null) { readOnly = bool.Parse(aReadOnly.Value); } // // Field type. // string type = (string)c.Attributes["Type"].Value; bool calc = false; // // Calculated field. Use underlying type for mapping. // if (type == "Calculated") { type = (string)c.Attributes["ResultType"].Value; calc = true; } // // Field inherited from base type? // XmlAttribute aFromBaseType = c.Attributes["FromBaseType"]; bool fromBaseType = false; if (aFromBaseType != null) { fromBaseType = bool.Parse(aFromBaseType.Value); } // // Export only field that aren't hidden and aren't inherited from the base type. // if (!hidden && !fromBaseType) { // // Get underlying .NET type textual name for C# class generation. // Additional field might be required for multi-choice fields with fill-in choice. // bool additional; string bclType = GetType(c, out additional); // // Is the underlying type recognized and supported by the mapper? // if (bclType != null) { // // Read-only and calculated field require additional mapping attribute parameters. // StringBuilder extra = new StringBuilder(); if (readOnly) { extra.Append(", ReadOnly = true"); } if (calc) { extra.Append(", Calculated = true"); } // // Create helper field and refer to it in case a multi-choice fields with fill-in choice was detected. // The helper field has the same name as the .NET type (which will be an enum) suffixed with "Other". // string helper = null; if (additional) { helper = GetFriendlyName(bclType) + "Other"; extra.AppendFormat(", OtherChoice = \"{0}\"", helper); } // // Generate a property for the current field and append it to the properties output string. // props.AppendFormat(PROP, (description ?? displayName), bclType, GetFriendlyName(displayName), XmlConvert.DecodeName(name), type, id, extra.ToString()); // // Generate additional helper property if needed. // if (additional) { props.AppendFormat(CHOICEHELPERPROP, displayName, helper, XmlConvert.DecodeName(name), id); } // // Keep field count. // n++; } } } // // Print statistical information. // Console.WriteLine("Done"); Console.WriteLine("Exported {0} properties and {1} helper enums", n, enums.Count); Console.WriteLine(); // // Build file with class definition containing the properties and the helper enums. // Console.Write("Writing file {0}... ", a.File); StringBuilder output = new StringBuilder(); output.AppendFormat(CLASS, listName, props.ToString(), listName, listID.ToString(), version, (listDescription ?? listName), path); foreach (string e in enums) { output.Append(e); } // // Write to output file. // using (StreamWriter sw = File.CreateText(a.File)) { sw.WriteLine(output.ToString()); Console.WriteLine("Done"); } }
/// <summary> /// Entry point for SpMetal. /// </summary> /// <param name="args">Command-line arguments.</param> static void Main(string[] args) { // // Unhandled exception signaling. // AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(Error); // // Title including assembly version number. // Console.WriteLine("Bart De Smet SpMetal SharePoint List Definition Export version {0}", Assembly.GetEntryAssembly().GetName().Version); Console.WriteLine("Copyright (C) Bart De Smet 2007. All rights reserved.\n"); // // Parse arguments. // Args a = Args.Parse(args); // // Invalid arguments: display help information and exit. // if (a == null) { ShowSyntaxInfo(); return; } // // Entity generator. // EG.EntityGenerator gen = new EG.EntityGenerator( new EntityGeneratorArgs() { RunMode = a.RunMode, Connection = new Connection() { CustomAuthentication = a.User != null, Url = a.Url, User = a.User, Password = a.Password, Domain = a.Domain }, Namespace = a.Namespace, Language = (a.Language == "VB" ? Language.VB : Language.CSharp) } ); // // Pluralization setting. // List.AutoPluralize = a.Pluralize; // // Get SPML first. // XmlDocument spml = new XmlDocument(); // // Check run mode: online or offline. // if ((a.RunMode & RunMode.Online) == RunMode.Online) { try { spml.InnerXml = gen.GenerateSpml(a.Context, a.List).InnerXml; } catch (EntityGeneratorException ex) { Console.WriteLine("Failed to generate SPML. " + ex.Message); return; } } else if ((a.RunMode & RunMode.Offline) == RunMode.Offline) { try { spml.InnerXml = File.ReadAllText(a.In); } catch (XmlException ex) { Console.WriteLine("Invalid SPML file. " + ex.Message); return; } catch (IOException ex) { Console.WriteLine("Failed to read input file. " + ex.Message); return; } } else { Debug.Assert(false); } // // Just save the SPML. // if ((a.RunMode & RunMode.Export) == RunMode.Export) { // // Write to output file. // try { using (FileStream fs = File.Open(a.Xml, FileMode.Create, FileAccess.Write)) { XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.Encoding = Encoding.UTF8; using (XmlWriter writer = XmlWriter.Create(fs, settings)) { spml.WriteTo(writer); Console.WriteLine("Output written to {0}.", a.Xml); } } } catch (UnauthorizedAccessException ex) { Console.WriteLine("Failed to write ouput. " + ex.Message); return; } catch (IOException ex) { Console.WriteLine("Failed to write ouput. " + ex.Message); return; } } // // Create and save entity code. // else if ((a.RunMode & RunMode.CodeGen) == RunMode.CodeGen) { // // Generate code in the appropriate language. // CodeCompileUnit compileUnit; try { compileUnit = gen.GenerateCode(spml); } catch (EntityGeneratorException ex) { Console.WriteLine(ex.Message); if (ex.Data.Contains("messages")) { Console.WriteLine("\nSchema validation messages:"); foreach (var s in (List <ValidationEventArgs>)ex.Data["messages"]) { Console.WriteLine("- [{3}] {0} ({1},{2})", s.Message, s.Exception.LineNumber, s.Exception.LinePosition, s.Severity.ToString().ToUpper()); } } return; } CodeDomProvider cdp = CodeDomProvider.CreateProvider(a.Language); StringBuilder code = new StringBuilder(); TextWriter tw = new StringWriter(code); cdp.GenerateCodeFromCompileUnit(compileUnit, tw, null); // // Infer file name from list name if not specified on the command-line (v0.2.0.0). // if (a.Code == null || a.Code.Length == 0) { string file; if (!string.IsNullOrEmpty(a.Context)) { file = a.Context + "SharePointDataContext"; } else { XmlAttribute ctx = spml["SharePointDataContext"].Attributes["Name"]; if (ctx != null && !string.IsNullOrEmpty(ctx.Value)) { file = ctx.Value + "SharePointDataContext"; } else if (!string.IsNullOrEmpty(a.List)) { file = a.List; //TODO: non-GUID file name } else { file = Path.GetRandomFileName(); } } file += (a.Language == "CS" ? ".cs" : ".vb"); foreach (char c in Path.GetInvalidFileNameChars()) { file = file.Replace(c.ToString(), ""); } a.Code = file; } // // Write to output file. // try { using (StreamWriter sw = File.CreateText(a.Code)) { sw.WriteLine(code.ToString()); Console.WriteLine("Output written to {0}.", a.Code); } } catch (UnauthorizedAccessException ex) { Console.WriteLine("Failed to write ouput. " + ex.Message); return; } catch (IOException ex) { Console.WriteLine("Failed to write ouput. " + ex.Message); return; } } else { Debug.Assert(false); } }
/// <summary> /// Entry point for SpMetal. /// </summary> /// <param name="args">Command-line arguments.</param> static void Main(string[] args) { // // Title including assembly version number. // Console.WriteLine("Bart De Smet SpMetal SharePoint List Definition Export version {0}", Assembly.GetEntryAssembly().GetName().Version); Console.WriteLine("Copyright (C) Bart De Smet 2007. All rights reserved.\n"); // // Parse arguments. // Args a = Args.Parse(args); // // Invalid arguments: display help information and exit. // if (a == null) { Console.WriteLine("No inputs specified\n"); string file = Assembly.GetEntryAssembly().GetName().Name + ".exe"; Console.WriteLine("Usage: {0} -url:<url> -list:<list> [-out:<file>] [-language:<language>]", file); Console.WriteLine(" {0} [-user:<user> -password:<password> [-domain:<domain>]]", new string(' ', file.Length)); Console.WriteLine(); Console.WriteLine(" -url:<url> URL to the root of the SharePoint site"); Console.WriteLine(" -list:<list> Name of the list"); Console.WriteLine(" -out:<file> Output file"); Console.WriteLine(" -language:<language> Code language used for output (VB or CS)"); Console.WriteLine(" (Default: CS)"); Console.WriteLine(); Console.WriteLine(" -user:<user> User name for connection to SharePoint site"); Console.WriteLine(" -password:<password> Password for connection to SharePoint site"); Console.WriteLine(" -domain:<domain> Domain for connection to SharePoint site"); return; } // // Entity generator. // EntityGenerator gen = new EntityGenerator(); gen.Connecting += delegate(object sender, ConnectingEventArgs e) { Console.Write("Connecting to server... "); }; gen.Connected += delegate(object sender, ConnectedEventArgs e) { if (e.Succeeded) { Console.WriteLine("Done"); } else { Console.WriteLine("Failed\n"); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(e.Exception.Message); Console.ResetColor(); Environment.Exit(-1); } }; gen.LoadingSchema += delegate(object sender, LoadingSchemaEventArgs e) { Console.Write("Loading schema... "); }; gen.LoadedSchema += delegate(object sender, LoadedSchemaEventArgs e) { if (e.Succeeded) { Console.WriteLine("Done\n"); } else { Console.WriteLine("Failed\n"); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(e.Exception.Message); Console.ResetColor(); Environment.Exit(-1); } }; gen.ExportingSchema += delegate(object sender, ExportingSchemaEventArgs e) { Console.Write("Processing list {0} ({1}) version {2}... ", e.List, e.Identifier, e.Version); }; gen.ExportedSchema += delegate(object sender, ExportedSchemaEventArgs e) { if (e.Succeeded) { Console.WriteLine("Done"); Console.WriteLine("Exported {0} properties\n", e.PropertyCount); } else { Console.WriteLine("Failed\n"); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(e.Exception.Message); Console.ResetColor(); Environment.Exit(-1); } }; // // Create a queue of entities that allows to process Lookup field entities. // Queue <Entity> entities = new Queue <Entity>(); HashSet <string> encounteredEntities = new HashSet <string>(); Dictionary <Guid, string> map = new Dictionary <Guid, string>(); // // Generate the requested entity. // HashSet <string> forbiddenTypeNames = new HashSet <string>(); Entity entity = gen.Generate(a); // // Infer file name from list name if not specified on the command-line (v0.2.0.0). // if (a.File == null || a.File.Length == 0) { string file = entity.Name + (a.Language == "CS" ? ".cs" : ".vb"); foreach (char c in Path.GetInvalidFileNameChars()) { file = file.Replace(c.ToString(), ""); } a.File = file; } // // Build the code; import the namespaces required. // StringBuilder allCode = new StringBuilder(); if (a.Language == "CS") { allCode.Append(IMPORTS_CS); } else { allCode.Append(IMPORTS_VB); } // // Resolve all Lookup field references, recursively. // entities.Enqueue(entity); map.Add(entity.Id, entity.Name); //Patch for lists that reference themselves. No need to re-generate entity type. encounteredEntities.Add(entity.Name); while (entities.Count > 0) { entity = entities.Dequeue(); // // Patch the entity's Lookup fields by generating sub-entities. // StringBuilder code = new StringBuilder(); code.Append(entity.Code); foreach (string patch in entity.Lookups.Keys) { string lookupList = entity.Lookups[patch]; string lookupEntityName; if (map.ContainsKey(new Guid(lookupList))) { lookupEntityName = map[new Guid(lookupList)]; } else { a.List = lookupList; Entity lookupEntity = gen.Generate(a); lookupEntityName = lookupEntity.Name; map.Add(lookupEntity.Id, lookupEntity.Name); entities.Enqueue(lookupEntity); } code.Replace(patch, lookupEntityName); } entity.Code = code.ToString(); // // Append the code to the accumulated code buffer. // allCode.Append(entity.Code); } foreach (string e in gen.Enums) { allCode.Append(e); } // // Write to output file. // Console.Write("Writing file {0}... ", a.File); using (StreamWriter sw = File.CreateText(a.File)) { sw.WriteLine(allCode.ToString()); Console.WriteLine("Done"); } }