First draft for Jcr nodes data model.
authorCharles du Jeu <charles.dujeu@gmail.com>
Tue, 27 Apr 2010 18:15:59 +0000 (18:15 +0000)
committerCharles du Jeu <charles.dujeu@gmail.com>
Tue, 27 Apr 2010 18:15:59 +0000 (18:15 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@3504 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/Manifest.json [new file with mode: 0644]
server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/JcrBrowser.js [new file with mode: 0644]
server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/model/AbstractItem.js [new file with mode: 0644]
server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/model/DataModel.js [new file with mode: 0644]
server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/model/Node.js [new file with mode: 0644]
server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/model/Property.js [new file with mode: 0644]
server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/provider/INodeProvider.js [new file with mode: 0644]
server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/provider/XmlNodeProvider.js [new file with mode: 0644]
server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/views/XmlNodeEditor.js [new file with mode: 0644]

diff --git a/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/Manifest.json b/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/Manifest.json
new file mode 100644 (file)
index 0000000..01fab47
--- /dev/null
@@ -0,0 +1,34 @@
+{\r
+  "info" : \r
+  {\r
+    "name" : "org.argeo.jcr.ria",\r
+\r
+    "summary" : "Jcr Ria library",\r
+    "description" : "Utilities for JCR RIA",\r
+    \r
+    "homepage" : "http://www.argeo.org/",\r
+\r
+    "license" : "LGPL",\r
+    "authors" : \r
+    [\r
+      {\r
+        "name" : "Charles du Jeu",\r
+        "email" : "charles.dujeu@gmail.com"\r
+      }\r
+    ],\r
+\r
+    "version" : "trunk",\r
+    "qooxdoo-versions": ["0.8"]\r
+  },\r
+  \r
+  "provides" : \r
+  {\r
+    "namespace"   : "org.argeo.jcr.ria",\r
+    "encoding"    : "utf-8",\r
+    "class"       : "class",\r
+    "resource"    : "resource",\r
+    "translation" : "translation",\r
+    "type"        : "library"\r
+  }\r
+}\r
+\r
diff --git a/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/JcrBrowser.js b/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/JcrBrowser.js
new file mode 100644 (file)
index 0000000..4e36ba1
--- /dev/null
@@ -0,0 +1,58 @@
+/**\r
+ * IPerspective Implementation : Horizontal split pane defining two panes, "list" and "applet".\r
+ */\r
\r
+/* ************************************************************************\r
+\r
+************************************************************************ */ \r
+qx.Class.define("org.argeo.jcr.ria.JcrBrowser",\r
+{\r
+  extend : qx.core.Object,\r
+  implement : [org.argeo.ria.components.IPerspective], \r
+  \r
+  construct : function(){\r
+               this.base(arguments);\r
+               org.argeo.ria.util.Element.DEFAULT_NAMESPACE_MAP = {slc:"http://argeo.org/projects/slc/schemas"};\r
+  },\r
+  \r
+  statics : {\r
+       LABEL : "JCR Browser",\r
+       ICON : "org.argeo.slc.ria/utilities-terminal.png"\r
+       //ROLES_RESTRICTION : ["ROLE_ADMIN"]\r
+  },\r
+  \r
+  members : {\r
+       _splitPane : null,      \r
+       \r
+       initViewPanes : function(viewsManager){\r
+               \r
+               this._splitPane = new qx.ui.splitpane.Pane("horizontal");\r
+               var mainPane = new org.argeo.ria.components.ViewPane("fulltree", "Full Tree");\r
+               this._splitPane.add(mainPane, 1);\r
+               viewsManager.registerViewPane(mainPane);      \r
+               /*\r
+               var uploadPane = new org.argeo.ria.components.ViewPane("upload", "Upload a distribution");\r
+               this._splitPane.add(uploadPane, 1);\r
+               viewsManager.registerViewPane(uploadPane);   \r
+               */   \r
+               viewsManager.getViewPanesContainer().add(this._splitPane, {flex:1});\r
+               \r
+       },\r
+       \r
+       initViews : function(viewsManager){\r
+               var nodeProvider = new org.argeo.jcr.ria.provider.XmlNodeProvider();\r
+               nodeProvider.initProvider({xmlSrc : "/org.argeo.slc.webapp/getJcrItem.jcr?path=/slc/testresults"})              \r
+               var rootNode = new org.argeo.jcr.ria.model.Node("Root", true);                  \r
+               rootNode.setNodeProvider(nodeProvider);\r
+               //rootNode.load();\r
+               var testView = viewsManager.initIViewClass(org.argeo.jcr.ria.views.XmlNodeEditor, "fulltree");\r
+               testView.load(rootNode);\r
+       },\r
+       \r
+       remove : function(viewsManager){\r
+               viewsManager.getViewPanesContainer().remove(this._splitPane);           \r
+       }\r
+       \r
+  }\r
+\r
+});
\ No newline at end of file
diff --git a/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/model/AbstractItem.js b/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/model/AbstractItem.js
new file mode 100644 (file)
index 0000000..21de4a4
--- /dev/null
@@ -0,0 +1,50 @@
+qx.Class.define("org.argeo.jcr.ria.model.AbstractItem", \r
+{\r
+       type : "abstract",\r
+       extend : qx.core.Object,\r
+       \r
+       properties : {\r
+               path : {\r
+                       check : "String"\r
+               },\r
+               name : {\r
+                       check : "String"\r
+               },\r
+               newItem : {\r
+                       check : "Boolean",\r
+                       event : "changeNew"\r
+               },\r
+               modified : {\r
+                       check : "Boolean",\r
+                       event : "changeModified"\r
+               },\r
+               node : {\r
+                       check : "Boolean",\r
+                       init : true\r
+               },\r
+               parent : {\r
+                       check : "org.argeo.jcr.ria.model.AbstractItem", \r
+                       nullable : true,\r
+                       init : null\r
+               },\r
+               root : {\r
+                       check : "org.argeo.jcr.ria.model.AbstractItem"                  \r
+               }\r
+       },\r
+       \r
+       members : {\r
+               itemIsRoot : function(){\r
+                       return (this.getRoot() == this);\r
+               },\r
+               fromDomElement : function(domElement){\r
+                       // TO BE IMPLEMENTED BY SUBCLASSES\r
+               },\r
+               toXmlString : function(){\r
+                       // TO BE IMPLEMENTED BY SUBCLASSES                      \r
+               },\r
+               remove : function(){\r
+                       // TO BE IMPLEMENTED BY SUBCLASSES                      \r
+               }\r
+       }\r
+\r
+});
\ No newline at end of file
diff --git a/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/model/DataModel.js b/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/model/DataModel.js
new file mode 100644 (file)
index 0000000..5cb49ba
--- /dev/null
@@ -0,0 +1,24 @@
+qx.Class.define("org.argeo.jcr.ria.model.DataModel", {\r
+       extend : qx.core.Object,\r
+       \r
+       properties : {\r
+               rootNode : {\r
+                       check : "org.argeo.jcr.ria.model.Node",\r
+                       event : "changeRootNode"                        \r
+               },\r
+               contextNode : {\r
+                       check : "org.argeo.jcr.ria.model.Node",\r
+                       event : "changeContextNode"\r
+               },\r
+               selection : {\r
+                       check : "org.argeo.jcr.ria.model.Node[]",\r
+                       event : "changeSelection"\r
+               }\r
+       },\r
+       \r
+       construct : function(rootNode){\r
+               this.base(arguments);\r
+               this.setRootNode(rootNode);\r
+       }\r
+       \r
+});
\ No newline at end of file
diff --git a/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/model/Node.js b/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/model/Node.js
new file mode 100644 (file)
index 0000000..c5e45f7
--- /dev/null
@@ -0,0 +1,144 @@
+qx.Class.define("org.argeo.jcr.ria.model.Node", {\r
+       extend : org.argeo.jcr.ria.model.AbstractItem,\r
+       \r
+       events : {\r
+               "clear" : "qx.event.type.Event",\r
+               "childNodeAdded" : "qx.event.type.Data",\r
+               "childNodeRemoved" : "qx.event.type.Data",\r
+               "childrenChanged" : "qx.event.type.Data",\r
+               \r
+               "propertyAdded" : "qx.event.type.Data",\r
+               "propertyRemoved" : "qx.event.type.Data",\r
+               "propertiesChanged" : "qx.event.type.Data"\r
+       },\r
+       properties : {\r
+               loadState : {\r
+                       check : "String",\r
+                       init : "empty", // Can be "empty" => "loading" => "loaded"\r
+                       event : "changeLoadState"\r
+               },\r
+               nodeProvider : {\r
+                       check : "org.argeo.jcr.ria.provider.INodeProvider"                      \r
+               }\r
+       },\r
+       \r
+       construct : function(nodeName, isRoot){\r
+               this.base(arguments);\r
+               this._children = {};\r
+               this._properties = {};  \r
+               this.setName(nodeName);\r
+               if(isRoot){\r
+                       this.setPath("");\r
+                       this.setRoot(this);\r
+               }\r
+       },\r
+\r
+       members : {\r
+               _children : null,\r
+               _properties : null,\r
+               \r
+               load : function(){\r
+                       this.getNodeProvider().loadNode(this);\r
+               },\r
+               \r
+               remove : function(){\r
+                       if(this.itemIsRoot()) return;\r
+                       this.getParent().removeChild(this.getName());\r
+               },\r
+               \r
+               fromXmlString : function(xmlString){\r
+                       var domDocument = qx.xml.Document.fromString(xmlString);\r
+                       var root = domDocument.documentElement;\r
+                       this.fromDomElement(root);\r
+               },\r
+               \r
+               fromDomElement : function(domElement){\r
+                       if(domElement.nodeType != 1) return;\r
+                       for(var i=0;i<domElement.attributes.length;i++){\r
+                               var att = domElement.attributes[i];\r
+                               var property = new org.argeo.jcr.ria.model.Property(att.nodeName);\r
+                               this.addProperty(property);\r
+                               property.fromDomElement(att);\r
+                       }\r
+                       for(var i=0;i<domElement.childNodes.length;i++){\r
+                               var child = domElement.childNodes[i];\r
+                               if(child.nodeType != 1) continue;\r
+                               var jcrChild = new org.argeo.jcr.ria.model.Node(child.nodeName);\r
+                               this.addChild(jcrChild);\r
+                               jcrChild.fromDomElement(child);\r
+                       }                       \r
+               },\r
+               \r
+               toXmlString : function(recurse, childrenWriter){\r
+                       var string = "<"+this.getName();\r
+                       var props = this.getProperties();\r
+                       for(var i=0;i<props.length;i++){\r
+                               string += " " + props[i].toXmlString();\r
+                       }\r
+                       string += ">";\r
+                       if(recurse){\r
+                               var childs = this.getChildren();\r
+                               var childrenString = "";\r
+                               for(var j=0;j<childs.length;j++){\r
+                                       childrenString += childs[j].toXmlString(recurse, childrenWriter);\r
+                               }\r
+                               if(childrenWriter){\r
+                                       string += childrenWriter(childrenString);\r
+                               }else{\r
+                                       string += childrenString;\r
+                               }\r
+                       }\r
+                       string += "</"+this.getName()+">";\r
+                       return string;\r
+               },              \r
+               \r
+               getChild : function(childName){\r
+                       return this._children[childName];\r
+               },\r
+               getProperty : function(propertyName){\r
+                       return this._properties[propertyName];\r
+               },\r
+               addChild : function(childNode){\r
+                       this._children[childNode.getName()] = childNode;\r
+                       \r
+                       childNode.setParent(this);\r
+                       childNode.setRoot(this.getRoot());\r
+                       childNode.setPath(this.getPath() + "/" + childNode.getName());\r
+                       \r
+                       this.fireDataEvent("childNodeAdded", childNode);\r
+                       this.fireDataEvent("childNodeChanged");\r
+               },\r
+               removeChild : function(childName){\r
+                       delete(this._children[childName]);\r
+                       this.fireDataEvent("childNodeRemoved", childName);\r
+                       this.fireDataEvent("childNodeChanged");\r
+               },\r
+               addProperty : function(property){\r
+                       this._properties[property.getName()] = property;\r
+                       \r
+                       property.setParent(this);\r
+                       property.setRoot(this.getRoot());\r
+                       property.setPath(this.getPath() + "/" + property.getName());\r
+                       \r
+                       this.fireDataEvent("propertyAdded", property);\r
+                       this.fireDataEvent("propertiesChanged");\r
+               },\r
+               removeProperty : function(propertyName){\r
+                       delete(this._properties[propertyName]);\r
+                       this.fireDataEvent("propertyRemoved", propertyName);\r
+                       this.fireDataEvent("propertiesChanged");\r
+               },\r
+               getChildren : function(){\r
+                       return qx.lang.Object.getValues(this._children);\r
+               },\r
+               getProperties : function(){\r
+                       return qx.lang.Object.getValues(this._properties);\r
+               },\r
+               getChildrenCount : function(){\r
+                       return qx.lang.Object.getLength(this._children);\r
+               },\r
+               getPropertiesCount : function(){\r
+                       return qx.lang.Object.getLength(this._properties);\r
+               }\r
+       }\r
+});
\ No newline at end of file
diff --git a/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/model/Property.js b/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/model/Property.js
new file mode 100644 (file)
index 0000000..988673d
--- /dev/null
@@ -0,0 +1,38 @@
+qx.Class.define("org.argeo.jcr.ria.model.Property", {\r
+       extend : org.argeo.jcr.ria.model.AbstractItem,\r
+       \r
+       properties : {\r
+               node : {\r
+                       refine : true,\r
+                       init : false\r
+               },\r
+               value : {\r
+                       event : "changeValue"\r
+               },\r
+               local : {\r
+                       check : "Boolean",\r
+                       init : false\r
+               }\r
+       },\r
+       \r
+       construct : function(propertyName){\r
+               this.base(arguments);\r
+               this.setName(propertyName);\r
+       },\r
+       \r
+       members : {\r
+               remove : function(){\r
+                       this.getParent().removeProperty(this.getName());\r
+               },\r
+               \r
+               fromDomElement : function(domElement){\r
+                       if(domElement.nodeType != 2) return;\r
+                       this.setValue(domElement.nodeValue);\r
+               },\r
+               toXmlString : function(){\r
+                       if(this.isLocal()) return "";\r
+                       return this.getName()+"="+'"'+this.getValue()+'"';\r
+               }\r
+               \r
+       }\r
+});
\ No newline at end of file
diff --git a/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/provider/INodeProvider.js b/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/provider/INodeProvider.js
new file mode 100644 (file)
index 0000000..fe81c56
--- /dev/null
@@ -0,0 +1,6 @@
+qx.Interface.define("org.argeo.jcr.ria.provider.INodeProvider", {\r
+       members : {\r
+               initProvider : function(properties){},\r
+               loadNode : function(path, nodeCallback, childCallback){}\r
+       }\r
+});
\ No newline at end of file
diff --git a/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/provider/XmlNodeProvider.js b/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/provider/XmlNodeProvider.js
new file mode 100644 (file)
index 0000000..a7f7d1b
--- /dev/null
@@ -0,0 +1,63 @@
+qx.Class.define("org.argeo.jcr.ria.provider.XmlNodeProvider", {\r
+       extend : qx.core.Object,\r
+       implement : [org.argeo.jcr.ria.provider.INodeProvider],\r
+       \r
+       properties : {\r
+               settings :{\r
+                       check : "Object"\r
+               },\r
+               xmlDoc : {\r
+                       \r
+               },\r
+               xmlDocLoaded : {\r
+                       check : "Boolean",\r
+                       init : false,\r
+                       event : "changeXmlDocLoaded"\r
+               }\r
+       },\r
+       \r
+       members : {\r
+               _xmlDoc : null,\r
+               initProvider : function(properties){\r
+                       this.setSettings(properties);                   \r
+               },\r
+               /**\r
+                * \r
+                * @param node org.argeo.jcr.ria.model.Node\r
+                * @param nodeCallback Function\r
+                * @param childCallback Function\r
+                */\r
+               loadNode : function(node, nodeCallback, childCallback){\r
+                       if(node.getLoadState() == "loaded") return;\r
+                       \r
+                       if(this.getXmlDocLoaded()){\r
+                               // Parse document and load\r
+                               node.setName(this._xmlDoc.documentElement.nodeName);\r
+                               node.fromDomElement(this._xmlDoc.documentElement);\r
+                               node.setLoadState("loaded");\r
+                       }else{\r
+                               this.addListenerOnce("changeXmlDocLoaded", function(){\r
+                                       this.loadNode(node, nodeCallback, childCallback);\r
+                               }, this);\r
+                               node.setLoadState("loading");\r
+                               this.loadXmlDoc();\r
+                       }\r
+               },\r
+                               \r
+               loadXmlDoc : function(){\r
+                       var properties = this.getSettings();\r
+                       if(!properties.xmlSrc && !properties.xmlString) return;\r
+                       if(properties.xmlSrc){\r
+                               var request = new org.argeo.ria.remote.Request(properties.xmlSrc, 'GET', 'application/xml');\r
+                               request.addListener("completed", function(response){\r
+                                       this._xmlDoc = response.getContent();\r
+                                       this.setXmlDocLoaded(true);\r
+                               }, this);\r
+                               request.send();\r
+                       }else{\r
+                               this._xmlDoc = qx.xml.Document.fromString(properties.xmlString);\r
+                               this.setXmlDocLoaded(true);\r
+                       }\r
+               }\r
+       }\r
+});
\ No newline at end of file
diff --git a/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/views/XmlNodeEditor.js b/server/org.argeo.slc.ria/src/argeo-ria-lib/jcr/class/org/argeo/jcr/ria/views/XmlNodeEditor.js
new file mode 100644 (file)
index 0000000..2493edd
--- /dev/null
@@ -0,0 +1,72 @@
+qx.Class.define("org.argeo.jcr.ria.views.XmlNodeEditor", {\r
+       extend : qx.ui.embed.Html,\r
+       implement : [org.argeo.ria.components.IView], \r
+\r
+       properties : {\r
+               /**\r
+                * The commands definition Map that will be automatically added and wired to the menubar and toolbar.\r
+                * See {@link org.argeo.ria.event.CommandsManager#definitions} for the keys to use for defining commands.\r
+                */\r
+               commands : {\r
+                       init : {}\r
+               },\r
+               viewSelection : {\r
+                       nullable:false, \r
+                       check:"org.argeo.ria.components.ViewSelection"\r
+               },\r
+               instanceId : {\r
+                       init:"XmlEditor",\r
+                       event : "changeInstanceId"\r
+               },\r
+               instanceLabel : {\r
+                       init:"Xml Editor",\r
+                       event : "changeInstanceLabel"\r
+               }\r
+       },\r
+       \r
+       construct : function(){\r
+               this.base(arguments);\r
+       },\r
+       \r
+       members : {\r
+               /**\r
+                * The implementation should contain the GUI initialisation.\r
+                * This is the role of the manager to actually add the graphical component to the pane, \r
+                * so it's not necessary to do it here. \r
+                * @param viewPane {org.argeo.ria.components.ViewPane} The pane manager\r
+                * @param data {Mixed} Any object or data passed by the initiator of the view\r
+                * @return {Boolean}\r
+                */\r
+               init : function(viewPane, data){\r
+                       this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));          \r
+                       this.setHtml("Hello!");\r
+               },\r
+               /**\r
+                * The implementation should contain the real data loading (i.o. query...)\r
+                * @return {Boolean}\r
+                */\r
+               load : function(rootNode){\r
+                       rootNode.load();\r
+                       rootNode.addListener("changeLoadState", function(){\r
+                               var xmlString = rootNode.toXmlString(true);\r
+                               this.setHtml(qx.xml.String.escape(xmlString));\r
+                       }, this);\r
+               },\r
+               /**\r
+                * Whether this component is already contained in a scroller (return false) or not (return true).\r
+                * @return {Boolean}\r
+                */\r
+               addScroll : function(){\r
+                       return true;\r
+               },\r
+               /**\r
+                * Called at destruction time\r
+                * Perform all the clean operations (stopping polling queries, etc.) \r
+                */\r
+               close : function(){\r
+                       \r
+               }               \r
+       }\r
+       \r
+       \r
+});
\ No newline at end of file