Author: lgiessmann Date: Thu Apr 21 05:56:59 2011 New Revision: 427
Log: JSON-Interface: all / that are not escaped will be escaped after calling prototypes toJSON method, because prototype does not escape /; if no topics for a player-constraint or other-player-constraint exist there is no error message thrown, instead the constraint is ignored as long as there are to few topics; the backend now escapes all /, too
Modified: trunk/src/ajax/javascripts/create.js trunk/src/ajax/javascripts/datamodel.js trunk/src/ajax/javascripts/requests.js trunk/src/ajax/javascripts/tmcl_tools.js trunk/src/json/json_exporter.lisp trunk/src/model/changes.lisp trunk/src/rest_interface/set-up-json-interface.lisp
Modified: trunk/src/ajax/javascripts/create.js ============================================================================== --- trunk/src/ajax/javascripts/create.js (original) +++ trunk/src/ajax/javascripts/create.js Thu Apr 21 05:56:59 2011 @@ -130,7 +130,8 @@ alert("The fragment wasn't committed - Please correct your input data!"); return; } - + + // --- if the validation succeeded the fragment will be sent to the server var tPsis = topic.getContent().subjectIdentifiers; if(!tPsis || tPsis.length === 0) tPsis = "null"; @@ -150,6 +151,7 @@ referencedTopics = referencedTopics.concat(aStubs); }
+ function onSuccessHandler(topicStubs){ var tsStr = "null"; if(topicStubs && topicStubs.length !== 0){ @@ -160,17 +162,19 @@ } tsStr += "]"; } + var jTopic = ""topic":" + topic.toJSON(); var jTopicStubs = ""topicStubs":" + tsStr; var jAssociations = ""associations":" + (associations ? associations.toJSON().gsub("\["" + CURRENT_TOPIC_ESCAPED + ""\]", tPsis) : "null"); var jTmId = ""tmIds":" + tmId.toJSON(); var json = "{" + jTopic + "," + jTopicStubs + "," + jAssociations + "," + jTmId + "}"; + commitFragment(json, function(xhr){ alert("The fragment was committed succesfully!"); }, null); } - + function onErrorHandler(){ // --- currently there is not needed a special handling for errors - // --- occurred during this operation + // --- occurring during this operation } getTopicStubs(referencedTopics, onSuccessHandler, onErrorHandler); });
Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Thu Apr 21 05:56:59 2011 @@ -549,7 +549,8 @@ }, "toJSON" : function(unique, removeNull){ var content = this.getContent(unique, removeNull); - return content.length === 0 ? "null" : content.toJSON(); + if(!content || content.length === 0) return "null"; + return content.toJSON(); }, "isValid" : function(){ var allIdentifiers = new Array(); @@ -2665,8 +2666,8 @@ this.__createFromContent__(contents); } catch(err){ - alert("From RoleContainerC(): " + err); - } + alert("From RoleContainerC(): " + err); + } }, "__orderContentsToRoles__" : function(contents, roleContainer, usedContents, alreadyUsedRoles){ if(!roleContainer || roleContainer.length === 0){ @@ -2920,31 +2921,31 @@ var cContents = contents; var usedContents = new Array(); var alreadyUsedRoles = new Array(); - + // --- searches for associaitonrole-constraints and roleplayer-constraints var ret = this.__orderContentsToRoles__(cContents, this.__arContainer__.__frames__, usedContents, alreadyUsedRoles); cContents = ret.contents; usedContents = ret.usedContents; alreadyUsedRoles = ret.alreadyUsedRoles; - + // --- searches for otherrole-constraints ret = this.__orderContentsToRoles__(cContents, this.__orContainer__.__frames__, usedContents, alreadyUsedRoles); cContents = ret.contents; usedContents = ret.usedContents; alreadyUsedRoles = ret.alreadyUsedRoles; - + // --- creates additional roles (associationrole-constraints) ret = this.__createAdditionalRolesFromContents__(cContents, usedContents, alreadyUsedRoles, true); cContents = ret.contents; usedContents = ret.usedContents; alreadyUsedRoles = ret.alreadyUsedRoles; - + // --- creates additional roles (associationrole-constraints) ret = this.__createAdditionalRolesFromContents__(cContents, usedContents, alreadyUsedRoles, false); cContents = ret.contents; usedContents = ret.usedContents; alreadyUsedRoles = ret.alreadyUsedRoles; - + this.__createNewRolesFromContents__(cContents); }, "resetValues" : function(associationRoleConstraints, rolePlayerConstraints, otherRoleConstraints){ @@ -2994,8 +2995,11 @@ var roleMin = associationRoleConstraint.cardMin === 0 ? 1 : parseInt(associationRoleConstraint.cardMin); var roleMinOrg = parseInt(associationRoleConstraint.cardMin); for(var i = 0; i !== rolePlayerConstraints.length; ++i){ + // if no player is available for a rolePlayerConstraint the constraint is ignored and no warning is thrown + if(!rolePlayerConstraints[i].players || rolePlayerConstraints[i].players.length < playerMin) continue; + + var playerMin = rolePlayerConstraints[i].cardMin === 0 ? 1 : parseInt(rolePlayerConstraints[i].cardMin); - if(rolePlayerConstraints[i].players.length < playerMin) throw "From __makeRolesFromARC__(): not enough players(=" + rolePlayerConstraints[i].players.length + ") to reach card-min(=" + playerMin + ") of roletype"" + roleType.flatten()[0] + ""!"; for(var k = 0; k !== playerMin; ++k){ // --- creates a new role var selectedPlayers = new Array(); @@ -3022,7 +3026,7 @@ for(var i= 0; i !== rolePlayerConstraints.length; ++i){ // existing roles --> all roles that owns a player which is selected of those listed in the roleplayer-constraint var existingRoles = this.getExistingRoles(roleType, rolePlayerConstraints[i].players, this.__arContainer__.__frames__); - var availablePlayers = rolePlayerConstraints[i].players; + var availablePlayers = (rolePlayerConstraints[i].players ? rolePlayerConstraints[i].players : new Array()); if(existingRoles.length < rolePlayerConstraints[i].cardMax && availablePlayers.length > existingRoles.length){ var currentAvailablePlayers = rolePlayerConstraints[i].players; var cleanedPlayers = cleanPlayers(allAvailablePlayers, currentAvailablePlayers); @@ -3047,7 +3051,9 @@ ++currentlyCreated; } } - if(currentlyCreated === 0) throw "Not enough players to create all needed roles of the type "" + roleType.flatten()[0] + ""!"; + + // not enough roles created so an association with zero roles can be made + if(currentlyCreated === 0) break; }; this.__checkARCButtons__(currentRoles, allAvailablePlayers, associationRoleConstraint); for(var i = 0; i !== currentRoles.length; ++i){ @@ -3064,7 +3070,11 @@ var cOtherRoleType = orpcs[i].otherRoleType; var cMin = orpcs[i].cardMin === 0 ? 1 : parseInt(orpcs[i].cardMin); var cMinOrg = parseInt(orpcs[i].cardMin); - if(!cOtherPlayers || cOtherPlayers.length < cMin) throw "from __makeRolesFromORC__(): not enough players(=" + cOtherPlayers.length + ") for roletype + "" + cOtherRoleType.flatten()[0] + ""!"; + + // if there are not enough other players the constraint is ignored and no error message is thrown + if(!cOtherPlayers || cOtherPlayers.length < cMin) continue; + + var existingRoles = this.getExistingRoles(cOtherRoleType, cOtherPlayers, this.__orContainer__.__frames__); for(var j = 0; j < cMin - existingRoles.length; ++j){ // --- removes all players that are already selected from the @@ -3471,7 +3481,7 @@ var orcs = this.__otherRoleConstraints__; var rpcs = this.__rolePlayerConstraints__; - // --- checks if there exist any constraints + // --- checks if there exist aniy constraints if(!arcs || arcs.length === 0){ this.showError("No association-constraints found for this association!"); return false; @@ -3485,20 +3495,24 @@ // --- collects all used roles depending on associationrole-constraints var allAroles = new Array(); var allAroles2 = new Array(); - for(var i = 0; this.__arContainer__.__frames__ && i !== this.__arContainer__.__frames__.length; ++i){ - this.__arContainer__.__frames__[i].hideError(); - if(this.__arContainer__.__frames__[i].isUsed() === true){ - allAroles.push(this.__arContainer__.__frames__[i]); - allAroles2.push(this.__arContainer__.__frames__[i]); + if(this.__arContainer__ && this.__arContainer__.__frames__){ + for(var i = 0; this.__arContainer__.__frames__ && i !== this.__arContainer__.__frames__.length; ++i){ + this.__arContainer__.__frames__[i].hideError(); + if(this.__arContainer__.__frames__[i].isUsed() === true){ + allAroles.push(this.__arContainer__.__frames__[i]); + allAroles2.push(this.__arContainer__.__frames__[i]); + } } } // --- collects all used roles depending on otherrole-constraints var allOroles = new Array(); - for(var i = 0; i !== this.__orContainer__.__frames__.length; ++i){ - this.__orContainer__.__frames__[i].hideError(); - if(this.__orContainer__.__frames__[i].isUsed() === true) - allOroles.push(this.__orContainer__.__frames__[i]); + if(this.__orContainer__ && this.__orContainer__.__frames__){ + for(var i = 0; i !== this.__orContainer__.__frames__.length; ++i){ + this.__orContainer__.__frames__[i].hideError(); + if(this.__orContainer__.__frames__[i].isUsed() === true) + allOroles.push(this.__orContainer__.__frames__[i]); + } } // --- checks all associationrole-constraints
Modified: trunk/src/ajax/javascripts/requests.js ============================================================================== --- trunk/src/ajax/javascripts/requests.js (original) +++ trunk/src/ajax/javascripts/requests.js Thu Apr 21 05:56:59 2011 @@ -10,6 +10,13 @@ //+ trunk/src/ajax/javascripts/external/MIT-LICENSE.txt. //+-----------------------------------------------------------------------------
+ +// --- replaces every / character that is not prefixed by a \ character +function escapeSlashInJSON(jsonString){ + return jsonString.replace(/([^\])//g, '$1\/').replace(/([^\])//g, '$1\/'); +} + + // --- Sets a timeout function which alerts a message. function setAjaxTimeout(time, url) { @@ -208,7 +215,7 @@ new Ajax.Request(COMMIT_URL, { "method" : "post", - "postBody" : json, + "postBody" : escapeSlashInJSON(json), "onSuccess" : createXHRHandler(onSuccessHandler, timeFun), "onFailure" : createXHRHandler(onFailure, timeFun)}); } @@ -228,7 +235,7 @@ var timeFun = setAjaxTimeout(TIMEOUT, COMMIT_URL); new Ajax.Request(MARK_AS_DELETED_URL, { "method" : "delete", - "postBody" : json, + "postBody" : escapeSlashInJSON(json), "onSuccess" : createXHRHandler(onSuccessHandler, timeFun), "onFailure" : createXHRHandler(onFailure, timeFun)}); }
Modified: trunk/src/ajax/javascripts/tmcl_tools.js ============================================================================== --- trunk/src/ajax/javascripts/tmcl_tools.js (original) +++ trunk/src/ajax/javascripts/tmcl_tools.js Thu Apr 21 05:56:59 2011 @@ -163,6 +163,7 @@ if(!anyConstraints || anyConstraints.length === 0) return players;
for(var i = 0; i !== anyConstraints.length; ++i){ + if(!anyConstraints[i].players) return players; for(var j = 0; j !== anyConstraints[i].players.length; ++j){ players.push(anyConstraints[i].players[j]) }
Modified: trunk/src/json/json_exporter.lisp ============================================================================== --- trunk/src/json/json_exporter.lisp (original) +++ trunk/src/json/json_exporter.lisp Thu Apr 21 05:56:59 2011 @@ -36,8 +36,9 @@ (or (eql what 'psis) (eql what 'item-identifiers) (eql what 'locators))) - (let ((items - (map 'list #'uri (funcall what parent-construct :revision revision)))) + (let ((items + (map 'list #'uri + (funcall what parent-construct :revision revision)))) (json:encode-json-to-string items))))
Modified: trunk/src/model/changes.lisp ============================================================================== --- trunk/src/model/changes.lisp (original) +++ trunk/src/model/changes.lisp Thu Apr 21 05:56:59 2011 @@ -37,10 +37,11 @@ (:documentation "Finds all associations for a topic.") (:method ((instance TopicC) &key (revision *TM-REVISION*)) (declare (type (or integer null) revision)) - (remove-duplicates - (map 'list #'(lambda(role) - (parent role :revision revision)) - (player-in-roles instance :revision revision))))) + (remove-null + (remove-duplicates + (map 'list #'(lambda(role) + (parent role :revision revision)) + (player-in-roles instance :revision revision))))))
(defgeneric find-associations (instance &key revision)
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 Thu Apr 21 05:56:59 2011 @@ -548,7 +548,7 @@ (let ((topictype (get-item-by-psi json-tmcl-constants::*topictype-psi* :revision 0)) (topictype-constraint (json-tmcl::is-type-constrained :revision 0))) - (format t "~%initialize cache: ") + (format t "~%initializing cache: ") (map 'list #'(lambda(top) (format t ".") (push-to-cache top topictype topictype-constraint)) @@ -576,7 +576,7 @@
(defun init-fragments () "Creates fragments of all topics that have a PSI." - (format t "create fragments: ") + (format t "creating fragments: ") (map 'list #'(lambda(top) (let ((psis-of-top (psis top))) (when psis-of-top