File: EntityTemplateFactory.cs

package info (click to toggle)
mono 6.12.0.199%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,296,836 kB
  • sloc: cs: 11,181,803; xml: 2,850,076; ansic: 699,709; cpp: 123,344; perl: 59,361; javascript: 30,841; asm: 21,853; makefile: 20,405; sh: 15,009; python: 4,839; pascal: 925; sql: 859; sed: 16; php: 1
file content (129 lines) | stat: -rw-r--r-- 5,441 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System.Diagnostics;
using System.Globalization;
using System.Web.Compilation;
using System.Web.Hosting;
using System.Web.UI.WebControls;

namespace System.Web.DynamicData {
    public class EntityTemplateFactory {
        private const string s_defaultTemplateName = "Default";
        
        private TemplateFactory _factory;
        private Func<string, EntityTemplateUserControl> _templateInstantiator;

        public EntityTemplateFactory()
            : this(CreateEntityTemplateInstance, /* trackChanges */ true) {
        }

        // for unit testing
        internal EntityTemplateFactory(Func<string, EntityTemplateUserControl> templateInstantiator, VirtualPathProvider vpp)
            : this(templateInstantiator, /* trackChanges */ false) {
            _factory.VirtualPathProvider = vpp;
        }

        private EntityTemplateFactory(Func<string, EntityTemplateUserControl> templateInstantiator, bool trackChanges) {
            _factory = new TemplateFactory("EntityTemplates", trackChanges);
            _templateInstantiator = templateInstantiator;
        }

        internal string TemplateFolderVirtualPath {
            get {
                return _factory.TemplateFolderVirtualPath;
            }
            set {
                _factory.TemplateFolderVirtualPath = value;
            }
        }

        private static EntityTemplateUserControl CreateEntityTemplateInstance(string path) {
            return (EntityTemplateUserControl)BuildManager.CreateInstanceFromVirtualPath(
                    path, typeof(EntityTemplateUserControl));
        }

        public virtual EntityTemplateUserControl CreateEntityTemplate(MetaTable table, DataBoundControlMode mode, string uiHint) {
            if (table == null) {
                throw new ArgumentNullException("table");
            }

            string entityTemplatePath = GetEntityTemplateVirtualPathWithCaching(table, mode, uiHint);
            if (entityTemplatePath == null) {
                return null;
            }

            return _templateInstantiator(entityTemplatePath);
        }

        private string GetEntityTemplateVirtualPathWithCaching(MetaTable table, DataBoundControlMode mode, string uiHint) {
            long cacheKey = Misc.CombineHashCodes(table, mode, uiHint);

            return _factory.GetTemplatePath(cacheKey, delegate() {
                return GetEntityTemplateVirtualPath(table, mode, uiHint);
            });
        }

        public virtual string GetEntityTemplateVirtualPath(MetaTable table, DataBoundControlMode mode, string uiHint) {
            if (table == null) {
                throw new ArgumentNullException("table");
            }

            // Fallback order is as follows (where CustomProducts is the uiHint)
            //    CustomProducts_Insert
            //    CustomProducts_Edit
            //    Products_Insert
            //    Products_Edit
            //    Default_Insert
            //    Default_Edit
            //    CustomProducts_ReadOnly
            //    Products_ReadOnly
            //    Default_ReadOnly
            //
            // If nothing matches null is returned

            return GetVirtualPathFallback(table, mode, uiHint, DataBoundControlMode.Edit) ??
                GetVirtualPathFallback(table, DataBoundControlMode.ReadOnly, uiHint, DataBoundControlMode.ReadOnly);
        }

        private string GetVirtualPathFallback(MetaTable table, DataBoundControlMode mode, string uiHint, DataBoundControlMode minModeToFallBack) {
            if (mode < minModeToFallBack) {
                return null;
            }

            // the strategy is to go over each candidate name and try to find an existing template for
            // each mode between 'mode' and 'minModeToFallBack'
            // note that GetVirtualPathForMode will return null for empty names (e.g. when the uiHint is not specified)
            string[] fallbackNames = new string[] { uiHint, table.Name, s_defaultTemplateName };
            foreach (var name in fallbackNames) {
                for (var currentMode = mode; currentMode >= minModeToFallBack; currentMode--) {
                    string virtualPath = GetVirtualPathForMode(name, currentMode);
                    if (virtualPath != null) {
                        return virtualPath;
                    }
                }
            }
            return null;
        }

        private string GetVirtualPathForMode(string candidateName, DataBoundControlMode mode) {
            if (String.IsNullOrEmpty(candidateName)) {
                return null;
            } else {
                string templatePath = BuildEntityTemplateVirtualPath(candidateName, mode);
                return _factory.FileExists(templatePath) ? templatePath : null;
            }
        }

        public virtual string BuildEntityTemplateVirtualPath(string templateName, DataBoundControlMode mode) {
            if (templateName == null) {
                throw new ArgumentNullException("templateName");
            }

            string modeString = mode == DataBoundControlMode.ReadOnly ? String.Empty : "_" + mode.ToString();
            return String.Format(CultureInfo.InvariantCulture, this.TemplateFolderVirtualPath + "{0}{1}.ascx", templateName, modeString);
        }

        internal void Initialize(MetaModel model) {
            Debug.Assert(model != null);
            _factory.Model = model;
        }
    }
}