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