1 //<Script type="text/javascript">
6 * Projects can only contain one directory... - it can import other projects..(later)
8 * we need to sort out that - paths is currently a key/value array..
14 public errordomain Error {
21 // static array of all projects.
22 public Gee.HashMap<string,Project> projects;
23 public bool projects_loaded = false;
26 public class Project : Object {
28 public signal void on_changed ();
31 public string fn = ""; // just a md5...
32 public string name = "";
33 public string runhtml = "";
34 public string base_template = "";
35 public string rootURL = "";
36 public Gee.HashMap<string,string> paths;
37 public Gee.HashMap<string,JsRender.JsRender> files ;
44 public Project (string path) {
46 this.name = GLib.Path.get_basename(path); // default..
48 this.is_scanned = false;
49 this.paths = new Gee.HashMap<string,string>();
50 this.files = new Gee.HashMap<string,JsRender.JsRender>();
51 //XObject.extend(this, cfg);
53 if (path.length > 0) {
54 this.paths.set(path, "dir");
65 public static void loadAll(bool force = false)
67 if (projects_loaded && !force) {
71 var dirname = GLib.Environment.get_home_dir() + "/.Builder";
72 var dir = File.new_for_path(dirname);
73 if (!dir.query_exists()) {
77 projects = new Gee.HashMap<string,Project>();
81 var file_enum = dir.enumerate_children(
82 GLib.FileAttribute.STANDARD_DISPLAY_NAME,
83 GLib.FileQueryInfoFlags.NONE,
89 while ((next_file = file_enum.next_file(null)) != null) {
90 var fn = next_file.get_display_name();
91 if (!Regex.match_simple("\\.json$", fn)) {
94 factoryFromFile(dirname + "/" + fn);
97 print("oops - something went wrong scanning the projects\n");
103 public static Gee.ArrayList<Project> allProjectsByName()
105 var ret = new Gee.ArrayList<Project>();
106 var iter = projects.map_iterator();
107 while (iter.next()) {
108 ret.add(iter.get_value());
115 public static Project? getProject(string name)
117 if (projects.has_key(name)) {
118 return projects.get(name);
123 // load project data from project file.
124 public static void factoryFromFile(string jsonfile)
127 print("parse %s\n", jsonfile);
129 var pa = new Json.Parser();
130 pa.load_from_file(jsonfile);
131 var node = pa.get_root();
134 if (node == null || node.get_node_type () != Json.NodeType.OBJECT) {
135 print("SKIP " + jsonfile + " - invalid format?\n");
139 var obj = node.get_object ();
140 var xtype = obj.get_string_member("xtype");
142 var proj = factory(xtype, "");
144 proj.fn = Path.get_basename(jsonfile).split(".")[0];
148 if (obj.has_member("runhtml")) {
149 proj.runhtml = obj.get_string_member("runhtml");
152 if (obj.has_member("base_template")) {
153 proj.base_template = obj.get_string_member("base_template");
156 if (obj.has_member("rootURL")) {
157 proj.rootURL = obj.get_string_member("rootURL");
160 proj.name = obj.get_string_member("name");
162 var paths = obj.get_object_member("paths");
163 paths.foreach_member((sobj, key, val) => {
164 proj.paths.set(key, "dir");
166 projects.set(proj.name,proj);
170 public static Project factory(string xtype, string path)
173 // check to see if it's already loaded..
176 var iter = projects.map_iterator();
177 while (iter.next()) {
178 if (iter.get_value().hasPath( path)) {
179 return iter.get_value();
186 return new Gtk(path);
188 return new Roo(path);
190 throw new Error.INVALID_TYPE("invalid project type");
193 public static void remove(Project project)
196 var dirname = GLib.Environment.get_home_dir() + "/.Builder";
198 FileUtils.unlink(dirname + "/" + project.fn + ".json");
199 projects.unset(project.name,null);
209 if (this.fn.length < 1) {
210 // make the filename..
211 //var t = new DateTime.now_local ();
213 //t.to_timeval(out tv);
214 //var str = "%l:%l".printf(tv.tv_sec,tv.tv_usec);
215 var str = this.firstPath();
217 this.fn = GLib.Checksum.compute_for_string(GLib.ChecksumType.MD5, str, str.length);
220 var dirname = GLib.Environment.get_home_dir() + "/.Builder";
221 var s = this.toJSON(false);
222 FileUtils.set_contents(dirname + "/" + this.fn + ".json", s, s.length);
229 public string toJSON(bool show_all)
232 var builder = new Json.Builder ();
234 builder.begin_object ();
236 builder.set_member_name ("name");
237 builder.add_string_value (this.name);
240 builder.set_member_name ("fn");
241 builder.add_string_value (this.fn);
243 builder.set_member_name ("xtype");
244 builder.add_string_value (this.xtype);
246 builder.set_member_name ("runhtml");
247 builder.add_string_value (this.runhtml);
250 builder.set_member_name ("rootURL");
251 builder.add_string_value (this.rootURL);
253 builder.set_member_name ("base_template");
254 builder.add_string_value (this.base_template);
255 // file ??? try/false?
256 builder.set_member_name ("paths");
259 builder.begin_object ();
262 var iter = this.paths.map_iterator();
263 while (iter.next()) {
264 builder.set_member_name (iter.get_key());
265 builder.add_string_value("path");
267 builder.end_object ();
270 builder.set_member_name ("files");
271 builder.begin_array ();
272 var fiter = this.files.map_iterator();
273 while (fiter.next()) {
274 builder.add_string_value (fiter.get_key());
278 builder.end_array ();
282 builder.end_object ();
284 var generator = new Json.Generator ();
285 var root = builder.get_root ();
286 generator.set_root (root);
288 generator.pretty = true;
289 generator.indent = 4;
292 return generator.to_data (null);
296 public string firstPath()
298 var iter = this.paths.map_iterator();
299 while (iter.next()) {
300 return iter.get_key();
306 public bool hasPath(string path)
308 var iter = this.paths.map_iterator();
309 while (iter.next()) {
310 if (iter.get_key() == path) {
319 // returns the first path
320 public string getName()
322 var iter = this.paths.map_iterator();
323 while (iter.next()) {
324 return GLib.Path.get_basename(iter.get_key());
330 public Gee.ArrayList<JsRender.JsRender> sortedFiles()
332 var files = new Gee.ArrayList<JsRender.JsRender>();
334 var fiter = this.files.map_iterator();
335 while(fiter.next()) {
336 files.add(fiter.get_value());
338 files.sort((fa,fb) => {
339 return ((JsRender.JsRender)fa).name.collate(((JsRender.JsRender)fb).name);
347 public JsRender.JsRender? getByName(string name)
350 var fiter = files.map_iterator();
351 while(fiter.next()) {
353 var f = fiter.get_value();
356 print ("Project.getByName: %s ?= %s\n" ,f.name , name);
357 if (f.name == name) {
364 public JsRender.JsRender? getById(string id)
367 var fiter = files.map_iterator();
368 while(fiter.next()) {
370 var f = fiter.get_value();
373 //console.log(f.id + '?=' + id);
381 public JsRender.JsRender newFile (string name)
383 var ret = JsRender.JsRender.factory(this.xtype,
385 this.firstPath() + "/" + name + ".bjs");
390 public JsRender.JsRender loadFileOnly (string path)
393 return JsRender.JsRender.factory(xt, this, path);
397 public JsRender.JsRender create(string filename)
399 var ret = this.loadFileOnly(filename);
407 public void addFile(JsRender.JsRender pfile) { // add a single file, and trigger changed.
410 this.files.set(pfile.path, pfile); // duplicate check?
414 public void add(string path, string type)
416 this.paths.set(path,type);
417 //Seed.print(" type is '" + type + "'");
420 // console.dump(this.files);
422 if (type == "file" ) {
424 this.files.set(path,this.loadFileOnly( path ));
429 public void scanDirs() // cached version
431 if (this.is_scanned) {
434 this.scanDirsForce();
435 //console.dump(this.files);
439 public void scanDirsForce()
441 this.is_scanned = true;
442 var iter = this.paths.map_iterator();
443 while (iter.next()) {
444 //print("path: " + iter.get_key() + " : " + iter.get_value() +"\n");
445 if (iter.get_value() != "dir") {
448 this.scanDir(iter.get_key());
450 //console.dump(this.files);
454 public void scanDir(string dir, int dp =0 )
457 //print("Project.Base: Running scandir on " + dir +"\n");
458 if (dp > 5) { // no more than 5 deep?
461 // this should be done async -- but since we are getting the proto up ...
463 var subs = new GLib.List<string>();;
464 var f = File.new_for_path(dir);
466 var file_enum = f.enumerate_children(GLib.FileAttribute.STANDARD_DISPLAY_NAME, GLib.FileQueryInfoFlags.NONE, null);
470 while ((next_file = file_enum.next_file(null)) != null) {
471 var fn = next_file.get_display_name();
474 //print("trying" + dir + "/" + fn +"\n");
476 if (fn[0] == '.') { // skip hidden
480 if (FileUtils.test(dir + "/" + fn, GLib.FileTest.IS_DIR)) {
481 subs.append(dir + "/" + fn);
485 if (!Regex.match_simple("\\.bjs$", fn)) {
486 //print("no a bjs\n");
493 var sp = dir.split("/");
495 for (var i = 0; i < sp.length; i++) {
500 sp = sp.splice(sp.length - (dp +1), (dp +1));
501 parent = sp.join('.');
504 if (typeof(_this.files[dir + '/' + fn]) != 'undefined') {
505 // we already have it..
506 _this.files[dir + '/' + fn].parent = parent;
511 var el = JsRender.JsRender.factory(xt,this, dir + "/" + fn);
512 this.files.set( dir + "/" + fn, el);
518 print("Project::scanDirs failed : " + e.message + "\n");
519 } catch (GLib.Error e) {
520 print("Project::scanDirs failed : " + e.message + "\n");
522 for (var i = 0; i < subs.length(); i++) {
524 this.scanDir(subs.nth_data(i), dp+1);