From lgiessmann at common-lisp.net Fri Jun 5 10:43:03 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Fri, 05 Jun 2009 06:43:03 -0400 Subject: [isidorus-cvs] r33 - in trunk: docs src/ajax/javascripts src/json src/unit_tests Message-ID: Author: lgiessmann Date: Fri Jun 5 06:42:59 2009 New Revision: 33 Log: client ajax: added the basic handling for roleplayer-constraints and associationrole-constraints Modified: trunk/docs/xtm_json.txt trunk/src/ajax/javascripts/datamodel.js trunk/src/ajax/javascripts/tmcl_tools.js trunk/src/json/json_tmcl.lisp trunk/src/unit_tests/poems.xtm Modified: trunk/docs/xtm_json.txt ============================================================================== --- trunk/docs/xtm_json.txt (original) +++ trunk/docs/xtm_json.txt Fri Jun 5 06:42:59 2009 @@ -341,7 +341,7 @@ //+----------------------------------------------------------------------------- { "players" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "topic-2-psi-1", "..."], <...> ] - "roleTypes" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-psi-1", "..." ], <...> ], + "roleType" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-psi-1", "..." ], <...> ], "cardMin" : "unsigned integer in string representation", "cardMax" : "unsigned integer in string representation or the string MAX_INT" } @@ -356,10 +356,10 @@ //+ The values cardMin and cardMax defines the cardinality of otherRoleType. //+----------------------------------------------------------------------------- { - "playerType" : [ "topic-psi-1", "topic-psi-2", "..." ], - "roleType" : [ "topic-psi-1", "topic-psi-2", "..." ], - "otherRoleType" : [ "topic-psi-1", "topic-psi-2", "..." ], - "otherPlayerType" : [ "topic-psi-1", "topic-psi-2", "..." ], + "players" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "topic-2-psi-1", "..."], <...> ] ], + "roleType" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-psi-1", "..." ], <...> ], + "otherPlayers" : [ "topic-psi-1", "topic-psi-2", "..." ], [ "topic-2-psi-1", "..."], <...> ] ], + "otherRoleType" : [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-psi-1", "..." ], <...> ], "cardMin" : "unsigned integer in string representation", "cardMax" : "unsigned integer in string representation or the string MAX_INT" } Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Fri Jun 5 06:42:59 2009 @@ -1276,11 +1276,12 @@ // --- representation of a role element. -var RoleC = Class.create(ContainerC, {"initialize" : function($super, itemIdentities, roleTypes, rolePlayers, owner, min, max){ +var RoleC = Class.create(ContainerC, {"initialize" : function($super, itemIdentities, roleTypes, rolePlayers, owner, removeFunction, addFunction){ $super(); if(!owner.__frames__) owner.__frames__ = new Array(); if(!roleTypes || roleTypes.length === 0) throw "From RoleC(): roleTypes must be set!"; - if(!rolePlayers || rolePlayers.length === 0) throw "From RoleC(): rolePalyers must be set"; + if(!rolePlayers || rolePlayers.length === 0) throw "From RoleC(): rolePlayers must be set"; + if(!removeFunction || !addFunction) throw "From RoleC(): removeFunction and addFunction must be set!"; owner.__frames__.push(this); this.__frame__.writeAttribute({"class" : CLASSES.roleFrame()}); this.__table__ = new Element("table", {"class" : CLASSES.roleFrame()}); @@ -1291,16 +1292,25 @@ 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, max); - setRemoveAddHandler(this, owner, 1, max, function(){ - return new RoleC(null, roleTypes, rolePlayers, owner, min, max); - }); + checkRemoveAddButtons(owner, 1, -1); + setRemoveAddHandler(this, owner, 1, -1, function(){ /*do nothing*/ }); + // --- resets the add and remove handlers + var cTd = this.__table__.select("tr." + CLASSES.itemIdentityFrame())[0].select("td." + CLASSES.controlColumn())[0].select("span." + CLASSES.clickable()); + var removeButton = cTd[1]; + var addButton = cTd[2]; + removeButton.show(); + addButton.show(); + removeButton.stopObserving(); + addButton.stopObserving(); + removeButton.observe("click", removeFunction); + addButton.observe("click", addFunction); // --- type var types = this.__roleTypes__.flatten(); this.__type__ = new Object(); var tr = newRow(CLASSES.typeFrame(), "Type", new SelectrowC(types, this.__type__, 1, 1).getFrame()); this.__table__.insert({"bottom" : tr}); + // TODO: implement a onTypeChangeHandler // --- player var players = this.__rolePlayers__.flatten(); @@ -1312,6 +1322,67 @@ alert("From RoleC(): " + err); } }, + "addPlayer" : function(player){ + if(!player || player.length === 0) return; + var selected = this.__player__.__frames__[0].getContent(); + var select = this.__player__.__frames__[0].getFrame().select("select")[0]; + select.update(""); + if(this.__rolePlayers__){ + var j = 0; + for(var i = 0; i !== player.length; ++i){ + j = 0; + for( ; j !== this.__rolePlayers__.length; ++j){ + if(this.__rolePlayers__[j].indexOf(player[i]) !== -1) break; + } + if(j !== this.__rolePlayers__.length){ + this.__rolePlayers__[j] = player; + alert("test"); + break; + } + } + if(j === this.__rolePlayers__.length)this.__rolePlayers__.push(player); + } + else { + this.__rolePlayers__ = new Array(player); + } + for(var i = 0; i !== this.__rolePlayers__.length; ++i){ + for(var j = 0; j !== this.__rolePlayers__[i].length; ++j){ + var opt = new Element("option", {"value" : this.__rolePlayers__[i][j]}).update(this.__rolePlayers__[i][j]); + if(this.__rolePlayers__[i][j] !== selected){ + select.insert({"bottom" : opt}); + } + else { + select.insert({"top" : opt}); + } + } + } + }, + "removePlayer" : function(player){ + if(!player || player.length === 0 || !this.__rolePlayers__ || this.__rolePlayers__.length === 0) return; + var selected = this.__player__.__frames__[0].getContent(); + var select = this.__player__.__frames__[0].getFrame().select("select")[0]; + select.update(""); + var j = 0; + for(var i = 0; i !== player.length; ++i){ + j = 0; + for( ; j !== this.__rolePlayers__.length; ++j){ + if(this.__rolePlayers__[j].indexOf(player[i]) !== -1) break; + } + if(j !== this.__rolePlayers__.length) break; + } + this.__rolePlayers__ = this.__rolePlayers__.slice(0, j).concat(this.__rolePlayers__.slice(j + 1, this.__rolePlayers__.length)); + for(var i = 0; i !== this.__rolePlayers__.length; ++i){ + for(var j = 0; j !== this.__rolePlayers__[i].length; ++j){ + var opt = new Element("option", {"value" : this.__rolePlayers__[i][j]}).update(this.__rolePlayers__[i][j]); + if(this.__rolePlayers__[i][j] !== selected){ + select.insert({"bottom" : opt}); + } + else { + select.insert({"top" : opt}); + } + } + } + }, "getType" : function(){ return this.__type__.__frames__[0].getContent(); }, @@ -1345,32 +1416,170 @@ // --- contains all roles of an association -var RoleContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, roleConstraints, playerConstraints, otherRoleConstraints){ +var RoleContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, associationRoleConstraints, rolePlayerConstraints, otherRoleConstraints){ $super(); this.__frame__.writeAttribute({"class" : CLASSES.roleContainer()}); - this.__container__ = new Object(); + this.__arContainer__ = new Object(); + this.__orContainer__ = new Object(); + + /* + + *associationrole-constraints: A association role constraint defines how many and of what type the roles in associations of given a type must be. + *min: card-min indicating the minimum number of times the role can appear in the association + *max: card-max indicating the maximum number of times the role can appear in the association + *roleplayer-constraints: A role player constraint defines a way to constrain the type of allowed role players of a given role with a given type + in an association of a given type. + *min: card-min indicating the minimum number of times a topic can play the role with the given type in the given + association of the given type + *max: card-max indicating the maximum number of times a topic can play the role with the given type in the given + association of the given type + *otherrole-constraints: A other role constraint defines a way to constrain the allowed type of role player given the existence of another role + player type in an association. + *min: card-min indicating the minimum number of times the other role can occur + *max: card-max indicating the maximum number of times the other role can occur + + +algorithmus: +OK *alle rollen aus associationroleconstraints erstellen in einem __arContainer__ +OK *?berpr?fen, ob die kardinalit?ten der roleplayer mit den kardinalit?ten der associationrole ?bereinstimmen +OK *card-min rp < card-min ar -> fehler +OK *card-max rp > card-max ar -> fehler +OK *card-min rp > card-max ar -> fehler +OK *card-max rp < card-min ar -> fehler +OK *zu allen gefundenen roles vorhandene roleplayer-constraints suchen +OK *alle roleplayer sammeln und an eine leere option anh?ngen, anschlie?end in RoleC anh?ngen +*__orContainer__ f?r otherrole-constraints initialisieren +*handler hinzuf?gen + */ + try{ - if((!contents || contents.length === 0) && roleConstraints && playerConstraints){ - for(var i = 0; playerConstraints && i !== playerConstraints.length; ++i){ - //new RoleC(new Array("itemIdentity " + i), playerConstraints[i].roleTypes, playerConstraints[i].players, this.__container__, 1, 4); - //this.__error__.insert({"before" : this.__container__.__frames__[i].getFrame()}); - } + if((!contents || contents.length === 0) && associationRoleConstraints){ + this.resetValues(associationRoleConstraints, rolePlayerConstraints, otherRoleConstraints); } else { // TODO: check already existing contents and order them to the corresponding fields } - - - } catch(err){ alert("From RoleContainerC(): " + err); } }, - "resetValues" : function(roleConstraints, playerConstraints, otherRoleConstraints){ + "resetValues" : function(associationRoleConstraints, rolePlayerConstraints, otherRoleConstraints){ + this.__associationRoleConstraints__ = associationRoleConstraints; + this.__rolePlayerConstraints__ = rolePlayerConstraints; + this.__otherRoleConstraints__ = otherRoleConstraints; + + try{ + for(var i = 0; this.__arContainer__.__frames__ && i !== this.__arContainer__.__frames__.length; ++i){ + this.__arContainer__.__frames__[i].remove(); + } + this.__arContainer__ = new Object(); + } + catch(err){ + this.__arContainer__ = new Object(); + } + try{ + for(var i = 0; this.__orContainer__.__frames__ && i !== this.__orContainer__.__frames__.length; ++i){ + this.__orContainer__.__frames__[i].remove(); + } + this.__orContainer__ = new Object(); + } + catch(err){ + this.__orContainer__ = new Object(); + } + + + // --- creates all roles from existing associationroleconstraints and roleplayerConstraints + // TODO: insert existing contents to the corresponding constraints + for(var i = 0; this.__associationRoleConstraints__ && i !== this.__associationRoleConstraints__.length; ++i){ + var arc = this.__associationRoleConstraints__[i]; + var foundRpcs = getRolePlayerConstraintsForRole(arc.roleType, this.__rolePlayerConstraints__); + this.__makeRolesFromARC__(arc, foundRpcs); + } + }, + "__makeRolesFromARC__" : function(associationRoleConstraint, rolePlayerConstraints){ + if(!associationRoleConstraint || !rolePlayerConstraints || rolePlayerConstraints.length === 0) return; + checkCardinalitiesARC_RPC(associationRoleConstraint, rolePlayerConstraints); + + // --- creates all roles with all needed players + var rolesCreated = 0; + var allAvailablePlayers = extractPlayersOfConstraints(rolePlayerConstraints); + var roleType = associationRoleConstraint.roleType; + var roleMin = associationRoleConstraint.cardMin; + for(var i = 0; i !== rolePlayerConstraints.length; ++i){ + var playerMin = rolePlayerConstraints[i].cardMin; + var currentAvailablePlayers = rolePlayerConstraints[i].players; + var cleanedPlayers = cleanPlayers(allAvailablePlayers, currentAvailablePlayers); + for(var j = playerMin; j < currentAvailablePlayers.length; ++j){ + cleanedPlayers.push(currentAvailablePlayers[j]); + } + if(currentAvailablePlayers.length < playerMin) throw "From __makeRolesFromARC__(): not enough players(=" + currentAvailablePlayers.length + ") to reach card-min(=" + playerMin + ") of roletype\"" + roleType.flatten()[0] + "\"!"; + for(var j = 0; j !== playerMin; ++j){ + var removeFunction = function(event){ alert("removeFunction"); }; + var addFunction = function(event){ alert("addFunction"); }; + var selectedPlayer = currentAvailablePlayers[j]; + var _players = cleanedPlayers; + _players.unshift(selectedPlayer); + var role = new RoleC(null, roleType, _players, this.__arContainer__, removeFunction, addFunction); + this.__setRoleChangePlayerHandler__(role); + this.__error__.insert({"before" : role.getFrame()}); + ++rolesCreated; + } + } + + // --- creates all further needed roles with players that owns a card-max > existing players + while(rolesCreated < roleMin){ + var currentlyCreated = 0; + 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; + if(existingRoles.length < rolePlayerConstraints[i].cardMax && availablePlayers.length > existingRoles.length){ + var currentAvailablePlayers = rolePlayerConstraints[i].players; + var cleanedPlayers = cleanPlayers(allAvailablePlayers, currentAvailablePlayers); + + // --- adds players that are not selected yet + for(var j = 0; j !== currentAvailablePlayers.length; ++j){ + if(this.getExistingRoles(roleType, currentAvailablePlayers[j], this.__arContainer__.__frames__).length === 0){ + cleanedPlayers.push(currentAvailablePlayers[j]); + } + } + + // --- removes the player which will be seleted by the new created role of all other select-elements + for(var j = 0; j !== this.__arContainer__.__frames__.length; ++j){ + this.__arContainer__.__frames__[j].removePlayer(cleanedPlayers[0]); + } + + var role = new RoleC(null, roleType, cleanedPlayers, this.__arContainer__, removeFunction, addFunction); + this.__setRoleChangePlayerHandler__(role); + this.__error__.insert({"before" : role.getFrame()}); + ++rolesCreated; + ++currentlyCreated; + } + } + if(currentlyCreated === 0) throw "Not enough players to create all needed roles of the type \"" + roleType.flatten()[0] + "\"!"; + } + }, + "__makeRolesFromORC__" : function(roleType, player){ + + }, + "getExistingRoles" : function(roleType, players, roles){ + var rolesFound = new Array(); + if(!roles || roles.length === 0) return rolesFound; - // TODO: implement + var allTypes = roleType && roleType.length !== 0 ? roleType.flatten() : new Array(); + var allPlayers = players && players.length !== 0 ? players.flatten() : new Array(); + for(var i = 0; i !== roles.length; ++i){ + if(allTypes.indexOf(roles[i].getType()) !== -1 && allPlayers.indexOf(roles[i].getPlayer()) !== -1) rolesFound.push(roles[i]); + } + + return rolesFound; + }, + "__setRoleChangePlayerHandler__" : function(role){ + var select = role.__table__.select("tr." + CLASSES.playerFrame())[0].select("td." + CLASSES.content())[0].select("select")[0]; + select.observe("change", function(event){ alert("changed!"); }); + }, "getContent" : function(){ // TODO: implement @@ -1380,9 +1589,6 @@ }, "isValid" : function(){ // TODO: implement - }, - "isUsed" : function(){ - // TODO: implement }}); Modified: trunk/src/ajax/javascripts/tmcl_tools.js ============================================================================== --- trunk/src/ajax/javascripts/tmcl_tools.js (original) +++ trunk/src/ajax/javascripts/tmcl_tools.js Fri Jun 5 06:42:59 2009 @@ -63,4 +63,140 @@ if(foundContents < min || foundContents > max) return false; } return true; +} + + +// --- Returns an array of rolePlayerConstraints belonging to the given type in roleType. +// --- roleType is of the form [["psi-1", "psi-2", "..."], ["sub-psi-1", "..."], <...>] +function getRolePlayerConstraintsForRole(roleType, rolePlayerConstraints){ + if(!roleType || roleType.length === 0 || !rolePlayerConstraints || rolePlayerConstraints.length === 0) return new Array(); + + var foundConstraints = new Array(); + var allRoleTypes = roleType.flatten(); + for(var i = 0; i !== rolePlayerConstraints.length; ++i){ + var allCRoleTypes = rolePlayerConstraints[i].roleType.flatten(); + for(var j = 0; j !== allRoleTypes.length; ++j){ + if(allCRoleTypes.indexOf(allRoleTypes[j]) !== -1){ + foundConstraints.push(rolePlayerConstraints[i]); + break; + } + } + } + return foundConstraints; +} + + +// --- Returns an array of otherRoleConstraints belonging to the given roleType and players. +// --- roleType is of the form [["psi-1", "psi-2", "..."], ["sub-psi-1", "..."], <...>] +// --- players is of the form [["t1-psi-1", "t1-psi-2", "..."], ["t2-psi-1", "..."], <...>] +function getOtherRoleConstraintsForRole(roleType, players, otherRoleConstraints){ + if(!roleType || roleType.length === 0 || !players || players.length === 0 || !otherRoleConstraints || otherRoleConstraints.length === 0) return new Array(); + + var foundConstraints = new Array(); + var allRoleTypes = roleType.flatten(); + var allPlayers = players.flatten(); + for(var i = 0; i !== otherRoleConstraints.length; ++i){ + var roleTypeMatches = false; + var allCRoleTypes = otherRoleConstraints[i].roleType.flatten(); + for(var j = 0; j !== allPlayers.length; ++j){ + if(allCRoleTypes.indexOf(allRoleTypes[j]) !== -1){ + var allCPlayers = otherRoleConstraints[i].players.flatten(); + for(var k = 0; k !== allPlayers.length; ++k){ + if(allCPlayers.indexOf(allPlayers[k]) !== -1){ + foundConstraints.push(otherRoleConstraints[i]); + break; + } + } + break; + } + } + } + return foundConstraints; +} + + +// --- Returns the sum of all cardMin values of all rolePlayerConstraints. +function getRolePlayerMinForRole(anyRoleConstraints){ + if(!anyRoleConstraints || anyRoleConstraints === 0) return 0; + var min = 0; + for(var i = 0; i !== anyRoleConstraints.length; ++i){ + min += parseInt(anyRoleConstraints[i].cardMin); + } + return min; +} + + +// --- Returns the sum of all cardMax values of all rolePlayerConstraints. +function getRolePlayerMaxForRole(anyRoleConstraints){ + if(!anyRoleConstraints || anyRoleConstraints === 0) return 0; + var max = 0; + for(var i = 0; i !== anyRoleConstraints.length; ++i){ + if(anyRoleConstraints[i].cardMax === "MAX_INT") return "*"; + else max += parseInt(anyRoleConstraints[i].cardMax); + } + return max; +} + + +// --- checks the cardinalities of all rolePlayerconstraints depending on a +// --- given associationRoleConstraint +function checkCardinalitiesARC_RPC(associationRoleConstraint, rolePlayerConstraints){ + if(!associationRoleConstraint) throw "From checkCardinalitiesARC(): associationRoleConstraint is not set!"; + if(!rolePlayerConstraints || rolePlayerConstraints.length === 0) throw "From checkCardinalitiesARC(): rolePlayerConstraints is not set!"; + var arMin = parseInt(associationRoleConstraint.cardMin); + var arMax = associationRoleConstraint.cardMax === "MAX_INT" ? "*" : parseInt(associationRoleConstraint.cardMax); + var rpcs = getRolePlayerConstraintsForRole(associationRoleConstraint.roleType, rolePlayerConstraints); + var rpMin = getRolePlayerMinForRole(rpcs); + var rpMax = getRolePlayerMaxForRole(rpcs); + var type = associationRoleConstraint.roleType.flatten()[0]; + + if(rpMax !== "*" && rpMax < arMin) throw "Not enough players available for roletype \"" + type + "\" (rpMax=" + rpMax + ", arMin=" + arMin + ")"; + if(arMax !== "*" && rpMin > arMax) throw "Too much players for the roletype \"" + type + "\" (rpMin=" + rpMin + ", arMax=" + arMax + ")"; + /* + if(rpMin < arMin) throw "sum of card-min(=" + rpMin + ") of all roleplayer-constraints < card-min(=" + arMin + ") of associationrole-constraint for the role \"" + type + "\"! not enough players"; + if(arMax !== "*" && (rpMax === "*" || rpMax > arMax)) throw "sum of card-max(=" + rpMax + ") of all roleplayer-constraints > card-max(=" + arMax + ") of associationrole-constraint for the role \"" + type + "\"! too much players" + if(arMax !== "*" && rpMin > arMax) throw "sum of card-min(=" + rpMin + ") of all roleplayer-constraints > card-max(=" + arMax + ") of associationrole-constraint for the role \"" + type + "\"! too much players"; + if(rpMax !== "*" && rpMax < arMin) throw "sum of card-max(=" + rpMax + ") of all roleplayer-constraints > card-min(=" + arMin + ") of associationrole-constraint for the role \"" + type + "\"! not enough players"; + */ +} + + +// --- Returns all listed players of a constraint of the type +// --- roleplayer-constraint or otherrole-constraint and returns them +// --- as an array. +function extractPlayersOfConstraints(anyConstraints){ + var players = new Array(); + if(!anyConstraints || anyConstraints.length === 0) return players; + + for(var i = 0; i !== anyConstraints.length; ++i){ + for(var j = 0; j !== anyConstraints[i].players.length; ++j){ + players.push(anyConstraints[i].players[j]) + } + } + + return players; +} + + +// --- Returns an array of players where the players from playersToClean will +// --- be deleted from allPlayers. +function cleanPlayers(allPlayers, playersToClean){ + var cleanedPlayers = new Array(); + if(!allPlayers) return cleanedPlayers; + if(!playersToClean) return allPlayers; + + for(var i = 0; i !== allPlayers.length; ++i){ + var toDel = false; + for(var j = 0; j !== allPlayers[i].length; ++j){ + for(var k = 0; k !== playersToClean.length; ++k){ + if(playersToClean[k].indexOf(allPlayers[i][j]) !== -1){ + toDel = true; + break; + } + } + if(toDel === true) break; + } + if(toDel === false) cleanedPlayers.push(allPlayers[i]); + } + return cleanedPlayers; } \ No newline at end of file Modified: trunk/src/json/json_tmcl.lisp ============================================================================== --- trunk/src/json/json_tmcl.lisp (original) +++ trunk/src/json/json_tmcl.lisp Fri Jun 5 06:42:59 2009 @@ -192,7 +192,7 @@ (topics-to-json-list (list-instances (getf involved-topic-tupple :player) topictype topictype-constraint)))) (json-role - (concatenate 'string "\"roleTypes\":" + (concatenate 'string "\"roleType\":" (topics-to-json-list (getf (list-subtypes (getf involved-topic-tupple :role) roletype roletype-constraint) :subtypes)))) (json-otherplayer @@ -291,7 +291,7 @@ (topics-to-json-list (list-instances (getf role-player-tupple :player) topictype topictype-constraint)))) (json-role - (concatenate 'string "\"roleTypes\":" + (concatenate 'string "\"roleType\":" (topics-to-json-list (getf (list-subtypes (getf role-player-tupple :role) roletype roletype-constraint) :subtypes)))) (card-min Modified: trunk/src/unit_tests/poems.xtm ============================================================================== --- trunk/src/unit_tests/poems.xtm (original) +++ trunk/src/unit_tests/poems.xtm Fri Jun 5 06:42:59 2009 @@ -1,5 +1,57 @@ + + + + + + + 1 + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1566,6 +1618,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + http://www.w3.org/2001/XMLSchema#float + + + + + + + + + + + + + + + + @@ -1732,10 +1824,10 @@ of type author and another role of type written which owns a player of type poem --> - - - + + @@ -1751,7 +1843,7 @@ - + @@ -1763,17 +1855,17 @@ - + - + - - - + + + @@ -1789,11 +1881,11 @@ - + - + @@ -1801,7 +1893,7 @@ - + @@ -1813,26 +1905,32 @@ - + - + - - - - + + + + - + + + 1 - + + + 1 @@ -1841,7 +1939,7 @@ - + @@ -1853,7 +1951,7 @@ - + @@ -1861,25 +1959,11 @@ - - - - - - - 1 - - - - 1 - - - - + @@ -1891,11 +1975,11 @@ - + - - + + @@ -1903,38 +1987,29 @@ - + - - + + + + - - - - - + + + + - - - + 1 - - - + 1 @@ -1943,11 +2018,11 @@ - + - + @@ -1955,7 +2030,7 @@ - + @@ -1963,11 +2038,25 @@ + + + + + + + 1 + + + + 1 + + + - + @@ -1979,11 +2068,11 @@ - + - - + + @@ -1991,16 +2080,20 @@ - + - - + + - - + + + @@ -2020,11 +2113,11 @@ - + - + @@ -2032,11 +2125,11 @@ - + - + @@ -2044,11 +2137,11 @@ - + - + @@ -2056,11 +2149,11 @@ - + - + @@ -2068,20 +2161,21 @@ - + - + - + + - - + + @@ -2097,11 +2191,11 @@ - + - + @@ -2109,17 +2203,17 @@ - + - + - - + + @@ -2135,11 +2229,11 @@ - + - + @@ -2147,11 +2241,11 @@ - + - + @@ -2159,446 +2253,22 @@ - + - + - - - - - - - 1 - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -2673,82 +2343,6 @@ - - - - - - - - 1 - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From lgiessmann at common-lisp.net Sun Jun 7 18:29:18 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Sun, 07 Jun 2009 14:29:18 -0400 Subject: [isidorus-cvs] r34 - trunk/src/ajax/javascripts Message-ID: Author: lgiessmann Date: Sun Jun 7 14:29:14 2009 New Revision: 34 Log: added the otherroleplayer-constraint and a player-type-change-handler to the ajax-client; currently there is missing a remove- and add- handler for roles and the possibility to set the new created topic as a roleplyer Modified: trunk/src/ajax/javascripts/datamodel.js Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Sun Jun 7 14:29:14 2009 @@ -1037,7 +1037,7 @@ "value" : this.__value__.value}; } return {"itemIdentities" : this.__itemIdentity__.getContent(true, true), - "type" : [this.__type__.__frames__[0].getContent()], + "type" : new Array(this.__type__.__frames__[0].getContent()), "scopes" : this.__scope__.getContent(), "resourceRef" : resourceRef, "resourceData" : resourceData}; @@ -1212,19 +1212,6 @@ _constraints = (constraints ? constraints.topicOccurrenceConstraints : null); this.__occurrence__ = new OccurrenceContainerC(_contents, _constraints); this.__table__.insert({"bottom" : newRow(CLASSES.occurrenceContainer(), "Occurrences", this.__occurrence__.getFrame())}); - - - - - - var btn = new Element("input", {"value" : "topic.toJSON()", "type" : "button"}); - function addBtnHandler(myself){ - btn.observe("click", function(event){ - alert(myself.toJSON()); - }) - } - addBtnHandler(this); - this.__frame__.insert({"bottom" : btn}); }catch(err){ alert("From TopciC(): " + err); } @@ -1336,7 +1323,6 @@ } if(j !== this.__rolePlayers__.length){ this.__rolePlayers__[j] = player; - alert("test"); break; } } @@ -1421,9 +1407,7 @@ this.__frame__.writeAttribute({"class" : CLASSES.roleContainer()}); this.__arContainer__ = new Object(); this.__orContainer__ = new Object(); - /* - *associationrole-constraints: A association role constraint defines how many and of what type the roles in associations of given a type must be. *min: card-min indicating the minimum number of times the role can appear in the association *max: card-max indicating the maximum number of times the role can appear in the association @@ -1437,22 +1421,7 @@ player type in an association. *min: card-min indicating the minimum number of times the other role can occur *max: card-max indicating the maximum number of times the other role can occur - - -algorithmus: -OK *alle rollen aus associationroleconstraints erstellen in einem __arContainer__ -OK *?berpr?fen, ob die kardinalit?ten der roleplayer mit den kardinalit?ten der associationrole ?bereinstimmen -OK *card-min rp < card-min ar -> fehler -OK *card-max rp > card-max ar -> fehler -OK *card-min rp > card-max ar -> fehler -OK *card-max rp < card-min ar -> fehler -OK *zu allen gefundenen roles vorhandene roleplayer-constraints suchen -OK *alle roleplayer sammeln und an eine leere option anh?ngen, anschlie?end in RoleC anh?ngen -*__orContainer__ f?r otherrole-constraints initialisieren -*handler hinzuf?gen */ - - try{ if((!contents || contents.length === 0) && associationRoleConstraints){ this.resetValues(associationRoleConstraints, rolePlayerConstraints, otherRoleConstraints); @@ -1489,7 +1458,6 @@ this.__orContainer__ = new Object(); } - // --- creates all roles from existing associationroleconstraints and roleplayerConstraints // TODO: insert existing contents to the corresponding constraints for(var i = 0; this.__associationRoleConstraints__ && i !== this.__associationRoleConstraints__.length; ++i){ @@ -1497,6 +1465,10 @@ var foundRpcs = getRolePlayerConstraintsForRole(arc.roleType, this.__rolePlayerConstraints__); this.__makeRolesFromARC__(arc, foundRpcs); } + // --- creates roles from otherrole-constraints + for(var i = 0; i !== this.__arContainer__.__frames__.length; ++i){ + this.__makeRolesFromORC__(this.__arContainer__.__frames__[i].getType(), this.__arContainer__.__frames__[i].getPlayer()); + } }, "__makeRolesFromARC__" : function(associationRoleConstraint, rolePlayerConstraints){ if(!associationRoleConstraint || !rolePlayerConstraints || rolePlayerConstraints.length === 0) return; @@ -1522,7 +1494,7 @@ var _players = cleanedPlayers; _players.unshift(selectedPlayer); var role = new RoleC(null, roleType, _players, this.__arContainer__, removeFunction, addFunction); - this.__setRoleChangePlayerHandler__(role); + this.__setRoleChangePlayerHandler__(role, this.__arContainer__.__frames__, rolePlayerConstraints, null); this.__error__.insert({"before" : role.getFrame()}); ++rolesCreated; } @@ -1552,7 +1524,7 @@ } var role = new RoleC(null, roleType, cleanedPlayers, this.__arContainer__, removeFunction, addFunction); - this.__setRoleChangePlayerHandler__(role); + this.__setRoleChangePlayerHandler__(role, this.__arContainer__.__frames__, rolePlayerConstraints, null); this.__error__.insert({"before" : role.getFrame()}); ++rolesCreated; ++currentlyCreated; @@ -1562,7 +1534,38 @@ } }, "__makeRolesFromORC__" : function(roleType, player){ + var orpcs = getOtherRoleConstraintsForRole(new Array(roleType), new Array(player), this.__otherRoleConstraints__); + var removeFunction = function(event){ alert("removeFunction"); }; + var addFunction = function(event){ alert("addFunction"); }; + for(var i = 0; i !== orpcs.length; ++i){ + var cPlayers = orpcs[i].players; + var cRoleType = orpcs[i].roleType; + var cOtherPlayers = orpcs[i].otherPlayers; + var cOtherRoleType = orpcs[i].otherRoleType; + var cMin = parseInt(orpcs[i].cardMin); + if(!cOtherPlayers || cOtherPlayers.length < cMin) throw "from __makeRolesFromORC__(): not enough players(=" + cOtherPlayers.length + ") for roletype + \"" + cOtherRoleType.flatten()[0] + "\"!"; + 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 + // --- current players list + var cleanedPlayers = new Array(); + for(var k = 0; k !== cOtherPlayers.length; ++k){ + if(this.getExistingRoles(cOtherRoleType, cOtherPlayers[k], this.__orContainer__.__frames__).length === 0){ + cleanedPlayers.push(cOtherPlayers[k]); + } + } + // --- removes the player that will be selected in this role + // --- from all existing roles + for(var j = 0; this.__orContainer__.__frames__ && j !== this.__orContainer__.__frames__.length; ++j){ + this.__orContainer__.__frames__[j].removePlayer(cleanedPlayers[0]); + } + + var role = new RoleC(null, cOtherRoleType, cleanedPlayers, this.__orContainer__, removeFunction, addFunction); + this.__setRoleChangePlayerHandler__(role, this.__orContainer__.__frames__, null, orpcs); + this.__error__.insert({"before" : role.getFrame()}); + } + } }, "getExistingRoles" : function(roleType, players, roles){ var rolesFound = new Array(); @@ -1576,19 +1579,90 @@ return rolesFound; }, - "__setRoleChangePlayerHandler__" : function(role){ + "__setRoleChangePlayerHandler__" : function(role, roleContainer, arConstraints, orConstraints){ + var constraints = null; + if(arConstraints && arConstraints.length !== 0) constraints = arConstraints; + else if(orConstraints && orConstraints.length !== 0) constraints = orConstraints; + else if(arConstraints && orConstraints && arConstraints.length !== 0 && orConstraints.length !== 0) throw "From __setRoleChangePlayerHandler__(): one of the parameters arConstraints or orConstraints must be set to null"; + role.__lastPlayer__ = new Array(role.getPlayer()); var select = role.__table__.select("tr." + CLASSES.playerFrame())[0].select("td." + CLASSES.content())[0].select("select")[0]; - select.observe("change", function(event){ alert("changed!"); }); - + function setEvent(myself){ + select.observe("change", function(event){ + role.__lastPlayer__.push(role.getPlayer()); + if(role.__lastPlayer__.length > 2) role.__lastPlayer__.shift(); + if(!roleContainer || roleContainer.length < 2 || ! constraints || constraints.length === 0) return; + role.getLastPlayer = function(){ + return role.__lastPlayer__[role.__lastPlayer__.length - 2]; + } + // --- selects the players which have to be removed or added to + // --- the found roles + var playerToAdd = new Array(role.getLastPlayer()); + var playerToRemove = new Array(role.getPlayer()); + + // --- collects all roles depending on the same constraint as the passed role + var existingRoles = new Array(); + for(var i = 0; constraints && i !== constraints.length; ++i){ + var roleType = orConstraints ? constraints[i].otherRoleType : constraints[i].roleType; + var players = orConstraints ? constraints[i].otherPlayers : constraints[i].players; + + // --- adds new psi of the roles have to be added + for(var j = 0; j !== players.length; ++j){ + if(players[j].indexOf(playerToRemove[0]) !== -1){ + for(var l = 0; l !== players[j].length; ++l){ + if(players[j][l] !== playerToRemove[0]) playerToRemove.push(players[j][l]); + } + } + if(players[j].indexOf(playerToAdd[0]) !== -1){ + for(var l = 0; l !== players[j].length; ++l){ + if(players[j][l] !== playerToAdd[0]) playerToAdd.push(players[j][l]); + } + } + } + + var foundRoles = myself.getExistingRoles(roleType, players, roleContainer); + for(var j = 0; j !== foundRoles.length; ++j){ + existingRoles.push(foundRoles[j]); + } + } + existingRoles = existingRoles.without(role); + + // --- removes and adds the new selected psi-value + // --- and the old deselected psi if the player is another one + if(playerToRemove.indexOf(role.getLastPlayer()) === -1){ + for(var i = 0; i !== existingRoles.length; ++i){ + existingRoles[i].addPlayer(playerToAdd); + existingRoles[i].removePlayer(playerToRemove); + } + } + }); + } + setEvent(this); }, "getContent" : function(){ - // TODO: implement + if((!this.__orContainer__.__frames__ && this.__orContainer__.frames__.length === 0) || (!this.__arContainer__.__frames__ && this.__arContainer__.__frames__.length === 0)) return null; + var roles = new Array(); + for(var i = 0; this.__arContainer__.__frames__ && i !== this.__arContainer__.__frames__.length; ++i){ + roles.push(this.__arContainer__.__frames__[i].getContent()); + } + for(var i = 0; this.__orContainer__.__frames__ && i !== this.__orContainer__.__frames__.length; ++i){ + roles.push(this.__orContainer__.__frames__[i].getContent()); + } + return roles; }, "toJSON" : function(){ - // TODO: implement + if((!this.__orContainer__.__frames__ && this.__orContainer__.frames__.length === 0) || (!this.__arContainer__.__frames__ && this.__arContainer__.__frames__.length === 0)) return "null"; + var roles = "["; + for(var i = 0; this.__arContainer__.__frames__ && i !== this.__arContainer__.__frames__.length; ++i){ + roles += this.__arContainer__.__frames__[i].toJSON() + ","; + } + for(var i = 0; this.__orContainer__.__frames__ && i !== this.__orContainer__.__frames__.length; ++i){ + roles += this.__orContainer__.__frames__[i].toJSON() + ","; + } + return roles.substring(0, roles.length - 1) + "]"; }, "isValid" : function(){ // TODO: implement + return true; }}); @@ -1676,16 +1750,26 @@ this.__roles__.resetValues(_roleConstraints, _playerConstraints, _otherRoleConstraints); }, "getContent" : function(){ - // TODO: implement + if(!this.isUsed()) return null; + return {"itemIdentities" : this.__itemIdentity__.getContent(true, true), + "type" : new Array(this.__type__.__frames__[0].getContent()), + "scopes" : this.__scope__.getContent(), + "roles" : this.__roles__.getContent()}; }, "toJSON" : function(){ - // TODO: implement + if(!this.isUsed()) return "null"; + return "{\"itemIdentities\":" + this.__itemIdentity__.toJSON(true, true) + + ",\"type\":[" + this.__type__.__frames__[0].toJSON() + "]" + + ",\"scopes\":" + this.__scope__.toJSON() + + ",\"roles\":" + this.__roles__.toJSON() + "}"; }, "isValid" : function(){ // TODO: implement + return true; }, "isUsed" : function(){ - // TODO: implement + // TODO: implement (activate button) + return true; }}); @@ -1718,22 +1802,56 @@ tr.update(td); this.__table__.insert({"bottom" : tr}); } + function setMinimizeHandler(myself){ + myself.__caption__.observe("click", function(event){ + myself.minimize(); + }); + } + setMinimizeHandler(this); +/* + var button = new Element("input", {"type" : "button", "value" : "toJSON()"}); + function test(myself){ + button.observe("click", function(event){ + alert("content:\n\n" + myself.getContent()); + alert("JSON:\n\n" + myself.toJSON()); + }); + } + test(this); + this.getFrame().insert({"bottom" : button}); +*/ } catch(err){ alert("From AssociationContainerC(): " + err); } }, "getContent" : function(){ - // TODO: implement + var associations = new Array(); + for(var i = 0; this.__container__.__frames__ && i !== this.__container__.__frames__.length; ++i){ + if(this.__container__.__frames__[i].isUsed() === true) associations.push(this.__container__.__frames__[i].getContent()); + } + if(associations.length === 0) return null; + return associations; }, "toJSON" : function(){ - // TODO: implement + var associations = "["; + for(var i = 0; this.__container__.__frames__ && i !== this.__container__.__frames__.length; ++i){ + if(this.__container__.__frames__[i].isUsed() === true) associations += this.__container__.__frames__[i].toJSON() +","; + } + + if(associations === "[") return "null"; + return associations.substring(0, associations.length - 1) + "]"; }, "isValid" : function(){ // TODO: implement + return true; }, "minimize" : function(){ - // TODO: implement + var rows = this.__table__.select("tr." + CLASSES.associationFrame()); + for(var i = 0; i != rows.length; ++i){ + if(this.__minimized__ === false) rows[i].hide(); + else rows[i].show(); + } + this.__minimized__ = !this.__minimized__; }}); From lgiessmann at common-lisp.net Wed Jun 10 07:15:19 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Wed, 10 Jun 2009 03:15:19 -0400 Subject: [isidorus-cvs] r35 - in trunk: docs src/ajax/javascripts src/json Message-ID: Author: lgiessmann Date: Wed Jun 10 03:15:18 2009 New Revision: 35 Log: ajax-client: fixed some problems in the onPlayerChangeHandler and added the possibility to use the new created topic as a player in associations which allows it Modified: trunk/docs/xtm_json.txt trunk/src/ajax/javascripts/constants.js trunk/src/ajax/javascripts/create.js trunk/src/ajax/javascripts/datamodel.js trunk/src/ajax/javascripts/tmcl_tools.js trunk/src/json/json_tmcl.lisp Modified: trunk/docs/xtm_json.txt ============================================================================== --- trunk/docs/xtm_json.txt (original) +++ trunk/docs/xtm_json.txt Wed Jun 10 03:15:18 2009 @@ -322,7 +322,7 @@ //+ in an association of a certain associationtype (the objects owner). //+----------------------------------------------------------------------------- { - "roleType" : [ [ "topic-psi-1", "topic-psi-2", "..." ], ["subtype-1-psi-1", "..."], <...> ], + "roleType" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-1-psi-1", "..."], <...> ], "cardMin" : "unsigned integer in string representation", "cardMax" : "unsigned integer in string representation or the string MAX_INT" } @@ -340,7 +340,8 @@ //+ association of a given type (= objects owner). //+----------------------------------------------------------------------------- { - "players" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "topic-2-psi-1", "..."], <...> ] + "playerType" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-1-psi-1", "..." ], <...> ], + "players" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "topic-2-psi-1", "..."], <...> ], "roleType" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-psi-1", "..." ], <...> ], "cardMin" : "unsigned integer in string representation", "cardMax" : "unsigned integer in string representation or the string MAX_INT" @@ -356,8 +357,10 @@ //+ The values cardMin and cardMax defines the cardinality of otherRoleType. //+----------------------------------------------------------------------------- { + "playerType" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-1-psi-1", "..." ], <...> ], "players" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "topic-2-psi-1", "..."], <...> ] ], "roleType" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-psi-1", "..." ], <...> ], + "otherPlayerType" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-1-psi-1", "..." ], <...> ], "otherPlayers" : [ "topic-psi-1", "topic-psi-2", "..." ], [ "topic-2-psi-1", "..."], <...> ] ], "otherRoleType" : [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-psi-1", "..." ], <...> ], "cardMin" : "unsigned integer in string representation", Modified: trunk/src/ajax/javascripts/constants.js ============================================================================== --- trunk/src/ajax/javascripts/constants.js (original) +++ trunk/src/ajax/javascripts/constants.js Wed Jun 10 03:15:18 2009 @@ -30,6 +30,7 @@ var ANY_URI = "http://www.w3.org/2001/XMLSchema#anyURI"; var STRING = "http://www.w3.org/2001/XMLSchema#string"; +var CURRENT_TOPIC = "**current-topic**"; // --- Contains most css classes used in this project // --- There should be called only the function to be sure to don't override Modified: trunk/src/ajax/javascripts/create.js ============================================================================== --- trunk/src/ajax/javascripts/create.js (original) +++ trunk/src/ajax/javascripts/create.js Wed Jun 10 03:15:18 2009 @@ -36,11 +36,16 @@ items[i].remove(); } - var topic = new TopicC(null, (constraints ? constraints.topicConstraints : null)); + var instanceOfs = new Array(); + for(var i = 0; psis && i !== psis.length; ++i){ + instanceOfs.push(new Array(psis[i])); + } + var topic = new TopicC(null, (constraints ? constraints.topicConstraints : null), instanceOfs); var liT = new Element("li", {"class" : CLASSES.topicFrame()}).update(topic.getFrame()); context.insert({"after" : liT}); - var associations = new AssociationContainerC(null, (constraints ? constraints.associationsConstraints : null)); + addTopicAsPlayer((constraints ? constraints.associationsConstraints : null), topic.getContent().instanceOfs); + var associations = new AssociationContainerC(null, (constraints ? constraints.associationsConstraints : null), topic); var liA = new Element("li", {"class" : CLASSES.associationContainer()}).update(associations.getFrame()); liT.insert({"after" : liA}); } Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Wed Jun 10 03:15:18 2009 @@ -243,7 +243,8 @@ myself.showError(str); } else { - successFun(contents, json); + //successFun(contents, json); + successFun(myself.getContent(true, true), json); } } @@ -1163,9 +1164,10 @@ // --- representation of a topic element. -var TopicC = Class.create(ContainerC, {"initialize" : function($super, content, constraints){ +var TopicC = Class.create(ContainerC, {"initialize" : function($super, content, constraints, instanceOfs){ $super(); this.__minimized__ = false; + this.__instanceOfs__ = (!instanceOfs || instanceOfs.length === 0 ? null : instanceOfs); try{ this.__frame__ .writeAttribute({"class" : CLASSES.topicFrame()}); this.__table__ = new Element("table", {"class" : CLASSES.topicFrame()}); @@ -1226,6 +1228,7 @@ "itemIdentities" : this.__itemIdentity__.getContent(true, true), "subjectLocators" : this.__subjectLocator__.getContent(true, true), "subjectIdentifiers" : this.__subjectIdentifier__.getContent(true, true), + "instanceOfs" : this.__instanceOfs__, "names" : this.__name__.getContent(), "occurrences" : this.__occurrence__.getContent()}; } @@ -1239,6 +1242,7 @@ ",\"itemIdentities\":" + this.__itemIdentity__.toJSON(true, true) + ",\"subjectLocators\":" + this.__subjectLocator__.toJSON(true, true) + ",\"subjectIdentifiers\":" + this.__subjectIdentifier__.toJSON(true, true) + + ",\"instanceOfs\":" + (!this.__instanceOfs__ ? "null" : this.__instanceOfs__.toJSON()) + ",\"names\":" + this.__name__.toJSON() + ",\"occurrences\":" + this.__occurrence__.toJSON() + "}"; } @@ -1259,6 +1263,9 @@ else rows[i].show(); } this.__minimized__ = !this.__minimized__; + }, + "hasPsi" : function(){ + return this.__subjectIdentifier__.getContent(true, true).length !== 0; }}); @@ -1311,7 +1318,7 @@ }, "addPlayer" : function(player){ if(!player || player.length === 0) return; - var selected = this.__player__.__frames__[0].getContent(); + var selected = this.getPlayer(); var select = this.__player__.__frames__[0].getFrame().select("select")[0]; select.update(""); if(this.__rolePlayers__){ @@ -1338,6 +1345,7 @@ select.insert({"bottom" : opt}); } else { + opt.writeAttribute({"selected" : "selected"}); select.insert({"top" : opt}); } } @@ -1345,7 +1353,7 @@ }, "removePlayer" : function(player){ if(!player || player.length === 0 || !this.__rolePlayers__ || this.__rolePlayers__.length === 0) return; - var selected = this.__player__.__frames__[0].getContent(); + var selected = this.getPlayer(); var select = this.__player__.__frames__[0].getFrame().select("select")[0]; select.update(""); var j = 0; @@ -1364,6 +1372,7 @@ select.insert({"bottom" : opt}); } else { + opt.writeAttribute({"selected" : "selected"}); select.insert({"top" : opt}); } } @@ -1773,9 +1782,10 @@ }}); -var AssociationContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints){ +var AssociationContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints, mainTopic){ $super(); this.__minimized__ = false; + this.__mainTopic__ = mainTopic; try{ this.__frame__ .writeAttribute({"class" : CLASSES.associationContainer()}); this.__table__ = new Element("table", {"class" : CLASSES.associationContainer()}); @@ -1808,17 +1818,18 @@ }); } setMinimizeHandler(this); -/* + var button = new Element("input", {"type" : "button", "value" : "toJSON()"}); function test(myself){ button.observe("click", function(event){ + try{ alert("content:\n\n" + myself.getContent()); - alert("JSON:\n\n" + myself.toJSON()); + alert("JSON:\n\n" + myself.toJSON().gsub("\"topicRef\":\\[\"\\*\\*current-topic\\*\\*\"\\]", myself.__mainTopic__.getContent().subjectIdentifiers.toJSON())); + }catch(err){ alert("test: " + err); } }); } test(this); this.getFrame().insert({"bottom" : button}); -*/ } catch(err){ alert("From AssociationContainerC(): " + err); Modified: trunk/src/ajax/javascripts/tmcl_tools.js ============================================================================== --- trunk/src/ajax/javascripts/tmcl_tools.js (original) +++ trunk/src/ajax/javascripts/tmcl_tools.js Wed Jun 10 03:15:18 2009 @@ -152,12 +152,6 @@ if(rpMax !== "*" && rpMax < arMin) throw "Not enough players available for roletype \"" + type + "\" (rpMax=" + rpMax + ", arMin=" + arMin + ")"; if(arMax !== "*" && rpMin > arMax) throw "Too much players for the roletype \"" + type + "\" (rpMin=" + rpMin + ", arMax=" + arMax + ")"; - /* - if(rpMin < arMin) throw "sum of card-min(=" + rpMin + ") of all roleplayer-constraints < card-min(=" + arMin + ") of associationrole-constraint for the role \"" + type + "\"! not enough players"; - if(arMax !== "*" && (rpMax === "*" || rpMax > arMax)) throw "sum of card-max(=" + rpMax + ") of all roleplayer-constraints > card-max(=" + arMax + ") of associationrole-constraint for the role \"" + type + "\"! too much players" - if(arMax !== "*" && rpMin > arMax) throw "sum of card-min(=" + rpMin + ") of all roleplayer-constraints > card-max(=" + arMax + ") of associationrole-constraint for the role \"" + type + "\"! too much players"; - if(rpMax !== "*" && rpMax < arMin) throw "sum of card-max(=" + rpMax + ") of all roleplayer-constraints > card-min(=" + arMin + ") of associationrole-constraint for the role \"" + type + "\"! not enough players"; - */ } @@ -199,4 +193,51 @@ if(toDel === false) cleanedPlayers.push(allPlayers[i]); } return cleanedPlayers; +} + + +// --- Ads the new created topic as a player to all association constraints +// --- where the player-type is one of the topic's instanceOf-topics. +function addTopicAsPlayer(associationsConstraints, topicInstanceOfs){ + if(!associationsConstraints || associationsConstraints.length === 0 || !topicInstanceOfs || topicInstanceOfs.length === 0) return; + var instanceOfsPsis = topicInstanceOfs.flatten(); + for(var i = 0; i !== associationsConstraints.length; ++i){ + // --- associationrole-constraints + if(associationsConstraints[i].rolePlayerConstraints){ + rpcs = associationsConstraints[i].rolePlayerConstraints; + for(var j = 0; j !== rpcs.length; ++j){ + for(var k = 0; k !== rpcs[j].playerType.length; ++k){ + for(var l = 0; l !== rpcs[j].playerType[k].length; ++l){ + if(instanceOfsPsis.indexOf(rpcs[j].playerType[k][l]) !== -1){ + rpcs[j].players.push(new Array(CURRENT_TOPIC)); + break; + } + } + } + } + } + + // --- otherrole-constraints + if(associationsConstraints[i].otherRoleConstraints){ + orcs = associationsConstraints[i].otherRoleConstraints; + for(var j = 0; j !== orcs.length; ++j){ + for(var k = 0; k !== orcs[j].playerType.length; ++k){ + for(var l = 0; l !== orcs[j].playerType[k].length; ++l){ + if(instanceOfsPsis.indexOf(orcs[j].playerType[k][l]) !== -1){ + orcs[j].players.push(new Array(CURRENT_TOPIC)); + break; + } + } + } + for(var k = 0; k !== orcs[j].otherPlayerType.length; ++k){ + for(var l = 0; l !== orcs[j].otherPlayerType[k].length; ++l){ + if(instanceOfsPsis.indexOf(orcs[j].otherPlayerType[k][l]) !== -1){ + orcs[j].otherPlayers.push(new Array(CURRENT_TOPIC)); + break; + } + } + } + } + } + } } \ No newline at end of file Modified: trunk/src/json/json_tmcl.lisp ============================================================================== --- trunk/src/json/json_tmcl.lisp (original) +++ trunk/src/json/json_tmcl.lisp Wed Jun 10 03:15:18 2009 @@ -187,7 +187,10 @@ (uri (first (psis (getf involved-topic-tupple :otherrole)))) constraint-lists)) - (let ((json-player + (let ((json-player-type + (concatenate 'string "\"playerType\":" + (topics-to-json-list (getf (list-subtypes (getf involved-topic-tupple :player) nil nil) :subtypes)))) + (json-player (concatenate 'string "\"players\":" (topics-to-json-list (list-instances (getf involved-topic-tupple :player) topictype topictype-constraint)))) @@ -195,6 +198,9 @@ (concatenate 'string "\"roleType\":" (topics-to-json-list (getf (list-subtypes (getf involved-topic-tupple :role) roletype roletype-constraint) :subtypes)))) + (json-otherplayer-type + (concatenate 'string "\"otherPlayerType\":" + (topics-to-json-list (getf (list-subtypes (getf involved-topic-tupple :otherplayer) nil nil) :subtypes)))) (json-otherplayer (concatenate 'string "\"otherPlayers\":" (topics-to-json-list @@ -209,7 +215,7 @@ (concatenate 'string "\"cardMax\":" (getf (first constraint-lists) :card-max)))) (setf cleaned-otherrole-constraints (concatenate 'string cleaned-otherrole-constraints - "{" json-player "," json-role "," json-otherplayer "," json-otherrole "," card-min "," card-max "},"))))) + "{" json-player-type "," json-player "," json-role "," json-otherplayer-type "," json-otherplayer "," json-otherrole "," card-min "," card-max "},"))))) (if (string= cleaned-otherrole-constraints "[") (setf cleaned-otherrole-constraints "null") (setf cleaned-otherrole-constraints @@ -272,7 +278,6 @@ :test #'(lambda(x y) (and (eq (getf x :player) (getf y :player)) (eq (getf x :role) (getf y :role))))))) - (let ((cleaned-roleplayer-constraints "[")) (loop for role-player-tupple in role-player-tupples do (let ((constraint-lists @@ -286,7 +291,10 @@ (uri (first (psis (getf role-player-tupple :role)))) (uri (first (psis (getf role-player-tupple :player)))) constraint-lists)) - (let ((json-players + (let ((json-player-type + (concatenate 'string "\"playerType\":" + (topics-to-json-list (getf (list-subtypes (getf role-player-tupple :player) nil nil) :subtypes)))) + (json-players (concatenate 'string "\"players\":" (topics-to-json-list (list-instances (getf role-player-tupple :player) topictype topictype-constraint)))) @@ -300,7 +308,7 @@ (concatenate 'string "\"cardMax\":" (getf (first constraint-lists) :card-max)))) (setf cleaned-roleplayer-constraints (concatenate 'string cleaned-roleplayer-constraints - "{" json-players "," json-role "," card-min "," card-max "},"))))) + "{" json-player-type "," json-players "," json-role "," card-min "," card-max "},"))))) (if (string= cleaned-roleplayer-constraints "[") (setf cleaned-roleplayer-constraints "null") (setf cleaned-roleplayer-constraints From lgiessmann at common-lisp.net Wed Jun 10 13:21:23 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Wed, 10 Jun 2009 09:21:23 -0400 Subject: [isidorus-cvs] r36 - trunk/src/ajax/javascripts Message-ID: Author: lgiessmann Date: Wed Jun 10 09:21:22 2009 New Revision: 36 Log: ajax-client: added an "add" and an "remove" handler to the roles depending on otherrole-constraints Modified: trunk/src/ajax/javascripts/datamodel.js Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Wed Jun 10 09:21:22 2009 @@ -1270,12 +1270,11 @@ // --- representation of a role element. -var RoleC = Class.create(ContainerC, {"initialize" : function($super, itemIdentities, roleTypes, rolePlayers, owner, removeFunction, addFunction){ +var RoleC = Class.create(ContainerC, {"initialize" : function($super, itemIdentities, roleTypes, rolePlayers, owner){ $super(); if(!owner.__frames__) owner.__frames__ = new Array(); if(!roleTypes || roleTypes.length === 0) throw "From RoleC(): roleTypes must be set!"; if(!rolePlayers || rolePlayers.length === 0) throw "From RoleC(): rolePlayers must be set"; - if(!removeFunction || !addFunction) throw "From RoleC(): removeFunction and addFunction must be set!"; owner.__frames__.push(this); this.__frame__.writeAttribute({"class" : CLASSES.roleFrame()}); this.__table__ = new Element("table", {"class" : CLASSES.roleFrame()}); @@ -1288,23 +1287,16 @@ 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*/ }); - // --- resets the add and remove handlers + // --- gets the add and remove button var cTd = this.__table__.select("tr." + CLASSES.itemIdentityFrame())[0].select("td." + CLASSES.controlColumn())[0].select("span." + CLASSES.clickable()); - var removeButton = cTd[1]; - var addButton = cTd[2]; - removeButton.show(); - addButton.show(); - removeButton.stopObserving(); - addButton.stopObserving(); - removeButton.observe("click", removeFunction); - addButton.observe("click", addFunction); + this.__removeButton__ = cTd[1]; + this.__addButton__ = cTd[2]; // --- type var types = this.__roleTypes__.flatten(); this.__type__ = new Object(); var tr = newRow(CLASSES.typeFrame(), "Type", new SelectrowC(types, this.__type__, 1, 1).getFrame()); this.__table__.insert({"bottom" : tr}); - // TODO: implement a onTypeChangeHandler // --- player var players = this.__rolePlayers__.flatten(); @@ -1316,6 +1308,24 @@ alert("From RoleC(): " + err); } }, + "setAddHandler" : function(handler){ + if(!handler) return; + this.__addButton__.stopObserving(); + var addButton = this.__addButton__; + function addHandler(myself){ + addButton.observe("click", function(event){ handler(myself); }); + } + addHandler(this); + }, + "setRemoveHandler" : function(handler){ + if(!handler) return; + this.__removeButton__.stopObserving(); + var removeButton = this.__removeButton__; + function addHandler(myself){ + removeButton.observe("click", function(event){ handler(myself); }); + } + addHandler(this); + }, "addPlayer" : function(player){ if(!player || player.length === 0) return; var selected = this.getPlayer(); @@ -1416,21 +1426,6 @@ this.__frame__.writeAttribute({"class" : CLASSES.roleContainer()}); this.__arContainer__ = new Object(); this.__orContainer__ = new Object(); - /* - *associationrole-constraints: A association role constraint defines how many and of what type the roles in associations of given a type must be. - *min: card-min indicating the minimum number of times the role can appear in the association - *max: card-max indicating the maximum number of times the role can appear in the association - *roleplayer-constraints: A role player constraint defines a way to constrain the type of allowed role players of a given role with a given type - in an association of a given type. - *min: card-min indicating the minimum number of times a topic can play the role with the given type in the given - association of the given type - *max: card-max indicating the maximum number of times a topic can play the role with the given type in the given - association of the given type - *otherrole-constraints: A other role constraint defines a way to constrain the allowed type of role player given the existence of another role - player type in an association. - *min: card-min indicating the minimum number of times the other role can occur - *max: card-max indicating the maximum number of times the other role can occur - */ try{ if((!contents || contents.length === 0) && associationRoleConstraints){ this.resetValues(associationRoleConstraints, rolePlayerConstraints, otherRoleConstraints); @@ -1487,9 +1482,9 @@ var rolesCreated = 0; var allAvailablePlayers = extractPlayersOfConstraints(rolePlayerConstraints); var roleType = associationRoleConstraint.roleType; - var roleMin = associationRoleConstraint.cardMin; + var roleMin = associationRoleConstraint.cardMin === 0 ? 1 : parseInt(associationRoleConstraint.cardMin); for(var i = 0; i !== rolePlayerConstraints.length; ++i){ - var playerMin = rolePlayerConstraints[i].cardMin; + var playerMin = rolePlayerConstraints[i].cardMin === 0 ? 1 : parseInt(rolePlayerConstraints[i].cardMin); var currentAvailablePlayers = rolePlayerConstraints[i].players; var cleanedPlayers = cleanPlayers(allAvailablePlayers, currentAvailablePlayers); for(var j = playerMin; j < currentAvailablePlayers.length; ++j){ @@ -1497,13 +1492,14 @@ } if(currentAvailablePlayers.length < playerMin) throw "From __makeRolesFromARC__(): not enough players(=" + currentAvailablePlayers.length + ") to reach card-min(=" + playerMin + ") of roletype\"" + roleType.flatten()[0] + "\"!"; for(var j = 0; j !== playerMin; ++j){ - var removeFunction = function(event){ alert("removeFunction"); }; - var addFunction = function(event){ alert("addFunction"); }; var selectedPlayer = currentAvailablePlayers[j]; var _players = cleanedPlayers; _players.unshift(selectedPlayer); - var role = new RoleC(null, roleType, _players, this.__arContainer__, removeFunction, addFunction); + var role = new RoleC(null, roleType, _players, this.__arContainer__); + this.__checkARCButtons__(role, associationRoleConstraint, rolePlayerConstraints[i]); this.__setRoleChangePlayerHandler__(role, this.__arContainer__.__frames__, rolePlayerConstraints, null); + this.__setARCAddHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); + this.__setARCRemoveHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); this.__error__.insert({"before" : role.getFrame()}); ++rolesCreated; } @@ -1532,8 +1528,11 @@ this.__arContainer__.__frames__[j].removePlayer(cleanedPlayers[0]); } - var role = new RoleC(null, roleType, cleanedPlayers, this.__arContainer__, removeFunction, addFunction); + var role = new RoleC(null, roleType, cleanedPlayers, this.__arContainer__); + this.__checkARCButtons__(role, associationRoleConstraint, rolePlayerConstraints[i]); this.__setRoleChangePlayerHandler__(role, this.__arContainer__.__frames__, rolePlayerConstraints, null); + this.__setARCAddHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); + this.__setARCRemoveHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); this.__error__.insert({"before" : role.getFrame()}); ++rolesCreated; ++currentlyCreated; @@ -1544,14 +1543,12 @@ }, "__makeRolesFromORC__" : function(roleType, player){ var orpcs = getOtherRoleConstraintsForRole(new Array(roleType), new Array(player), this.__otherRoleConstraints__); - var removeFunction = function(event){ alert("removeFunction"); }; - var addFunction = function(event){ alert("addFunction"); }; for(var i = 0; i !== orpcs.length; ++i){ var cPlayers = orpcs[i].players; var cRoleType = orpcs[i].roleType; var cOtherPlayers = orpcs[i].otherPlayers; var cOtherRoleType = orpcs[i].otherRoleType; - var cMin = parseInt(orpcs[i].cardMin); + var cMin = orpcs[i].cardMin === 0 ? 1 : parseInt(orpcs[i].cardMin); if(!cOtherPlayers || cOtherPlayers.length < cMin) throw "from __makeRolesFromORC__(): not enough players(=" + cOtherPlayers.length + ") for roletype + \"" + cOtherRoleType.flatten()[0] + "\"!"; var existingRoles = this.getExistingRoles(cOtherRoleType, cOtherPlayers, this.__orContainer__.__frames__); for(var j = 0; j < cMin - existingRoles.length; ++j){ @@ -1570,12 +1567,198 @@ this.__orContainer__.__frames__[j].removePlayer(cleanedPlayers[0]); } - var role = new RoleC(null, cOtherRoleType, cleanedPlayers, this.__orContainer__, removeFunction, addFunction); + var role = new RoleC(null, cOtherRoleType, cleanedPlayers, this.__orContainer__); + this.__checkORCButtons__(role, orpcs[i]); this.__setRoleChangePlayerHandler__(role, this.__orContainer__.__frames__, null, orpcs); + this.__setORCAddHandler__(role, orpcs[i], orpcs); + this.__setORCRemoveHandler__(role, orpcs[i], orpcs); this.__error__.insert({"before" : role.getFrame()}); } } }, + "__checkORCButtons__" : function(role, constraint){ + if(!role || !constraint) return; + var cOtherPlayers = constraint.otherPlayers; + var cOtherRoleType = constraint.otherRoleType; + var cardMax = constraint.cardMax === "MAX_INT" ? "*" : parseInt(constraint.cardMax); + var cardMin = parseInt(constraint.cardMin); + var existingRoles = this.getExistingRoles(cOtherRoleType, cOtherPlayers, this.__orContainer__.__frames__); + var cleanedPlayers = new Array(); + for(var i = 0; i !== cOtherPlayers.length; ++i){ + if(this.getExistingRoles(cOtherRoleType, cOtherPlayers[i], this.__orContainer__.__frames__).length === 0){ + cleanedPlayers.push(cOtherPlayers[i]); + } + } + + // --- add button + if(cardMax > existingRoles.length && cleanedPlayers.length !== 0){ + for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].showAddButton(); + } + else { + for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].hideAddButton(); + } + + // --- remove button + if(cardMin > existingRoles.length){ + for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].showRemoveButton(); + } + else { + for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].hideRemoveButton(); + } + }, + "__checkARCButtons__" : function(role, arConstraint, rpConstraint){ + if(!role || !arConstraint || !rpConstraint) return; + + var roleMax = arConstraint.cardMax === "MAX_INT" ? "*" : parseInt(arConstraint.cardMax); + var playerMax = rpConstraint.cardMax === "MAX_INT" ? "*" : parseInt(rpConstraint.cardMax); + var playerMin = rpConstraint.cardMin === 0 ? 1 : parseInt(rpConstraint.cardMin); + var players = rpConstraint.players; + var existingRoles = this.getExistingRoles(arConstraint.roleType, rpConstraint.players, this.__arContainer__.__frames__); + var allExistingRoles = new Array(); + var tPsis = arConstraint.roleType.flatten(); + for(var i = 0; i !== this.__arContainer__.__frames__.length; ++i){ + if(tPsis.indexOf(this.__arContainer__.__frames__[i].getType()) !== -1) + allExistingRoles.push(this.__arContainer__.__frames__[i]); + } + var cleanedPlayers = new Array(); + for(var i = 0; i !== players.length; ++i){ + if(this.getExistingRoles(arConstraint.roleType, players[i], this.__arContainer__.__frames__).length === 0){ + cleanedPlayers.push(players[i]); + } + } + + // --- add button + if(cleanedPlayers.length !== 0 && playerMax > existingRoles.length && roleMax > allExistingRoles.length){ + for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].showAddButton(); + } + else { + for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].hideAddButton(); + } + + // --- remove button + // --- If there is just one roleplayer-constraint to the passed roletype, there will be + // --- checked this card-min otherwise the minimum cardinality of this roletype and the + // --- players depending on the found roleplayer-constraints hast to exist only once. + // --- The defined cardinality will be cheched before committing, so the user will + // --- be warned before committing a bad fragment. + var foundRpcs = getRolePlayerConstraintsForRole(arConstraint.roleType, this.__rolePlayerConstraints__); + if(foundRpcs.length === 1 && playerMin < existingRoles.length){ + for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].showRemoveButton(); + } + else if(foundRpcs.length > 1 && existingRoles.length > 1){ + for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].showRemoveButton(); + } + else { + for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].hideRemoveButton(); + } + }, + "__setORCAddHandler__" : function(role, currentConstraint, constraints){ + if(!role || !currentConstraint || !constraints || constraints.length === 0) return; + + var roleContainer = this; + function addHandler(myself){ + var cOtherPlayers = currentConstraint.otherPlayers; + var cOtherRoleType = currentConstraint.otherRoleType; + var cardMax = currentConstraint.cardMax === "MAX_INT" ? "*" : parseInt(currentConstraint.cardMax); + var cardMin = currentConstraint.cardMin === 0 ? 1 : parseInt(currentConstraint.cardMin); + var existingRoles = roleContainer.getExistingRoles(cOtherRoleType, cOtherPlayers, roleContainer.__orContainer__.__frames__); + var cleanedPlayers = new Array(); + for(var i = 0; i !== cOtherPlayers.length; ++i){ + if(roleContainer.getExistingRoles(cOtherRoleType, cOtherPlayers[i], roleContainer.__orContainer__.__frames__).length === 0){ + cleanedPlayers.push(cOtherPlayers[i]); + } + } + + // --- creates new role + if(cleanedPlayers.length !== 0){ + var role = new RoleC(null, cOtherRoleType, cleanedPlayers, roleContainer.__orContainer__); + roleContainer.__checkORCButtons__(role, currentConstraint); + roleContainer.__setRoleChangePlayerHandler__(role, roleContainer.__orContainer__.__frames__, null, constraints); + roleContainer.__setORCAddHandler__(role, currentConstraint, constraints); + roleContainer.__setORCRemoveHandler__(role, currentConstraint, constraints); + roleContainer.__error__.insert({"before" : role.getFrame()}); + // --- removes the selected player from all other roles + for(var i = 0; i !== existingRoles.length; ++i){ + existingRoles[i].removePlayer(new Array(role.getPlayer())); + } + var allRoles = existingRoles; + allRoles.push(role); + roleContainer.__innerCheckORCButtons__(allRoles, cardMin, cardMax); + } + } + + role.setAddHandler(addHandler); + }, + "__setORCRemoveHandler__" : function(role, currentConstraint, constraints){ + if(!role || !currentConstraint || !constraints) return; + + var roleContainer = this; + function removeHandler(myself){ + var cOtherPlayers = currentConstraint.otherPlayers; + var cOtherRoleType = currentConstraint.otherRoleType; + var cardMax = currentConstraint.cardMax === "MAX_INT" ? "*" : parseInt(currentConstraint.cardMax); + var cardMin = currentConstraint.cardMin === 0 ? 1 : parseInt(currentConstraint.cardMin); + var playerToAdd = null; + for(var i = 0; i !== cOtherPlayers.length; ++i){ + if(cOtherPlayers[i].indexOf(role.getPlayer()) !== -1){ + playerToAdd = cOtherPlayers[i]; + } + } + roleContainer.__orContainer__.__frames__ = roleContainer.__orContainer__.__frames__.without(role); + role.remove(); + var existingRoles = roleContainer.getExistingRoles(cOtherRoleType, cOtherPlayers, roleContainer.__orContainer__.__frames__); + for(var i = 0; i !== existingRoles.length; ++i){ + existingRoles[i].addPlayer(playerToAdd); + } + roleContainer.__innerCheckORCButtons__(existingRoles, cardMin, cardMax); + } + + role.setRemoveHandler(removeHandler); + }, + "__innerCheckORCButtons__" : function(existingRoles, cardMin, cardMax){ + if(!existingRoles) return; + + // --- checks all control buttons after an add or remove operation + if(cardMax !== "*" && existingRoles.length >= cardMax){ + for(var i = 0; i !== existingRoles.length; ++i){ + existingRoles[i].hideAddButton(); + } + } + else { + for(var i = 0; i !== existingRoles.length; ++i){ + existingRoles[i].showAddButton(); + } + } + + if(cardMin < existingRoles.length){ + for(var i = 0; i !== existingRoles.length; ++i){ + existingRoles[i].showRemoveButton(); + } + } + else { + for(var i = 0; i !== existingRoles.length; ++i){ + existingRoles[i].hideRemoveButton(); + } + } + }, + "__setARCAddHandler__" : function(role, arConstraint, rpConstraint){ + if(!role || !arConstraint || !rpConstraint) return; + + function addHandler(myself){ + //alert("myself: " + myself + "!!!"); + } + + role.setAddHandler(addHandler); + }, + "__setARCRemoveHandler__" : function(role, arConstraint, rpConstraint){ + if(!role || !arConstraint || !rpConstraint) return; + + function removeHandler(myself){ + //alert("myself: " + myself + "!!!"); + } + + role.setRemoveHandler(removeHandler); + }, "getExistingRoles" : function(roleType, players, roles){ var rolesFound = new Array(); if(!roles || roles.length === 0) return rolesFound; @@ -1782,6 +1965,7 @@ }}); +// --- contains all fragment's associations depending on the main topic var AssociationContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints, mainTopic){ $super(); this.__minimized__ = false; From lgiessmann at common-lisp.net Thu Jun 11 12:40:45 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Thu, 11 Jun 2009 08:40:45 -0400 Subject: [isidorus-cvs] r37 - trunk/src/ajax/javascripts Message-ID: Author: lgiessmann Date: Thu Jun 11 08:40:44 2009 New Revision: 37 Log: fixed some problems by creating associationroles from associationrole-constraints Modified: trunk/src/ajax/javascripts/datamodel.js Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Thu Jun 11 08:40:44 2009 @@ -1479,29 +1479,33 @@ checkCardinalitiesARC_RPC(associationRoleConstraint, rolePlayerConstraints); // --- creates all roles with all needed players + var currentRoles = new Array(); var rolesCreated = 0; var allAvailablePlayers = extractPlayersOfConstraints(rolePlayerConstraints); var roleType = associationRoleConstraint.roleType; var roleMin = associationRoleConstraint.cardMin === 0 ? 1 : parseInt(associationRoleConstraint.cardMin); for(var i = 0; i !== rolePlayerConstraints.length; ++i){ var playerMin = rolePlayerConstraints[i].cardMin === 0 ? 1 : parseInt(rolePlayerConstraints[i].cardMin); - var currentAvailablePlayers = rolePlayerConstraints[i].players; - var cleanedPlayers = cleanPlayers(allAvailablePlayers, currentAvailablePlayers); - for(var j = playerMin; j < currentAvailablePlayers.length; ++j){ - cleanedPlayers.push(currentAvailablePlayers[j]); - } - if(currentAvailablePlayers.length < playerMin) throw "From __makeRolesFromARC__(): not enough players(=" + currentAvailablePlayers.length + ") to reach card-min(=" + playerMin + ") of roletype\"" + roleType.flatten()[0] + "\"!"; - for(var j = 0; j !== playerMin; ++j){ - var selectedPlayer = currentAvailablePlayers[j]; - var _players = cleanedPlayers; - _players.unshift(selectedPlayer); - var role = new RoleC(null, roleType, _players, this.__arContainer__); - this.__checkARCButtons__(role, associationRoleConstraint, rolePlayerConstraints[i]); + 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(); + for(var j = 0; j !== currentRoles.length; ++j) selectedPlayers.push(currentRoles[j].getPlayer()); + var currentPlayers = cleanPlayers(rolePlayerConstraints[i].players, selectedPlayers) + var cleanedPlayers = cleanPlayers(allAvailablePlayers, selectedPlayers); + cleanedPlayers = cleanPlayers(cleanedPlayers, currentPlayers); + cleanedPlayers = currentPlayers.concat(cleanedPlayers); + var role = new RoleC(null, roleType, cleanedPlayers, this.__arContainer__); this.__setRoleChangePlayerHandler__(role, this.__arContainer__.__frames__, rolePlayerConstraints, null); this.__setARCAddHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); this.__setARCRemoveHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); this.__error__.insert({"before" : role.getFrame()}); + // --- removes the new role's selected item from all other existing roles + for(var j = 0; j !== currentRoles.length; ++j){ + currentRoles[j].removePlayer(new Array(role.getPlayer())); + } ++rolesCreated; + currentRoles.push(role); } } @@ -1529,7 +1533,7 @@ } var role = new RoleC(null, roleType, cleanedPlayers, this.__arContainer__); - this.__checkARCButtons__(role, associationRoleConstraint, rolePlayerConstraints[i]); + currentRoles.push(role); this.__setRoleChangePlayerHandler__(role, this.__arContainer__.__frames__, rolePlayerConstraints, null); this.__setARCAddHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); this.__setARCRemoveHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); @@ -1539,7 +1543,10 @@ } } if(currentlyCreated === 0) throw "Not enough players to create all needed roles of the type \"" + roleType.flatten()[0] + "\"!"; - } + }; + this.__checkARCButtons__(currentRoles, allAvailablePlayers, associationRoleConstraint); + for(var i = 0; i !== currentRoles.length; ++i) + this.__setARCAddHandler__(currentRoles[i], allAvailablePlayers, associationRoleConstraint); }, "__makeRolesFromORC__" : function(roleType, player){ var orpcs = getOtherRoleConstraintsForRole(new Array(roleType), new Array(player), this.__otherRoleConstraints__); @@ -1606,50 +1613,23 @@ for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].hideRemoveButton(); } }, - "__checkARCButtons__" : function(role, arConstraint, rpConstraint){ - if(!role || !arConstraint || !rpConstraint) return; - - var roleMax = arConstraint.cardMax === "MAX_INT" ? "*" : parseInt(arConstraint.cardMax); - var playerMax = rpConstraint.cardMax === "MAX_INT" ? "*" : parseInt(rpConstraint.cardMax); - var playerMin = rpConstraint.cardMin === 0 ? 1 : parseInt(rpConstraint.cardMin); - var players = rpConstraint.players; - var existingRoles = this.getExistingRoles(arConstraint.roleType, rpConstraint.players, this.__arContainer__.__frames__); - var allExistingRoles = new Array(); - var tPsis = arConstraint.roleType.flatten(); - for(var i = 0; i !== this.__arContainer__.__frames__.length; ++i){ - if(tPsis.indexOf(this.__arContainer__.__frames__[i].getType()) !== -1) - allExistingRoles.push(this.__arContainer__.__frames__[i]); - } - var cleanedPlayers = new Array(); - for(var i = 0; i !== players.length; ++i){ - if(this.getExistingRoles(arConstraint.roleType, players[i], this.__arContainer__.__frames__).length === 0){ - cleanedPlayers.push(players[i]); - } - } - - // --- add button - if(cleanedPlayers.length !== 0 && playerMax > existingRoles.length && roleMax > allExistingRoles.length){ - for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].showAddButton(); + "__checkARCButtons__" : function(rolesToCheck, players, associationRoleConstraint){ + if(!rolesToCheck || !associationRoleConstraint) return; + var cardMin = associationRoleConstraint.cardMin === 0 ? 1 : parseInt(associationRoleConstraint.cardMin); + var cardMax = associationRoleConstraint.cardMax === "MAX_INT" ? "*" : parseInt(associationRoleConstraint.cardMax); + var lenPlayers = players ? players.length : 0; + if(cardMin < rolesToCheck.length) { + for(var i = 0; i !== rolesToCheck.length; ++i) rolesToCheck[i].showRemoveButton(); } else { - for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].hideAddButton(); + for(var i = 0; i !== rolesToCheck.length; ++i) rolesToCheck[i].hideRemoveButton(); } - // --- remove button - // --- If there is just one roleplayer-constraint to the passed roletype, there will be - // --- checked this card-min otherwise the minimum cardinality of this roletype and the - // --- players depending on the found roleplayer-constraints hast to exist only once. - // --- The defined cardinality will be cheched before committing, so the user will - // --- be warned before committing a bad fragment. - var foundRpcs = getRolePlayerConstraintsForRole(arConstraint.roleType, this.__rolePlayerConstraints__); - if(foundRpcs.length === 1 && playerMin < existingRoles.length){ - for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].showRemoveButton(); - } - else if(foundRpcs.length > 1 && existingRoles.length > 1){ - for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].showRemoveButton(); + if(cardMax > rolesToCheck.length && rolesToCheck.length < lenPlayers){ + for(var i = 0; i !== rolesToCheck.length; ++i) rolesToCheck[i].showAddButton(); } else { - for(var i = 0; i !== existingRoles.length; ++i) existingRoles[i].hideRemoveButton(); + for(var i = 0; i !== rolesToCheck.length; ++i) rolesToCheck[i].hideAddButton(); } }, "__setORCAddHandler__" : function(role, currentConstraint, constraints){ @@ -1741,11 +1721,39 @@ } } }, - "__setARCAddHandler__" : function(role, arConstraint, rpConstraint){ - if(!role || !arConstraint || !rpConstraint) return; + "__setARCAddHandler__" : function(role, players, associationRoleConstraint){ + if(!role || !associationRoleConstraint) return; + var lenPlayers = players ? players.length : 0; + var roleContainer = this; function addHandler(myself){ - //alert("myself: " + myself + "!!!"); + try{ + var roleType = associationRoleConstraint.roleType.flatten(); + var rolesToCheck = new Array(); + for(var i = 0; i !== roleContainer.__arContainer__.__frames__.length; ++i){ + if(roleType.indexOf(roleContainer.__arContainer__.__frames__[i].getType()) !== -1) + rolesToCheck.push(roleContainer.__arContainer__.__frames__[i]); + } + + // --- creates a new role + var cardMax = associationRoleConstraint.cardMax === "MAX_INT" ? "*" : parseInt(associationRoleConstraint.cardMax); + if(cardMax === "*" || cardMax > rolesToCheck.length){ + var usedPlayers = new Array(); + for(var i = 0; i !== rolesToCheck.length; ++i) usedPlayers.push(rolesToCheck[i].getPlayer()); + var cleanedPlayers = cleanPlayers(players ? players : new Array(), usedPlayers); + var role = new RoleC(null, roleType, cleanedPlayers, roleContainer.__arContainer__); + +//-----------------> + /*this.__setRoleChangePlayerHandler__(role, roleContainer.__arContainer__.__frames__, rolePlayerConstraints, null); + this.__setARCAddHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); + this.__setARCRemoveHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]);*/ + roleContainer.__arContainer__.__frames__[roleContainer.__arContainer__.__frames__.length - 2].getFrame().insert({"after" : role.getFrame()}); + rolesToCheck.push(role); +// TODO: otherrole-constraints 1/3 + } + + roleContainer.__checkARCButtons__(rolesToCheck, players, associationRoleConstraint); + }catch(err){ alert("err: " + err); } } role.setAddHandler(addHandler); @@ -1754,7 +1762,8 @@ if(!role || !arConstraint || !rpConstraint) return; function removeHandler(myself){ - //alert("myself: " + myself + "!!!"); + alert("myself: " + myself + "!!!"); +// TODO: otherrole-constraints 2/3 } role.setRemoveHandler(removeHandler); @@ -1826,6 +1835,7 @@ existingRoles[i].removePlayer(playerToRemove); } } +// TODO: otherrole-constraints 3/3 }); } setEvent(this); From lgiessmann at common-lisp.net Thu Jun 11 13:40:45 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Thu, 11 Jun 2009 09:40:45 -0400 Subject: [isidorus-cvs] r38 - trunk/src/ajax/javascripts Message-ID: Author: lgiessmann Date: Thu Jun 11 09:40:44 2009 New Revision: 38 Log: fixsed some problems with roles created from otherrole-constraints by using the "onPlayerChange" handler; so by changing players of roles created from roleplayer-constraints there will be checked and corrected all otherroles Modified: trunk/src/ajax/javascripts/datamodel.js Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Thu Jun 11 09:40:44 2009 @@ -1426,6 +1426,7 @@ this.__frame__.writeAttribute({"class" : CLASSES.roleContainer()}); this.__arContainer__ = new Object(); this.__orContainer__ = new Object(); + this.__otherRoleConstraints__ = otherRoleConstraints; try{ if((!contents || contents.length === 0) && associationRoleConstraints){ this.resetValues(associationRoleConstraints, rolePlayerConstraints, otherRoleConstraints); @@ -1826,7 +1827,7 @@ } } existingRoles = existingRoles.without(role); - + // --- removes and adds the new selected psi-value // --- and the old deselected psi if the player is another one if(playerToRemove.indexOf(role.getLastPlayer()) === -1){ @@ -1835,11 +1836,47 @@ existingRoles[i].removePlayer(playerToRemove); } } -// TODO: otherrole-constraints 3/3 + + // --- chekcs roles created from otherrole-contraints + myself.__checkORCRoles__(role); }); } setEvent(this); }, + "__checkORCRoles__" : function(changedRole){ + // --- removes all roles created from otherrole-constraints, which + // --- currently must not exist + var toRemove = new Array(); + for(var i = 0; i !== this.__orContainer__.__frames__.length; ++i){ + var oRole = this.__orContainer__.__frames__[i]; + var orcs = new Array(); // found orcs for the existing orc-roles + var checkedOrcs = new Array(); + for(var j = 0; this.__otherRoleConstraints__ && j !== this.__otherRoleConstraints__.length; ++j){ + var orc = this.__otherRoleConstraints__[j]; + if(orc.otherRoleType.flatten().indexOf(oRole.getType()) !== -1 && orc.otherPlayers.flatten().indexOf(oRole.getPlayer()) !== -1) orcs.push(orc); + } + + for(var j = 0; j !== orcs.length; ++j){ + for(var k = 0; this.__arContainer__.__frames__ && k !== this.__arContainer__.__frames__.length; ++k){ + var aRole = this.__arContainer__.__frames__[k]; + if(orcs[j].roleType.flatten().indexOf(aRole.getType()) !== -1 && orcs[j].players.flatten().indexOf(aRole.getPlayer()) !== -1){ + checkedOrcs.push(orcs[j]); + break; + } + } + } + + // --- no otherrole-constraints exist for this roles, so they have to be removed + if(checkedOrcs.length === 0) toRemove.push(oRole); + } + for(var i = 0; i !== toRemove.length; ++i){ + this.__orContainer__.__frames__ = this.__orContainer__.__frames__.without(toRemove[i]); + toRemove[i].remove(); + } + + // --- creates new roles from other role-constraints, which has to exist or are optional + this.__makeRolesFromORC__(changedRole.getType(), changedRole.getPlayer()); + }, "getContent" : function(){ if((!this.__orContainer__.__frames__ && this.__orContainer__.frames__.length === 0) || (!this.__arContainer__.__frames__ && this.__arContainer__.__frames__.length === 0)) return null; var roles = new Array(); From lgiessmann at common-lisp.net Thu Jun 11 17:02:01 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Thu, 11 Jun 2009 13:02:01 -0400 Subject: [isidorus-cvs] r39 - trunk/src/ajax/javascripts Message-ID: Author: lgiessmann Date: Thu Jun 11 13:02:00 2009 New Revision: 39 Log: ajax-client: added an "add-player"-handler to the role container Modified: trunk/src/ajax/javascripts/datamodel.js Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Thu Jun 11 13:02:00 2009 @@ -1427,6 +1427,7 @@ this.__arContainer__ = new Object(); this.__orContainer__ = new Object(); this.__otherRoleConstraints__ = otherRoleConstraints; + this.__rolePlayerConstraints__ = rolePlayerConstraints; try{ if((!contents || contents.length === 0) && associationRoleConstraints){ this.resetValues(associationRoleConstraints, rolePlayerConstraints, otherRoleConstraints); @@ -1498,8 +1499,6 @@ cleanedPlayers = currentPlayers.concat(cleanedPlayers); var role = new RoleC(null, roleType, cleanedPlayers, this.__arContainer__); this.__setRoleChangePlayerHandler__(role, this.__arContainer__.__frames__, rolePlayerConstraints, null); - this.__setARCAddHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); - this.__setARCRemoveHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); this.__error__.insert({"before" : role.getFrame()}); // --- removes the new role's selected item from all other existing roles for(var j = 0; j !== currentRoles.length; ++j){ @@ -1536,8 +1535,6 @@ var role = new RoleC(null, roleType, cleanedPlayers, this.__arContainer__); currentRoles.push(role); this.__setRoleChangePlayerHandler__(role, this.__arContainer__.__frames__, rolePlayerConstraints, null); - this.__setARCAddHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); - this.__setARCRemoveHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); this.__error__.insert({"before" : role.getFrame()}); ++rolesCreated; ++currentlyCreated; @@ -1546,8 +1543,10 @@ if(currentlyCreated === 0) throw "Not enough players to create all needed roles of the type \"" + roleType.flatten()[0] + "\"!"; }; this.__checkARCButtons__(currentRoles, allAvailablePlayers, associationRoleConstraint); - for(var i = 0; i !== currentRoles.length; ++i) + for(var i = 0; i !== currentRoles.length; ++i){ this.__setARCAddHandler__(currentRoles[i], allAvailablePlayers, associationRoleConstraint); + this.__setARCRemoveHandler__(currentRoles[i], associationRoleConstraint); + } }, "__makeRolesFromORC__" : function(roleType, player){ var orpcs = getOtherRoleConstraintsForRole(new Array(roleType), new Array(player), this.__otherRoleConstraints__); @@ -1728,7 +1727,6 @@ var roleContainer = this; function addHandler(myself){ - try{ var roleType = associationRoleConstraint.roleType.flatten(); var rolesToCheck = new Array(); for(var i = 0; i !== roleContainer.__arContainer__.__frames__.length; ++i){ @@ -1743,28 +1741,32 @@ for(var i = 0; i !== rolesToCheck.length; ++i) usedPlayers.push(rolesToCheck[i].getPlayer()); var cleanedPlayers = cleanPlayers(players ? players : new Array(), usedPlayers); var role = new RoleC(null, roleType, cleanedPlayers, roleContainer.__arContainer__); + var foundRpcs = getRolePlayerConstraintsForRole(roleType, roleContainer.__rolePlayerConstraints__); + alert("frpcs: " + foundRpcs.length); + roleContainer.__setRoleChangePlayerHandler__(role, roleContainer.__arContainer__.__frames__, foundRpcs, null); + roleContainer.__setARCAddHandler__(role, players, associationRoleConstraint); + roleContainer.__setARCRemoveHandler__(role, associationRoleConstraint); + roleContainer.__error__.insert({"before" : role.getFrame()}); -//-----------------> - /*this.__setRoleChangePlayerHandler__(role, roleContainer.__arContainer__.__frames__, rolePlayerConstraints, null); - this.__setARCAddHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]); - this.__setARCRemoveHandler__(role, associationRoleConstraint, rolePlayerConstraints[i]);*/ + // --- removes the new role's selected item from all other existing roles + for(var j = 0; j !== rolesToCheck.length; ++j){ + rolesToCheck[j].removePlayer(new Array(role.getPlayer())); + } roleContainer.__arContainer__.__frames__[roleContainer.__arContainer__.__frames__.length - 2].getFrame().insert({"after" : role.getFrame()}); rolesToCheck.push(role); -// TODO: otherrole-constraints 1/3 } roleContainer.__checkARCButtons__(rolesToCheck, players, associationRoleConstraint); - }catch(err){ alert("err: " + err); } } role.setAddHandler(addHandler); }, - "__setARCRemoveHandler__" : function(role, arConstraint, rpConstraint){ - if(!role || !arConstraint || !rpConstraint) return; + "__setARCRemoveHandler__" : function(role, associationRoleConstraint){ + if(!role || !associationRoleConstraint) return; function removeHandler(myself){ alert("myself: " + myself + "!!!"); -// TODO: otherrole-constraints 2/3 + } role.setRemoveHandler(removeHandler); From lgiessmann at common-lisp.net Thu Jun 11 18:10:31 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Thu, 11 Jun 2009 14:10:31 -0400 Subject: [isidorus-cvs] r40 - trunk/src/ajax/javascripts Message-ID: Author: lgiessmann Date: Thu Jun 11 14:10:31 2009 New Revision: 40 Log: ajax-client: added a "player-remove"-handler for roles; fixed a problem with roles depending on otherrole-constraints by adding new roles depending on associationrole-constraints Modified: trunk/src/ajax/javascripts/datamodel.js Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Thu Jun 11 14:10:31 2009 @@ -1625,7 +1625,7 @@ for(var i = 0; i !== rolesToCheck.length; ++i) rolesToCheck[i].hideRemoveButton(); } - if(cardMax > rolesToCheck.length && rolesToCheck.length < lenPlayers){ + if(cardMax === "*" || cardMax > rolesToCheck.length && rolesToCheck.length < lenPlayers){ for(var i = 0; i !== rolesToCheck.length; ++i) rolesToCheck[i].showAddButton(); } else { @@ -1742,11 +1742,9 @@ var cleanedPlayers = cleanPlayers(players ? players : new Array(), usedPlayers); var role = new RoleC(null, roleType, cleanedPlayers, roleContainer.__arContainer__); var foundRpcs = getRolePlayerConstraintsForRole(roleType, roleContainer.__rolePlayerConstraints__); - alert("frpcs: " + foundRpcs.length); roleContainer.__setRoleChangePlayerHandler__(role, roleContainer.__arContainer__.__frames__, foundRpcs, null); roleContainer.__setARCAddHandler__(role, players, associationRoleConstraint); roleContainer.__setARCRemoveHandler__(role, associationRoleConstraint); - roleContainer.__error__.insert({"before" : role.getFrame()}); // --- removes the new role's selected item from all other existing roles for(var j = 0; j !== rolesToCheck.length; ++j){ @@ -1754,6 +1752,7 @@ } roleContainer.__arContainer__.__frames__[roleContainer.__arContainer__.__frames__.length - 2].getFrame().insert({"after" : role.getFrame()}); rolesToCheck.push(role); + roleContainer.__checkORCRoles__(role); } roleContainer.__checkARCButtons__(rolesToCheck, players, associationRoleConstraint); @@ -1764,9 +1763,43 @@ "__setARCRemoveHandler__" : function(role, associationRoleConstraint){ if(!role || !associationRoleConstraint) return; + var roleContainer = this; function removeHandler(myself){ - alert("myself: " + myself + "!!!"); + var cardMin = associationRoleConstraint.cardMin === 0 ? 1 : parseInt(associationRoleConstraint.cardMin); + var roleType = associationRoleConstraint.roleType.flatten(); + var rolesToCheck = new Array(); + for(var i = 0; i !== roleContainer.__arContainer__.__frames__.length; ++i){ + if(roleType.indexOf(roleContainer.__arContainer__.__frames__[i].getType()) !== -1) + rolesToCheck.push(roleContainer.__arContainer__.__frames__[i]); + } + // --- removes the role + if(cardMin < rolesToCheck.length){ + // --- gets the player which is selected by the role has to be removed + var player = null; + for(var i = 0; roleContainer.__rolePlayerConstraints__ && i !== roleContainer.__rolePlayerConstraints__.length; ++i){ + if(player !== null) break; + for(var j = 0; roleContainer.__rolePlayerConstraints__[i].players && j !== roleContainer.__rolePlayerConstraints__[i].players.length; ++j){ + if(roleContainer.__rolePlayerConstraints__[i].players[j].indexOf(role.getPlayer()) !== -1){ + player = roleContainer.__rolePlayerConstraints__[i].players[j]; + break; + } + } + } + rolesToCheck = rolesToCheck.without(role); + role.remove(); + roleContainer.__arContainer__.__frames__ = roleContainer.__arContainer__.__frames__.without(role); + + // --- adds the player which was selected by the removed role to all other + // --- existing roles of the same type + for(var i = 0; i !== rolesToCheck.length; ++i){ + rolesToCheck[i].addPlayer(player); + } + } + var foundRpcs = getRolePlayerConstraintsForRole(associationRoleConstraint.roleType, roleContainer.__rolePlayerConstraints__); + var players = extractPlayersOfConstraints(foundRpcs); + roleContainer.__checkARCButtons__(rolesToCheck, players, associationRoleConstraint); + roleContainer.__checkORCRoles__(null); } role.setRemoveHandler(removeHandler); @@ -1877,7 +1910,7 @@ } // --- creates new roles from other role-constraints, which has to exist or are optional - this.__makeRolesFromORC__(changedRole.getType(), changedRole.getPlayer()); + if(changedRole) this.__makeRolesFromORC__(changedRole.getType(), changedRole.getPlayer()); }, "getContent" : function(){ if((!this.__orContainer__.__frames__ && this.__orContainer__.frames__.length === 0) || (!this.__arContainer__.__frames__ && this.__arContainer__.__frames__.length === 0)) return null; From lgiessmann at common-lisp.net Tue Jun 16 07:27:03 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Tue, 16 Jun 2009 03:27:03 -0400 Subject: [isidorus-cvs] r41 - in trunk/src: ajax/css ajax/javascripts rest_interface unit_tests Message-ID: Author: lgiessmann Date: Tue Jun 16 03:27:00 2009 New Revision: 41 Log: ajax-client: added the functionality to disable optional elements, like optional itmeIdentity, subjectLocator, subjectIdentifier, names, occurrences, associations and roles. Modified: trunk/src/ajax/css/main.css trunk/src/ajax/javascripts/constants.js trunk/src/ajax/javascripts/create.js trunk/src/ajax/javascripts/datamodel.js trunk/src/rest_interface/set-up-json-interface.lisp trunk/src/unit_tests/poems.xtm Modified: trunk/src/ajax/css/main.css ============================================================================== --- trunk/src/ajax/css/main.css (original) +++ trunk/src/ajax/css/main.css Tue Jun 16 03:27:00 2009 @@ -34,6 +34,18 @@ cursor: pointer; } +.clickable:hover{ + color: #ff7f00; +} + +.deselect { + cursor: pointer; +} + +.deselect:hover{ + color: #ff7f00; +} + .errorMessage { color: red; font-size: 0.85em; Modified: trunk/src/ajax/javascripts/constants.js ============================================================================== --- trunk/src/ajax/javascripts/constants.js (original) +++ trunk/src/ajax/javascripts/constants.js Tue Jun 16 03:27:00 2009 @@ -72,6 +72,9 @@ "__divRoleContainer__" : "roleContainer", "__divRoleFrame__" : "roleFrame", "__divPlayerFrame__" : "playerFrame", + "__spanDeselect__" : "deselect", + "__divFog__" : "fog", + "__inputCommitButton__" : "commitButton", "page" : function(){ return this.__divPage__; }, "subPage" : function(){ return this.__divSubPage__; }, @@ -108,5 +111,8 @@ "associationFrame" : function(){ return this.__divAssociationFrame__; }, "roleContainer" : function(){ return this.__divRoleContainer__; }, "roleFrame" : function(){ return this.__divRoleFrame__; }, - "playerFrame" : function(){ return this.__divPlayerFrame__; } + "playerFrame" : function(){ return this.__divPlayerFrame__; }, + "deselect" : function(){ return this.__spanDeselect__; }, + "fog" : function(){ return this.__divFog__; }, + "commitButton" : function(){ return this.__inputCommitButton__; } }; \ No newline at end of file Modified: trunk/src/ajax/javascripts/create.js ============================================================================== --- trunk/src/ajax/javascripts/create.js (original) +++ trunk/src/ajax/javascripts/create.js Tue Jun 16 03:27:00 2009 @@ -36,6 +36,11 @@ items[i].remove(); } + items = $$("li." + CLASSES.commitButton()); + for(var i = 0; i !== items.length; ++i){ + items[i].remove(); + } + var instanceOfs = new Array(); for(var i = 0; psis && i !== psis.length; ++i){ instanceOfs.push(new Array(psis[i])); @@ -48,6 +53,15 @@ var associations = new AssociationContainerC(null, (constraints ? constraints.associationsConstraints : null), topic); var liA = new Element("li", {"class" : CLASSES.associationContainer()}).update(associations.getFrame()); liT.insert({"after" : liA}); + + var commitButton = new Element("input", {"type" : "button", "value" : "commit fragment", "style" : "float: right; margin-top: -10px;"}) + commitButton.observe("click", function(event){ + alert("commit fragment"); + }); + var liCB = new Element("li", {"class" : CLASSES.commitButton()}); + liCB.update(commitButton); + liA.insert({"after" : liCB}); + } function onSuccessHandler(xhr){ Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Tue Jun 16 03:27:00 2009 @@ -30,6 +30,7 @@ this.__frame__.insert({"bottom" : this.__content__}); this.__frame__.insert({"bottom" : this.__add__}); this.__frame__.insert({"bottom" : this.__error__}); + this.__disabled__ = false; setRemoveAddHandler(this, owner, min, max, function(){ return new FrameC("", owner, min, max); @@ -74,30 +75,45 @@ }, "append" : function(elem){ return this.getFrame().insert({"after" : elem}); + }, + "isUsed" : function(){ + return !this.__disabled__; }}); // --- This class represents a textrow with the functionality of FrameC plus the method isValid // --- which returns a boolean value depending on the instance's value and the given regular expression. -var TextrowC = Class.create(FrameC, {"initialize" : function($super, content, regexp, owner, min, max, cssTitle){ +var TextrowC = Class.create(FrameC, {"initialize" : function($super, content, regexp, owner, min, max, cssTitle, dblClickHandler){ $super(content, owner, min, max); owner.__frames__.pop(); owner.__frames__.push(this); + this.__owner__ = owner; + this.__min__ = min; + this.__max__ = max; this.__regexp__ = new RegExp(regexp); this.__frame__.writeAttribute({"class" : CLASSES.textrowWithRemoveButton()}); this.__content__.remove(); this.__content__ = new Element("input", {"type" : "text", "value" : content}); + this.__dblClickHandler__ = dblClickHandler; if(cssTitle && cssTitle.length){ this.__content__.writeAttribute({"title" : cssTitle}); } this.__remove__.insert({"after" : this.__content__}); checkRemoveAddButtons(owner, min, max); + var myself = this; setRemoveAddHandler(this, owner, min, max, function(){ - return new TextrowC("", regexp, owner, min, max, cssTitle); + return new TextrowC("", regexp, owner, min, max, cssTitle, dblClickHandler); + }); + + this.getFrame().observe("dblclick", function(event){ + dblClickHandler(owner, event); }); }, + "dblClick" : function(){ + if(this.__dblClickHandler__) this.__dblClickHandler__(this.__owner__); + }, "getContent" : function(){ return this.__content__.value; }, @@ -111,6 +127,17 @@ "hideRemoveButton" : function(){ this.__remove__.hide(); this.getFrame().writeAttribute({"class" : CLASSES.textrowWithoutRemoveButton()}); + }, + "disable" : function(){ + this.__content__.writeAttribute({"readonly" : "readonly"}); + this.hideRemoveButton(); + this.hideAddButton(); + this.__disabled__ = true; + }, + "enable" : function(){ + this.__content__.removeAttribute("readonly"); + checkRemoveAddButtons(this.__owner__, this.__min__, this.__max__); + this.__disabled__ = false; }}); @@ -145,8 +172,16 @@ "hideRemoveButton" : function(){ this.__remove__.hide(); this.getFrame().writeAttribute({"class" : CLASSES.selectrowWithoutRemoveButton()}); + }, + "disable" : function(){ + this.__content__.writeAttribute({"disabled" : "disables"}); + this.__disabled__ = true; + }, + "enable" : function(){ + this.__content__.removeAttribute("disabled"); + this.__disabled__ = false; }}); - + // --- The base Class for alomost all frames which contains other frames like names, occurrences, ... var ContainerC = Class.create({"initialize" : function(){ @@ -154,6 +189,7 @@ this.__error__ = new Element("div", {"class" : CLASSES.error()}); this.__error__.hide(); this.__frame__.insert({"bottom" : this.__error__}); + this.__disabled__ = false; }, "hide" : function(){ this.__frame__.hide(); @@ -194,6 +230,9 @@ }, "hideAddButton" : function(){ try{ this.__add__.hide(); } catch(err) {} + }, + "isUsed" : function(){ + return !this.__disabled__; }}); @@ -242,8 +281,7 @@ } myself.showError(str); } - else { - //successFun(contents, json); + else { successFun(myself.getContent(true, true), json); } } @@ -268,9 +306,8 @@ }}); - // --- Representation of a itemIdentity frame. -var ItemIdentityC = Class.create(ContainerC, {"initialize" : function($super, contents){ +var ItemIdentityC = Class.create(ContainerC, {"initialize" : function($super, contents, parent){ $super(); this.__frame__.writeAttribute({"class" : CLASSES.itemIdentityFrame()}); this.__container__ = new Object(); @@ -286,6 +323,25 @@ new TextrowC("", ".*", this.__container__, 1, -1, null); this.__error__.insert({"before" : this.__container__.__frames__[i].getFrame()}); } + finally { + function setDeactivateHandler(myself){ + myself.__frame__.observe("dblclick", function(event){ + if(myself.__container__.__frames__.length === 1){ + if(myself.isUsed() === true){ + myself.disable(); + Event.stop(event); + } + else { + myself.enable(); + if(parent.isUsed() === true) Event.stop(event); + } + } + }); + } + setDeactivateHandler(this); + + if(!contents || contents.length === 0) this.disable(); + } }, "getContent" : function(unique, removeNull){ var values = new Array(); @@ -299,9 +355,26 @@ "toJSON" : function(unique, removeNull){ var content = this.getContent(unique, removeNull); return content.length === 0 ? "null" : content.toJSON(); + }, + "disable" : function(){ + if(this.__container__.__frames__){ + for(var i = 0; i !== this.__container__.__frames__.length; ++i){ + this.__container__.__frames__[i].disable(); + } + } + this.__disabled__ = true; + }, + "enable" : function(){ + if(this.__container__.__frames__){ + for(var i = 0; i !== this.__container__.__frames__.length; ++i){ + this.__container__.__frames__[i].enable(); + } + } + this.__disabled__ = false; }}); + // --- Representation of a subjectLocator and subjectIdentifier frames. var IdentifierC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints, cssClass){ $super(); @@ -317,8 +390,12 @@ if(max !== 0){ var cssTitle = "min: " + min + " max: " + max + " regular expression: " + constraints[i].regexp; for(var j = 0; j != (min === 0 ? 1 : min); ++j){ + + var dblClickHandler = null; + if(min === 0) dblClickHandler = dblClickHandlerF; var row = new TextrowC("", constraints[i].regexp, this.__containers__[i], - min === 0 ? 1 : min, max === "*" ? -1 : max, cssTitle); + min === 0 ? 1 : min, max === "*" ? -1 : max, cssTitle, dblClickHandler); + row.dblClick(); this.__error__.insert({"before" : row.getFrame()}); } } @@ -384,6 +461,8 @@ if(!contents || contents.length < min) throw "From ScopeC.resetRows(): contents.length (" + (contents ? contents.length : "null") + ") must be > min (" + min + ")!"; if(max !== -1 && min > max)throw "From FrameC(): min must be > max(" + max + ") and > 0 but is " + min; + this.__min__ = min; + this.__max__ = max; // --- creates an empty div element if(max === 0){ @@ -555,7 +634,7 @@ } }, "isUsed" : function(){ - return this.getContent(true, true).length !== 0; + return this.getContent(true, true).length !== 0 && !this.__disabled__; }, "getContent" : function(unique, removeNull){ var values = new Array(); @@ -572,6 +651,26 @@ return new Array(); } return values; + }, + "disable" : function(){ + var rows = this.getFrame().select("div"); + for(var i = 0; i != rows.length; ++i){ + rows[i].select("select")[0].disable(); + var buttons = rows[i].select("span." + CLASSES.clickable()); + buttons[0].hide(); + buttons[1].hide(); + } + this.__disabled__ = true; + }, + "enable" : function(){ + var rows = this.getFrame().select("div"); + for(var i = 0; i != rows.length; ++i){ + rows[i].select("select")[0].enable(); + var buttons = rows[i].select("span." + CLASSES.clickable()); + if(this.__min__ < rows.length && rows.length !== 1) buttons[0].show(); + if(this.__max__ === -1 || this.__max__ > rows.length) buttons[1].show(); + } + this.__disabled__ = false; }}); @@ -616,6 +715,7 @@ } }, "isUsed" : function(){ + if(this.__disabled__ === true) return false; for(var i = 0; i != this.__container__.length; ++i){ if(this.__container__[i].isUsed() === true) return true; } @@ -645,26 +745,37 @@ "toJSON" : function(){ if(this.getContent().length === 0) return "null"; return this.getContent().toJSON(); + }, + "disable" : function(){ + for(var i = 0; i !== this.__container__.length; ++i) this.__container__[i].disable(); + this.__disabled__ = true; + }, + "enable" : function(){ + for(var i = 0; i !== this.__container__.length; ++i) this.__container__[i].enable(); + this.__disabled__ = false; }}); // --- Representation of a variant element -var VariantC = Class.create(ContainerC, {"initialize" : function($super, contents, owner){ +var VariantC = Class.create(ContainerC, {"initialize" : function($super, contents, owner, dblClickHandler, parent){ $super(); if(!owner.__frames__) owner.__frames__ = new Array(); owner.__frames__.push(this); this.__frame__.writeAttribute({"class" : CLASSES.variantFrame()}); this.__table__ = new Element("table", {"class" : CLASSES.variantFrame()}); this.__frame__.insert({"top" : this.__table__}); + this.__owner__ = owner; + this.__owner__ = owner; + this.__dblClickHandler__ = dblClickHandler; try{ // --- control row + itemIdentity makeControlRow(this, 4, contents ? contents.itemIdentities : null); checkRemoveAddButtons(owner, 1, -1); setRemoveAddHandler(this, owner, 1, -1, function(){ - return new VariantC(null, owner); + return new VariantC(null, owner, dblClickHandler, parent); }); - + // --- scopes this.__scopes__ = null; //TODO: implement -> also in the server @@ -673,8 +784,10 @@ // --- resource value and datatype makeResource(this, contents, null, null, null); - // --- minimize - this.minimize(); + this.getFrame().observe("dblclick", function(event){ + dblClickHandler(owner, event); + if(parent.isUsed() === true)Event.stop(event); + }); } catch(err){ alert("From VariantC(): " + err); @@ -724,20 +837,29 @@ return this.__value__.value.strip() !== ""; }, "isUsed" : function(){ - return (this.__itemIdentity__.getContent(true, true).length !== 0 || - this.__value__.value.strip() !== "" || this.__datatype__.__frames__[0].getContent().strip() !== ""); - }, - "showRemoveButton" : function(){ - this.__remove__.show(); - }, - "hideRemoveButton" : function(){ - this.__remove__.hide(); + return !this.__disabled__; }, - "showAddButton" : function(){ - this.__add__.show(); + "disable" : function(){ + this.__itemIdentity__.disable(); + // TODO: scope + this.__value__.writeAttribute({"readonly" : "readonly"}); + this.__datatype__.__frames__[0].disable(); + this.hideRemoveButton(); + this.hideAddButton(); + this.getFrame().setStyle({"backgroundColor" : "#edeceb"}); + this.getFrame().setStyle({"border" : "1px solid darkgrey"}); + this.__disabled__ = true; }, - "hideAddButton" : function(){ - this.__add__.hide(); + "enable" : function(){ + this.__itemIdentity__.enable(); + // TODO: scope + this.__value__.removeAttribute("readonly"); + this.__datatype__.__frames__[0].enable(); + if(this.__owner__.__frames__.length > 1) this.showRemoveButton(); + this.showAddButton(); + this.getFrame().setStyle({"backgroundColor" : "inherit"}); + this.getFrame().setStyle({"border" : "none"}); + this.__disabled__ = false; }, "minimize" : function(){ var trs = this.__table__.select("tr"); @@ -749,20 +871,22 @@ // --- contains all variants of a name element -var VariantContainerC = Class.create(ContainerC, {"initialize" : function($super, contents){ +var VariantContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, parent){ $super(); this.__frame__.writeAttribute({"class" : CLASSES.variantContainer()}); this.__container__ = new Object(); if(contents && contents.length != 0){ for(var i = 0; i != contents.length; ++i){ - var variant = new VariantC(contents[i], this.__container__); + var variant = new VariantC(contents[i], this.__container__, dblClickHandlerF, parent); this.__frame__.insert({"bottom" : variant.getFrame()}); + variant.minimize(); } } else { - var variant = new VariantC(null, this.__container__); + var variant = new VariantC(null, this.__container__, dblClickHandlerF, parent); this.__frame__.insert({"bottom" : variant.getFrame()}); + variant.minimize(); } }, "getContent" : function(){ @@ -793,11 +917,28 @@ } str += "]"; return str === "[]" ? null : str; + }, + "isUsed" : function(){ + return !this.__disabled__; + }, + "disable" : function(){ + if(this.__container__.__frames__){ + for(var i = 0; i !== this.__container__.__frames__.length; ++i) + this.__container__.__frames__[i].disable(); + } + this.__disabled__ = true; + }, + "enable" : function(){ + if(this.__container__.__frames__){ + for(var i = 0; i !== this.__container__.__frames__.length; ++i) + this.__container__.__frames__[i].enable(); + } + this.__disabled__ = false; }}); // --- representation of a name element -var NameC = Class.create(ContainerC, {"initialize" : function($super, contents, nametypescopes, simpleConstraint, owner, min, max, cssTitle){ +var NameC = Class.create(ContainerC, {"initialize" : function($super, contents, nametypescopes, simpleConstraint, owner, min, max, cssTitle, dblClickHandler){ $super(); if(!owner) throw "From NameC(): owner must be set but is null"; if(max !== -1 && (min > max || max === 0))throw "From FrameC(): min must be > max(" + max + ") and > 0 but is " + min; @@ -807,13 +948,16 @@ this.__frame__.writeAttribute({"class" : CLASSES.nameFrame()}); this.__table__ = new Element("table", {"class" : CLASSES.nameFrame()}); this.__frame__.insert({"top" : this.__table__}); + this.__max__ = max; + this.__owner__ = owner; + this.__dblClickHandler__ = dblClickHandler; try{ // --- control row + ItemIdentity makeControlRow(this, 5, contents ? contents.itemIdentities : null); checkRemoveAddButtons(owner, min, max); setRemoveAddHandler(this, owner, min, max, function(){ - return new NameC(null, nametypescopes, simpleConstraint, owner, min, max, cssTitle); + return new NameC(null, nametypescopes, simpleConstraint, owner, min, max, cssTitle, dblClickHandler); }); // --- type @@ -842,11 +986,12 @@ var _min = parseInt(simpleConstraint.cardMin); var _max = simpleConstraint.cardMax !== "MAX_INT" ? parseInt(simpleConstraint.cardMax) : "*"; var cssTitleV = "min: " + _min + " max: " + _max + " regular expression: " + (simpleConstraint ? simpleConstraint.regexp : ".*"); + this.__cssTitle__ = cssTitle; new TextrowC((contents ? contents.value : ""), (simpleConstraint ? simpleConstraint.regexp : ".*"), this.__value__, 1, 1, cssTitleV); this.__table__.insert({"bottom" : newRow(CLASSES.valueFrame(), "Value", this.__value__.__frames__[0].getFrame())}); // --- variants - this.__variants__ = new VariantContainerC(contents? contents.variants : null); + this.__variants__ = new VariantContainerC(contents? contents.variants : null, this); this.__table__.insert({"bottom" : newRow(CLASSES.variantContainer(), "Variants", this.__variants__.getFrame())}); // --- adds a second show handler, so the variants will be hidden, when the entire @@ -862,6 +1007,10 @@ } addSecondShowHandler(this); + + this.getFrame().observe("dblclick", function(event){ + dblClickHandler(owner, event); + }); } catch(err){ alert("From NameC(): " + err); @@ -882,11 +1031,6 @@ ",\"value\":" + this.__value__.__frames__[0].toJSON() + ",\"variants\":" + this.__variants__.toJSON() + "}"; }, - "isUsed" : function(){ - return this.__itemIdentity__.getContent(true, true).length !== 0 || - this.__value__.__frames__[0].getContent().strip().length !== 0 || - this.__variants__.getContent().length !== 0; - }, "isValid" : function(){ // TODO: check the content and the constraints + variants.isValid() return true; @@ -897,6 +1041,30 @@ if(i === 0) trs[i].show(); else trs[i].hide(); } + }, + "disable" : function(){ + this.__itemIdentity__.disable(); + this.__type__.__frames__[0].disable(); + this.__scope__.disable(); + this.__value__.__frames__[0].disable(); + this.__variants__.disable(); + this.getFrame().setStyle({"backgroundColor" : "#edeceb"}); + this.getFrame().setStyle({"border" : "1px solid darkgrey"}); + this.getFrame().writeAttribute({"title" : this.__cssTitle__}); + this.hideAddButton(); + this.__disabled__ = true; + }, + "enable" : function(){ + this.__itemIdentity__.enable(); + this.__type__.__frames__[0].enable(); + this.__scope__.enable(); + this.__value__.__frames__[0].enable(); + this.__variants__.enable(); + this.getFrame().setStyle({"backgroundColor" : "inherit"}); + this.getFrame().setStyle({"border" : "none"}); + this.getFrame().removeAttribute("title"); + checkRemoveAddButtons(this.__owner__, 1, this.__max__); + this.__disabled__ = false; }}); @@ -917,9 +1085,13 @@ var max = constraints[i].constraints[j].cardMax !== "MAX_INT" ? parseInt(constraints[i].constraints[j].cardMax) : "*"; var regexp = constraints[i].constraints[j].regexp; if(max !== 0){ + var dblClickHandler = null; + if(min === 0) dblClickHandler = dblClickHandlerF; + var title = "min: " + min + " max: " + max + " regular expression: " + regexp; var name = new NameC("", constraints[i].nametypescopes, constraints[i].constraints[j], - this.__containers__[i][j], min === 0 ? 1 : min, max === "*" ? -1 : max, title); + this.__containers__[i][j], min === 0 ? 1 : min, max === "*" ? -1 : max, title, dblClickHandler); + if(min === 0)name.disable(); this.__error__.insert({"before" : name.getFrame()}); if(min === 0)name.minimize(); } @@ -979,20 +1151,23 @@ // --- represenation of an occurrence element -var OccurrenceC = Class.create(ContainerC, {"initialize" : function($super, contents, occurrenceTypes, constraint, uniqueConstraints, owner, min, max, cssTitle){ +var OccurrenceC = Class.create(ContainerC, {"initialize" : function($super, contents, occurrenceTypes, constraint, uniqueConstraints, owner, min, max, cssTitle, dblClickHandler){ $super(); if(!owner.__frames__) owner.__frames__ = new Array(); owner.__frames__.push(this); this.__frame__.writeAttribute({"class" : CLASSES.occurrenceFrame()}); this.__table__ = new Element("table", {"class" : CLASSES.occurrenceFrame()}); this.__frame__.insert({"top" : this.__table__}); + this.__max__ = max; + this.__owner__ = owner; + this.__dblClickHandler__ = dblClickHandler; try{ // --- control row + itemIdentity makeControlRow(this, 5, contents ? contents.itemIdentities : null); checkRemoveAddButtons(owner, 1, max); setRemoveAddHandler(this, owner, 1, max, function(){ - return new OccurrenceC(null, occurrenceTypes, constraint, uniqueConstraints, owner, min, max, cssTitle); + return new OccurrenceC(null, occurrenceTypes, constraint, uniqueConstraints, owner, min, max, cssTitle, dblClickHandler); }); // --- type @@ -1014,13 +1189,18 @@ // --- scopes this.__scope__ = new ScopeContainerC(contents && contents.scopes ? contents.scopes : null, occurrenceTypes && occurrenceTypes[0].scopeConstraints ? occurrenceTypes[0].scopeConstraints : null); this.__table__.insert({"bottom" : newRow(CLASSES.scopeContainer(), "Scope", this.__scope__.getFrame())}); - onTypeChangeScope(this, contents.scopes, occurrenceTypes, "occurrence"); + onTypeChangeScope(this, contents && contents.scopes ? contents.scopes : null, occurrenceTypes, "occurrence"); // --- resource value and datatype var _min = parseInt(constraint.cardMin); var _max = constraint.cardMax !== "MAX_INT" ? parseInt(constraint.cardMax) : "*"; var cssTitle = "min: " + _min + " max: " + _max + " regular expression: " + constraint.regexp; + this.__cssTitle__ = cssTitle; makeResource(this, contents, constraint, (occurrenceTypes ? occurrenceTypes[0].datatypeConstraint : null), cssTitle); + + this.getFrame().observe("dblclick", function(event){ + dblClickHandler(owner, event); + }); } catch(err){ alert("From OccurrenceC(): " + err); @@ -1068,10 +1248,6 @@ return "null"; } }, - "isUsed" : function(){ - return this.__itemIdentity__.getContent(true, true).length !== 0 || - this.__value__.value.strip().length !== 0; - }, "isValid" : function(){ // TODO: check the content and the constraints return true; @@ -1082,6 +1258,30 @@ if(i === 0) trs[i].show(); else trs[i].hide(); } + }, + "disable" : function(){ + this.__itemIdentity__.disable(); + this.__type__.__frames__[0].disable(); + this.__scope__.disable(); + this.__value__.writeAttribute({"readonly" : "readonly"}); + this.__datatype__.__frames__[0].disable(); + this.getFrame().setStyle({"backgroundColor" : "#edeceb"}); + this.getFrame().setStyle({"border" : "1px solid darkgrey"}); + this.getFrame().writeAttribute({"title" : this.__cssTitle__}); + this.hideAddButton(); + this.__disabled__ = true; + }, + "enable" : function(){ + this.__itemIdentity__.enable(); + this.__type__.__frames__[0].enable(); + this.__scope__.enable(); + this.__value__.removeAttribute("readonly"); + this.__datatype__.__frames__[0].enable(); + this.getFrame().setStyle({"backgroundColor" : "inherit"}); + this.getFrame().setStyle({"border" : "none"}); + this.getFrame().removeAttribute("title"); + checkRemoveAddButtons(this.__owner__, 1, this.__max__); + this.__disabled__ = false; }}); @@ -1101,10 +1301,14 @@ var max = constraints[i].constraints[j].cardMax !== "MAX_INT" ? parseInt(constraints[i].constraints[j].cardMax) : "*"; var regexp = constraints[i].constraints[j].regexp; if(max !== 0){ + var dblClickHandler = null; + if(min === 0) dblClickHandler = dblClickHandlerF; + var title = "min: " + min + " max: " + max + " regular expression: " + regexp; var occurrence = new OccurrenceC("", constraints[i].occurrenceTypes, constraints[i].constraints[j], constraints[i].uniqueConstraints, this.__containers__[i][j], - min === 0 ? 1 : min, max === "*" ? -1 : max, title); + min === 0 ? 1 : min, max === "*" ? -1 : max, title, dblClickHandler); + if(min === 0) occurrence.disable(); this.__error__.insert({"before" : occurrence.getFrame()}); if(min === 0)occurrence.minimize(); } @@ -1188,7 +1392,7 @@ this.__table__.insert({"bottom" : newRow(CLASSES.topicIdFrame(), "Topic ID", this.__topicid__.__frames__[0].getFrame())}); // --- itemIdentity - this.__itemIdentity__ = new ItemIdentityC(content ? content.itemIdentities : null); + this.__itemIdentity__ = new ItemIdentityC(content ? content.itemIdentities : null, this); this.__table__.insert({"bottom" : newRow(CLASSES.itemIdentityFrame(), "ItemIdentity", this.__itemIdentity__.getFrame())}); // --- subjectLocator @@ -1270,7 +1474,7 @@ // --- representation of a role element. -var RoleC = Class.create(ContainerC, {"initialize" : function($super, itemIdentities, roleTypes, rolePlayers, owner){ +var RoleC = Class.create(ContainerC, {"initialize" : function($super, itemIdentities, roleTypes, rolePlayers, owner, typeMin, parent){ $super(); if(!owner.__frames__) owner.__frames__ = new Array(); if(!roleTypes || roleTypes.length === 0) throw "From RoleC(): roleTypes must be set!"; @@ -1281,6 +1485,9 @@ this.__frame__.insert({"top" : this.__table__}); this.__roleTypes__ = roleTypes; this.__rolePlayers__ = rolePlayers; + this.__owner__ = owner; + this.__typeMin__ = typeMin; + this.__parentElem__ = parent; try{ // --- control row + itemIdentity @@ -1303,6 +1510,28 @@ this.__player__ = new Object(); tr = newRow(CLASSES.playerFrame(), "Player", new SelectrowC(players, this.__player__, 1, 1).getFrame()); this.__table__.insert({"bottom" : tr}); + + function setDblClickHandler(myself){ + myself.getFrame().observe("dblclick", function(event){ + if(myself.__typeMin__ === 0){ + var roles = new Array(); + for(var i = 0; i !== owner.__frames__.length; ++i){ + if(roleTypes.flatten().indexOf(owner.__frames__[i].getType()) !== -1) + roles.push(owner.__frames__[i]); + } + + if(roles.length === 1 && roles[0].isUsed() === true){ + roles[0].disable(); + } + else if(roles.length === 1 && roles[0].isUsed() === false){ + roles[0].enable(); + } + if(parent.isUsed() === true)Event.stop(event); + } + }); + } + setDblClickHandler(this); + } catch(err){ alert("From RoleC(): " + err); @@ -1416,18 +1645,35 @@ return this.getType().length !== 0 && this.getPlayer().length !== 0; }, "isUsed" : function(){ - return this.getType().length !== 0 || this.getPlayer().length !== 0 || this.__itemIdentity__.getContent(true, true).length !== 0; + return !this.__disabled__; + }, + "disable" : function(){ + this.__itemIdentity__.disable(); + this.__type__.__frames__[0].disable(); + this.__player__.__frames__[0].disable(); + this.getFrame().setStyle({"backgroundColor" : "#edeceb"}); + this.getFrame().setStyle({"border" : "1px solid darkgrey"}); + this.__disabled__ = true; + }, + "enable" : function(){ + this.__itemIdentity__.enable(); + this.__type__.__frames__[0].enable(); + this.__player__.__frames__[0].enable(); + this.getFrame().setStyle({"backgroundColor" : "inherit"}); + this.getFrame().setStyle({"border" : "none"}); + this.__disabled__ = false; }}); // --- contains all roles of an association -var RoleContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, associationRoleConstraints, rolePlayerConstraints, otherRoleConstraints){ +var RoleContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, associationRoleConstraints, rolePlayerConstraints, otherRoleConstraints, parent){ $super(); this.__frame__.writeAttribute({"class" : CLASSES.roleContainer()}); this.__arContainer__ = new Object(); this.__orContainer__ = new Object(); this.__otherRoleConstraints__ = otherRoleConstraints; this.__rolePlayerConstraints__ = rolePlayerConstraints; + this.__parentElem__ = parent; try{ if((!contents || contents.length === 0) && associationRoleConstraints){ this.resetValues(associationRoleConstraints, rolePlayerConstraints, otherRoleConstraints); @@ -1486,6 +1732,7 @@ var allAvailablePlayers = extractPlayersOfConstraints(rolePlayerConstraints); var roleType = associationRoleConstraint.roleType; var roleMin = associationRoleConstraint.cardMin === 0 ? 1 : parseInt(associationRoleConstraint.cardMin); + var roleMinOrg = parseInt(associationRoleConstraint.cardMin); for(var i = 0; i !== rolePlayerConstraints.length; ++i){ 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] + "\"!"; @@ -1497,7 +1744,7 @@ var cleanedPlayers = cleanPlayers(allAvailablePlayers, selectedPlayers); cleanedPlayers = cleanPlayers(cleanedPlayers, currentPlayers); cleanedPlayers = currentPlayers.concat(cleanedPlayers); - var role = new RoleC(null, roleType, cleanedPlayers, this.__arContainer__); + var role = new RoleC(null, roleType, cleanedPlayers, this.__arContainer__, roleMinOrg, this.__parentElem__); this.__setRoleChangePlayerHandler__(role, this.__arContainer__.__frames__, rolePlayerConstraints, null); this.__error__.insert({"before" : role.getFrame()}); // --- removes the new role's selected item from all other existing roles @@ -1532,7 +1779,7 @@ this.__arContainer__.__frames__[j].removePlayer(cleanedPlayers[0]); } - var role = new RoleC(null, roleType, cleanedPlayers, this.__arContainer__); + var role = new RoleC(null, roleType, cleanedPlayers, this.__arContainer__, roleMinOrg, this.__parentElem__); currentRoles.push(role); this.__setRoleChangePlayerHandler__(role, this.__arContainer__.__frames__, rolePlayerConstraints, null); this.__error__.insert({"before" : role.getFrame()}); @@ -1556,6 +1803,7 @@ var cOtherPlayers = orpcs[i].otherPlayers; 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] + "\"!"; var existingRoles = this.getExistingRoles(cOtherRoleType, cOtherPlayers, this.__orContainer__.__frames__); for(var j = 0; j < cMin - existingRoles.length; ++j){ @@ -1574,7 +1822,7 @@ this.__orContainer__.__frames__[j].removePlayer(cleanedPlayers[0]); } - var role = new RoleC(null, cOtherRoleType, cleanedPlayers, this.__orContainer__); + var role = new RoleC(null, cOtherRoleType, cleanedPlayers, this.__orContainer__, cMinOrg, this.__parentElem__); this.__checkORCButtons__(role, orpcs[i]); this.__setRoleChangePlayerHandler__(role, this.__orContainer__.__frames__, null, orpcs); this.__setORCAddHandler__(role, orpcs[i], orpcs); @@ -1641,6 +1889,7 @@ var cOtherRoleType = currentConstraint.otherRoleType; var cardMax = currentConstraint.cardMax === "MAX_INT" ? "*" : parseInt(currentConstraint.cardMax); var cardMin = currentConstraint.cardMin === 0 ? 1 : parseInt(currentConstraint.cardMin); + var cardMinOrg = parseInt(currentConstraint.cardMin);; var existingRoles = roleContainer.getExistingRoles(cOtherRoleType, cOtherPlayers, roleContainer.__orContainer__.__frames__); var cleanedPlayers = new Array(); for(var i = 0; i !== cOtherPlayers.length; ++i){ @@ -1651,7 +1900,7 @@ // --- creates new role if(cleanedPlayers.length !== 0){ - var role = new RoleC(null, cOtherRoleType, cleanedPlayers, roleContainer.__orContainer__); + var role = new RoleC(null, cOtherRoleType, cleanedPlayers, roleContainer.__orContainer__, cardMinOrg, this.__parentElem__); roleContainer.__checkORCButtons__(role, currentConstraint); roleContainer.__setRoleChangePlayerHandler__(role, roleContainer.__orContainer__.__frames__, null, constraints); roleContainer.__setORCAddHandler__(role, currentConstraint, constraints); @@ -1736,11 +1985,12 @@ // --- creates a new role var cardMax = associationRoleConstraint.cardMax === "MAX_INT" ? "*" : parseInt(associationRoleConstraint.cardMax); + var cardMin = parseInt(associationRoleConstraint.cardMin); if(cardMax === "*" || cardMax > rolesToCheck.length){ var usedPlayers = new Array(); for(var i = 0; i !== rolesToCheck.length; ++i) usedPlayers.push(rolesToCheck[i].getPlayer()); var cleanedPlayers = cleanPlayers(players ? players : new Array(), usedPlayers); - var role = new RoleC(null, roleType, cleanedPlayers, roleContainer.__arContainer__); + var role = new RoleC(null, roleType, cleanedPlayers, roleContainer.__arContainer__, cardMin, this.__parentElem__); var foundRpcs = getRolePlayerConstraintsForRole(roleType, roleContainer.__rolePlayerConstraints__); roleContainer.__setRoleChangePlayerHandler__(role, roleContainer.__arContainer__.__frames__, foundRpcs, null); roleContainer.__setARCAddHandler__(role, players, associationRoleConstraint); @@ -1934,6 +2184,24 @@ } return roles.substring(0, roles.length - 1) + "]"; }, + "disable" : function(){ + if(this.__orContainer__.__frames__){ + for(var i = 0; i !== this.__orContainer__.__frames__.length; ++i) this.__orContainer__.__frames__[i].disable(); + } + if(this.__arContainer__.__frames__){ + for(var i = 0; i !== this.__arContainer__.__frames__.length; ++i) this.__arContainer__.__frames__[i].disable(); + } + this.__disabled__ = true; + }, + "enable" : function(){ + if(this.__orContainer__.__frames__){ + for(var i = 0; i !== this.__orContainer__.__frames__.length; ++i) this.__orContainer__.__frames__[i].enable(); + } + if(this.__arContainer__.__frames__){ + for(var i = 0; i !== this.__arContainer__.__frames__.length; ++i) this.__arContainer__.__frames__[i].enable(); + } + this.__disable__ = false; + }, "isValid" : function(){ // TODO: implement return true; @@ -1952,6 +2220,8 @@ this.__frame__.insert({"top" : this.__table__}); this.__constraints__ = constraints; this.__contents__ = contents; + this.__owner__ = owner; + this.__dblClickHandler__ = dblClickHandlerF; try{ // --- control row + ItemIdentity @@ -1989,11 +2259,18 @@ _otherRoleConstraints = this.__constraints__[0].otherRoleConstraints; } - this.__roles__ = new RoleContainerC(this.__contents__ ? this.__contents__.roles : null, _roleConstraints, _playerConstraints, _otherRoleConstraints); + this.__roles__ = new RoleContainerC(this.__contents__ ? this.__contents__.roles : null, _roleConstraints, _playerConstraints, _otherRoleConstraints, this); this.__table__.insert({"bottom" : newRow(CLASSES.roleContainer(), "Roles", this.__roles__.getFrame())}); // --- registers the onChangeHandler of the Type-selectrow onTypeChangeScope(this, null, null, "association"); + + function setDblClickHandler(myself){ + myself.getFrame().observe("dblclick", function(event){ + myself.__dblClickHandler__(owner, event); + }); + } + setDblClickHandler(this); } catch(err){ alert("From AssociationC(): " + err); @@ -2041,9 +2318,27 @@ // TODO: implement return true; }, - "isUsed" : function(){ - // TODO: implement (activate button) - return true; + "disable" : function(){ + this.__itemIdentity__.disable(); + this.__roles__.disable(); + this.__type__.__frames__[0].disable(); + this.__scope__.disable(); + this.hideRemoveButton(); + this.hideAddButton(); + this.getFrame().setStyle({"backgroundColor" : "#edeceb"}); + this.getFrame().setStyle({"border" : "1px solid darkgrey"}); + this.__disabled__ = true; + }, + "enable" : function(){ + this.__itemIdentity__.enable(); + this.__roles__.enable(); + this.__type__.__frames__[0].enable(); + this.__scope__.enable(); + if(this.__owner__.__frames__.length > 1) this.showRemoveButton(); + this.showAddButton(); + this.getFrame().setStyle({"backgroundColor" : "inherit"}); + this.getFrame().setStyle({"border" : "none"}); + this.__disabled__ = false; }}); @@ -2084,18 +2379,6 @@ }); } setMinimizeHandler(this); - - var button = new Element("input", {"type" : "button", "value" : "toJSON()"}); - function test(myself){ - button.observe("click", function(event){ - try{ - alert("content:\n\n" + myself.getContent()); - alert("JSON:\n\n" + myself.toJSON().gsub("\"topicRef\":\\[\"\\*\\*current-topic\\*\\*\"\\]", myself.__mainTopic__.getContent().subjectIdentifiers.toJSON())); - }catch(err){ alert("test: " + err); } - }); - } - test(this); - this.getFrame().insert({"bottom" : button}); } catch(err){ alert("From AssociationContainerC(): " + err); @@ -2173,15 +2456,17 @@ - - - - - - - - - +// --- A handler for the dblclick-event. So a frame can be disabled or enabled. +function dblClickHandlerF(owner, event){ + if(owner.__frames__.length === 1){ + if(owner.__frames__[0].isUsed() === true){ + owner.__frames__[0].disable(); + } + else { + if(!owner.__frames__[0].__parentElem__ || owner.__frames__[0].__parentElem__.isUsed() === true) owner.__frames__[0].enable(); + } + } +} // --- helper function to create a dom-fragment of the form @@ -2202,31 +2487,39 @@ myself.__remove__.stopObserving(); myself.__add__.stopObserving(); myself.__remove__.observe("click", function(event){ - myself.remove(); - owner.__frames__ = owner.__frames__.without(myself); - if(min >= owner.__frames__.length){ - for(var i = 0; i != owner.__frames__.length; ++i){ - owner.__frames__[i].hideRemoveButton(); + var disabled = false; + try{ disabled = myself.__disabled__; } catch(err){ }; + if(disabled === false){ + myself.remove(); + owner.__frames__ = owner.__frames__.without(myself); + if(min >= owner.__frames__.length){ + for(var i = 0; i != owner.__frames__.length; ++i){ + owner.__frames__[i].hideRemoveButton(); + } } - } - if(max > owner.__frames__.length){ - for(var i = 0; i != owner.__frames__.length; ++i){ - owner.__frames__[i].showAddButton(); + if(max > owner.__frames__.length){ + for(var i = 0; i != owner.__frames__.length; ++i){ + owner.__frames__[i].showAddButton(); + } } } }); myself.__add__.observe("click", function(event){ - var newElem = call(); - myself.append(newElem.getFrame()); - if(remove === true && min !== -1 && owner.__frames__.length > min){ - for(var i = 0; i != owner.__frames__.length; ++i){ - owner.__frames__[i].showRemoveButton(); + var disabled = false; + try{ disabled = myself.__disabled__; } catch(err){ }; + if(disabled === false){ + var newElem = call(); + myself.append(newElem.getFrame()); + if(remove === true && min !== -1 && owner.__frames__.length > min){ + for(var i = 0; i != owner.__frames__.length; ++i){ + owner.__frames__[i].showRemoveButton(); + } } - } - if(max > -1 && max <= owner.__frames__.length){ - for(var i = 0; i != owner.__frames__.length; ++i){ - owner.__frames__[i].hideAddButton(); + if(max > -1 && max <= owner.__frames__.length){ + for(var i = 0; i != owner.__frames__.length; ++i){ + owner.__frames__[i].hideAddButton(); + } } } }); @@ -2255,12 +2548,17 @@ owner.__frames__[i].hideAddButton(); } } + + if(max === -1 || max > owner.__frames__.length){ + for(var i = 0; i != owner.__frames__.length; ++i){ + owner.__frames__[i].showAddButton(); + } + } } // --- creates a control row for NameC, OccurrenceC and VariantC with a nested ItemIdentity frame. -function makeControlRow(myself, rowspan, contents) -{ +function makeControlRow(myself, rowspan, contents){ var tr = new Element("tr", {"class" : CLASSES.itemIdentityFrame()}); var tdCtrl = new Element("td", {"class" : CLASSES.controlColumn(), "rowspan" : rowspan}); tr.insert({"top" : tdCtrl}) @@ -2277,7 +2575,7 @@ tdCtrl.insert({"bottom" : myself.__add__}); var tdCont = new Element("td", {"class" : CLASSES.content()}); tr.insert({"bottom" : tdCont}); - myself.__itemIdentity__ = new ItemIdentityC(contents ? contents.itemIdentities : null); + myself.__itemIdentity__ = new ItemIdentityC(contents ? contents.itemIdentities : null, myself); tdCont.insert({"top" : myself.__itemIdentity__.getFrame()}); myself.__table__.insert({"bottom" : tr}); @@ -2379,7 +2677,7 @@ }catch(err){} try{ this.__datatype__.__frames__[0].remove(); - this.__datytype__ = new Object(); + this.__datatype__ = new Object(); }catch(err){} myself.__value__ = new Element("textarea", {"rows" : 3}).update(value); 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 Tue Jun 16 03:27:00 2009 @@ -180,30 +180,6 @@ (format nil "Condition: \"~a\"" err)))))) (setf (hunchentoot:return-code*) hunchentoot:+http-bad-request+)))) -;(defun return-tmcl-info-of-psis(treat-as &otptional psi) -; "Returns a json string which represents the defined tmcl-constraints of the -; topic and the associations where this topic can be a player." -; (alert psi) -; (let ((http-method (hunchentoot:request-method*))) -; (if (eq http-method :GET) -; (let ((identifier (string-replace psi "%23" "#"))) -; (setf (hunchentoot:content-type*) "application/json") ;RFC 4627 -; (handler-case (let ((tmcl -; (json-tmcl:get-constraints-of-fragment identifier :treat-as treat-as))) -; (if tmcl -; (progn -; (setf (hunchentoot:content-type*) "application/json") ;RFC 4627 -; tmcl) -; (progn -; (setf (hunchentoot:return-code*) hunchentoot:+http-not-found+) -; (setf (hunchentoot:content-type*) "text") -; (format nil "Topic \"~a\" not found." psis)))) -; (condition (err) (progn -; (setf (hunchentoot:return-code*) hunchentoot:+http-internal-server-error+) -; (setf (hunchentoot:content-type*) "text") -; (format nil "Condition: \"~a\"" err))))) -; (setf (hunchentoot:return-code*) hunchentoot:+http-bad-request+)))) - (defun return-all-topic-psis (&optional param) "return all psis currently existing in isidorus as a list of list. every topic is a list Modified: trunk/src/unit_tests/poems.xtm ============================================================================== --- trunk/src/unit_tests/poems.xtm (original) +++ trunk/src/unit_tests/poems.xtm Tue Jun 16 03:27:00 2009 @@ -1,6 +1,6 @@ - + @@ -1301,7 +1301,7 @@ - 2 + 1 From lgiessmann at common-lisp.net Tue Jun 16 10:04:55 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Tue, 16 Jun 2009 06:04:55 -0400 Subject: [isidorus-cvs] r42 - trunk/src/ajax/javascripts Message-ID: Author: lgiessmann Date: Tue Jun 16 06:04:53 2009 New Revision: 42 Log: ajax-client: by commiting a fragment, there will be requested all needed topicStubs for a valid fragment by the ajax as a "background process", so the user does not need to care about the referenced topicStubs Modified: trunk/src/ajax/javascripts/constants.js trunk/src/ajax/javascripts/create.js trunk/src/ajax/javascripts/datamodel.js trunk/src/ajax/javascripts/requests.js Modified: trunk/src/ajax/javascripts/constants.js ============================================================================== --- trunk/src/ajax/javascripts/constants.js (original) +++ trunk/src/ajax/javascripts/constants.js Tue Jun 16 06:04:53 2009 @@ -31,6 +31,7 @@ var ANY_URI = "http://www.w3.org/2001/XMLSchema#anyURI"; var STRING = "http://www.w3.org/2001/XMLSchema#string"; var CURRENT_TOPIC = "**current-topic**"; +var CURRENT_TOPIC_ESCAPED = "\\*\\*current-topic\\*\\*"; // --- Contains most css classes used in this project // --- There should be called only the function to be sure to don't override Modified: trunk/src/ajax/javascripts/create.js ============================================================================== --- trunk/src/ajax/javascripts/create.js (original) +++ trunk/src/ajax/javascripts/create.js Tue Jun 16 06:04:53 2009 @@ -56,7 +56,31 @@ var commitButton = new Element("input", {"type" : "button", "value" : "commit fragment", "style" : "float: right; margin-top: -10px;"}) commitButton.observe("click", function(event){ - alert("commit fragment"); + try{ + var tPsis = topic.getContent().subjectIdentifiers; + var referencedTopics = topic.getReferencedTopics().concat(associations.getReferencedTopics()).without(CURRENT_TOPIC).uniq(); + + function onSuccessHandler(topicStubs){ + var str = "null"; + if(topicStubs && topicStubs.length !== 0){ + str = "["; + for(var i = 0; i !== topicStubs.length; ++i){ + str += topicStubs[i]; + if(i !== topicStubs.length - 1) str += ","; + } + str += "]"; + } + var json = "{\"topic\":" + topic.toJSON() + ",\"topicStubs\":" + str + ",\"associations\":" + associations.toJSON().gsub(CURRENT_TOPIC_ESCAPED, tPsis) + ",\"tmIds\":" + "[\"myTM\"]}"; + alert(json); + } + + function onErrorHandler(){ + // --- currently there is not neede a special handling for errors + // --- occurred during this operation + } + + getTopicStubs(referencedTopics, onSuccessHandler, onErrorHandler); + }catch(err){ alert("test: " + err); } }); var liCB = new Element("li", {"class" : CLASSES.commitButton()}); liCB.update(commitButton); Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Tue Jun 16 06:04:53 2009 @@ -1018,7 +1018,9 @@ }, "getContent" : function(){ if(this.isUsed() === false) return null; + var type = this.__type__.__frames__[0].getContent(); return {"itemIdentities" : this.__itemIdentity__.getContent(true, true), + "type" : type ? new Array(type) : null, "scopes" : this.__scope__.getContent(), "value" : this.__value__.__frames__[0].getContent(), "variants" : this.__variants__.getContent()}; @@ -1470,6 +1472,42 @@ }, "hasPsi" : function(){ return this.__subjectIdentifier__.getContent(true, true).length !== 0; + }, + "getReferencedTopics" : function(){ + var referencedTopics = new Array(); + var names = this.getContent().names; + if(names){ + for(var i = 0; i !== names.length; ++i){ + // TODO: variant (-scope topicStubs) + var type = names[i].type; + if(type){ + if(referencedTopics.indexOf(type[0]) === -1) referencedTopics.push(type[0]); + } + var scopes = names[i].scopes; + if(scopes){ + for(var j = 0; j !== scopes.length; ++j){ + if(referencedTopics.indexOf(scopes[j]) === -1) referencedTopics.push(scopes[j]); + } + } + } + } + + var occurrences = this.getContent().occurrences; + if(occurrences){ + for(var i = 0; i !== occurrences.length; ++i){ + var type = occurrences[i].type; + if(type){ + if(referencedTopics.indexOf(type[0]) === -1) referencedTopics.push(type[0]); + } + var scopes = occurrences[i].scopes; + if(scopes){ + for(var j = 0; j !== scopes.length; ++j){ + if(referencedTopics.indexOf(scopes[j]) === -1) referencedTopics.push(scopes[j]); + } + } + } + } + return referencedTopics; }}); @@ -2302,8 +2340,9 @@ }, "getContent" : function(){ if(!this.isUsed()) return null; + var type = this.__type__.__frames__[0].getContent(); return {"itemIdentities" : this.__itemIdentity__.getContent(true, true), - "type" : new Array(this.__type__.__frames__[0].getContent()), + "type" : type ? new Array(type) : null, "scopes" : this.__scope__.getContent(), "roles" : this.__roles__.getContent()}; }, @@ -2412,6 +2451,32 @@ else rows[i].show(); } this.__minimized__ = !this.__minimized__; + }, + "getReferencedTopics" : function(){ + var referencedTopics = new Array(); + var associations = this.getContent(); + if(associations){ + for(var i = 0; i !== associations.length; ++i){ + var assType = associations[i].type; + if(referencedTopics.indexOf(assType[0]) === -1) referencedTopics.push(assType[0]); + var scopes = associations[i].scopes; + if(scopes){ + for(var j = 0; j !== scopes.length; ++j){ + if(referencedTopics.indexOf(scopes[j]) === -1) referencedTopics.push(scopes[j]); + } + } + var roles = associations[i].roles; + if(roles){ + for(var j = 0; j !== roles.length; ++j){ + var roleType = roles[j].type; + if(roleType && referencedTopics.indexOf(roleType[0]) === -1) referencedTopics.push(roleType[0]); + var player = roles[j].topicRef; + if(player && referencedTopics.indexOf(player[0]) === -1) referencedTopics.push(player[0]); + } + } + } + } + return referencedTopics; }}); Modified: trunk/src/ajax/javascripts/requests.js ============================================================================== --- trunk/src/ajax/javascripts/requests.js (original) +++ trunk/src/ajax/javascripts/requests.js Tue Jun 16 06:04:53 2009 @@ -52,4 +52,57 @@ catch(err){ alert("Could not request contraints, please try again!\n\n" + err); } +} + + +// --- gets all topicStubs information for the passed psis and +// --- executes the onSuccessHandler or the on FailureHandler +// --- if all stubs are requested or one request fails. +function getTopicStubs(psis, onSuccessHandler, onFailureHandler) +{ + if(!onSuccessHandler || !onFailureHandler) throw "From getTopicStubs(): onsuccessHandler and onFailureHandler must be set!"; + try{ + var topicStubs = new Array(); + + if(psis){ + for(var i = 0; i !== psis.length; ++i){ + var url = GET_STUB_PREFIX + psis[i].gsub("#", "%23"); + new Ajax.Request(url, { + "method" : "get", + "requestHeaders" : ["If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT"], + "onSuccess" : function(xhr){ + if(xhr.responseText.length === 0 || xhr.responseText.isJSON() === false) errorHandler("Got bad JSON-Data for \"" + psis[i] + "\"!"); + else topicStubs.push(xhr.responseText); + }, + "onFailure" : function(xhr){ + alert("From getTopicStubs(): Could not equest topicStub information for \"" + xhr.request.url + "\"!!!"); + onFailureHandler(); + }}); + } + } + + // --- Checks the requested value. If there are all values requested, there will be called the + // --- onSuccessHandler - otherwise (after the maximum time out or an faild request) there will + // --- be called the onErrorHandler. + var maxTimeout = psis.length * TIMEOUT; + var neededTime = 0; + function checkRequests(){ + var delta = 100; + neededTime += delta; + if(delta > maxTimeout){ + alert("From getTopicStubs(): Please check your network-connection - the request timed out!!!"); + onFailureHandler(); + return; + } + + if(topicStubs.length === psis.length) onSuccessHandler(topicStubs); + else setTimeout(checkRequests, delta); + } + + checkRequests(); + + } + catch(err){ + alert("From getTopicStubs(): Could not request topicStubs information for: " + psis + "\n\n" + err); + } } \ No newline at end of file From lgiessmann at common-lisp.net Tue Jun 16 10:52:20 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Tue, 16 Jun 2009 06:52:20 -0400 Subject: [isidorus-cvs] r43 - trunk/src/ajax/javascripts Message-ID: Author: lgiessmann Date: Tue Jun 16 06:52:20 2009 New Revision: 43 Log: ajax-client: finalized the "toJSON()" methods of all needed classes - so it is possible to create a json-string of the users objects Modified: trunk/src/ajax/javascripts/constants.js trunk/src/ajax/javascripts/create.js trunk/src/ajax/javascripts/datamodel.js Modified: trunk/src/ajax/javascripts/constants.js ============================================================================== --- trunk/src/ajax/javascripts/constants.js (original) +++ trunk/src/ajax/javascripts/constants.js Tue Jun 16 06:52:20 2009 @@ -76,6 +76,7 @@ "__spanDeselect__" : "deselect", "__divFog__" : "fog", "__inputCommitButton__" : "commitButton", + "__divTmIdFrame__" : "tmIdFrame", "page" : function(){ return this.__divPage__; }, "subPage" : function(){ return this.__divSubPage__; }, @@ -115,5 +116,6 @@ "playerFrame" : function(){ return this.__divPlayerFrame__; }, "deselect" : function(){ return this.__spanDeselect__; }, "fog" : function(){ return this.__divFog__; }, - "commitButton" : function(){ return this.__inputCommitButton__; } + "commitButton" : function(){ return this.__inputCommitButton__; }, + "tmIdFrame" : function(){ return this.__divTmIdFrame__; } }; \ No newline at end of file Modified: trunk/src/ajax/javascripts/create.js ============================================================================== --- trunk/src/ajax/javascripts/create.js (original) +++ trunk/src/ajax/javascripts/create.js Tue Jun 16 06:52:20 2009 @@ -50,10 +50,14 @@ context.insert({"after" : liT}); addTopicAsPlayer((constraints ? constraints.associationsConstraints : null), topic.getContent().instanceOfs); - var associations = new AssociationContainerC(null, (constraints ? constraints.associationsConstraints : null), topic); + var associations = new AssociationContainerC(null, (constraints ? constraints.associationsConstraints : null)); var liA = new Element("li", {"class" : CLASSES.associationContainer()}).update(associations.getFrame()); liT.insert({"after" : liA}); + var tmId = new tmIdC(null); + var liTm = new Element("li", {"class" : CLASSES.tmIdFrame()}).update(tmId.getFrame()); + liA.insert({"after" : liTm}); + var commitButton = new Element("input", {"type" : "button", "value" : "commit fragment", "style" : "float: right; margin-top: -10px;"}) commitButton.observe("click", function(event){ try{ @@ -61,16 +65,20 @@ var referencedTopics = topic.getReferencedTopics().concat(associations.getReferencedTopics()).without(CURRENT_TOPIC).uniq(); function onSuccessHandler(topicStubs){ - var str = "null"; + var tsStr = "null"; if(topicStubs && topicStubs.length !== 0){ - str = "["; + tsStr = "["; for(var i = 0; i !== topicStubs.length; ++i){ - str += topicStubs[i]; - if(i !== topicStubs.length - 1) str += ","; + tsStr += topicStubs[i]; + if(i !== topicStubs.length - 1) tsStr += ","; } - str += "]"; + tsStr += "]"; } - var json = "{\"topic\":" + topic.toJSON() + ",\"topicStubs\":" + str + ",\"associations\":" + associations.toJSON().gsub(CURRENT_TOPIC_ESCAPED, tPsis) + ",\"tmIds\":" + "[\"myTM\"]}"; + var jTopic = "\"topic\":" + topic.toJSON(); + var jTopicStubs = "\"topicStubs\":" + tsStr; + var jAssociations = "\"associations\":" + associations.toJSON().gsub(CURRENT_TOPIC_ESCAPED, tPsis) + var jTmId = "\"tmIds\":" + tmId.toJSON(); + var json = "{" + jTopic + "," + jTopicStubs + "," + jAssociations + "," + jTmId + "}"; alert(json); } @@ -84,7 +92,7 @@ }); var liCB = new Element("li", {"class" : CLASSES.commitButton()}); liCB.update(commitButton); - liA.insert({"after" : liCB}); + liTm.insert({"after" : liCB}); } Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Tue Jun 16 06:52:20 2009 @@ -2382,10 +2382,9 @@ // --- contains all fragment's associations depending on the main topic -var AssociationContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints, mainTopic){ +var AssociationContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints){ $super(); this.__minimized__ = false; - this.__mainTopic__ = mainTopic; try{ this.__frame__ .writeAttribute({"class" : CLASSES.associationContainer()}); this.__table__ = new Element("table", {"class" : CLASSES.associationContainer()}); @@ -2480,45 +2479,53 @@ }}); +// --- Representation of a topic map if frame. +var tmIdC = Class.create(ContainerC, {"initialize" : function($super, contents){ + $super(); + try{ + this.__frame__.writeAttribute({"class" : CLASSES.itemIdentityFrame()}); + this.__container__ = new Object(); + this.__frame__.writeAttribute({"class" : CLASSES.tmIdFrame()}); + this.__table__ = new Element("table", {"class" : CLASSES.tmIdFrame()}); + this.__frame__.insert({"top" : this.__table__}); + this.__caption__ = new Element("caption", {"class" : CLASSES.clickable()}).update("Topic Map ID"); + this.__table__.update(this.__caption__); + var value = contents && contents.length !== 0 ? contents[0] : ""; + this.__contentrow__ = new Element("input", {"type" : "text", "value" : value}); + this.__tr__ = new Element("tr", {"class" : CLASSES.tmIdFrame()}); + var td =new Element("td", {"class" : CLASSES.content()}); + this.__tr__.update(td); + td.update(this.__contentrow__); + this.__table__.insert({"bottom" : this.__tr__}); + + this.__minimized__ = false; + function setMinimizeHandler(myself){ + myself.__caption__.observe("click", function(event){ + myself.minimize(); + }); + } + setMinimizeHandler(this); + } + catch(err){ + alert("From tmIdC(): " + err); + } + }, + "getContent" : function(){ + if(this.__contentrow__.value.strip().length === 0) return null; + return new Array(this.__contentrow__.value.strip()); + }, + "toJSON" : function(){ + return (this.getContent() === null ? "null" : this.getContent().toJSON()); + }, + "isValid" : function(){ + return this.getContent() !== null; + }, + "minimize": function(){ + if(this.__minimized__ === false) this.__tr__.hide(); + else this.__tr__.show(); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + this.__minimized__ = !this.__minimized__; + }}); // --- A handler for the dblclick-event. So a frame can be disabled or enabled. From lgiessmann at common-lisp.net Tue Jun 16 12:17:10 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Tue, 16 Jun 2009 08:17:10 -0400 Subject: [isidorus-cvs] r44 - in trunk/src: ajax/javascripts json Message-ID: Author: lgiessmann Date: Tue Jun 16 08:17:10 2009 New Revision: 44 Log: ajax-client: a fragment commit without validation is implemented; json-importer: to import a topic or a topicStub it is necessary to define a psi for this element - this is difference between the xtm-importer \(there must be one of the elements psi, itemidentity, subjectlocator defined\), because all topics are referenced via psis and not topicid\'s Modified: trunk/src/ajax/javascripts/create.js trunk/src/ajax/javascripts/datamodel.js trunk/src/ajax/javascripts/requests.js trunk/src/json/json_importer.lisp Modified: trunk/src/ajax/javascripts/create.js ============================================================================== --- trunk/src/ajax/javascripts/create.js (original) +++ trunk/src/ajax/javascripts/create.js Tue Jun 16 08:17:10 2009 @@ -36,6 +36,11 @@ items[i].remove(); } + items = $$("li." + CLASSES.tmIdFrame()); + for(var i = 0; i !== items.length; ++i){ + items[i].remove(); + } + items = $$("li." + CLASSES.commitButton()); for(var i = 0; i !== items.length; ++i){ items[i].remove(); @@ -49,10 +54,17 @@ var liT = new Element("li", {"class" : CLASSES.topicFrame()}).update(topic.getFrame()); context.insert({"after" : liT}); - addTopicAsPlayer((constraints ? constraints.associationsConstraints : null), topic.getContent().instanceOfs); - var associations = new AssociationContainerC(null, (constraints ? constraints.associationsConstraints : null)); - var liA = new Element("li", {"class" : CLASSES.associationContainer()}).update(associations.getFrame()); - liT.insert({"after" : liA}); + var liA = null; + var associations = null; + if(constraints && constraints.associationsConstraints && constraints.associationsConstraints.length !== 0){ + addTopicAsPlayer((constraints ? constraints.associationsConstraints : null), topic.getContent().instanceOfs); + associations = new AssociationContainerC(null, (constraints ? constraints.associationsConstraints : null)); + liA = new Element("li", {"class" : CLASSES.associationContainer()}).update(associations.getFrame()); + liT.insert({"after" : liA}); + } + else { + liA = liT; + } var tmId = new tmIdC(null); var liTm = new Element("li", {"class" : CLASSES.tmIdFrame()}).update(tmId.getFrame()); @@ -60,10 +72,12 @@ var commitButton = new Element("input", {"type" : "button", "value" : "commit fragment", "style" : "float: right; margin-top: -10px;"}) commitButton.observe("click", function(event){ - try{ var tPsis = topic.getContent().subjectIdentifiers; - var referencedTopics = topic.getReferencedTopics().concat(associations.getReferencedTopics()).without(CURRENT_TOPIC).uniq(); - + var referencedTopics = topic.getReferencedTopics(); + if(associations){ + referencedTopics = referencedTopics.concat(associations.getReferencedTopics()).without(CURRENT_TOPIC).uniq(); + } + function onSuccessHandler(topicStubs){ var tsStr = "null"; if(topicStubs && topicStubs.length !== 0){ @@ -76,19 +90,18 @@ } var jTopic = "\"topic\":" + topic.toJSON(); var jTopicStubs = "\"topicStubs\":" + tsStr; - var jAssociations = "\"associations\":" + associations.toJSON().gsub(CURRENT_TOPIC_ESCAPED, tPsis) + var jAssociations = "\"associations\":" + (associations ? associations.toJSON().gsub(CURRENT_TOPIC_ESCAPED, tPsis) : "null"); var jTmId = "\"tmIds\":" + tmId.toJSON(); var json = "{" + jTopic + "," + jTopicStubs + "," + jAssociations + "," + jTmId + "}"; - alert(json); + commitFragment(json, function(xhr){ alert("The fragment was committed succesfully!"); }, null); } - + function onErrorHandler(){ - // --- currently there is not neede a special handling for errors + // --- currently there is not needed a special handling for errors // --- occurred during this operation } - + getTopicStubs(referencedTopics, onSuccessHandler, onErrorHandler); - }catch(err){ alert("test: " + err); } }); var liCB = new Element("li", {"class" : CLASSES.commitButton()}); liCB.update(commitButton); Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Tue Jun 16 08:17:10 2009 @@ -650,6 +650,9 @@ catch(err){ return new Array(); } + + for(var i = 0; i !== values.length; ++i) + values[i] = new Array(values[i]); return values; }, "disable" : function(){ @@ -1486,7 +1489,7 @@ var scopes = names[i].scopes; if(scopes){ for(var j = 0; j !== scopes.length; ++j){ - if(referencedTopics.indexOf(scopes[j]) === -1) referencedTopics.push(scopes[j]); + if(referencedTopics.indexOf(scopes[j][0]) === -1) referencedTopics.push(scopes[j][0]); } } } @@ -1502,7 +1505,7 @@ var scopes = occurrences[i].scopes; if(scopes){ for(var j = 0; j !== scopes.length; ++j){ - if(referencedTopics.indexOf(scopes[j]) === -1) referencedTopics.push(scopes[j]); + if(referencedTopics.indexOf(scopes[j][0]) === -1) referencedTopics.push(scopes[j][0]); } } } @@ -2461,7 +2464,7 @@ var scopes = associations[i].scopes; if(scopes){ for(var j = 0; j !== scopes.length; ++j){ - if(referencedTopics.indexOf(scopes[j]) === -1) referencedTopics.push(scopes[j]); + if(referencedTopics.indexOf(scopes[j][0]) === -1) referencedTopics.push(scopes[j][0]); } } var roles = associations[i].roles; Modified: trunk/src/ajax/javascripts/requests.js ============================================================================== --- trunk/src/ajax/javascripts/requests.js (original) +++ trunk/src/ajax/javascripts/requests.js Tue Jun 16 08:17:10 2009 @@ -89,7 +89,7 @@ function checkRequests(){ var delta = 100; neededTime += delta; - if(delta > maxTimeout){ + if(delta > maxTimeout && psis && psis.length !== 0){ alert("From getTopicStubs(): Please check your network-connection - the request timed out!!!"); onFailureHandler(); return; @@ -105,4 +105,22 @@ catch(err){ alert("From getTopicStubs(): Could not request topicStubs information for: " + psis + "\n\n" + err); } +} + + +function commitFragment(json, onSuccessHandler, onFailureHandler) +{ + if(!json || !onSuccessHandler) throw "From commitFragment(): json and onSuccessHandler must be set!"; + try{ + var onFailure = onFailureHandler ? onFailureHandler : defaultFailureHandler; + + new Ajax.Request(COMMIT_URL, { + "method" : "post", + "postBody" : json, + "onSuccess" : onSuccessHandler, + "onFailure" : onFailure}); + } + catch(err){ + alert("From commitFragment(): " + err); + } } \ No newline at end of file Modified: trunk/src/json/json_importer.lisp ============================================================================== --- trunk/src/json/json_importer.lisp (original) +++ trunk/src/json/json_importer.lisp Tue Jun 16 08:17:10 2009 @@ -391,9 +391,8 @@ (t (error "json-importer:get-topicStub-values-from-json-string: bad item-specifier found in json-list")))) - (unless (or itemIdentities subjectLocators subjectIdentifiers) - (error "json-importer:get-topicStub-values-from-json-string: one of the elements - itemIdentity, sbjectLocator or subjectIdentifier must be set")) + (unless subjectIdentifiers + (error "json-importer:get-topicStub-values-from-json-string: the element subjectIdentifiers mus be set!")) (unless id (error "json-importer:get-topic-valuesStub-from-json-string: the element id must be set")) (list :id id @@ -433,9 +432,8 @@ (t (error "json-importer:get-topic-values-from-json-string: bad item-specifier found in json-list ~a" (car j-elem))))) - (unless (or itemIdentities subjectLocators subjectIdentifiers) - (error "json-importer:get-topic-values-from-json-string: one of the elements - itemIdentity, sbjectLocator or subjectIdentifier must be set")) + (unless subjectIdentifiers + (error "json-importer:get-topic-values-from-json-string: the element subjectIdentifiers must be set!")) (unless id (error "json-importer:get-topic-values-from-json-string: the element id must be set")) (let ((names-list (map 'list #'get-name-values-from-json-list names)) From lgiessmann at common-lisp.net Thu Jun 18 13:07:00 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Thu, 18 Jun 2009 09:07:00 -0400 Subject: [isidorus-cvs] r45 - in trunk: docs src/ajax/css src/ajax/javascripts Message-ID: Author: lgiessmann Date: Thu Jun 18 09:06:59 2009 New Revision: 45 Log: ajax-client: before committing a fragment, the given data will be validated by the client - and only be sent when the fragment is valid; currently the constraints "uniqueoccurrence-constraint" and "datatype-constraint" won\'t be checked Modified: trunk/docs/xtm_json.txt trunk/src/ajax/css/frame.css trunk/src/ajax/javascripts/create.js trunk/src/ajax/javascripts/datamodel.js Modified: trunk/docs/xtm_json.txt ============================================================================== --- trunk/docs/xtm_json.txt (original) +++ trunk/docs/xtm_json.txt Thu Jun 18 09:06:59 2009 @@ -1,4 +1,4 @@ -?//+----------------------------------------------------------------------------- +//+----------------------------------------------------------------------------- //+ Overview: //+ *Part 1: XTM - data model //+ *Part 2: Object summaries Modified: trunk/src/ajax/css/frame.css ============================================================================== --- trunk/src/ajax/css/frame.css (original) +++ trunk/src/ajax/css/frame.css Thu Jun 18 09:06:59 2009 @@ -24,4 +24,9 @@ tr.showHiddenRows { background-color: #eaeaee; +} + +li.errorMessage { + margin-top: 1em; + font-size: 1.2em; } \ No newline at end of file Modified: trunk/src/ajax/javascripts/create.js ============================================================================== --- trunk/src/ajax/javascripts/create.js (original) +++ trunk/src/ajax/javascripts/create.js Thu Jun 18 09:06:59 2009 @@ -45,7 +45,7 @@ for(var i = 0; i !== items.length; ++i){ items[i].remove(); } - + var instanceOfs = new Array(); for(var i = 0; psis && i !== psis.length; ++i){ instanceOfs.push(new Array(psis[i])); @@ -66,12 +66,21 @@ liA = liT; } - var tmId = new tmIdC(null); + var tmId = new TmIdC(null); var liTm = new Element("li", {"class" : CLASSES.tmIdFrame()}).update(tmId.getFrame()); liA.insert({"after" : liTm}); var commitButton = new Element("input", {"type" : "button", "value" : "commit fragment", "style" : "float: right; margin-top: -10px;"}) commitButton.observe("click", function(event){ + // --- validates the given data + var ret = true; + if(topic.isValid() === false) ret = false; + if(associations.isValid() === false) ret = false; + if(tmId.isValid() === false) ret = false; + + if(ret === false) return; + + // --- if the validation succeeded the fragment will be sent to the server var tPsis = topic.getContent().subjectIdentifiers; var referencedTopics = topic.getReferencedTopics(); if(associations){ Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Thu Jun 18 09:06:59 2009 @@ -92,6 +92,7 @@ this.__max__ = max; this.__regexp__ = new RegExp(regexp); + this.__regExpString__ = regexp; this.__frame__.writeAttribute({"class" : CLASSES.textrowWithRemoveButton()}); this.__content__.remove(); this.__content__ = new Element("input", {"type" : "text", "value" : content}); @@ -129,6 +130,7 @@ this.getFrame().writeAttribute({"class" : CLASSES.textrowWithoutRemoveButton()}); }, "disable" : function(){ + this.hideError(); this.__content__.writeAttribute({"readonly" : "readonly"}); this.hideRemoveButton(); this.hideAddButton(); @@ -138,6 +140,9 @@ this.__content__.removeAttribute("readonly"); checkRemoveAddButtons(this.__owner__, this.__min__, this.__max__); this.__disabled__ = false; + }, + "getRegexp" : function(){ + return this.__regExpString__; }}); @@ -174,6 +179,7 @@ this.getFrame().writeAttribute({"class" : CLASSES.selectrowWithoutRemoveButton()}); }, "disable" : function(){ + this.hideError(); this.__content__.writeAttribute({"disabled" : "disables"}); this.__disabled__ = true; }, @@ -314,7 +320,7 @@ try{ for(var i = 0; i != contents.length; ++i){ - new TextrowC(contents[i], ".*", this.__container__, 1, -1, null); + new TextrowC(decodeURI(contents[i]), ".*", this.__container__, 1, -1, null); this.__error__.insert({"before" : this.__container__.__frames__[i].getFrame()}); } } @@ -350,6 +356,7 @@ if(removeNull === true && this.__container__.__frames__[i].getContent().strip().length === 0) continue; values.push(this.__container__.__frames__[i].getContent().strip()); } + for(var i = 0; i !== values.length; ++i)values[i] = encodeURI(values[i]); return values; }, "toJSON" : function(unique, removeNull){ @@ -357,6 +364,7 @@ return content.length === 0 ? "null" : content.toJSON(); }, "disable" : function(){ + this.hideError(); if(this.__container__.__frames__){ for(var i = 0; i !== this.__container__.__frames__.length; ++i){ this.__container__.__frames__[i].disable(); @@ -380,6 +388,7 @@ $super(); this.__frame__.writeAttribute({"class" : cssClass}); this.__containers__ = new Array(); + this.__constraints__ = constraints; try{ if((!contents || contents.length === 0) && constraints && constraints.length > 0){ @@ -421,8 +430,10 @@ } } catch(err){ + for(var i = 0; i !== values.length; ++i) values[i] = encodeURI(values[i]); return values; } + for(var i = 0; i !== values.length; ++i) values[i] = encodeURI(values[i]); return values; }, "toJSON" : function(unique, removeNull){ @@ -430,8 +441,68 @@ return content.length === 0 ? "null" : content.toJSON(); }, "isValid" : function(){ - // TODO: check the validity of this frame with the passed constraints and return a boolean value - return true; + try { + var allIdentifiers = new Array(); + var errorStr = ""; + var ret = true; + + // --- checks if there are any constraints + if((!this.__constraints__ || this.__constraints__.length === 0) && this.__containers__.length !== 0){ + for(var i = 0; i !== this.__containers__.length; ++i){ + for(var j = 0; this.__containers__[i].__frames__ && j !== this.__containers__[i].__frames__.length; ++j){ + this.__containers__[i].__frames__[j].showError("No constraints found for this identifier!"); + } + } + return false; + } + else if(!this.__constraints__ || this.__constraints__.length === 0) return true; + + // --- collects all non-empty identifiers + for(var i = 0; i !== this.__containers__.length; ++i){ + for(var j = 0; this.__containers__[i].__frames__ && j !== this.__containers__[i].__frames__.length; ++j){ + var row = this.__containers__[i].__frames__[j]; + row.hideError(); + if(row.isUsed() === true && row.getContent().strip().length !== 0) allIdentifiers.push(row); + } + } + + var checkedIdentifiers = new Array(); + for(var i = 0; i !== this.__constraints__.length; ++i){ + var regexp = new RegExp(this.__constraints__[i].regexp); + var cardMin = parseInt(this.__constraints__[i].cardMin); + var cardMax = this.__constraints__[i].cardMax === "MAX_INT" ? "*" : parseInt(this.__constraints__[i].cardMax); + var currentIdentifiers = new Array(); + for(var j = 0; j !== allIdentifiers.length; ++j){ + if(regexp.match(allIdentifiers[j].getContent()) === true) currentIdentifiers.push(allIdentifiers[j]); + } + checkedIdentifiers = checkedIdentifiers.concat(currentIdentifiers); + + // --- checks card-min and card-max for the current constraint + if(cardMin > currentIdentifiers.length){ + errorStr += "card-min of the constraint regexp: \"" + this.__constraints__[i].regexp + "\" card-min: " + cardMin + " card-max: " + cardMax + " is not satisfied (" + cardMin + ")!
"; + ret = false; + } + if(cardMax !== "*" && cardMax < currentIdentifiers.length){ + errorStr += "card-max of the constraint regexp: \"" + this.__constraints__[i].regexp + "\" card-min: " + cardMin + " card-max: " + cardMax + " is not satisfied (" + cardMax + ")!
"; + ret = false; + } + } + + // --- checks if there are some identifiers which don't satisfies any constraint + checkedIdentifiers = checkedIdentifiers.uniq(); + if(checkedIdentifiers.length < allIdentifiers.length){ + ret = false; + for(var i = 0; i !== allIdentifiers.length; ++i){ + if(checkedIdentifiers.indexOf(allIdentifiers[i]) === -1) allIdentifiers[i].showError("This Identifier does not satisfie any constraint!"); + } + } + + if(ret === true) this.hideError(); + else this.showError(errorStr); + return ret; + }catch(err){ alert("err: " + err); } + + }}); @@ -656,6 +727,7 @@ return values; }, "disable" : function(){ + this.hideError(); var rows = this.getFrame().select("div"); for(var i = 0; i != rows.length; ++i){ rows[i].select("select")[0].disable(); @@ -750,6 +822,7 @@ return this.getContent().toJSON(); }, "disable" : function(){ + this.hideError(); for(var i = 0; i !== this.__container__.length; ++i) this.__container__[i].disable(); this.__disabled__ = true; }, @@ -836,13 +909,24 @@ ",\"scopes\":null,\"resourceRef\":" + resourceRef + ",\"resourceData\":" + resourceData + "}"; }, + "isEmpty" : function(){ + return this.__value__.value.length === 0; + }, "isValid" : function(){ - return this.__value__.value.strip() !== ""; + if(this.__value__.value.strip() === ""){ + this.showError("Resource Value must be set!"); + return false; + } + else { + this.hideError(); + return true; + } }, "isUsed" : function(){ return !this.__disabled__; }, "disable" : function(){ + this.hideError(); this.__itemIdentity__.disable(); // TODO: scope this.__value__.writeAttribute({"readonly" : "readonly"}); @@ -890,41 +974,41 @@ var variant = new VariantC(null, this.__container__, dblClickHandlerF, parent); this.__frame__.insert({"bottom" : variant.getFrame()}); variant.minimize(); + variant.disable(); } }, "getContent" : function(){ var values = new Array(); for(var i = 0; i != this.__container__.__frames__.length; ++i){ - if(this.__container__.__frames__[i].isUsed() === true){ + if(this.__container__.__frames__[i].isUsed() === true && this.__container__.__frames__[i].isEmpty() === false){ values.push(this.__container__.__frames__[i].getContent()); } } return values; }, "isValid" : function(){ + var ret = true; for(var i = 0; i != this.__container__.__frames__.length; ++i){ if(this.__container__.__frames__[i].isUsed() === true && - this.__container__.__frames__[i].isValid() === false) return false; + this.__container__.__frames__[i].isValid() === false) ret = false;; } - return true; + return ret; }, "toJSON" : function(){ var str = "["; for(var i = 0; i != this.__container__.__frames__.length; ++i){ - if(this.__container__.__frames__[i].isUsed() === true){ - str += this.__container__.__frames__[i].toJSON(); - } - if(i < this.__container__.__frames__.length - 1){ - str += "," + if(this.__container__.__frames__[i].isUsed() === true && this.__container__.__frames__[i].isEmpty() === false){ + str += this.__container__.__frames__[i].toJSON() + ","; } } - str += "]"; - return str === "[]" ? null : str; + str = str.substring(0, str.length - 1) + "]" + return str === "]" ? null : str; }, "isUsed" : function(){ return !this.__disabled__; }, "disable" : function(){ + this.hideError(); if(this.__container__.__frames__){ for(var i = 0; i !== this.__container__.__frames__.length; ++i) this.__container__.__frames__[i].disable(); @@ -1019,6 +1103,9 @@ alert("From NameC(): " + err); } }, + "isEmpty" : function(){ + return this.__value__.__frames__[0].getContent().length === 0; + }, "getContent" : function(){ if(this.isUsed() === false) return null; var type = this.__type__.__frames__[0].getContent(); @@ -1037,8 +1124,11 @@ ",\"variants\":" + this.__variants__.toJSON() + "}"; }, "isValid" : function(){ - // TODO: check the content and the constraints + variants.isValid() - return true; + var valueValid = this.__value__.__frames__[0].isValid(); + if(valueValid === false) this.showError("The name-value \"" + this.__value__.__frames__[0].getContent() + "\" doesn't matches the constraint \"" + this.__value__.__frames__[0].getRegexp() + "\"!"); + else this.hideError(); + var variantsValid = this.__variants__.isValid(); + return valueValid && variantsValid; }, "minimize" : function(){ var trs = this.__table__.select("tr"); @@ -1048,6 +1138,7 @@ } }, "disable" : function(){ + this.hideError(); this.__itemIdentity__.disable(); this.__type__.__frames__[0].disable(); this.__scope__.disable(); @@ -1079,6 +1170,7 @@ $super(); this.__frame__.writeAttribute({"class" : CLASSES.nameContainer()}); this.__containers__ = new Array(); + this.__constraints__ = constraints; try{ if((!contents || contents.length === 0) && constraints && constraints.length > 0){ @@ -1094,11 +1186,12 @@ if(min === 0) dblClickHandler = dblClickHandlerF; var title = "min: " + min + " max: " + max + " regular expression: " + regexp; - var name = new NameC("", constraints[i].nametypescopes, constraints[i].constraints[j], - this.__containers__[i][j], min === 0 ? 1 : min, max === "*" ? -1 : max, title, dblClickHandler); - if(min === 0)name.disable(); - this.__error__.insert({"before" : name.getFrame()}); - if(min === 0)name.minimize(); + for(var k = 0; k !== (min === 0 ? 1 : min); ++k){ + var name = new NameC("", constraints[i].nametypescopes, constraints[i].constraints[j], this.__containers__[i][j], min === 0 ? 1 : min, max === "*" ? -1 : max, title, dblClickHandler); + if(min === 0)name.disable(); + this.__error__.insert({"before" : name.getFrame()}); + if(min === 0)name.minimize(); + } } } } @@ -1117,7 +1210,7 @@ for(var i = 0; i != this.__containers__.length; ++i){ for(var j = 0; j != this.__containers__[i].length; ++j){ for(var k = 0; k != this.__containers__[i][j].__frames__.length; ++k){ - if(this.__containers__[i][j].__frames__[k].isUsed() === true){ + if(this.__containers__[i][j].__frames__[k].isUsed() === true && this.__containers__[i][j].__frames__[k].isEmpty() === false){ values.push(this.__containers__[i][j].__frames__[k].getContent()); } } @@ -1135,7 +1228,7 @@ for(var i = 0; i != this.__containers__.length; ++i){ for(var j = 0; j != this.__containers__[i].length; ++j){ for(var k = 0; k != this.__containers__[i][j].__frames__.length; ++k){ - if(this.__containers__[i][j].__frames__[k].isUsed() === true){ + if(this.__containers__[i][j].__frames__[k].isUsed() === true && this.__containers__[i][j].__frames__[k].isEmpty() === false){ str += this.__containers__[i][j].__frames__[k].toJSON() + ","; } } @@ -1150,8 +1243,97 @@ } }, "isValid" : function(){ - // TODO: check the validity of this frame with the passed constraints and return a boolean value + isValid() of all names - return true; + var ret = true; + var errorStr = ""; + + // --- checks if there are any constraints + if((!this.__constraints__ || this.__constraints__.length === 0) && this.__containers__.length !== 0){ + var nameTypes = new Array(); + for(var i = 0; i !== this.__containers__.length; ++i){ + for(var j = 0; j !== this.__containers__[i].length; ++j){ + for(var k = 0; k !== this.__containers__[i][j].__frames__.length; ++k){ + this.__containers__[i][j].__frames__[k].hideError(); + if(this.__containers__[i][j].__frames__[k].isUsed() === true){ + this.__containers__[i][j].__frames__[k].showError("No constraints found for this name!"); + } + } + } + } + return false; + } + else if(!this.__constraints__ || this.__constraints__.length === 0) return true; + + // --- summarizes all names + var allNames = new Array(); + for(var i = 0; i !== this.__containers__.length; ++i){ + for(var j = 0; j !== this.__containers__[i].length; ++j){ + for(var k = 0; k !== this.__containers__[i][j].__frames__.length; ++k){ + this.__containers__[i][j].__frames__[k].hideError(); + if(this.__containers__[i][j].__frames__[k].isUsed() === true && this.__containers__[i][j].__frames__[k].isEmpty() === false){ + allNames.push(this.__containers__[i][j].__frames__[k]); + } + } + } + } + + // --- checks every constraint and the existing names corresponding to the constraint + for(var i = 0; i !== this.__constraints__.length; ++i){ + var currentConstraintTypes = new Array(); + for(var j = 0; j !== this.__constraints__[i].nametypescopes.length; ++j){ + currentConstraintTypes = currentConstraintTypes.concat(this.__constraints__[i].nametypescopes[j].nameType); + } + currentConstraintTypes = currentConstraintTypes.uniq(); + + // --- collects all names to the current constraint + var currentNames = new Array(); + for(var j = 0; j !== allNames.length; ++j){ + var type = allNames[j].getContent().type; + if(type && currentConstraintTypes.indexOf(type[0]) !== -1) currentNames.push(allNames[j]); + + } + // --- removes all current found names from "allNames" + for(var j = 0; j !== currentNames.length; ++j) allNames = allNames.without(currentNames[j]); + // --- removes empty names (for constraints that have a subset of regexp) + + // --- checks the regExp, card-min and card-max for the found types + var satisfiedNames = new Array(); + for(var j = 0; j !== this.__constraints__[i].constraints.length; ++j){ + var regexp = new RegExp(this.__constraints__[i].constraints[j].regexp); + var cardMin = parseInt(this.__constraints__[i].constraints[j].cardMin); + var cardMax = this.__constraints__[i].constraints[j].cardMax === "MAX_INT" ? "*" : parseInt(this.__constraints__[i].constraints[j].cardMax); + var matchedNames = 0; + for(var k = 0; k !== currentNames.length; ++k){ + if(regexp.match(currentNames[k].getContent().value) === true){ + ++matchedNames; + satisfiedNames.push(currentNames[k]); + } + } + if(matchedNames < cardMin){ + ret = false; + if(errorStr.length !== 0) errorStr += "

"; + errorStr += "card-min of the constraint regexp: \"" + this.__constraints__[i].constraints[j].regexp + "\" card-min: " + cardMin + " card-max: " + cardMax + " for the nametype \"" + currentConstraintTypes + " is not satisfied (" + matchedNames + ")!"; + } + if(cardMax !== "*" && matchedNames > cardMax){ + ret = false; + if(errorStr.length !== 0) errorStr += "

"; + errorStr += "card-max of the constraint regexp: \"" + this.__constraints__[i].constraints[j].regexp + "\" card-min: " + cardMin + " card-max: " + cardMax + " for the nametype \"" + currentConstraintTypes + " is not satisfied (" + matchedNames + ")!"; + } + } + + // --- checks if there are names which wasn't checked --> bad value + satisfiedNames = satisfiedNames.uniq(); + for(var j = 0; j !== satisfiedNames.length; ++j)currentNames = currentNames.without(satisfiedNames[j]); + if(currentNames.length !== 0){ + ret = false; + for(var j = 0; j !== currentNames.length; ++j) + currentNames[j].showError("This name does not satisfie any constraint!"); + } + } + + // --- all names are valid -> hide the error-div-element + if(ret === true) this.hideError(); + else this.showError(errorStr); + return ret; }}); @@ -1164,6 +1346,7 @@ this.__table__ = new Element("table", {"class" : CLASSES.occurrenceFrame()}); this.__frame__.insert({"top" : this.__table__}); this.__max__ = max; + this.__constraint__ = constraint; this.__owner__ = owner; this.__dblClickHandler__ = dblClickHandler; @@ -1253,9 +1436,14 @@ return "null"; } }, + "isEmpty" : function(){ + return this.__value__.value.length === 0; + }, "isValid" : function(){ - // TODO: check the content and the constraints - return true; + var regexp = new RegExp(this.__constraint__.regexp); + // TODO: validate the data via the given datatype + // TODO: validate the uniqeuoccurrence-constraint + return regexp.match(this.__value__.value); }, "minimize" : function(){ var trs = this.__table__.select("tr"); @@ -1265,6 +1453,7 @@ } }, "disable" : function(){ + this.hideError(); this.__itemIdentity__.disable(); this.__type__.__frames__[0].disable(); this.__scope__.disable(); @@ -1295,6 +1484,7 @@ $super(); this.__containers__ = new Array(); this.__frame__.writeAttribute({"class" : CLASSES.occurrenceContainer()}); + this.__constraints__ = constraints; try{ if((!contents || contents.length === 0) && constraints && constraints.length > 0){ @@ -1310,12 +1500,12 @@ if(min === 0) dblClickHandler = dblClickHandlerF; var title = "min: " + min + " max: " + max + " regular expression: " + regexp; - var occurrence = new OccurrenceC("", constraints[i].occurrenceTypes, constraints[i].constraints[j], - constraints[i].uniqueConstraints, this.__containers__[i][j], - min === 0 ? 1 : min, max === "*" ? -1 : max, title, dblClickHandler); - if(min === 0) occurrence.disable(); - this.__error__.insert({"before" : occurrence.getFrame()}); - if(min === 0)occurrence.minimize(); + for(var k = 0; k !== (min === 0 ? 1 : min); ++k){ + var occurrence = new OccurrenceC("", constraints[i].occurrenceTypes, constraints[i].constraints[j], constraints[i].uniqueConstraints, this.__containers__[i][j], min === 0 ? 1 : min, max === "*" ? -1 : max, title, dblClickHandler); + if(min === 0) occurrence.disable(); + this.__error__.insert({"before" : occurrence.getFrame()}); + if(min === 0)occurrence.minimize(); + } } } } @@ -1329,8 +1519,97 @@ } }, "isValid" : function(){ - // TODO: implement this method - return true; + var ret = true; + var errorStr = ""; + + // --- checks if there are any constraints + if((!this.__constraints__ || this.__constraints__.length === 0) && this.__containers__.length !== 0){ + for(var i = 0; i !== this.__containers__.length; ++i){ + for(var j = 0; j !== this.__containers__[i].length; ++j){ + for(var k = 0; k !== this.__containers__[i][j].__frames__.length; ++k){ + this.__containers__[i][j].__frames__[k].hideError(); + if(this.__containers__[i][j].__frames__[k].isUsed() === true){ + var type = this.__containers__[i][j].__frames__[k].showError("No constraints found for this occurrence!"); + } + } + } + } + return false; + } + else if(!this.__constraints__ || this.__constraints__.length === 0) return true; + + // --- summarizes all occurrences + var allOccurrences = new Array(); + for(var i = 0; i !== this.__containers__.length; ++i){ + for(var j = 0; j !== this.__containers__[i].length; ++j){ + for(var k = 0; k !== this.__containers__[i][j].__frames__.length; ++k){ + if(this.__containers__[i][j].__frames__[k].isUsed() === true && this.__containers__[i][j].__frames__[k].isEmpty() === false){ + allOccurrences.push(this.__containers__[i][j].__frames__[k]); + } + this.__containers__[i][j].__frames__[k].hideError(); + } + } + } + + // --- checks every constraint and the existing occurrences corresponding to the current constraint + for(var i = 0; i !== this.__constraints__.length; ++i){ + var currentConstraintTypes = new Array(); + for(var j = 0; j !== this.__constraints__[i].occurrenceTypes.length; ++j){ + currentConstraintTypes = currentConstraintTypes.concat(this.__constraints__[i].occurrenceTypes[j].occurrenceType); + } + currentConstraintTypes = currentConstraintTypes.uniq(); + + // --- collects all occurrences to the current constraint + var currentOccurrences = new Array(); + for(var j = 0; j !== allOccurrences.length; ++j){ + var type = allOccurrences[j].getContent().type; + if(type && currentConstraintTypes.indexOf(type[0]) !== -1) currentOccurrences.push(allOccurrences[j]); + } + // --- removes all current found occurrences from "allOccurrences" + for(var j = 0; j !== currentOccurrences.length; ++j) allOccurrences = allOccurrences.without(currentOccurrences[j]); + // --- checks the regExp, card-min and card-max for the found types + var satisfiedOccurrences = new Array(); + for(var j = 0; j !== this.__constraints__[i].constraints.length; ++j){ + var regexp = new RegExp(this.__constraints__[i].constraints[j].regexp); + var cardMin = parseInt(this.__constraints__[i].constraints[j].cardMin); + var cardMax = this.__constraints__[i].constraints[j].cardMax === "MAX_INT" ? "*" : parseInt(this.__constraints__[i].constraints[j].cardMax); + var matchedOccurrences = 0; + for(var k = 0; k !== currentOccurrences.length; ++k){ + var value = currentOccurrences[k].getContent().resourceRef; + if(!value) value = currentOccurrences[k].getContent().resourceData.value; + if(regexp.match(value) === true){ + ++matchedOccurrences; + satisfiedOccurrences.push(currentOccurrences[k]); + } + } + // TODO: check the unique-occurrence + // TODO: check the occurrence's datatype and its content + if(matchedOccurrences < cardMin){ + ret = false; + if(errorStr.length !== 0) errorStr += "

"; + errorStr += "card-min of the constraint regexp: \"" + this.__constraints__[i].constraints[j].regexp + "\" card-min: " + cardMin + " card-max: " + cardMax + " for the occurrencetype \"" + currentConstraintTypes + " is not satisfied (" + matchedOccurrences + ")!"; + } + if(cardMax !== "*" && matchedOccurrences > cardMax){ + ret = false; + if(errorStr.length !== 0) errorStr += "

"; + errorStr += "card-max of the constraint regexp: \"" + this.__constraints__[i].constraints[j].regexp + "\" card-min: " + cardMin + " card-max: " + cardMax + " for the occurrencetype \"" + currentConstraintTypes + " is not satisfied (" + matchedOccurrences + ")!"; + } + } + + // --- checks if there are any occurrences which wasn't checked --> bad value + satisfiedOccurrences = satisfiedOccurrences.uniq(); + for(var j = 0; j !== satisfiedOccurrences.length; ++j) + currentOccurrences = currentOccurrences.without(satisfiedOccurrences[j]); + if(currentOccurrences.length !== 0){ + ret = false; + for(var j = 0; j !== currentOccurrences.length; ++j) + currentOccurrences[j].showError("This occurrence does not satisfie any constraint!"); + } + } + + if(ret === true) this.hideError(); + else this.showError(errorStr); + return ret; }, "getContent" : function(){ var values = new Array(); @@ -1377,6 +1656,7 @@ $super(); this.__minimized__ = false; this.__instanceOfs__ = (!instanceOfs || instanceOfs.length === 0 ? null : instanceOfs); + try{ this.__frame__ .writeAttribute({"class" : CLASSES.topicFrame()}); this.__table__ = new Element("table", {"class" : CLASSES.topicFrame()}); @@ -1427,10 +1707,6 @@ alert("From TopciC(): " + err); } }, - "isValid" : function(){ - // TODO: implement - return true; - }, "getContent" : function(){ try{ return {"id" : this.__topicid__.__frames__[0].getContent().strip(), @@ -1476,6 +1752,24 @@ "hasPsi" : function(){ return this.__subjectIdentifier__.getContent(true, true).length !== 0; }, + "isValid" : function(){ + try{ + var ret = true; + if(this.__topicid__.__frames__[0].getContent().strip().length === 0){ + ret = false; + this.__topicid__.__frames__[0].showError("The topic must contain a topic ID!"); + } + else { + this.__topicid__.__frames__[0].hideError(); + } + + if(this.__subjectLocator__.isValid() === false) ret = false; + if(this.__subjectIdentifier__.isValid() === false) ret = false; + if(this.__name__.isValid() === false) ret = false; + if(this.__occurrence__.isValid() === false) ret = false; + }catch(err){ alert("err: " + err); } + return ret; + }, "getReferencedTopics" : function(){ var referencedTopics = new Array(); var names = this.getContent().names; @@ -1682,13 +1976,11 @@ return "null"; }, - "isValid" : function(){ - return this.getType().length !== 0 && this.getPlayer().length !== 0; - }, "isUsed" : function(){ return !this.__disabled__; }, "disable" : function(){ + this.hideError(); this.__itemIdentity__.disable(); this.__type__.__frames__[0].disable(); this.__player__.__frames__[0].disable(); @@ -1712,9 +2004,11 @@ this.__frame__.writeAttribute({"class" : CLASSES.roleContainer()}); this.__arContainer__ = new Object(); this.__orContainer__ = new Object(); + this.__associationRoleConstraints__ = associationRoleConstraints; this.__otherRoleConstraints__ = otherRoleConstraints; this.__rolePlayerConstraints__ = rolePlayerConstraints; this.__parentElem__ = parent; + try{ if((!contents || contents.length === 0) && associationRoleConstraints){ this.resetValues(associationRoleConstraints, rolePlayerConstraints, otherRoleConstraints); @@ -2226,6 +2520,7 @@ return roles.substring(0, roles.length - 1) + "]"; }, "disable" : function(){ + this.hideError(); if(this.__orContainer__.__frames__){ for(var i = 0; i !== this.__orContainer__.__frames__.length; ++i) this.__orContainer__.__frames__[i].disable(); } @@ -2244,8 +2539,135 @@ this.__disable__ = false; }, "isValid" : function(){ - // TODO: implement - return true; + var ret = true; + var errorStr = ""; + + var arcs = this.__associationRoleConstraints__; + var orcs = this.__otherRoleConstraints__; + var rpcs = this.__rolePlayerConstraints__; + + // --- checks if there exist any constraints + if(!arcs || arcs.length === 0){ + this.showError("No association-constraints found for this association!"); + return false; + } + + if(!rpcs || rpcs.length === 0){ + this.showError("No roleplayer-constraints found for this association!"); + return false; + } + + // --- 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]); + } + } + + // --- 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]); + } + + // --- checks all associationrole-constraints + var checkedRoles = new Array(); + for(var i = 0; i !== arcs.length; ++i){ + var currentRoles = new Array(); + var rType = arcs[i].roleType.flatten(); + var cardMin = parseInt(arcs[i].cardMin); + var cardMax = arcs[i].cardMax === "MAX_INT" ? "*" : parseInt(arcs[i].cardMax); + + // --- collects all roles for the current constraint + for(var j = 0; j !== allAroles.length; ++j){ + if(rType.indexOf(allAroles[j].getType()) !== -1) currentRoles.push(allAroles[j]); + } + allAroles = allAroles.uniq(); + + if(cardMin > currentRoles.length){ + ret = false; + if(errorStr.length !== 0) errorStr += "

"; + errorStr += "card-min of the associationrole-constraint card-min: " + cardMin + " card-max: " + cardMax + " for the roletype \"" + rType + " is not satisfied (" + currentRoles.length + ")!"; + } + if(cardMax !== "*" && cardMax < currentRoles.length){ + ret = false; + if(errorStr.length !== 0) errorStr += "

"; + errorStr += "card-max of the associationrole-constraint card-min: " + cardMin + " card-max: " + cardMax + " for the roletype \"" + rType + " is not satisfied (" + currentRoles.length + ")!"; + } + + // --- checks roleplayer-constraints for the found roles + var currentRpcs = getRolePlayerConstraintsForRole(rType, rpcs); + if(currentRpcs.length === 0){ + ret = false; + for(var j = 0; j !== currentRoles.length; ++j) currentRoles[j].showError("This role does not satisfie any roleplayer-constraint!"); + } + for(var j = 0; j !== currentRpcs.length; ++j){ + var players = currentRpcs[i].players; + var pType = currentRpcs[i].playerType.flatten(); + cardMin = parseInt(currentRpcs[i].cardMin); + cardMax = currentRpcs[i].cardMax === "MAX_INT" ? "*" : parseInt(currentRpcs[i].cardMax); + var foundRoles = this.getExistingRoles(rType, players, currentRoles); + if(cardMin > foundRoles.length){ + ret = false; + if(errorStr.length !== 0) errorStr += "

"; + errorStr += "card-min of the roleplayer-constraint card-min: " + cardMin + " card-max: " + cardMax + " for the roletype \"" + rType + " and the playertype \"" + pType + "\" is not satisfied (" + foundRoles.length + ")!"; + } + if(cardMax !== "*" && cardMax < foundRoles.length){ + ret = false; + if(errorStr.length !== 0) errorStr += "

"; + errorStr += "card-max of the roleplayer-constraint card-min: " + cardMin + " card-max: " + cardMax + " for the roletype \"" + rType + " and the playertype \"" + pType + "\" is not satisfied (" + foundRoles.length + ")!"; + } + // --- marks all found roles from "allAroles" + for(var k = 0; k !== foundRoles.length; ++k) checkedRoles.push(foundRoles[k]); + } + } + + // --- checks roles that does not belong to any constraint + for(var i = 0; i !== checkedRoles.length; ++i) allAroles = allAroles.without(checkedRoles[i]); + + if(allAroles.length !== 0){ + for(var i = 0; i !== allAroles.length; ++i) allAroles[i].showError("This role does not satisfie any associationrole- or roleplayer-constraints!"); + } + + // --- checks otherrole-constraints + // --- collects all neede otherrole-constraints + var usedOrcs = new Array(); + allAroles = allAroles2; + for(var i = 0; i !== allAroles.length; ++i){ + usedOrcs = usedOrcs.concat(getOtherRoleConstraintsForRole(new Array(allAroles[i].getType()), new Array(allAroles[i].getPlayer()), orcs)); + } + + checkedRole = new Array(); + for(var i = 0; i !== usedOrcs.length; ++i){ + var players = usedOrcs[i].otherPlayers; + var pType = usedOrcs[i].otherPlayerType; + var rType = usedOrcs[i].otherRoleType; + var cardMin = parseInt(usedOrcs[i].cardMin); + var cardMax = usedOrcs[i].cardMax === "MAX_INT" ? "*" : parseInt(usedOrcs[i].cardMax); + var foundRoles = this.getExistingRoles(rType, players, allOroles); + checkedRoles = checkedRoles.concat(foundRoles); + if(cardMin > foundRoles.length){ + ret = false; + if(errorStr.length !== 0) errorStr += "

"; + errorStr += "card-min of the otherrole-constraint card-min: " + cardMin + " card-max: " + cardMax + " for the roletype \"" + rType + " and the playertype \"" + pType + "\" is not satisfied (" + foundRoles.length + ")!"; + } + if(cardMax !== "*" && cardMax < foundRoles.length){ + ret = false; + if(errorStr.length !== 0) errorStr += "

"; + errorStr += "card-max of the otherrole-constraint card-min: " + cardMin + " card-max: " + cardMax + " for the roletype \"" + rType + " and the playertype \"" + pType + "\" is not satisfied (" + foundRoles.length + ")!"; + } + } + + + if(ret === false) this.showError(errorStr); + else this.hideError(); + return ret; }}); @@ -2255,12 +2677,13 @@ if(!owner) throw "From NameC(): owner must be set but is null"; if(!owner.__frames__) owner.__frames__ = new Array(); owner.__frames__.push(this); - + this.__frame__.writeAttribute({"class" : CLASSES.associationFrame()}); this.__table__ = new Element("table", {"class" : CLASSES.associationFrame()}); this.__frame__.insert({"top" : this.__table__}); this.__constraints__ = constraints; this.__contents__ = contents; + this.__constraints__ = constraints; this.__owner__ = owner; this.__dblClickHandler__ = dblClickHandlerF; @@ -2357,10 +2780,10 @@ ",\"roles\":" + this.__roles__.toJSON() + "}"; }, "isValid" : function(){ - // TODO: implement - return true; + return this.__roles__.isValid(); }, "disable" : function(){ + this.hideError(); this.__itemIdentity__.disable(); this.__roles__.disable(); this.__type__.__frames__[0].disable(); @@ -2394,7 +2817,6 @@ this.__frame__.insert({"top" : this.__table__}); this.__caption__ = new Element("caption", {"class" : CLASSES.clickable()}).update("Associations"); this.__table__.insert({"top" : this.__caption__}) - this.__container__ = new Object(); for(var i = 0; contents && i != contents.length; ++i){ @@ -2443,8 +2865,13 @@ return associations.substring(0, associations.length - 1) + "]"; }, "isValid" : function(){ - // TODO: implement - return true; + var ret = true; + for(var i = 0; i !== this.__container__.__frames__.length; ++i){ + if(this.__container__.__frames__[i].isUsed() === true && this.__container__.__frames__[i].isValid() === false) + ret = false; + } + + return ret; }, "minimize" : function(){ var rows = this.__table__.select("tr." + CLASSES.associationFrame()); @@ -2483,7 +2910,7 @@ // --- Representation of a topic map if frame. -var tmIdC = Class.create(ContainerC, {"initialize" : function($super, contents){ +var TmIdC = Class.create(ContainerC, {"initialize" : function($super, contents){ $super(); try{ this.__frame__.writeAttribute({"class" : CLASSES.itemIdentityFrame()}); @@ -2493,7 +2920,7 @@ this.__frame__.insert({"top" : this.__table__}); this.__caption__ = new Element("caption", {"class" : CLASSES.clickable()}).update("Topic Map ID"); this.__table__.update(this.__caption__); - var value = contents && contents.length !== 0 ? contents[0] : ""; + var value = contents && contents.length !== 0 ? decodeURI(contents[0]) : ""; this.__contentrow__ = new Element("input", {"type" : "text", "value" : value}); this.__tr__ = new Element("tr", {"class" : CLASSES.tmIdFrame()}); var td =new Element("td", {"class" : CLASSES.content()}); @@ -2515,13 +2942,20 @@ }, "getContent" : function(){ if(this.__contentrow__.value.strip().length === 0) return null; - return new Array(this.__contentrow__.value.strip()); + return new Array(encodeURI(this.__contentrow__.value.strip())); }, "toJSON" : function(){ return (this.getContent() === null ? "null" : this.getContent().toJSON()); }, "isValid" : function(){ - return this.getContent() !== null; + if(this.getContent() !== null){ + this.hideError(); + return true; + } + else { + this.showError("Please enter a Topic Map ID!"); + return false; + } }, "minimize": function(){ if(this.__minimized__ === false) this.__tr__.hide(); From lgiessmann at common-lisp.net Thu Jun 18 13:29:57 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Thu, 18 Jun 2009 09:29:57 -0400 Subject: [isidorus-cvs] r46 - trunk/src/ajax/javascripts Message-ID: Author: lgiessmann Date: Thu Jun 18 09:29:56 2009 New Revision: 46 Log: ajax-client: all ajax-requests have a timeout depending on the data to be commited or requested - the minimum timeout is set by the constant "TIMEOUT" Modified: trunk/src/ajax/javascripts/requests.js Modified: trunk/src/ajax/javascripts/requests.js ============================================================================== --- trunk/src/ajax/javascripts/requests.js (original) +++ trunk/src/ajax/javascripts/requests.js Thu Jun 18 09:29:56 2009 @@ -10,6 +10,29 @@ //+----------------------------------------------------------------------------- +// --- Sets a timeout function which alerts a message. +function setAjaxTimeout(time, url) +{ + return setTimeout(function(){ + alert("The AJAX request for \"" + url + "\" timed out. Please check your network connection!"); + }, time); +} + + +// --- Returns a function whihc can be used as an XHR-Handler. +// --- The returned function is the passed handler wrapped in +// --- a lambda-function which additionally clears the passed timeout +// --- function. +function createXHRHandler(handler, timeFun) +{ + function fun(xhr){ + clearTimeout(timeFun); + handler(xhr); + } + return fun; +} + + // --- This is the default error handler of the used ajax.requests. function defaultFailureHandler(xhr) { @@ -23,12 +46,13 @@ { try{ var onFailure = onFailureHandler ? onFailureHandler : defaultFailureHandler; - + var timeFun = setAjaxTimeout(TIMEOUT, TYPE_PSIS_URL); + new Ajax.Request(TYPE_PSIS_URL, { "method" : "get", "requestHeaders" : ["If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT"], - "onSuccess" : onSuccessHandler, - "onFailure" : onFailure}); + "onSuccess" : createXHRHandler(onSuccessHandler, timeFun), + "onFailure" : createXHRHandler(onFailure, timeFun)}); } catch(err){ alert("Could not request all type PSIs, please try again!\n\n" + err); @@ -42,12 +66,13 @@ { try{ var onFailure = onFailureHandler ? onFailureHandler : defaultFailureHandler; - + var timeFun = setAjaxTimeout(TIMEOUT, TMCL_TYPE_URL); + new Ajax.Request(TMCL_TYPE_URL, { "method" : "post", "postBody" : psis, - "onSuccess" : onSuccessHandler, - "onFailure" : onFailure}); + "onSuccess" : createXHRHandler(onSuccessHandler, timeFun), + "onFailure" : createXHRHandler(onFailure, timeFun)}); } catch(err){ alert("Could not request contraints, please try again!\n\n" + err); @@ -108,17 +133,19 @@ } +// --- Sends a POST-Message to the server with the fragment data which hast to be committed. function commitFragment(json, onSuccessHandler, onFailureHandler) { if(!json || !onSuccessHandler) throw "From commitFragment(): json and onSuccessHandler must be set!"; try{ var onFailure = onFailureHandler ? onFailureHandler : defaultFailureHandler; + var timeFun = setAjaxTimeout(TIMEOUT, COMMIT_URL); new Ajax.Request(COMMIT_URL, { "method" : "post", "postBody" : json, - "onSuccess" : onSuccessHandler, - "onFailure" : onFailure}); + "onSuccess" : createXHRHandler(onSuccessHandler, timeFun), + "onFailure" : createXHRHandler(onFailure, timeFun)}); } catch(err){ alert("From commitFragment(): " + err); From lgiessmann at common-lisp.net Thu Jun 18 15:05:10 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Thu, 18 Jun 2009 11:05:10 -0400 Subject: [isidorus-cvs] r47 - in trunk/src/ajax: css javascripts Message-ID: Author: lgiessmann Date: Thu Jun 18 11:05:08 2009 New Revision: 47 Log: ajax-client: fixed a bug with exclusive-instance-constraints; changes: associations created from constraints are initialy disabled; during ajax-requests there will be hidden the entire content. instead of the content there will be shown a message with some information what the client is doing at the moment - but this should be displaced by a loader-gif or something Modified: trunk/src/ajax/css/main.css trunk/src/ajax/javascripts/constants.js trunk/src/ajax/javascripts/create.js trunk/src/ajax/javascripts/datamodel.js trunk/src/ajax/javascripts/requests.js Modified: trunk/src/ajax/css/main.css ============================================================================== --- trunk/src/ajax/css/main.css (original) +++ trunk/src/ajax/css/main.css Thu Jun 18 11:05:08 2009 @@ -47,6 +47,12 @@ } .errorMessage { + margin: 0.5em; color: red; font-size: 0.85em; +} + +div.loadFrame { + padding: 2em; + color: #ff7f00; } \ No newline at end of file Modified: trunk/src/ajax/javascripts/constants.js ============================================================================== --- trunk/src/ajax/javascripts/constants.js (original) +++ trunk/src/ajax/javascripts/constants.js Thu Jun 18 11:05:08 2009 @@ -32,6 +32,9 @@ var STRING = "http://www.w3.org/2001/XMLSchema#string"; var CURRENT_TOPIC = "**current-topic**"; var CURRENT_TOPIC_ESCAPED = "\\*\\*current-topic\\*\\*"; +var INIT_DATE = ["If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT"]; +var MAX_INT = "MAX_INT"; +var MMAX_INT = "*"; // --- Contains most css classes used in this project // --- There should be called only the function to be sure to don't override @@ -77,6 +80,7 @@ "__divFog__" : "fog", "__inputCommitButton__" : "commitButton", "__divTmIdFrame__" : "tmIdFrame", + "__divLoad__" : "loadFrame", "page" : function(){ return this.__divPage__; }, "subPage" : function(){ return this.__divSubPage__; }, @@ -117,5 +121,6 @@ "deselect" : function(){ return this.__spanDeselect__; }, "fog" : function(){ return this.__divFog__; }, "commitButton" : function(){ return this.__inputCommitButton__; }, - "tmIdFrame" : function(){ return this.__divTmIdFrame__; } + "tmIdFrame" : function(){ return this.__divTmIdFrame__; }, + "load" : function(){ return this.__divLoad__; } }; \ No newline at end of file Modified: trunk/src/ajax/javascripts/create.js ============================================================================== --- trunk/src/ajax/javascripts/create.js (original) +++ trunk/src/ajax/javascripts/create.js Thu Jun 18 11:05:08 2009 @@ -26,26 +26,7 @@ function makeInstanceOfFrame(context){ function makeFragment(psis, constraints){ - var items = $$("li." + CLASSES.topicFrame()); - for(var i = 0; i != items.length; ++i){ - items[i].remove(); - } - - items = $$("li." + CLASSES.associationContainer()); - for(var i = 0; i != items.length; ++i){ - items[i].remove(); - } - - items = $$("li." + CLASSES.tmIdFrame()); - for(var i = 0; i !== items.length; ++i){ - items[i].remove(); - } - - items = $$("li." + CLASSES.commitButton()); - for(var i = 0; i !== items.length; ++i){ - items[i].remove(); - } - + clearFragment(); var instanceOfs = new Array(); for(var i = 0; psis && i !== psis.length; ++i){ instanceOfs.push(new Array(psis[i])); @@ -115,8 +96,7 @@ var liCB = new Element("li", {"class" : CLASSES.commitButton()}); liCB.update(commitButton); liTm.insert({"after" : liCB}); - - } + } //makeFragment function onSuccessHandler(xhr){ var json = null; @@ -134,13 +114,38 @@ catch(innerErr){ alert("There occurred an error by creating an InstanceOfC frame, please reload this page!\n\n" + innerErr); } - } + } //onSuccessHandler getTypePsis(onSuccessHandler, null); - } + } //makeInstanceOfFrame makeInstanceOfFrame(liTopicSelect); }catch(err){ alert(err); } +} + + +// --- removes old elements from the fragment frame +function clearFragment() +{ + var items = $$("li." + CLASSES.topicFrame()); + for(var i = 0; i != items.length; ++i){ + items[i].remove(); + } + + items = $$("li." + CLASSES.associationContainer()); + for(var i = 0; i != items.length; ++i){ + items[i].remove(); + } + + items = $$("li." + CLASSES.tmIdFrame()); + for(var i = 0; i !== items.length; ++i){ + items[i].remove(); + } + + items = $$("li." + CLASSES.commitButton()); + for(var i = 0; i !== items.length; ++i){ + items[i].remove(); + } } \ No newline at end of file Modified: trunk/src/ajax/javascripts/datamodel.js ============================================================================== --- trunk/src/ajax/javascripts/datamodel.js (original) +++ trunk/src/ajax/javascripts/datamodel.js Thu Jun 18 11:05:08 2009 @@ -294,6 +294,7 @@ myself.__commit__.observe("click", function(event){ myself.hideError(); + clearFragment(); requestConstraints(myself.toJSON(true), onSuccessHandler, null); }); } @@ -395,7 +396,7 @@ for(var i = 0; i != constraints.length; ++i){ this.__containers__.push(new Object()); var min = parseInt(constraints[i].cardMin); - var max = constraints[i].cardMax !== "MAX_INT" ? parseInt(constraints[i].cardMax) : "*"; + var max = constraints[i].cardMax !== MAX_INT ? parseInt(constraints[i].cardMax) : MMAX_INT; if(max !== 0){ var cssTitle = "min: " + min + " max: " + max + " regular expression: " + constraints[i].regexp; for(var j = 0; j != (min === 0 ? 1 : min); ++j){ @@ -403,7 +404,7 @@ var dblClickHandler = null; if(min === 0) dblClickHandler = dblClickHandlerF; var row = new TextrowC("", constraints[i].regexp, this.__containers__[i], - min === 0 ? 1 : min, max === "*" ? -1 : max, cssTitle, dblClickHandler); + min === 0 ? 1 : min, max === MMAX_INT ? -1 : max, cssTitle, dblClickHandler); row.dblClick(); this.__error__.insert({"before" : row.getFrame()}); } @@ -470,7 +471,7 @@ for(var i = 0; i !== this.__constraints__.length; ++i){ var regexp = new RegExp(this.__constraints__[i].regexp); var cardMin = parseInt(this.__constraints__[i].cardMin); - var cardMax = this.__constraints__[i].cardMax === "MAX_INT" ? "*" : parseInt(this.__constraints__[i].cardMax); + var cardMax = this.__constraints__[i].cardMax === MAX_INT ? MMAX_INT : parseInt(this.__constraints__[i].cardMax); var currentIdentifiers = new Array(); for(var j = 0; j !== allIdentifiers.length; ++j){ if(regexp.match(allIdentifiers[j].getContent()) === true) currentIdentifiers.push(allIdentifiers[j]); @@ -482,7 +483,7 @@ errorStr += "card-min of the constraint regexp: \"" + this.__constraints__[i].regexp + "\" card-min: " + cardMin + " card-max: " + cardMax + " is not satisfied (" + cardMin + ")!
"; ret = false; } - if(cardMax !== "*" && cardMax < currentIdentifiers.length){ + if(cardMax !== MMAX_INT && cardMax < currentIdentifiers.length){ errorStr += "card-max of the constraint regexp: \"" + this.__constraints__[i].regexp + "\" card-min: " + cardMin + " card-max: " + cardMax + " is not satisfied (" + cardMax + ")!
"; ret = false; } @@ -773,7 +774,7 @@ for(var i = 0; i != constraints.length; ++i){ var scopeTypes = constraints[i].scopeTypes; var min = parseInt(constraints[i].cardMin); - var max = constraints[i].cardMax !== "MAX_INT" ? parseInt(constraints[i].cardMax) : "*"; + var max = constraints[i].cardMax !== MAX_INT ? parseInt(constraints[i].cardMax) : MMAX_INT; // TODO: check and adds contents to the types @@ -781,7 +782,7 @@ if(min === 0){ // TODO: check contents of this type scopeTypes.unshift(new Array(new Array(""))); // [[""]] } - this.__container__.push(new ScopeC(scopeTypes, min === 0 ? 1 : min, max === "*" ? -1 : max)); + this.__container__.push(new ScopeC(scopeTypes, min === 0 ? 1 : min, max === MMAX_INT ? -1 : max)); this.__error__.insert({"before" : this.__container__[this.__container__.length - 1].getFrame()}); } } @@ -1071,7 +1072,7 @@ // --- value this.__value__ = new Object(); var _min = parseInt(simpleConstraint.cardMin); - var _max = simpleConstraint.cardMax !== "MAX_INT" ? parseInt(simpleConstraint.cardMax) : "*"; + var _max = simpleConstraint.cardMax !== MAX_INT ? parseInt(simpleConstraint.cardMax) : MMAX_INT; var cssTitleV = "min: " + _min + " max: " + _max + " regular expression: " + (simpleConstraint ? simpleConstraint.regexp : ".*"); this.__cssTitle__ = cssTitle; new TextrowC((contents ? contents.value : ""), (simpleConstraint ? simpleConstraint.regexp : ".*"), this.__value__, 1, 1, cssTitleV); @@ -1179,7 +1180,7 @@ for(var j = 0; j != constraints[i].constraints.length; ++j){ this.__containers__[i].push(new Object()); var min = parseInt(constraints[i].constraints[j].cardMin); - var max = constraints[i].constraints[j].cardMax !== "MAX_INT" ? parseInt(constraints[i].constraints[j].cardMax) : "*"; + var max = constraints[i].constraints[j].cardMax !== MAX_INT ? parseInt(constraints[i].constraints[j].cardMax) : MMAX_INT; var regexp = constraints[i].constraints[j].regexp; if(max !== 0){ var dblClickHandler = null; @@ -1187,7 +1188,7 @@ var title = "min: " + min + " max: " + max + " regular expression: " + regexp; for(var k = 0; k !== (min === 0 ? 1 : min); ++k){ - var name = new NameC("", constraints[i].nametypescopes, constraints[i].constraints[j], this.__containers__[i][j], min === 0 ? 1 : min, max === "*" ? -1 : max, title, dblClickHandler); + var name = new NameC("", constraints[i].nametypescopes, constraints[i].constraints[j], this.__containers__[i][j], min === 0 ? 1 : min, max === MMAX_INT ? -1 : max, title, dblClickHandler); if(min === 0)name.disable(); this.__error__.insert({"before" : name.getFrame()}); if(min === 0)name.minimize(); @@ -1300,7 +1301,7 @@ for(var j = 0; j !== this.__constraints__[i].constraints.length; ++j){ var regexp = new RegExp(this.__constraints__[i].constraints[j].regexp); var cardMin = parseInt(this.__constraints__[i].constraints[j].cardMin); - var cardMax = this.__constraints__[i].constraints[j].cardMax === "MAX_INT" ? "*" : parseInt(this.__constraints__[i].constraints[j].cardMax); + var cardMax = this.__constraints__[i].constraints[j].cardMax === MAX_INT ? MMAX_INT : parseInt(this.__constraints__[i].constraints[j].cardMax); var matchedNames = 0; for(var k = 0; k !== currentNames.length; ++k){ if(regexp.match(currentNames[k].getContent().value) === true){ @@ -1313,7 +1314,7 @@ if(errorStr.length !== 0) errorStr += "

"; errorStr += "card-min of the constraint regexp: \"" + this.__constraints__[i].constraints[j].regexp + "\" card-min: " + cardMin + " card-max: " + cardMax + " for the nametype \"" + currentConstraintTypes + " is not satisfied (" + matchedNames + ")!"; } - if(cardMax !== "*" && matchedNames > cardMax){ + if(cardMax !== MMAX_INT && matchedNames > cardMax){ ret = false; if(errorStr.length !== 0) errorStr += "

"; errorStr += "card-max of the constraint regexp: \"" + this.__constraints__[i].constraints[j].regexp + "\" card-min: " + cardMin + " card-max: " + cardMax + " for the nametype \"" + currentConstraintTypes + " is not satisfied (" + matchedNames + ")!"; @@ -1381,7 +1382,7 @@ // --- resource value and datatype var _min = parseInt(constraint.cardMin); - var _max = constraint.cardMax !== "MAX_INT" ? parseInt(constraint.cardMax) : "*"; + var _max = constraint.cardMax !== MAX_INT ? parseInt(constraint.cardMax) : MMAX_INT; var cssTitle = "min: " + _min + " max: " + _max + " regular expression: " + constraint.regexp; this.__cssTitle__ = cssTitle; makeResource(this, contents, constraint, (occurrenceTypes ? occurrenceTypes[0].datatypeConstraint : null), cssTitle); @@ -1493,7 +1494,7 @@ for(var j = 0; j != constraints[i].constraints.length; ++j){ this.__containers__[i].push(new Object()); var min = parseInt(constraints[i].constraints[j].cardMin); - var max = constraints[i].constraints[j].cardMax !== "MAX_INT" ? parseInt(constraints[i].constraints[j].cardMax) : "*"; + var max = constraints[i].constraints[j].cardMax !== MAX_INT ? parseInt(constraints[i].constraints[j].cardMax) : MMAX_INT; var regexp = constraints[i].constraints[j].regexp; if(max !== 0){ var dblClickHandler = null; @@ -1501,7 +1502,7 @@ var title = "min: " + min + " max: " + max + " regular expression: " + regexp; for(var k = 0; k !== (min === 0 ? 1 : min); ++k){ - var occurrence = new OccurrenceC("", constraints[i].occurrenceTypes, constraints[i].constraints[j], constraints[i].uniqueConstraints, this.__containers__[i][j], min === 0 ? 1 : min, max === "*" ? -1 : max, title, dblClickHandler); + var occurrence = new OccurrenceC("", constraints[i].occurrenceTypes, constraints[i].constraints[j], constraints[i].uniqueConstraints, this.__containers__[i][j], min === 0 ? 1 : min, max === MMAX_INT ? -1 : max, title, dblClickHandler); if(min === 0) occurrence.disable(); this.__error__.insert({"before" : occurrence.getFrame()}); if(min === 0)occurrence.minimize(); @@ -1572,7 +1573,7 @@ for(var j = 0; j !== this.__constraints__[i].constraints.length; ++j){ var regexp = new RegExp(this.__constraints__[i].constraints[j].regexp); var cardMin = parseInt(this.__constraints__[i].constraints[j].cardMin); - var cardMax = this.__constraints__[i].constraints[j].cardMax === "MAX_INT" ? "*" : parseInt(this.__constraints__[i].constraints[j].cardMax); + var cardMax = this.__constraints__[i].constraints[j].cardMax === MAX_INT ? MMAX_INT : parseInt(this.__constraints__[i].constraints[j].cardMax); var matchedOccurrences = 0; for(var k = 0; k !== currentOccurrences.length; ++k){ var value = currentOccurrences[k].getContent().resourceRef; @@ -1589,7 +1590,7 @@ if(errorStr.length !== 0) errorStr += "

"; errorStr += "card-min of the constraint regexp: \"" + this.__constraints__[i].constraints[j].regexp + "\" card-min: " + cardMin + " card-max: " + cardMax + " for the occurrencetype \"" + currentConstraintTypes + " is not satisfied (" + matchedOccurrences + ")!"; } - if(cardMax !== "*" && matchedOccurrences > cardMax){ + if(cardMax !== MMAX_INT && matchedOccurrences > cardMax){ ret = false; if(errorStr.length !== 0) errorStr += "

"; errorStr += "card-max of the constraint regexp: \"" + this.__constraints__[i].constraints[j].regexp + "\" card-min: " + cardMin + " card-max: " + cardMax + " for the occurrencetype \"" + currentConstraintTypes + " is not satisfied (" + matchedOccurrences + ")!"; @@ -2170,7 +2171,7 @@ if(!role || !constraint) return; var cOtherPlayers = constraint.otherPlayers; var cOtherRoleType = constraint.otherRoleType; - var cardMax = constraint.cardMax === "MAX_INT" ? "*" : parseInt(constraint.cardMax); + var cardMax = constraint.cardMax === MAX_INT ? MMAX_INT : parseInt(constraint.cardMax); var cardMin = parseInt(constraint.cardMin); var existingRoles = this.getExistingRoles(cOtherRoleType, cOtherPlayers, this.__orContainer__.__frames__); var cleanedPlayers = new Array(); @@ -2199,7 +2200,7 @@ "__checkARCButtons__" : function(rolesToCheck, players, associationRoleConstraint){ if(!rolesToCheck || !associationRoleConstraint) return; var cardMin = associationRoleConstraint.cardMin === 0 ? 1 : parseInt(associationRoleConstraint.cardMin); - var cardMax = associationRoleConstraint.cardMax === "MAX_INT" ? "*" : parseInt(associationRoleConstraint.cardMax); + var cardMax = associationRoleConstraint.cardMax === MAX_INT ? MMAX_INT : parseInt(associationRoleConstraint.cardMax); var lenPlayers = players ? players.length : 0; if(cardMin < rolesToCheck.length) { for(var i = 0; i !== rolesToCheck.length; ++i) rolesToCheck[i].showRemoveButton(); @@ -2208,7 +2209,7 @@ for(var i = 0; i !== rolesToCheck.length; ++i) rolesToCheck[i].hideRemoveButton(); } - if(cardMax === "*" || cardMax > rolesToCheck.length && rolesToCheck.length < lenPlayers){ + if(cardMax === MMAX_INT || cardMax > rolesToCheck.length && rolesToCheck.length < lenPlayers){ for(var i = 0; i !== rolesToCheck.length; ++i) rolesToCheck[i].showAddButton(); } else { @@ -2222,7 +2223,7 @@ function addHandler(myself){ var cOtherPlayers = currentConstraint.otherPlayers; var cOtherRoleType = currentConstraint.otherRoleType; - var cardMax = currentConstraint.cardMax === "MAX_INT" ? "*" : parseInt(currentConstraint.cardMax); + var cardMax = currentConstraint.cardMax === MAX_INT ? MMAX_INT : parseInt(currentConstraint.cardMax); var cardMin = currentConstraint.cardMin === 0 ? 1 : parseInt(currentConstraint.cardMin); var cardMinOrg = parseInt(currentConstraint.cardMin);; var existingRoles = roleContainer.getExistingRoles(cOtherRoleType, cOtherPlayers, roleContainer.__orContainer__.__frames__); @@ -2260,7 +2261,7 @@ function removeHandler(myself){ var cOtherPlayers = currentConstraint.otherPlayers; var cOtherRoleType = currentConstraint.otherRoleType; - var cardMax = currentConstraint.cardMax === "MAX_INT" ? "*" : parseInt(currentConstraint.cardMax); + var cardMax = currentConstraint.cardMax === MAX_INT ? MMAX_INT : parseInt(currentConstraint.cardMax); var cardMin = currentConstraint.cardMin === 0 ? 1 : parseInt(currentConstraint.cardMin); var playerToAdd = null; for(var i = 0; i !== cOtherPlayers.length; ++i){ @@ -2283,7 +2284,7 @@ if(!existingRoles) return; // --- checks all control buttons after an add or remove operation - if(cardMax !== "*" && existingRoles.length >= cardMax){ + if(cardMax !== MMAX_INT && existingRoles.length >= cardMax){ for(var i = 0; i !== existingRoles.length; ++i){ existingRoles[i].hideAddButton(); } @@ -2319,9 +2320,9 @@ } // --- creates a new role - var cardMax = associationRoleConstraint.cardMax === "MAX_INT" ? "*" : parseInt(associationRoleConstraint.cardMax); + var cardMax = associationRoleConstraint.cardMax === MAX_INT ? MMAX_INT : parseInt(associationRoleConstraint.cardMax); var cardMin = parseInt(associationRoleConstraint.cardMin); - if(cardMax === "*" || cardMax > rolesToCheck.length){ + if(cardMax === MMAX_INT || cardMax > rolesToCheck.length){ var usedPlayers = new Array(); for(var i = 0; i !== rolesToCheck.length; ++i) usedPlayers.push(rolesToCheck[i].getPlayer()); var cleanedPlayers = cleanPlayers(players ? players : new Array(), usedPlayers); @@ -2582,7 +2583,7 @@ var currentRoles = new Array(); var rType = arcs[i].roleType.flatten(); var cardMin = parseInt(arcs[i].cardMin); - var cardMax = arcs[i].cardMax === "MAX_INT" ? "*" : parseInt(arcs[i].cardMax); + var cardMax = arcs[i].cardMax === MAX_INT ? MMAX_INT : parseInt(arcs[i].cardMax); // --- collects all roles for the current constraint for(var j = 0; j !== allAroles.length; ++j){ @@ -2595,7 +2596,7 @@ if(errorStr.length !== 0) errorStr += "

"; errorStr += "card-min of the associationrole-constraint card-min: " + cardMin + " card-max: " + cardMax + " for the roletype \"" + rType + " is not satisfied (" + currentRoles.length + ")!"; } - if(cardMax !== "*" && cardMax < currentRoles.length){ + if(cardMax !== MMAX_INT && cardMax < currentRoles.length){ ret = false; if(errorStr.length !== 0) errorStr += "

"; errorStr += "card-max of the associationrole-constraint card-min: " + cardMin + " card-max: " + cardMax + " for the roletype \"" + rType + " is not satisfied (" + currentRoles.length + ")!"; @@ -2611,14 +2612,14 @@ var players = currentRpcs[i].players; var pType = currentRpcs[i].playerType.flatten(); cardMin = parseInt(currentRpcs[i].cardMin); - cardMax = currentRpcs[i].cardMax === "MAX_INT" ? "*" : parseInt(currentRpcs[i].cardMax); + cardMax = currentRpcs[i].cardMax === MAX_INT ? MMAX_INT : parseInt(currentRpcs[i].cardMax); var foundRoles = this.getExistingRoles(rType, players, currentRoles); if(cardMin > foundRoles.length){ ret = false; if(errorStr.length !== 0) errorStr += "

"; errorStr += "card-min of the roleplayer-constraint card-min: " + cardMin + " card-max: " + cardMax + " for the roletype \"" + rType + " and the playertype \"" + pType + "\" is not satisfied (" + foundRoles.length + ")!"; } - if(cardMax !== "*" && cardMax < foundRoles.length){ + if(cardMax !== MMAX_INT && cardMax < foundRoles.length){ ret = false; if(errorStr.length !== 0) errorStr += "

"; errorStr += "card-max of the roleplayer-constraint card-min: " + cardMin + " card-max: " + cardMax + " for the roletype \"" + rType + " and the playertype \"" + pType + "\" is not satisfied (" + foundRoles.length + ")!"; @@ -2649,7 +2650,7 @@ var pType = usedOrcs[i].otherPlayerType; var rType = usedOrcs[i].otherRoleType; var cardMin = parseInt(usedOrcs[i].cardMin); - var cardMax = usedOrcs[i].cardMax === "MAX_INT" ? "*" : parseInt(usedOrcs[i].cardMax); + var cardMax = usedOrcs[i].cardMax === MAX_INT ? MMAX_INT : parseInt(usedOrcs[i].cardMax); var foundRoles = this.getExistingRoles(rType, players, allOroles); checkedRoles = checkedRoles.concat(foundRoles); if(cardMin > foundRoles.length){ @@ -2657,7 +2658,7 @@ if(errorStr.length !== 0) errorStr += "

"; errorStr += "card-min of the otherrole-constraint card-min: " + cardMin + " card-max: " + cardMax + " for the roletype \"" + rType + " and the playertype \"" + pType + "\" is not satisfied (" + foundRoles.length + ")!"; } - if(cardMax !== "*" && cardMax < foundRoles.length){ + if(cardMax !== MMAX_INT && cardMax < foundRoles.length){ ret = false; if(errorStr.length !== 0) errorStr += "

"; errorStr += "card-max of the otherrole-constraint card-min: " + cardMin + " card-max: " + cardMax + " for the roletype \"" + rType + " and the playertype \"" + pType + "\" is not satisfied (" + foundRoles.length + ")!"; @@ -2835,6 +2836,7 @@ td.update(association.getFrame()); tr.update(td); this.__table__.insert({"bottom" : tr}); + association.disable(); } function setMinimizeHandler(myself){ myself.__caption__.observe("click", function(event){ Modified: trunk/src/ajax/javascripts/requests.js ============================================================================== --- trunk/src/ajax/javascripts/requests.js (original) +++ trunk/src/ajax/javascripts/requests.js Thu Jun 18 11:05:08 2009 @@ -10,6 +10,8 @@ //+----------------------------------------------------------------------------- + + // --- Sets a timeout function which alerts a message. function setAjaxTimeout(time, url) { @@ -26,13 +28,32 @@ function createXHRHandler(handler, timeFun) { function fun(xhr){ - clearTimeout(timeFun); - handler(xhr); + try{ + clearTimeout(timeFun); + var loading = $$("div." + CLASSES.load()); + if(loading.length === 1) loading[0].remove(); + var content = $$("div." + CLASSES.content()); + if(content.length === 1) content[0].show(); + handler(xhr); + } + catch(err) {alert("err: " + err); } } return fun; } +function onLoad(text) +{ + var div = new Element("div", {"class" : CLASSES.load()}).update(content); + var content = $$("div." + CLASSES.content()); + if(content.length === 1){ + content[0].hide(); + var load = new Element("div", {"class" : CLASSES.load()}).update(text); + content[0].insert({"before" : load}); + } +} + + // --- This is the default error handler of the used ajax.requests. function defaultFailureHandler(xhr) { @@ -47,10 +68,11 @@ try{ var onFailure = onFailureHandler ? onFailureHandler : defaultFailureHandler; var timeFun = setAjaxTimeout(TIMEOUT, TYPE_PSIS_URL); + onLoad("Requesting all Type PSIs"); new Ajax.Request(TYPE_PSIS_URL, { "method" : "get", - "requestHeaders" : ["If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT"], + "requestHeaders" : INIT_DATE, "onSuccess" : createXHRHandler(onSuccessHandler, timeFun), "onFailure" : createXHRHandler(onFailure, timeFun)}); } @@ -67,6 +89,7 @@ try{ var onFailure = onFailureHandler ? onFailureHandler : defaultFailureHandler; var timeFun = setAjaxTimeout(TIMEOUT, TMCL_TYPE_URL); + onLoad("Requesting all constraints for psis:\
" + psis.gsub("\\[", "").gsub("\\]", "")); new Ajax.Request(TMCL_TYPE_URL, { "method" : "post", @@ -89,12 +112,13 @@ try{ var topicStubs = new Array(); - if(psis){ + if(psis && psis.length !== 0){ + onLoad("Requesting topicStubs information for
" + psis); for(var i = 0; i !== psis.length; ++i){ var url = GET_STUB_PREFIX + psis[i].gsub("#", "%23"); new Ajax.Request(url, { "method" : "get", - "requestHeaders" : ["If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT"], + "requestHeaders" : INIT_DATE, "onSuccess" : function(xhr){ if(xhr.responseText.length === 0 || xhr.responseText.isJSON() === false) errorHandler("Got bad JSON-Data for \"" + psis[i] + "\"!"); else topicStubs.push(xhr.responseText); @@ -116,11 +140,21 @@ neededTime += delta; if(delta > maxTimeout && psis && psis.length !== 0){ alert("From getTopicStubs(): Please check your network-connection - the request timed out!!!"); + var loading = $$("div." + CLASSES.load()); + if(loading.length === 1) loading[0].remove(); + var content = $$("div." + CLASSES.content()); + if(content.length === 1) content[0].show(); onFailureHandler(); return; } - if(topicStubs.length === psis.length) onSuccessHandler(topicStubs); + if(topicStubs.length === psis.length){ + var loading = $$("div." + CLASSES.load()); + if(loading.length === 1) loading[0].remove(); + var content = $$("div." + CLASSES.content()); + if(content.length === 1) content[0].show(); + onSuccessHandler(topicStubs); + } else setTimeout(checkRequests, delta); } @@ -140,6 +174,7 @@ try{ var onFailure = onFailureHandler ? onFailureHandler : defaultFailureHandler; var timeFun = setAjaxTimeout(TIMEOUT, COMMIT_URL); + onLoad("Committing current fragment to " + COMMIT_URL); new Ajax.Request(COMMIT_URL, { "method" : "post", From lgiessmann at common-lisp.net Thu Jun 18 15:06:47 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Thu, 18 Jun 2009 11:06:47 -0400 Subject: [isidorus-cvs] r48 - trunk/src/ajax/javascripts Message-ID: Author: lgiessmann Date: Thu Jun 18 11:06:47 2009 New Revision: 48 Log: added two .GIFs which will be used as ajax-loader-animations Added: trunk/src/ajax/javascripts/ajaxLoader_big.gif (contents, props changed) trunk/src/ajax/javascripts/ajaxLoader_small.gif (contents, props changed) Added: trunk/src/ajax/javascripts/ajaxLoader_big.gif ============================================================================== Binary file. No diff available. Added: trunk/src/ajax/javascripts/ajaxLoader_small.gif ============================================================================== Binary file. No diff available. From lgiessmann at common-lisp.net Thu Jun 18 17:30:48 2009 From: lgiessmann at common-lisp.net (Lukas Giessmann) Date: Thu, 18 Jun 2009 13:30:48 -0400 Subject: [isidorus-cvs] r49 - in trunk: docs src/ajax src/ajax/css src/ajax/javascripts Message-ID: Author: lgiessmann Date: Thu Jun 18 13:30:48 2009 New Revision: 49 Log: ajax-client: during AJAX-requests the client hides all current sub-content and shows a GIF representing a loader with a message what the client is currently doing Modified: trunk/docs/JSON_model.pdf trunk/src/ajax/css/main.css trunk/src/ajax/isidorus.html trunk/src/ajax/javascripts/constants.js trunk/src/ajax/javascripts/requests.js Modified: trunk/docs/JSON_model.pdf ============================================================================== Binary files. No diff available. Modified: trunk/src/ajax/css/main.css ============================================================================== --- trunk/src/ajax/css/main.css (original) +++ trunk/src/ajax/css/main.css Thu Jun 18 13:30:48 2009 @@ -55,4 +55,10 @@ div.loadFrame { padding: 2em; color: #ff7f00; + text-align: center; +} + +img.ajaxLoader { + display: none; + margin-left: 412px; /* the image has a width of 100px */ } \ No newline at end of file Modified: trunk/src/ajax/isidorus.html ============================================================================== --- trunk/src/ajax/isidorus.html (original) +++ trunk/src/ajax/isidorus.html Thu Jun 18 13:30:48 2009 @@ -57,6 +57,7 @@
+ ajax loader