--- /dev/null
+{\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
--- /dev/null
+/**\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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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