Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKB/HeuristicLab.Services.OKB.DataAccess/3.3/L2ST4.ttinclude @ 7544

Last change on this file since 7544 was 4276, checked in by swagner, 14 years ago

Integrated OKB data access layer (#1166)

File size: 30.4 KB
Line 
1<#@ assembly name="System.Core"
2#><#@ assembly name="System.Data.Linq"
3#><#@ assembly name="EnvDTE"
4#><#@ assembly name="System.Xml"
5#><#@ assembly name="System.Xml.Linq"
6#><#@ import namespace="System"
7#><#@ import namespace="System.CodeDom"
8#><#@ import namespace="System.CodeDom.Compiler"
9#><#@ import namespace="System.Collections.Generic"
10#><#@ import namespace="System.Data.Linq"
11#><#@ import namespace="System.Data.Linq.Mapping"
12#><#@ import namespace="System.IO"
13#><#@ import namespace="System.Linq"
14#><#@ import namespace="System.Reflection"
15#><#@ import namespace="System.Text"
16#><#@ import namespace="System.Xml.Linq"
17#><#@ import namespace="Microsoft.VisualStudio.TextTemplating"
18#><#+
19// L2ST4 - LINQ to SQL templates for T4 v0.82 - http://www.codeplex.com/l2st4
20// Copyright (c) Microsoft Corporation.  All rights reserved.
21// This source code is made available under the terms of the Microsoft Public License (MS-PL)
22
23// DBML Database element > code DataContext class
24class Data
25{
26  public XNamespace NS = "http://schemas.microsoft.com/linqtosql/dbml/2007";
27  public String BaseClassName { get; private set; }
28  public String ConnectSettingsObject { get; private set; }
29  public String ConnectSettingsProperty { get; private set; }
30  public String ContextName { get; private set; }
31  public String ContextNamespace { get; set; }
32  public String DatabaseName { get; private set; }
33  public String DbmlFileName { get; private set; }
34  public String EntityBase { get; private set; }
35  public String EntityNamespace { get; set; }
36  public List<Function> Functions { get; private set; }
37  public List<FunctionClass> FunctionClasses { get; private set; }
38  public bool Serialization { get; private set; }
39  public string SpecifiedContextNamespace { get; private set; }
40  public string SpecifiedEntityNamespace { get; private set; }
41  public TypeAttributes TypeAttributes { get; private set; }
42  public List<Table> Tables { get; private set; }
43  public List<TableClass> TableClasses { get; private set; }
44 
45  public Data(String dbmlFileName) {
46    DbmlFileName = dbmlFileName;
47    if (!File.Exists(DbmlFileName))
48      throw new Exception(String.Format("DBML file '{0}' could not be found.", DbmlFileName));
49    XElement xe = XDocument.Load(DbmlFileName).Root;
50    TableClasses = new List<TableClass>();
51    FunctionClasses = new List<FunctionClass>();
52   
53    foreach(XElement connection in xe.Elements(NS + "Connection")) {
54      ConnectSettingsObject = (String) connection.Attribute("SettingsObjectName");
55      ConnectSettingsProperty = (String) connection.Attribute("SettingsPropertyName");
56    }
57    BaseClassName = (String) xe.Attribute("BaseType") ?? "DataContext";
58    ContextName = (String) xe.Attribute("Class");
59    ContextNamespace = SpecifiedContextNamespace = (String) xe.Attribute("ContextNamespace");
60    DatabaseName = (String) xe.Attribute("Name") ?? "";
61    EntityBase = (String) xe.Attribute("EntityBase");
62    EntityNamespace = SpecifiedEntityNamespace = (String) xe.Attribute("EntityNamespace");
63    Serialization = (String) xe.Attribute("Serialization") == "Unidirectional";
64    TypeAttributes = Class.DecodeAccess((String) xe.Attribute("AccessModifier")) | Class.DecodeModifier((String) xe.Attribute("Modifier"));
65    Tables = (from t in xe.Elements(NS + "Table")
66      select new Table(this, t)).ToList();
67    Functions = (from f in xe.Elements(NS + "Function")
68      select new Function(this, f)).ToList();
69  }
70   
71  static internal Type GetType(String typeName, bool canBeNull) {
72    Type type = null;
73    switch(typeName) {
74      case "System.Xml.Linq.XElement": type = typeof(System.Xml.Linq.XElement); break;
75      case "System.Data.Linq.Binary": type = typeof(System.Data.Linq.Binary); break;
76      default: type = Type.GetType(typeName); break;
77    }
78    if (type == null)
79      type = new TypeStub(typeName);
80    if (type.IsValueType && canBeNull)
81      type = typeof(Nullable<>).MakeGenericType(type);
82    return type;
83  }
84}
85
86// DBML Table element > Base entity class, events & property on DataContext class
87class Table
88{
89  public TableClass BaseClass {
90    get { return Classes.First(); }
91  }
92  public IEnumerable<TableClass> Classes {
93    get { return Data.TableClasses.Where(c => c.Table == this); }
94  }
95  public Data Data { get; private set; }
96  private String member;
97  public String Member {
98    get { return member ?? Name; }
99    set { member = value; }
100  }
101  public String Name { get; set; }
102  public List<TableOperation> Operations { get; private set; }
103
104  public Table(Data data, XElement xe) {
105    Data = data;
106    Name = (String) xe.Attribute("Name");
107    Member = (String) xe.Attribute("Member");
108    Data.TableClasses.AddRange(from c in xe.Elements(Data.NS + "Type")
109      select new TableClass(this, c));
110    Operations = new List<TableOperation>();
111    foreach(OperationType operationType in Enum.GetValues(typeof(OperationType)))
112      Operations.AddRange((from o in xe.Elements(Data.NS + operationType.ToString() + "Function")
113        select new TableOperation(this, o)).ToList());
114  }
115}
116
117// DBML Type element > Entity class, subclasses or stored procedure return type
118class Class
119{
120  public Class SuperClass { get; protected set; }
121  public List<Column> Columns { get; private set; }
122  public Data Data {get; private set; }
123  public String Id { get; private set; }
124  public String InheritanceCode { get; private set; }
125  public Boolean IsInheritanceDefault { get; private set; }
126  public Boolean IsSerializable {
127    get { return (TypeAttributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public; }
128  }
129  protected String name;
130  public virtual String Name {
131    get { return name; }
132    set { name = value; }
133  }
134  public String QualifiedName {
135    get { return (String.IsNullOrEmpty(Data.EntityNamespace) || (Data.EntityNamespace == Data.ContextNamespace))
136        ? Name : Data.EntityNamespace + '.' + Name; }
137  }
138  public TypeAttributes TypeAttributes { get; private set; }
139 
140  public Class(Data data, XElement xe) {
141    Data = data;
142    Id = (String) xe.Attribute("Id");
143    InheritanceCode = (String) xe.Attribute("InheritanceCode");
144    IsInheritanceDefault = (Boolean ?) xe.Attribute("IsInheritanceDefault") ?? false;
145    Name = (String) xe.Attribute("Name");
146    TypeAttributes = DecodeAccess((String) xe.Attribute("AccessModifier")) | DecodeModifier((String) xe.Attribute("Modifier"));
147    Columns = (from c in xe.Elements(Data.NS + "Column")
148      select new Column(this, c)).ToList();
149  }
150 
151  internal static TypeAttributes DecodeAccess(String access) {
152    switch(access) {
153      case "Private": return TypeAttributes.NestedPrivate;
154      case "Internal": return TypeAttributes.NestedAssembly;
155      case "Protected": return TypeAttributes.NestedFamily;
156      case "ProtectedInternal": return TypeAttributes.NestedFamORAssem;
157      default: return TypeAttributes.Public;
158    }
159  }
160 
161  internal static TypeAttributes DecodeModifier(String modifier) {
162    switch(modifier) {
163      case "Abstract": return TypeAttributes.Abstract;
164      case "Sealed": return TypeAttributes.Sealed;
165      default: return TypeAttributes.Class;
166    }
167  }
168}
169
170// DBML Type element > Classes and subclasses that map to tables
171class TableClass : Class
172{
173  public List<Association> Associations { get; private set; }
174  public Boolean HasPrimaryKey {
175    get { return Columns.Any(c => c.IsPrimaryKey); }
176  }
177  public override String Name { get; set; }
178  public IList<Column> PrimaryKey {
179    get { return Columns.Where(c => c.IsPrimaryKey).ToList(); }
180  }
181  public MemberAttributes PropertyChangeAccess {
182    get { return ((TypeAttributes & TypeAttributes.Sealed) != 0) ? MemberAttributes.Private | MemberAttributes.Final : MemberAttributes.Public; }
183  }
184  public IEnumerable<TableClass> Subclasses {
185    get { return Table.Data.TableClasses.Where(c => c.SuperClass == this); }
186  }
187  public Table Table { get; private set; }
188
189  public TableClass(TableClass superClass, XElement xe) : this(superClass.Table, xe) {
190    SuperClass = superClass;
191  }
192
193  public TableClass(Table table, XElement xe) : base(table.Data, xe) {
194    Table = table;
195    Associations = (from a in xe.Elements(Data.NS + "Association")
196      select new Association(this, a)).ToList();
197    Table.Data.TableClasses.AddRange(from c in xe.Elements(Data.NS + "Type")
198      select new TableClass(this, c));
199  }
200}
201
202// DBML Type > Classes that map to stored procedure return types
203class FunctionClass : Class
204{
205  public Function Function { get; set; }
206 
207  public FunctionClass(Function function, XElement xe) : base(function.Data, xe) {
208    Function = function;
209  }
210}
211
212// DBML type Column > Properties on a class
213class Column
214{
215  private String member, typeName, storage;
216
217  private AutoSync autoSync;
218  public AutoSync AutoSync {
219    get {
220      if (IsDbGenerated)
221        if (IsPrimaryKey)
222          return AutoSync.OnInsert;
223        else
224          return AutoSync.Always;
225      return autoSync;
226    }
227    private set { autoSync = value; }
228  }
229  public Boolean CanBeNull { get; private set; }
230  public Class Class { get; private set; }
231  public String DbType { get; private set; }
232  public String Expression { get; private set; }
233  private Boolean isDbGenerated;
234  public Boolean IsDbGenerated {
235    get { return (!String.IsNullOrEmpty(Expression) || IsVersion) ? true : isDbGenerated;  }
236    private set { isDbGenerated = value; }
237  }
238  public Boolean IsDelayLoaded { get; private set; }
239  public Boolean IsDiscriminator { get; private set; }
240  public List<Association> ForeignKeyAssociations {
241    get {
242      if (Class is TableClass) {
243        return ((TableClass)Class).Associations.Where(a => a.ThisKey.Contains(this) && a.IsForeignKey).ToList();
244      }
245      else
246        return new List<Association>();
247    }
248  }
249  public Boolean IsPrimaryKey { get; private set; }
250  private Boolean isReadOnly;
251  public Boolean IsReadOnly {
252    get { return (Class.Data.Serialization) ? false : isReadOnly; }
253    private set { isReadOnly = value; }
254  }
255  public Boolean IsVersion { get; private set; }
256  public String Member {
257    get { return member + ((member == Class.Name) ? "1" : ""); }
258    set { member = value; }
259  }
260  public MemberAttributes MemberAttributes { get; private set; }
261  public String Name { get; private set; }
262  public String Storage {
263    get { return String.IsNullOrEmpty(storage) ? "_" + Member : storage; }
264    set { storage = value; }
265  }
266  public Type StorageType {
267    get { return (IsDelayLoaded) ? typeof(Link<>).MakeGenericType(Type) : Type; }
268  }
269  public String StorageValue {
270    get { return (IsDelayLoaded) ? Storage + ".Value" : Storage; }
271  }
272  public Type Type {
273    get { return Data.GetType(typeName, CanBeNull); }
274  }
275  private UpdateCheck updateCheck;
276  public UpdateCheck UpdateCheck {
277    get { return (IsReadOnly) ? UpdateCheck.Never : updateCheck; }
278    private set { updateCheck = value; }
279  }
280 
281  public Column(Class class1, XElement xe) {
282    Class = class1;
283    Name = (String) xe.Attribute("Name") ?? "";
284    Member = (String) xe.Attribute("Member") ?? Name;
285    typeName = xe.Attribute("Type").Value;
286    CanBeNull = (Boolean?) xe.Attribute("CanBeNull") ?? false;
287    DbType = (String) xe.Attribute("DbType") ?? "";
288    Expression = (String) xe.Attribute("Expression") ?? "";
289    IsDbGenerated = (Boolean?) xe.Attribute("IsDbGenerated") ?? (IsVersion);
290    IsDelayLoaded = (Boolean?) xe.Attribute("IsDelayLoaded") ?? false;
291    IsDiscriminator = (Boolean?) xe.Attribute("IsDiscriminator") ?? false;
292    IsPrimaryKey = (Boolean?) xe.Attribute("IsPrimaryKey") ?? false;
293    IsReadOnly = (Boolean?) xe.Attribute("IsReadOnly") ?? false;
294    IsVersion = (Boolean?) xe.Attribute("IsVersion") ?? false;
295    Storage = (String) xe.Attribute("Storage") ?? "";
296    AutoSync autoSyncDefault = (IsDbGenerated) ? AutoSync.OnInsert : AutoSync.Default;
297    AutoSync = Util.ParseEnum((String) xe.Attribute("AutoSync"), (IsVersion) ? AutoSync.Always : autoSyncDefault);
298    UpdateCheck = Util.ParseEnum((String) xe.Attribute("UpdateCheck"), (IsVersion || IsPrimaryKey) ? UpdateCheck.Never : UpdateCheck.Always);
299    MemberAttributes = Util.DecodeMemberAccess((String) xe.Attribute("AccessModifier")) | Util.DecodeMemberModifier((String) xe.Attribute("Modifier"));
300  }
301}
302
303// DBML Association element > EntitySet or EntityRef between two table-mapped classes
304class Association
305{
306  private TableClass thisClass;
307  private String typeName, storage;
308
309  public Association OtherSide {
310    get { return Type.Associations.Find(a => a.Name == Name && a != this); }
311  }
312  public Boolean DeleteOnNull { get; private set; }
313  public String DeleteRule { get; private set; }
314  public Boolean IsForeignKey { get; private set; }
315  public Boolean IsMany { get; private set; }
316  public Boolean IsSerializable {
317    get { return ((MemberAttributes & MemberAttributes.AccessMask) == MemberAttributes.Public); }
318  }
319  public Boolean IsUnique {
320    get { return (!IsMany && !IsForeignKey); }
321  }
322  public Boolean ManagesKeys {
323    get { return !(IsMany || (OtherSide == null) || !IsForeignKey); }
324  }
325  public String Member { get; private set; }
326  public MemberAttributes MemberAttributes { get; private set; }
327  public String Name { get; private set; }
328  public IList<Column> OtherKey {
329    get { return OtherKeyMembers.Select(o => Type.Columns.Single(c => c.Member == o)).ToList(); }
330  }
331  private String[] otherKeyMembers;
332  public String[] OtherKeyMembers {
333    get { return (otherKeyMembers != null) ? otherKeyMembers : Type.PrimaryKey.Select(p => p.Member).ToArray(); }
334    set { otherKeyMembers = value; }
335  }
336  public String Storage { get { return storage ?? "_" + Member; } }
337  public IList<Column> ThisKey {
338    get { return ThisKeyMembers.Select(o => thisClass.Columns.Single(c => c.Member == o)).ToList(); }
339  }
340  private String[] thisKeyMembers;
341  public String[] ThisKeyMembers {
342    get { return (thisKeyMembers != null) ? thisKeyMembers : thisClass.PrimaryKey.Select(p => p.Member).ToArray(); }
343    set { thisKeyMembers = value; }
344  }
345  public TableClass Type {
346    get { return thisClass.Table.Data.TableClasses.Find(c => c.Name == typeName); }
347  }
348 
349  public Association(TableClass thisClass, XElement xe) {
350    this.thisClass = thisClass;
351    typeName = (String) xe.Attribute("Type");
352    String thisKey = ((String) xe.Attribute("ThisKey"));
353    if (thisKey != null)
354      thisKeyMembers = thisKey.Split(',');
355    storage = (String) xe.Attribute("Storage");
356    String otherKey = ((String) xe.Attribute("OtherKey"));
357    if (otherKey != null)
358      otherKeyMembers = otherKey.Split(',');
359    DeleteOnNull = (Boolean?) xe.Attribute("DeleteOnNull") ?? false;
360    DeleteRule = (String) xe.Attribute("DeleteRule");
361    IsForeignKey = (xe.Attribute("IsForeignKey") != null);
362    Member = (String) xe.Attribute("Member");
363    MemberAttributes = Util.DecodeMemberAccess((String) xe.Attribute("AccessModifier")) | Util.DecodeMemberModifier((String) xe.Attribute("Modifier"));
364    Name = (String) xe.Attribute("Name");
365    String cardinality = (String) xe.Attribute("Cardinality");
366    IsMany = (cardinality == null) ? !IsForeignKey : (cardinality.Equals("Many"));
367  }
368}
369
370// DBML Function element (stored procedure) > Method on DataContext
371class Function
372{
373  public List<Class> Classes { get; private set; }
374  public Data Data { get; private set; }
375  private Boolean? hasMultipleResults = null;
376  public Boolean HasMultipleResults {
377    get { return (hasMultipleResults.HasValue) ? hasMultipleResults.Value : Classes.Count() > 1; }
378  }
379  public String ID { get; private set; }
380  public Boolean IsComposable { get; private set; }
381  public MemberAttributes MemberAttributes { get; private set; }
382  public String Method { get; private set; }
383  public String Name { get; private set; }
384  public List<Parameter> Parameters { get; private set; }
385  public Return Return { get; private set; }
386  public CodeTypeReference ReturnType {
387    get {
388      if (Return != null)
389        return new CodeTypeReference(Return.Type);
390      else
391        if (HasMultipleResults)
392          return new CodeTypeReference(typeof(IMultipleResults));
393        else {
394          CodeTypeReference typeRef = new CodeTypeReference(typeof(ISingleResult<>));
395          typeRef.TypeArguments.Add(new CodeTypeReference(Classes[0].QualifiedName));
396          return typeRef;
397        }
398    }
399  }
400 
401  public Function(Data data, XElement xe) {
402    Data = data;
403    String hasMultiResultsElement = (String) xe.Attribute("HasMultipleResults");
404    if (hasMultiResultsElement != null)
405      hasMultipleResults = Boolean.Parse(hasMultiResultsElement);
406    ID = (String) xe.Attribute("Id");
407    IsComposable = (Boolean ?) xe.Attribute("IsComposable") ?? false;
408    Name = (String) xe.Attribute("Name");
409    Method = (String) xe.Attribute("Method");
410    MemberAttributes = Util.DecodeMemberAccess((String) xe.Attribute("AccessModifier")) | Util.DecodeMemberModifier((String) xe.Attribute("Modifier"));
411    Parameters = (from p in xe.Elements(Data.NS + "Parameter")
412      select new Parameter(this, p)).ToList();
413    Return = (from r in xe.Elements(Data.NS + "Return")
414      select new Return(this, r)).SingleOrDefault();
415    Classes = new List<Class>();
416    foreach(XElement fxe in xe.Elements(Data.NS + "ElementType")) {
417      String idRef = (String) fxe.Attribute("IdRef");
418      if (idRef == null) {
419        var functionClass = new FunctionClass(this, fxe);
420        Classes.Add(functionClass);
421        Data.FunctionClasses.Add(functionClass);
422      }
423      else
424        Classes.Add(Data.TableClasses.Single(c => c.Id == idRef));
425    }
426  }
427}
428
429// Function return type -> Method return type
430class Return
431{
432  private String typeName;
433  public String DbType { get; private set; }
434  public Function Function { get; private set; }
435  public Type Type {
436    get { return Data.GetType(typeName, false); }
437  }
438 
439  public Return(Function function, XElement xe) {
440    Function = function;
441    DbType = (String) xe.Attribute("DbType");
442    typeName = (String) xe.Attribute("Type");
443  }
444}
445
446public enum ParameterDirection { In, Out, InOut };
447public enum OperationType { Insert, Update, Delete };
448public enum ArgumentVersion { Original, New };
449
450// Function parameter -> Method parameter
451class Parameter
452{
453  private String typeName;
454  public String DbType { get; private set; }
455  public Function Function { get; private set; }
456  public String Name { get; private set; }
457  public String DbName { get; private set; }
458  public ParameterDirection Direction { get; private set; }
459  public Type Type {
460    get { return Data.GetType(typeName, true); }
461  }
462 
463  public Parameter(Function function, XElement xe) {
464    Function = function;
465    DbName = (String) xe.Attribute("Name");
466    Name = (String) xe.Attribute("Parameter") ?? DbName;
467    DbType = (String) xe.Attribute("DbType");
468    typeName = (String) xe.Attribute("Type");
469    Direction = Util.ParseEnum((String) xe.Attribute("Direction"), ParameterDirection.In);
470  }
471}
472
473// Functions associated with a table's CUD operations
474class TableOperation
475{
476  private String functionID;
477  private Function function;
478  public List<Argument> Arguments { get; private set; }
479  public OperationType Type { get; private set; }
480  public Function Function {
481    get {
482      if ((function == null) && (!String.IsNullOrEmpty(functionID)))
483        function = Table.Data.Functions.Where(f => f.ID == functionID).SingleOrDefault();
484      return function;
485    }
486    set {
487      function = value;
488      functionID = null;
489    }
490  }
491  public Table Table { get; private set; }
492  public TableOperation(Table table, XElement xe) {
493    Table = table;
494    functionID = (String) xe.Attribute("FunctionId");
495    Type = (OperationType) Enum.Parse(typeof(OperationType), xe.Name.LocalName.Replace("Function",""));
496    Arguments = (from a in xe.Elements(Table.Data.NS + "Argument") select new Argument(this, a)).ToList();
497  }
498}
499
500// Argument to a function
501class Argument
502{
503  private String parameterName;
504  private Parameter parameter;
505  public TableOperation TableOperation;
506  public Parameter Parameter {
507    get {
508      if ((parameter == null) && (!String.IsNullOrEmpty(parameterName)))
509        parameter = TableOperation.Function.Parameters.Single(p => p.Name == parameterName);
510      return parameter;
511    }
512    set {
513      parameter = value;
514      parameterName = null;
515    }
516  }
517  public String Member { get; private set; }
518  public ArgumentVersion Version { get; private set; }
519 
520  public Argument(TableOperation tableOperation, XElement xe) {
521    TableOperation = tableOperation;
522    parameterName = (String) xe.Attribute("Parameter");
523    Member = (String) xe.Attribute("Member");
524    Version = Util.ParseEnum((String) xe.Attribute("Version"), ArgumentVersion.New);
525  }
526}
527
528abstract class CodeLanguage
529{
530  public CodeDomProvider CodeDomProvider { get; protected set; }
531  public abstract String GetAccess(MemberAttributes memberAttributes);
532  public abstract String GetAccess(TypeAttributes typeAttributes);
533  public abstract String GetModifier(MemberAttributes memberAttributes);
534  public abstract String GetModifier(TypeAttributes typeAttributes);
535 
536  public String Format(Type type) {
537    return Format(new CodeTypeReference(type));
538  }
539 
540  public virtual String ShortenTypeRef(String typeRef) {
541    return (typeRef.LastIndexOf('.') != 6) ? typeRef.Replace("System.Data.Linq.","") : typeRef.Replace("System.","");
542  }
543 
544  public String Format(CodeTypeReference codeTypeRef) {
545    return ShortenTypeRef(CodeDomProvider.GetTypeOutput(codeTypeRef));
546  }
547 
548  public abstract String Format(ParameterDirection direction);
549 
550  public String Format(MemberAttributes memberAttributes) {
551    return GetAccess(memberAttributes) + GetModifier(memberAttributes);
552  }
553
554  public String Format(TypeAttributes typeAttributes) {
555    return GetAccess(typeAttributes) + GetModifier(typeAttributes);
556  }
557}
558
559class CSharpCodeLanguage : CodeLanguage
560{
561  public CSharpCodeLanguage() {
562    CodeDomProvider = new Microsoft.CSharp.CSharpCodeProvider();
563  }
564 
565  public override String Format(ParameterDirection direction) {
566    switch(direction) {
567      case ParameterDirection.InOut: return "ref ";
568      case ParameterDirection.Out: return "out ";
569      default: return "";
570    }
571  }
572
573  public override String ShortenTypeRef(String typeRef) {
574    if (typeRef.StartsWith("System.Nullable<"))
575      typeRef = typeRef.Replace("System.Nullable<","").Replace(">","?");
576    return base.ShortenTypeRef(typeRef);
577  }
578
579  public override String GetAccess(MemberAttributes memberAttributes) {
580    switch(memberAttributes & MemberAttributes.AccessMask) {
581      case MemberAttributes.Private: return "private ";
582      case MemberAttributes.Public: return "public ";
583      case MemberAttributes.Family: return "protected ";
584      case MemberAttributes.Assembly: return "internal ";
585      case MemberAttributes.FamilyAndAssembly: return "protected internal ";
586      default: return memberAttributes.ToString();
587    }
588  }
589
590  public override String GetAccess(TypeAttributes typeAttributes) {
591    switch(typeAttributes & TypeAttributes.VisibilityMask) {
592      case TypeAttributes.NestedPrivate: return "private ";
593      case TypeAttributes.NestedAssembly: return "internal ";
594      case TypeAttributes.NestedFamily: return "protected ";
595      case TypeAttributes.NestedFamORAssem: return "protected internal ";
596      default: return "public ";
597    }
598  }
599
600  public override String GetModifier(MemberAttributes memberAttributes) {
601    switch(memberAttributes & MemberAttributes.ScopeMask) {
602      case MemberAttributes.Final: return "";
603      case MemberAttributes.Abstract: return "abstract ";
604      case MemberAttributes.Override: return "override ";
605      default: return "virtual ";
606    }
607  }
608 
609  public override String GetModifier(TypeAttributes typeAttributes) {
610    if ((typeAttributes & TypeAttributes.Abstract) != 0) return "abstract ";
611    if ((typeAttributes & TypeAttributes.Sealed) != 0) return "sealed ";
612    return "";
613  }
614}
615
616class VBCodeLanguage : CodeLanguage
617{
618  public VBCodeLanguage() {
619    CodeDomProvider = new Microsoft.VisualBasic.VBCodeProvider();
620  }
621 
622  public override String Format(ParameterDirection direction) {
623    switch(direction) {
624      case ParameterDirection.InOut: return "ByRef ";
625      case ParameterDirection.Out: return "ByRef ";
626      default: return "";
627    }
628  }
629
630  public override String GetAccess(MemberAttributes memberAttributes) {
631    switch(memberAttributes & MemberAttributes.AccessMask) {
632      case MemberAttributes.Private: return "Private ";
633      case MemberAttributes.Public: return "Public ";
634      case MemberAttributes.Family: return "Protected ";
635      case MemberAttributes.Assembly: return "Friend ";
636      case MemberAttributes.FamilyAndAssembly: return "Protected Friend ";
637      default: return memberAttributes.ToString();
638    }
639  }
640 
641  public override String GetAccess(TypeAttributes typeAttributes) {
642    switch(typeAttributes & TypeAttributes.VisibilityMask) {
643      case TypeAttributes.NestedPrivate: return "Private ";
644      case TypeAttributes.NestedAssembly: return "Friend ";
645      case TypeAttributes.NestedFamily: return "Protected ";
646      case TypeAttributes.NestedFamORAssem: return "protected internal ";
647      default: return "Public ";
648    }
649  }
650
651  public override String GetModifier(MemberAttributes memberAttributes) {
652    switch(memberAttributes & MemberAttributes.ScopeMask) {
653      case MemberAttributes.Final: return "";
654      case MemberAttributes.Abstract: return "MustOverride ";
655      case MemberAttributes.Override: return "Override ";
656      default: return "Overridable ";
657    }
658  }
659 
660  public override String GetModifier(TypeAttributes typeAttributes) {
661    if ((typeAttributes & TypeAttributes.Abstract) != 0) return "MustInherit ";
662    if ((typeAttributes & TypeAttributes.Sealed) != 0) return "NotInheritable ";
663    return "";
664  }
665}
666
667// Manager class records the various blocks so it can split them up
668class Manager
669{
670  private struct Block {
671    public String Name;
672    public int Start, Length;
673  }
674 
675  private List<Block> blocks = new List<Block>();
676  private Block currentBlock;
677  private Block footerBlock = new Block();
678  private Block headerBlock = new Block();
679  private ITextTemplatingEngineHost host;
680  private ManagementStrategy strategy;
681  private StringBuilder template;
682  public String OutputPath { get; set; }
683 
684  public Manager(ITextTemplatingEngineHost host, StringBuilder template, bool commonHeader) {
685    this.host = host;
686    this.template = template;
687    OutputPath = String.Empty;
688    strategy = ManagementStrategy.Create(host);   
689  }
690   
691  public void StartBlock(String name) {
692    currentBlock = new Block { Name = name, Start = template.Length };
693  }
694
695  public void StartFooter() {
696    footerBlock.Start = template.Length;
697  }
698 
699  public void EndFooter() {
700    footerBlock.Length = template.Length - footerBlock.Start;
701  }
702 
703  public void StartHeader() {
704    headerBlock.Start = template.Length;
705  }
706 
707  public void EndHeader() {
708    headerBlock.Length = template.Length - headerBlock.Start;
709  }
710
711  public void EndBlock() {
712    currentBlock.Length = template.Length - currentBlock.Start;
713    blocks.Add(currentBlock);
714  }
715   
716  public void Process(bool split) {
717    String header = template.ToString(headerBlock.Start, headerBlock.Length);
718    String footer = template.ToString(footerBlock.Start, footerBlock.Length);
719    blocks.Reverse();   
720    foreach(Block block in blocks) {
721      String fileName = Path.Combine(OutputPath, block.Name);
722      if (split) {
723        String content = header + template.ToString(block.Start, block.Length) + footer;
724        strategy.CreateFile(fileName, content);
725        template.Remove(block.Start, block.Length);
726      } else {
727        strategy.DeleteFile(fileName);
728      }
729    }
730  }
731
732  public string GetCustomToolNamespace(string fileName) {
733    return strategy.GetCustomToolNamespace(fileName);
734  }
735 
736  public string DefaultProjectNamespace {
737    get { return strategy.DefaultProjectNamespace; }
738  }
739}
740
741class ManagementStrategy
742{
743  internal static ManagementStrategy Create(ITextTemplatingEngineHost host) {
744    return (host is IServiceProvider) ? new VSManagementStrategy(host) : new ManagementStrategy(host);
745  }
746
747  internal ManagementStrategy(ITextTemplatingEngineHost host) { }
748
749  internal virtual void CreateFile(String fileName, String content) {
750    File.WriteAllText(fileName, content);
751  }
752 
753  internal virtual void DeleteFile(String fileName) {
754    if (File.Exists(fileName))
755      File.Delete(fileName);
756  }
757 
758  internal virtual string DefaultProjectNamespace {
759    get { return null; }
760  }
761   
762  internal virtual string GetCustomToolNamespace(string fileName) {
763    return null;
764  }
765}
766
767class VSManagementStrategy : ManagementStrategy
768{
769  private EnvDTE.ProjectItem templateProjectItem;
770  private EnvDTE.DTE dte;
771 
772  internal VSManagementStrategy(ITextTemplatingEngineHost host) : base(host) {
773    IServiceProvider hostServiceProvider = (IServiceProvider)host;
774    if(hostServiceProvider == null)
775      throw new ArgumentNullException("Could not obtain hostServiceProvider");
776   
777    dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
778    if(dte == null)
779      throw new ArgumentNullException("Could not obtain DTE from host");
780   
781    templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);     
782  }
783 
784  internal override void CreateFile(String fileName, String content) {
785    base.CreateFile(fileName, content);
786    ((EventHandler)delegate { templateProjectItem.ProjectItems.AddFromFile(fileName); }).BeginInvoke(null, null, null, null);
787  }
788 
789  internal override void DeleteFile(String fileName) {
790    ((EventHandler)delegate { FindAndDeleteFile(fileName); }).BeginInvoke(null, null, null, null);
791  }
792 
793  private void FindAndDeleteFile(String fileName) {
794    foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) {
795      if (projectItem.get_FileNames(0) == fileName) {
796        projectItem.Delete();
797        return;
798      }
799    }
800  }
801
802  internal override string DefaultProjectNamespace {
803    get { return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString(); }
804  }
805 
806  internal override string GetCustomToolNamespace(string fileName) {
807    return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
808  }
809}
810
811// Methods that deserve a better home
812public static class Util
813{
814  public static T ParseEnum<T>(String value, T defaultValue) where T:struct {
815    try { return (T)Enum.Parse(typeof(T), value); }
816    catch { return defaultValue; }
817  }
818 
819  public static MemberAttributes DecodeMemberAccess(String access) {
820    switch(access) {
821      case "Private": return MemberAttributes.Private;
822      case "Internal": return MemberAttributes.Assembly;
823      case "Protected": return MemberAttributes.Family;
824      case "ProtectedInternal": return MemberAttributes.FamilyAndAssembly;
825      default: return MemberAttributes.Public;
826    }
827  }
828 
829  public static MemberAttributes DecodeMemberModifier(String modifier) {
830    switch(modifier) {
831      case "Virtual": return 0;
832      case "Override": return MemberAttributes.Override;
833      default: return MemberAttributes.Final;
834    }
835  }
836}
837
838class TypeStub : System.Reflection.TypeDelegator
839{
840  private String name;
841 
842  public TypeStub(String name) : base(typeof(System.Enum)) {
843    this.name = name;
844  }
845 
846  public override String Name {
847    get { return name; }
848  }
849 
850  public override String FullName {
851    get { return name; }
852  }
853}#>
Note: See TracBrowser for help on using the repository browser.