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 + ")!<br/>"; + 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 + ")!<br/>"; + 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 += "<br/><br/>"; + 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 += "<br/><br/>"; + 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 += "<br/><br/>"; + 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 += "<br/><br/>"; + 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 += "<br/><br/>"; + 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 += "<br/><br/>"; + 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 += "<br/><br/>"; + 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 += "<br/><br/>"; + 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 += "<br/><br/>"; + 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 += "<br/><br/>"; + 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();