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 abstract class Tool
28 {
29     import dls.tools.configuration : Configuration;
30     import std.json : JSONValue;
31 
32     private static Configuration _globalConfig;
33     private static JSONValue[string] _workspacesConfigs;
34     private static Hook[string] _configHooks;
35 
36     @property static Uri[] workspacesUris()
37     {
38         import std.algorithm : map, sort;
39         import std.array : array;
40 
41         return _workspacesConfigs.keys.sort().map!(u => Uri.fromPath(u)).array;
42     }
43 
44     static this()
45     {
46         _globalConfig = new Configuration();
47     }
48 
49     static void updateConfig(const Uri uri, JSONValue json)
50     {
51         import dls.protocol.state : initState;
52 
53         if (uri is null || uri.path.length == 0)
54         {
55             _globalConfig.merge(json);
56         }
57         else
58         {
59             _workspacesConfigs[uri.path] = json;
60         }
61 
62         foreach (hook; _configHooks.byValue)
63         {
64             hook(uri is null ? initState.rootUri.isNull ? null : new Uri(initState.rootUri) : uri);
65         }
66     }
67 
68     static void removeConfig(const Uri uri)
69     {
70         if (uri in _workspacesConfigs)
71         {
72             _workspacesConfigs.remove(uri.path);
73         }
74     }
75 
76     protected static Configuration getConfig(const Uri uri)
77     {
78         import dls.util.json : convertToJSON;
79 
80         if (uri is null || uri.path !in _workspacesConfigs)
81         {
82             return _globalConfig;
83         }
84 
85         auto config = new Configuration();
86         config.merge(convertToJSON(_globalConfig));
87         config.merge(_workspacesConfigs[uri.path]);
88         return config;
89     }
90 
91     protected void addConfigHook(string name, Hook hook)
92     {
93         _configHooks[this.toString() ~ '/' ~ name] = hook;
94     }
95 
96     protected void removeConfigHook(string name)
97     {
98         _configHooks.remove(this.toString() ~ '/' ~ name);
99     }
100 
101     static void initialize();
102     static void shutdown();
103     @property static T instance(T : Tool)();
104 }