1 /*
2  *Copyright (C) 2018 Laurent Tréguier
3  *
4  *This file is part of DLS.
5  *
6  *DLS is free software: you can redistribute it and/or modify
7  *it under the terms of the GNU General Public License as published by
8  *the Free Software Foundation, either version 3 of the License, or
9  *(at your option) any later version.
10  *
11  *DLS is distributed in the hope that it will be useful,
12  *but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *GNU General Public License for more details.
15  *
16  *You should have received a copy of the GNU General Public License
17  *along with DLS.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 module dls.tools.tool;
22 
23 import dls.util.uri : Uri;
24 
25 alias Hook = void delegate(const Uri uri);
26 
27 class Tool
28 {
29     import dls.tools.configuration : Configuration;
30     import std.json : JSONValue;
31 
32     private static Tool _instance;
33     private static Configuration _globalConfig;
34     private static JSONValue[string] _workspacesConfigs;
35     private static Hook[string] _configHooks;
36 
37     @property Uri[] workspacesUris()
38     {
39         import std.algorithm : map, sort;
40         import std.array : array;
41 
42         return _workspacesConfigs.keys.sort().map!(u => Uri.fromPath(u)).array;
43     }
44 
45     static void initialize(Tool tool)
46     {
47         _instance = tool;
48         _globalConfig = new Configuration();
49     }
50 
51     static void shutdown()
52     {
53         _globalConfig = new Configuration();
54         _workspacesConfigs.clear();
55         _configHooks.clear();
56     }
57 
58     protected static Configuration getConfig(const Uri uri)
59     {
60         import dls.util.json : convertToJSON;
61 
62         if (uri is null || uri.path !in _workspacesConfigs)
63         {
64             return _globalConfig;
65         }
66 
67         auto config = new Configuration();
68         config.merge(convertToJSON(_globalConfig));
69         config.merge(_workspacesConfigs[uri.path]);
70         return config;
71     }
72 
73     @property static Tool instance()
74     {
75         return _instance;
76     }
77 
78     void updateConfig(const Uri uri, JSONValue json)
79     {
80         import dls.protocol.state : initState;
81 
82         if (uri is null || uri.path.length == 0)
83         {
84             _globalConfig.merge(json);
85         }
86         else
87         {
88             _workspacesConfigs[uri.path] = json;
89         }
90 
91         foreach (hook; _configHooks.byValue)
92         {
93             hook(uri is null ? initState.rootUri.isNull ? null : new Uri(initState.rootUri) : uri);
94         }
95     }
96 
97     void removeConfig(const Uri uri)
98     {
99         if (uri in _workspacesConfigs)
100         {
101             _workspacesConfigs.remove(uri.path);
102         }
103     }
104 
105     protected void addConfigHook(string name, Hook hook)
106     {
107         _configHooks[this.toString() ~ '/' ~ name] = hook;
108     }
109 
110     protected void removeConfigHooks()
111     {
112         import std.algorithm : startsWith;
113 
114         foreach (key; _configHooks.byKey)
115         {
116             if (key.startsWith(this.toString() ~ '/'))
117             {
118                 _configHooks.remove(key);
119             }
120         }
121     }
122 }