Utility class for generating text-based representations of the virtual storage's tree
90 | structure. Provides static methods for generating various debug texts.
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
103 |
104 |
105 |
106 |
107 |
108 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/AkiraNetwork/VirtualStorageLibrary.Test/WildcardMatchers/PowerShellWildcardMatcherTests.cs:
--------------------------------------------------------------------------------
1 | // This file is part of VirtualStorageLibrary.
2 | //
3 | // Copyright (C) 2024 Akira Shimodate
4 | //
5 | // VirtualStorageLibrary is free software, and it is distributed under the terms of
6 | // the GNU Lesser General Public License (version 3, or at your option, any later
7 | // version). This license is published by the Free Software Foundation.
8 | //
9 | // VirtualStorageLibrary is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or
11 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 | // more details.
13 | //
14 | // You should have received a copy of the GNU Lesser General Public License along
15 | // with VirtualStorageLibrary. If not, see https://www.gnu.org/licenses/.
16 |
17 | using AkiraNetwork.VirtualStorageLibrary.WildcardMatchers;
18 |
19 | namespace AkiraNetwork.VirtualStorageLibrary.Test.WildcardMatchers
20 | {
21 | [TestClass]
22 | public class PowerShellWildcardMatcherTests
23 | {
24 | [TestMethod]
25 | public void WildcardDictionary_ContainsExpectedPatterns()
26 | {
27 | var matcher = new PowerShellWildcardMatcher();
28 | var dictionary = matcher.WildcardDictionary;
29 |
30 | Assert.AreEqual(4, dictionary.Count);
31 | Assert.AreEqual(".*", dictionary["*"]);
32 | Assert.AreEqual(".", dictionary["?"]);
33 | Assert.AreEqual("[", dictionary["["]);
34 | Assert.AreEqual("]", dictionary["]"]);
35 | }
36 |
37 | [TestMethod]
38 | public void Wildcards_ContainsExpectedKeys()
39 | {
40 | var matcher = new PowerShellWildcardMatcher();
41 | var wildcards = matcher.Wildcards.ToList();
42 |
43 | Assert.AreEqual(4, wildcards.Count);
44 | CollectionAssert.Contains(wildcards, "*");
45 | CollectionAssert.Contains(wildcards, "?");
46 | CollectionAssert.Contains(wildcards, "[");
47 | CollectionAssert.Contains(wildcards, "]");
48 | }
49 |
50 | [TestMethod]
51 | public void Patterns_ContainsExpectedValues()
52 | {
53 | var matcher = new PowerShellWildcardMatcher();
54 | var patterns = matcher.Patterns.ToList();
55 |
56 | Assert.AreEqual(4, patterns.Count);
57 | CollectionAssert.Contains(patterns, ".*");
58 | CollectionAssert.Contains(patterns, ".");
59 | CollectionAssert.Contains(patterns, "[");
60 | CollectionAssert.Contains(patterns, "]");
61 | }
62 |
63 | [TestMethod]
64 | public void Count_ReturnsCorrectValue()
65 | {
66 | var matcher = new PowerShellWildcardMatcher();
67 | Assert.AreEqual(4, matcher.Count);
68 | }
69 |
70 | [TestMethod]
71 | public void PatternMatcher_MatchesCorrectly()
72 | {
73 | var matcher = new PowerShellWildcardMatcher();
74 |
75 | // "*" matches zero or more characters
76 | Assert.IsTrue(matcher.PatternMatcher("test.txt", "*"));
77 | Assert.IsTrue(matcher.PatternMatcher("test.txt", "t*"));
78 | Assert.IsTrue(matcher.PatternMatcher("test.txt", "*t"));
79 | Assert.IsTrue(matcher.PatternMatcher("test.txt", "test*"));
80 | Assert.IsTrue(matcher.PatternMatcher("test.txt", "*txt"));
81 | Assert.IsFalse(matcher.PatternMatcher("test.txt", "testX*"));
82 |
83 | // "?" matches exactly one character
84 | Assert.IsTrue(matcher.PatternMatcher("test.txt", "t?st.txt"));
85 | Assert.IsTrue(matcher.PatternMatcher("test.txt", "te?t.txt"));
86 | Assert.IsFalse(matcher.PatternMatcher("test.txt", "test?.txt"));
87 |
88 | // "[" and "]" for character class
89 | Assert.IsTrue(matcher.PatternMatcher("test.txt", "tes[stu].txt"));
90 | Assert.IsFalse(matcher.PatternMatcher("test.txt", "tes[pqr].txt"));
91 | }
92 |
93 | [TestMethod]
94 | public void IsValidWildcardPattern_ReturnsTrueForValidPatterns()
95 | {
96 | var matcher = new PowerShellWildcardMatcher();
97 |
98 | // Valid patterns
99 | Assert.IsTrue(matcher.IsValidWildcardPattern("*")); // Matches zero or more characters
100 | Assert.IsTrue(matcher.IsValidWildcardPattern("?")); // Matches any single character
101 | Assert.IsTrue(matcher.IsValidWildcardPattern("[a-z]")); // Character class
102 | Assert.IsTrue(matcher.IsValidWildcardPattern("test*")); // Matches "test" followed by any characters
103 | Assert.IsTrue(matcher.IsValidWildcardPattern("file[1-5].txt")); // Matches "file1.txt" to "file5.txt"
104 | Assert.IsTrue(matcher.IsValidWildcardPattern("a`*b")); // Escaped asterisk as literal '*'
105 | }
106 |
107 | [TestMethod]
108 | public void IsValidWildcardPattern_ReturnsFalseForInvalidPatterns()
109 | {
110 | var matcher = new PowerShellWildcardMatcher();
111 |
112 | // Invalid patterns
113 | Assert.IsFalse(matcher.IsValidWildcardPattern("[a-z")); // Missing closing bracket in character class
114 | Assert.IsFalse(matcher.IsValidWildcardPattern("test[`]")); // Improper escape within character class
115 | Assert.IsFalse(matcher.IsValidWildcardPattern("file[`")); // Unclosed escape character
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/AkiraNetwork/VirtualStorageLibrary.Test/VirtualExceptionTests.cs:
--------------------------------------------------------------------------------
1 | // This file is part of VirtualStorageLibrary.
2 | //
3 | // Copyright (C) 2024 Akira Shimodate
4 | //
5 | // VirtualStorageLibrary is free software, and it is distributed under the terms of
6 | // the GNU Lesser General Public License (version 3, or at your option, any later
7 | // version). This license is published by the Free Software Foundation.
8 | //
9 | // VirtualStorageLibrary is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or
11 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 | // more details.
13 | //
14 | // You should have received a copy of the GNU Lesser General Public License along
15 | // with VirtualStorageLibrary. If not, see https://www.gnu.org/licenses/.
16 |
17 | using System.Globalization;
18 |
19 | namespace AkiraNetwork.VirtualStorageLibrary.Test
20 | {
21 | [TestClass]
22 | public class VirtualExceptionTests : VirtualTestBase
23 | {
24 | [TestInitialize]
25 | public override void TestInitialize()
26 | {
27 | base.TestInitialize();
28 |
29 | Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
30 |
31 | VirtualStorageSettings.Initialize();
32 | VirtualNodeName.ResetCounter();
33 | }
34 |
35 | [TestMethod]
36 | public void DefaultConstructor_CreatesInstance()
37 | {
38 | VirtualNodeNotFoundException exception = new();
39 | Assert.IsNotNull(exception);
40 | }
41 |
42 | [TestMethod]
43 | public void ConstructorWithMessage_CreatesInstanceWithMessage()
44 | {
45 | string message = "Test message";
46 | VirtualNodeNotFoundException exception = new(message);
47 |
48 | Assert.IsNotNull(exception);
49 | Assert.AreEqual(message, exception.Message);
50 | }
51 |
52 | [TestMethod]
53 | public void ConstructorWithMessageAndInnerException_CreatesInstanceWithMessageAndInnerException()
54 | {
55 | string message = "Test message";
56 | Exception innerException = new("Inner exception");
57 | VirtualNodeNotFoundException exception = new(message, innerException);
58 |
59 | Assert.IsNotNull(exception);
60 | Assert.AreEqual(message, exception.Message);
61 | Assert.AreEqual(innerException, exception.InnerException);
62 | }
63 | }
64 |
65 | [TestClass]
66 | public class VirtualNotFoundExceptionTests : VirtualTestBase
67 | {
68 | [TestInitialize]
69 | public override void TestInitialize()
70 | {
71 | base.TestInitialize();
72 |
73 | Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
74 |
75 | VirtualStorageSettings.Initialize();
76 | VirtualNodeName.ResetCounter();
77 | }
78 |
79 | [TestMethod]
80 | public void DefaultConstructor_CreatesInstance()
81 | {
82 | VirtualNotFoundException exception = new();
83 | Assert.IsNotNull(exception);
84 | }
85 |
86 | [TestMethod]
87 | public void ConstructorWithMessage_CreatesInstanceWithMessage()
88 | {
89 | string message = "Test message";
90 | VirtualNotFoundException exception = new(message);
91 |
92 | Assert.IsNotNull(exception);
93 | Assert.AreEqual(message, exception.Message);
94 | }
95 |
96 | [TestMethod]
97 | public void ConstructorWithMessageAndInnerException_CreatesInstanceWithMessageAndInnerException()
98 | {
99 | string message = "Test message";
100 | Exception innerException = new("Inner exception");
101 | VirtualNotFoundException exception = new(message, innerException);
102 |
103 | Assert.IsNotNull(exception);
104 | Assert.AreEqual(message, exception.Message);
105 | Assert.AreEqual(innerException, exception.InnerException);
106 | }
107 | }
108 |
109 | [TestClass]
110 | public class VirtualPathNotFoundExceptionTests : VirtualTestBase
111 | {
112 | [TestInitialize]
113 | public override void TestInitialize()
114 | {
115 | base.TestInitialize();
116 |
117 | Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
118 |
119 | VirtualStorageSettings.Initialize();
120 | VirtualNodeName.ResetCounter();
121 | }
122 |
123 | [TestMethod]
124 | public void DefaultConstructor_CreatesInstance()
125 | {
126 | VirtualPathNotFoundException exception = new();
127 | Assert.IsNotNull(exception);
128 | }
129 |
130 | [TestMethod]
131 | public void ConstructorWithMessage_CreatesInstanceWithMessage()
132 | {
133 | string message = "Test message";
134 | VirtualPathNotFoundException exception = new(message);
135 |
136 | Assert.IsNotNull(exception);
137 | Assert.AreEqual(message, exception.Message);
138 | }
139 |
140 | [TestMethod]
141 | public void ConstructorWithMessageAndInnerException_CreatesInstanceWithMessageAndInnerException()
142 | {
143 | string message = "Test message";
144 | Exception innerException = new("Inner exception");
145 | VirtualPathNotFoundException exception = new(message, innerException);
146 |
147 | Assert.IsNotNull(exception);
148 | Assert.AreEqual(message, exception.Message);
149 | Assert.AreEqual(innerException, exception.InnerException);
150 | }
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/documents/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "HOMEPAGE"
3 | _layout: landing
4 | ---
5 |
6 | 
7 |
8 |
9 | Language: English
10 |
14 |
15 |
16 | # **Welcome to VirtualStorageLibrary!**
17 |
18 | ---
19 |
20 | ## **Tree Structure Collection for .NET Developers**
21 |
22 | `VirtualStorageLibrary` is a .NET library that operates entirely in memory and provides a
23 | **tree structure collection**.
24 | This library offers a **foundation for managing hierarchical data structures**,
25 | supporting items, directories, and symbolic links that encapsulate user-defined types `T`.
26 | This library is **not a file system**.
27 | Inspired by traditional file systems, it has been **redesigned from scratch** to offer a
28 | more flexible and user-friendly tree structure.
29 | The library aims to enable users to **intuitively** reference, traverse, and manipulate
30 | nodes via **path specification**.
31 |
32 | 
33 |
34 | ## Main Features
35 |
36 | ### Flexible Tree Structure
37 |
38 | Provides a hierarchical data structure based on parent-child relationships, enabling
39 | flexible node management.
40 |
41 | 
42 |
43 | ### Support for Various Node Types
44 |
45 | Supports items, directories, and symbolic links containing user-defined types `T`.
46 |
47 | Items are of a generic type, with `T` representing the user-defined type encapsulated by
48 | the item.
49 |
50 | Links function similarly to traditional symbolic links and contain the target path they
51 | point to.
52 |
53 | 
54 |
55 | ### Intuitive Node Operations via Paths
56 |
57 | Allows easy referencing, traversing, adding, deleting, renaming, copying, and moving of
58 | nodes through path specification, offering a user-friendly API.
59 |
60 | - Full Path Specification
61 | "/dir1/item1"
62 |
63 | - Relative Path Specification
64 | "item1"
65 |
66 | - Relative Path (Dot)
67 | "./item"
68 |
69 | - Relative Path (Dot Dot)
70 | "../item"
71 |
72 | ### Link Management
73 |
74 | Just like general file systems, symbolic links are supported.
75 | You can create symbolic links by specifying a target path for nodes that do not exist.
76 | It is also possible to specify `null` as the target path, creating what
77 | `VirtualStorageLibrary` refers to as `null links`.
78 | If link resolution is specified during path traversal and the target path does not exist,
79 | an exception will be thrown. In the case of a `null link`, even if link resolution is
80 | specified, it will not resolve (no exception will be thrown).
81 |
82 | 
83 |
84 | Manages changes to symbolic links using a link dictionary, tracking changes to the target path.
85 |
86 | 
87 |
88 | ### Prevention of Circular References
89 |
90 | When traversing paths that include symbolic links, if a structure that would result in
91 | circular directory references is detected, an exception will be thrown.
92 | `VirtualStorageLibrary` employs a method of recording only the link information at the
93 | time of path resolution in a circular reference check dictionary.
94 | It is possible to create links that would result in circular references.
95 |
96 | 
97 |
98 | When traversing paths, the link information is registered in the dictionary during the first path resolution. During the second path resolution, the dictionary is checked for the link information, and if it is found, it is considered a circular reference.
99 |
100 | ### Flexible Node List Retrieval
101 |
102 | When retrieving a list of nodes within a directory, you can filter and group by the
103 | specified node type and retrieve the sorted results based on the specified properties.
104 |
105 | - Default: Nodes are grouped by node type and sorted by name.
106 |
107 | 
108 |
109 | - Filtering: You can retrieve only specific node types.
110 |
111 | 
112 |
113 | - Sorting: You can retrieve nodes sorted by specific properties.
114 |
115 | 
116 |
117 | ## Documentation
118 |
119 | For detailed usage and reference information about this library, please refer to the
120 | following documents.
121 |
122 | - [Introduction](introduction.md)
123 | An overview and design philosophy of the library.
124 | It explains the purpose behind its development, introduces its basic functions and
125 | features, and serves as an introductory guide for new users to understand the library
126 | as a whole.
127 |
128 | - [Getting Started](getting-started.md)
129 | A step-by-step guide to getting started with the library.
130 | It explains the basic steps necessary to install, configure, and use the library, from
131 | installation to sample code.
132 |
133 | - [API Reference](xref:AkiraNetwork.VirtualStorageLibrary)
134 | Detailed information about all classes, methods, and properties included in the
135 | library.
136 | It includes explanations of how to use each member and its parameters, helping you
137 | understand the specific usage of the library.
138 |
139 | - Tutorial (Coming Soon)
140 | A guide based on real-world use cases, providing detailed examples to help you learn
141 | how to apply the library in practice. This will be added soon.
142 |
143 | - [Licenses](licenses.md)
144 | Information about the license for this library and the licenses for the libraries,
145 | tools, CSS, etc., used.
146 |
147 | ## Repository
148 |
149 | [VirtualStorageLibrary GitHub](https://github.com/AkiraNetwork/VirtualStorageLibrary)
150 |
--------------------------------------------------------------------------------
/AkiraNetwork/VirtualStorageLibrary.Test/VirtualStorageStateTests.cs:
--------------------------------------------------------------------------------
1 | // This file is part of VirtualStorageLibrary.
2 | //
3 | // Copyright (C) 2024 Akira Shimodate
4 | //
5 | // VirtualStorageLibrary is free software, and it is distributed under the terms of
6 | // the GNU Lesser General Public License (version 3, or at your option, any later
7 | // version). This license is published by the Free Software Foundation.
8 | //
9 | // VirtualStorageLibrary is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or
11 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 | // more details.
13 | //
14 | // You should have received a copy of the GNU Lesser General Public License along
15 | // with VirtualStorageLibrary. If not, see https://www.gnu.org/licenses/.
16 |
17 | using AkiraNetwork.VirtualStorageLibrary.WildcardMatchers;
18 | using System.Diagnostics;
19 | using System.Globalization;
20 |
21 | namespace AkiraNetwork.VirtualStorageLibrary.Test
22 | {
23 | [TestClass]
24 | public class VirtualStorageStateTests : VirtualTestBase
25 | {
26 | [TestInitialize]
27 | public override void TestInitialize()
28 | {
29 | base.TestInitialize();
30 |
31 | Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
32 |
33 | VirtualStorageSettings.Initialize();
34 | VirtualNodeName.ResetCounter();
35 | }
36 |
37 | [TestMethod]
38 | public void SetNodeListConditions_UpdatesConditionsCorrectly()
39 | {
40 | // Arrange
41 | var filter = VirtualNodeTypeFilter.Item | VirtualNodeTypeFilter.SymbolicLink;
42 | var groupCondition = new VirtualGroupCondition(node => node.NodeType, true);
43 | var sortConditions = new List>
44 | {
45 | new(node => node.Name, true)
46 | };
47 |
48 | // Act
49 | VirtualStorageState.SetNodeListConditions(new VirtualNodeListConditions(filter, groupCondition, sortConditions));
50 | var state = VirtualStorageState.State;
51 |
52 | // Assert
53 | Assert.AreEqual(filter, state.NodeListConditions.Filter);
54 | Assert.AreEqual(groupCondition, state.NodeListConditions.GroupCondition);
55 | CollectionAssert.AreEqual(sortConditions, state.NodeListConditions.SortConditions!.ToList());
56 | }
57 |
58 | [TestMethod]
59 | public void SetNodeListConditions_IndividualParameters_UpdatesConditionsCorrectly()
60 | {
61 | // Arrange
62 | var filter = VirtualNodeTypeFilter.Directory; // ディレクトリのみを対象とするフィルター
63 | var groupCondition = new VirtualGroupCondition(node => node.CreatedDate, false); // 作成日時で降順にグループ化
64 | var sortConditions = new List>
65 | {
66 | new(node => node.Name, true)
67 | };
68 |
69 | // Act
70 | VirtualStorageState.SetNodeListConditions(filter, groupCondition, sortConditions);
71 | var state = VirtualStorageState.State;
72 |
73 | // Assert
74 | Assert.AreEqual(filter, state.NodeListConditions.Filter);
75 | Assert.AreEqual(groupCondition, state.NodeListConditions.GroupCondition);
76 | CollectionAssert.AreEqual(sortConditions, state.NodeListConditions.SortConditions!.ToList());
77 | }
78 |
79 | [TestMethod]
80 | public void SetWildcardMatcher_UpdatesMatcherCorrectly()
81 | {
82 | // Arrange
83 | VirtualStorage vs = new();
84 | DefaultWildcardMatcher matcher = new DefaultWildcardMatcher();
85 |
86 | // Act
87 | VirtualStorageState.SetWildcardMatcher(matcher);
88 |
89 | // Assert
90 | Assert.AreEqual(matcher, VirtualStorageState.State.WildcardMatcher);
91 |
92 | // Arrange
93 | vs.AddDirectory("/dir1");
94 | vs.AddItem("/dir1/item1.txt");
95 | vs.AddItem("/dir1/item2.txt");
96 | vs.AddItem("/dir1/item3.bin");
97 |
98 | // Act
99 | var paths = vs.ExpandPath(@"/dir1/item.*\.txt").ToList();
100 |
101 | // デバッグ出力
102 | Debug.WriteLine("*:");
103 | foreach (var node in paths)
104 | {
105 | Debug.WriteLine(node);
106 | }
107 |
108 | // Assert
109 | Assert.AreEqual(2, paths.Count);
110 | Assert.AreEqual("/dir1/item1.txt", (string)paths[0]);
111 | Assert.AreEqual("/dir1/item2.txt", (string)paths[1]);
112 |
113 | // Act
114 | paths = vs.ExpandPath(@"/dir1/item.?\.txt").ToList();
115 |
116 | // デバッグ出力
117 | Debug.WriteLine("\n?:");
118 | foreach (var node in paths)
119 | {
120 | Debug.WriteLine(node);
121 | }
122 |
123 | // Assert
124 | Assert.AreEqual(2, paths.Count);
125 | Assert.AreEqual("/dir1/item1.txt", (string)paths[0]);
126 | Assert.AreEqual("/dir1/item2.txt", (string)paths[1]);
127 |
128 | // Act
129 | paths = vs.ExpandPath(@"/dir1/item.+\.txt").ToList();
130 |
131 | // デバッグ出力
132 | Debug.WriteLine("\n+:");
133 | foreach (var node in paths)
134 | {
135 | Debug.WriteLine(node);
136 | }
137 |
138 | // Assert
139 | Assert.AreEqual(2, paths.Count);
140 | Assert.AreEqual("/dir1/item1.txt", (string)paths[0]);
141 | Assert.AreEqual("/dir1/item2.txt", (string)paths[1]);
142 | }
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/VirtualStorageLibrary.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.9.34414.90
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VirtualStorageLibrary", "AkiraNetwork\VirtualStorageLibrary\VirtualStorageLibrary.csproj", "{5A5196A7-5006-40ED-9FEE-45830834E4D4}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VirtualStorageLibrary.Test", "AkiraNetwork\VirtualStorageLibrary.Test\VirtualStorageLibrary.Test.csproj", "{0663E095-E958-44A4-8137-174F9872CC5F}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "documents", "documents", "{3C77738F-41D5-4A1B-A323-A8A813B7ECE6}"
11 | ProjectSection(SolutionItems) = preProject
12 | documents\aboutme.ja.md = documents\aboutme.ja.md
13 | documents\aboutme.md = documents\aboutme.md
14 | documents\docfx.json = documents\docfx.json
15 | documents\getting-started.ja.md = documents\getting-started.ja.md
16 | documents\getting-started.md = documents\getting-started.md
17 | documents\index.ja.md = documents\index.ja.md
18 | documents\index.md = documents\index.md
19 | documents\introduction.ja.md = documents\introduction.ja.md
20 | documents\introduction.md = documents\introduction.md
21 | documents\licenses.md = documents\licenses.md
22 | documents\toc.yml = documents\toc.yml
23 | EndProjectSection
24 | EndProject
25 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "images", "images", "{33E318B8-D84D-4F65-A581-89EA442E3E41}"
26 | ProjectSection(SolutionItems) = preProject
27 | documents\images\burner.png = documents\images\burner.png
28 | documents\images\index_tree1.png = documents\images\index_tree1.png
29 | documents\images\index_tree2.png = documents\images\index_tree2.png
30 | documents\images\index_tree3.png = documents\images\index_tree3.png
31 | documents\images\index_tree4.png = documents\images\index_tree4.png
32 | documents\images\index_tree5.png = documents\images\index_tree5.png
33 | documents\images\index_tree6A.png = documents\images\index_tree6A.png
34 | documents\images\index_tree6B.png = documents\images\index_tree6B.png
35 | documents\images\index_tree6C.png = documents\images\index_tree6C.png
36 | documents\images\tree.png = documents\images\tree.png
37 | documents\images\treetree_earthtones.webp = documents\images\treetree_earthtones.webp
38 | documents\images\tree_256x256.svg = documents\images\tree_256x256.svg
39 | documents\images\tree_32x32.svg = documents\images\tree_32x32.svg
40 | documents\images\tree_51x51.svg = documents\images\tree_51x51.svg
41 | documents\images\tree_banner_960x540.png = documents\images\tree_banner_960x540.png
42 | documents\images\tree_banner_960x540_1.png = documents\images\tree_banner_960x540_1.png
43 | documents\images\tree_banner_960x540_2.png = documents\images\tree_banner_960x540_2.png
44 | documents\images\tree_banner_960x540_3.png = documents\images\tree_banner_960x540_3.png
45 | documents\images\tree_banner_960x540_4.png = documents\images\tree_banner_960x540_4.png
46 | documents\images\tree_banner_960x540_5.png = documents\images\tree_banner_960x540_5.png
47 | documents\images\tree_banner_960x540_6.png = documents\images\tree_banner_960x540_6.png
48 | documents\images\tree_earthtones_240x240_trans.png = documents\images\tree_earthtones_240x240_trans.png
49 | documents\images\tree_earthtones_512x512.png = documents\images\tree_earthtones_512x512.png
50 | EndProjectSection
51 | EndProject
52 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "styles", "styles", "{9E8DC177-DE75-41E0-871A-141E672A7499}"
53 | ProjectSection(SolutionItems) = preProject
54 | documents\styles\an_custom.css = documents\styles\an_custom.css
55 | EndProjectSection
56 | EndProject
57 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{D732F07F-FD10-473B-AEA1-2CD979B1248E}"
58 | EndProject
59 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "material", "material", "{2A3765A1-0A3B-44A2-97B2-2B8389858FFF}"
60 | EndProject
61 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "public", "public", "{07FA2120-C263-484B-AB25-FF9B853A81A5}"
62 | ProjectSection(SolutionItems) = preProject
63 | documents\templates\material\public\main.css = documents\templates\material\public\main.css
64 | EndProjectSection
65 | EndProject
66 | Global
67 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
68 | Debug|Any CPU = Debug|Any CPU
69 | Release|Any CPU = Release|Any CPU
70 | EndGlobalSection
71 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
72 | {5A5196A7-5006-40ED-9FEE-45830834E4D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
73 | {5A5196A7-5006-40ED-9FEE-45830834E4D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
74 | {5A5196A7-5006-40ED-9FEE-45830834E4D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
75 | {5A5196A7-5006-40ED-9FEE-45830834E4D4}.Release|Any CPU.Build.0 = Release|Any CPU
76 | {0663E095-E958-44A4-8137-174F9872CC5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
77 | {0663E095-E958-44A4-8137-174F9872CC5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
78 | {0663E095-E958-44A4-8137-174F9872CC5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
79 | {0663E095-E958-44A4-8137-174F9872CC5F}.Release|Any CPU.Build.0 = Release|Any CPU
80 | EndGlobalSection
81 | GlobalSection(SolutionProperties) = preSolution
82 | HideSolutionNode = FALSE
83 | EndGlobalSection
84 | GlobalSection(NestedProjects) = preSolution
85 | {33E318B8-D84D-4F65-A581-89EA442E3E41} = {3C77738F-41D5-4A1B-A323-A8A813B7ECE6}
86 | {9E8DC177-DE75-41E0-871A-141E672A7499} = {3C77738F-41D5-4A1B-A323-A8A813B7ECE6}
87 | {D732F07F-FD10-473B-AEA1-2CD979B1248E} = {3C77738F-41D5-4A1B-A323-A8A813B7ECE6}
88 | {2A3765A1-0A3B-44A2-97B2-2B8389858FFF} = {D732F07F-FD10-473B-AEA1-2CD979B1248E}
89 | {07FA2120-C263-484B-AB25-FF9B853A81A5} = {2A3765A1-0A3B-44A2-97B2-2B8389858FFF}
90 | EndGlobalSection
91 | GlobalSection(ExtensibilityGlobals) = postSolution
92 | SolutionGuid = {6A8605B9-7762-4E7E-A370-79CD7536FFC8}
93 | EndGlobalSection
94 | EndGlobal
95 |
--------------------------------------------------------------------------------
/AkiraNetwork/VirtualStorageLibrary/WildcardMatchers/DefaultWildcardMatcher.cs:
--------------------------------------------------------------------------------
1 | // This file is part of VirtualStorageLibrary.
2 | //
3 | // Copyright (C) 2024 Akira Shimodate
4 | //
5 | // VirtualStorageLibrary is free software, and it is distributed under the terms of
6 | // the GNU Lesser General Public License (version 3, or at your option, any later
7 | // version). This license is published by the Free Software Foundation.
8 | //
9 | // VirtualStorageLibrary is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or
11 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 | // more details.
13 | //
14 | // You should have received a copy of the GNU Lesser General Public License along
15 | // with VirtualStorageLibrary. If not, see https://www.gnu.org/licenses/.
16 |
17 | using System.Collections.ObjectModel;
18 |
19 | namespace AkiraNetwork.VirtualStorageLibrary.WildcardMatchers
20 | {
21 | ///
22 | /// Implements default wildcard matching using regular expression patterns.
23 | /// Provides a straightforward mapping of regular expression symbols.
24 | ///
25 | public class DefaultWildcardMatcher : IVirtualWildcardMatcher
26 | {
27 | ///
28 | /// Dictionary mapping regular expression symbols to their literal equivalents.
29 | ///
30 | ///
31 | /// A read-only dictionary where the keys are regular expression symbols and the values
32 | /// are their literal equivalents.
33 | ///
34 | private static readonly ReadOnlyDictionary _wildcardDictionary = new(
35 | new Dictionary
36 | {
37 | { @".", @"." }, // Matches any single character
38 | { @"*", @"*" }, // Matches zero or more characters
39 | { @"+", @"+" }, // Matches one or more characters
40 | { @"?", @"?" }, // Matches zero or one character
41 | { @"^", @"^" }, // Start of line
42 | { @"$", @"$" }, // End of line
43 | { @"|", @"|" }, // OR condition
44 | { @"(", @"(" }, // Start of group
45 | { @")", @")" }, // End of group
46 | { @"[", @"[" }, // Start of character class
47 | { @"]", @"]" }, // End of character class
48 | { @"{", @"{" }, // Start of repetition
49 | { @"}", @"}" }, // End of repetition
50 | { @"\", @"\" } // Escape character
51 | });
52 |
53 | ///
54 | /// Gets the dictionary of regular expression symbols and their corresponding literals.
55 | ///
56 | ///
57 | /// A read-only dictionary where the keys are regular expression symbols and the values
58 | /// are their literal equivalents.
59 | ///
60 | public ReadOnlyDictionary WildcardDictionary => _wildcardDictionary;
61 |
62 | ///
63 | /// Gets the list of supported wildcard characters.
64 | ///
65 | ///
66 | /// A collection of supported wildcard characters.
67 | ///
68 | public IEnumerable Wildcards => _wildcardDictionary.Keys;
69 |
70 | ///
71 | /// Gets the list of regular expression patterns corresponding to the wildcard characters.
72 | ///
73 | ///
74 | /// A collection of regular expression patterns corresponding to the wildcard characters.
75 | ///
76 | public IEnumerable Patterns => _wildcardDictionary.Values;
77 |
78 | ///
79 | /// Gets the number of supported wildcard characters.
80 | ///
81 | ///
82 | /// The number of supported wildcard characters.
83 | ///
84 | public int Count => _wildcardDictionary.Count;
85 |
86 | ///
87 | /// Performs simple regular expression-based wildcard matching.
88 | ///
89 | /// The name of the node to match against the pattern.
90 | /// The regular expression pattern to use for matching.
91 | /// True if the node name matches the pattern; otherwise, false.
92 | public bool PatternMatcher(string nodeName, string pattern)
93 | {
94 | // Uses the pattern string as is for regular expression matching
95 | return Regex.IsMatch(nodeName, pattern);
96 | }
97 |
98 | ///
99 | /// Determines whether the specified wildcard pattern is valid according to the rules
100 | /// defined by the wildcard matcher implementation.
101 | /// This method checks if the wildcard pattern adheres to the syntax rules defined
102 | /// by the wildcard matcher implementation. If the pattern is not valid,
103 | /// this method returns false.
104 | ///
105 | /// The wildcard pattern to validate.
106 | ///
107 | /// true if the pattern is a valid wildcard pattern; otherwise, false.
108 | ///
109 | public bool IsValidWildcardPattern(string pattern)
110 | {
111 | try
112 | {
113 | // Uses the pattern string as is for regular expression matching
114 | _ = new Regex(pattern);
115 | return true;
116 | }
117 | catch (ArgumentException)
118 | {
119 | // If the regex pattern is not valid
120 | return false;
121 | }
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/docs/api/AkiraNetwork.VirtualStorageLibrary.WildcardMatchers.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Namespace AkiraNetwork.VirtualStorageLibrary.WildcardMatchers | VirtualStorageLibrary
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
Implements wildcard matching based on PowerShell's wildcard patterns.
94 | Provides pattern matching with support for specific escape characters.
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
107 |
108 |
109 |
110 |
111 |
112 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/AkiraNetwork/VirtualStorageLibrary/VirtualExtensions.cs:
--------------------------------------------------------------------------------
1 | // This file is part of VirtualStorageLibrary.
2 | //
3 | // Copyright (C) 2024 Akira Shimodate
4 | //
5 | // VirtualStorageLibrary is free software, and it is distributed under the terms of
6 | // the GNU Lesser General Public License (version 3, or at your option, any later
7 | // version). This license is published by the Free Software Foundation.
8 | //
9 | // VirtualStorageLibrary is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or
11 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 | // more details.
13 | //
14 | // You should have received a copy of the GNU Lesser General Public License along
15 | // with VirtualStorageLibrary. If not, see https://www.gnu.org/licenses/.
16 |
17 | namespace AkiraNetwork.VirtualStorageLibrary
18 | {
19 | ///
20 | /// Provides extension methods for various operations on collections in the Virtual Storage Library.
21 | ///
22 | public static class VirtualStorageExtensions
23 | {
24 | ///
25 | /// Groups and sorts the elements of the source sequence based on the specified conditions.
26 | ///
27 | /// The type of elements in the source sequence.
28 | /// The sequence of elements to group and sort.
29 | ///
30 | /// The condition that defines how to group the elements. If null, no grouping is applied.
31 | ///
32 | ///
33 | /// A list of conditions that define the sort order. If null or empty, no sorting is applied.
34 | ///
35 | /// An containing the grouped and sorted elements.
36 | public static IEnumerable GroupAndSort(
37 | this IEnumerable source,
38 | VirtualGroupCondition? groupCondition = null,
39 | List>? sortConditions = null)
40 | {
41 | var query = source.AsQueryable();
42 |
43 | if (groupCondition != null)
44 | {
45 | var groupedData = groupCondition.Ascending
46 | ? query.GroupBy(groupCondition.GroupBy).OrderBy(g => g.Key)
47 | : query.GroupBy(groupCondition.GroupBy).OrderByDescending(g => g.Key);
48 |
49 | // Apply additional sort conditions within each group
50 | return groupedData.SelectMany(group => group.ApplySortConditions(sortConditions));
51 | }
52 | else
53 | {
54 | // Apply sort conditions to the entire collection without grouping
55 | return query.ApplySortConditions(sortConditions);
56 | }
57 | }
58 |
59 | ///
60 | /// Applies the specified sort conditions to the elements of the source sequence.
61 | ///
62 | /// The type of elements in the source sequence.
63 | /// The sequence of elements to sort.
64 | ///
65 | /// A list of conditions that define the sort order. If null or empty, no sorting is applied.
66 | ///
67 | /// An containing the sorted elements.
68 | public static IEnumerable ApplySortConditions(
69 | this IEnumerable source,
70 | List>? sortConditions = null)
71 | {
72 | if (sortConditions == null || sortConditions.Count == 0)
73 | {
74 | return source;
75 | }
76 |
77 | IQueryable sourceQuery = source.AsQueryable();
78 | IOrderedQueryable? orderedQuery = null;
79 |
80 | for (int i = 0; i < sortConditions.Count; i++)
81 | {
82 | var condition = sortConditions[i];
83 | if (orderedQuery == null)
84 | {
85 | // Apply the first sort condition
86 | orderedQuery = condition.Ascending
87 | ? sourceQuery.AsQueryable().OrderBy(condition.SortBy)
88 | : sourceQuery.AsQueryable().OrderByDescending(condition.SortBy);
89 | }
90 | else
91 | {
92 | // Apply subsequent sort conditions
93 | orderedQuery = condition.Ascending
94 | ? orderedQuery.ThenBy(condition.SortBy)
95 | : orderedQuery.ThenByDescending(condition.SortBy);
96 | }
97 | }
98 |
99 | return orderedQuery!;
100 | }
101 | }
102 |
103 | ///
104 | /// Provides extension methods for operations on virtual nodes in the Virtual Storage Library.
105 | ///
106 | public static class VirtualNodeExtensions
107 | {
108 | ///
109 | /// Resolves the type of the specified virtual node. If the node is a symbolic link,
110 | /// returns the type of the target node. Otherwise, returns the type of the node itself.
111 | ///
112 | /// The virtual node to resolve the type for.
113 | ///
114 | /// The type of the node or, if the node is a symbolic link, the type of the target node.
115 | ///
116 | public static VirtualNodeType ResolveNodeType(this VirtualNode node)
117 | {
118 | if (node is VirtualSymbolicLink link)
119 | {
120 | return link.TargetNodeType;
121 | }
122 | return node.NodeType;
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/AkiraNetwork/VirtualStorageLibrary/VirtualException.cs:
--------------------------------------------------------------------------------
1 | // This file is part of VirtualStorageLibrary.
2 | //
3 | // Copyright (C) 2024 Akira Shimodate
4 | //
5 | // VirtualStorageLibrary is free software, and it is distributed under the terms of
6 | // the GNU Lesser General Public License (version 3, or at your option, any later
7 | // version). This license is published by the Free Software Foundation.
8 | //
9 | // VirtualStorageLibrary is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or
11 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 | // more details.
13 | //
14 | // You should have received a copy of the GNU Lesser General Public License along
15 | // with VirtualStorageLibrary. If not, see https://www.gnu.org/licenses/.
16 |
17 | namespace AkiraNetwork.VirtualStorageLibrary
18 | {
19 | ///
20 | /// The base class for exceptions that occur within the virtual storage library.
21 | ///
22 | public abstract class VirtualException : Exception
23 | {
24 | ///
25 | /// Initializes a new instance of the class.
26 | ///
27 | public VirtualException() { }
28 |
29 | ///
30 | /// Initializes a new instance of the class with a specified error message.
31 | ///
32 | /// The error message.
33 | public VirtualException(string message) : base(message) { }
34 |
35 | ///
36 | /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception.
37 | ///
38 | /// The error message.
39 | /// The exception that is the cause of this exception.
40 | public VirtualException(string message, Exception innerException) : base(message, innerException) { }
41 | }
42 |
43 | ///
44 | /// The base exception that is thrown when an entity is not found in the virtual storage.
45 | ///
46 | public class VirtualNotFoundException : VirtualException
47 | {
48 | ///
49 | /// Initializes a new instance of the class.
50 | ///
51 | public VirtualNotFoundException() { }
52 |
53 | ///
54 | /// Initializes a new instance of the class with a specified error message.
55 | ///
56 | /// The error message.
57 | public VirtualNotFoundException(string message) : base(message) { }
58 |
59 | ///
60 | /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception.
61 | ///
62 | /// The error message.
63 | /// The exception that is the cause of this exception.
64 | public VirtualNotFoundException(string message, Exception innerException) : base(message, innerException) { }
65 | }
66 |
67 | ///
68 | /// The exception that is thrown when a node is not found in the virtual storage.
69 | ///
70 | public class VirtualNodeNotFoundException : VirtualNotFoundException
71 | {
72 | ///
73 | /// Initializes a new instance of the class.
74 | ///
75 | public VirtualNodeNotFoundException() { }
76 |
77 | ///
78 | /// Initializes a new instance of the class with a specified error message.
79 | ///
80 | /// The error message.
81 | public VirtualNodeNotFoundException(string message) : base(message) { }
82 |
83 | ///
84 | /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception.
85 | ///
86 | /// The error message.
87 | /// The exception that is the cause of this exception.
88 | public VirtualNodeNotFoundException(string message, Exception innerException) : base(message, innerException) { }
89 | }
90 |
91 | ///
92 | /// The exception that is thrown when a path is not found in the virtual storage.
93 | ///
94 | public class VirtualPathNotFoundException : VirtualNotFoundException
95 | {
96 | ///
97 | /// Initializes a new instance of the class.
98 | ///
99 | public VirtualPathNotFoundException() { }
100 |
101 | ///
102 | /// Initializes a new instance of the class with a specified error message.
103 | ///
104 | /// The error message.
105 | public VirtualPathNotFoundException(string message) : base(message) { }
106 |
107 | ///
108 | /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception.
109 | ///
110 | /// The error message.
111 | /// The exception that is the cause of this exception.
112 | public VirtualPathNotFoundException(string message, Exception innerException) : base(message, innerException) { }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/documents/introduction.ja.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction"
3 | ---
4 |
5 | 
6 |
7 |
8 | Language: Japanese
9 |
VirtualStorageLibrary is free software. This software is distributed under the terms of the GNU Lesser General
82 | Public License v3.0 or (at your option) any later version. VirtualStorageLibrary is distributed in
83 | the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
84 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
85 | A copy of the GNU Lesser General Public License is saved in the LICENSE file at the root of the repository. If
86 | not provided, you can also view it here.
87 |
Future Commercial License
88 |
We are considering offering a commercial license for VirtualStorageLibrary in the future. For more details or to inquire about the commercial license, please contact us at akiranetwork211@gmail.com.
13 |
14 |
15 |
16 | #### 私について
17 |
18 | こんにちは、あきらです。日本人です。
19 |
20 | この文章は私のキャリアサマリー(職歴、業種、スキルの経歴)というよりも、私の半生を簡単にまとめたものである事を明記しておきます。少しでも私の人となりを知っていただければ幸いです。
21 |
22 | 私の主な興味はプログラミングともう一つあります。
23 |
24 | #### 幼少期
25 |
26 | 私は1971年に生まれました。小学生時代、まだ、パソコンがマイコンと呼ばれていた時代、私はプログラミング言語BASICに出会いました。お小遣いをためて購入したNEC PC-6001mk2でBASICを楽しみました。これが人生で最初のプログラミングライフでした。カセットテープなどの外部記憶装置を持っていなかったので、プログラムを作って実行してはクリアし、また別のプログラムを作る、という事をしていました。
27 |
28 | #### 高校時代
29 |
30 | その後、中学時代を経て、新座総合技術高等学校という当時としては割合珍しい形態の学校に入学しました。この学校は、電子機械科、情報技術科、服飾デザイン科、工業デザイン科、食物調理科、情報処理科が設置されており、専門学校の様な学校でした(現在は科名や構成が変更されています)。当時の私はプログラミングの仕事を目指していた為、その種の大学か専門学校を探していたので、私にとって理想的な学校でした。そこでプログラミングとコンピュータの基礎を学びました。FORTRANで開発したプログラムがプログラミングコンテストで入賞した事もありました。
31 |
32 | #### 会社時代
33 |
34 | 高校を卒業後、東京にあるIT関連の会社に就職しました。その時はOS関係の何らかの仕事に就きたいと思いその会社を選んだのですが、実際に配属されたのは別の部署でした。最初の仕事はあるOS上で動作するプログラムを別のOSで動作するようにするという言語移植の仕事でした。つまり、ある言語で作られたプログラムを別の言語に書き換えて動作させるという仕事です。これは技術的に困難な仕事でしたがチームで力を結集し、無事、プロジェクトを完了させる事ができました。その後も非常に多くのシステム開発に携わり、多くの困難を乗り越えてきました。
35 |
36 | #### チーム
37 |
38 | キャリアを重ねるという事は、自分に後輩ができ、自分がチームリーダーになる事もある、という事でもあります。チームリーダーはチーム全体を管理し、プロジェクトの計画、実施、検証までもフォーカスしなければなりません。その為、非常に高いストレスを抱えることもあります。それでも小さなプロジェクトをチームで進めていく事にはやりがいがありました。
39 |
40 | #### 歯車
41 |
42 | その会社でのキャリアの末期、私は非常に大きなプロジェクトに配属されました。大企業の指揮のもと、複数の協力会社と共に、かなり大きな、そしてかなり古い既存システムを作り直すというプロジェクトでした。そのシステムは複数のサブシステムで構成されていて、私はそのサブシステムの開発チームのリーダーに選ばれました。そのチームは複数の協力会社のメンバーで構成されていました。非常にタイトなスケジュール、開発費用の計算、品質保証の計画と実施、他チームとの調整等々、やるべき事が非常に多く、私の負担は大きくなりストレスを抱える事になりました。
43 |
44 | #### ひび割れ
45 |
46 | もともとそのサブシステムは別の人がリーダーをやっていました。しかし、その人が適任ではないという上司の判断で急遽、私が呼ばれたという経緯がありました。その為、プロジェクトに途中で参加した私は知識不足の状態であり、また、他チームの信頼もない、という状況であった為、ストレスに追い打ちをかける事になりました。上司も非常に怖い人だったので相談もできなかったのです。私はチームメンバーともうまくいかなくなり、プロジェクトの運用に支障をきたすようになりました。
47 |
48 | #### キャリアブレイク
49 |
50 | やがて私はうつ病になり、その頃に親戚の紹介で出会った女性との結婚もダメになりました。そして、会社を退社して自宅で療養する事になりました。幸い私の場合は後天的なうつなので比較的軽い方ではありましたが、私自身の感覚では「何も考えたくない」「動きたくない」という酷い状態でした。約一年、自宅で療養し、その後、障害者施設で数年間を過ごしました。障害者施設は、生活のリズムを整える事、社会と関わり続ける事、障害の理解を深める事、この三つの役割があります。
51 |
52 | #### 障害者施設
53 |
54 | 障害者は毎日、決まった時間に通所し、決まった時間に退所します。これは障害者にとって非常に基本的で非常に大切な行動の反復練習に他なりません。健常者にとっては普通にできることであっても、簡単にできない人も世の中にはいるという事です。通所した障害者は、スタッフの指導のもと、リクリエーションでお互いにコミュニケーションをとりあったり、簡単な内職の作業をして、生活のリズムを整えます。私が利用した施設ではお菓子やケーキを作り、市営の店に卸したり、市内のお祭りで販売をしたりしていました。このような地道な活動によって、障害者は社会と接点を持ち、自分に対する認識を少しずつポジティブな方向へ改める事ができるのです。
55 |
56 | #### 就労継続支援施設
57 |
58 | 障害者施設を卒業した私は、次に就労継続支援施設に行きました。私が行ったのはA型の施設なので、一般の会社が運営している障害者向けの就労施設です。雇用形態はパートタイマーとなっており短時間からの就労が可能です。一般の会社での就労とは異なり、労働環境についてある程度は配慮されるという特徴があります。また、定期的な面談もあります。
59 |
60 | #### しいたけ栽培
61 |
62 | 私は障害者施設時代、植物を育てる事に喜びを感じるようになりました。障害者施設では一年草などの植物を育て市内の公園に配布するなどの作業もあり、私もその活動に携わっていたのです。就労継続支援施設では、菌床しいたけの栽培を行い、そのしいたけを近隣のスーパーに卸していました。つまり農業の事業であり、労働者が障害者という形です。しいたけは植物ではありませんが、育てる事に喜びを感じていた私はしいたけ栽培に対してもまじめに取り組むようになりました。時にはスーパーで試食販売をする事もあり、お客さんのダイレクトな反応を見る事に充実感を味わう事もありました。
63 |
64 | #### 労働者の負担
65 |
66 | 就労継続支援施設は一般の会社が運営しているとは言え、資金が潤沢にあるというわけではありません。その施設において利用している障害者が数十人いるのに対し、管理する社員は数人。その為、障害者自らが判断し自らが動かなければならないという状況もたまにあります。当時、この施設ではしいたけ栽培の生産管理をMicrosoft Excelで行っていました。生産量の入力は利用者が行って、その集計を社員が手動で行う、という形でした。社員が別の仕事で忙しいときは利用者が代わりに行うという事も高頻度でありました。施設に来てから2年くらい経過したある日、社員から私にデータを管理するシステムが作れないかという相談がありました。私は利用者の作業の負担を減らしたいと考えていたので了承しました。もちろん特別手当が支給されるわけでもなく、通常の栽培業務をやらなくてもいい、というわけでもありません。通常の栽培業務と調整しながら同時並行で開発してほしい、という事でした。
67 |
68 | #### データ管理システム
69 |
70 | データ管理システムは、大きく分けて生産管理、販売管理の二つのコンポーネントで構成されています。生産管理は私が担当し、販売管理はその社員が担当という事になりました。環境はMicrosoft Access, Microsoft Excel, Form, VBAという組み合わせです。Accessで品質毎に入力された収穫量をもとに、自動起動したExcelで週単位の収穫量、生産棚毎の収穫量を集計しレポートにまとめ、それを毎朝、栽培棟内の掲示板に貼り出す、という流れです。このシステムが完成し一緒に働く仲間たちがオペレーションを覚え、運用が軌道に乗った時、私たちの負担が大きく軽減されました。その事は、その当時の私にとって大きな喜びでした。今でも本当に作って良かった思います。
71 |
72 | #### 新しい仕事
73 |
74 | データ管理システムの開発を終えた頃、私は今のしいたけ栽培とは別の何か新しい仕事を始めたいと考えるようになりました。ここを卒業して健常者として仕事をして収入を得たいと考えました。いろいろ探していくうちに、農業が面白そうだと考え、いくつか農作業のスタッフ募集に応募をしてみましたが、全て断られました。基本的には近隣在住である事が条件のようでした。次に私はオンラインスクールに興味を持ち、やってみようと思いました。オンラインスクールは場所と時間に縛られない働き方が出来、私にはとても眩しく見えたのです。就労継続支援施設を辞めた後、オンラインスクールでしいたけ栽培のスクールを開こうと準備を進めました。しかし、最後の段階で「本当にこれが自分がやりたい事なのか?」と疑問を持つようになりました。どうしてもこのスクールの将来がイメージとして浮かびませんでした。オンラインスクールをやってみたいという動機のひとつに、就労継続支援施設時代の賃金の安さに不満があり、オンラインスクールでもっと稼ぎたい、という動機があった事も事実です。本来、オンラインスクールは、お客様に大切な何かを伝える手段の一つであって、それが全てはない、という事です。私の動機は全くの逆に思えたのでした。しいたけ栽培のノウハウをそこまで情熱的に伝えたいと思ってなかったのです。この期間は4か月間で最後は貯金が底をつきました。
75 |
76 | #### 倉庫の仕事
77 |
78 | 私は生活費を稼ぐために倉庫の仕事に就きました。自宅から近く、勤務形態もパートタイマーなので短時間で働く事ができました。最初の一か月は真面目に働いていましたが、そのうちにこの仕事へのモチベーションが維持できなくなりました。本来、私はクリエイターという体質、性格なのです。何かをゼロから生み出したい、それによって問題を解決し、その問題に関わる多くの人々を少しでも幸せにしたい、そんなエネルギーに突き動かされて、過去にはプログラミングの仕事をしてきました。だから、「生活費を稼ぐ為」という動機だけでは、どんな仕事であろうとも私は続けることが出来ないのです。私はだんだん体調を崩しやすくなり、仕事を休みがちになりました。
79 |
80 | #### 霊性の目覚め
81 |
82 | 私は幼少の頃から何か不思議で神秘的なものに興味を惹かれていました。といって、何か特別な霊能力があるわけでもなく、幽霊が見えたりする事もありません。しかし、直感だけは昔から鋭かったと思います。就労継続支援施設時代、私は自分のこれまでの人生を振り返る事が多くありました。自分が地球に生まれた理由、生きる目的、死んだ後は何があるのか、この世以外に世界はあるのか、神は存在するのか、多くの疑問が芽生えました。多くの考察をし、多くの情報に触れ、多くの導きを得ました。この様な内観的な状況の変化はありつつも、この地球世界は同時に進行し、目を開ければ倉庫の仕事をしている自分に気づくのです。時には涙が出る事さえありました。
83 |
84 | #### 本当にやりたい事
85 |
86 | バシャールは言います「やりたい事は本当にやりたい事ではない。本当にやりたい事は既にやっている事だ」。私はこの言葉を知った時「今、既にやっている事はなんだろう?」と自分に問いました。「もちろんプログラミングだ」と答えました。「昔から大好きなプログラミングをする事が今の自分がやりたい事だし、やっている事だ。そして、今の自分を支えている事だし、自分を高い波動に維持し続ける事だ」。体力的にも精神的にもつらい倉庫の仕事を休んでプログラミングに夢中になる時、それは私にとっては癒しでもありました。外から見ればただのさぼりであり、社会的には非難されるものでしょう。しかし、その時の私にはそれが避難場所であったのです。本当にそうするしかなかった。
87 |
88 | 
89 |
90 | #### 今、やっている事
91 |
92 | 倉庫の仕事を辞めた。収入がゼロの状態。カード会社への多額の返済の当てもない。多分、もう少し時間がたてばスマートフォンで電話やネットをする事すらできなくなる。高級外車を乗り回し、やりたい事をやって、高級な食べ物を食べ、海外旅行に行っている人達を何度、うらやんだ事か。
93 |
94 | だけど、今、ボクはやりたい事をやっている。プログラミングだ。自分の中にある強烈な衝動に素直に従っている状態。クリエイティブなエネルギーの奔流が今のボクを突き動かしている。やればやるほど、やりたい事がインスピレーションとなってボクに流れ込んでくる。
95 |
96 | そして、このプログラミングのエネルギーが落ち着けば、また、別のクリエイティブなエネルギーがボクに流れ込んでくるだろう、という事も分かっている。いずれはネパールに渡り、子供たちの面倒を見る、という魂の計画はまた、別の話だ。まだ、ボクにもよく観えていない。いつか別れた彼女と再会できたら、どんなに幸せな事だろう。彼女はボクにとってのソウルパートナーなんだ。彼女と一緒にこの計画を実行できる事を毎日、祈ってる。
97 |
98 | さて、ボクのプログラミングしたオープンソースライブラリはスポンサーを募る予定だ。だけど、スポンサーがいつ付くのか分からない。だから、当面の資金繰りをどうすべきか非常に悩んでる。資金というより、生活費だけどね。地球という3次元の物理世界で活動するのは、とても勇気がいる事だし、とても大変なんだよ。
99 |
100 | 正直に言おう。どなたか支援して頂けないだろうか。
101 |
--------------------------------------------------------------------------------
/AkiraNetwork/VirtualStorageLibrary/VirtualNodeContext.cs:
--------------------------------------------------------------------------------
1 | // This file is part of VirtualStorageLibrary.
2 | //
3 | // Copyright (C) 2024 Akira Shimodate
4 | //
5 | // VirtualStorageLibrary is free software, and it is distributed under the terms of
6 | // the GNU Lesser General Public License (version 3, or at your option, any later
7 | // version). This license is published by the Free Software Foundation.
8 | //
9 | // VirtualStorageLibrary is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or
11 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 | // more details.
13 | //
14 | // You should have received a copy of the GNU Lesser General Public License along
15 | // with VirtualStorageLibrary. If not, see https://www.gnu.org/licenses/.
16 |
17 | namespace AkiraNetwork.VirtualStorageLibrary
18 | {
19 | ///
20 | /// A class that holds context information for a node.
21 | /// It is returned during or after path traversal, providing information about the node, path,
22 | /// parent directory, depth, index, resolved path, and symbolic link.
23 | ///
24 | [DebuggerStepThrough]
25 | public class VirtualNodeContext
26 | {
27 | ///
28 | /// Gets the node and can only be set within the assembly.
29 | ///
30 | ///
31 | /// The current node.
32 | ///
33 | public VirtualNode? Node { get; internal set; }
34 |
35 | ///
36 | /// Gets the traversal path and can only be set within the assembly.
37 | ///
38 | ///
39 | /// The path used for node traversal.
40 | ///
41 | public VirtualPath TraversalPath { get; internal set; }
42 |
43 | ///
44 | /// Gets the parent directory of the node and can only be set within the assembly.
45 | ///
46 | ///
47 | /// The instance of the parent directory.
48 | ///
49 | public VirtualDirectory? ParentDirectory { get; internal set; }
50 |
51 | ///
52 | /// Gets the depth of the node and can only be set within the assembly.
53 | /// The root is considered 0.
54 | ///
55 | ///
56 | /// The depth of the node.
57 | ///
58 | public int Depth { get; internal set; }
59 |
60 | ///
61 | /// Gets the index of the node and can only be set within the assembly.
62 | /// This is the index corresponding to the enumeration order within the directory.
63 | ///
64 | ///
65 | /// The index of the node.
66 | ///
67 | public int Index { get; internal set; }
68 |
69 | ///
70 | /// Gets the resolved path and can only be set within the assembly.
71 | /// This represents the result of resolving a symbolic link.
72 | ///
73 | ///
74 | /// The resolved path, or null.
75 | ///
76 | public VirtualPath? ResolvedPath { get; internal set; }
77 |
78 | ///
79 | /// Gets a value indicating whether the symbolic link has been resolved and can only
80 | /// be set within the assembly.
81 | ///
82 | ///
83 | /// True if the link is resolved; otherwise, false.
84 | ///
85 | public bool Resolved { get; internal set; }
86 |
87 | ///
88 | /// Gets the resolved symbolic link and can only be set within the assembly.
89 | ///
90 | ///
91 | /// The resolved symbolic link, or null.
92 | ///
93 | public VirtualSymbolicLink? ResolvedLink { get; internal set; }
94 |
95 | ///
96 | /// Initializes a new instance of the class.
97 | ///
98 | /// The node being traversed.
99 | /// The path used for node traversal.
100 | /// The parent directory of the node.
101 | /// The depth of the node. The root is considered 0.
102 | /// The index of the node. Corresponds to the enumeration order within the directory.
103 | /// The result of resolving a symbolic link.
104 | /// Indicates whether the symbolic link has been resolved.
105 | /// The resolved symbolic link.
106 | public VirtualNodeContext(
107 | VirtualNode? node,
108 | VirtualPath traversalPath,
109 | VirtualDirectory? parentNode = null,
110 | int depth = 0,
111 | int index = 0,
112 | VirtualPath? resolvedPath = null,
113 | bool resolved = false,
114 | VirtualSymbolicLink? resolvedLink = null)
115 | {
116 | Node = node;
117 | TraversalPath = traversalPath;
118 | ParentDirectory = parentNode;
119 | Depth = depth;
120 | Index = index;
121 | ResolvedPath = resolvedPath;
122 | Resolved = resolved;
123 | ResolvedLink = resolvedLink;
124 | }
125 |
126 | ///
127 | /// Returns a string representation of this instance's information.
128 | ///
129 | /// A string representing this instance's information.
130 | public override string ToString()
131 | {
132 | List parts =
133 | [
134 | $"Node: {Node}",
135 | $"TraversalPath: {TraversalPath}",
136 | $"ParentDirectory: {ParentDirectory}",
137 | $"Depth: {Depth}",
138 | $"Index: {Index}"
139 | ];
140 |
141 | if (ResolvedPath != null)
142 | {
143 | parts.Add($"ResolvedPath: {ResolvedPath}");
144 | }
145 |
146 | parts.Add($"Resolved: {Resolved}");
147 | parts.Add($"ResolvedLink: {ResolvedLink}");
148 |
149 | return string.Join(", ", parts);
150 | }
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/AkiraNetwork/VirtualStorageLibrary/VirtualStorageSettings.cs:
--------------------------------------------------------------------------------
1 | // This file is part of VirtualStorageLibrary.
2 | //
3 | // Copyright (C) 2024 Akira Shimodate
4 | //
5 | // VirtualStorageLibrary is free software, and it is distributed under the terms of
6 | // the GNU Lesser General Public License (version 3, or at your option, any later
7 | // version). This license is published by the Free Software Foundation.
8 | //
9 | // VirtualStorageLibrary is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or
11 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 | // more details.
13 | //
14 | // You should have received a copy of the GNU Lesser General Public License along
15 | // with VirtualStorageLibrary. If not, see https://www.gnu.org/licenses/.
16 |
17 | namespace AkiraNetwork.VirtualStorageLibrary
18 | {
19 | ///
20 | /// Manages settings for the virtual storage. This class implements the singleton pattern
21 | /// and holds default settings and various parameters.
22 | ///
23 | [DebuggerStepThrough]
24 | public class VirtualStorageSettings
25 | {
26 | private static VirtualStorageSettings _settings = new();
27 |
28 | ///
29 | /// Gets the current instance of the settings.
30 | ///
31 | ///
32 | /// The current instance of .
33 | ///
34 | public static VirtualStorageSettings Settings => _settings;
35 |
36 | ///
37 | /// Initializes a new instance of the VirtualStorageSettings class with default settings.
38 | ///
39 | private VirtualStorageSettings()
40 | {
41 | InvalidNodeNameCharacters = [PathSeparator];
42 | InvalidNodeNames = [PathDot, PathDotDot];
43 |
44 | WildcardMatcher = new PowerShellWildcardMatcher();
45 |
46 | NodeListConditions = new()
47 | {
48 | Filter = VirtualNodeTypeFilter.All,
49 | GroupCondition = new(node => node.ResolveNodeType(), true),
50 | SortConditions =
51 | [
52 | new(node => node.Name, true)
53 | ]
54 | };
55 | }
56 |
57 | ///
58 | /// Initializes the settings. Existing settings are reset, and default settings
59 | /// are applied.
60 | ///
61 | public static void Initialize()
62 | {
63 | _settings = new();
64 |
65 | // Apply settings to state
66 | VirtualStorageState.InitializeFromSettings(_settings);
67 | }
68 |
69 | ///
70 | /// Gets or sets the path separator character. The default value is '/'.
71 | ///
72 | ///
73 | /// The character used to separate path segments.
74 | ///
75 | public char PathSeparator { get; set; } = '/';
76 |
77 | ///
78 | /// Gets or sets the root path. The default value is "/".
79 | ///
80 | ///
81 | /// The root directory path in the virtual storage.
82 | ///
83 | public string PathRoot { get; set; } = "/";
84 |
85 | ///
86 | /// Gets or sets the path representing the current directory. The default value
87 | /// is ".".
88 | ///
89 | ///
90 | /// The representation of the current directory.
91 | ///
92 | public string PathDot { get; set; } = ".";
93 |
94 | ///
95 | /// Gets or sets the path representing the parent directory. The default value
96 | /// is "..".
97 | ///
98 | ///
99 | /// The representation of the parent directory.
100 | ///
101 | public string PathDotDot { get; set; } = "..";
102 |
103 | ///
104 | /// Gets or sets an array of characters that are invalid in node names.
105 | ///
106 | ///
107 | /// An array of characters that cannot be used in node names.
108 | ///
109 | public HashSet InvalidNodeNameCharacters { get; set; }
110 |
111 | ///
112 | /// Gets or sets an array of invalid node names.
113 | ///
114 | ///
115 | /// An array of node names that are not allowed in the virtual storage.
116 | ///
117 | public HashSet InvalidNodeNames { get; set; }
118 |
119 | ///
120 | /// Gets or sets the wildcard matcher.
121 | ///
122 | ///
123 | /// The implementation of wildcard matching used in the storage.
124 | ///
125 | public IVirtualWildcardMatcher? WildcardMatcher { get; set; }
126 |
127 | ///
128 | /// Gets or sets the conditions for listing nodes.
129 | ///
130 | ///
131 | /// The conditions used to filter, group, and sort nodes.
132 | ///
133 | public VirtualNodeListConditions NodeListConditions { get; set; }
134 |
135 | ///
136 | /// Gets or sets the prefix used for item names. The default value is "item".
137 | /// Used for auto-generating node names.
138 | ///
139 | ///
140 | /// The prefix added to auto-generated item names.
141 | ///
142 | public string PrefixItem { get; set; } = "item";
143 |
144 | ///
145 | /// Gets or sets the prefix used for directory names. The default value is "dir".
146 | /// Used for auto-generating node names.
147 | ///
148 | ///
149 | /// The prefix added to auto-generated directory names.
150 | ///
151 | public string PrefixDirectory { get; set; } = "dir";
152 |
153 | ///
154 | /// Gets or sets the prefix used for symbolic link names. The default value is
155 | /// "link". Used for auto-generating node names.
156 | ///
157 | ///
158 | /// The prefix added to auto-generated symbolic link names.
159 | ///
160 | public string PrefixSymbolicLink { get; set; } = "link";
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/docs/api/AkiraNetwork.VirtualStorageLibrary.NotifyNodeDelegate.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Delegate NotifyNodeDelegate | VirtualStorageLibrary
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |