1+ /*
2+ * Copyright (c) 2014-2015, Facebook, Inc.
3+ * All rights reserved.
4+ *
5+ * This source code is licensed under the BSD-style license found in the
6+ * LICENSE file in the root directory of this source tree. An additional grant
7+ * of patent rights can be found in the PATENTS file in the same directory.
8+ */
9+
10+ using System ;
11+ using System . Collections . Generic ;
12+ using System . IO ;
13+ using System . Linq ;
14+ using System . Text ;
15+
16+ using Microsoft . Owin . FileSystems ;
17+
18+ namespace React . Owin
19+ {
20+ /// <summary>
21+ /// Owin file system that serves transformed JSX files.
22+ /// </summary>
23+ public class JsxFileSystem : Microsoft . Owin . FileSystems . IFileSystem
24+ {
25+ private readonly IJsxTransformer _transformer ;
26+ private readonly Microsoft . Owin . FileSystems . IFileSystem _physicalFileSystem ;
27+ private readonly string [ ] _extensions ;
28+
29+ /// <summary>
30+ /// Creates a new instance of the JsxFileSystem.
31+ /// </summary>
32+ /// <param name="transformer">JSX transformer used to compile JSX files</param>
33+ /// <param name="root">The root directory</param>
34+ /// <param name="extensions">Extensions of files that will be treated as JSX files</param>
35+ public JsxFileSystem ( IJsxTransformer transformer , string root , IEnumerable < string > extensions )
36+ : this ( transformer , new PhysicalFileSystem ( root ) , extensions )
37+ {
38+ }
39+
40+ /// <summary>
41+ /// Creates a new instance of the JsxFileSystem.
42+ /// </summary>
43+ /// <param name="transformer">JSX transformer used to compile JSX files</param>
44+ /// <param name="fileSystem">File system used to look up files</param>
45+ /// <param name="extensions">Extensions of files that will be treated as JSX files</param>
46+ public JsxFileSystem ( IJsxTransformer transformer , Microsoft . Owin . FileSystems . IFileSystem fileSystem , IEnumerable < string > extensions )
47+ {
48+ _transformer = transformer ;
49+ _physicalFileSystem = fileSystem ;
50+
51+ // Make sure the extensions start with dot
52+ _extensions = extensions . Select ( extension => extension . StartsWith ( "." ) ? extension : "." + extension ) . ToArray ( ) ;
53+ }
54+
55+ /// <summary>
56+ /// Locate a JSX file at the given path.
57+ /// </summary>
58+ /// <param name="subpath">The path that identifies the file</param>
59+ /// <param name="fileInfo">The discovered file if any</param>
60+ /// <returns>
61+ /// True if a JSX file was located at the given path
62+ /// </returns>
63+ public bool TryGetFileInfo ( string subpath , out IFileInfo fileInfo )
64+ {
65+ IFileInfo internalFileInfo ;
66+ fileInfo = null ;
67+
68+ if ( ! _physicalFileSystem . TryGetFileInfo ( subpath , out internalFileInfo ) )
69+ return false ;
70+
71+ if ( internalFileInfo . IsDirectory || ! _extensions . Any ( internalFileInfo . Name . EndsWith ) )
72+ return false ;
73+
74+ fileInfo = new JsxFileInfo ( _transformer , internalFileInfo ) ;
75+ return true ;
76+ }
77+
78+ /// <summary>
79+ /// Enumerate a directory at the given path, if any
80+ /// </summary>
81+ /// <param name="subpath">The path that identifies the directory</param>
82+ /// <param name="contents">The contents if any</param>
83+ /// <returns>
84+ /// True if a directory was located at the given path
85+ /// </returns>
86+ public bool TryGetDirectoryContents ( string subpath , out IEnumerable < IFileInfo > contents )
87+ {
88+ return _physicalFileSystem . TryGetDirectoryContents ( subpath , out contents ) ;
89+ }
90+
91+ private class JsxFileInfo : IFileInfo
92+ {
93+ private readonly IJsxTransformer _jsxTransformer ;
94+ private readonly IFileInfo _fileInfo ;
95+ private readonly Lazy < byte [ ] > _content ;
96+
97+ public JsxFileInfo ( IJsxTransformer jsxTransformer , IFileInfo fileInfo )
98+ {
99+ _jsxTransformer = jsxTransformer ;
100+ _fileInfo = fileInfo ;
101+
102+ _content = new Lazy < byte [ ] > (
103+ ( ) =>
104+ {
105+ return Encoding . UTF8 . GetBytes ( _jsxTransformer . TransformJsxFile ( fileInfo . PhysicalPath ) ) ;
106+ } ) ;
107+ }
108+
109+ public Stream CreateReadStream ( )
110+ {
111+ return new MemoryStream ( _content . Value ) ;
112+ }
113+
114+ public long Length
115+ {
116+ get { return _content . Value . Length ; }
117+ }
118+
119+ public string PhysicalPath
120+ {
121+ get { return _fileInfo . PhysicalPath ; }
122+ }
123+
124+ public string Name
125+ {
126+ get { return _fileInfo . Name ; }
127+ }
128+
129+ public DateTime LastModified
130+ {
131+ get { return _fileInfo . LastModified ; }
132+ }
133+
134+ public bool IsDirectory
135+ {
136+ get { return _fileInfo . IsDirectory ; }
137+ }
138+ }
139+ }
140+ }
0 commit comments