src/Palete/Palete.vala
[app.Builder.js] / src / Palete / Palete.vala
1
2 namespace Palete 
3 {
4
5
6         public errordomain Error {
7                 INVALID_TYPE,
8                 NEED_IMPLEMENTING,
9                 MISSING_FILE,
10                 INVALID_VALUE
11         }
12
13         public class Usage : Object 
14         {
15                 public Gee.ArrayList<string> left;
16                 public Gee.ArrayList<string> right;
17                 public Usage(Gee.ArrayList<string> ileft, Gee.ArrayList<string> iright)
18                 {
19                         this.left = ileft;
20                         this.right=  iright;
21                 }
22                 public bool leftHas(string s)
23                 {
24                         for(var i = 0 ; i < this.left.size; i++) {
25                                 var m = this.left.get(i);
26                                 if (s == m) {
27                                         return true;
28                                 }
29                                 if (!m.contains(":")) {
30                                         continue;
31                                 }
32                                 var ar = m.split(":");
33                                 if (ar[0] == s) {
34                                         return true;
35                                 }
36                         }
37                         return false;
38                                 
39                 }
40
41                 
42         }
43
44         
45
46     static Gee.HashMap<string,Palete>? cache = null;
47     
48     public static Palete factory(string xtype)
49     {
50         if (cache == null) {
51             cache = new Gee.HashMap<string,Palete>();
52         }
53         if (cache.get(xtype) != null) {
54             return cache.get(xtype);
55         }
56         switch(xtype) {
57             case "Gtk":
58                 cache.set(xtype, new Gtk());
59                 break;
60             case "Roo":
61                 cache.set(xtype, new Roo());
62                 break;
63             default:
64                 throw new Error.INVALID_TYPE("invalid argument to Palete factory");
65         }
66         return cache.get(xtype);
67     }
68        
69
70     public abstract class Palete : Object 
71     {
72         
73        
74         public string name;
75
76         public Gee.ArrayList<Usage> map;
77                 
78         public Palete()
79         {
80             // nothing?
81                 this.map = null;
82         }
83         
84         
85         //map : false, // array of mappings   left: [] , right : []
86         
87         //items : false, // the tree of nodes.
88         
89         
90
91
92         string  guessName(JsRender.Node ar) throws Error // turns the object into full name.
93         {
94             throw new Error.NEED_IMPLEMENTING("xxx. guessName needs implimenting");
95         }
96             
97
98             
99          
100
101             
102         public string[] getChildList(string in_rval)
103         {
104
105                 if (this.map == null) {
106                         this.load();
107                 }
108                 // empty == *top
109                 
110                 var rval = in_rval == "" ? "*top" : in_rval; 
111                                 
112                                 // should be a bit more than this..
113                         // -> it should look for all elements that inherit 
114                 string[] ret = {};
115                 var rt = new Gee.ArrayList<string>();
116                 for (var i = 0; i < this.map.size; i++) {
117                         var m = this.map.get(i);
118                                 
119                         if (!m.leftHas(rval)) {
120                                 continue;
121                         }
122                         print("found LEFT, adding right\n");
123                 
124                         for(var ii =0; ii < m.right.size; ii++) {
125                                 var l = m.right.get(ii);
126                                         
127                                 if (rt.index_of(l) > -1) {
128                                     continue;
129                                 }
130                                 //print("ADD " + string.joinv(", ", ret) + "\n");
131                                 ret += l;
132                                 rt.add(l);
133                         }
134                         
135                 
136                 }
137                 print ("drop list for %s is:\n%s\n", rval, string.joinv("\n", ret));
138                 //console.log("DROP LIST:");
139                 //console.dump(ret);
140                 return ret;
141             
142         }
143
144             
145         public string[] getDropList(string rval)
146         {
147
148                 if (this.map == null) {
149                         this.load();
150                 }
151
152                                 
153                                 // should be a bit more than this..
154                         // -> it should look for all elements that inherit 
155                 string[] ret = {};
156                 var rt = new Gee.ArrayList<string>();
157                 for (var i = 0; i < this.map.size; i++) {
158                         var m = this.map.get(i);
159                                 
160                         if (m.right.index_of(rval) < 0) {
161                                 continue;
162                         }
163                         //print("found RIGHT, adding left\n");
164                 
165                         for(var ii =0; ii < m.left.size; ii++) {
166                                 var l = m.left.get(ii);
167                                         
168                                 if (rt.index_of(l) > -1) {
169                                     continue;
170                                 }
171                                 //print("ADD " + string.joinv(", ", ret) + "\n");
172                                 ret += l;
173                                 rt.add(l);
174                         }
175                         
176                 
177                 }
178                  print ("drop list for %s is:\n%s\n", rval, string.joinv("\n", ret));
179                 //console.log("DROP LIST:");
180                 //console.dump(ret);
181                 return ret;
182             
183         }
184       
185         public void saveTemplate (string name, JsRender.Node data)
186         {
187
188                         var gn = data.fqn();
189             // store it in user's directory..
190             var appdir =  GLib.Environment.get_home_dir() + "/.Builder"; 
191
192                         
193             if (!GLib.FileUtils.test(appdir+ "/" + gn, GLib.FileTest.IS_DIR)) {
194                                 GLib.File.new_for_path (appdir+ "/" + gn).make_directory ();
195                                 
196             }
197             GLib.FileUtils.set_contents(appdir+ "/" + gn + "/" +  name + ".json", data.toJsonString());
198             
199         }
200         
201         /**
202          * list templates - in home directory (and app dir in future...)
203          * @param {String} name  - eg. Gtk.Window..
204          * @return {Array} list of templates available..
205          */
206           
207         public  GLib.List<string> listTemplates (JsRender.Node node)
208         {
209             
210                 var gn = node.fqn();
211             
212                 var ret = new GLib.List<string>();
213                 var dir= GLib.Environment.get_home_dir() + "/.Builder/" + gn;
214                 if (!GLib.FileUtils.test(dir, GLib.FileTest.IS_DIR)) {
215                         return ret;
216                 }
217                         
218
219
220                                     
221                 var f = File.new_for_path(dir);
222         
223             var file_enum = f.enumerate_children(GLib.FileAttribute.STANDARD_DISPLAY_NAME, GLib.FileQueryInfoFlags.NONE, null);
224              
225             FileInfo next_file; 
226             while ((next_file = file_enum.next_file(null)) != null) {
227                 var n = next_file.get_display_name();
228                         if (!Regex.match_simple ("\\.json$", n)) {
229                                         continue;
230                                 }
231                                 ret.append( dir + "/" + n);
232             }
233             return ret;
234             
235         }
236  
237         public JsRender.Node? loadTemplate(string path)
238         {
239
240                 var pa = new Json.Parser();
241                 pa.load_from_file(path);
242                 var node = pa.get_root();
243
244                 if (node.get_node_type () != Json.NodeType.OBJECT) {
245                         return null;
246                 }
247                 var obj = node.get_object ();
248
249                 var ret = new JsRender.Node();
250
251
252                 ret.loadFromJson(obj, 1);
253                 ret.ref(); // not sure if needed -- but we had a case where ret became uninitialized?
254                 
255                 return ret;
256          }
257
258
259
260     public   void  loadUsageFile (string fname) {
261
262
263
264                         
265                 print("Palete Load called\n");
266                 string raw;
267                 if (!FileUtils.test (fname, FileTest.EXISTS)) {
268                         throw new Error.MISSING_FILE(fname + " not found");
269                 }
270         
271                 FileUtils.get_contents(fname, out raw);
272               // print(data);
273                 var data  = raw.split("\n");
274                 var state = 0;
275                 var cfg = new Gee.ArrayList<Usage>();
276                 var left = new Gee.ArrayList<string>();
277                 var right = new Gee.ArrayList<string>();
278         
279                 for (var i = 0; i < data.length; i++) {
280                         var d = data[i].strip();
281                         //print("READ " + d + "\n");
282                         if (
283                                 d.length < 1
284                             ||
285                              Regex.match_simple ("^\\s+$", d)
286                             ||
287                                 Regex.match_simple ("^\\s*/", d)
288                      ){
289                             continue;
290                         }
291                                 
292                         if (Regex.match_simple ("^left:", d)) { 
293                             state = 1;
294                             if (left.size > 0 ){
295                                 cfg.add(new Usage( left, right));
296                                                 }
297                             left = new Gee.ArrayList<string>();
298                                         right = new Gee.ArrayList<string>();
299                             continue;
300                         }
301                          if (Regex.match_simple ("^right:", d)) { 
302                             state = 2;
303                             continue;
304                         }
305                         if (state == 1) {
306                                                 //print("add left: " + d + "\n");
307                             left.add(d);
308                             continue;
309                         }
310                                         //print("add Right: " + d + "\n");
311                         right.add(d);
312                         //Seed.quit();
313                        
314                 }
315                 if (left.size > 0 ){
316                         cfg.add(new Usage( left, right));
317                 }
318                 this.map = cfg;
319
320    }
321
322         
323           
324         public Gee.HashMap<int,string>  validateCode(
325                         string code, 
326                         string property, 
327                         string ptype,
328                         JsRender.JsRender file,
329                         JsRender.Node node
330                      ) 
331         {   
332
333                 //print("validate code (%s) %s\n", file.language, code);
334                  
335                 
336                 if (file.language == "js" && (ptype == "listener" || property[0] == '|')) {
337                         var ret = new Gee.HashMap<int,string>();
338                         
339                         //var cd = new JSCore.ClassDefinitionEmpty();
340                         string errmsg;
341                         var line = Javascript.singleton().validate(
342                                   "var __aaa___ = " + code, out errmsg);
343
344                         if (line < 0) {
345                                 return ret;
346                         }
347                         ret.set(line, errmsg);
348                         return ret;
349                 }
350                 if (file.language == "vala" ) { // not sure if we need to validate property
351                         
352                         var vs = new ValaSource(file);
353                         //var cd = new JSCore.ClassDefinitionEmpty();
354                         var ret = vs.checkFileWithNodePropChange(
355                                 node, 
356                                 property, 
357                                 ptype,
358                                 code
359                          );
360                         return ret;
361                 }
362                 var ret = new Gee.HashMap<int,string>();
363
364                 //print ("not javascript\n");
365                 return ret;
366
367         }
368
369             
370           
371         public abstract void fillPack(JsRender.Node node,JsRender.Node parent);
372         public abstract void load();
373         public abstract Gee.HashMap<string,GirObject> getPropertiesFor(string ename, string type);
374         public abstract GirObject? getClass(string ename);
375     }
376
377
378 }
379
380
381