Author: lgiessmann Date: Fri Jun 26 09:29:12 2009 New Revision: 70
Log: ajax-client: fixed some bugs that were discovered by using opera; json-server: implemented a new json-handler, this handler returns a topic-psi-list of all valid topic-instances (valid: is oriented only on topic-typing and tmcl - all other constraints are not checked by the server)
Modified: trunk/src/ajax/javascripts/constants.js trunk/src/ajax/javascripts/create.js trunk/src/ajax/javascripts/datamodel.js trunk/src/ajax/javascripts/edit.js trunk/src/ajax/javascripts/requests.js trunk/src/json/json_tmcl.lisp trunk/src/json/json_tmcl_validation.lisp trunk/src/rest_interface/rest-interface.lisp trunk/src/rest_interface/set-up-json-interface.lisp
Modified: trunk/src/ajax/javascripts/constants.js ============================================================================== --- trunk/src/ajax/javascripts/constants.js (original) +++ trunk/src/ajax/javascripts/constants.js Fri Jun 26 09:29:12 2009 @@ -12,7 +12,7 @@
// --- Some constants fot the http connections via the XMLHttpRequest-Object var TIMEOUT = 10000; // const TIMEOUT = 10000 --> "const" doesn't work under IE -var HOST_PREF = "192.168.178.21/"; //"http://localhost:8000/"; +var HOST_PREF = "http://143.93.190.237:8000/"; //"http://localhost:8000/"; // of the form "http://(.+)/" var GET_PREFIX = HOST_PREF + "json/get/"; var GET_STUB_PREFIX = HOST_PREF + "json/topicstubs/"; var TMCL_TYPE_URL = HOST_PREF + "json/tmcl/type/"; @@ -20,6 +20,7 @@ var COMMIT_URL = HOST_PREF + "json/commit/"; var ALL_PSIS_URL = HOST_PREF + "json/psis/"; var TYPE_PSIS_URL = HOST_PREF + "json/tmcl/types/"; +var INSTANCE_PSIS_URL = HOST_PREF + "json/tmcl/instances/"; var OWN_URL = HOST_PREF + "isidorus"; var SUMMARY_URL = HOST_PREF + "json/summary"
Modified: trunk/src/ajax/javascripts/create.js ============================================================================== --- trunk/src/ajax/javascripts/create.js (original) +++ trunk/src/ajax/javascripts/create.js Fri Jun 26 09:29:12 2009 @@ -46,7 +46,7 @@ } } //onSuccessHandler - getPsis(onSuccessHandler, null, true); + getPsis(onSuccessHandler, null, {"types" : true}); }catch(err){ alert("From makeCreate(): " + err); }
Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Fri Jun 26 09:29:12 2009 @@ -20,7 +20,7 @@ this.__remove__ = new Element("span", {"class" : CLASSES.clickable()}).update("-"); this.__add__ = new Element("span", {"class" : CLASSES.clickable()}).update("+");
- checkRemoveAddButtons(owner, min, max); + checkRemoveAddButtons(owner, min, max, null);
this.__error__ = new Element("div", {"class" : CLASSES.error()}); this.__error__.hide(); @@ -32,7 +32,7 @@ this.__frame__.insert({"bottom" : this.__error__}); this.__disabled__ = false;
- setRemoveAddHandler(this, owner, min, max, function(){ + setRemoveAddHandler(this, true, owner, min, max, function(){ return new FrameC("", owner, min, max); }); }, @@ -102,9 +102,9 @@ } this.__remove__.insert({"after" : this.__content__});
- checkRemoveAddButtons(owner, min, max); + checkRemoveAddButtons(owner, min, max, null); var myself = this; - setRemoveAddHandler(this, owner, min, max, function(){ + setRemoveAddHandler(this, true, owner, min, max, function(){ return new TextrowC("", regexp, owner, min, max, cssTitle, dblClickHandler); });
@@ -138,7 +138,7 @@ }, "enable" : function(){ this.__content__.removeAttribute("readonly"); - checkRemoveAddButtons(this.__owner__, this.__min__, this.__max__); + checkRemoveAddButtons(this.__owner__, this.__min__, this.__max__, null); this.__disabled__ = false; }, "getRegexp" : function(){ @@ -162,8 +162,8 @@ } this.__remove__.insert({"after" : this.__content__});
- checkRemoveAddButtons(owner, min, max); - setRemoveAddHandler(this, owner, min, max, function(){ + checkRemoveAddButtons(owner, min, max, null); + setRemoveAddHandler(this, true, owner, min, max, function(){ return new SelectrowC(contents, owner, min, max); }); }, @@ -1145,8 +1145,8 @@
// --- control row + itemIdentity makeControlRow(this, 4, itemIdentityContent); - checkRemoveAddButtons(owner, 1, -1); - setRemoveAddHandler(this, owner, 1, -1, function(){ + checkRemoveAddButtons(owner, 1, -1, null); + setRemoveAddHandler(this, true, owner, 1, -1, function(){ return new VariantC(null, owner, dblClickHandler, parent); }); @@ -1336,6 +1336,7 @@ this.__max__ = max; this.__owner__ = owner; this.__dblClickHandler__ = dblClickHandler; + this.__constraint__ = simpleConstraint;
try{ var itemIdentityContent = null; @@ -1353,8 +1354,8 @@ // --- control row + ItemIdentity makeControlRow(this, 5, itemIdentityContent); - checkRemoveAddButtons(owner, min, max); - setRemoveAddHandler(this, owner, min, max, function(){ + checkRemoveAddButtons(owner, min, max, this); + setRemoveAddHandler(this, this.__constraint__, owner, min, max, function(){ return new NameC(null, nametypescopes, simpleConstraint, owner, min, max, dblClickHandler); });
@@ -1469,7 +1470,7 @@ this.getFrame().setStyle({"backgroundColor" : "inherit"}); this.getFrame().setStyle({"border" : "none"}); this.getFrame().removeAttribute("title"); - checkRemoveAddButtons(this.__owner__, 1, this.__max__); + checkRemoveAddButtons(this.__owner__, 1, this.__max__, this); this.__disabled__ = false; }});
@@ -1713,8 +1714,8 @@ // --- control row + itemIdentity makeControlRow(this, 5, itemIdentityContent); - checkRemoveAddButtons(owner, 1, max); - setRemoveAddHandler(this, owner, 1, max, function(){ + checkRemoveAddButtons(owner, 1, max, this); + setRemoveAddHandler(this, this.__constraint__, owner, 1, max, function(){ return new OccurrenceC(null, occurrenceTypes, constraint, uniqueConstraints, owner, min, max, cssTitle, dblClickHandler); });
@@ -1848,7 +1849,7 @@ this.getFrame().setStyle({"backgroundColor" : "inherit"}); this.getFrame().setStyle({"border" : "none"}); this.getFrame().removeAttribute("title"); - checkRemoveAddButtons(this.__owner__, 1, this.__max__); + checkRemoveAddButtons(this.__owner__, 1, this.__max__, this); this.__disabled__ = false; }}); @@ -2275,12 +2276,13 @@ this.__owner__ = owner; this.__typeMin__ = typeMin; this.__parentElem__ = parent; + this.__constraint__ = true; // is needed for checkAddRemoveButtons
try{ // --- control row + itemIdentity makeControlRow(this, 3, itemIdentities); // make control row have to be changed to a separate control row for roles - checkRemoveAddButtons(owner, 1, -1); - setRemoveAddHandler(this, owner, 1, -1, function(){ /*do nothing*/ }); + checkRemoveAddButtons(owner, 1, -1, this); + setRemoveAddHandler(this, this.__constraint__, owner, 1, -1, function(){ /*do nothing*/ }); // --- gets the add and remove button var cTd = this.__table__.select("tr." + CLASSES.itemIdentityFrame())[0].select("td." + CLASSES.controlColumn())[0].select("span." + CLASSES.clickable()); this.__removeButton__ = cTd[1]; @@ -2514,6 +2516,10 @@ } }, "__orderContentsToRoles__" : function(contents, roleContainer, usedContents, alreadyUsedRoles){ + if(!roleContainer || roleContainer.length === 0){ + return {"usedContents" : usedContents, "contents" : contents, "alreadyUsedRoles" : alreadyUsedRoles}; + } + for(var i = 0; i !== contents.length; ++i){ var rType = contents[i].type; var player = contents[i].topicRef; @@ -2819,7 +2825,7 @@ this.__makeRolesFromARC__(arc, foundRpcs); } // --- creates roles from otherrole-constraints - for(var i = 0; i !== this.__arContainer__.__frames__.length; ++i){ + for(var i = 0; this.__arContainer__.__frames__ && i !== this.__arContainer__.__frames__.length; ++i){ this.__makeRolesFromORC__(this.__arContainer__.__frames__[i].getType(), this.__arContainer__.__frames__[i].getPlayer()); } }, @@ -3465,13 +3471,14 @@ // --- control row + ItemIdentity makeControlRow(this, 4, itemIdentityContent); - checkRemoveAddButtons(owner, 1, -1); - setRemoveAddHandler(this, owner, 1, -1, function(){ + checkRemoveAddButtons(owner, 1, -1, this); + setRemoveAddHandler(this, this.__constraints__, owner, 1, -1, function(){ return new AssociationC(null, constraints, owner); });
// --- type - var types = makeTypes(this, typeContent, constraints); + var types = makeTypes(this, typeContent, constraints); + if(types.flatten().length === 0 || types.flatten()[0].strip().length === 0 || !constraints || constraints.length === 0) this.hideAddButton(); // --- scopes var currentConstraint = this.getCurrentConstraint(); @@ -3577,8 +3584,8 @@ this.__roles__.enable(); this.__type__.__frames__[0].enable(); this.__scope__.enable(); - if(this.__owner__.__frames__.length > 1) this.showRemoveButton(); - this.showAddButton(); + if(this.__owner__.__frames__.length > 1 || !this.__constraints__ || this.__constraints__.length !== 0) this.showRemoveButton(); + if(this.__constraints__ && this.__constraints__.length !== 0) this.showAddButton(); this.getFrame().setStyle({"backgroundColor" : "inherit"}); this.getFrame().setStyle({"border" : "none"}); this.__disabled__ = false; @@ -3605,6 +3612,11 @@ tr.update(td); this.__table__.insert({"bottom" : tr}); } + if(!constraints || constraints.length === 0){ + for(var i = 0; i !== this.__container__.__frames__.length; ++i){ + this.__container__.__frames__[i].hideAddButton(); + } + }
if(!this.__container__.__frames__ && constraints && constraints.length !== 0){ var association = new AssociationC(null, constraints, this.__container__); @@ -3773,7 +3785,7 @@ // --- Helper function for the constructors of all classes // --- of the type FrameC. // --- There will be set the remome and add handler. -function setRemoveAddHandler(myself, owner, min, max, call) +function setRemoveAddHandler(myself, constraint, owner, min, max, call) { myself.__remove__.stopObserving(); myself.__add__.stopObserving(); @@ -3783,12 +3795,12 @@ if(disabled === false){ myself.remove(); owner.__frames__ = owner.__frames__.without(myself); - if(min >= owner.__frames__.length){ + if(min >= owner.__frames__.length && constraint){ for(var i = 0; i != owner.__frames__.length; ++i){ owner.__frames__[i].hideRemoveButton(); } } - if(max > owner.__frames__.length){ + if((max === -1 || max > owner.__frames__.length) && constraint){ for(var i = 0; i != owner.__frames__.length; ++i){ owner.__frames__[i].showAddButton(); } @@ -3802,12 +3814,12 @@ if(disabled === false){ var newElem = call(); myself.append(newElem.getFrame()); - if(remove === true && min !== -1 && owner.__frames__.length > min){ + if((remove === true && min !== -1 && owner.__frames__.length > min) || !constraint){ for(var i = 0; i != owner.__frames__.length; ++i){ owner.__frames__[i].showRemoveButton(); } } - if(max > -1 && max <= owner.__frames__.length){ + if((max > -1 && max <= owner.__frames__.length) || !constraint){ for(var i = 0; i != owner.__frames__.length; ++i){ owner.__frames__[i].hideAddButton(); } @@ -3818,30 +3830,33 @@
// --- Helper function for the constructors of all classes -// --- of the type FrameC. +// --- of the type FrameC and some of the type ContainerC. // --- There will be checked the visibility of the remove and // --- add buttons. -function checkRemoveAddButtons(owner, min, max) +function checkRemoveAddButtons(owner, min, max, myself) { - if(min >= owner.__frames__.length){ + var constraint = true; + if(myself && !myself.__constraint__ && (!myself.__constraints__ || myself.__constraints__.length === 0)) constraint = false; + + if(min >= owner.__frames__.length && constraint === true){ for(var i = 0; i != owner.__frames__.length; ++i){ owner.__frames__[i].hideRemoveButton(); } }
- if(min > -1 && min < owner.__frames__.length){ + if((min > -1 && min < owner.__frames__.length) || constraint === false){ for(var i = 0; i != owner.__frames__.length; ++i){ owner.__frames__[i].showRemoveButton(); } }
- if(max > -1 && max <= owner.__frames__.length){ + if((max > -1 && max <= owner.__frames__.length) || constraint === false){ for(var i = 0; i != owner.__frames__.length; ++i){ owner.__frames__[i].hideAddButton(); } }
- if(max === -1 || max > owner.__frames__.length){ + if((max === -1 || max > owner.__frames__.length) && constraint === true){ for(var i = 0; i != owner.__frames__.length; ++i){ owner.__frames__[i].showAddButton(); }
Modified: trunk/src/ajax/javascripts/edit.js ============================================================================== --- trunk/src/ajax/javascripts/edit.js (original) +++ trunk/src/ajax/javascripts/edit.js Fri Jun 26 09:29:12 2009 @@ -55,7 +55,7 @@ alert("There occurred an error by creating an EditC frame, please reload this page!\n\n" + err); } } - getPsis(onSuccessHandler, null, false); + getPsis(onSuccessHandler, null, {"instances" : true}); } catch(err){ alert("From makeEdit(): " + err);
Modified: trunk/src/ajax/javascripts/requests.js ============================================================================== --- trunk/src/ajax/javascripts/requests.js (original) +++ trunk/src/ajax/javascripts/requests.js Fri Jun 26 09:29:12 2009 @@ -83,7 +83,7 @@
// --- Gets all psis from the server. If typePsis is set to true // --- there will be requested only TopicType's psis. -function getPsis(onSuccessHandler, onFailureHandler, typePsis) +function getPsis(onSuccessHandler, onFailureHandler, what) { try{ var onFailure = onFailureHandler ? onFailureHandler : defaultFailureHandler; @@ -91,7 +91,9 @@ onLoad("Requesting all type PSIs");
var url = ALL_PSIS_URL; - if(typePsis === true) url = TYPE_PSIS_URL; + if(what && what.types && what.types === true) url = TYPE_PSIS_URL; + else if(what && what.instances && what.instances === true) url = INSTANCE_PSIS_URL; + else if(what && what.all && what.all === true) url = ALL_PSIS_URL;
new Ajax.Request(url, { "method" : "get",
Modified: trunk/src/json/json_tmcl.lisp ============================================================================== --- trunk/src/json/json_tmcl.lisp (original) +++ trunk/src/json/json_tmcl.lisp Fri Jun 26 09:29:12 2009 @@ -992,8 +992,7 @@ (remove-duplicates (if (eql treat-as 'type) (topictype-p topic-instance) - (loop for topic in (union (get-direct-types-of-topic topic-instance) (get-direct-supertypes-of-topic topic-instance)) - append (topictype-p topic)))))) + (valid-instance-p topic-instance))))) (let ((all-abstract-topictype-constraints nil) (all-exclusive-instance-constraints nil) (all-subjectidentifier-constraints nil) @@ -1104,8 +1103,7 @@ (remove-duplicates (if (eql treat-as 'type) (topictype-p topic-instance) - (loop for topic in (union (get-direct-types-of-topic topic-instance) (get-direct-supertypes-of-topic topic-instance)) - append (topictype-p topic)))))) + (valid-instance-p topic-instance))))) (let ((all-available-associationtypes (remove-duplicates (loop for possible-player-topic in all-possible-player-topics
Modified: trunk/src/json/json_tmcl_validation.lisp ============================================================================== --- trunk/src/json/json_tmcl_validation.lisp (original) +++ trunk/src/json/json_tmcl_validation.lisp Fri Jun 26 09:29:12 2009 @@ -12,6 +12,7 @@ (:export :get-constraints-of-fragment :topictype-p :abstract-p + :valid-instance-p :list-subtypes))
@@ -272,6 +273,64 @@ all-subtypes-of-all-instances)))))))
+(defun valid-instance-p (topic-instance &optional (akos-checked nil) (all-checked-topics nil)) + "Returns a list of all checked topics or throws an exception if the given + topic is not a valid instance of any topictype in elephant." + (let ((isas-of-this + (get-direct-types-of-topic topic-instance)) + (akos-of-this + (get-direct-supertypes-of-topic topic-instance)) + (psi-of-this (uri (first (psis topic-instance)))) + (topictype (d:get-item-by-psi json-tmcl-constants::*topictype-psi*)) + (topictype-constraint (d:get-item-by-psi json-tmcl-constants::*topictype-constraint-psi*)) + (local-all-checked-topics all-checked-topics) + (local-akos-checked)) + + (when (not topictype-constraint) + (return-from valid-instance-p topic-instance)) + + (when (and topictype-constraint + (not topictype)) + (error (format nil "From valid-instance-p(): The topic "~a" does not exist - please create it or remove the topic "~a"" + json-tmcl-constants::*topictype-psi* json-tmcl-constants::*topictype-constraint-psi*))) + + (when (eql topic-instance topictype) + (return-from valid-instance-p (remove-duplicates (append all-checked-topics (list topic-instance))))) + + (unless (or isas-of-this akos-of-this) + (error (format nil "The topic "~a" is not a valid topic-instance for any topic-type" psi-of-this))) + + (when (find topic-instance akos-checked) + (return-from valid-instance-p all-checked-topics)) + + (pushnew topic-instance local-all-checked-topics) + (pushnew topic-instance local-akos-checked) + + (dolist (isa isas-of-this) + (handler-case (let ((topics + (topictype-p isa topictype topictype-constraint))) + (dolist (top topics) + (pushnew top local-all-checked-topics))) + (condition (err) (error (format nil "The topic "~a" is not a valid topic-instance for any topic-type~%~%~a" psi-of-this err))))) + + (dolist (ako akos-of-this) + (when (not (handler-case (let ((topics + (topictype-p ako topictype topictype-constraint all-checked-topics))) + (dolist (top topics) + (pushnew top local-all-checked-topics)) + (pushnew ako local-akos-checked) + topics) + (condition () nil))) + (handler-case (let ((topics + (valid-instance-p ako akos-checked (append all-checked-topics (list ako))))) + (dolist (top topics) + (pushnew top local-all-checked-topics) + (pushnew top local-akos-checked)) + topics) + (condition (err) (error (format nil "The topic "~a" is not a valid topic-instance for any topic-type~%~%~a" psi-of-this err)))))) + local-all-checked-topics)) + + (defun return-all-tmcl-types () "Returns all topics that are valid tmcl-types" (let ((all-topics @@ -282,7 +341,7 @@ (remove-if #'null (map 'list #'(lambda(x) (handler-case (progn - (json-tmcl::topictype-p x topictype topictype-constraint) + (topictype-p x topictype topictype-constraint) x) (condition () nil))) all-topics)))) (let ((not-abstract-types @@ -291,4 +350,20 @@ (unless (json-tmcl:abstract-p x) x)) all-types)))) - not-abstract-types)))) \ No newline at end of file + not-abstract-types)))) + + +(defun return-all-tmcl-instances () + "Returns all topics that are valid instances of any topic type. + The validity is only oriented on the typing of topics, e.g. + type-instance or supertype-subtype." + (let ((all-topics + (elephant:get-instances-by-class 'd:TopicC))) + (let ((valid-instances + (remove-if #'null + (map 'list #'(lambda(x) + (handler-case (progn + (valid-instance-p x) + x) + (condition () nil))) all-topics)))) + valid-instances))) \ No newline at end of file
Modified: trunk/src/rest_interface/rest-interface.lisp ============================================================================== --- trunk/src/rest_interface/rest-interface.lisp (original) +++ trunk/src/rest_interface/rest-interface.lisp Fri Jun 26 09:29:12 2009 @@ -30,6 +30,7 @@ :*json-get-all-psis* :*json-get-summary-prefix* :*json-get-all-type-psis* + :*json-get-all-instance-psis* :*json-get-topic-stub-prefix* :*json-get-type-tmcl-prefix* :*json-get-instance-tmcl-prefix*
Modified: trunk/src/rest_interface/set-up-json-interface.lisp ============================================================================== --- trunk/src/rest_interface/set-up-json-interface.lisp (original) +++ trunk/src/rest_interface/set-up-json-interface.lisp Fri Jun 26 09:29:12 2009 @@ -14,6 +14,7 @@ (defparameter *json-get-all-psis* "/json/psis/?$") ;the url to get all topic psis of isidorus -> localhost:8000/json/psis (defparameter *json-get-summary-url* "/json/summary/?$") ;the url to get a summary of all topic stored in isidorus; you have to set the GET-parameter "start" for the start index of all topics within elephant and the GET-paramter "end" for the last index of the topic sequence -> http://localhost:8000/json/summary/?start=12&end=13 (defparameter *json-get-all-type-psis* "/json/tmcl/types/?$") ;returns a list of all psis that can be a type +(defparameter *json-get-all-instance-psis* "/json/tmcl/instances/?$") ;returns a list of all psis that belongs to a valid topic-instance (defparameter *json-get-topic-stub-prefix* "/json/topicstubs/(.+)$") ;the json prefix for getting some topic stub information of a topic (defparameter *json-get-type-tmcl-url* "/json/tmcl/type/?$") ;the json url for getting some tmcl information of a topic treated as a type (defparameter *json-get-instance-tmcl-url* "/json/tmcl/instance/?$") ;the json url for getting some tmcl information of a topic treated as an instance @@ -29,6 +30,7 @@ (json-commit-url *json-commit-url*) (json-get-summary-url *json-get-summary-url*) (json-get-all-type-psis *json-get-all-type-psis*) + (json-get-all-instance-psis *json-get-all-instance-psis*) (json-get-topic-stub-prefix *json-get-topic-stub-prefix*) (json-get-type-tmcl-url *json-get-type-tmcl-url*) (json-get-instance-tmcl-url *json-get-instance-tmcl-url*) @@ -84,6 +86,9 @@ (create-regex-dispatcher json-get-all-type-psis #'return-all-tmcl-types) hunchentoot:*dispatch-table*) (push + (create-regex-dispatcher json-get-all-instance-psis #'return-all-tmcl-instances) + hunchentoot:*dispatch-table*) + (push (create-regex-dispatcher json-get-type-tmcl-url #'(lambda(&optional param) (declare (ignorable param)) (return-tmcl-info-of-psis 'json-tmcl::type))) @@ -104,7 +109,7 @@ ;; --- some handlers for the json-rest-interface ------------------------------- ;; ============================================================================= (defun return-all-tmcl-types(&optional param) - "Returns all topics that are valid types -> so they have to be valid to the + "Returns all topic-psi that are valid types -> so they have to be valid to the topictype-constraint (if it exists) and the can't be abstract." (declare (ignorable param)) (handler-case (let ((topic-types (json-tmcl::return-all-tmcl-types))) @@ -118,6 +123,23 @@ (setf (hunchentoot:content-type*) "text") (format nil "Condition: "~a"" err)))))
+(defun return-all-tmcl-instances(&optional param) + "Returns all topic-psis that are valid instances of any topic type. + The validity is only oriented on the typing of topics, e.g. + type-instance or supertype-subtype." + (declare (ignorable param)) + (handler-case (let ((topic-instances (json-tmcl::return-all-tmcl-instances))) + (setf (hunchentoot:content-type*) "application/json") ;RFC 4627 + (json:encode-json-to-string + (map 'list #'(lambda(y) + (map 'list #'uri y)) + (map 'list #'psis topic-instances)))) + (condition (err) (progn + (setf (hunchentoot:return-code*) hunchentoot:+http-internal-server-error+) + (setf (hunchentoot:content-type*) "text") + (format nil "Condition: "~a"" err))))) + + (defun return-topic-stub-of-psi(&optional psi) "Returns a json string of a topic depending on the passed psi as a topic-stub-construct."