server/src/main/webapp/static/js/models.js
changeset 47 267d67791e05
parent 45 37c9a17c3284
child 48 01fb9167ad75
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/models.js	Tue Dec 25 21:29:11 2012 +0100
@@ -0,0 +1,219 @@
+(function() {
+    
+    var root = this;
+        
+    var Backbone = root.Backbone;
+    
+    var Models = root.Rkns.Models = {};
+    
+    
+    Models.getUID = function(obj) {
+        var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+            var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
+            return v.toString(16);
+        });
+        return obj.type + "-" + guid; 
+    };
+    
+    
+    var RenkanModel = Backbone.RelationalModel.extend({
+        idAttribute : "_id",
+        constructor: function(options) {
+            
+            if (typeof options !== "undefined") {
+                options._id = options._id || options.id || Models.getUID(this);
+                options.title = options.title || "(untitled " + this.type + ")";
+                options.description = options.description || "";
+                options.uri = options.uri || "";
+                
+                if(typeof this.prepare === "function") {
+                    options = this.prepare(options);
+                }
+            }
+            Backbone.RelationalModel.prototype.constructor.call(this, options);
+        },
+        validate: function() {
+            if(!this.type) {
+                return "object has no type";
+            }
+        },
+        addReference : function(_options, _propName, _list, _id, _default) {
+            var _element = _list.get(_id);
+            if (typeof _element === "undefined" && typeof _default !== "undefined") {
+                _options[_propName ] = _default;
+            }
+            else {
+                _options[_propName ] = _element;
+            }
+        }
+    });
+        
+    // USER
+    var User = Models.User = RenkanModel.extend({
+        type: "user",
+        prepare: function(options) {
+            options.color = options.color || "#666666";
+            return options;
+        },
+        toJSON: function() {
+            return {
+                _id: this.get("_id"),
+                title: this.get("title"),
+                uri: this.get("uri"),
+                description: this.get("description"),
+                color: this.get("color"),
+            };
+        },
+    });
+    
+    // NODE
+    var Node = Models.Node = RenkanModel.extend({
+        type: "node",
+        relations: [{
+            type: Backbone.HasOne,
+            key: "created_by",
+            relatedModel: User
+        }],
+        prepare: function(options) {
+            project = options.project;
+            this.addReference(options, "created_by", project.get("users"), options.created_by, project.current_user);
+            options.description = options.description || "";
+            return options;
+        },
+        toJSON: function() {
+            return {
+                _id: this.get("_id"),
+                title: this.get("title"),
+                uri: this.get("uri"),
+                description: this.get("description"),
+                position: this.get("position"),
+                image: this.get("image"),
+                created_by: this.get("created_by") ? this.get("created_by").get("_id") : null
+            };
+        },
+    });
+    
+    // EDGE
+    var Edge = Models.Edge = RenkanModel.extend({
+        type: "edge",
+        relations: [
+          {
+            type: Backbone.HasOne,
+            key: "created_by",
+            relatedModel: User
+          },
+          {
+            type: Backbone.HasOne,
+            key: "from",
+            relatedModel: Node
+          },
+          {
+            type: Backbone.HasOne,
+            key: "to",
+            relatedModel: Node
+          },
+        ],
+        prepare: function(options) {
+            project = options.project;
+            this.addReference(options, "created_by", project.get("users"), options.created_by, project.current_user);
+            this.addReference(options, "from", project.get("nodes"), options.from);
+            this.addReference(options, "to", project.get("nodes"), options.to);
+            return options;
+        },
+        toJSON: function() {
+            return {
+                _id: this.get("_id"),
+                title: this.get("title"),
+                uri: this.get("uri"),
+                description: this.get("description"),
+                from: this.get("from") ? this.get("from").get("_id") : null,
+                to: this.get("to") ? this.get("to").get("_id") : null,
+                created_by: this.get("created_by") ? this.get("created_by").get("_id") : null
+            };
+        },
+    });
+        
+    // PROJECT
+    var Project = Models.Project = RenkanModel.extend({
+        type: "project",
+        relations: [
+          {
+            type: Backbone.HasMany,
+            key: "users",
+            relatedModel: User,
+            reverseRelation: {
+                key: 'project',
+                includeInJSON: '_id'
+            },
+          },
+          {
+            type: Backbone.HasMany,
+            key: "nodes",
+            relatedModel: Node,
+            reverseRelation: {
+                key: 'project',
+                includeInJSON: '_id'
+            },
+          },
+          {
+            type: Backbone.HasMany,
+            key: "edges",
+            relatedModel: Edge,
+            reverseRelation: {
+                key: 'project',
+                includeInJSON: '_id'
+            },
+          }
+        ],
+        addUser: function(_props) {
+            _props.project = this;
+            var _user = new User(_props);
+            this.get("users").push(_user);
+            return _user;
+        },
+        addNode: function(_props) {
+            _props.project = this;
+            var _node = new Node(_props);
+            this.get("nodes").push(_node);
+            return _node;
+        },
+        addEdge: function(_props) {
+            _props.project = this;
+            var _edge = new Edge(_props);
+            this.get("edges").push(_edge);
+            return _edge;
+        },
+        removeNode: function(_model) {
+            this.get("nodes").remove(_model);
+        },
+        removeEdge: function(_model) {
+            this.get("edges").remove(_model);
+        },
+        validate: function(options) {
+            var _project = this;
+            _(options.users).each(function(_item) {
+                _item.project = _project;
+            });
+            _(options.nodes).each(function(_item) {
+                _item.project = _project;
+            });
+            _(options.edges).each(function(_item) {
+                _item.project = _project;
+            });
+        },
+        // Add event handler to remove edges when a node is removed
+        initialize: function() {
+            var _this = this;
+            this.on("remove:nodes", function(_node) {
+                _this.get("edges").remove(
+                    _this.get("edges").filter(function(_edge) {
+                        return _edge.get("from") == _node || _edge.get("to") == _node;
+                    })
+                );
+            });
+        }
+    });
+    
+
+}).call(window);
+