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 {
22 // static array of all projects.
23 public Gee.HashMap<string,Project> projects;
26 public bool projects_loaded = false;
29 public class Project : Object {
31 public signal void on_changed ();
34 public string fn = ""; // just a md5...
35 public string name = "";
36 public string runhtml = "";
37 public string base_template = "";
38 public string rootURL = "";
39 public Gee.HashMap<string,string> paths;
40 public Gee.HashMap<string,JsRender.JsRender> files ;
44 public Json.Object json_project_data;
45 public Palete.RooDatabase roo_database;
50 public Project (string path) {
52 this.name = GLib.Path.get_basename(path); // default..
53 this.json_project_data = new Json.Object();
55 this.is_scanned = false;
56 this.paths = new Gee.HashMap<string,string>();
57 this.files = new Gee.HashMap<string,JsRender.JsRender>();
58 //XObject.extend(this, cfg);
60 if (path.length > 0) {
61 this.paths.set(path, "dir");
63 // dummy roo database...
64 this.initRooDatabase();
69 public void initRooDatabase()
72 this.roo_database = new Palete.RooDatabase.from_project(this);
77 public static void loadAll(bool force = false)
79 if (projects_loaded && !force) {
83 var dirname = GLib.Environment.get_home_dir() + "/.Builder";
84 var dir = File.new_for_path(dirname);
85 if (!dir.query_exists()) {
89 projects = new Gee.HashMap<string,Project>();
93 var file_enum = dir.enumerate_children(
94 GLib.FileAttribute.STANDARD_DISPLAY_NAME,
95 GLib.FileQueryInfoFlags.NONE,
101 while ((next_file = file_enum.next_file(null)) != null) {
102 var fn = next_file.get_display_name();
103 if (!Regex.match_simple("\\.json$", fn)) {
106 factoryFromFile(dirname + "/" + fn);
109 GLib.warning("oops - something went wrong scanning the projects\n");
115 public static Gee.ArrayList<Project> allProjectsByName()
117 var ret = new Gee.ArrayList<Project>();
118 var iter = projects.map_iterator();
119 while (iter.next()) {
120 ret.add(iter.get_value());
127 public static Project getProject(string name)
130 var iter = projects.map_iterator();
131 while (iter.next()) {
132 if (iter.get_value().name == name) {
133 return iter.get_value();
142 public static string listAllToString()
144 var all = new Gee.ArrayList<Project>();
146 var fiter = projects.map_iterator();
148 while(fiter.next()) {
149 all.add(fiter.get_value());
152 all.sort((fa,fb) => {
153 return ((Project)fa).name.collate(((Project)fb).name);
157 var iter = all.list_iterator();
158 var ret = "ID\tName\tDirectory\n";
159 while (iter.next()) {
160 ret += "%s\t%s\t%s\n".printf(
163 iter.get().firstPath()
175 public static Project getProjectByHash(string fn)
178 var iter = projects.map_iterator();
179 while (iter.next()) {
180 if (iter.get_value().fn == fn) {
181 return iter.get_value();
190 // load project data from project file.
191 public static void factoryFromFile(string jsonfile)
194 GLib.debug("parse %s", jsonfile);
196 var pa = new Json.Parser();
197 pa.load_from_file(jsonfile);
198 var node = pa.get_root();
201 if (node == null || node.get_node_type () != Json.NodeType.OBJECT) {
202 GLib.debug("SKIP " + jsonfile + " - invalid format?");
206 var obj = node.get_object ();
207 var xtype = obj.get_string_member("xtype");
210 var paths = obj.get_object_member("paths");
213 paths.foreach_member((sobj, key, val) => {
221 var proj = factory(xtype, fpath);
223 proj.json_project_data = obj; // store the original object...
225 proj.fn = Path.get_basename(jsonfile).split(".")[0];
229 if (obj.has_member("runhtml")) {
230 proj.runhtml = obj.get_string_member("runhtml");
233 if (obj.has_member("base_template")) {
234 proj.base_template = obj.get_string_member("base_template");
237 if (obj.has_member("rootURL")) {
238 proj.rootURL = obj.get_string_member("rootURL");
241 proj.name = obj.get_string_member("name");
244 paths.foreach_member((sobj, key, val) => {
245 proj.paths.set(key, "dir");
247 proj.initRooDatabase();
249 GLib.debug("Add Project %s", proj.id);
251 projects.set(proj.id,proj);
259 public static Project factory(string xtype, string path)
262 // check to see if it's already loaded..
265 var iter = projects.map_iterator();
266 while (iter.next()) {
267 if (iter.get_value().hasPath( path)) {
268 return iter.get_value();
275 return new Gtk(path);
277 return new Roo(path);
279 throw new Error.INVALID_TYPE("invalid project type");
285 public static void remove(Project project)
288 var dirname = GLib.Environment.get_home_dir() + "/.Builder";
290 FileUtils.unlink(dirname + "/" + project.fn + ".json");
291 projects.unset(project.id,null);
301 if (this.fn.length < 1) {
302 // make the filename..
303 //var t = new DateTime.now_local ();
305 //t.to_timeval(out tv);
306 //var str = "%l:%l".printf(tv.tv_sec,tv.tv_usec);
307 var str = this.firstPath();
309 this.fn = GLib.Checksum.compute_for_string(GLib.ChecksumType.MD5, str, str.length);
312 var dirname = GLib.Environment.get_home_dir() + "/.Builder";
313 var s = this.toJSON(false);
314 FileUtils.set_contents(dirname + "/" + this.fn + ".json", s, s.length);
321 public string toJSON(bool show_all)
325 this.json_project_data.set_string_member("name", this.name);
326 this.json_project_data.set_string_member("fn", this.fn);
327 this.json_project_data.set_string_member("xtype", this.xtype);
328 this.json_project_data.set_string_member("runhtml", this.runhtml);
329 this.json_project_data.set_string_member("rootURL", this.rootURL);
330 this.json_project_data.set_string_member("base_template", this.base_template);
331 this.json_project_data.set_string_member("rootURL", this.rootURL);
333 var paths = new Json.Object();
336 var iter = this.paths.map_iterator();
337 while (iter.next()) {
338 paths.set_string_member(iter.get_key(), "path");
340 this.json_project_data.set_object_member("paths", paths);
344 var files = new Json.Array();
347 var fiter = this.files.map_iterator();
348 while (fiter.next()) {
349 files.add_string_element (fiter.get_key());
351 this.json_project_data.set_array_member("files", files);
356 var generator = new Json.Generator ();
357 var root = new Json.Node(Json.NodeType.OBJECT);
358 root.init_object(this.json_project_data);
359 generator.set_root (root);
361 generator.pretty = true;
362 generator.indent = 4;
365 return generator.to_data (null);
369 public string firstPath()
371 var iter = this.paths.map_iterator();
372 while (iter.next()) {
373 return iter.get_key();
379 public bool hasPath(string path)
381 var iter = this.paths.map_iterator();
382 while (iter.next()) {
383 if (iter.get_key() == path) {
392 // returns the first path
393 public string getName()
395 var iter = this.paths.map_iterator();
396 while (iter.next()) {
397 return GLib.Path.get_basename(iter.get_key());
403 public Gee.ArrayList<JsRender.JsRender> sortedFiles()
405 var files = new Gee.ArrayList<JsRender.JsRender>();
407 var fiter = this.files.map_iterator();
408 while(fiter.next()) {
409 files.add(fiter.get_value());
411 files.sort((fa,fb) => {
412 return ((JsRender.JsRender)fa).name.collate(((JsRender.JsRender)fb).name);
421 public string listAllFilesToString()
424 var iter = this.sortedFiles().list_iterator();
425 var ret = "ID\tName\tDirectory\n";
426 while (iter.next()) {
427 ret += "%s\n".printf(
443 public JsRender.JsRender? getByName(string name)
446 var fiter = files.map_iterator();
447 while(fiter.next()) {
449 var f = fiter.get_value();
452 GLib.debug ("Project.getByName: %s ?= %s" ,f.name , name);
453 if (f.name == name) {
459 public JsRender.JsRender? getByPath(string path)
462 var fiter = files.map_iterator();
463 while(fiter.next()) {
465 var f = fiter.get_value();
468 //GLib.debug ("Project.getByName: %s ?= %s" ,f.name , name);
469 if (f.path == path) {
476 public JsRender.JsRender? getById(string id)
479 var fiter = files.map_iterator();
480 while(fiter.next()) {
482 var f = fiter.get_value();
485 //console.log(f.id + '?=' + id);
493 public JsRender.JsRender newFile (string name)
495 var ret = JsRender.JsRender.factory(this.xtype,
497 this.firstPath() + "/" + name + ".bjs");
502 public JsRender.JsRender loadFileOnly (string path)
505 return JsRender.JsRender.factory(xt, this, path);
509 public JsRender.JsRender create(string filename)
511 var ret = this.loadFileOnly(filename);
519 public void addFile(JsRender.JsRender pfile) { // add a single file, and trigger changed.
522 this.files.set(pfile.path, pfile); // duplicate check?
526 public void add(string path, string type)
528 this.paths.set(path,type);
529 //Seed.print(" type is '" + type + "'");
532 // console.dump(this.files);
534 if (type == "file" ) {
536 this.files.set(path,this.loadFileOnly( path ));
541 public void scanDirs() // cached version
543 if (this.is_scanned) {
546 this.scanDirsForce();
547 //console.dump(this.files);
551 public void scanDirsForce()
553 this.is_scanned = true;
554 var iter = this.paths.map_iterator();
555 while (iter.next()) {
556 //print("path: " + iter.get_key() + " : " + iter.get_value() +"\n");
557 if (iter.get_value() != "dir") {
560 this.scanDir(iter.get_key());
562 //console.dump(this.files);
566 public void scanDir(string dir, int dp =0 )
569 //print("Project.Base: Running scandir on " + dir +"\n");
570 if (dp > 5) { // no more than 5 deep?
573 // this should be done async -- but since we are getting the proto up ...
575 var subs = new GLib.List<string>();;
576 var f = File.new_for_path(dir);
578 var file_enum = f.enumerate_children(GLib.FileAttribute.STANDARD_DISPLAY_NAME, GLib.FileQueryInfoFlags.NONE, null);
582 while ((next_file = file_enum.next_file(null)) != null) {
583 var fn = next_file.get_display_name();
586 //print("trying" + dir + "/" + fn +"\n");
588 if (fn[0] == '.') { // skip hidden
592 if (FileUtils.test(dir + "/" + fn, GLib.FileTest.IS_DIR)) {
593 subs.append(dir + "/" + fn);
597 if (!Regex.match_simple("\\.bjs$", fn)) {
598 //print("no a bjs\n");
605 var sp = dir.split("/");
607 for (var i = 0; i < sp.length; i++) {
612 sp = sp.splice(sp.length - (dp +1), (dp +1));
613 parent = sp.join('.');
616 if (typeof(_this.files[dir + '/' + fn]) != 'undefined') {
617 // we already have it..
618 _this.files[dir + '/' + fn].parent = parent;
623 var el = JsRender.JsRender.factory(xt,this, dir + "/" + fn);
624 this.files.set( dir + "/" + fn, el);
630 GLib.warning("Project::scanDirs failed : " + e.message + "\n");
631 } catch (GLib.Error e) {
632 GLib.warning("Project::scanDirs failed : " + e.message + "\n");
634 for (var i = 0; i < subs.length(); i++) {
636 this.scanDir(subs.nth_data(i), dp+1);
640 // wrapper around the javascript data...
641 public string get_string_member(string key) {
643 if (!this.json_project_data.has_member(key)) {
646 var ret = this.json_project_data.get_string_member(key);