-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
ThemingVirtualPathProvider.cs
161 lines (134 loc) · 4.31 KB
/
ThemingVirtualPathProvider.cs
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Caching;
using System.Web.Hosting;
using SmartStore.Core.Infrastructure;
using SmartStore.Core.Themes;
using SmartStore.Utilities;
using SmartStore.Web.Framework.Theming.Assets;
namespace SmartStore.Web.Framework.Theming
{
public class ThemingVirtualPathProvider : SmartVirtualPathProvider
{
private readonly VirtualPathProvider _previous;
private static readonly ContextState<Dictionary<string, InheritedThemeFileResult>> _requestState;
static ThemingVirtualPathProvider()
{
_requestState = new ContextState<Dictionary<string, InheritedThemeFileResult>>("ThemeFileResolver.RequestCache", () => new Dictionary<string, InheritedThemeFileResult>());
}
public ThemingVirtualPathProvider(VirtualPathProvider previous)
{
_previous = previous;
}
public override bool FileExists(string virtualPath)
{
var result = GetResolveResult(virtualPath);
if (result != null)
{
if (!result.IsBased)
{
return true;
}
else
{
if (result.Query.HasValue() && result.Query.IndexOf('.') >= 0)
{
// libSass tries to locate files by appending .[s]css extension to our querystring. Prevent this shit!
return false;
}
else
{
// Let system VPP check for this file
virtualPath = result.ResultVirtualPath ?? result.OriginalVirtualPath;
}
}
}
return _previous.FileExists(virtualPath);
}
public override VirtualFile GetFile(string virtualPath)
{
VirtualFile file = null;
string debugPath = null;
var result = GetResolveResult(virtualPath);
if (result != null)
{
// File is an inherited theme file. Set the result virtual path.
virtualPath = result.ResultVirtualPath ?? result.OriginalVirtualPath;
if (!result.IsBased)
{
file = new InheritedVirtualThemeFile(result);
}
}
if (result == null || file is InheritedVirtualThemeFile)
{
// Handle plugin and symlinked theme folders in debug mode.
debugPath = ResolveDebugFilePath(virtualPath);
if (debugPath != null)
{
file = new DebugVirtualFile(file?.VirtualPath ?? virtualPath, debugPath);
}
}
return file ?? _previous.GetFile(virtualPath);
}
public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies)
{
if (virtualPathDependencies == null)
{
return _previous.GetFileHash(virtualPath, virtualPathDependencies);
}
var fileNames = MapDependencyPaths(virtualPathDependencies.Cast<string>(), out _);
var combiner = HashCodeCombiner.Start();
foreach (var fileName in fileNames)
{
combiner.Add(new FileInfo(fileName));
}
return combiner.CombinedHashString;
}
public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)
{
if (virtualPathDependencies == null)
{
return null;
}
var mappedPaths = MapDependencyPaths(virtualPathDependencies.Cast<string>(), out var cacheKeys);
return new CacheDependency(mappedPaths, cacheKeys, utcStart);
}
/// <summary>
/// Maps virtual to physical paths. Used to compute cache dependecies and file hashes.
/// </summary>
internal string[] MapDependencyPaths(IEnumerable<string> virtualPathDependencies, out string[] cacheKeys)
{
cacheKeys = null;
var mappedPaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
var cacheKeySet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var dep in virtualPathDependencies)
{
var file = GetFile(dep);
if (file is IFileDependencyProvider provider)
{
provider.AddFileDependencies(mappedPaths, cacheKeySet);
}
else if (file != null)
{
mappedPaths.Add(HostingEnvironment.MapPath(file.VirtualPath));
}
}
cacheKeys = cacheKeySet.ToArray();
var paths = mappedPaths.ToArray();
Array.Sort<string>(paths);
return paths;
}
private static InheritedThemeFileResult GetResolveResult(string virtualPath)
{
var d = _requestState.GetState();
if (!d.TryGetValue(virtualPath, out var result))
{
result = d[virtualPath] = EngineContext.Current.Resolve<IThemeFileResolver>().Resolve(virtualPath);
}
return result;
}
}
}