1 /**
2  * JSON Loader
3  *
4  * Copyright: (c) 2015-2016, Milofon Project.
5  * License: Subject to the terms of the BSD license, as written in the included LICENSE.txt file.
6  * Authors: Maksim Galanin
7  */
8 module proped.loaders.json;
9 
10 
11 private
12 {
13     import std.file : FileException, readText;
14 
15     import std.json;
16 
17     import proped.properties : Properties, PropNode;
18     import proped.loader : PropertiesLoader;
19     import proped.exception : PropertiesException;
20 }
21 
22 
23 /**
24  * The loader data from a JSON file
25  *
26  * Implements PropertiesLoader
27  */
28 class JSONPropertiesLoader : PropertiesLoader
29 {
30     /**
31      * Loading properties from a file
32      *
33      * Params:
34      *
35      * fileName = Path to the file system
36      */
37     Properties loadPropertiesFile(string fileName)
38     {
39         try 
40         {
41             string source = readText(fileName);       
42             return loadPropertiesString(source);
43         }
44         catch (FileException e)
45             throw new PropertiesException("Error loading properties from a file '" ~ fileName ~ "':", e);
46     }
47 
48 
49     /**
50      * Loading properties from a string
51      *
52      * Params:
53      *
54      * data = Source string
55      */
56     Properties loadPropertiesString(string data)
57     {
58         JSONValue root;
59         try
60             root = parseJSON(data);
61         catch (JSONException e)
62             throw new PropertiesException("Error loading properties from a string:", e);
63 
64         return toProperties(root);
65     }
66 
67 
68     private Properties toProperties(JSONValue root)
69     {
70         PropNode convert(JSONValue node)
71         {
72             switch(node.type) with (JSON_TYPE)
73             {
74                 case NULL:
75                     return PropNode();
76                 case TRUE:
77                     return PropNode(true);
78                 case FALSE:
79                     return PropNode(false);
80                 case INTEGER:
81                 case UINTEGER:
82                     return PropNode(node.integer);
83                 case FLOAT:
84                     return PropNode(node.floating);
85                 case STRING:
86                     return PropNode(node.str);
87                 case ARRAY: 
88                 {
89                     PropNode[] arr;
90                     foreach(JSONValue ch; node.array)
91                         arr ~= convert(ch);
92                     return PropNode(arr);
93                 }
94                 case OBJECT:
95                 {
96                     PropNode[string] map;
97                     foreach(string key, JSONValue ch; node.object)
98                         map[key] = convert(ch);
99 
100                     return PropNode(map);
101                 }
102                 default:
103                     return PropNode();
104             }
105         }
106 
107         return Properties(convert(root));
108     }
109 
110 
111     /**
112      * Returns the file extension to delermite the type loader
113      */
114     string[] getExtensions()
115     {
116         return [".json"];
117     }
118 }
119