isidorus-cvs
Threads by month
- ----- 2025 -----
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
May 2009
- 1 participants
- 5 discussions

[isidorus-cvs] r32 - in trunk: docs src/ajax/javascripts src/json src/rest_interface src/unit_tests src/xml
by Lukas Giessmann 31 May '09
by Lukas Giessmann 31 May '09
31 May '09
Author: lgiessmann
Date: Sun May 31 09:08:00 2009
New Revision: 32
Log:
some fixes in the json-tmcl module and the json-data-model, some new developments in the ajax module
Added:
trunk/docs/JSON_model.pdf (contents, props changed)
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/json/json_tmcl.lisp
trunk/src/json/json_tmcl_validation.lisp
trunk/src/rest_interface/set-up-json-interface.lisp
trunk/src/unit_tests/poems.xtm
trunk/src/xml/setup.lisp
Added: trunk/docs/JSON_model.pdf
==============================================================================
Binary file. No diff available.
Modified: trunk/docs/xtm_json.txt
==============================================================================
--- trunk/docs/xtm_json.txt (original)
+++ trunk/docs/xtm_json.txt Sun May 31 09:08:00 2009
@@ -1,4 +1,4 @@
-//+-----------------------------------------------------------------------------
+//+-----------------------------------------------------------------------------
//+ Overview:
//+ *Part 1: XTM - data model
//+ *Part 2: Object summaries
@@ -6,8 +6,6 @@
//+-----------------------------------------------------------------------------
-
-
//+-----------------------------------------------------------------------------
//+ Part 1: XTM - data model:
//+ The first part describes the xtm's data model, here will be all elements
@@ -112,7 +110,6 @@
"roles" : [ { <role> }, { <...> } ]
}
-
//+-----------------------------------------------------------------------------
//+ topicStub
//+-----------------------------------------------------------------------------
@@ -173,7 +170,6 @@
}
-
//+-----------------------------------------------------------------------------
//+ Part 3: TMCL - data model
//+ This part explains how the tmcl-rules/suggestions of isidorus are
@@ -198,13 +194,13 @@
//+ constraint, a cardMin member with the minimum cardinality of
//+ the referenced element which is represented as an unsignedInt
//+ and a cardMax member which describes the maximum cardinality of this
-//+ element, this member contains an unsigendInt or the string
+//+ element, this member contains an unsignedInt or the string
//+ "MAX_INT".
//+-----------------------------------------------------------------------------
{
"regexp" : "regular expression",
"cardMin" : "unsigned integer in string representation",
- "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+ "cardMax" : "unsigned integer in string representation or the string MAX_INT"
}
@@ -214,7 +210,7 @@
//+ subjectIdentifier, a cardMin member with the minimum cardinality of
//+ this subjectIdentifier in a topic which is represented as an unsignedInt
//+ and a cardMax member which describes the maximum cardinality of this
-//+ subjectIdentifier, this member contains an unsigendInt or the string
+//+ subjectIdentifier, this member contains an unsignedInt or the string
//+ "MAX_INT".
//+-----------------------------------------------------------------------------
<simpleConstraint>
@@ -226,7 +222,7 @@
//+ subjectLocator, a cardMin member with the minimum cardinality of
//+ this subjectLocator in a topic which is represented as an unsignedInt
//+ and a cardMax member which describes the maximum cardinality of this
-//+ subjectLocator, this member contains an unsigendInt or the string
+//+ subjectLocator, this member contains an unsignedInt or the string
//+ "MAX_INT".
//+-----------------------------------------------------------------------------
<simpleConstraint>
@@ -246,7 +242,7 @@
{
"scopeTypes" : [ [ [ "psi-1-1", "psi-1-2", "..." ], [ "subtype-psi-1", "..." ], <...> ], [ "psi-2-1" "..."], <...> ],
"cardMin" : "unsigned integer in string representation",
- "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+ "cardMax" : "unsigned integer in string representation or the string MAX_INT"
}
@@ -254,13 +250,20 @@
//+ topicNameConstraint
//+ nametypescope constains the original nametype and all valid subtypes
//+ with the specific scope constraints.
-//+ constriants contains the constraints for the owner topic.
+//+ constraints contains the constraints for the owner topic.
+//+ Note scopeConstraints is a list, because, the can be more scope
+//+ constriants, e.g. one constraints wants 2 scopes of the type "en", and
+//+ "de", and another, wants 3 scopes of the type "fr", "pl" and "sp".
//+-----------------------------------------------------------------------------
{
"nametypescopes" : [ {
"nameType" : [psi-1, psi-2, "..." ],
"scopeConstraints" : [ <scopeConstraints> ]
},
+ {
+ "nameType" : [subtype-1-psi-1, subtype-1-psi-2, "..." ],
+ "scopeConstraints" : [ <scopeConstraints> ]
+ },
<...>
]
"constraints" : [ <simpleConstraint>, < ... > ]
@@ -299,10 +302,15 @@
"scopeConstraints" : [ <scopeConstraints> ],
"datatypeConstraint" : "datatype"
},
+ {
+ "occurrenceType" : [ "subtype-1-psi-1", "subtype-1-psi-2", "..." ],
+ "scopeConstraints" : [ <scopeConstraints> ],
+ "datatypeConstraint" : "datatype"
+ },
<...>
],
"constraints" : [ <simpleConstraints>, <...>],
- "uniqueConstraint" : [ <uniqueConstraints>, <...> ]
+ "uniqueConstraints" : [ <uniqueConstraints>, <...> ]
}
@@ -316,7 +324,7 @@
{
"roleType" : [ [ "topic-psi-1", "topic-psi-2", "..." ], ["subtype-1-psi-1", "..."], <...> ],
"cardMin" : "unsigned integer in string representation",
- "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+ "cardMax" : "unsigned integer in string representation or the string MAX_INT"
}
@@ -335,7 +343,7 @@
"players" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "topic-2-psi-1", "..."], <...> ]
"roleTypes" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-psi-1", "..." ], <...> ],
"cardMin" : "unsigned integer in string representation",
- "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+ "cardMax" : "unsigned integer in string representation or the string MAX_INT"
}
@@ -353,7 +361,7 @@
"otherRoleType" : [ "topic-psi-1", "topic-psi-2", "..." ],
"otherPlayerType" : [ "topic-psi-1", "topic-psi-2", "..." ],
"cardMin" : "unsigned integer in string representation",
- "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+ "cardMax" : "unsigned integer in string representation or the string MAX_INT"
}
@@ -368,6 +376,7 @@
//+ associationTypeScopes contains all available scopes for this association.
//+-----------------------------------------------------------------------------
{
+ "associationType" : [ "topic-psi-1", "topic-psi-2" ],
"associationRoleConstraints" : [ <associationRoleConstraint>, <...> ],
"rolePlayerConstraints" : [ <rolePlayerConstraints>, <...> ],
"otherRoleConstraints" : [ <otherRoleConstraint>, <...> ],
@@ -378,6 +387,8 @@
//+-----------------------------------------------------------------------------
//+ topicConstraint
//+ The topicConstraint contains the members:
+//+ *exclusiveInstances which contains a topic-list of topic-psis depending
+//+ on the users exclusive-instance-constraints
//+ *subjectIdentifierConstraints which defines the subjectIdentifiers
//+ *subjectLocatorConstraints which defines the subjectLocators
//+ *topicNameConstraints which defines the topic names
@@ -398,9 +409,7 @@
//+-----------------------------------------------------------------------------
//+ fragmentConstraint
//+ This JSON-Object contains all constraints necessary for an entire
-//+ fragment but not the exclusive-instance-constraint.
-//+ The exclusive-instance-constraint should be sent before a
-//+ fragmentConstraint separately.
+//+ fragment.
//+ topicConstraint contains an object with all constraints of all baseTypes
//+ of the mainTopic.
//+ associationConstraints contains a list of all association constraints
Modified: trunk/src/ajax/javascripts/constants.js
==============================================================================
--- trunk/src/ajax/javascripts/constants.js (original)
+++ trunk/src/ajax/javascripts/constants.js Sun May 31 09:08:00 2009
@@ -59,10 +59,18 @@
"__trShowHiddenRows__" : "showHiddenRows",
"__trTypeFrame__" : "typeFrame",
"__divScopeFrame__" : "scopeFrame",
+ "__divScopeContainer__" : "scopeContainer",
"__divValueFrame__" : "valueFrame",
"__divVariantFrame__" : "variantFrame",
"__divVariantContainer__" : "variantContainer",
"__divDatatypeFrame__" : "datatypeFrame",
+ "__divOccurrenceContainer__" : "occurrenceContainer",
+ "__divOccurrenceFrame__" : "occurrenceFrame",
+ "__divAssociationContainer__" : "associationContainer",
+ "__divAssociationFrame__" : "associationFrame",
+ "__divRoleContainer__" : "roleContainer",
+ "__divRoleFrame__" : "roleFrame",
+ "__divPlayerFrame__" : "playerFrame",
"page" : function(){ return this.__divPage__; },
"subPage" : function(){ return this.__divSubPage__; },
@@ -88,8 +96,16 @@
"showHiddenRows" : function(){ return this.__trShowHiddenRows__; },
"typeFrame" : function(){ return this.__trTypeFrame__; },
"scopeFrame" : function(){ return this.__divScopeFrame__; },
+ "scopeContainer" : function(){ return this.__divScopeContainer__; },
"valueFrame" : function(){ return this.__divValueFrame__; },
"variantFrame" : function(){ return this.__divVariantFrame__; },
"variantContainer" : function(){ return this.__divVariantContainer__; },
- "datatypeFrame" : function(){ return this.__divDatatypeFrame__; }
+ "datatypeFrame" : function(){ return this.__divDatatypeFrame__; },
+ "occurrenceContainer" : function(){ return this.__divOccurrenceContainer__; },
+ "occurrenceFrame" : function(){ return this.__divOccurrenceFrame__; },
+ "associationContainer" : function(){ return this.__divAssociationContainer__; },
+ "associationFrame" : function(){ return this.__divAssociationFrame__; },
+ "roleContainer" : function(){ return this.__divRoleContainer__; },
+ "roleFrame" : function(){ return this.__divRoleFrame__; },
+ "playerFrame" : function(){ return this.__divPlayerFrame__; }
};
\ 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 Sun May 31 09:08:00 2009
@@ -31,8 +31,18 @@
items[i].remove();
}
+ items = $$("li." + CLASSES.associationContainer());
+ for(var i = 0; i != items.length; ++i){
+ items[i].remove();
+ }
+
var topic = new TopicC(null, (constraints ? constraints.topicConstraints : null));
- context.insert({"after" : new Element("li", {"class" : CLASSES.topicFrame()}).update(topic.getFrame())});
+ var liT = new Element("li", {"class" : CLASSES.topicFrame()}).update(topic.getFrame());
+ context.insert({"after" : liT});
+
+ var associations = new AssociationContainerC(null, (constraints ? constraints.associationsConstraints : null));
+ var liA = new Element("li", {"class" : CLASSES.associationContainer()}).update(associations.getFrame());
+ liT.insert({"after" : liA});
}
function onSuccessHandler(xhr){
Modified: trunk/src/ajax/javascripts/datamodel.js
==============================================================================
--- trunk/src/ajax/javascripts/datamodel.js (original)
+++ trunk/src/ajax/javascripts/datamodel.js Sun May 31 09:08:00 2009
@@ -182,6 +182,18 @@
},
"remove" : function(){
this.getFrame().remove();
+ },
+ "showRemoveButton" : function(){
+ try{ this.__remove__.show(); } catch(err) {}
+ },
+ "hideRemoveButton" : function(){
+ try{ this.__remove__.hide(); } catch(err) {}
+ },
+ "showAddButton" : function(){
+ try{ this.__add__.show(); } catch(err) {}
+ },
+ "hideAddButton" : function(){
+ try{ this.__add__.hide(); } catch(err) {}
}});
@@ -291,36 +303,37 @@
// --- Representation of a subjectLocator and subjectIdentifier frames.
var IdentifierC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints, cssClass){
- $super();
- this.__frame__.writeAttribute({"class" : cssClass});
- this.__containers__ = new Array();
-
- try{
- if((!contents || contents.length === 0) && constraints && constraints.length > 0){
- 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) : "*";
- 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 row = new TextrowC("", constraints[i].regexp, this.__containers__[i],
- min === 0 ? 1 : min, max === "*" ? -1 : max, cssTitle);
- this.__error__.insert({"before" : row.getFrame()});
- }
+ $super();
+ this.__frame__.writeAttribute({"class" : cssClass});
+ this.__containers__ = new Array();
+
+ try{
+ if((!contents || contents.length === 0) && constraints && constraints.length > 0){
+ 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) : "*";
+ 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 row = new TextrowC("", constraints[i].regexp, this.__containers__[i],
+ min === 0 ? 1 : min, max === "*" ? -1 : max, cssTitle);
+ this.__error__.insert({"before" : row.getFrame()});
}
}
}
- else {
- // TODO: check already existing contents and order them to the corresponding fields
- }
}
- catch(err){
- alert("From IdentifierC(): " + err);
+ else {
+ // TODO: check already existing contents and order them to the corresponding fields
}
- },
- "getContent" : function(unique, removeNull){
- var values = new Array();
+ }
+ catch(err){
+ alert("From IdentifierC(): " + err);
+ }
+ },
+ "getContent" : function(unique, removeNull){
+ var values = new Array();
+ try{
for(var i = 0; i != this.__containers__.length; ++i){
for(var j = 0; j != this.__containers__[i].__frames__.length; ++j){
if(unique === true && values.indexOf(this.__containers__[i].__frames__[j].getContent()) !== -1) continue;
@@ -328,12 +341,20 @@
values.push(this.__containers__[i].__frames__[j].getContent().strip());
}
}
+ }
+ catch(err){
return values;
- },
- "isValid" : function(){
- // TODO: check the validity of this frame with the passed constraints and return a boolean value
- return true;
- }});
+ }
+ return values;
+ },
+ "toJSON" : function(unique, removeNull){
+ var content = this.getContent(unique, removeNull);
+ 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;
+ }});
// --- Represantation of a scope frame, doesn't contain SelectrowCs, because the values must be unique!
@@ -361,9 +382,18 @@
this.__contents__ = contents;
if(!contents || contents.length < min) throw "From ScopeC.resetRows(): contents.length (" +
(contents ? contents.length : "null") + ") must be > min (" + min + ")!";
- if(max !== -1 && (min > max || max === 0))throw "From FrameC(): min must be > max(" + max + ") and > 0 but is " + min;
-
+ if(max !== -1 && min > max)throw "From FrameC(): min must be > max(" + max + ") and > 0 but is " + min;
+ // --- creates an empty div element
+ if(max === 0){
+ this.getFrame().update("");
+ var div = new Element("div", {"class" : CLASSES.selectrowWithoutRemoveButton()});
+ div.insert({"top" : select});
+ this.getFrame().insert({"bottom" : div});
+ return;
+ }
+
+ // --- creates an array with all available psis
var options = new Array();
for(var i = 0; i != contents.length; ++i){
var topicPsis = new Array();
@@ -378,7 +408,7 @@
function checkValues(myself){
var rows = myself.getFrame().select("div");
var selectedItems = new Array();
- // --- collects all old selected values and removes the option elements
+ // --- collects all old selected values and removes the elements
for(var i = 0; i != rows.length; ++i){
var selects = rows[i].select("select");
if(selects[0].value.strip().length !== 0) selectedItems.push(selects[0].value);
@@ -410,6 +440,23 @@
values = cleanedValues;
}
+ // --- if there is an empty value "" (if cardMin == 0), this value should be the last
+ // --- in the array (only when there is another value selected)
+ for(var h = 0; h != rows.length; ++h){
+ var select = rows[h].select("select")[0].value;
+ if(select !== ""){
+ for(var i = 0; i != values.length; ++i){
+ for(var j = 0; j != values[i].length; ++j){
+ if(values[i][j].length === 0){
+ values[i] = values[values.length - 1];
+ values[values.length - 1] = new Array("");
+ }
+ }
+ }
+ break;
+ }
+ }
+
// --- fills all empty select elements
for(var i = 0; i != rows.length; ++i){
var select = rows[i].select("select")[0];
@@ -506,17 +553,98 @@
addHandlers(this);
}
},
+ "isUsed" : function(){
+ return this.getContent(true, true).length !== 0;
+ },
"getContent" : function(unique, removeNull){
- // --- unique and removeNull aren't be used, they exist only for consistency
var values = new Array();
- var rows = this.getFrame().select("div");
- for(var i = 0; i != rows.length; ++i){
- values.push(new Array(rows[i].select("select")[0].value)); // must be a list of lists
+ try{
+ var rows = this.getFrame().select("div");
+ for(var i = 0; i != rows.length; ++i){
+ var select = rows[i].select("select")[0].value;
+ if(unique === true && values.indexOf(select) !== -1) continue;
+ if(removeNull === true && select.length === 0) continue;
+ values.push(select);
+ }
+ }
+ catch(err){
+ return new Array();
}
return values;
- }
- });
+ }});
+
+
+
+// --- Contains all scope frames of an element (there can be more than one scope constraint)
+var ScopeContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints){
+ $super();
+ this.__frame__.writeAttribute({"class" : CLASSES.scopeContainer()});
+ this.__container__ = new Array();
+ this.resetValues(contents, constraints);
+ },
+ "resetValues" : function(contents, constraints){
+ try{
+ for(var i = 0; i != this.__container__.length; ++i){
+ this.__container__[i].remove();
+ }
+ this.__container__ = new Array();
+ }
+ catch(err){
+ this.__container__ = new Array();
+ }
+ // --- sets contents corresponding to the passed constraints
+ if(constraints && constraints.length){
+ 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) : "*";
+
+ // TODO: check and adds contents to the types
+
+ // --- if min === 0 && there is no content, adds an empty option
+ 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.__error__.insert({"before" : this.__container__[this.__container__.length - 1].getFrame()});
+ }
+ }
+ else {
+ this.getFrame().insert({"top" : new Element("div", {"class" : CLASSES.selectrowWithoutRemoveButton()})});
+ }
+ },
+ "isUsed" : function(){
+ for(var i = 0; i != this.__container__.length; ++i){
+ if(this.__container__[i].isUsed() === true) return true;
+ }
+ return false;
+ },
+ "isValid" : function(){
+ for(var i = 0; i != this.__container__.length; ++i){
+ if(this.__container__[i].isUsed() === true) return true;
+ }
+ return false;
+ },
+ "getContent" : function(){
+ var values = new Array();
+ try{
+ for(var i = 0; i != this.__container__.length; ++i){
+ var cValues = this.__container__[i].getContent(true, true);
+ for(var j = 0; j != cValues.length; ++j){
+ if(values.indexOf(cValues[j]) !== -1) continue;
+ values.push(cValues[j]);
+ }
+ }
+ }catch(err){
+ return new Array();
+ }
+ return values;
+ },
+ "toJSON" : function(){
+ if(this.getContent().length === 0) return "null";
+ return this.getContent().toJSON();
+ }});
// --- Representation of a variant element
@@ -539,27 +667,10 @@
// --- scopes
this.__scopes__ = null;
//TODO: implement -> also in the server
- this.__table__.insert({"bottom" : newRow(CLASSES.scopeFrame(), "Scope", new Element("div"))});
-
- // --- resourceValue
- var value = "";
- var datatype = "";
- if(contents && contents.resourceRef && contents.resourceRef.length !== 0){
- value = contents.resourceRef;
- datatype = ANY_URI;
- }
- else if(contents && contents.resourceData){
- value = contents.resourceData.value;
- datatype = contents.resourceData.datatype;
- }
-
- this.__value__ = new Element("textarea", {"rows" : 3}).update(value);
- this.__table__.insert({"bottom" : newRow(CLASSES.valueFrame(), "Resource Value", this.__value__)});
+ this.__table__.insert({"bottom" : newRow(CLASSES.scopeContainer(), "Scope", new Element("div"))});
- // --- datatype
- this.__datatype__ = new Object();
- new TextrowC(datatype, ".*", this.__datatype__, 1, 1, null);
- this.__table__.insert({"bottom" : newRow(CLASSES.datatypeFrame(), "Datatype", this.__datatype__.__frames__[0].getFrame())});
+ // --- resource value and datatype
+ makeResource(this, contents, null, null, null);
// --- minimize
this.minimize();
@@ -633,8 +744,7 @@
if(i === 0) trs[i].show();
else trs[i].hide();
}
- }
- });
+ }});
// --- contains all variants of a name element
@@ -708,10 +818,10 @@
// --- type
var types = new Array();
for(var i = 0; nametypescopes && i !== nametypescopes.length; ++i){
- for(j = 0; j != nametypescopes[i].nameType.length; ++j){
+ for(var j = 0; j != nametypescopes[i].nameType.length; ++j){
types.push(nametypescopes[i].nameType[j]);
if(contents && contents.type && contents.type[0] === nametypescopes[i].nameType[j]){
- var sslected = nametypescopes[i].nameType[j];
+ var selected = nametypescopes[i].nameType[j];
types[types.length - 1] = types[0];
types[0] = selected;
}
@@ -722,29 +832,16 @@
this.__table__.insert({"bottom" : tr});
// --- scopes
- this.__scopes__ = null;
- if(nametypescopes && nametypescopes[0].scopeConstraints){
- // TODO: pass the selected items seperately to the object, so they can be chosen as default
- var scopeTypes = nametypescopes[0].scopeConstraints[0].scopeTypes;
- var min = parseInt(nametypescopes[0].scopeConstraints[0].cardMin);
- var max = nametypescopes[0].scopeConstraints[0].cardMax !== "MAX_INT" ? parseInt(nametypescopes[0].scopeConstraints[0].cardMax) : "*";
- this.__scopes__ = new ScopeC(scopeTypes, min === 0 ? 1 : min, max === "*" ? -1 : max);
- tr = newRow(CLASSES.scopeFrame(), "Scope", this.__scopes__.getFrame());
- this.__table__.insert({"bottom" : tr});
- }
- else {
- var tr = new Element("tr", {"class" : CLASSES.scopeFrame()});
- var tdd = new Element("td", {"class" : CLASSES.description()}).update("Scope");
- var tdc = new Element("td", {"class" : CLASSES.content()});
- tr.insert({"top" : tdd});
- tr.insert({"bottom" : tdc});
- this.__table__.insert({"bottom" : tr});
- }
-
+ this.__scope__ = new ScopeContainerC(contents && contents.scopes ? scopes : null, nametypescopes && nametypescopes[0].scopeConstraints ? nametypescopes[0].scopeConstraints : null);
+ this.__table__.insert({"bottom" : newRow(CLASSES.scopeContainer(), "Scope", this.__scope__.getFrame())});
+ onTypeChangeScope(this, contents ? contents.scopes : null, nametypescopes, "name");
+
// --- value
this.__value__ = new Object();
- var cssTitleV = "min: " + min + " max: " + max + " regular expression: " + (simpleConstraint ? simpleConstraint.regexp : ".*");
- new TextrowC((contents && contents.value ? contents.value : ""), (simpleConstraint ? simpleConstraint.regexp : ".*"), this.__value__, 1, 1, cssTitleV);
+ 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 : ".*");
+ 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
@@ -772,7 +869,7 @@
"getContent" : function(){
if(this.isUsed() === false) return null;
return {"itemIdentities" : this.__itemIdentity__.getContent(true, true),
- "scopes" : this.__scopes__.getContent(),
+ "scopes" : this.__scope__.getContent(),
"value" : this.__value__.__frames__[0].getContent(),
"variants" : this.__variants__.getContent()};
},
@@ -780,7 +877,7 @@
if(this.isUsed() === false) return "null";
return "{\"itemIdentities\":" + this.__itemIdentity__.toJSON(true, true) +
",\"type\":[" + this.__type__.__frames__[0].toJSON() +
- "],\"scopes\":" + (this.__scopes__ ? this.__scopes__.toJSON() : "null") +
+ "],\"scopes\":" + this.__scope__.toJSON() +
",\"value\":" + this.__value__.__frames__[0].toJSON() +
",\"variants\":" + this.__variants__.toJSON() + "}";
},
@@ -789,21 +886,16 @@
this.__value__.__frames__[0].getContent().strip().length !== 0 ||
this.__variants__.getContent().length !== 0;
},
- "showRemoveButton" : function(){
- this.__remove__.show();
- },
- "hideRemoveButton" : function(){
- this.__remove__.hide();
- },
- "showAddButton" : function(){
- this.__add__.show();
- },
- "hideAddButton" : function(){
- this.__add__.hide();
- },
"isValid" : function(){
// TODO: check the content and the constraints + variants.isValid()
return true;
+ },
+ "minimize" : function(){
+ var trs = this.__table__.select("tr");
+ for(var i = 0; i != trs.length; ++i){
+ if(i === 0) trs[i].show();
+ else trs[i].hide();
+ }
}});
@@ -824,10 +916,11 @@
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 title = "min: " + min + " max: " + max + " regular expression: " + constraints[i].regexp;
+ 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.__error__.insert({"before" : name.getFrame()});
+ if(min === 0)name.minimize();
}
}
}
@@ -842,31 +935,41 @@
},
"getContent" : function(){
var values = 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){
- values.push(this.__containers__[i][j].__frames__[k].getContent());
+ try{
+ 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){
+ values.push(this.__containers__[i][j].__frames__[k].getContent());
+ }
}
}
}
+ return values;
+ }
+ catch(err){
+ return values;
}
- return values;
},
"toJSON" : function(){
- var str = "[";
- 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){
- str += this.__containers__[i][j].__frames__[k].toJSON() + ",";
+ try{
+ var str = "[";
+ 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){
+ str += this.__containers__[i][j].__frames__[k].toJSON() + ",";
+ }
}
}
}
+ if(str.endsWith(",")) str = str.slice(0, str.length - 1);
+ str += "]";
+ return str === "[]" ? null : str;
+ }
+ catch(err){
+ return "null";
}
- if(str.endsWith(",")) str = str.slice(0, str.length - 1);
- str += "]";
- return str === "[]" ? null : str;
},
"isValid" : function(){
// TODO: check the validity of this frame with the passed constraints and return a boolean value + isValid() of all names
@@ -874,64 +977,208 @@
}});
+// --- represenation of an occurrence element
+var OccurrenceC = Class.create(ContainerC, {"initialize" : function($super, contents, occurrenceTypes, constraint, uniqueConstraints, owner, min, max, cssTitle){
+ $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__});
-var OccurrenceC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints, owner, min, max, cssTitl){
-
-},
+ 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);
+ });
+
+ // --- type
+ var types = new Array();
+ for(var i = 0; occurrenceTypes && i !== occurrenceTypes.length; ++i){
+ for(var j = 0; j != occurrenceTypes[i].occurrenceType.length; ++j){
+ types.push(occurrenceTypes[i].occurrenceType[j]);
+ if(contents && contents.type && contents.type[0] === ooccurrenceTypes[i].occurrenceType[j]){
+ var selected = occurrenceTypes[i].occurrenceType[j];
+ types[types.length - 1] = types[0];
+ types[0] = selected;
+ }
+ }
+ }
+ this.__type__ = new Object();
+ var tr = newRow(CLASSES.typeFrame(), "Type", new SelectrowC(types, this.__type__, 1, 1).getFrame());
+ this.__table__.insert({"bottom" : tr});
+
+ // --- 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");
+
+ // --- 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;
+ makeResource(this, contents, constraint, (occurrenceTypes ? occurrenceTypes[0].datatypeConstraint : null), cssTitle);
+ }
+ catch(err){
+ alert("From OccurrenceC(): " + err);
+ }
+ },
"getContent" : function(){
- // TODO: implement
+ if(this.isUsed() === true){
+ var resourceRef = null;
+ var resourceData = null;
+ if(this.__datatype__.__frames__[0].getContent() === ANY_URI){
+ resourceRef = this.__value__.value;
+ }
+ else {
+ resourceData = {"datatype" : this.__datatype__.__frames__[0].getContent(),
+ "value" : this.__value__.value};
+ }
+ return {"itemIdentities" : this.__itemIdentity__.getContent(true, true),
+ "type" : [this.__type__.__frames__[0].getContent()],
+ "scopes" : this.__scope__.getContent(),
+ "resourceRef" : resourceRef,
+ "resourceData" : resourceData};
+ }
+ else {
+ return null;
+ }
},
"toJSON" : function(){
- // TODO: implement
+ if(this.isUsed() === true){
+ var resourceRef = "null";
+ var resourceData = "null";
+ if(this.__datatype__.__frames__[0].getContent() === ANY_URI){
+ resourceRef = this.__value__.value.toJSON();
+ }
+ else {
+ resourceData = "{\"datatype\":" + this.__datatype__.__frames__[0].toJSON() +
+ ",\"value\":" + this.__value__.value.toJSON() + "}";
+ }
+ return "{\"itemIdentities\":" + this.__itemIdentity__.toJSON(true, true) +
+ ",\"type\":[" + this.__type__.__frames__[0].toJSON() +
+ "],\"scopes\":" + this.__scope__.toJSON() +
+ ",\"resourceRef\":" + resourceRef +
+ ",\"resourceData\":" + resourceData + "}";
+ }
+ else {
+ return "null";
+ }
},
"isUsed" : function(){
- // TODO: implement
- },
- "showRemoveButton" : function(){
- this.__remove__.show();
- },
- "hideRemoveButton" : function(){
- this.__remove__.hide();
- },
- "showAddButton" : function(){
- this.__add__.show();
- },
- "hideAddButton" : function(){
- this.__add__.hide();
+ 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;
+ },
+ "minimize" : function(){
+ var trs = this.__table__.select("tr");
+ for(var i = 0; i != trs.length; ++i){
+ if(i === 0) trs[i].show();
+ else trs[i].hide();
+ }
}});
+
-
-
+// --- contains all occurrences of an topic element
var OccurrenceContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints){
-
-},
+ $super();
+ this.__containers__ = new Array();
+ this.__frame__.writeAttribute({"class" : CLASSES.occurrenceContainer()});
+
+ try{
+ if((!contents || contents.length === 0) && constraints && constraints.length > 0){
+ for(var i = 0; i != constraints.length; ++i){
+ this.__containers__.push(new Array());
+ 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 regexp = constraints[i].constraints[j].regexp;
+ if(max !== 0){
+ 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);
+ this.__error__.insert({"before" : occurrence.getFrame()});
+ if(min === 0)occurrence.minimize();
+ }
+ }
+ }
+ }
+ else {
+ // TODO: check already existing contents and order them to the corresponding fields
+ }
+ }
+ catch(err){
+ alert("From OccurrenceContainerC(): " + err);
+ }
+ },
"isValid" : function(){
// TODO: implement this method
return true;
},
"getContent" : function(){
- // TODO: implement this method
+ var values = new Array();
+ try{
+ 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){
+ values.push(this.__containers__[i][j].__frames__[k].getContent());
+ }
+ }
+ }
+ }
+ return values;
+ }
+ catch(err){
+ return values;
+ }
},
- "toJSON" : function(){
- // TODO: implement this method
+ "toJSON" : function(){
+ try{
+ var str = "[";
+ 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){
+ str += this.__containers__[i][j].__frames__[k].toJSON() + ",";
+ }
+ }
+ }
+ }
+ if(str.endsWith(",")) str = str.slice(0, str.length - 1);
+ str += "]";
+ return str === "[]" ? null : str;
+ }
+ catch(err){
+ return "null";
+ }
}});
-
-
-
+// --- representation of a topic element.
var TopicC = Class.create(ContainerC, {"initialize" : function($super, content, constraints){
$super();
+ this.__minimized__ = false;
try{
this.__frame__ .writeAttribute({"class" : CLASSES.topicFrame()});
this.__table__ = new Element("table", {"class" : CLASSES.topicFrame()});
this.__frame__.insert({"top" : this.__table__});
- this.__caption__ = new Element("caption").update("Topic");
+ this.__caption__ = new Element("caption", {"class" : CLASSES.clickable()}).update("Topic");
this.__table__.insert({"top" : this.__caption__});
+
+ function setMinimizeHandler(myself){
+ myself.__caption__.observe("click", function(event){
+ myself.minimize();
+ });
+ }
+ setMinimizeHandler(this);
// --- topic id
this.__topicid__ = new Object();
@@ -960,32 +1207,328 @@
this.__name__ = new NameContainerC(_contents, _constraints);
this.__table__.insert({"bottom" : newRow(CLASSES.nameContainer(), "Names", this.__name__.getFrame())});
-
-
-
-
+ // --- occurrences
+ _contents = (content ? content.occurrences : null);
+ _constraints = (constraints ? constraints.topicOccurrenceConstraints : null);
+ this.__occurrence__ = new OccurrenceContainerC(_contents, _constraints);
+ this.__table__.insert({"bottom" : newRow(CLASSES.occurrenceContainer(), "Occurrences", this.__occurrence__.getFrame())});
- var tmp = new Element("input", {"type" : "button", "value" : "test"});
- function tester(myself){
- tmp.observe("click", function(event){
- //alert(myself.__subjectLocator__.getContent() + " -> " + myself.__subjectLocator__.toJSON() + "\n\n" + myself.__subjectLocator__.getContent(true, true) + " -> " + myself.__subjectLocator__.toJSON(true, true));
-
- });
- };
- tester(this);
- this.__frame__.insert({"bottom" : tmp});
+ 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);
}
},
+ "isValid" : function(){
+ // TODO: implement
+ return true;
+ },
"getContent" : function(){
- return {"id" : this.__topicid__.__frames__[0].getContent };
- }
- });
+ try{
+ return {"id" : this.__topicid__.__frames__[0].getContent().strip(),
+ "itemIdentities" : this.__itemIdentity__.getContent(true, true),
+ "subjectLocators" : this.__subjectLocator__.getContent(true, true),
+ "subjectIdentifiers" : this.__subjectIdentifier__.getContent(true, true),
+ "names" : this.__name__.getContent(),
+ "occurrences" : this.__occurrence__.getContent()};
+ }
+ catch(err){
+ return null;
+ }
+ },
+ "toJSON" : function(){
+ try{
+ return "{\"id\":" + this.__topicid__.__frames__[0].getContent().strip().toJSON() +
+ ",\"itemIdentities\":" + this.__itemIdentity__.toJSON(true, true) +
+ ",\"subjectLocators\":" + this.__subjectLocator__.toJSON(true, true) +
+ ",\"subjectIdentifiers\":" + this.__subjectIdentifier__.toJSON(true, true) +
+ ",\"names\":" + this.__name__.toJSON() +
+ ",\"occurrences\":" + this.__occurrence__.toJSON() + "}";
+ }
+ catch(err){
+ return "null";
+ }
+ },
+ "minimize" : function(){
+ var rows = new Array();
+ rows.push(this.getFrame().select("tr." + CLASSES.topicIdFrame())[0],
+ this.getFrame().select("tr." + CLASSES.itemIdentityFrame())[0],
+ this.getFrame().select("tr." + CLASSES.subjectLocatorFrame())[0],
+ this.getFrame().select("tr." + CLASSES.subjectIdentifierFrame())[0],
+ this.getFrame().select("tr." + CLASSES.nameContainer())[0],
+ this.getFrame().select("tr." + CLASSES.occurrenceContainer())[0]);
+ for(var i = 0; i != rows.length; ++i){
+ if(this.__minimized__ === false) rows[i].hide();
+ else rows[i].show();
+ }
+ this.__minimized__ = !this.__minimized__;
+ }});
+
+
+// --- representation of a role element.
+var RoleC = Class.create(ContainerC, {"initialize" : function($super, itemIdentities, roleTypes, rolePlayers, owner, min, max){
+ $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";
+ owner.__frames__.push(this);
+ this.__frame__.writeAttribute({"class" : CLASSES.roleFrame()});
+ this.__table__ = new Element("table", {"class" : CLASSES.roleFrame()});
+ this.__frame__.insert({"top" : this.__table__});
+ this.__roleTypes__ = roleTypes;
+ this.__rolePlayers__ = rolePlayers;
+
+ 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);
+ });
+
+ // --- 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});
+
+ // --- player
+ var players = this.__rolePlayers__.flatten();
+ this.__player__ = new Object();
+ tr = newRow(CLASSES.playerFrame(), "Player", new SelectrowC(players, this.__player__, 1, 1).getFrame());
+ this.__table__.insert({"bottom" : tr});
+ }
+ catch(err){
+ alert("From RoleC(): " + err);
+ }
+ },
+ "getType" : function(){
+ return this.__type__.__frames__[0].getContent();
+ },
+ "getPlayer" : function(){
+ return this.__player__.__frames__[0].getContent();
+ },
+ "getContent" : function(){
+ if(this.isUsed()){
+ return {"itemIdentities" : this.__itemIdentity__.getContent(true, true),
+ "type" : new Array(this.getType()),
+ "topicRef" : new Array(this.getPlayer())};
+ }
+
+ return null;
+ },
+ "toJSON" : function(){
+ if(this.isUsed()){
+ return "{\"itemIdentities\":" + this.__itemIdentity__.toJSON(true, true) +
+ ",\"type\":[" + this.getType().toJSON() + "]" +
+ ",\"topicRef\":[" + this.getPlayer().toJSON() + "]}";
+ }
+
+ return "null";
+ },
+ "isValid" : function(){
+ 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;
+ }});
+
+
+// --- contains all roles of an association
+var RoleContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, roleConstraints, playerConstraints, otherRoleConstraints){
+ $super();
+ this.__frame__.writeAttribute({"class" : CLASSES.roleContainer()});
+ this.__container__ = new Object();
+
+ 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()});
+ }
+ }
+ else {
+ // TODO: check already existing contents and order them to the corresponding fields
+ }
+
+
+
+ }
+ catch(err){
+ alert("From RoleContainerC(): " + err);
+ }
+ },
+ "resetValues" : function(roleConstraints, playerConstraints, otherRoleConstraints){
+
+ // TODO: implement
+ },
+ "getContent" : function(){
+ // TODO: implement
+ },
+ "toJSON" : function(){
+ // TODO: implement
+ },
+ "isValid" : function(){
+ // TODO: implement
+ },
+ "isUsed" : function(){
+ // TODO: implement
+ }});
+
+
+// --- representation of an association element
+var AssociationC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints, owner){
+ $super();
+ 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;
+
+ try{
+ // --- control row + ItemIdentity
+ makeControlRow(this, 4, contents ? contents.itemIdentities : null);
+ checkRemoveAddButtons(owner, 1, -1);
+ setRemoveAddHandler(this, owner, 1, -1, function(){
+ return new AssociationC(null, constraints, owner);
+ });
+
+ // --- type
+ var types = new Array();
+ for(var i = 0; constraints && i !== constraints.length; ++i){
+ for(var j = 0; j != constraints[i].associationType.length; ++j){
+ types.push(constraints[i].associationType[j]);
+ if(contents && contents.type && contents.type[0] === constraints[i].associationType[j]){
+ var selected = constraints[i].associationType[j];
+ types[types.length - 1] = types[0];
+ types[0] = selected;
+ }
+ }
+ }
+ this.__type__ = new Object();
+ var tr = newRow(CLASSES.typeFrame(), "Type", new SelectrowC(types, this.__type__, 1, 1).getFrame());
+ this.__table__.insert({"bottom" : tr});
+
+ // --- scopes
+ this.__scope__ = new ScopeContainerC(this.__contents__ && this.__contents__.scopes ? this.__contents__.scopes : null, this.__constraints__ && this.__constraints__[0].scopeConstraints ? this.__constraints__[0].scopeConstraints : null);
+ this.__table__.insert({"bottom" : newRow(CLASSES.scopeContainer(), "Scope", this.__scope__.getFrame())});
+
+ // --- roles
+ var _roleConstraints = _playerConstraints = _otherRoleConstraints = null;
+ if(this.__constraints__){
+ _roleConstraints = this.__constraints__[0].associationRoleConstraints;
+ _playerConstraints = this.__constraints__[0].rolePlayerConstraints;
+ _otherRoleConstraints = this.__constraints__[0].otherRoleConstraints;
+ }
+
+ this.__roles__ = new RoleContainerC(this.__contents__ ? this.__contents__.roles : null, _roleConstraints, _playerConstraints, _otherRoleConstraints);
+ this.__table__.insert({"bottom" : newRow(CLASSES.roleContainer(), "Roles", this.__roles__.getFrame())});
+
+ // --- registers the onChangeHandler of the Type-selectrow
+ onTypeChangeScope(this, null, null, "association");
+ }
+ catch(err){
+ alert("From AssociationC(): " + err);
+ }
+ },
+ "resetValues" : function(){
+ // --- scope, depends only to the associationtype, roles can be ignored
+ // --- finds the scopes depending to the selected type
+ var foundIdx = -1;
+ for(var i = 0; this.__constraints__ && i != this.__constraints__.length; ++i)
+ {
+ if(foundIdx !== -1) break;
+ for(var j = 0; j != this.__constraints__[i].associationType.length; ++j){
+ if(this.__type__.__frames__[0].getContent() === this.__constraints__[i].associationType[j]){
+ foundIdx = i;
+ break;
+ }
+ }
+ }
+ this.__scope__.resetValues(null, (foundIdx === -1 ? null : this.__constraints__[foundIdx].scopeConstraints));
+
+ var _roleConstraints = _playerConstraints = _otherRoleConstraints = null;
+ if(foundIdx !== -1){
+ _roleConstraints = this.__constraints__[foundIdx].associationRoleConstraints;
+ _playerConstraints = this.__constraints__[foundIdx].rolePlayerConstraints;
+ _otherRoleConstraints = this.__constraints__[foundIdx].otherRoleConstraints;
+ }
+ this.__roles__.resetValues(_roleConstraints, _playerConstraints, _otherRoleConstraints);
+ },
+ "getContent" : function(){
+ // TODO: implement
+ },
+ "toJSON" : function(){
+ // TODO: implement
+ },
+ "isValid" : function(){
+ // TODO: implement
+ },
+ "isUsed" : function(){
+ // TODO: implement
+ }});
+
+
+var AssociationContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints){
+ $super();
+ this.__minimized__ = false;
+ try{
+ this.__frame__ .writeAttribute({"class" : CLASSES.associationContainer()});
+ this.__table__ = new Element("table", {"class" : CLASSES.associationContainer()});
+ 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){
+ var association = new AssociationC(contents[i], constraints, this.__container__);
+ var tr = new Element("tr", {"class" : CLASSES.associationFrame()});
+ var td = new Element("td", {"class" : CLASSES.content()});
+ td.update(association.getFrame());
+ tr.update(td);
+ this.__table__.insert({"bottom" : tr});
+ }
+
+ if(!this.__container__.__frames__ && constraints && constraints.length !== 0){
+ var association = new AssociationC(null, constraints, this.__container__);
+ var tr = new Element("tr", {"class" : CLASSES.associationFrame()});
+ var td = new Element("td", {"class" : CLASSES.content()});
+ td.update(association.getFrame());
+ tr.update(td);
+ this.__table__.insert({"bottom" : tr});
+ }
+ }
+ catch(err){
+ alert("From AssociationContainerC(): " + err);
+ }
+ },
+ "getContent" : function(){
+ // TODO: implement
+ },
+ "toJSON" : function(){
+ // TODO: implement
+ },
+ "isValid" : function(){
+ // TODO: implement
+ },
+ "minimize" : function(){
+ // TODO: implement
+ }});
@@ -1155,4 +1698,101 @@
else trs[i].hide();
}
});
+}
+
+
+// --- This function adds a onchange handler to the type-selct-element
+// --- of the instance passed through the variable myself.
+// --- On changing there will be reset the scope frame to the corresponding
+// --- type and when what is set to "occurrence" there will be set a corresponding
+// --- datatype-value.
+function onTypeChangeScope(myself, contents, constraints, what){
+ try{
+ var select = myself.__table__.select("tr." + CLASSES.typeFrame())[0].select("td." + CLASSES.content())[0].select("select")[0];
+ select.observe("change", function(event){
+ var type = event.element().value;
+
+ var foundIdx = -1;
+ if(what === "name"){
+ for(var i = 0; constraints && i !== constraints.length; ++i){
+ if(foundIdx !== -1) break;
+ for(var j = 0; j !== constraints[i].nameType.length; ++j){
+ if(foundIdx !== -1) break;
+ if(constraints[i].nameType[j] === type){
+ foundIdx = i;
+ break;
+ }
+ }
+ }
+ myself.__scope__.resetValues(contents, (foundIdx === -1 ? null : constraints[foundIdx].scopeConstraints));
+ }
+ else if(what === "occurrence"){
+ for(var i = 0; constraints && i !== constraints.length; ++i){
+ if(foundIdx !== -1) break;
+ for(var j = 0; j !== constraints[i].occurrenceType.length; ++j){
+ if(foundIdx !== -1) break;
+ if(constraints[i].occurrenceType[j] === type){
+ foundIdx = i;
+ break;
+ }
+ }
+ }
+ if(foundIdx !== -1 && constraints[foundIdx].datatypeConstraint){
+ var dc = constraints[foundIdx].datatypeConstraint;
+ myself.__datatype__.__frames__[0].getFrame().select("input")[0].writeAttribute({"readonly" : "readonly", "value" : dc});
+ }
+ else {
+ myself.__datatype__.__frames__[0].getFrame().select("input")[0].writeAttribute({"value" : ""});
+ myself.__datatype__.__frames__[0].getFrame().select("input")[0].removeAttribute("readonly");
+ }
+ myself.__scope__.resetValues(contents, (foundIdx === -1 ? null : constraints[foundIdx].scopeConstraints));
+ }
+ else if(what === "variant"){
+ // do nothing all values will be stored
+ }
+ else if(what === "association"){
+ myself.resetValues();
+ }
+ });
+ }
+ catch(err){}
+}
+
+
+// --- sets the resource value and datatype of names and occurrences
+function makeResource(myself, content, constraints, datatypeConstraint, cssTitle){
+ var value = "";
+ var datatype = "";
+ if(content && content.resourceRef && content.resourceRef.length !== 0){
+ value = content.resourceRef;
+ datatype = ANY_URI;
+ }
+ else if(content && content.resourceData){
+ value = content.resourceData.value;
+ datatype = contents.resourceData.datatype;
+ }
+
+ try{
+ this.__value__.remove();
+ this.__value__ = null;
+ }catch(err){}
+ try{
+ this.__datatype__.__frames__[0].remove();
+ this.__datytype__ = new Object();
+ }catch(err){}
+
+ myself.__value__ = new Element("textarea", {"rows" : 3}).update(value);
+ myself.__table__.insert({"bottom" : newRow(CLASSES.valueFrame(), "Resource Value", myself.__value__)});
+ if(cssTitle && cssTitle.length !== 0) myself.__value__.writeAttribute({"title" : cssTitle});
+
+ // --- datatype
+ myself.__datatype__ = new Object();
+ if(datatypeConstraint && datatypeConstraint.length !== 0){
+ new TextrowC(datatypeConstraint, datatypeConstraint, myself.__datatype__, 1, 1, null);
+ myself.__datatype__.__frames__[0].getFrame().select("input")[0].writeAttribute({"readonly" : "readonly"});
+ }
+ else {
+ new TextrowC(datatype, ".*", myself.__datatype__, 1, 1, null);
+ }
+ myself.__table__.insert({"bottom" : newRow(CLASSES.datatypeFrame(), "Datatype", myself.__datatype__.__frames__[0].getFrame())});
}
\ 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 Sun May 31 09:08:00 2009
@@ -35,7 +35,7 @@
(let ((value
(get-constraints-of-topic topics :treat-as treat-as)))
(concatenate 'string "\"topicConstraints\":" value))))
- (let ((available-associations ;what's with association which have only a associationrole-constraint?
+ (let ((available-associations ;what's with association which have only a associationrole-constraints?
(remove-duplicates
(loop for topic in topics
append (get-available-associations-of-topic topic :treat-as treat-as)))))
@@ -58,40 +58,6 @@
"{" topic-constraints "," associations-constraints "}")))
json-string)))))))
-;(defun get-constraints-of-fragment(topic-psi &key (treat-as 'type))
-; (let ((associationtype (get-item-by-psi *associationtype-psi*))
-; (associationtype-constraint (get-item-by-psi *associationtype-constraint-psi*))
-; (topic
-; (let ((psi
-; (elephant:get-instance-by-value 'PersistentIdC 'uri topic-psi)))
-; (when psi
-; (identified-construct psi)))))
-; (when topic
-; (let ((topic-constraints
-; (let ((value
-; (get-constraints-of-topic topic :treat-as treat-as)))
-; (concatenate 'string "\"topicConstraints\":" value))))
-; (let ((available-associations ;what's with association which have only a associationrole-constraint?
-; (get-available-associations-of-topic topic :treat-as treat-as)))
-; (dolist (item available-associations)
-; (topictype-p item associationtype associationtype-constraint))
-; (let ((associations-constraints
-; (concatenate 'string "\"associationsConstraints\":"
-; (let ((inner-associations-constraints "["))
-; (loop for available-association in available-associations
-; do (let ((value
-; (get-constraints-of-association available-association)))
-; (setf inner-associations-constraints
-; (concatenate 'string inner-associations-constraints value ","))))
-; (if (string= inner-associations-constraints "[")
-; (setf inner-associations-constraints "null")
-; (setf inner-associations-constraints
-; (concatenate 'string (subseq inner-associations-constraints 0 (- (length inner-associations-constraints) 1)) "]")))))))
-; (let ((json-string
-; (concatenate 'string
-; "{" topic-constraints "," associations-constraints "}")))
-; json-string)))))))
-
;; =============================================================================
;; --- all association constraints ---------------------------------------------
@@ -101,7 +67,10 @@
passed associationtype-topic."
(let ((constraint-topics
(get-all-constraint-topics-of-association associationtype-topic)))
- (let ((associationtypescope-constraints
+ (let ((associationtype
+ (concatenate 'string "\"associationType\":"
+ (json-exporter::identifiers-to-json-string associationtype-topic)))
+ (associationtypescope-constraints
(let ((value (get-typescope-constraints associationtype-topic :what 'association)))
(concatenate 'string "\"scopeConstraints\":" value)))
(associationrole-constraints
@@ -117,7 +86,7 @@
(get-otherrole-constraints (getf constraint-topics :otherrole-constraints))))
(concatenate 'string "\"otherRoleConstraints\":" value))))
(let ((json-string
- (concatenate 'string "{" associationrole-constraints "," roleplayer-constraints ","
+ (concatenate 'string "{" associationtype "," associationrole-constraints "," roleplayer-constraints ","
otherrole-constraints "," associationtypescope-constraints "}")))
json-string))))
@@ -217,6 +186,7 @@
(uri (first (psis (getf involved-topic-tupple :otherplayer))))
(uri (first (psis (getf involved-topic-tupple :otherrole))))
constraint-lists))
+
(let ((json-player
(concatenate 'string "\"players\":"
(topics-to-json-list
@@ -342,7 +312,9 @@
"Returns a list of the form
((:associationroletype <topic> :card-min <string> :card-max <string>), <...>)
which describes all associationrole-constraints of the passed
- constraint-topics."
+ constraint-topics.
+ If as-json is set to t the return value of this function is a json-string otherwise a
+ list of lists of the following form (:roletype <topic, topic, ...> :cardMin <min> :cardMax <max>)"
(let ((applies-to (get-item-by-psi *applies-to-psi*))
(roletype-role (get-item-by-psi *roletype-role-psi*))
(constraint-role (get-item-by-psi *constraint-role-psi*))
@@ -366,6 +338,7 @@
associationroletype))
associationrole-constraints))))
(let ((cleaned-associationrole-constraints "["))
+ ;(raw-constraints nil))
(loop for associationroletype-topic in associationroletype-topics
do (let ((constraint-lists
(remove-duplicate-constraints
@@ -385,6 +358,7 @@
"{\"roleType\":" roletype-with-subtypes
",\"cardMin\":" (getf (first constraint-lists) :card-min)
",\"cardMax\":" (getf (first constraint-lists) :card-max) "},")))))
+
(if (string= cleaned-associationrole-constraints "[")
(setf cleaned-associationrole-constraints "null")
@@ -475,41 +449,6 @@
topicoccurrence-constraints "," abstract-constraint "}")))
json-string))))
-;(defun get-constraints-of-topic (topic-instances &key(treat-as 'type))
-; (let ((constraint-topics
-; (get-all-constraint-topics-of-topic topic-instance :treat-as treat-as)))
-; (let ((exclusive-instance-constraints
-; (let ((value
-; (get-exclusive-instance-constraints (getf constraint-topics :exclusive-instance-constraints))))
-; (concatenate 'string "\"exclusiveInstances\":" value)))
-; (subjectidentifier-constraints
-; (let ((value
-; (get-simple-constraints (getf constraint-topics :subjectidentifier-constraints) :error-msg-constraint-name "subjectidentifier")))
-; (concatenate 'string "\"subjectIdentifierConstraints\":" value)))
-; (subjectlocator-constraints
-; (let ((value
-; (get-simple-constraints (getf constraint-topics :subjectlocator-constraints) :error-msg-constraint-name "subjectlocator")))
-; (concatenate 'string "\"subjectLocatorConstraints\":" value)))
-; (topicname-constraints
-; (let ((value
-; (get-topicname-constraints (getf constraint-topics :topicname-constraints))))
-; (concatenate 'string "\"topicNameConstraints\":" value)))
-; (topicoccurrence-constraints
-; (let ((value
-; (get-topicoccurrence-constraints (getf constraint-topics :topicoccurrence-constraints)
-; (getf constraint-topics :uniqueoccurrence-constraints))))
-; (concatenate 'string "\"topicOccurrenceConstraints\":" value)))
-; (abstract-constraint
-; (concatenate 'string "\"abstractConstraint\":"
-; (if (getf constraint-topics :abstract-topictype-constraints)
-; "true"
-; "false"))))
-; (let ((json-string
-; (concatenate 'string "{" exclusive-instance-constraints "," subjectidentifier-constraints
-; "," subjectlocator-constraints "," topicname-constraints ","
-; topicoccurrence-constraints "," abstract-constraint "}")))
-; json-string))))
-
(defun get-exclusive-instance-constraints(owner exclusive-instances-lists)
"Returns a JSON-obejct of the following form:
@@ -745,7 +684,7 @@
(error "found contrary occurrence-datatype-constraints: ~a~%" datatype-constraints))
(if datatype-constraint
(json:encode-json-to-string (first datatype-constraint))
- nil)))))
+ "null")))))
(defun get-typescope-constraints(element-type-topic &key(what 'topicname))
Modified: trunk/src/json/json_tmcl_validation.lisp
==============================================================================
--- trunk/src/json/json_tmcl_validation.lisp (original)
+++ trunk/src/json/json_tmcl_validation.lisp Sun May 31 09:08:00 2009
@@ -241,7 +241,7 @@
(defun list-instances (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*))
(topictype-constraint (get-item-by-psi *topictype-constraint-psi*)))
- "Returns the topic-instance, all subtypes found by the function lis-subtypes and all direct
+ "Returns the topic-instance, all subtypes found by the function list-subtypes and all direct
instances for the found subtypes."
(let ((all-subtypes-of-this
(getf (list-subtypes topic-instance topictype topictype-constraint) :subtypes))
@@ -262,10 +262,11 @@
(remove-duplicates
(loop for subtype in all-instances-of-this
append (getf (list-subtypes subtype nil nil) :subtypes))))))
- (remove-if #'null
- (map 'list #'(lambda(x)
- (handler-case (progn
- (topictype-of-p x nil)
- x)
- (condition () nil)))
- all-subtypes-of-all-instances))))))
\ No newline at end of file
+ (union all-instances-of-this
+ (remove-if #'null
+ (map 'list #'(lambda(x)
+ (handler-case (progn
+ (topictype-of-p x nil)
+ x)
+ (condition () nil)))
+ all-subtypes-of-all-instances)))))))
\ No newline at end of file
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 Sun May 31 09:08:00 2009
@@ -12,7 +12,7 @@
(defparameter *json-get-prefix* "/json/get/(.+)$") ;the prefix to get a fragment by the psis -> localhost:8000/json/get/<fragment-psi>
(defparameter *json-commit-url* "/json/commit/?$") ;the url to commit a json fragment by "put" or "post"
(defparameter *json-get-all-psis* "/json/psis/?$") ;the url to get all topic psis of isidorus -> localhost:8000/json/psis
-(defparameter *json-get-summary-url* "/json/summary/?$") ;the url to get a summary od all topic stored in isidorus; you have to set the GET-parameter "start" for the start index of all topics within elephant and the GET-paramter "end" for the last index of the topic sequence -> http://localhost:8000/json/summary/?start=12&end=13
+(defparameter *json-get-summary-url* "/json/summary/?$") ;the url to get a summary of all topic stored in isidorus; you have to set the GET-parameter "start" for the start index of all topics within elephant and the GET-paramter "end" for the last index of the topic sequence -> http://localhost:8000/json/summary/?start=12&end=13
(defparameter *json-get-all-type-psis* "/json/tmcl/types/?$") ;returns a list of all psis that can be a type
(defparameter *json-get-topic-stub-prefix* "/json/topicstubs/(.+)$") ;the json prefix for getting some topic stub information of a topic
(defparameter *json-get-type-tmcl-url* "/json/tmcl/type/?$") ;the json url for getting some tmcl information of a topic treated as a type
Modified: trunk/src/unit_tests/poems.xtm
==============================================================================
--- trunk/src/unit_tests/poems.xtm (original)
+++ trunk/src/unit_tests/poems.xtm Sun May 31 09:08:00 2009
@@ -582,7 +582,7 @@
<tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
</tm:topic>
- <!-- poem scopes -->
+ <!-- available scopes -->
<tm:topic id="de">
<tm:subjectIdentifier href="http://some.where/base-psis/de"/>
<tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
@@ -593,6 +593,26 @@
<tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
</tm:topic>
+ <tm:topic id="fr">
+ <tm:subjectIdentifier href="http://some.where/base-psis/fr"/>
+ <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="fin">
+ <tm:subjectIdentifier href="http://some.where/base-psis/fin"/>
+ <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="rus">
+ <tm:subjectIdentifier href="http://some.where/base-psis/rus"/>
+ <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="pl">
+ <tm:subjectIdentifier href="http://some.where/base-psis/pl"/>
+ <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
+ </tm:topic>
+
<!-- region -->
<tm:topic id="region">
<tm:subjectIdentifier href="http://some.where/base-psis/region"/>
@@ -1059,7 +1079,7 @@
</tm:occurrence>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-max"/></tm:type>
- <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">3</tm:resourceData>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
</tm:occurrence>
<tm:occurrence>
<tm:type><tm:topicRef href="#regexp"/></tm:type>
@@ -1262,8 +1282,9 @@
</tm:association>
<!-- country-name scopes -->
- <tm:topic id="scoped-country-name-constraint">
- <tm:subjectIdentifier href="http://some.where/constraint-psis/scoped-country-name-constraint"/>
+ <!-- scope constraint 1: there must be either the scope en or de -->
+ <tm:topic id="scoped-country-name-constraint-1">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/scoped-country-name-constraint-1"/>
<tm:instanceOf><tm:topicRef href="#nametypescope-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-min"/></tm:type>
@@ -1279,7 +1300,7 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#scoped-country-name-constraint"/>
+ <tm:topicRef href="#scoped-country-name-constraint-1"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#nametype-role"/></tm:type>
@@ -1291,7 +1312,7 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#scoped-country-name-constraint"/>
+ <tm:topicRef href="#scoped-country-name-constraint-1"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
@@ -1303,14 +1324,111 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#scoped-country-name-constraint"/>
+ <tm:topicRef href="#scoped-country-name-constraint-1"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
<tm:topicRef href="#de"/>
</tm:role>
</tm:association>
+
+ <!-- scope constraint 2: there can exist the scopes de, en, pl, fr, fin or rus -->
+ <tm:topic id="scoped-country-name-constraint-2">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/scoped-country-name-constraint-2"/>
+ <tm:instanceOf><tm:topicRef href="#nametypescope-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">6</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-country-name-constraint-2"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#nametype-role"/></tm:type>
+ <tm:topicRef href="#country-name"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-country-name-constraint-2"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+ <tm:topicRef href="#en"/>
+ </tm:role>
+ </tm:association>
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-country-name-constraint-2"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+ <tm:topicRef href="#pl"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-country-name-constraint-2"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+ <tm:topicRef href="#fr"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-country-name-constraint-2"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+ <tm:topicRef href="#fin"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-country-name-constraint-2"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+ <tm:topicRef href="#rus"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-country-name-constraint-2"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+ <tm:topicRef href="#de"/>
+ </tm:role>
+ </tm:association>
<!-- ===================================================================== -->
<!-- === own datamodel: occurence constraints ============================ -->
Modified: trunk/src/xml/setup.lisp
==============================================================================
--- trunk/src/xml/setup.lisp (original)
+++ trunk/src/xml/setup.lisp Sun May 31 09:08:00 2009
@@ -33,7 +33,10 @@
(if (eq xtm-format '2.0)
(importer xtm-dom :tm-id tm-id :xtm-id xtm-id)
(importer-xtm1.0 xtm-dom :tm-id tm-id :xtm-id xtm-id))
- (format t "#Topics in the store: ~a~%" (length (elephant:get-instances-by-class 'TopicC)))))
+ (format t "#Objects in the store: Topics: ~a, Associations: ~a~%"
+ (length (elephant:get-instances-by-class 'TopicC))
+ (length (elephant:get-instances-by-class 'AssociationC)))))
+ ;(format t "#Topics in the store: ~a~%" (length (elephant:get-instances-by-class 'TopicC)))))
(defun setup-repository (xtm-path repository-path
&key
1
0

[isidorus-cvs] r31 - in trunk: docs src/ajax src/ajax/css src/ajax/javascripts src/json src/rest_interface src/unit_tests
by Lukas Giessmann 19 May '09
by Lukas Giessmann 19 May '09
19 May '09
Author: lgiessmann
Date: Tue May 19 05:23:26 2009
New Revision: 31
Log:
fixed some problems in the json-tmcl module and started to implement the ajax-client
Added:
trunk/src/ajax/css/frame.css (contents, props changed)
- copied, changed from r26, /trunk/src/ajax/css/home.css
trunk/src/ajax/javascripts/create.js
trunk/src/ajax/javascripts/datamodel.js
trunk/src/ajax/javascripts/edit.js
trunk/src/ajax/javascripts/requests.js (contents, props changed)
trunk/src/ajax/javascripts/search.js
trunk/src/ajax/javascripts/tmcl_tools.js
Removed:
trunk/src/ajax/css/home.css
trunk/src/ajax/javascripts/edit_topic.js
trunk/src/ajax/javascripts/make_fragment_node.js
Modified:
trunk/docs/xtm_json.txt
trunk/src/ajax/css/main.css
trunk/src/ajax/css/navi.css
trunk/src/ajax/isidorus.html
trunk/src/ajax/javascripts/constants.js
trunk/src/ajax/javascripts/home.js
trunk/src/ajax/javascripts/navi.js
trunk/src/json/json_tmcl.lisp
trunk/src/json/json_tmcl_validation.lisp
trunk/src/rest_interface/set-up-json-interface.lisp
trunk/src/unit_tests/poems.xtm
Modified: trunk/docs/xtm_json.txt
==============================================================================
--- trunk/docs/xtm_json.txt (original)
+++ trunk/docs/xtm_json.txt Tue May 19 05:23:26 2009
@@ -186,7 +186,10 @@
//+ This message constains a list of topics represented as a list of topic
//+ psis which are exclusive instances for the owner.
//+-----------------------------------------------------------------------------
-[ [ "topic-1-psi-1", "topic-2-psi-2", "..." ], [ "topic-2-psi", "..." ], <...> ]
+{
+ "owner" : ["psi-1", "..."],
+ "exclusives" : [ [ "topic-1-psi-1", "topic-2-psi-2", "..." ], [ "topic-2-psi", "..." ], <...> ]
+}
//+-----------------------------------------------------------------------------
@@ -234,14 +237,14 @@
//+ The scopeConstraint-Object contains a list of all available scopes of
//+ for an association/name/occurrence element - this depends where this
//+ json-onbject is contained.
-//+ The member availableScopeTypes contains a list of topics in psi-list
-//+ representation which can be used as scope.
+//+ The member availableScopeTypes contains a list of lists of topics in
+//+ form of psi-lists.
//+ cardMin defines the minimum number of all scopes of the parent element
//+ (association/name/occurrence).
//+ cardMax defines the maximum number of all scopes of the parent element.
//+-----------------------------------------------------------------------------
{
- "scopeTypes" : [ [ "topic-1-psi-1", "topic-1-psi-2", "..." ], [ "topic-2-psi-1", "..." ] <...> ],
+ "scopeTypes" : [ [ [ "psi-1-1", "psi-1-2", "..." ], [ "subtype-psi-1", "..." ], <...> ], [ "psi-2-1" "..."], <...> ],
"cardMin" : "unsigned integer in string representation",
"cardMax" : "unsigend integer in string representation or the string MAX_INT"
}
@@ -255,7 +258,7 @@
//+-----------------------------------------------------------------------------
{
"nametypescopes" : [ {
- "nametype" : [psi-1, psi-2, "..." ],
+ "nameType" : [psi-1, psi-2, "..." ],
"scopeConstraints" : [ <scopeConstraints> ]
},
<...>
Copied: trunk/src/ajax/css/frame.css (from r26, /trunk/src/ajax/css/home.css)
==============================================================================
--- /trunk/src/ajax/css/home.css (original)
+++ trunk/src/ajax/css/frame.css Tue May 19 05:23:26 2009
@@ -9,36 +9,19 @@
/* in trunk/src/ajax/javascripts/external/MIT-LICENSE.txt. */
/*----------------------------------------------------------------------------*/
-
-.topicSummaryTd {
- width: 40px;
- border: solid 1px gray;
-}
-
-#topicTable {
- width: 80%;
- border: solid 1px gray;
- margin-left: auto;
- margin-right: auto;
- margin-top: 10px;
- margin-bottom: 10px;
-}
-
-th {
- color: red;
- border: solid 1px gray;
+ul.fragmentFrame {
+ list-style-type: none;
}
-ul.topicTable {
- list-style: none;
+caption {
+ font-size: 1.5em;
+ font-weight: bold;
}
-div.naviTopicTable {
- width: 80%;
- margin-left: auto;
- margin-right: auto;
+td.controlColumn {
+ background-color: #eaeaee;
}
-select.topicTable {
- margin-left: 20px;
+tr.showHiddenRows {
+ background-color: #eaeaee;
}
\ No newline at end of file
Modified: trunk/src/ajax/css/main.css
==============================================================================
--- trunk/src/ajax/css/main.css (original)
+++ trunk/src/ajax/css/main.css Tue May 19 05:23:26 2009
@@ -10,42 +10,31 @@
/*----------------------------------------------------------------------------*/
-.clickable{
- cursor: pointer;
- padding-left: 5px;
- padding-right: 5px;
-}
-
-.clickable:hover{
- text-decoration: underline;
-}
-
-.clickable:active{
- color: red;
-}
-
-.headerRow {
- background-color: #EEEEFF;
-}
-
-
-.topicHeaderRow {
- background-color: #CCE5FF;
+body {
+ width: 1024px;
+ margin-left: auto;
+ margin-right: auto;
}
-.topicStubsHeaderRow {
- background-color: #CCE5FF;
+#subPage {
+ color: #333377;
+ min-height: 800px;
+ border-left: 1px solid #d1d1d3;
+ border-right: 1px solid #d1d1d3;
+ border-bottom: 1px solid #d1d1d3;
+ margin-top: -21px;
}
-.associationsHeaderRow {
- background-color: #CCE5FF;
+h1 {
+ margin-left: 10px;
+ padding-top: 20px;
}
-.tmIdsHeaderRow {
- background-color: #CCE5FF;
+.clickable {
+ cursor: pointer;
}
-.frame{
- border: 1px outset black;
- margin: 5px;
-}
+.errorMessage {
+ color: red;
+ font-size: 0.85em;
+}
\ No newline at end of file
Modified: trunk/src/ajax/css/navi.css
==============================================================================
--- trunk/src/ajax/css/navi.css (original)
+++ trunk/src/ajax/css/navi.css Tue May 19 05:23:26 2009
@@ -11,11 +11,55 @@
#navi {
- border: solid 1px;
- margin-top: 10px;
- margin-bottom: 10px;
+ background-color: #aebae3;
+ width: 1022px;
+ margin-left: auto;
+ margin-right: auto;
+ padding-top: 10px;
+ padding-bottom: 5px;
+ border-left: 1px solid #d1d1d3;
+ border-top: 1px solid #d1d1d3;
+ border-right: 1px solid #d1d1d3;
}
-.naviElem {
- background-color: silver;
-}
\ No newline at end of file
+#navi > span {
+ color: #fbfcff;
+ cursor: pointer;
+ border-left: 1px solid #aebae3;
+ border-top: 1px solid #aebae3;
+ border-right: 1px solid #aebae3;
+ padding-left: 3px;
+ padding-right: 3px;
+ padding-top: 3px;
+ padding-bottom: 5px;
+ font-weight: bold;
+}
+
+#navi > span:first-child {
+ border-left: none;
+}
+
+#navi > span:first-child:hover {
+ border-left: none;
+}
+
+#navi > span:hover {
+ color: #333377;
+ background-color: #fbfcff;
+ border-left: 1px solid #d1d1d3;
+ border-top: 1px solid #d1d1d3;
+ border-right: 1px solid #d1d1d3;
+}
+
+#navi > .isActive {
+ color: #333377;
+ background-color: #fbfcff;
+ border-left: 1px solid #d1d1d3;
+ border-top: 1px solid #d1d1d3;
+ border-right: 1px solid #d1d1d3;
+}
+
+#navi > .isActive:hover {
+ color: #333377;
+ background-color: #fbfcff;
+}
Modified: trunk/src/ajax/isidorus.html
==============================================================================
--- trunk/src/ajax/isidorus.html (original)
+++ trunk/src/ajax/isidorus.html Tue May 19 05:23:26 2009
@@ -18,7 +18,7 @@
<!-- includes all necessary css-files -->
<link rel="stylesheet" type="text/css" href="css/main.css"/>
- <link rel="stylesheet" type="text/css" href="css/home.css"/>
+ <link rel="stylesheet" type="text/css" href="css/frame.css"/>
<link rel="stylesheet" type="text/css" href="css/navi.css"/>
<!-- error handling for javascript code -->
@@ -45,21 +45,25 @@
<!-- includes own javascript files -->
<script language="JavaScript" type="text/javascript" src="javascripts/constants.js"></script>
- <script language="JavaScript" type="text/javascript" src="javascripts/make_fragment_node.js"></script>
- <script language="JavaScript" type="text/javascript" src="javascripts/edit_topic.js"></script>
+ <script language="JavaScript" type="text/javascript" src="javascripts/tmcl_tools.js"></script>
+ <script language="JavaScript" type="text/javascript" src="javascripts/requests.js"></script>
+ <script language="JavaScript" type="text/javascript" src="javascripts/datamodel.js"></script>
<script language="JavaScript" type="text/javascript" src="javascripts/home.js"></script>
+ <script language="JavaScript" type="text/javascript" src="javascripts/search.js"></script>
+ <script language="JavaScript" type="text/javascript" src="javascripts/edit.js"></script>
+ <script language="JavaScript" type="text/javascript" src="javascripts/create.js"></script>
<script language="JavaScript" type="text/javascript" src="javascripts/navi.js"></script>
</head>
<body>
<div id="page">
<div id="navi">
- <span id="home" class="naviElem clickable">home</span>
- <span id="searchTopic" class="naviElem clickable">search topic</span>
- <span id="editTopic" class="naviElem clickable">edit topic</span>
- <span id="createTopic" class="naviElem clickable">create topic</span>
+ <span id="home" class="isActive">Home</span>
+ <span id="searchTopic" class="clickableButton">Search Topics</span>
+ <span id="editTopic" class="clickableButton">Edit Topics</span>
+ <span id="createTopic" class="clickableButton">Create Topics</span>
</div>
- <div id="content" style="border: red solid 1px;">
+ <div id="subPage">
</div>
</div>
</body>
Modified: trunk/src/ajax/javascripts/constants.js
==============================================================================
--- trunk/src/ajax/javascripts/constants.js (original)
+++ trunk/src/ajax/javascripts/constants.js Tue May 19 05:23:26 2009
@@ -10,116 +10,86 @@
//+-----------------------------------------------------------------------------
-var TIMEOUT = 5000; // const TIMEOUT = 5000 --> "const" doesn't work under IE
+// --- Some constants fot the http connections via the XMLHttpRequest-Object
+var TIMEOUT = 10000; // const TIMEOUT = 10000 --> "const" doesn't work under IE
var HOST_PREF = "http://localhost:8000/";
var GET_PREFIX = HOST_PREF + "json/get/";
+var GET_STUB_PREFIX = HOST_PREF + "json/topicstubs/";
+var TMCL_TYPE_URL = HOST_PREF + "json/tmcl/type/";
+var TMCL_INSTANCE_URL = HOST_PREF + "json/tmcl/instance/";
var COMMIT_URL = HOST_PREF + "json/commit/";
var ALL_PSIS_URL = HOST_PREF + "json/psis/";
+var TYPE_PSIS_URL = HOST_PREF + "json/tmcl/types/";
var OWN_URL = HOST_PREF + "isidorus";
var SUMMARY_URL = HOST_PREF + "json/summary"
-// --- a kind of enum for the the different pages with an attribute and a value
-var PAGES = {"home" : "home", "search" : "searchTopic", "edit" : "editTopic", "create" : "createTopic"};
-// --- contains most css classes used in this project
-var CLASSES = {"__addBtnHeader" : "addButton",
- "__associationFrame" : "associationFrame",
- "__associationsFrame" : "assocaitionsFrame",
- "__associationsHeader" : "associationsHeaderRow",
- "__button" : "clickable",
- "__fragmentFrame" : "fragmentFrame",
- "__frame" : "frame",
- "__header" : "headerRow",
- "__headerTitle" : "title",
- "__hideBtnHeader" : "hideButton",
- "__inAssociationFrame" : "inAssociationFrame",
- "__inNameFrame" : "inNameFrame",
- "__inOccurrenceFrame" : "inOccurrenceFrame",
- "__inRoleFrame" : "inRoleFrame",
- "__instanceOfFrame" : "instanceOf",
- "__inTopicFrame" : "inTopicFrame",
- "__inTopicStubFrame" : "inTopicStubFrame",
- "__inVariantFrame" : "inVariantFrame",
- "__itemIdentityFrame" : "itemIdentity",
- "__listFrame" : "listFrame",
- "__nameFrame" : "nameFrame",
- "__namesFrame" : "namesFrame",
- "__occurrenceFrame" : "occurrenceFrame",
- "__occurrencesFrame" : "occurrencesFrame",
- "__playerFrame" : "playerFrame",
- "__removeBtnHeader" : "removeButton",
- "__removeBtnRow" : "rowDel",
- "__resourceFrame" : "resourceFrame",
- "__roleFrame" : "roleFrame",
- "__rolesFrame" : "roleFrame",
- "__row" : "row",
- "__scopeFrame" : "scopeFrame",
- "__subjectIdentifierFrame" : "subjectIdentifier",
- "__subjectLocatorFrame" : "subjectLocator",
- "__textareaRow" : "rowTextArea",
- "__textRow" : "rowTextfield",
- "__tmIdsFrame" : "tmIdsFrame",
- "__tmIdsHeader" : "tmIdsHeaderRow",
- "__topicFrame" : "topicFrame",
- "__topicHeader" : "topicHeaderRow",
- "__topicIdFrame" : "topicId",
- "__topicStubFrame" : "topicStubFrame",
- "__topicStubsHeader" : "topicStubsHeaderRow",
- "__topicStubsFrame" : "topicStubsFrame",
- "__typeFrame" : "typeFrame",
- "__valueFrame" : "valueFrame",
- "__variantFrame" : "variantFrame",
- "__variantHeader" : "variantHeaderRow",
- "__variantsFrame" : "variantsFrame",
-
- "addBtnHeader" : function(){ return this.__button + " " + this.__addBtnHeader; },
- "associationFrame" : function(){ return this.__frame + " " + this.__associationFrame; },
- "associationsFrame" : function(){ return this.__frame + " " + this.__associationsFrame; },
- "associationsHeader" : function(){ return this.__associationsHeader; },
- "button" : function(){ this.__button; },
- "fragmentFrame" : function(){ return this.__frame + " " + this.__fragmentFrame; },
- "frame" : function(){ return this.__frame; },
- "header" : function(){ return this.__header; },
- "headerTitle" : function(){ return this.__headerTitle; },
- "hideBtnHeader" : function(){ return this.__button + " " + this.__hideBtnHeader; },
- "inAssociationFrame" : function(){ return this.__inAssociationFrame; },
- "inNameFrame" : function(){ return this.__inNameFrame; },
- "inOccurrenceFrame" : function(){ return this.__inOccurrenceFrame; },
- "inRoleFrame" : function(){ return this.__inRoleFrame; },
- "instanceOfFrame" : function(){ return this.__instanceOfFrame; },
- "inTopicFrame" : function(){ return this.__inTopicFrame; },
- "inTopicStubFrame" : function(){ return this.__inTopicStubFrame; },
- "inVariantFrame" : function(){ return this.__inVariantFrame; },
- "itemIdentityFrame" : function(){ return this.__itemIdentityFrame; },
- "listFrame" : function(){ return this.__frame + " " + this.__listFrame; },
- "nameFrame" : function(){ return this.__frame + " " + this.__nameFrame; },
- "namesFrame" : function(){ return this.__frame + " " + this.__namesFrame; },
- "occurrenceFrame" : function(){ return this.__frame + " " + this.__occurrenceFrame; },
- "occurrencesFrame" : function(){ return this.__frame + " " + this.__occurrencesFrame; },
- "playerFrame" : function(){ return this.__playerFrame; },
- "removeBtnHeader" : function(){ return this.__button + " " + this.__removeBtnHeader; },
- "removeBtnRow" : function(){ return this.__button + " " + this.__removeBtnRow; },
- "roleFrame" : function(){ return this.__frame + " " + this.__roleFrame; },
- "rolesFrame" : function(){ return this.__frame + " " + this.__rolesFrame; },
- "row" : function(){ return this.__row; },
- "scopeFrame" : function(){ return this.__scopeFrame; },
- "resourceFrame" : function(){ return this.__frame + " " + this.__resourceFrame; },
- "subjectIdentifierFrame" : function(){ return this.__subjectIdentifierFrame; },
- "subjectLocatorFrame" : function(){ return this.__subjectLocatorFrame; },
- "textareaRow" : function(){ return this.__textareaRow; },
- "textRow" : function(){ return this.__textRow; },
- "tmIdsFrame" : function(){ return this.__frame + " " + this.__tmIdsFrame; },
- "tmIdsHeader" : function(){ return this.__tmIdsHeader; },
- "topicFrame" : function(){ return this.__frame + " " + this.__topicFrame; },
- "topicHeader" : function(){ return this.__topicHeader; },
- "topicIdFrame" : function(){ return this.__topicIdFrame; },
- "topicStubFrame" : function(){ return this.__frame + " " + this.__topicStubFrame; },
- "topicStubsHeader" : function(){ return this.__topicStubsHeader; },
- "topicStubsFrame" : function(){ return this.__frame + " " + this.__topicStubsFrame; },
- "typeFrame" : function(){ return this.__typeFrame; },
- "valueFrame" : function(){ return this.__valueFrame; },
- "variantFrame" : function(){ return this.__frame + " " + this.__variantFrame; },
- "variantHeader" : function(){ return this.__variantHeader; },
- "variantsFrame" : function(){ return this.__frame + " " + this.__variantsFrame; }
+// --- A kind of enum for the the different pages with an attribute and a value
+var PAGES = {"home" : "home", "search" : "searchTopic", "edit" : "editTopic", "create" : "createTopic", "current" : ""};
+
+var ANY_URI = "http://www.w3.org/2001/XMLSchema#anyURI";
+var STRING = "http://www.w3.org/2001/XMLSchema#string";
+
+// --- Contains most css classes used in this project
+// --- There should be called only the function to be sure to don't override
+// --- the original values.
+var CLASSES = {"__divPage__" : "page",
+ "__divSubPage__" : "subPage",
+ "__divContent__" : "content",
+ "__divTextrowWithRemoveButton__" : "textrowWithRemoveButton",
+ "__divTextrowWithoutRemoveButton__" : "textrowWithoutRemoveButton",
+ "__divSelectrowWithRemoveButton__" : "selectrowWithRemoveButton",
+ "__divSelectrowWithoutRemoveButton__" : "selectrowWithoutRemoveButton",
+ "__spanClickable__" : "clickable",
+ "__notVisible__" : "notvisible",
+ "__divError__" : "errorMessage",
+ "__ulFragmentFrame__" : "fragmentFrame",
+ "__tableTopicFrame__" : "topicFrame",
+ "__trTopicIdFrame__" : "topicIdFrame",
+ "__tdContent__" : "content",
+ "__tdDescription__" : "description",
+ "__divInstanceOfFrame__" : "instanceOfFrame",
+ "__divItemIdentityFrame__" : "itemIdentityFrame",
+ "__divSubjectLocatorFrame__" : "subjectLocatorFrame",
+ "__divSubjectIdentifierFrame__" : "subjectIdentifierFrame",
+ "__divNameContainer__" : "nameContainer",
+ "__divNameFrame__" : "nameFrame",
+ "__trControlColumn__" : "controlColumn",
+ "__trShowHiddenRows__" : "showHiddenRows",
+ "__trTypeFrame__" : "typeFrame",
+ "__divScopeFrame__" : "scopeFrame",
+ "__divValueFrame__" : "valueFrame",
+ "__divVariantFrame__" : "variantFrame",
+ "__divVariantContainer__" : "variantContainer",
+ "__divDatatypeFrame__" : "datatypeFrame",
+
+ "page" : function(){ return this.__divPage__; },
+ "subPage" : function(){ return this.__divSubPage__; },
+ "content" : function(){ return this.__divContent__; },
+ "textrowWithRemoveButton" : function(){ return this.__divTextrowWithRemoveButton__; },
+ "textrowWithoutRemoveButton" : function(){ return this.__divTextrowWithoutRemoveButton__; },
+ "selectrowWithRemoveButton" : function(){ return this.__divSelectrowWithRemoveButton__; },
+ "selectrowWithoutRemoveButton" : function(){ return this.__divSelectrowWithoutRemoveButton__; },
+ "clickable" : function(){ return this.__spanClickable__; },
+ "notVisible" : function(){ return this.__notVisible__; },
+ "error" : function(){ return this.__divError__; }, "fragmentFrame" : function(){ return this.__ulFragmentFrame__; },
+ "topicFrame" : function(){ return this.__tableTopicFrame__; },
+ "topicIdFrame" : function(){ return this.__trTopicIdFrame__; },
+ "content" : function(){ return this.__tdContent__; },
+ "description" : function(){ return this.__tdDescription__; },
+ "instanceOfFrame" : function(){ return this.__divInstanceOfFrame__; },
+ "itemIdentityFrame" : function(){ return this.__divItemIdentityFrame__; },
+ "subjectLocatorFrame" : function(){ return this.__divSubjectLocatorFrame__; },
+ "subjectIdentifierFrame" : function(){ return this.__divSubjectIdentifierFrame__; },
+ "nameContainer" : function(){ return this.__divNameContainer__; },
+ "nameFrame" : function(){ return this.__divNameFrame__; },
+ "controlColumn" : function(){ return this.__trControlColumn__; },
+ "showHiddenRows" : function(){ return this.__trShowHiddenRows__; },
+ "typeFrame" : function(){ return this.__trTypeFrame__; },
+ "scopeFrame" : function(){ return this.__divScopeFrame__; },
+ "valueFrame" : function(){ return this.__divValueFrame__; },
+ "variantFrame" : function(){ return this.__divVariantFrame__; },
+ "variantContainer" : function(){ return this.__divVariantContainer__; },
+ "datatypeFrame" : function(){ return this.__divDatatypeFrame__; }
};
\ No newline at end of file
Added: trunk/src/ajax/javascripts/create.js
==============================================================================
--- (empty file)
+++ trunk/src/ajax/javascripts/create.js Tue May 19 05:23:26 2009
@@ -0,0 +1,63 @@
+//+-----------------------------------------------------------------------------
+//+ Isidorus
+//+ (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
+//+
+//+ Isidorus is freely distributable under the LGPL license.
+//+ This ajax module uses the frameworks PrototypeJs and Scriptaculous, both
+//+ are distributed under the MIT license.
+//+ You can find a detailed description in trunk/docs/LGPL-LICENSE.txt and
+//+ in trunk/src/ajax/javascripts/external/MIT-LICENSE.txt.
+//+-----------------------------------------------------------------------------
+
+
+function makeCreate(psi)
+{
+ var content = new Element("div", {"class" : CLASSES.content()});
+ var header = new Element("h1").update("Create a Topic");
+ content.insert(header, {"position" : "bottom"});
+ $(CLASSES.subPage()).insert(content, {"position" : "bottom"});
+
+ try{
+ var fragmentFrame = new Element("ul", {"class" : CLASSES.fragmentFrame()});
+ content.insert({"bottom" : fragmentFrame});
+ var liTopicSelect = new Element("li", {"class" : CLASSES.instanceOfFrame()});
+ fragmentFrame.insert({"bottom" : liTopicSelect});
+
+
+ function makeInstanceOfFrame(context){
+ function makeFragment(psis, constraints){
+ var items = $$("li." + CLASSES.topicFrame());
+ for(var i = 0; i != items.length; ++i){
+ items[i].remove();
+ }
+
+ var topic = new TopicC(null, (constraints ? constraints.topicConstraints : null));
+ context.insert({"after" : new Element("li", {"class" : CLASSES.topicFrame()}).update(topic.getFrame())});
+ }
+
+ function onSuccessHandler(xhr){
+ var json = null;
+ try{
+ json = xhr.responseText.evalJSON();
+ }
+ catch(innerErr){
+ alert("Got bad JSON data from " + xhr.request.url + "\n\n" + innerErr);
+ }
+ var instanceOf = null;
+ try{
+ instanceOf = new InstanceOfC(json.flatten().sort(), makeFragment);
+ context.insert({"bottom" : instanceOf.getFrame()});
+ }
+ catch(innerErr){
+ alert("There occurred an error by creating an InstanceOfC frame, please reload this page!\n\n" + innerErr);
+ }
+ }
+
+ getTypePsis(onSuccessHandler, null);
+ }
+
+ makeInstanceOfFrame(liTopicSelect);
+ }catch(err){
+ alert(err);
+ }
+}
\ No newline at end of file
Added: trunk/src/ajax/javascripts/datamodel.js
==============================================================================
--- (empty file)
+++ trunk/src/ajax/javascripts/datamodel.js Tue May 19 05:23:26 2009
@@ -0,0 +1,1158 @@
+//+-----------------------------------------------------------------------------
+//+ Isidorus
+//+ (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
+//+
+//+ Isidorus is freely distributable under the LGPL license.
+//+ This ajax module uses the frameworks PrototypeJs and Scriptaculous, both
+//+ are distributed under the MIT license.
+//+ You can find a detailed description in trunk/docs/LGPL-LICENSE.txt and
+//+ in trunk/src/ajax/javascripts/external/MIT-LICENSE.txt.
+//+-----------------------------------------------------------------------------
+
+// --- The base class of all Frames defined in this file.
+var FrameC = Class.create({"initialize" : function(content, owner, min, max){
+ if(!owner) throw "From FrameC(): 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;
+ if(!owner.__frames__) owner.__frames__ = new Array();
+ owner.__frames__.push(this);
+
+ this.__frame__ = new Element("div");
+ this.__remove__ = new Element("span", {"class" : CLASSES.clickable()}).update("-");
+ this.__add__ = new Element("span", {"class" : CLASSES.clickable()}).update("+");
+
+ checkRemoveAddButtons(owner, min, max);
+
+ this.__error__ = new Element("div", {"class" : CLASSES.error()});
+ this.__error__.hide();
+ this.__content__ = new Element("span").update(content);
+
+ this.__frame__.insert({"bottom" : this.__remove__});
+ this.__frame__.insert({"bottom" : this.__content__});
+ this.__frame__.insert({"bottom" : this.__add__});
+ this.__frame__.insert({"bottom" : this.__error__});
+
+ setRemoveAddHandler(this, owner, min, max, function(){
+ return new FrameC("", owner, min, max);
+ });
+ },
+ "getFrame" : function(){
+ return this.__frame__;
+ },
+ "remove" : function(){
+ return this.getFrame().remove();
+ },
+ "hide" : function(){
+ this.getFrame().hide();
+ },
+ "show" : function(){
+ this.getFrame().show();
+ },
+ "getContent" : function(){
+ return this.__content__.textContent;
+ },
+ "toJSON" : function(){
+ return this.getContent().toJSON();
+ },
+ "showError" : function(message){
+ this.__error__.update(message);
+ this.__error__.show();
+ },
+ "hideError" : function(){
+ this.__error__.hide();
+ },
+ "hideRemoveButton" : function(){
+ this.__remove__.hide();
+ },
+ "showRemoveButton" : function(){
+ this.__remove__.show();
+ },
+ "hideAddButton" : function(){
+ this.__add__.hide();
+ },
+ "showAddButton" : function(){
+ this.__add__.show();
+ },
+ "append" : function(elem){
+ return this.getFrame().insert({"after" : elem});
+ }});
+
+
+// --- 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){
+ $super(content, owner, min, max);
+ owner.__frames__.pop();
+ owner.__frames__.push(this);
+
+ this.__regexp__ = new RegExp(regexp);
+ this.__frame__.writeAttribute({"class" : CLASSES.textrowWithRemoveButton()});
+ this.__content__.remove();
+ this.__content__ = new Element("input", {"type" : "text", "value" : content});
+ if(cssTitle && cssTitle.length){
+ this.__content__.writeAttribute({"title" : cssTitle});
+ }
+ this.__remove__.insert({"after" : this.__content__});
+
+ checkRemoveAddButtons(owner, min, max);
+ setRemoveAddHandler(this, owner, min, max, function(){
+ return new TextrowC("", regexp, owner, min, max, cssTitle);
+ });
+ },
+ "getContent" : function(){
+ return this.__content__.value;
+ },
+ "isValid" : function(){
+ return this.__regexp__.match(this.getContent());
+ },
+ "showRemoveButton" : function($super){
+ this.__remove__.show();
+ this.getFrame().writeAttribute({"class" : CLASSES.textrowWithRemoveButton()});
+ },
+ "hideRemoveButton" : function(){
+ this.__remove__.hide();
+ this.getFrame().writeAttribute({"class" : CLASSES.textrowWithoutRemoveButton()});
+ }});
+
+
+// --- This class represents a selectrow with the functionality of FrameC.
+var SelectrowC = Class.create(FrameC, {"initialize" : function($super, contents, owner, min, max){
+ if(!contents || !contents.length)throw "From SelectrowC(): contents must be an array!";
+ $super(contents, owner, min, max);
+ owner.__frames__.pop();
+ owner.__frames__.push(this);
+
+ this.__frame__.writeAttribute({"class" : CLASSES.selectrowWithRemoveButton()});
+ this.__content__.remove();
+ this.__content__ = new Element("select");
+ for(var i = 0; i != contents.length; ++i){
+ // --- the attribute value must be set for IE
+ this.__content__.insert({"bottom" : new Element("option", {"value" : contents[i]}).update(contents[i])});
+ }
+ this.__remove__.insert({"after" : this.__content__});
+
+ checkRemoveAddButtons(owner, min, max);
+ setRemoveAddHandler(this, owner, min, max, function(){
+ return new SelectrowC(contents, owner, min, max);
+ });
+ },
+ "getContent" : function(){
+ return this.__content__.value;
+ },
+ "showRemoveButton" : function(){
+ this.__remove__.show();
+ this.getFrame().writeAttribute({"class" : CLASSES.selectrowWithRemoveButton()});
+ },
+ "hideRemoveButton" : function(){
+ this.__remove__.hide();
+ this.getFrame().writeAttribute({"class" : CLASSES.selectrowWithoutRemoveButton()});
+ }});
+
+
+// --- The base Class for alomost all frames which contains other frames like names, occurrences, ...
+var ContainerC = Class.create({"initialize" : function(){
+ this.__frame__ = new Element("div");
+ this.__error__ = new Element("div", {"class" : CLASSES.error()});
+ this.__error__.hide();
+ this.__frame__.insert({"bottom" : this.__error__});
+ },
+ "hide" : function(){
+ this.__frame__.hide();
+ },
+ "show" : function(){
+ this.__frame__.show();
+ },
+ "getFrame" : function(){
+ return this.__frame__;
+ },
+ "getContent" : function(unique, removeNull){
+ return "";
+ },
+ "toJSON" : function(unique, removeNull){
+ return this.getContent(unique, removeNull).toJSON();
+ },
+ "showError" : function(message){
+ this.__error__.update(message);
+ this.__error__.show();
+ },
+ "hideError" : function(){
+ this.__error__.hide();
+ },
+ "append" : function(newElem){
+ this.getFrame().insert({"after" : newElem});
+ },
+ "remove" : function(){
+ this.getFrame().remove();
+ }});
+
+
+// --- Represents a container for all instanceOf-Psis of a fragment's topic
+var InstanceOfC = Class.create(ContainerC, {"initialize" : function($super, contents, successFun){
+ $super();
+ this.__frame__.writeAttribute({"class" : CLASSES.instanceOfFrame()});
+ this.__container__ = new Object();
+ try{
+ var row = new SelectrowC(contents, this.__container__, 1, -1);
+ this.__error__.insert({"before" : row.getFrame()});
+ }
+ catch(err){
+ throw "From InstanceOfC(): The following exception was thrown:\n" + err;
+ this.__container__ = null;
+ }
+ this.__commit__ = new Element("input", {"type" : "button", "value" : "get constraints"});
+
+ function setHandler(myself){
+ function onSuccessHandler(xhr){
+ var json = null;
+ try{
+ json = xhr.responseText.evalJSON();
+ }
+ catch(err){
+ alert("Got bad JSON data from " + xhr.request.url + "!\n\n" + err);
+ }
+
+ var ret = checkExclusiveInstances(json, myself.getContent(true));
+ if(ret){
+ var str = "Some topics own exclusive-instance-constraints, please deselect the corresponding topics!<br/>";
+ for(var i = 0; i != ret.length; ++i){
+ for(var j = 0; j != ret[i].length; ++j){
+ if(j === 0){
+ str += "<br/>" + ret[i][j];
+ }
+ else {
+ str += " " + ret[i][j];
+ }
+ str += "<br/>";
+ }
+ }
+ var items = $$("li." + CLASSES.topicFrame());
+ for(var i = 0; i != items.length; ++i){
+ items[i].remove();
+ }
+ myself.showError(str);
+ }
+ else {
+ successFun(contents, json);
+ }
+ }
+
+ myself.__commit__.observe("click", function(event){
+ myself.hideError();
+ requestConstraints(myself.toJSON(true), onSuccessHandler, null);
+ });
+ }
+ setHandler(this);
+
+ this.__error__.insert({"before" : this.__commit__});
+ },
+ "getContent" : function(unique, removeNull){
+ var values = new Array();
+ for(var i = 0; i != this.__container__.__frames__.length; ++i){
+ if(unique === true && values.indexOf(this.__container__.__frames__[i].getContent()) !== -1) continue;
+ if(removeNull === true && this.__container__.__frames__[i].getContent().strip().length === 0) continue;
+ values.push(this.__container__.__frames__[i].getContent().strip());
+ }
+ return values;
+ }});
+
+
+
+// --- Representation of a itemIdentity frame.
+var ItemIdentityC = Class.create(ContainerC, {"initialize" : function($super, contents){
+ $super();
+ this.__frame__.writeAttribute({"class" : CLASSES.itemIdentityFrame()});
+ this.__container__ = new Object();
+
+ try{
+ for(var i = 0; i != contents.length; ++i){
+ new TextrowC(contents[i], ".*", this.__container__, 1, -1, null);
+ this.__error__.insert({"before" : this.__container__.__frames__[i].getFrame()});
+ }
+ }
+ catch(err){
+ this.__container__ = new Object();
+ new TextrowC("", ".*", this.__container__, 1, -1, null);
+ this.__error__.insert({"before" : this.__container__.__frames__[i].getFrame()});
+ }
+ },
+ "getContent" : function(unique, removeNull){
+ var values = new Array();
+ for(var i = 0; i != this.__container__.__frames__.length; ++i){
+ if(unique === true && values.indexOf(this.__container__.__frames__[i].getContent()) !== -1) continue;
+ if(removeNull === true && this.__container__.__frames__[i].getContent().strip().length === 0) continue;
+ values.push(this.__container__.__frames__[i].getContent().strip());
+ }
+ return values;
+ },
+ "toJSON" : function(unique, removeNull){
+ var content = this.getContent(unique, removeNull);
+ return content.length === 0 ? "null" : content.toJSON();
+ }});
+
+
+// --- Representation of a subjectLocator and subjectIdentifier frames.
+var IdentifierC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints, cssClass){
+ $super();
+ this.__frame__.writeAttribute({"class" : cssClass});
+ this.__containers__ = new Array();
+
+ try{
+ if((!contents || contents.length === 0) && constraints && constraints.length > 0){
+ 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) : "*";
+ 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 row = new TextrowC("", constraints[i].regexp, this.__containers__[i],
+ min === 0 ? 1 : min, max === "*" ? -1 : max, cssTitle);
+ this.__error__.insert({"before" : row.getFrame()});
+ }
+ }
+ }
+ }
+ else {
+ // TODO: check already existing contents and order them to the corresponding fields
+ }
+ }
+ catch(err){
+ alert("From IdentifierC(): " + err);
+ }
+ },
+ "getContent" : function(unique, removeNull){
+ var values = new Array();
+ for(var i = 0; i != this.__containers__.length; ++i){
+ for(var j = 0; j != this.__containers__[i].__frames__.length; ++j){
+ if(unique === true && values.indexOf(this.__containers__[i].__frames__[j].getContent()) !== -1) continue;
+ if(removeNull === true && this.__containers__[i].__frames__[j].getContent().strip().length === 0) continue;
+ values.push(this.__containers__[i].__frames__[j].getContent().strip());
+ }
+ }
+ return values;
+ },
+ "isValid" : function(){
+ // TODO: check the validity of this frame with the passed constraints and return a boolean value
+ return true;
+ }});
+
+
+// --- Represantation of a scope frame, doesn't contain SelectrowCs, because the values must be unique!
+// --- So this class uses another implementation.
+var ScopeC = Class.create(ContainerC, {"initialize" : function($super, contents, min, max){
+ $super();
+ this.__frame__.writeAttribute({"class" : CLASSES.scopeFrame()});
+ this.__error__ = this.__error__.remove();
+
+ this.__container__ = null;
+ this.__contents__ = contents;
+ this.resetRows(this.__contents__, min, max);
+ },
+ "resetRows" : function(contents, min, max){
+ try{
+ for(var i = 0; i != this.__container__.__frames__.length; ++i){
+ this.__container__.__frames__[i].remove();
+ }
+ this.__container__ = new Object();
+ }
+ catch(err){
+ this.__container__ = new Object();
+ };
+
+ this.__contents__ = contents;
+ if(!contents || contents.length < min) throw "From ScopeC.resetRows(): contents.length (" +
+ (contents ? contents.length : "null") + ") must be > min (" + min + ")!";
+ if(max !== -1 && (min > max || max === 0))throw "From FrameC(): min must be > max(" + max + ") and > 0 but is " + min;
+
+
+ var options = new Array();
+ for(var i = 0; i != contents.length; ++i){
+ var topicPsis = new Array();
+ for(var j = 0; j != contents[i].length; ++j){
+ for(var k = 0; k != contents[i][j].length; ++k){
+ topicPsis.push(contents[i][j][k]);
+ }
+ }
+ options.push(topicPsis);
+ }
+
+ function checkValues(myself){
+ var rows = myself.getFrame().select("div");
+ var selectedItems = new Array();
+ // --- collects all old selected values and removes the option elements
+ for(var i = 0; i != rows.length; ++i){
+ var selects = rows[i].select("select");
+ if(selects[0].value.strip().length !== 0) selectedItems.push(selects[0].value);
+ selects[0].update("");
+ }
+
+ // --- recreates the original values
+ var values = options.clone();
+ for(var i = 0; i != rows.length && i != selectedItems.length; ++i){
+ var select = rows[i].select("select")[0];
+ var selectedIdx = new Array();
+ for(var j = 0; j != values.length; ++j){
+ if(values[j].indexOf(selectedItems[i]) !== -1){
+ for(var k = 0; k != values[j].length; ++k){
+ select.insert({"bottom" : new Element("option", {"value" : values[j][k]}).update(values[j][k])});
+ if(values[j][k] === selectedItems[i])select.writeAttribute({"selected" : "selected"});
+ //values = values.without(values[j]);
+ selectedIdx.push(j);
+ }
+ break;
+ }
+ }
+ var cleanedValues = new Array();
+ for(var k = 0; k != values.length; ++k){
+ if(selectedIdx.indexOf(k) === -1){
+ cleanedValues.push(values[k]);
+ }
+ }
+ values = cleanedValues;
+ }
+
+ // --- fills all empty select elements
+ for(var i = 0; i != rows.length; ++i){
+ var select = rows[i].select("select")[0];
+ if(select.childElements().length === 0 && values.length !== 0){
+ for(var j = 0; j != values[0].length; ++j){
+ select.insert({"bottom" : new Element("option", {"value" : values[0][j]}).update(values[0][j])});
+ }
+ values.shift();
+ }
+ }
+
+ // --- adds the values which wasn't distributed
+ for(var i = 0; i != rows.length; ++i){
+ var select = rows[i].select("select")[0];
+ for(var j = 0; j != values.length; ++j){
+ for(var k = 0; k != values[j].length; ++k){
+ select.insert({"bottom" : new Element("option" , {"value" :values[j][k]}).update(values[j][k])});
+ }
+ }
+ }
+ }// checkValues
+
+
+ function addHandlers(myself){
+ var rows = myself.getFrame().select("div");
+ checkValues(myself);
+
+ function addHandler(event){
+ var div = new Element("div", {"class" : CLASSES.selectrowWithRemoveButton()});
+ myself.getFrame().insert({"bottom" : div});
+ var select = new Element("select");
+ div.insert({"top" : select});
+ addHandlers(myself);
+ }
+
+ function removeHandler(event){
+ event.element().up().remove();
+ addHandlers(myself);
+ }
+
+ for(var i = 0; i != rows.length; ++i){
+ var spans = rows[i].select("span." + CLASSES.clickable());
+ var removeS = null;
+ var addS = null;
+ if(spans.length === 0){
+ removeS = new Element("span", {"class" : CLASSES.clickable()}).update("-");
+ removeS.observe("click", removeHandler);
+ addS = new Element("span", {"class" : CLASSES.clickable()}).update("+");
+ addS.observe("click", addHandler);
+ rows[i].insert({"top" : removeS});
+ rows[i].insert({"bottom" : addS});
+ }
+ else {
+ removeS = spans[0];
+ addS = spans[1];
+ }
+
+ if(max === -1 || max > rows.length){
+ addS.show()
+ }
+ else {
+ addS.hide();
+ }
+
+ if(min !== -1 || min < rows.length){
+ removeS.show()
+ rows[i].writeAttribute({"class" : CLASSES.selectrowWithRemoveButton()});
+ }
+ else {
+ removeS.hide();
+ rows[i].writeAttribute({"class" : CLASSES.selectrowWithoutRemoveButton()});
+ }
+ if(i == 0 && rows.length === 1 && max > 1){
+ rows[i].writeAttribute({"class" : CLASSES.selectrowWithoutRemoveButton()});
+ removeS.hide();
+ }
+ }
+ } // addHandlers
+
+ for(var i = 0; i != (min === -1 ? 1 : min); ++i){
+ var div = new Element("div", {"class" : CLASSES.selectrowWithoutRemoveButton()});
+ var select = new Element("select");
+ for(var j = 0; j != options.length; ++j){
+ if(j === i || j > min){
+ for(var k = 0; k != options[j].length; ++k){
+ select.insert({"bottom" : new Element("option", {"value" : options[j][k]}).update(options[j][k])});
+ }
+ }
+ }
+
+
+ div.insert({"top" : select});
+ this.getFrame().insert({"bottom" : div});
+ addHandlers(this);
+ }
+ },
+ "getContent" : function(unique, removeNull){
+ // --- unique and removeNull aren't be used, they exist only for consistency
+ var values = new Array();
+ var rows = this.getFrame().select("div");
+ for(var i = 0; i != rows.length; ++i){
+ values.push(new Array(rows[i].select("select")[0].value)); // must be a list of lists
+ }
+ return values;
+ }
+ });
+
+
+
+// --- Representation of a variant element
+var VariantC = Class.create(ContainerC, {"initialize" : function($super, contents, owner){
+ $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__});
+
+ 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);
+ });
+
+ // --- scopes
+ this.__scopes__ = null;
+ //TODO: implement -> also in the server
+ this.__table__.insert({"bottom" : newRow(CLASSES.scopeFrame(), "Scope", new Element("div"))});
+
+ // --- resourceValue
+ var value = "";
+ var datatype = "";
+ if(contents && contents.resourceRef && contents.resourceRef.length !== 0){
+ value = contents.resourceRef;
+ datatype = ANY_URI;
+ }
+ else if(contents && contents.resourceData){
+ value = contents.resourceData.value;
+ datatype = contents.resourceData.datatype;
+ }
+
+ this.__value__ = new Element("textarea", {"rows" : 3}).update(value);
+ this.__table__.insert({"bottom" : newRow(CLASSES.valueFrame(), "Resource Value", this.__value__)});
+
+ // --- datatype
+ this.__datatype__ = new Object();
+ new TextrowC(datatype, ".*", this.__datatype__, 1, 1, null);
+ this.__table__.insert({"bottom" : newRow(CLASSES.datatypeFrame(), "Datatype", this.__datatype__.__frames__[0].getFrame())});
+
+ // --- minimize
+ this.minimize();
+ }
+ catch(err){
+ alert("From VariantC(): " + err);
+ }
+ },
+ "getContent" : function(){
+ var resourceRef = null;
+ var resourceData = null;
+ if(this.__datatype__.__frames__[0].getContent() === ANY_URI){
+ resourceRef = this.__value__.textContent.strip();
+ }
+ else {
+ var datatype = STRING;
+ if(this.__datatype__.__frames__[0].getContent().strip() !== "")
+ datatype = this.__datatype__.__frames__[0].getContent().strip();
+ resoureceData = {"datatype" : datatype, "value" : this.__value__.textContent.strip()};
+ }
+
+ // TODO: scopes
+ if(this.__itemIdentity__.getContent(true, true).length === 0 &&
+ resourceRef === null && resourceData === null) return null;
+ return {"itemIdentities" : this.__itemIdentity__.getContent(true, true),
+ "scopes" : null,
+ "resourceRef" : resourceRef,
+ "resourceData" : resourceData};
+
+ },
+ "toJSON" : function(){
+ var resourceRef = null;
+ var resourceData = null;
+ if(this.__datatype__.__frames__[0].getContent() === ANY_URI){
+ resourceRef = this.__value__.value.strip().toJSON();
+ }
+ else {
+ var datatype = STRING.toJSON();
+ if(this.__datatype__.__frames__[0].getContent().strip() !== "")
+ datatype = this.__datatype__.__frames__[0].getContent().strip().toJSON();
+ resourceData = "{\"datatype\":" + datatype + ",\"value\":" + this.__value__.value.strip().toJSON() + "}";
+ }
+
+ // TODO: scopes
+ return "{\"itemIdentities\":" + this.__itemIdentity__.toJSON(true, true) +
+ ",\"scopes\":null,\"resourceRef\":" + resourceRef + ",\"resourceData\":" + resourceData + "}";
+
+ },
+ "isValid" : function(){
+ 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();
+ },
+ "showAddButton" : function(){
+ this.__add__.show();
+ },
+ "hideAddButton" : function(){
+ this.__add__.hide();
+ },
+ "minimize" : function(){
+ var trs = this.__table__.select("tr");
+ for(var i = 0; i != trs.length; ++i){
+ if(i === 0) trs[i].show();
+ else trs[i].hide();
+ }
+ }
+ });
+
+
+// --- contains all variants of a name element
+var VariantContainerC = Class.create(ContainerC, {"initialize" : function($super, contents){
+ $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__);
+ this.__frame__.insert({"bottom" : variant.getFrame()});
+ }
+ }
+ else {
+ var variant = new VariantC(null, this.__container__);
+ this.__frame__.insert({"bottom" : variant.getFrame()});
+ }
+ },
+ "getContent" : function(){
+ var values = new Array();
+ for(var i = 0; i != this.__container__.__frames__.length; ++i){
+ if(this.__container__.__frames__[i].isUsed() === true){
+ values.push(this.__container__.__frames__[i].getContent());
+ }
+ }
+ return values;
+ },
+ "isValid" : function(){
+ 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;
+ }
+ return true;
+ },
+ "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 += ","
+ }
+ }
+ str += "]";
+ return str === "[]" ? null : str;
+ }});
+
+
+// --- representation of a name element
+var NameC = Class.create(ContainerC, {"initialize" : function($super, contents, nametypescopes, simpleConstraint, owner, min, max, cssTitle){
+ $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;
+ if(!owner.__frames__) owner.__frames__ = new Array();
+ owner.__frames__.push(this);
+
+ this.__frame__.writeAttribute({"class" : CLASSES.nameFrame()});
+ this.__table__ = new Element("table", {"class" : CLASSES.nameFrame()});
+ this.__frame__.insert({"top" : this.__table__});
+
+ 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);
+ });
+
+ // --- type
+ var types = new Array();
+ for(var i = 0; nametypescopes && i !== nametypescopes.length; ++i){
+ for(j = 0; j != nametypescopes[i].nameType.length; ++j){
+ types.push(nametypescopes[i].nameType[j]);
+ if(contents && contents.type && contents.type[0] === nametypescopes[i].nameType[j]){
+ var sslected = nametypescopes[i].nameType[j];
+ types[types.length - 1] = types[0];
+ types[0] = selected;
+ }
+ }
+ }
+ this.__type__ = new Object();
+ var tr = newRow(CLASSES.typeFrame(), "Type", new SelectrowC(types, this.__type__, 1, 1).getFrame());
+ this.__table__.insert({"bottom" : tr});
+
+ // --- scopes
+ this.__scopes__ = null;
+ if(nametypescopes && nametypescopes[0].scopeConstraints){
+ // TODO: pass the selected items seperately to the object, so they can be chosen as default
+ var scopeTypes = nametypescopes[0].scopeConstraints[0].scopeTypes;
+ var min = parseInt(nametypescopes[0].scopeConstraints[0].cardMin);
+ var max = nametypescopes[0].scopeConstraints[0].cardMax !== "MAX_INT" ? parseInt(nametypescopes[0].scopeConstraints[0].cardMax) : "*";
+ this.__scopes__ = new ScopeC(scopeTypes, min === 0 ? 1 : min, max === "*" ? -1 : max);
+ tr = newRow(CLASSES.scopeFrame(), "Scope", this.__scopes__.getFrame());
+ this.__table__.insert({"bottom" : tr});
+ }
+ else {
+ var tr = new Element("tr", {"class" : CLASSES.scopeFrame()});
+ var tdd = new Element("td", {"class" : CLASSES.description()}).update("Scope");
+ var tdc = new Element("td", {"class" : CLASSES.content()});
+ tr.insert({"top" : tdd});
+ tr.insert({"bottom" : tdc});
+ this.__table__.insert({"bottom" : tr});
+ }
+
+ // --- value
+ this.__value__ = new Object();
+ var cssTitleV = "min: " + min + " max: " + max + " regular expression: " + (simpleConstraint ? simpleConstraint.regexp : ".*");
+ new TextrowC((contents && contents.value ? 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.__table__.insert({"bottom" : newRow(CLASSES.variantContainer(), "Variants", this.__variants__.getFrame())});
+
+ // --- adds a second show handler, so the variants will be hidden, when the entire
+ // --- name element will be shown
+ function addSecondShowHandler(myself){
+ myself.__table__.select("tr")[0].observe("click", function(event){
+ try{
+ for(var i = 0; i != myself.__variants__.__container__.__frames__.length; ++i){
+ myself.__variants__.__container__.__frames__[i].minimize();
+ }
+ }catch(tmp){ alert(tmp);}
+ });
+ }
+
+ addSecondShowHandler(this);
+ }
+ catch(err){
+ alert("From NameC(): " + err);
+ }
+ },
+ "getContent" : function(){
+ if(this.isUsed() === false) return null;
+ return {"itemIdentities" : this.__itemIdentity__.getContent(true, true),
+ "scopes" : this.__scopes__.getContent(),
+ "value" : this.__value__.__frames__[0].getContent(),
+ "variants" : this.__variants__.getContent()};
+ },
+ "toJSON" : function(){
+ if(this.isUsed() === false) return "null";
+ return "{\"itemIdentities\":" + this.__itemIdentity__.toJSON(true, true) +
+ ",\"type\":[" + this.__type__.__frames__[0].toJSON() +
+ "],\"scopes\":" + (this.__scopes__ ? this.__scopes__.toJSON() : "null") +
+ ",\"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;
+ },
+ "showRemoveButton" : function(){
+ this.__remove__.show();
+ },
+ "hideRemoveButton" : function(){
+ this.__remove__.hide();
+ },
+ "showAddButton" : function(){
+ this.__add__.show();
+ },
+ "hideAddButton" : function(){
+ this.__add__.hide();
+ },
+ "isValid" : function(){
+ // TODO: check the content and the constraints + variants.isValid()
+ return true;
+ }});
+
+
+
+// --- contains all names of a topic
+var NameContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints){
+ $super();
+ this.__frame__.writeAttribute({"class" : CLASSES.nameContainer()});
+ this.__containers__ = new Array();
+
+ try{
+ if((!contents || contents.length === 0) && constraints && constraints.length > 0){
+ for(var i = 0; i != constraints.length; ++i){
+ this.__containers__.push(new Array());
+ 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 regexp = constraints[i].constraints[j].regexp;
+ if(max !== 0){
+ var title = "min: " + min + " max: " + max + " regular expression: " + constraints[i].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.__error__.insert({"before" : name.getFrame()});
+ }
+ }
+ }
+ }
+ else {
+ // TODO: check already existing contents and order them to the corresponding fields
+ }
+ }
+ catch(err){
+ alert("From NameContainerC(): " + err);
+ }
+ },
+ "getContent" : function(){
+ var values = 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){
+ values.push(this.__containers__[i][j].__frames__[k].getContent());
+ }
+ }
+ }
+ }
+ return values;
+ },
+ "toJSON" : function(){
+ var str = "[";
+ 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){
+ str += this.__containers__[i][j].__frames__[k].toJSON() + ",";
+ }
+ }
+ }
+ }
+ if(str.endsWith(",")) str = str.slice(0, str.length - 1);
+ str += "]";
+ return str === "[]" ? null : str;
+ },
+ "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 OccurrenceC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints, owner, min, max, cssTitl){
+
+},
+ "getContent" : function(){
+ // TODO: implement
+ },
+ "toJSON" : function(){
+ // TODO: implement
+ },
+ "isUsed" : function(){
+ // TODO: implement
+ },
+ "showRemoveButton" : function(){
+ this.__remove__.show();
+ },
+ "hideRemoveButton" : function(){
+ this.__remove__.hide();
+ },
+ "showAddButton" : function(){
+ this.__add__.show();
+ },
+ "hideAddButton" : function(){
+ this.__add__.hide();
+ },
+ "isValid" : function(){
+ // TODO: check the content and the constraints
+ return true;
+ }});
+
+
+
+var OccurrenceContainerC = Class.create(ContainerC, {"initialize" : function($super, contents, constraints){
+
+},
+ "isValid" : function(){
+ // TODO: implement this method
+ return true;
+ },
+ "getContent" : function(){
+ // TODO: implement this method
+ },
+ "toJSON" : function(){
+ // TODO: implement this method
+ }});
+
+
+
+
+
+var TopicC = Class.create(ContainerC, {"initialize" : function($super, content, constraints){
+ $super();
+ try{
+ this.__frame__ .writeAttribute({"class" : CLASSES.topicFrame()});
+ this.__table__ = new Element("table", {"class" : CLASSES.topicFrame()});
+ this.__frame__.insert({"top" : this.__table__});
+ this.__caption__ = new Element("caption").update("Topic");
+ this.__table__.insert({"top" : this.__caption__});
+
+ // --- topic id
+ this.__topicid__ = new Object();
+ new TextrowC((content ? content.topicid : null), ".*", this.__topicid__, 1, 1, null);
+ this.__table__.insert({"bottom" : newRow(CLASSES.topicIdFrame(), "Topic ID", this.__topicid__.__frames__[0].getFrame())});
+
+ // --- itemIdentity
+ this.__itemIdentity__ = new ItemIdentityC(content ? content.itemIdentities : null);
+ this.__table__.insert({"bottom" : newRow(CLASSES.itemIdentityFrame(), "ItemIdentity", this.__itemIdentity__.getFrame())});
+
+ // --- subjectLocator
+ var _contents = (content ? content.subjectLocators : null);
+ var _constraints = (constraints ? constraints.subjectLocatorConstraints : null);
+ this.__subjectLocator__ = new IdentifierC(_contents, _constraints, CLASSES.subjectLocatorFrame());
+ this.__table__.insert({"bottom" : newRow(CLASSES.subjectLocatorFrame(), "SubjectLocator", this.__subjectLocator__.getFrame())});
+
+ // --- subjectIdentifier
+ _contents = (content ? content.subjectIdentifiers : null);
+ _constraints = (constraints ? constraints.subjectIdentifierConstraints : null);
+ this.__subjectIdentifier__ = new IdentifierC(_contents, _constraints, CLASSES.subjectIdentifierFrame());
+ this.__table__.insert({"bottom" : newRow(CLASSES.subjectIdentifierFrame(), "SubjectIdentifier", this.__subjectIdentifier__.getFrame())});
+
+ // --- names
+ _contents = (content ? content.names : null);
+ _constraints = (constraints ? constraints.topicNameConstraints : null);
+ this.__name__ = new NameContainerC(_contents, _constraints);
+ this.__table__.insert({"bottom" : newRow(CLASSES.nameContainer(), "Names", this.__name__.getFrame())});
+
+
+
+
+
+
+
+
+
+
+ var tmp = new Element("input", {"type" : "button", "value" : "test"});
+ function tester(myself){
+ tmp.observe("click", function(event){
+ //alert(myself.__subjectLocator__.getContent() + " -> " + myself.__subjectLocator__.toJSON() + "\n\n" + myself.__subjectLocator__.getContent(true, true) + " -> " + myself.__subjectLocator__.toJSON(true, true));
+
+ });
+ };
+ tester(this);
+ this.__frame__.insert({"bottom" : tmp});
+ }catch(err){
+ alert("From TopciC(): " + err);
+ }
+ },
+ "getContent" : function(){
+ return {"id" : this.__topicid__.__frames__[0].getContent };
+ }
+ });
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// --- helper function to create a dom-fragment of the form
+// --- <tr class="rowClass"><td class="description">description</td>
+//---- <td class="content">content</td></tr>
+function newRow(rowClass, description, content){
+ var tr = new Element("tr", {"class" : rowClass});
+ tr.insert({"top" : new Element("td", {"class" : CLASSES.description()}).update(description)});
+ tr.insert({"bottom" : new Element("td", {"class" : CLASSES.content()}).update(content)});
+ return tr;
+}
+
+
+// --- Helper function for the constructors of all classes
+// --- of the type FrameC.
+// --- There will be set the remome and add handler.
+function setRemoveAddHandler(myself, owner, min, max, call){
+ 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();
+ }
+ }
+ 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();
+ }
+ }
+ if(max > -1 && max <= owner.__frames__.length){
+ for(var i = 0; i != owner.__frames__.length; ++i){
+ owner.__frames__[i].hideAddButton();
+ }
+ }
+ });
+}
+
+
+// --- Helper function for the constructors of all classes
+// --- of the type FrameC.
+// --- There will be checked the visibility of the remove and
+// --- add buttons.
+function checkRemoveAddButtons(owner, min, max){
+ if(min >= owner.__frames__.length){
+ for(var i = 0; i != owner.__frames__.length; ++i){
+ owner.__frames__[i].hideRemoveButton();
+ }
+ }
+
+ if(min > -1 && min < owner.__frames__.length){
+ 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();
+ }
+ }
+}
+
+
+// --- creates a control row for NameC, OccurrenceC and VariantC with a nested ItemIdentity frame.
+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})
+ var tdDesc = new Element("td", {"class" : CLASSES.description()}).update("ItemIdentity");
+ tr.insert({"bottom" : tdDesc});
+ var min = new Element("span", {"class" : CLASSES.clickable()}).update("«");
+ myself.__min__ = min;
+ myself.__remove__ = new Element("span", {"class" : CLASSES.clickable()}).update("-");
+ myself.__add__ = new Element("span", {"class" : CLASSES.clickable()}).update("+");
+ tdCtrl.insert({"top" : min});
+ tdCtrl.insert({"bottom" : "<br/>"});
+ tdCtrl.insert({"bottom" : myself.__remove__});
+ tdCtrl.insert({"bottom" : "<br/>"});
+ 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);
+ tdCont.insert({"top" : myself.__itemIdentity__.getFrame()});
+ myself.__table__.insert({"bottom" : tr});
+
+ var trCtrl = new Element("tr", {"class" : CLASSES.showHiddenRows()});
+ trCtrl.insert({"top" : new Element("td", {"class" : CLASSES.clickable()}).update("»")});
+ myself.__table__.insert({"top" : trCtrl});
+ trCtrl.hide();
+ trCtrl.observe("click", function(){
+ var trs = myself.__table__.select("tr");
+ for(var i = 0; i != trs.length; ++i) trs[i].show();
+ trCtrl.hide();
+ });
+
+ // --- min click-handler
+ min.observe("click", function(event){
+ var trs = myself.__table__.select("tr");
+ for(var i = 0; i != trs.length; ++i){
+ if(i === 0) trs[i].show();
+ else trs[i].hide();
+ }
+ });
+}
\ No newline at end of file
Added: trunk/src/ajax/javascripts/edit.js
==============================================================================
--- (empty file)
+++ trunk/src/ajax/javascripts/edit.js Tue May 19 05:23:26 2009
@@ -0,0 +1,18 @@
+//+-----------------------------------------------------------------------------
+//+ Isidorus
+//+ (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
+//+
+//+ Isidorus is freely distributable under the LGPL license.
+//+ This ajax module uses the frameworks PrototypeJs and Scriptaculous, both
+//+ are distributed under the MIT license.
+//+ You can find a detailed description in trunk/docs/LGPL-LICENSE.txt and
+//+ in trunk/src/ajax/javascripts/external/MIT-LICENSE.txt.
+//+-----------------------------------------------------------------------------
+
+
+function makeEdit(psi)
+{
+ var content = new Element("div", {"class" : CLASSES.content()});
+ var header = new Element("h1").update("Edit a Topic");
+ $(CLASSES.subPage()).insert((content.insert(header, {"position" : "bottom"})), {"position" : "bottom"});
+}
Modified: trunk/src/ajax/javascripts/home.js
==============================================================================
--- trunk/src/ajax/javascripts/home.js (original)
+++ trunk/src/ajax/javascripts/home.js Tue May 19 05:23:26 2009
@@ -10,265 +10,9 @@
//+-----------------------------------------------------------------------------
-// --- with this object there will be set the first and last index of topics to get by the ajax request
-// --- further this object handles out of range violations and some other site effects, e.g.
-// --- topicsPerPage === -1 -> show all topics, ...
-var __idx = {"firstIdx" : 0, "lastIdx" : 10, "lastDirectionForward" : true, "topicsPerPage" : 10, "outOfRange" : false,
- "topicPerPageVals" : ["5", "10", "15", "25", "50", "100", "200", "300", "All"],
- "getTopicPerPageVals" : function(){ return this.topicPerPageVals; },
- "getFirstIdx" : function(){ return this.firstIdx; },
- "setFirstIdx" : function(x) { if(typeof(x) === "number" && x >= 0) this.firstIdx = x; },
- "getLastIdx" : function(){ return this.lastIdx; },
- "setLastIdx" : function(x) { if(typeof(x) === "number" && x >= 0) this.lastIdx = x; },
- "getLastDirectionForward" : function() { return this.lastDirectionForward; },
- "setLastDirectionForward" : function(x) { if(typeof(x) === "boolean") this.lastDirectionForward = x; },
- "getTopicsPerPage" : function() {return (this.topicsPerPage === -1 ? "nil" : this.topicsPerPage); },
- "getTopicsPerPageAsNumber" : function(){ return this.topicsPerPage; },
- "setTopicsPerPage" : function(x) {
- if(typeof(x) === "number" && x > 0){
- this.topicsPerPage = x;
- this.lastIdx = this.firstIdx + this.topicsPerPage;
- }
- else if(typeof(x) === "number" && x === -1){
- this.topicsPerPage = x;
- this.lastIdx = "nil";
- }
- },
- "getOutOfRange" : function() { return this.outOfRange; },
- "setOutOfRange" : function(x){ if(typeof(x) === "boolean") this.outOfRange = x; },
- "next" : function() {
- if(this.outOfRange) return;
- this.firstIdx += this.topicsPerPage;
- if(this.topicsPerPage !== -1){ this.lastIdx = this.firstIdx + this.topicsPerPage; }
- else { this.lastIdx = "nil"; }
- this.lastDirectionForward = true;
- },
- "prev" : function() {
- if(this.topicsPerPage !== -1){
- this.firstIdx -= this.topicsPerPage;
- if(this.firstIdx < 0)this.firstIdx = 0;
- this.lastIdx = this.firstIdx + this.topicsPerPage;
- }
- else {
- this.firstIdx = 0;
- this.lastIdx = "nil";
- }
- this.lastDirectionForward = false;
- }
- };
-
-
-
-// --- creates a html table with the id "tableId" and appends it on the element with the id
-// --- "parentId", if the variable next ist set to true there will be shown the next
-// --- topics otherwise the previous topics
-// --- the table looks like the following schema:
-// --- itemIdentity | subjectLocator | subjectIdentifier | instanceOf | name | occurrence
-function makeHome(parentId, tableId, next)
+function makeHome()
{
- // --- create the ajax-request handlers ------------------------------------
- function onSuccessHandler(xhr)
- {
- // --- creates the navigation div-element with a forward-, backward- button and a
- // --- selection box where the user can choose the amount of topics per page
- function createTableNavi(top)
- {
- // --- creates the backwards and forwards buttons, if they don't exist
- if(($("naviDivTop") === null && top === true) || ($("naviDivBottom") === null && top === false) && $(parentId)){
- var div = new Element("div", {"id" : (top ? "naviDivTop" : "naviDivBottom"), "class" : "naviTopicTable " + PAGES.home});
- var lftBtn = new Element("input", {"type" : "button", "id" : (top ? "topicTableLftBtnTop" : "topicTableLftBtnBottom")});
- var rgtBtn = new Element("input", {"type" : "button", "id" : (top ? "topicTableRgtBtnTop" : "topicTableRgtBtnBottom")});
- lftBtn.value = "<<";
- rgtBtn.value = ">>";
- rgtBtn.setStyle({"float" : "right"});
- lftBtn.setStyle({"float" : "left"});
- div.insert(lftBtn, {"position" : "top"});
- div.insert(rgtBtn, {"position" : "bottom"});
- $("content").insert(div, {"position" : "top"});
-
- rgtBtn.observe("click", function(event)
- {
- __idx.next();
- makeHome(parentId, tableId, true);
- });
- lftBtn.observe("click", function(event)
- {
- __idx.prev();
- makeHome(parentId, tableId, false);
- });
-
- var select = new Element("select", {"id" : (top === true ? "topicTableSelectTop" : "topicTableSelectBottom"), "class" : "topicTable"});
- var selectValues = __idx.getTopicPerPageVals();
- var selectInnerHTML = "";
- selectValues.each(function(value, idx)
- {
- var numberValue = value;
- numberValue = (numberValue === "All" ? "-1" : numberValue);
- if(Number(numberValue) !== __idx.getTopicsPerPageAsNumber()){
- select.insert(new Element("option", {"value" : numberValue}).update(value), {"position" : "bottom"});
- }
- else {
- select.insert(new Element("option", {"value" : numberValue, "selected" : "selected"}).update(value), {"position" : "bottom"});
- }
- });
- div.insert(select, {"position" : "content"});
-
- select.observe("change", function(event)
- {
- __idx.setTopicsPerPage(Number(event.element().value));
- makeHome(parentId, tableId, true);
- });
- }
- }
-
-
- try {
- var topicSummaries = xhr.responseText.evalJSON();
- // --- inserts or updates the topic table if there is some json data or
- // --- if there isn't a table yet
- if(topicSummaries !== null || $(tableId) === null){
- // --- removes the old table - if there exists an element with the id "tableId"
- if($(tableId) !== null)$(tableId).remove();
- if($("naviDivTop") !== null)$("naviDivTop").remove();
- if($("naviDivBottom") !== null)$("naviDivBottom").remove();
-
- createTableNavi(true);
-
- // --- creates the html table
- var topicTable = new Element("table", {"id" : "topicTable", "class" : PAGES.home});
-
- // --- creates the header row
- var header = new Element("tr");
- header.insert(new Element("th", {"id" : "itemIdentityTh"}).update("itemIdentity"), {"position" : "bottom"});
- header.insert(new Element("th", {"id" : "subjectLocatorTh"}).update("subjectLocator"), {"position" : "bottom"});
- header.insert(new Element("th", {"id" : "subjectIdentifierTh"}).update("subjectIdentifier"), {"position" : "bottom"});
- header.insert(new Element("th", {"id" : "instanceOfTh"}).update("instanceOf"), {"position" : "bottom"});
- header.insert(new Element("th", {"id" : "nameTh"}).update("name"), {"position" : "bottom"});
- header.insert(new Element("th", {"id" : "occurrenceTh"}).update("occurrence"), {"position" : "bottom"});
- topicTable.insert(header, {"position" : "top"});
-
- // --- creates the topic summary data of the json object
- if(topicSummaries !== null){
- topicSummaries.each(function(topicSummary, idx)
- {
- var tr = new Element("tr");
-
-
- var itemIdentity = new Element("td", {"class" : "topicSummaryTd"});
- var ul = new Element("ul", {"class" : "topicTable"});
- itemIdentity.insert(ul, {"position" : "top"});
- if(topicSummary.itemIdentities){
- topicSummary.itemIdentities.each(function(itemIdentityJ, innerIdx)
- {
- ul.insert(new Element("li").update(itemIdentityJ), {"position" : "bottom"});
- });
- }
-
- var subjectLocator = new Element("td", {"class" : "topicSummaryTd"});
- ul = new Element("ul", {"class" : "topicTable"});
- subjectLocator.insert(ul, {"position" : "top"});
- if(topicSummary.subjectLocators){
- topicSummary.subjectLocators.each(function(subjectLocatorJ, innerIdx)
- {
- ul.insert(new Element("li").update(subjectLocatorJ), {"position" : "bottom"});
- });
- }
-
- var subjectIdentifier = new Element("td", {"class" : "topicSummaryTd"});
- ul = new Element("ul", {"class" : "topicTable"});
- subjectIdentifier.insert(ul, {"position" : "top"});
- if(topicSummary.subjectIdentifiers){
- topicSummary.subjectIdentifiers.each(function(subjectIdentifierJ, innerIdx)
- {
- var li = new Element("li", {"class" : "clickable"}).update(subjectIdentifierJ);
- ul.insert(li, {"position" : "bottom"});
- li.observe("click", function(event)
- {
- var node = event.element();
- makePage(PAGES.edit, node.textContent);
- });
- });
- }
-
- var instanceOf = new Element("td", {"class" : "topicSummaryTd"});
- ul = new Element("ul", {"class" : "topicTable"});
- instanceOf.insert(ul, {"position" : "top"});
- if(topicSummary.instanceOfs){
- topicSummary.instanceOfs.each(function(instanceOfJ, innerIdx)
- {
- if(instanceOfJ){
- instanceOfJ.each(function(psi, psiIdx)
- {
- ul.insert(new Element("li").update(psi), {"position" : "top"});
- });
- }
- });
- }
-
- var name = new Element("td", {"class" : "topicSummaryTd"});
- ul = new Element("ul", {"class" : "topicTable"});
- name.insert(ul, {"position" : "top"});
- if(topicSummary.names){
- topicSummary.names.each(function(nameJ, innerIdx)
- {
- ul.insert(new Element("li").update(nameJ), {"position" : "top"});
- });
- }
-
- var occurrence = new Element("td", {"class" : "topicSummaryTd"});
- ul = new Element("ul", {"class" : "topicTable"});
- occurrence.insert(ul, {"position" : "top"});
- if(topicSummary.occurrences){
- topicSummary.occurrences.each(function(occurrenceJ, innerIdx)
- {
- ul.insert(new Element("li").update(occurrenceJ), {"position" : "top"});
- });
- }
-
- tr.insert(itemIdentity, {"position" : "bottom"});
- tr.insert(subjectLocator, {"position" : "bottom"});
- tr.insert(subjectIdentifier, {"position" : "bottom"});
- tr.insert(instanceOf, {"position" : "bottom"});
- tr.insert(name, {"position" : "bottom"});
- tr.insert(occurrence, {"position" : "bottom"});
-
- topicTable.insert(tr, {"position" : "bottom"});
- });
- }
- }
-
- // --- there was no data received or not all requested
- // --- so it's not allowed to increment the indices of the requested topics
- if(topicSummaries === null || topicSummaries.length != __idx.getTopicsPerPage()){
- __idx.setOutOfRange(true);
- }
- else {
- __idx.setOutOfRange(false);
- }
-
- // --- inserts the table in the parent element
- if($(parentId)){
- $(parentId).insert(topicTable, {"position" : "top"});
- }
- createTableNavi(false);
- }
- catch(err){
- window.alert("got bad json data from: " + SUMMARY_URL + "\n\n" + err);
- }
- }
-
-
- function onFailureHandler(xhr)
- {
- window.alert("something went wrong ...\n" + xhr.status + ": " + xhr.statusText);
- }
-
-
- // --- the real ajax request
- new Ajax.Request(SUMMARY_URL,
- {"method" : "get",
- "onSuccess" : onSuccessHandler,
- "onFailure" : onFailureHandler,
- "parameters" : {"start" : __idx.getFirstIdx(), "end" : __idx.getLastIdx()}
- });
-}
\ No newline at end of file
+ var content = new Element("div", {"class" : CLASSES.content()});
+ var header = new Element("h1").update("Topic Map Overview");
+ $(CLASSES.subPage()).insert((content.insert(header, {"position" : "bottom"})), {"position" : "bottom"});
+}
Modified: trunk/src/ajax/javascripts/navi.js
==============================================================================
--- trunk/src/ajax/javascripts/navi.js (original)
+++ trunk/src/ajax/javascripts/navi.js Tue May 19 05:23:26 2009
@@ -13,49 +13,55 @@
// --- adds some event handlers to the navigation elements
function addHandlersToNavi()
{
- $(PAGES.home).observe("click", function(){ makePage(PAGES.home, ""); });
- $(PAGES.search).observe("click", function(){ makePage(PAGES.search, ""); });
- $(PAGES.edit).observe("click", function(){ makePage(PAGES.edit, ""); });
- $(PAGES.create).observe("click", function(){ makePage(PAGES.create, ""); });
+ $(PAGES.home).observe("click", function(event){ setNaviClasses(event.element()); makePage(PAGES.home, ""); });
+ $(PAGES.search).observe("click", function(event){ setNaviClasses(event.element()); makePage(PAGES.search, ""); });
+ $(PAGES.edit).observe("click", function(event){ setNaviClasses(event.element()); makePage(PAGES.edit, ""); });
+ $(PAGES.create).observe("click", function(event){ setNaviClasses(event.element()); makePage(PAGES.create, ""); });
// --- necessary for the first call of the page
- makePage(PAGES.home);
+ makePage(PAGES.home, "");
+}
+
+
+// --- Sets the classes of all navi-elements to the default class.
+// --- The currently clicked element is set to "isActive".
+function setNaviClasses(activeNaviElement)
+{
+ $(PAGES.home).writeAttribute({"class" : "clickableButton"});
+ $(PAGES.search).writeAttribute({"class" : "clickableButton"});
+ $(PAGES.edit).writeAttribute({"class" : "clickableButton"});
+ $(PAGES.create).writeAttribute({"class" : "clickableButton"});
+ activeNaviElement.writeAttribute({"class" : "isActive"});
}
// --- generates the current page depending on the variable __currentPage
function makePage(newPage, psi)
{
+ // --- if there is called the subpage which is already displayed
+ // --- there will be done nothing!
+ if(newPage === PAGES.current) return;
+ PAGES.current = newPage;
+
// --- removes the old content
- cleanPage(newPage);
+ $(CLASSES.subPage()).update();
// --- creates the new content
switch(newPage){
case PAGES.home:
- makeHome("content", "topicTable", true);
+ makeHome();
break;
case PAGES.search:
+ makeSearch(psi);
break;
case PAGES.edit:
- makeEdit(psi);
+ makeEdit(psi)
break;
case PAGES.create:
+ makeCreate(psi);
break;
}
}
-// --- removes all old DOM-Elements - if the page to create is not
-// --- the old page
-function cleanPage(newPage)
-{
- $("content").childElements().each(function(nodeToDelete, idx)
- {
- if(!nodeToDelete.hasClassName(newPage))
- nodeToDelete.remove();
- });
-}
-
-
-document.observe("dom:loaded", addHandlersToNavi);
-
+document.observe("dom:loaded", addHandlersToNavi);
\ No newline at end of file
Added: trunk/src/ajax/javascripts/requests.js
==============================================================================
--- (empty file)
+++ trunk/src/ajax/javascripts/requests.js Tue May 19 05:23:26 2009
@@ -0,0 +1,55 @@
+//+-----------------------------------------------------------------------------
+//+ Isidorus
+//+ (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
+//+
+//+ Isidorus is freely distributable under the LGPL license.
+//+ This ajax module uses the frameworks PrototypeJs and Scriptaculous, both
+//+ are distributed under the MIT license.
+//+ You can find a detailed description in trunk/docs/LGPL-LICENSE.txt and
+//+ in trunk/src/ajax/javascripts/external/MIT-LICENSE.txt.
+//+-----------------------------------------------------------------------------
+
+
+// --- This is the default error handler of the used ajax.requests.
+function defaultFailureHandler(xhr)
+{
+ window.alert("Something went wrong by calling \"" + xhr.request.url + "\"\n" + xhr.status +
+ ": " + xhr.statusText + "\n" + xhr.responseText);
+}
+
+
+// --- Gets all type psis from the server.
+function getTypePsis(onSuccessHandler, onFailureHandler)
+{
+ try{
+ var onFailure = onFailureHandler ? onFailureHandler : defaultFailureHandler;
+
+ new Ajax.Request(TYPE_PSIS_URL, {
+ "method" : "get",
+ "requestHeaders" : ["If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT"],
+ "onSuccess" : onSuccessHandler,
+ "onFailure" : onFailure});
+ }
+ catch(err){
+ alert("Could not request all type PSIs, please try again!\n\n" + err);
+ }
+}
+
+
+// --- Sends a post-request to the server with the passed psis as postBody.
+// --- Gets a constraint-object.
+function requestConstraints(psis, onSuccessHandler, onFailureHandler)
+{
+ try{
+ var onFailure = onFailureHandler ? onFailureHandler : defaultFailureHandler;
+
+ new Ajax.Request(TMCL_TYPE_URL, {
+ "method" : "post",
+ "postBody" : psis,
+ "onSuccess" : onSuccessHandler,
+ "onFailure" : onFailure});
+ }
+ catch(err){
+ alert("Could not request contraints, please try again!\n\n" + err);
+ }
+}
\ No newline at end of file
Added: trunk/src/ajax/javascripts/search.js
==============================================================================
--- (empty file)
+++ trunk/src/ajax/javascripts/search.js Tue May 19 05:23:26 2009
@@ -0,0 +1,18 @@
+//+-----------------------------------------------------------------------------
+//+ Isidorus
+//+ (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
+//+
+//+ Isidorus is freely distributable under the LGPL license.
+//+ This ajax module uses the frameworks PrototypeJs and Scriptaculous, both
+//+ are distributed under the MIT license.
+//+ You can find a detailed description in trunk/docs/LGPL-LICENSE.txt and
+//+ in trunk/src/ajax/javascripts/external/MIT-LICENSE.txt.
+//+-----------------------------------------------------------------------------
+
+
+function makeSearch(psi)
+{
+ var content = new Element("div", {"class" : CLASSES.content()});
+ var header = new Element("h1").update("Search a Topic");
+ $(CLASSES.subPage()).insert((content.insert(header, {"position" : "bottom"})), {"position" : "bottom"});
+}
Added: trunk/src/ajax/javascripts/tmcl_tools.js
==============================================================================
--- (empty file)
+++ trunk/src/ajax/javascripts/tmcl_tools.js Tue May 19 05:23:26 2009
@@ -0,0 +1,66 @@
+//+-----------------------------------------------------------------------------
+//+ Isidorus
+//+ (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
+//+
+//+ Isidorus is freely distributable under the LGPL license.
+//+ This ajax module uses the frameworks PrototypeJs and Scriptaculous, both
+//+ are distributed under the MIT license.
+//+ You can find a detailed description in trunk/docs/LGPL-LICENSE.txt and
+//+ in trunk/src/ajax/javascripts/external/MIT-LICENSE.txt.
+//+-----------------------------------------------------------------------------
+
+
+// --- Returns an Array of the type [<boolean>, <string>].
+// --- If there are exclusive-instance-constraints, the return value is an array
+// --- of the form [false, "message"] otherwise [true, ""].
+function checkExclusiveInstances(constraints, psis){
+ try{
+ var exc = constraints.topicConstraints.exclusiveInstances;
+ var ret = new Array();
+ for(var i = 0; i !== psis.length; ++i){
+ var currentArray = new Array(psis[i]);
+ for(var j = 0; j !== exc.length; ++j){
+ for(var k = 0; k !== exc[j].exclusives.length; ++k){
+ for(var l = 0; l !== exc[j].exclusives[k].length; ++l){
+ if(exc[j].exclusives[k][l] === psis[i]){
+ for(var m = 0; m != exc[j].owner.length; ++m){
+ currentArray.push(exc[j].owner[m]);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if(currentArray.length > 1)ret.push(currentArray);
+ }
+ if(ret.length === 0) return null;
+ return ret;
+ }
+ catch(err){
+ return null;
+ }
+}
+
+
+// --- checks SubjectLocator and SubjectIdentifier contraints and contents
+function checkIdentifierConstraints(contents, constraints)
+{
+ var innerConstents = (!contents ? new Array() : contents);
+ if((!constraints || constraints.length === 0) && innerConstraints.length === 0) return false;
+
+ for(var i = 0; i != constraints.length; ++i){
+ var regexp = constraints[i].regexp;
+ var min = constraints[i].cardMin;
+ var max = constraints[i].cardMax;
+
+ var foundContents = 0;
+ for(var j = 0; j != innerContents.length; ++j){
+ var rex = new RegExp(regexp);
+ if(rex.match(innerContents[j]) === true) ++foundContents;
+ }
+
+ if(foundContents < min || foundContents > max) return false;
+ }
+ return true;
+}
\ 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 Tue May 19 05:23:26 2009
@@ -13,21 +13,32 @@
;; =============================================================================
;; --- all fragment constraints ------------------------------------------------
;; =============================================================================
-(defun get-constraints-of-fragment(topic-psi &key (treat-as 'type))
+(defun get-constraints-of-fragment(topic-psis &key (treat-as 'type))
+ "Returns a json string with all constraints of this topic-psis.
+ topic-psis must contain one item if it is treated as instance other wiese there can be more psis
+ then the fragment will be treated as an instanceOf all passed psis."
(let ((associationtype (get-item-by-psi *associationtype-psi*))
(associationtype-constraint (get-item-by-psi *associationtype-constraint-psi*))
- (topic
- (let ((psi
- (elephant:get-instance-by-value 'PersistentIdC 'uri topic-psi)))
- (when psi
- (identified-construct psi)))))
- (when topic
+ (topics nil))
+ (when (and (not (eql treat-as 'type))
+ (> (length topic-psis) 1))
+ (error "From get-constraints-of-fragment: when treat-as is set ot instance there must be exactly one item in topic-psis!"))
+
+ (loop for topic-psi in topic-psis
+ do (let ((psi
+ (elephant:get-instance-by-value 'PersistentIdC 'uri topic-psi)))
+ (if psi
+ (pushnew (identified-construct psi) topics)
+ (error "Topic \"~a\" not found!" topic-psi))))
+ (when topics
(let ((topic-constraints
(let ((value
- (get-constraints-of-topic topic :treat-as treat-as)))
+ (get-constraints-of-topic topics :treat-as treat-as)))
(concatenate 'string "\"topicConstraints\":" value))))
(let ((available-associations ;what's with association which have only a associationrole-constraint?
- (get-available-associations-of-topic topic :treat-as treat-as)))
+ (remove-duplicates
+ (loop for topic in topics
+ append (get-available-associations-of-topic topic :treat-as treat-as)))))
(dolist (item available-associations)
(topictype-p item associationtype associationtype-constraint))
(let ((associations-constraints
@@ -46,6 +57,40 @@
(concatenate 'string
"{" topic-constraints "," associations-constraints "}")))
json-string)))))))
+
+;(defun get-constraints-of-fragment(topic-psi &key (treat-as 'type))
+; (let ((associationtype (get-item-by-psi *associationtype-psi*))
+; (associationtype-constraint (get-item-by-psi *associationtype-constraint-psi*))
+; (topic
+; (let ((psi
+; (elephant:get-instance-by-value 'PersistentIdC 'uri topic-psi)))
+; (when psi
+; (identified-construct psi)))))
+; (when topic
+; (let ((topic-constraints
+; (let ((value
+; (get-constraints-of-topic topic :treat-as treat-as)))
+; (concatenate 'string "\"topicConstraints\":" value))))
+; (let ((available-associations ;what's with association which have only a associationrole-constraint?
+; (get-available-associations-of-topic topic :treat-as treat-as)))
+; (dolist (item available-associations)
+; (topictype-p item associationtype associationtype-constraint))
+; (let ((associations-constraints
+; (concatenate 'string "\"associationsConstraints\":"
+; (let ((inner-associations-constraints "["))
+; (loop for available-association in available-associations
+; do (let ((value
+; (get-constraints-of-association available-association)))
+; (setf inner-associations-constraints
+; (concatenate 'string inner-associations-constraints value ","))))
+; (if (string= inner-associations-constraints "[")
+; (setf inner-associations-constraints "null")
+; (setf inner-associations-constraints
+; (concatenate 'string (subseq inner-associations-constraints 0 (- (length inner-associations-constraints) 1)) "]")))))))
+; (let ((json-string
+; (concatenate 'string
+; "{" topic-constraints "," associations-constraints "}")))
+; json-string)))))))
;; =============================================================================
@@ -351,37 +396,77 @@
;; =============================================================================
;; --- all topic constraints ---------------------------------------------------
;; =============================================================================
-(defun get-constraints-of-topic (topic-instance &key(treat-as 'type))
- "Returns a constraint list with the constraints:
- subjectidentifier-constraints, subjectlocator-constraints,
- topicname-constraints, topicoccurrence-constraints and
- uniqueoccurrence-constraints."
- (let ((constraint-topics
- (get-all-constraint-topics-of-topic topic-instance :treat-as treat-as)))
+(defun get-constraints-of-topic (topic-instances &key(treat-as 'type))
+ "Returns a constraint list with the constraints:
+ subjectidentifier-constraints, subjectlocator-constraints,
+ topicname-constraints, topicoccurrence-constraints and
+ uniqueoccurrence-constraints.
+ topic-instances should be a list with exactly one item if trea-as is set to type
+ otherwise it can constain more items."
+ (declare (list topic-instances))
+ (when (and (> (length topic-instances) 1)
+ (not (eql treat-as 'type)))
+ (error "From get-constraints-of-topic: topic-instances must contain exactly one item when treated as instance!"))
+ (let ((abstract-topictype-constraints nil)
+ (exclusive-instance-constraints nil)
+ (subjectidentifier-constraints nil)
+ (subjectlocator-constraints nil)
+ (topicname-constraints nil)
+ (topicoccurrence-constraints nil)
+ (uniqueoccurrence-constraints nil))
+ (loop for topic-instance in topic-instances
+ do (let ((current-constraints
+ (get-all-constraint-topics-of-topic topic-instance :treat-as treat-as)))
+ (dolist (item (getf current-constraints :abstract-topictype-constraints))
+ (pushnew item abstract-topictype-constraints))
+ (dolist (item (getf current-constraints :exclusive-instance-constraints))
+ (let ((current-list
+ (list topic-instance (list item))))
+ (let ((found-item
+ (find current-list exclusive-instance-constraints :key #'first)))
+ (if found-item
+ (dolist (inner-item (second current-list))
+ (pushnew inner-item (second found-item)))
+ (push current-list exclusive-instance-constraints)))))
+ (dolist (item (getf current-constraints :subjectidentifier-constraints))
+ (pushnew item subjectidentifier-constraints))
+ (dolist (item (getf current-constraints :subjectlocator-constraints))
+ (pushnew item subjectlocator-constraints))
+ (dolist (item (getf current-constraints :topicname-constraints))
+ (pushnew item topicname-constraints))
+ (dolist (item (getf current-constraints :topicoccurrence-constraints))
+ (pushnew item topicoccurrence-constraints))
+ (dolist (item (getf current-constraints :uniqueoccurrence-constraints))
+ (pushnew item uniqueoccurrence-constraints))))
(let ((exclusive-instance-constraints
- (let ((value
- (get-exclusive-instance-constraints (getf constraint-topics :exclusive-instance-constraints))))
+ (let ((value "["))
+ (loop for exclusive-instance-constraint in exclusive-instance-constraints
+ do (setf value (concatenate 'string value
+ (get-exclusive-instance-constraints (first exclusive-instance-constraint)
+ (second exclusive-instance-constraint)) ",")))
+ (if (string= value "[")
+ (setf value "null")
+ (setf value (concatenate 'string (subseq value 0 (- (length value) 1)) "]")))
(concatenate 'string "\"exclusiveInstances\":" value)))
(subjectidentifier-constraints
(let ((value
- (get-simple-constraints (getf constraint-topics :subjectidentifier-constraints) :error-msg-constraint-name "subjectidentifier")))
+ (get-simple-constraints subjectidentifier-constraints :error-msg-constraint-name "subjectidentifier")))
(concatenate 'string "\"subjectIdentifierConstraints\":" value)))
(subjectlocator-constraints
(let ((value
- (get-simple-constraints (getf constraint-topics :subjectlocator-constraints) :error-msg-constraint-name "subjectlocator")))
+ (get-simple-constraints subjectlocator-constraints :error-msg-constraint-name "subjectlocator")))
(concatenate 'string "\"subjectLocatorConstraints\":" value)))
(topicname-constraints
(let ((value
- (get-topicname-constraints (getf constraint-topics :topicname-constraints))))
+ (get-topicname-constraints topicname-constraints)))
(concatenate 'string "\"topicNameConstraints\":" value)))
(topicoccurrence-constraints
(let ((value
- (get-topicoccurrence-constraints (getf constraint-topics :topicoccurrence-constraints)
- (getf constraint-topics :uniqueoccurrence-constraints))))
+ (get-topicoccurrence-constraints topicoccurrence-constraints uniqueoccurrence-constraints)))
(concatenate 'string "\"topicOccurrenceConstraints\":" value)))
(abstract-constraint
(concatenate 'string "\"abstractConstraint\":"
- (if (getf constraint-topics :abstract-constraint)
+ (if abstract-topictype-constraints
"true"
"false"))))
(let ((json-string
@@ -390,12 +475,50 @@
topicoccurrence-constraints "," abstract-constraint "}")))
json-string))))
-
-(defun get-exclusive-instance-constraints(exclusive-instances-lists)
- "Returns a list of psis which represents some topics."
+;(defun get-constraints-of-topic (topic-instances &key(treat-as 'type))
+; (let ((constraint-topics
+; (get-all-constraint-topics-of-topic topic-instance :treat-as treat-as)))
+; (let ((exclusive-instance-constraints
+; (let ((value
+; (get-exclusive-instance-constraints (getf constraint-topics :exclusive-instance-constraints))))
+; (concatenate 'string "\"exclusiveInstances\":" value)))
+; (subjectidentifier-constraints
+; (let ((value
+; (get-simple-constraints (getf constraint-topics :subjectidentifier-constraints) :error-msg-constraint-name "subjectidentifier")))
+; (concatenate 'string "\"subjectIdentifierConstraints\":" value)))
+; (subjectlocator-constraints
+; (let ((value
+; (get-simple-constraints (getf constraint-topics :subjectlocator-constraints) :error-msg-constraint-name "subjectlocator")))
+; (concatenate 'string "\"subjectLocatorConstraints\":" value)))
+; (topicname-constraints
+; (let ((value
+; (get-topicname-constraints (getf constraint-topics :topicname-constraints))))
+; (concatenate 'string "\"topicNameConstraints\":" value)))
+; (topicoccurrence-constraints
+; (let ((value
+; (get-topicoccurrence-constraints (getf constraint-topics :topicoccurrence-constraints)
+; (getf constraint-topics :uniqueoccurrence-constraints))))
+; (concatenate 'string "\"topicOccurrenceConstraints\":" value)))
+; (abstract-constraint
+; (concatenate 'string "\"abstractConstraint\":"
+; (if (getf constraint-topics :abstract-topictype-constraints)
+; "true"
+; "false"))))
+; (let ((json-string
+; (concatenate 'string "{" exclusive-instance-constraints "," subjectidentifier-constraints
+; "," subjectlocator-constraints "," topicname-constraints ","
+; topicoccurrence-constraints "," abstract-constraint "}")))
+; json-string))))
+
+
+(defun get-exclusive-instance-constraints(owner exclusive-instances-lists)
+ "Returns a JSON-obejct of the following form:
+ {owner: [psi-1, psi-2], exclusives: [[psi-1-1, psi-1-2], [psi-2-1, <...>], <...>]}."
(let ((constraint-role (get-item-by-psi *constraint-role-psi*))
(applies-to (get-item-by-psi *applies-to-psi*))
- (topictype-role (get-item-by-psi *topictype-role-psi*)))
+ (topictype-role (get-item-by-psi *topictype-role-psi*))
+ (topictype (get-item-by-psi *topictype-psi*))
+ (topictype-constraint (get-item-by-psi *topictype-constraint-psi*)))
(let ((topics
(remove-duplicates
(loop for exclusive-instances-list in exclusive-instances-lists
@@ -408,10 +531,13 @@
append (loop for other-role in (roles (parent role))
when (and (eq topictype-role (instance-of other-role))
(not (eq owner (player other-role))))
- collect (player other-role)))))))))
- (json:encode-json-to-string (map 'list #'(lambda(y)
- (map 'list #'uri y))
- (map 'list #'psis topics))))))
+ ;collect (player other-role)))))))))
+ append (getf (list-subtypes (player other-role) topictype topictype-constraint) :subtypes)))))))))
+ (concatenate 'string "{\"owner\":" (json-exporter::identifiers-to-json-string owner)
+ ",\"exclusives\":"
+ (json:encode-json-to-string (map 'list #'(lambda(y)
+ (map 'list #'uri y))
+ (map 'list #'psis topics))) "}"))))
(defun get-simple-constraints(constraint-topics &key (error-msg-constraint-name "uniqueoccurrence"))
@@ -456,7 +582,7 @@
(defun get-topicname-constraints(constraint-topics)
"Returns all topicname constraints as a list of the following form:
[{nametypescopes:[{nameType: [psi-1, psi-2], scopeConstraints: [<scopeConstraint>]},
- {nameType: [subtype-1-psi-1], scopeConstriants: [<scopeConstraints>]},
+ {nameType: [subtype-1-psi-1], scopeConstraints: [<scopeConstraints>]},
constraints: [<simpleConstraint>, <...>]},
<...>]."
(let ((constraint-role (get-item-by-psi *constraint-role-psi*))
@@ -742,7 +868,7 @@
(defun get-constraint-occurrence-value(topic &key (what 'regexp))
"Checks the occurrence-value of a regexp, card-min or card-max
- constriant-occurrence.
+ constraint-occurrence.
If what = 'regexp and the occurrence-value is empty there will be returned
the value '.*!'.
If what = 'card-min and the occurrence-value is empty there will be returned
@@ -905,7 +1031,7 @@
:uniqueoccurrence-constraints uniqueoccurrence-constraints)))
-(defmethod get-all-constraint-topics-of-topic (topic-instance &key (treat-as 'type))
+(defun get-all-constraint-topics-of-topic (topic-instance &key (treat-as 'type))
"Returns a list of constraint-topics of the topics-instance's base type(s).
If topic c is instanceOf a and b, there will be returned all
constraint-topics of the topic types a and b.
Modified: trunk/src/json/json_tmcl_validation.lisp
==============================================================================
--- trunk/src/json/json_tmcl_validation.lisp (original)
+++ trunk/src/json/json_tmcl_validation.lisp Tue May 19 05:23:26 2009
@@ -30,7 +30,7 @@
(eq applies-to (instance-of (parent role))))
return (loop for other-role in (roles (parent role))
when (and (eq constraint-role (instance-of other-role))
- (eq abstract-topictype-constraint (player other-role)))
+ (topictype-of-p (player other-role) abstract-topictype-constraint))
return t))))
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 May 19 05:23:26 2009
@@ -15,8 +15,8 @@
(defparameter *json-get-summary-url* "/json/summary/?$") ;the url to get a summary od all topic stored in isidorus; you have to set the GET-parameter "start" for the start index of all topics within elephant and the GET-paramter "end" for the last index of the topic sequence -> http://localhost:8000/json/summary/?start=12&end=13
(defparameter *json-get-all-type-psis* "/json/tmcl/types/?$") ;returns a list of all psis that can be a type
(defparameter *json-get-topic-stub-prefix* "/json/topicstubs/(.+)$") ;the json prefix for getting some topic stub information of a topic
-(defparameter *json-get-type-tmcl-prefix* "/json/tmcl/type/(.+)$") ;the json prefix for getting some tmcl information of a topic treated as a type
-(defparameter *json-get-instance-tmcl-prefix* "/json/tmcl/instance/(.+)$") ;the json prefix for getting some tmcl information of a topic treated as an instance
+(defparameter *json-get-type-tmcl-url* "/json/tmcl/type/?$") ;the json url for getting some tmcl information of a topic treated as a type
+(defparameter *json-get-instance-tmcl-url* "/json/tmcl/instance/?$") ;the json url for getting some tmcl information of a topic treated as an instance
(defparameter *ajax-user-interface-url* "/isidorus/?$") ;the url to the user interface; if you want to get all topics set start=0&end=nil -> localhost:8000/isidorus
(defparameter *ajax-user-interface-css-prefix* "/css") ;the url to the css files of the user interface
(defparameter *ajax-user-interface-css-directory-path* "ajax/css") ;the directory contains the css files
@@ -30,8 +30,8 @@
(json-get-summary-url *json-get-summary-url*)
(json-get-all-type-psis *json-get-all-type-psis*)
(json-get-topic-stub-prefix *json-get-topic-stub-prefix*)
- (json-get-type-tmcl-prefix *json-get-type-tmcl-prefix*)
- (json-get-instance-tmcl-prefix *json-get-instance-tmcl-prefix*)
+ (json-get-type-tmcl-url *json-get-type-tmcl-url*)
+ (json-get-instance-tmcl-url *json-get-instance-tmcl-url*)
(ajax-user-interface-url *ajax-user-interface-url*)
(ajax-user-interface-file-path *ajax-user-interface-file-path*)
(ajax-user-interface-css-prefix *ajax-user-interface-css-prefix*)
@@ -84,12 +84,14 @@
(create-regex-dispatcher json-get-all-type-psis #'return-all-tmcl-types)
hunchentoot:*dispatch-table*)
(push
- (create-regex-dispatcher json-get-type-tmcl-prefix #'(lambda(&optional psi)
- (return-tmcl-info-of-psi 'json-tmcl::type psi)))
+ (create-regex-dispatcher json-get-type-tmcl-url #'(lambda(&optional param)
+ (declare (ignorable param))
+ (return-tmcl-info-of-psis 'json-tmcl::type)))
hunchentoot:*dispatch-table*)
(push
- (create-regex-dispatcher json-get-instance-tmcl-prefix #'(lambda(&optional psi)
- (return-tmcl-info-of-psi 'json-tmcl::instance psi)))
+ (create-regex-dispatcher json-get-instance-tmcl-url #'(lambda(&optional param)
+ (declare (ignorable param))
+ (return-tmcl-info-of-psis 'json-tmcl::instance)))
hunchentoot:*dispatch-table*)
(push
(create-regex-dispatcher json-commit-url #'json-commit)
@@ -102,6 +104,8 @@
;; --- some handlers for the json-rest-interface -------------------------------
;; =============================================================================
(defun return-all-tmcl-types(&optional param)
+ "Returns all topics that are valid types -> so they have to be valid to the
+ topictype-constraint (if it exists) and the can't be abstract."
(declare (ignorable param))
(handler-case (let ((all-topics
(elephant:get-instances-by-class 'd:TopicC))
@@ -150,29 +154,55 @@
(format nil "Condition: Topic \"~a\" not found" psi)))))
-(defun return-tmcl-info-of-psi(treat-as &optional psi)
+(defun return-tmcl-info-of-psis(treat-as)
"Returns a json string which represents the defined tmcl-constraints of the
topic and the associations where this topic can be a player."
- (assert 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." psi))))
+ (let ((http-method (hunchentoot:request-method*)))
+ (if (or (eq http-method :POST)
+ (eq http-method :PUT))
+ (let ((external-format (flexi-streams:make-external-format :UTF-8 :eol-style :LF)))
+ (let ((json-data (hunchentoot:raw-post-data :external-format external-format :force-text t)))
+ (handler-case (let ((psis
+ (json:decode-json-from-string json-data)))
+ (let ((tmcl
+ (json-tmcl:get-constraints-of-fragment psis :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+))))
+ (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)
Modified: trunk/src/unit_tests/poems.xtm
==============================================================================
--- trunk/src/unit_tests/poems.xtm (original)
+++ trunk/src/unit_tests/poems.xtm Tue May 19 05:23:26 2009
@@ -1,90 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<tm:topicMap version="2.0" xmlns:tm="http://www.topicmaps.org/xtm/">
-
- <!-- === association-test ================================================ -->
- <tm:topic id="test-scope-1">
- <tm:subjectIdentifier href="test-scope-1"/>
- <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
- </tm:topic>
-
- <tm:topic id="test-scope-2">
- <tm:subjectIdentifier href="test-scope-2"/>
- <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
- </tm:topic>
-
- <tm:topic id="written-by-test-scope-constraint">
- <tm:subjectIdentifier href="written-by-test-scope-constraint"/>
- <tm:instanceOf><tm:topicRef href="#associationtypescope-constraint"/></tm:instanceOf>
- <tm:occurrence>
- <tm:type>
- <tm:topicRef href="#card-min"/>
- </tm:type>
- <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
- </tm:occurrence>
- <tm:occurrence>
- <tm:type>
- <tm:topicRef href="#card-max"/>
- </tm:type>
- <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
- </tm:occurrence>
- </tm:topic>
-
- <tm:association>
- <tm:type>
- <tm:topicRef href="#applies-to"/>
- </tm:type>
- <tm:role>
- <tm:type>
- <tm:topicRef href="#constraint-role"/>
- </tm:type>
- <tm:topicRef href="#written-by-test-scope-constraint"/>
- </tm:role>
- <tm:role>
- <tm:type>
- <tm:topicRef href="#associationtype-role"/>
- </tm:type>
- <tm:topicRef href="#written-by"/>
- </tm:role>
- </tm:association>
-
- <tm:association>
- <tm:type>
- <tm:topicRef href="#applies-to"/>
- </tm:type>
- <tm:role>
- <tm:type>
- <tm:topicRef href="#constraint-role"/>
- </tm:type>
- <tm:topicRef href="#written-by-test-scope-constraint"/>
- </tm:role>
- <tm:role>
- <tm:type>
- <tm:topicRef href="#scopetype-role"/>
- </tm:type>
- <tm:topicRef href="#test-scope-1"/>
- </tm:role>
- </tm:association>
-
- <tm:association>
- <tm:type>
- <tm:topicRef href="#applies-to"/>
- </tm:type>
- <tm:role>
- <tm:type>
- <tm:topicRef href="#constraint-role"/>
- </tm:type>
- <tm:topicRef href="#written-by-test-scope-constraint"/>
- </tm:role>
- <tm:role>
- <tm:type>
- <tm:topicRef href="#scopetype-role"/>
- </tm:type>
- <tm:topicRef href="#test-scope-2"/>
- </tm:role>
- </tm:association>
- <!-- === end association-test ============================================ -->
-
-
<!-- ===================================================================== -->
<!-- === TMCL meta-model topics ========================================== -->
<!-- ===================================================================== -->
@@ -678,6 +593,84 @@
<tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
</tm:topic>
+ <!-- region -->
+ <tm:topic id="region">
+ <tm:subjectIdentifier href="http://some.where/base-psis/region"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="abstract-constraint-for-region">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/abstract-constraint-for-region"/>
+ <tm:instanceOf><tm:topicRef href="#abstract-topictype-constraint"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#abstract-constraint-for-region"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#region"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:topic id="region-name">
+ <tm:subjectIdentifier href="http://some.where/base-psis/region-name"/>
+ <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="region-population">
+ <tm:subjectIdentifier href="http://some.where/base-psis/region-population"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- city -->
+ <tm:topic id="city">
+ <tm:subjectIdentifier href="http://some.where/base-psis/city"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#region"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#city"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- metropolis -->
+ <tm:topic id="metropolis">
+ <tm:subjectIdentifier href="http://some.where/base-psis/metropolis"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#region"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#metropolis"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- country -->
+ <tm:topic id="country">
+ <tm:subjectIdentifier href="http://some.where/base-psis/country"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="country-name">
+ <tm:subjectIdentifier href="http://some.where/base-psis/country-name"/>
+ <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf>
+ </tm:topic>
+
<!-- association author-poem -->
<tm:topic id="written-by">
<tm:subjectIdentifier href="http://some.where/base-psis/written-by"/>
@@ -694,6 +687,34 @@
<tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
</tm:topic>
+ <!-- association country-city -->
+ <tm:topic id="located-in">
+ <tm:subjectIdentifier href="http://some.where/base-psis/located-in"/>
+ <tm:instanceOf><tm:topicRef href="#associationtype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="container">
+ <tm:subjectIdentifier href="http://some.where/base-psis/container"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="containee">
+ <tm:subjectIdentifier href="http://some.where/base-psis/containee"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- association author-city -->
+ <tm:topic id="born-in">
+ <tm:subjectIdentifier href="http://some.where/base-psis/born-in"/>
+ <tm:instanceOf><tm:topicRef href="#associationtype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- writer already defined for written-by -->
+
+ <tm:topic id="place">
+ <tm:subjectIdentifier href="http://some.where/base-psis/place"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
<!-- ===================================================================== -->
<!-- === own datamodel: exclusive type constraint ======================== -->
@@ -728,6 +749,30 @@
</tm:role>
</tm:association>
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#exc"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#region"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#exc"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#country"/>
+ </tm:role>
+ </tm:association>
+
<!-- ===================================================================== -->
<!-- === own datamodel: subjectIdentifier constraints ==================== -->
<!-- ===================================================================== -->
@@ -797,9 +842,69 @@
</tm:role>
</tm:association>
- <!-- further subjectidentifiers of author and poem -->
- <tm:topic id="sic-author-poem">
- <tm:subjectIdentifier href="http://some.where/constraint-psis/sic-author-poem"/>
+ <!-- subjectidentifier of region -->
+ <tm:topic id="sic-region">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/sic-region"/>
+ <tm:instanceOf><tm:topicRef href="#subjectidentifier-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://some.where/psis/region/.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#sic-region"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#region"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- subjectidentifier of country -->
+ <tm:topic id="sic-country">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/sic-country"/>
+ <tm:instanceOf><tm:topicRef href="#subjectidentifier-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://some.where/psis/country/.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#sic-country"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#country"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- further subjectidentifiers of all topics -->
+ <tm:topic id="sic-all">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/all"/>
<tm:instanceOf><tm:topicRef href="#subjectidentifier-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-min"/></tm:type>
@@ -819,7 +924,7 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#sic-author-poem"/>
+ <tm:topicRef href="#sic-all"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#topictype-role"/></tm:type>
@@ -831,7 +936,7 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#sic-author-poem"/>
+ <tm:topicRef href="#sic-all"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#topictype-role"/></tm:type>
@@ -839,15 +944,39 @@
</tm:role>
</tm:association>
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#sic-all"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#region"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#sic-all"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#country"/>
+ </tm:role>
+ </tm:association>
+
<!-- ===================================================================== -->
- <!-- === own datamodel: subjectIdentifier constraints ==================== -->
+ <!-- === own datamodel: subjectLocator constraints ======================= -->
<!-- ===================================================================== -->
- <!-- all instances of author and poem are not allowed to own a
+ <!-- all instances of author, poem, city and country are not allowed to own a
subjectLocator -->
- <tm:topic id="slc-author-poem">
- <tm:subjectIdentifier href="http://some.where/constraint-psis/slc-author-poem"/>
+ <tm:topic id="slc-author-poem-city-country">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/slc-author-poem-city-country"/>
<tm:instanceOf><tm:topicRef href="#subjectlocator-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-min"/></tm:type>
@@ -867,7 +996,7 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#slc-author-poem"/>
+ <tm:topicRef href="#slc-author-poem-city-country"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#topictype-role"/></tm:type>
@@ -879,7 +1008,7 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#slc-author-poem"/>
+ <tm:topicRef href="#slc-author-poem-city-country"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#topictype-role"/></tm:type>
@@ -887,8 +1016,32 @@
</tm:role>
</tm:association>
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#slc-author-poem-city-country"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#region"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#slc-author-poem-city-country"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#country"/>
+ </tm:role>
+ </tm:association>
+
<!-- ===================================================================== -->
- <!-- === own datamodel: names constraints ================================ -->
+ <!-- === own datamodel: name constraints ================================= -->
<!-- ===================================================================== -->
<!-- instances of the type author has to own a name of the type first-name
and one of the type last-name. both must be valid to the regular
@@ -902,11 +1055,11 @@
<tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-min"/></tm:type>
- <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
</tm:occurrence>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-max"/></tm:type>
- <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">3</tm:resourceData>
</tm:occurrence>
<tm:occurrence>
<tm:type><tm:topicRef href="#regexp"/></tm:type>
@@ -944,7 +1097,7 @@
<tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-min"/></tm:type>
- <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
</tm:occurrence>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-max"/></tm:type>
@@ -986,7 +1139,7 @@
<tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-min"/></tm:type>
- <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
</tm:occurrence>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-max"/></tm:type>
@@ -1022,20 +1175,13 @@
</tm:role>
</tm:association>
-
- <!-- ===================================================================== -->
- <!-- === own datamodel: occurences constraints =========================== -->
- <!-- ===================================================================== -->
- <!-- every instance of the topic author can have one occurrence of the type
- author-info which contains a resourceRef (= datatype #anyURI) -->
-
- <!-- author info occurrence -->
- <tm:topic id="author-occurrence-constraint">
- <tm:subjectIdentifier href="http://some.where/constraint-psis/author-occurrence-constraint"/>
- <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+ <!-- region: region-name -->
+ <tm:topic id="region-name-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/region-name-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-min"/></tm:type>
- <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
</tm:occurrence>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-max"/></tm:type>
@@ -1051,11 +1197,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#author-occurrence-constraint"/>
+ <tm:topicRef href="#region-name-constraint"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#topictype-role"/></tm:type>
- <tm:topicRef href="#author"/>
+ <tm:topicRef href="#region"/>
</tm:role>
</tm:association>
@@ -1063,7 +1209,150 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#author-occurrence-constraint"/>
+ <tm:topicRef href="#region-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#nametype-role"/></tm:type>
+ <tm:topicRef href="#region-name"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- country: country-name
+ A country hast to have at least one name with the scope "en" or "de".
+ There can exist both names with the scopes "en" and "de". -->
+ <tm:topic id="country-name-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/country-name-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">2</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#country-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#country"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#country-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#nametype-role"/></tm:type>
+ <tm:topicRef href="#country-name"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- country-name scopes -->
+ <tm:topic id="scoped-country-name-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/scoped-country-name-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#nametypescope-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">2</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-country-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#nametype-role"/></tm:type>
+ <tm:topicRef href="#country-name"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-country-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+ <tm:topicRef href="#en"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-country-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+ <tm:topicRef href="#de"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: occurence constraints ============================ -->
+ <!-- ===================================================================== -->
+ <!-- every instance of the topic author can have one occurrence of the type
+ author-info which contains a resourceRef (= datatype #anyURI) -->
+
+ <!-- author info occurrence -->
+ <tm:topic id="author-occurrence-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/author-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#author-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#author-occurrence-constraint"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
@@ -1137,57 +1426,824 @@
</tm:role>
</tm:association>
- <!-- poem content-occurrence datatype -->
- <tm:topic id="poem-content-occurrence-datatype-constraint">
- <tm:subjectIdentifier href="http://some.where/constraint-psis/poem-content-occurrence-datatype-constrai…"/>
- <tm:instanceOf><tm:topicRef href="#occurrencedatatype-constraint"/></tm:instanceOf>
- <tm:occurrence>
- <tm:type><tm:topicRef href="#datatype"/></tm:type>
- <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#string</tm:resourceData>
- </tm:occurrence>
- </tm:topic>
-
+ <!-- poem content-occurrence datatype -->
+ <tm:topic id="poem-content-occurrence-datatype-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/poem-content-occurrence-datatype-constrai…"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencedatatype-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#datatype"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#string</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#poem-content-occurrence-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#poem-content"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- the poem-content-occurrence can only appear once per topictype,
+ so all topic with this occurrence type must have different
+ occurrence-values -->
+ <tm:topic id="unique-poem-occurrence-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/unique-poem-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#uniqueoccurrence-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.*$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#unique-poem-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#unique-poem-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#poem-content"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- add a scope to the occurrence "poem-content" -->
+ <tm:topic id="scoped-poem-occurrence-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/scoped-poem-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetypescope-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">2</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-poem-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#poem-content"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-poem-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+ <tm:topicRef href="#en"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-poem-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+ <tm:topicRef href="#de"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- city population-occurrence -->
+ <tm:topic id="region-population-occurrence-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/region-population-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#region-population-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#region"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#region-population-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#region-population"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- city population-occurrence datatype -->
+ <tm:topic id="region-population-occurrence-datatype-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/region-population-occurrence-datatype-con…"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencedatatype-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#datatype"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#unsignedLong</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#region-population-occurrence-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#region-population"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: association (-role) constraints ================== -->
+ <!-- ===================================================================== -->
+ <!-- there exists one asoociation of the type written-by between the types
+ author and poem. where one role is of type writer which has a player
+ of type author and another role of type written which owns a player of
+ type poem -->
+
+ <!-- the writer role has to appear exactly once in an association of type
+ written-by -->
+ <tm:topic id="written-by-writer-role-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/written-by-writer-role-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#associationrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-writer-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-writer-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#writer"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- the writer role owns a player of the type author -->
+ <tm:topic id="written-by-writer-role-player-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/written-by-writer-role-player-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#roleplayer-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-writer-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-writer-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-writer-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#writer"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- the written role has to appear exactly once in an association of type
+ written-by -->
+ <tm:topic id="written-role-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/written-role-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#associationrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#written"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- the written role owns a player of the type poem -->
+ <tm:topic id="written-role-player-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/written-role-player-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#roleplayer-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#written"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- otherrole-constraint:
+ If there is a role of the type written with a player of the type poem
+ there must be another role of the type writer with a player of the
+ type author.
+ In contrast if there is a role of the type writer with a player of the
+ type author there must be a role of the type written with a player of
+ the type poem.
+ So for this case there are two otherrole-constraints which handle this
+ both cases. -->
+
+ <tm:topic id="written-by-otherrole-constraint-for-writer">
+ <tm:subjectIdentifier href="http://some.where/contraint-psis/written-by-otherrole-constraint-for-writer"/>
+ <tm:instanceOf><tm:topicRef href="#otherrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#writer"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#otherroletype-role"/></tm:type>
+ <tm:topicRef href="#written"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#othertopictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:topic id="written-by-otherrole-constraint-for-written">
+ <tm:subjectIdentifier href="http://some.where/contraint-psis/written-by-otherrole-constraint-for-written"/>
+ <tm:instanceOf><tm:topicRef href="#otherrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#written"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#otherroletype-role"/></tm:type>
+ <tm:topicRef href="#writer"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#othertopictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- born-in associations have to have one role of the type writer with a
+ player of the type author. The other role is of type place with the
+ player of the type city. -->
+ <!-- place associationrole-constraint -->
+ <tm:topic id="born-in-place-role-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/born-in-place-role-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#associationrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-place-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#born-in"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-place-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#place"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- place-role roleplayer-constraint -->
+ <tm:topic id="born-in-place-role-player-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/born-in-place-role-player-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#roleplayer-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-place-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#region"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-place-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#born-in"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-place-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#place"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- writer associationrole-constraint -->
+ <tm:topic id="born-in-writer-role-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/born-in-writer-role-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#associationrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-writer-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#born-in"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-writer-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#writer"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- place-role roleplayer-constraint -->
+ <tm:topic id="born-in-writer-role-player-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/born-in-writer-role-player-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#roleplayer-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-writer-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-writer-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#born-in"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-writer-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#writer"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- otherplayer-constraints:
+ A "born-in" association must have exactly one writer-role with a
+ player of the type author and one place-role with a player of the
+ type city. -->
+ <tm:topic id="born-in-otherrole-constraint-for-writer">
+ <tm:subjectIdentifier href="http://some.where/contraint-psis/born-in-otherrole-constraint-for-writer"/>
+ <tm:instanceOf><tm:topicRef href="#otherrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#born-in"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#writer"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#born-in-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#otherroletype-role"/></tm:type>
+ <tm:topicRef href="#place"/>
+ </tm:role>
+ </tm:association>
+
<tm:association>
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#poem-content-occurrence-datatype-constraint"/>
+ <tm:topicRef href="#born-in-otherrole-constraint-for-writer"/>
</tm:role>
<tm:role>
- <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
- <tm:topicRef href="#poem-content"/>
+ <tm:type><tm:topicRef href="#othertopictype-role"/></tm:type>
+ <tm:topicRef href="#region"/>
</tm:role>
</tm:association>
- <!-- the poem-content-occurrence can only appear once per topictype,
- so all topic with this occurrence type must have different
- occurrence-values -->
- <tm:topic id="unique-poem-occurrence-constraint">
- <tm:subjectIdentifier href="http://some.where/constraint-psis/unique-poem-occurrence-constraint"/>
- <tm:instanceOf><tm:topicRef href="#uniqueoccurrence-constraint"/></tm:instanceOf>
+ <tm:topic id="born-in-otherrole-constraint-for-place">
+ <tm:subjectIdentifier href="http://some.where/contraint-psis/born-in-otherrole-constraint-for-place"/>
+ <tm:instanceOf><tm:topicRef href="#otherrole-constraint"/></tm:instanceOf>
<tm:occurrence>
- <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
<tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
</tm:occurrence>
<tm:occurrence>
- <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
<tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
</tm:occurrence>
- <tm:occurrence>
- <tm:type><tm:topicRef href="#regexp"/></tm:type>
- <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.*$</tm:resourceData>
- </tm:occurrence>
</tm:topic>
<tm:association>
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#unique-poem-occurrence-constraint"/>
+ <tm:topicRef href="#born-in-otherrole-constraint-for-place"/>
</tm:role>
<tm:role>
- <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
- <tm:topicRef href="#poem"/>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#born-in"/>
</tm:role>
</tm:association>
@@ -1195,37 +2251,23 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#unique-poem-occurrence-constraint"/>
+ <tm:topicRef href="#born-in-otherrole-constraint-for-place"/>
</tm:role>
<tm:role>
- <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
- <tm:topicRef href="#poem-content"/>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#place"/>
</tm:role>
</tm:association>
-
- <!-- add a scope to the occurrence "poem-content" -->
- <tm:topic id="scoped-poem-occurrence-constraint">
- <tm:subjectIdentifier href="http://some.where/constraint-psis/scoped-poem-occurrence-constraint"/>
- <tm:instanceOf><tm:topicRef href="#occurrencetypescope-constraint"/></tm:instanceOf>
- <tm:occurrence>
- <tm:type><tm:topicRef href="#card-min"/></tm:type>
- <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
- </tm:occurrence>
- <tm:occurrence>
- <tm:type><tm:topicRef href="#card-max"/></tm:type>
- <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">2</tm:resourceData>
- </tm:occurrence>
- </tm:topic>
<tm:association>
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#scoped-poem-occurrence-constraint"/>
+ <tm:topicRef href="#born-in-otherrole-constraint-for-place"/>
</tm:role>
<tm:role>
- <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
- <tm:topicRef href="#poem-content"/>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#region"/>
</tm:role>
</tm:association>
@@ -1233,11 +2275,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#scoped-poem-occurrence-constraint"/>
+ <tm:topicRef href="#born-in-otherrole-constraint-for-place"/>
</tm:role>
<tm:role>
- <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
- <tm:topicRef href="#en"/>
+ <tm:type><tm:topicRef href="#otherroletype-role"/></tm:type>
+ <tm:topicRef href="#writer"/>
</tm:role>
</tm:association>
@@ -1245,27 +2287,20 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#scoped-poem-occurrence-constraint"/>
+ <tm:topicRef href="#born-in-otherrole-constraint-for-place"/>
</tm:role>
<tm:role>
- <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
- <tm:topicRef href="#de"/>
+ <tm:type><tm:topicRef href="#othertopictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
</tm:role>
</tm:association>
-
- <!-- ===================================================================== -->
- <!-- === own datamodel: association (-role) constraints ================== -->
- <!-- ===================================================================== -->
- <!-- there exists one asoociation of the type written-by between the types
- author and poem. where one role is of type writer which has a player
- of type author and another role of type written which owns a player of
- type poem -->
-
- <!-- the writer role has to appear exactly once in an association of type
- written-by -->
- <tm:topic id="writer-role-constraint">
- <tm:subjectIdentifier href="http://some.where/constraint-psis/writer-role-constraint"/>
+ <!-- located-in associations have to have one role of the type container with
+ a player of the type country. The other role is of type containee with
+ a player of the type city. -->
+ <!-- place associationrole-constraint -->
+ <tm:topic id="located-in-container-role-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/located-in-container-role-constraint"/>
<tm:instanceOf><tm:topicRef href="#associationrole-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-min"/></tm:type>
@@ -1281,11 +2316,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#writer-role-constraint"/>
+ <tm:topicRef href="#located-in-container-role-constraint"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
- <tm:topicRef href="#written-by"/>
+ <tm:topicRef href="#located-in"/>
</tm:role>
</tm:association>
@@ -1293,17 +2328,17 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#writer-role-constraint"/>
+ <tm:topicRef href="#located-in-container-role-constraint"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#roletype-role"/></tm:type>
- <tm:topicRef href="#writer"/>
+ <tm:topicRef href="#container"/>
</tm:role>
</tm:association>
- <!-- the writer role owns a player of the type author -->
- <tm:topic id="writer-role-player-constraint">
- <tm:subjectIdentifier href="http://some.where/constraint-psis/writer-role-player-constraint"/>
+ <!-- place-role roleplayer-constraint -->
+ <tm:topic id="located-in-container-role-player-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/located-in-container-role-player-constrai…"/>
<tm:instanceOf><tm:topicRef href="#roleplayer-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-min"/></tm:type>
@@ -1319,11 +2354,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#writer-role-player-constraint"/>
+ <tm:topicRef href="#located-in-container-role-player-constraint"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#topictype-role"/></tm:type>
- <tm:topicRef href="#author"/>
+ <tm:topicRef href="#region"/>
</tm:role>
</tm:association>
@@ -1331,11 +2366,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#writer-role-player-constraint"/>
+ <tm:topicRef href="#located-in-container-role-player-constraint"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
- <tm:topicRef href="#written-by"/>
+ <tm:topicRef href="#located-in"/>
</tm:role>
</tm:association>
@@ -1343,19 +2378,17 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#writer-role-player-constraint"/>
+ <tm:topicRef href="#located-in-container-role-player-constraint"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#roletype-role"/></tm:type>
- <tm:topicRef href="#writer"/>
+ <tm:topicRef href="#container"/>
</tm:role>
</tm:association>
-
- <!-- the written role has to appear exactly once in an association of type
- written-by -->
- <tm:topic id="written-role-constraint">
- <tm:subjectIdentifier href="http://some.where/constraint-psis/written-role-constraint"/>
+ <!-- writer associationrole-constraint -->
+ <tm:topic id="located-in-containee-role-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/located-in-containee-role-constraint"/>
<tm:instanceOf><tm:topicRef href="#associationrole-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-min"/></tm:type>
@@ -1371,11 +2404,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-role-constraint"/>
+ <tm:topicRef href="#located-in-containee-role-constraint"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
- <tm:topicRef href="#written-by"/>
+ <tm:topicRef href="#located-in"/>
</tm:role>
</tm:association>
@@ -1383,17 +2416,17 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-role-constraint"/>
+ <tm:topicRef href="#located-in-containee-role-constraint"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#roletype-role"/></tm:type>
- <tm:topicRef href="#written"/>
+ <tm:topicRef href="#containee"/>
</tm:role>
</tm:association>
- <!-- the written role owns a player of the type poem -->
- <tm:topic id="written-role-player-constraint">
- <tm:subjectIdentifier href="http://some.where/constraint-psis/written-role-player-constraint"/>
+ <!-- place-role roleplayer-constraint -->
+ <tm:topic id="located-in-containee-role-player-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/located-in-containee-role-player-constrai…"/>
<tm:instanceOf><tm:topicRef href="#roleplayer-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type><tm:topicRef href="#card-min"/></tm:type>
@@ -1409,11 +2442,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-role-player-constraint"/>
+ <tm:topicRef href="#located-in-containee-role-player-constraint"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#topictype-role"/></tm:type>
- <tm:topicRef href="#poem"/>
+ <tm:topicRef href="#region"/>
</tm:role>
</tm:association>
@@ -1421,11 +2454,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-role-player-constraint"/>
+ <tm:topicRef href="#located-in-containee-role-player-constraint"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
- <tm:topicRef href="#written-by"/>
+ <tm:topicRef href="#located-in"/>
</tm:role>
</tm:association>
@@ -1433,27 +2466,20 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-role-player-constraint"/>
+ <tm:topicRef href="#located-in-containee-role-player-constraint"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#roletype-role"/></tm:type>
- <tm:topicRef href="#written"/>
+ <tm:topicRef href="#containee"/>
</tm:role>
</tm:association>
-
- <!-- otherrole-constraint:
- If there is a role of the type written with a player of the type poem
- there must be another role of the type writer with a player of the
- type author.
- In contrast if there is a role of the type writer with a player of the
- type author there must be a role of the type written with a player of
- the type poem.
- So for this case there are two otherrole-constraints which handle this
- both cases. -->
-
- <tm:topic id="written-by-otherrole-constraint-for-writer">
- <tm:subjectIdentifier href="written-by-otherrole-constraint-for-writer"/>
+ <!-- otherplayer-constraints:
+ A "born-in" association must have exactly one writer-role with a
+ player of the type author and one place-role with a player of the
+ type city. -->
+ <tm:topic id="located-in-otherrole-constraint-for-container">
+ <tm:subjectIdentifier href="http://some.where/contraint-psis/located-in-otherrole-constraint-for-contai…"/>
<tm:instanceOf><tm:topicRef href="#otherrole-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type>
@@ -1473,11 +2499,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ <tm:topicRef href="#located-in-otherrole-constraint-for-container"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
- <tm:topicRef href="#written-by"/>
+ <tm:topicRef href="#located-in"/>
</tm:role>
</tm:association>
@@ -1485,11 +2511,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ <tm:topicRef href="#located-in-otherrole-constraint-for-container"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#roletype-role"/></tm:type>
- <tm:topicRef href="#writer"/>
+ <tm:topicRef href="#container"/>
</tm:role>
</tm:association>
@@ -1497,11 +2523,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ <tm:topicRef href="#located-in-otherrole-constraint-for-container"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#topictype-role"/></tm:type>
- <tm:topicRef href="#author"/>
+ <tm:topicRef href="#country"/>
</tm:role>
</tm:association>
@@ -1509,11 +2535,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ <tm:topicRef href="#located-in-otherrole-constraint-for-container"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#otherroletype-role"/></tm:type>
- <tm:topicRef href="#written"/>
+ <tm:topicRef href="#containee"/>
</tm:role>
</tm:association>
@@ -1521,16 +2547,16 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ <tm:topicRef href="#located-in-otherrole-constraint-for-container"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#othertopictype-role"/></tm:type>
- <tm:topicRef href="#poem"/>
+ <tm:topicRef href="#region"/>
</tm:role>
</tm:association>
- <tm:topic id="written-by-otherrole-constraint-for-written">
- <tm:subjectIdentifier href="written-by-otherrole-constraint-for-written"/>
+ <tm:topic id="located-in-otherrole-constraint-for-containee">
+ <tm:subjectIdentifier href="http://some.where/contraint-psis/located-in-otherrole-constraint-for-contai…"/>
<tm:instanceOf><tm:topicRef href="#otherrole-constraint"/></tm:instanceOf>
<tm:occurrence>
<tm:type>
@@ -1550,11 +2576,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ <tm:topicRef href="#located-in-otherrole-constraint-for-containee"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
- <tm:topicRef href="#written-by"/>
+ <tm:topicRef href="#born-in"/>
</tm:role>
</tm:association>
@@ -1562,11 +2588,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ <tm:topicRef href="#located-in-otherrole-constraint-for-containee"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#roletype-role"/></tm:type>
- <tm:topicRef href="#written"/>
+ <tm:topicRef href="#containee"/>
</tm:role>
</tm:association>
@@ -1574,11 +2600,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ <tm:topicRef href="#located-in-otherrole-constraint-for-containee"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#topictype-role"/></tm:type>
- <tm:topicRef href="#poem"/>
+ <tm:topicRef href="#region"/>
</tm:role>
</tm:association>
@@ -1586,11 +2612,11 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ <tm:topicRef href="#located-in-otherrole-constraint-for-containee"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#otherroletype-role"/></tm:type>
- <tm:topicRef href="#writer"/>
+ <tm:topicRef href="#container"/>
</tm:role>
</tm:association>
@@ -1598,17 +2624,131 @@
<tm:type><tm:topicRef href="#applies-to"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#constraint-role"/></tm:type>
- <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ <tm:topicRef href="#located-in-otherrole-constraint-for-containee"/>
</tm:role>
<tm:role>
<tm:type><tm:topicRef href="#othertopictype-role"/></tm:type>
- <tm:topicRef href="#author"/>
+ <tm:topicRef href="#country"/>
</tm:role>
</tm:association>
<!-- ===================================================================== -->
<!-- === the "user's" topic map ========================================== -->
<!-- ===================================================================== -->
+ <tm:topic id="germany">
+ <tm:subjectIdentifier href="http://some.where/psis/country/germany"/>
+ <tm:instanceOf><tm:topicRef href="#country"/></tm:instanceOf>
+ <tm:name>
+ <tm:scope><tm:topicRef href="#de"/></tm:scope>
+ <tm:value>Deutschland</tm:value>
+ </tm:name>
+ <tm:name>
+ <tm:scope><tm:topicRef href="#en"/></tm:scope>
+ <tm:value>Germany</tm:value>
+ </tm:name>
+ </tm:topic>
+
+ <tm:topic id="poland">
+ <tm:subjectIdentifier href="http://some.where/psis/country/poland"/>
+ <tm:instanceOf><tm:topicRef href="#country"/></tm:instanceOf>
+ <tm:name>
+ <tm:scope><tm:topicRef href="#de"/></tm:scope>
+ <tm:value>Polen</tm:value>
+ </tm:name>
+ <tm:name>
+ <tm:scope><tm:topicRef href="#en"/></tm:scope>
+ <tm:value>Poland</tm:value>
+ </tm:name>
+ </tm:topic>
+
+ <tm:topic id="frankfurt_am_main">
+ <tm:subjectIdentifier href="http://some.where/psis/city/frankfurt_am_main"/>
+ <tm:instanceOf><tm:topicRef href="#metropolis"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#region-name"/></tm:type>
+ <tm:value>Frankfurt am Main</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#region-population"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedLong">659021</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#located-in"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#container"/></tm:type>
+ <tm:topicRef href="#germany"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#containee"/></tm:type>
+ <tm:topicRef href="#frankfurt_am_main"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:topic id="marbach_am_neckar">
+ <tm:subjectIdentifier href="http://some.where/psis/city/marbach_am_neckar"/>
+ <tm:instanceOf><tm:topicRef href="#city"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#region-name"/></tm:type>
+ <tm:value>Marbach am Neckar</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#region-population"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedLong">15601</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#located-in"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#container"/></tm:type>
+ <tm:topicRef href="#germany"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#containee"/></tm:type>
+ <tm:topicRef href="#marbach_am_neckar"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:topic id="lubowitz">
+ <tm:subjectIdentifier href="http://some.where/psis/city/lubowitz"/>
+ <tm:instanceOf><tm:topicRef href="#city"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#region-name"/></tm:type>
+ <tm:value>Lubowitz</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#region-population"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedLong">365</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#located-in"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#container"/></tm:type>
+ <tm:topicRef href="#poland"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#containee"/></tm:type>
+ <tm:topicRef href="#lubowitz"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:topic id="eichendorff">
+ <tm:subjectIdentifier href="http://some.where/psis/author/eichendorff"/>
+ <tm:instanceOf><tm:topicRef href="#author"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#first-name"/></tm:type>
+ <tm:value>Joseph Karl Benedikt</tm:value>
+ </tm:name>
+ <tm:name>
+ <tm:type><tm:topicRef href="#last-name"/></tm:type>
+ <tm:value>von Eichendorff</tm:value>
+ </tm:name>
+ </tm:topic>
+
<tm:topic id="goethe">
<tm:subjectIdentifier href="http://some.where/psis/author/goethe"/> <!-- must have a psi of this form -->
<tm:subjectIdentifier href="http://some.where/psis/persons/goethe"/> <!-- can own psis of any form -->
@@ -1627,6 +2767,18 @@
</tm:occurrence>
</tm:topic>
+ <tm:association>
+ <tm:type><tm:topicRef href="#born-in"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#place"/></tm:type>
+ <tm:topicRef href="#frankfurt_am_main"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#writer"/></tm:type>
+ <tm:topicRef href="#goethe"/>
+ </tm:role>
+ </tm:association>
+
<tm:topic id="schiller">
<tm:subjectIdentifier href="http://some.where/psis/author/schiller"/> <!-- must have a psi of this form -->
<tm:instanceOf><tm:topicRef href="#author"/></tm:instanceOf> <!-- must be an instanceOf author -->
@@ -1644,15 +2796,23 @@
</tm:occurrence>
</tm:topic>
+ <tm:association>
+ <tm:type><tm:topicRef href="#born-in"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#place"/></tm:type>
+ <tm:topicRef href="#marbach_am_neckar"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#writer"/></tm:type>
+ <tm:topicRef href="#schiller"/>
+ </tm:role>
+ </tm:association>
+
<tm:topic id="zauberlehrling">
<tm:subjectIdentifier href="http://some.where/psis/poem/zauberlehrling"/> <!-- must have a psi of this form -->
<tm:subjectIdentifier href="http://some.where/psis/der_zauberlehrling"/> <!-- can own psis of any form -->
<tm:instanceOf>
- <tm:topicRef href="#poem"/><!--
- <tm:topicRef href="#author"/>
- <tm:topicRef href="#zauberlehrling"/>
- <tm:topicRef href="#topictype-constraint"/>-->
- </tm:instanceOf> <!-- must be an instanceOf poem -->
+ <tm:topicRef href="#poem"/></tm:instanceOf> <!-- must be an instanceOf poem -->
<tm:name>
<tm:type><tm:topicRef href="#title"/></tm:type> <!-- must have a name of the type title -->
<tm:value>Der Zauberlehrling</tm:value>
@@ -1826,10 +2986,6 @@
</tm:occurrence>
</tm:topic>
- <!-- some assocaitions between goethe and some of his poems,
- currently there are no associations between the topic schiller
- and any other topic, because there are no topic representing
- a poem of schiller -->
<tm:association>
<tm:type><tm:topicRef href="#written-by"/></tm:type>
<tm:role>
@@ -1854,4 +3010,187 @@
</tm:role>
</tm:association>
+ <tm:topic id="resignation">
+ <tm:subjectIdentifier href="http://some.where/psis/poem/resignation"/> <!-- must have a psi of this form -->
+ <tm:instanceOf><tm:topicRef href="#poem"/></tm:instanceOf> <!-- must be an instanceOf poem -->
+ <tm:name>
+ <tm:type><tm:topicRef href="#title"/></tm:type> <!-- must have a name of the type title -->
+ <tm:value>Resignation - Eine Phantasie</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#poem-content"/></tm:type> <!-- must have an occurrence of the type poem-content with the scope de or en -->
+ <tm:scope><tm:topicRef href="#de"/></tm:scope>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">Auch ich war in Arkadien geboren,
+Auch mir hat die Natur
+An meiner Wiege Freude zugeschworen,
+Auch ich war in Arkadien geboren,
+Doch Tränen gab der kurze Lenz mir nur.
+
+Des Lebens Mai blüht einmal und nicht wieder,
+Mir hat er abgeblüht.
+Der stille Gott - o weinet, meine Brüder -
+Der stille Gott taucht meine Fackel nieder,
+Und die Erscheinung flieht.
+
+Da steh ich schon auf deiner Schauerbrücke,
+Ehrwürdge Geistermutter - Ewigkeit.
+Empfange meinen Vollmachtbrief zum Glücke,
+Ich bring ihn unerbrochen dir zurücke,
+Mein Lauf ist aus. Ich weiß von keiner Seligkeit.
+
+Vor deinem Thron erheb ich meine Klage,
+Verhüllte Richterin.
+Auf jenem Stern ging eine frohe Sage,
+Du thronest hier mit des Gerichtes Waage
+Und nennest dich Vergelterin.
+
+Hier - spricht man - warten Schrecken auf den Bösen,
+Und Freuden auf den Redlichen.
+Des Herzens Krümmen werdest du entblößen,
+Der Vorsicht Rätsel werdest du mir lösen
+Und Rechnung halten mit dem Leidenden.
+
+Hier öffne sich die Heimat dem Verbannten,
+Hier endige des Dulders Dornenbahn.
+Ein Götterkind, das sie mir Wahrheit nannten,
+Die meisten flohen, wenige nur kannten,
+Hielt meines Lebens raschen Zügel an.
+
+»Ich zahle dir in einem andern Leben,
+Gib deine Jugend mir!
+Nichts kann ich dir als diese Weisung geben.«
+Ich nahm die Weisung auf das andre Leben,
+Und meiner Jugend Freuden gab ich ihr.
+
+»Gib mir das Weib, so teuer deinem Herzen,
+Gib deine Laura mir.
+Jenseits der Gräber wuchern deine Schmerzen.« -
+Ich riß sie blutend aus dem wunden Herzen
+Und weinte laut und gab sie ihr.
+
+»Du siehst die Zeit nach jenen Ufern fliegen,
+Die blühende Natur
+Bleibt hinter ihr - ein welker Leichnam - liegen.
+Wenn Erd und Himmel trümmernd auseinanderfliegen,
+Daran erkenne den erfüllten Schwur.«
+
+»Die Schuldverschreibung lautet an die Toten«,
+Hohnlächelte die Welt,
+»Die Lügnerin, gedungen von Despoten,
+Hat für die Wahrheit Schatten dir geboten,
+Du bist nicht mehr, wenn dieser Schein verfällt.«
+
+Frech witzelte das Schlangenheer der Spötter:
+»Vor einem Wahn, den nur Verjährung weiht,
+Erzitterst du? Was sollen deine Götter,
+Des kranken Weltplans schlau erdachte Retter,
+Die Menschenwitz des Menschen Notdurft leiht?
+
+Ein Gaukelspiel, ohnmächtigen Gewürmen
+Vom Mächtigen gegönnt,
+Schreckfeuer, angesteckt auf hohen Türmen,
+Die Phantasie des Träumers zu bestürmen,
+Wo des Gesetzes Fackel dunkel brennt.
+
+Was heißt die Zukunft, die uns Gräber decken?
+Die Ewigkeit, mit der du eitel prangst?
+Ehrwürdig nur, weil schlaue Hüllen sie verstecken,
+Der Riesenschatten unsrer eignen Schrecken
+Im hohlen Spiegel der Gewissensangst;
+
+Ein Lügenbild lebendiger Gestalten,
+Die Mumie der Zeit,
+Vom Balsamgeist der Hoffnung in den kalten
+Behausungen des Grabes hingehalten,
+Das nennt dein Fieberwahn - Unsterblichkeit?
+
+Für Hoffnungen - Verwesung straft sie Lügen -
+Gabst du gewisse Güter hin?
+Sechstausend Jahre hat der Tod geschwiegen,
+Kam je ein Leichnam aus der Gruft gestiegen,
+Der Meldung tat von der Vergelterin?" -
+
+Ich sah die Zeit nach deinen Ufern fliegen,
+Die blühende Natur
+Blieb hinter ihr, ein welker Leichnam, liegen,
+Kein Toter kam aus seiner Gruft gestiegen,
+Und fest vertraut ich auf den Götterschwur.
+
+All meine Freuden hab ich dir geschlachtet,
+Jetzt werf ich mich vor deinen Richterthron.
+Der Menge Spott hab ich beherzt verachtet,
+Nur deine Güter hab ich groß geachtet,
+Vergelterin, ich fodre meinen Lohn.
+
+"Mit gleicher Liebe lieb ich meine Kinder!"
+Rief unsichtbar ein Genius.
+"Zwei Blumen", rief er, "- hört es, Menschenkinder -
+Zwei Blumen blühen für den weisen Finder,
+Sie heißen Hoffnung und Genuß.
+
+Wer dieser Blumen eine brach, begehre
+Die andre Schwester nicht.
+Genieße, wer nicht glauben kann. Die Lehre
+Ist ewig wie die Welt. Wer glauben kann, entbehre.
+Die Weltgeschichte ist das Weltgericht.
+
+Du hast gehofft, dein Lohn ist abgetragen,
+Dein Glaube war dein zugewognes Glück.
+Du konntest deine Weisen fragen,
+Was man von der Minute ausgeschlagen,
+Gibt keine Ewigkeit zurück."</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#written-by"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#writer"/></tm:type>
+ <tm:topicRef href="#schiller"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#written"/></tm:type>
+ <tm:topicRef href="#resignation"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:topic id="mondnacht">
+ <tm:subjectIdentifier href="http://some.where/psis/poem/mondnacht"/> <!-- must have a psi of this form -->
+ <tm:instanceOf><tm:topicRef href="#poem"/></tm:instanceOf> <!-- must be an instanceOf poem -->
+ <tm:name>
+ <tm:type><tm:topicRef href="#title"/></tm:type> <!-- must have a name of the type title -->
+ <tm:value>Mondnacht</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#poem-content"/></tm:type> <!-- must have an occurrence of the type poem-content with the scope de or en -->
+ <tm:scope><tm:topicRef href="#de"/></tm:scope>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">Es war, als hätt' der Himmel
+Die Erde still geküsst,
+Dass sie im Blütenschimmer
+Von ihm nun träumen müsst'.
+
+Die Luft ging durch die Felder,
+Die Ähren wogten sacht,
+Es rauschten leis' die Wälder,
+So sternklar war die Nacht.
+
+Und meine Seele spannte
+Weit ihre Flügel aus,
+Flog durch die stillen Lande,
+Als flöge sie nach Haus.</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#written-by"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#writer"/></tm:type>
+ <tm:topicRef href="#eichendorff"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#written"/></tm:type>
+ <tm:topicRef href="#mondnacht"/>
+ </tm:role>
+ </tm:association>
+
</tm:topicMap>
1
0
Author: lgiessmann
Date: Tue May 5 15:18:11 2009
New Revision: 30
Log:
some structural improvements in the json module
Added:
trunk/src/json/json_tmcl_validation.lisp
Modified:
trunk/docs/xtm_json.txt
trunk/src/isidorus.asd
trunk/src/json/json_tmcl.lisp
Modified: trunk/docs/xtm_json.txt
==============================================================================
--- trunk/docs/xtm_json.txt (original)
+++ trunk/docs/xtm_json.txt Tue May 5 15:18:11 2009
@@ -294,7 +294,7 @@
"occurrenceTypes" : [ {
"occurrenceType" : [ "psi-1", "psi-2", "..." ],
"scopeConstraints" : [ <scopeConstraints> ],
- "datatypeConstraint" : "datatype",
+ "datatypeConstraint" : "datatype"
},
<...>
],
Modified: trunk/src/isidorus.asd
==============================================================================
--- trunk/src/isidorus.asd (original)
+++ trunk/src/isidorus.asd Tue May 5 15:18:11 2009
@@ -128,9 +128,11 @@
(:module "json"
:components ((:file "json_exporter")
(:file "json_importer")
+ (:file "json_tmcl_validation"
+ :depends-on ("json_tmcl_constants" "json_exporter" ))
(:file "json_tmcl_constants")
(:file "json_tmcl"
- :depends-on ("json_tmcl_constants" "json_exporter")))
+ :depends-on ("json_tmcl_validation")))
:depends-on ("model" "xml"))
(:module "ajax"
:components ((:static-file "isidorus.html")
Modified: trunk/src/json/json_tmcl.lisp
==============================================================================
--- trunk/src/json/json_tmcl.lisp (original)
+++ trunk/src/json/json_tmcl.lisp Tue May 5 15:18:11 2009
@@ -7,13 +7,6 @@
;;+-----------------------------------------------------------------------------
-(defpackage :json-tmcl
- (:use :cl :datamodel :constants :json-tmcl-constants)
- (:export :get-constraints-of-fragment
- :topictype-p
- :abstract-p
- :list-subtypes))
-
(in-package :json-tmcl)
@@ -525,14 +518,13 @@
(defun get-topicoccurrence-constraints(constraint-topics unique-constraint-topics)
"Returns all topicoccurrence constraints as a list of the following form:
- ( ( :type <occurrencetype-topic>
- :constraints ( ( :regexp <string> :card-min <string> :card-max <string>)
- <...>)
- :scopes ( ( :scope <scope-topic> :regexp <string> :card-min <string> :card-max <string>)
- <...>)
- :datatype <string>
- :uniqe ( ( :regexp <string> :dard-min <string> :card-max <string> ) )
- <...>)."
+ [{occurrenceTypes:[{occurrenceType:[psi-1,psi-2],
+ scopeConstraints:[<scopeConstraints>],
+ datatypeConstraint:datatype},
+ <...>],
+ constraints:[<simpleConstraints>, <...>],
+ uniqueConstraint:[<uniqueConstraints>, <...> ]}
+ <...>]."
(let ((constraint-role (get-item-by-psi *constraint-role-psi*))
(applies-to (get-item-by-psi *applies-to-psi*))
(occurrencetype-role (get-item-by-psi *occurrencetype-role-psi*))
@@ -855,173 +847,6 @@
(string= (getf lst-1 :card-max) (getf lst-2 :card-max)))))
-;; --- checks if the given topic is a valid topictype --------------------------
-(defun get-direct-types-of-topic(topic-instance)
- "Returns the direct types of the topic as a list passed to this function.
- This function only returns the types of the type-instance-relationship -> TMDM 7.2"
- (let ((type-instance (get-item-by-psi *type-instance-psi*))
- (instance (get-item-by-psi *instance-psi*))
- (type (get-item-by-psi *type-psi*)))
- (let ((topic-types
- (loop for role in (player-in-roles topic-instance)
- when (eq instance (instance-of role))
- collect (loop for other-role in (roles (parent role))
- when (and (not (eq role other-role))
- (eq type-instance (instance-of (parent role)))
- (eq type (instance-of other-role)))
- return (player other-role)))))
- (when topic-types
- (remove-if #'null topic-types)))))
-
-
-(defun get-direct-supertypes-of-topic(topic-instance)
- "Returns the direct supertypes of the topic as a list passed to this function.
- This function only returns the types of the supertype-subtype-relationship -> TMDM 7.3"
- (let ((supertype-subtype (get-item-by-psi *supertype-subtype-psi*))
- (supertype (get-item-by-psi *supertype-psi*))
- (subtype (get-item-by-psi *subtype-psi*)))
- (let ((supertypes
- (loop for role in (player-in-roles topic-instance)
- when (eq subtype (instance-of role))
- append (loop for other-role in (roles (parent role))
- when (and (not (eq role other-role))
- (eq supertype-subtype (instance-of (parent role)))
- (eq supertype (instance-of other-role)))
- collect (player other-role)))))
- (remove-if #'null supertypes))))
-
-
-(defun subtype-p (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*)) (checked-topics nil))
- "Returns a list of all supertypes of the passed topic if the passed topic
- is not an instanceOf any other topic but a subtype of some supertypes
- of topictype or it is the topictype-topic itself."
- ;(format t "~%~%subtype-p ~a~%" (uri (first (psis topic-instance))))
- (let ((current-checked-topics (remove-duplicates (append checked-topics (list topic-instance)))))
-
- (when (eq topictype topic-instance)
- (return-from subtype-p current-checked-topics))
-
- (when (get-direct-types-of-topic topic-instance)
- (return-from subtype-p nil))
-
- (let ((supertypes-of-this (get-direct-supertypes-of-topic topic-instance)))
- (when (not supertypes-of-this)
- (return-from subtype-p nil))
- (when supertypes-of-this
- (loop for supertype-of-this in supertypes-of-this
- when (not (find supertype-of-this current-checked-topics :test #'eq))
- do (let ((further-supertypes (subtype-p topictype supertype-of-this current-checked-topics)))
- (when (not further-supertypes)
- (return-from subtype-p nil))
-
- (dolist (item further-supertypes)
- (pushnew item current-checked-topics))))))
-
- current-checked-topics))
-
-
-(defun topictype-p (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*))
- (topictype-constraint (get-item-by-psi *topictype-constraint-psi*))
- (checked-topics nil))
- "Returns a list of all instanceOf-topics and all Supertypes of this topic
- if this topic is a valid topic (-type). I.e. the passed topic is the
- topictype or it is an instanceOf of the topictype or it is a subtype of
- the topictype. TMDM 7.2 + TMDM 7.3"
- ;(format t "~%~%topictype-p ~a~%" (uri (first (psis topic-instance))))
- (let ((current-checked-topics (append checked-topics (list topic-instance)))
- (akos-of-this (get-direct-supertypes-of-topic topic-instance))
- (isas-of-this (get-direct-types-of-topic topic-instance)))
-
- (when (eq topictype topic-instance)
- (return-from topictype-p current-checked-topics))
-
- (when (not (union akos-of-this isas-of-this :test #'eq))
- (when topictype-constraint
- ;(return-from topictype-p nil))
- (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype)))))
- (return-from topictype-p current-checked-topics))
-
- (let ((akos-are-topictype nil))
- (loop for ako-of-this in akos-of-this
- when (not (find ako-of-this current-checked-topics))
- do (let ((further-topics (topictype-p ako-of-this topictype topictype-constraint)))
- (if further-topics
- (progn
- (dolist (item further-topics)
- (pushnew item current-checked-topics))
- (pushnew ako-of-this akos-are-topictype))
- (when topictype-constraint
- ;(return-from topictype-p nil)))))
- (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype))))))))
-
- (when isas-of-this
- (let ((topictype-topics-of-isas nil))
- (loop for isa-of-this in isas-of-this
- do (let ((topic-akos (subtype-p isa-of-this topictype)))
- (when topic-akos
- (pushnew isa-of-this topictype-topics-of-isas)
- (pushnew isa-of-this current-checked-topics)
- (dolist (item topic-akos)
- (pushnew item current-checked-topics)))))
-
- (when (and (not topictype-topics-of-isas)
- (not akos-are-topictype)
- topictype-constraint)
- ;(return-from topictype-p nil))
- (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype)))))
-
- (loop for isa-of-this in isas-of-this
- when (and (not (find isa-of-this current-checked-topics :test #'eq))
- (not (find isa-of-this topictype-topics-of-isas :test #'eq)))
- do (let ((further-topic-types (topictype-p isa-of-this topictype topictype-constraint current-checked-topics)))
- (if further-topic-types
- (dolist (item further-topic-types)
- (pushnew item current-checked-topics))
- (when topictype-constraint
- ;(return-from topictype-p nil))))))))
- (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype)))))))))))
- current-checked-topics))
-
-
-(defun topictype-of-p (topic-instance type-instance &optional (topictype (get-item-by-psi *topictype-psi*))
- (topictype-constraint (get-item-by-psi *topictype-constraint-psi*))
- checked-topics)
- "Returns a list of all types and supertypes of this topic if this topic is a
- valid instance-topic of the type-topic called type-instance. TMCL 4.4.2.
- When the type-instance is set to nil there will be checked only if the
- topic-instance is a valid instance."
- (let ((current-checked-topics (append checked-topics (list topic-instance)))
- (isas-of-this (get-direct-types-of-topic topic-instance))
- (akos-of-this (get-direct-supertypes-of-topic topic-instance)))
-
- (when (eq topic-instance topictype)
- t)
-
- (when (and (not isas-of-this)
- (not akos-of-this))
- (return-from topictype-of-p nil))
-
- (loop for isa-of-this in isas-of-this
- do (let ((found-topics (topictype-p isa-of-this topictype topictype-constraint)))
- (when (not found-topics)
- (return-from topictype-of-p nil))
- (dolist (item found-topics)
- (pushnew item current-checked-topics))))
-
- (loop for ako-of-this in akos-of-this
- when (not (find ako-of-this current-checked-topics :test #'eq))
- do (let ((found-topics (topictype-of-p ako-of-this type-instance topictype topictype-constraint current-checked-topics)))
- (when (not found-topics)
- (return-from topictype-of-p nil))
- (dolist (item found-topics)
- (pushnew item current-checked-topics))))
-
- (if type-instance
- (when (find type-instance current-checked-topics)
- current-checked-topics)
- current-checked-topics)))
-
-
;; --- gets all constraint topics ----------------------------------------------
(defun get-direct-constraint-topics-of-topic (topic-instance)
"Returns all constraint topics defined for the passed topic-instance"
@@ -1129,22 +954,6 @@
:uniqueoccurrence-constraints all-uniqueoccurrence-constraints))))
-(defun abstract-p (topic-instance)
- "Returns t if this topic type is an abstract topic type."
- (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
- (topictype-role (get-item-by-psi *topictype-role-psi*))
- (applies-to (get-item-by-psi *applies-to-psi*))
- (abstract-topictype-constraint (get-item-by-psi *abstract-topictype-constraint-psi*)))
-
- (loop for role in (player-in-roles topic-instance)
- when (and (eq topictype-role (instance-of role))
- (eq applies-to (instance-of (parent role))))
- return (loop for other-role in (roles (parent role))
- when (and (eq constraint-role (instance-of other-role))
- (eq abstract-topictype-constraint (player other-role)))
- return t))))
-
-
(defun get-direct-constraint-topics-of-association(associationtype-topic)
"Returns all direct constraint topics defined for associations if
the passed associationtype-topic"
@@ -1245,74 +1054,9 @@
all-available-associationtypes)))
-(defun list-subtypes (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*))
- (topictype-constraint (get-item-by-psi *topictype-constraint-psi*))
- (checked-topics nil) (valid-subtypes nil))
- "Returns all valid subtypes of a topic, e.g.:
- nametype-constraint ako constraint .
- first-name isa nametype .
- first-name-1 ako first-name .
- // ...
- The return value is a named list of the form (:subtypes (<topic> <...>) :checked-topics (<topic> <...>)"
- (let ((current-checked-topics (append checked-topics (list topic-instance))))
-
- (handler-case (topictype-p topic-instance topictype topictype-constraint)
- (condition () (return-from list-subtypes (list :subtypes nil :checked-topics current-checked-topics))))
-
- (let ((subtype (get-item-by-psi *subtype-psi*))
- (supertype (get-item-by-psi *supertype-psi*))
- (supertype-subtype (get-item-by-psi *supertype-subtype-psi*))
- (current-valid-subtypes (append valid-subtypes (list topic-instance))))
- (loop for role in (player-in-roles topic-instance)
- when (and (eq supertype (instance-of role))
- (eq supertype-subtype (instance-of (parent role))))
- do (loop for other-role in (roles (parent role))
- do (when (and (eq subtype (instance-of other-role))
- (not (find (player other-role) current-checked-topics)))
- (let ((new-values
- (list-subtypes (player other-role) topictype topictype-constraint current-checked-topics current-valid-subtypes)))
- (dolist (item (getf new-values :subtypes))
- (pushnew item current-valid-subtypes))
- (dolist (item (getf new-values :checked-topics))
- (pushnew item current-checked-topics))))))
- (list :subtypes current-valid-subtypes :checked-topics current-checked-topics))))
-
-
-(defun list-instances (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*))
- (topictype-constraint (get-item-by-psi *topictype-constraint-psi*)))
- "Returns the topic-instance, all subtypes found by the function lis-subtypes and all direct
- instances for the found subtypes."
- (let ((all-subtypes-of-this
- (getf (list-subtypes topic-instance topictype topictype-constraint) :subtypes))
- (type (get-item-by-psi *type-psi*))
- (instance (get-item-by-psi *instance-psi*))
- (type-instance (get-item-by-psi *type-instance-psi*)))
- (let ((all-instances-of-this
- (remove-duplicates
- (loop for subtype-of-this in all-subtypes-of-this
- append (loop for role in (player-in-roles subtype-of-this)
- when (and (eq type (instance-of role))
- (eq type-instance (instance-of (parent role))))
- append (loop for other-role in (roles (parent role))
- when (eq instance (instance-of other-role))
- collect (player other-role)))))))
- (let ((all-subtypes-of-all-instances
- (remove-if #'null
- (remove-duplicates
- (loop for subtype in all-instances-of-this
- append (getf (list-subtypes subtype nil nil) :subtypes))))))
- (remove-if #'null
- (map 'list #'(lambda(x)
- (handler-case (progn
- (topictype-of-p x nil)
- x)
- (condition () nil)))
- all-subtypes-of-all-instances))))))
-
-
(defun topics-to-json-list (topics)
"Returns a json list of psi-lists."
(json:encode-json-to-string
(map 'list #'(lambda(topic)
(map 'list #'uri (psis topic)))
- topics)))
\ No newline at end of file
+ topics)))
Added: trunk/src/json/json_tmcl_validation.lisp
==============================================================================
--- (empty file)
+++ trunk/src/json/json_tmcl_validation.lisp Tue May 5 15:18:11 2009
@@ -0,0 +1,271 @@
+;;+-----------------------------------------------------------------------------
+;;+ Isidorus
+;;+ (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
+;;+
+;;+ Isidorus is freely distributable under the LGPL license.
+;;+ You can find a detailed description in trunk/docs/LGPL-LICENSE.txt.
+;;+-----------------------------------------------------------------------------
+
+
+(defpackage :json-tmcl
+ (:use :cl :datamodel :constants :json-tmcl-constants)
+ (:export :get-constraints-of-fragment
+ :topictype-p
+ :abstract-p
+ :list-subtypes))
+
+
+(in-package :json-tmcl)
+
+
+(defun abstract-p (topic-instance)
+ "Returns t if this topic type is an abstract topic type."
+ (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+ (topictype-role (get-item-by-psi *topictype-role-psi*))
+ (applies-to (get-item-by-psi *applies-to-psi*))
+ (abstract-topictype-constraint (get-item-by-psi *abstract-topictype-constraint-psi*)))
+
+ (loop for role in (player-in-roles topic-instance)
+ when (and (eq topictype-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ return (loop for other-role in (roles (parent role))
+ when (and (eq constraint-role (instance-of other-role))
+ (eq abstract-topictype-constraint (player other-role)))
+ return t))))
+
+
+(defun topictype-of-p (topic-instance type-instance &optional (topictype (get-item-by-psi *topictype-psi*))
+ (topictype-constraint (get-item-by-psi *topictype-constraint-psi*))
+ checked-topics)
+ "Returns a list of all types and supertypes of this topic if this topic is a
+ valid instance-topic of the type-topic called type-instance. TMCL 4.4.2.
+ When the type-instance is set to nil there will be checked only if the
+ topic-instance is a valid instance."
+ (let ((current-checked-topics (append checked-topics (list topic-instance)))
+ (isas-of-this (get-direct-types-of-topic topic-instance))
+ (akos-of-this (get-direct-supertypes-of-topic topic-instance)))
+
+ (when (eq topic-instance topictype)
+ t)
+
+ (when (and (not isas-of-this)
+ (not akos-of-this))
+ (return-from topictype-of-p nil))
+
+ (loop for isa-of-this in isas-of-this
+ do (let ((found-topics (topictype-p isa-of-this topictype topictype-constraint)))
+ (when (not found-topics)
+ (return-from topictype-of-p nil))
+ (dolist (item found-topics)
+ (pushnew item current-checked-topics))))
+
+ (loop for ako-of-this in akos-of-this
+ when (not (find ako-of-this current-checked-topics :test #'eq))
+ do (let ((found-topics (topictype-of-p ako-of-this type-instance topictype topictype-constraint current-checked-topics)))
+ (when (not found-topics)
+ (return-from topictype-of-p nil))
+ (dolist (item found-topics)
+ (pushnew item current-checked-topics))))
+
+ (if type-instance
+ (when (find type-instance current-checked-topics)
+ current-checked-topics)
+ current-checked-topics)))
+
+
+(defun topictype-p (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*))
+ (topictype-constraint (get-item-by-psi *topictype-constraint-psi*))
+ (checked-topics nil))
+ "Returns a list of all instanceOf-topics and all Supertypes of this topic
+ if this topic is a valid topic (-type). I.e. the passed topic is the
+ topictype or it is an instanceOf of the topictype or it is a subtype of
+ the topictype. TMDM 7.2 + TMDM 7.3"
+ ;(format t "~%~%topictype-p ~a~%" (uri (first (psis topic-instance))))
+ (let ((current-checked-topics (append checked-topics (list topic-instance)))
+ (akos-of-this (get-direct-supertypes-of-topic topic-instance))
+ (isas-of-this (get-direct-types-of-topic topic-instance)))
+
+ (when (eq topictype topic-instance)
+ (return-from topictype-p current-checked-topics))
+
+ (when (not (union akos-of-this isas-of-this :test #'eq))
+ (when topictype-constraint
+ ;(return-from topictype-p nil))
+ (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype)))))
+ (return-from topictype-p current-checked-topics))
+
+ (let ((akos-are-topictype nil))
+ (loop for ako-of-this in akos-of-this
+ when (not (find ako-of-this current-checked-topics))
+ do (let ((further-topics (topictype-p ako-of-this topictype topictype-constraint)))
+ (if further-topics
+ (progn
+ (dolist (item further-topics)
+ (pushnew item current-checked-topics))
+ (pushnew ako-of-this akos-are-topictype))
+ (when topictype-constraint
+ ;(return-from topictype-p nil)))))
+ (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype))))))))
+
+ (when isas-of-this
+ (let ((topictype-topics-of-isas nil))
+ (loop for isa-of-this in isas-of-this
+ do (let ((topic-akos (subtype-p isa-of-this topictype)))
+ (when topic-akos
+ (pushnew isa-of-this topictype-topics-of-isas)
+ (pushnew isa-of-this current-checked-topics)
+ (dolist (item topic-akos)
+ (pushnew item current-checked-topics)))))
+
+ (when (and (not topictype-topics-of-isas)
+ (not akos-are-topictype)
+ topictype-constraint)
+ ;(return-from topictype-p nil))
+ (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype)))))
+
+ (loop for isa-of-this in isas-of-this
+ when (and (not (find isa-of-this current-checked-topics :test #'eq))
+ (not (find isa-of-this topictype-topics-of-isas :test #'eq)))
+ do (let ((further-topic-types (topictype-p isa-of-this topictype topictype-constraint current-checked-topics)))
+ (if further-topic-types
+ (dolist (item further-topic-types)
+ (pushnew item current-checked-topics))
+ (when topictype-constraint
+ ;(return-from topictype-p nil))))))))
+ (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype)))))))))))
+ current-checked-topics))
+
+
+(defun subtype-p (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*)) (checked-topics nil))
+ "Returns a list of all supertypes of the passed topic if the passed topic
+ is not an instanceOf any other topic but a subtype of some supertypes
+ of a topictype or it is the topictype-topic itself.
+ This function isn't useable as a standalone function - it's only necessary
+ for a special case in the function topictype-p."
+ ;(format t "~%~%subtype-p ~a~%" (uri (first (psis topic-instance))))
+ (let ((current-checked-topics (remove-duplicates (append checked-topics (list topic-instance)))))
+
+ (when (eq topictype topic-instance)
+ (return-from subtype-p current-checked-topics))
+
+ (when (get-direct-types-of-topic topic-instance)
+ (return-from subtype-p nil))
+
+ (let ((supertypes-of-this (get-direct-supertypes-of-topic topic-instance)))
+ (when (not supertypes-of-this)
+ (return-from subtype-p nil))
+ (when supertypes-of-this
+ (loop for supertype-of-this in supertypes-of-this
+ when (not (find supertype-of-this current-checked-topics :test #'eq))
+ do (let ((further-supertypes (subtype-p topictype supertype-of-this current-checked-topics)))
+ (when (not further-supertypes)
+ (return-from subtype-p nil))
+
+ (dolist (item further-supertypes)
+ (pushnew item current-checked-topics))))))
+
+ current-checked-topics))
+
+
+(defun get-direct-types-of-topic(topic-instance)
+ "Returns the direct types of the topic as a list passed to this function.
+ This function only returns the types of the type-instance-relationship -> TMDM 7.2
+ This function was defined for the use in topictype-p and not for a standalone
+ usage."
+ (let ((type-instance (get-item-by-psi *type-instance-psi*))
+ (instance (get-item-by-psi *instance-psi*))
+ (type (get-item-by-psi *type-psi*)))
+ (let ((topic-types
+ (loop for role in (player-in-roles topic-instance)
+ when (eq instance (instance-of role))
+ collect (loop for other-role in (roles (parent role))
+ when (and (not (eq role other-role))
+ (eq type-instance (instance-of (parent role)))
+ (eq type (instance-of other-role)))
+ return (player other-role)))))
+ (when topic-types
+ (remove-if #'null topic-types)))))
+
+
+(defun get-direct-supertypes-of-topic(topic-instance)
+ "Returns the direct supertypes of the topic as a list passed to this function.
+ This function only returns the types of the supertype-subtype-relationship -> TMDM 7.3.
+ This function was defined for the use in topictype-p and not for a standalone
+ usage."
+ (let ((supertype-subtype (get-item-by-psi *supertype-subtype-psi*))
+ (supertype (get-item-by-psi *supertype-psi*))
+ (subtype (get-item-by-psi *subtype-psi*)))
+ (let ((supertypes
+ (loop for role in (player-in-roles topic-instance)
+ when (eq subtype (instance-of role))
+ append (loop for other-role in (roles (parent role))
+ when (and (not (eq role other-role))
+ (eq supertype-subtype (instance-of (parent role)))
+ (eq supertype (instance-of other-role)))
+ collect (player other-role)))))
+ (remove-if #'null supertypes))))
+
+
+(defun list-subtypes (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*))
+ (topictype-constraint (get-item-by-psi *topictype-constraint-psi*))
+ (checked-topics nil) (valid-subtypes nil))
+ "Returns all valid subtypes of a topic, e.g.:
+ nametype-constraint ako constraint .
+ first-name isa nametype .
+ first-name-1 ako first-name .
+ // ...
+ The return value is a named list of the form (:subtypes (<topic> <...>) :checked-topics (<topic> <...>)"
+ (let ((current-checked-topics (append checked-topics (list topic-instance))))
+
+ (handler-case (topictype-p topic-instance topictype topictype-constraint)
+ (condition () (return-from list-subtypes (list :subtypes nil :checked-topics current-checked-topics))))
+
+ (let ((subtype (get-item-by-psi *subtype-psi*))
+ (supertype (get-item-by-psi *supertype-psi*))
+ (supertype-subtype (get-item-by-psi *supertype-subtype-psi*))
+ (current-valid-subtypes (append valid-subtypes (list topic-instance))))
+ (loop for role in (player-in-roles topic-instance)
+ when (and (eq supertype (instance-of role))
+ (eq supertype-subtype (instance-of (parent role))))
+ do (loop for other-role in (roles (parent role))
+ do (when (and (eq subtype (instance-of other-role))
+ (not (find (player other-role) current-checked-topics)))
+ (let ((new-values
+ (list-subtypes (player other-role) topictype topictype-constraint current-checked-topics current-valid-subtypes)))
+ (dolist (item (getf new-values :subtypes))
+ (pushnew item current-valid-subtypes))
+ (dolist (item (getf new-values :checked-topics))
+ (pushnew item current-checked-topics))))))
+ (list :subtypes current-valid-subtypes :checked-topics current-checked-topics))))
+
+
+(defun list-instances (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*))
+ (topictype-constraint (get-item-by-psi *topictype-constraint-psi*)))
+ "Returns the topic-instance, all subtypes found by the function lis-subtypes and all direct
+ instances for the found subtypes."
+ (let ((all-subtypes-of-this
+ (getf (list-subtypes topic-instance topictype topictype-constraint) :subtypes))
+ (type (get-item-by-psi *type-psi*))
+ (instance (get-item-by-psi *instance-psi*))
+ (type-instance (get-item-by-psi *type-instance-psi*)))
+ (let ((all-instances-of-this
+ (remove-duplicates
+ (loop for subtype-of-this in all-subtypes-of-this
+ append (loop for role in (player-in-roles subtype-of-this)
+ when (and (eq type (instance-of role))
+ (eq type-instance (instance-of (parent role))))
+ append (loop for other-role in (roles (parent role))
+ when (eq instance (instance-of other-role))
+ collect (player other-role)))))))
+ (let ((all-subtypes-of-all-instances
+ (remove-if #'null
+ (remove-duplicates
+ (loop for subtype in all-instances-of-this
+ append (getf (list-subtypes subtype nil nil) :subtypes))))))
+ (remove-if #'null
+ (map 'list #'(lambda(x)
+ (handler-case (progn
+ (topictype-of-p x nil)
+ x)
+ (condition () nil)))
+ all-subtypes-of-all-instances))))))
\ No newline at end of file
1
0

05 May '09
Author: lgiessmann
Date: Tue May 5 12:28:18 2009
New Revision: 29
Log:
changed the tmcl-json-model and the tmcl-json-exporter. so there will be exported to every constraint the original topictypes e.g. nametypes and all valid subtypes, the second point is that there will be exported all possible player-psis of associationrole, so the user is able to choose a player directly without further communication with the server
Modified:
trunk/docs/xtm_json.txt
trunk/src/json/json_tmcl.lisp
trunk/src/rest_interface/set-up-json-interface.lisp
Modified: trunk/docs/xtm_json.txt
==============================================================================
--- trunk/docs/xtm_json.txt (original)
+++ trunk/docs/xtm_json.txt Tue May 5 12:28:18 2009
@@ -226,7 +226,7 @@
//+ subjectLocator, this member contains an unsigendInt or the string
//+ "MAX_INT".
//+-----------------------------------------------------------------------------
-<simepleConstraint>
+<simpleConstraint>
//+-----------------------------------------------------------------------------
@@ -249,20 +249,18 @@
//+-----------------------------------------------------------------------------
//+ topicNameConstraint
-//+ The topicNameConstraint describes how the topic's names have to be
-//+ defined.
-//+ The nameType is a topic representation in form of a list of psis of the
-//+ topic representing the name's type.
-//+ regexp defines the content of the name.
-//+ cardMin defines the minimum number of names a topic must have.
-//+ cardMax defines the maximum number of names a topic must have.
-//+ nameTypeScopes describes how many scopes there must exist and of what
-//+ type the scopes have to be .
+//+ nametypescope constains the original nametype and all valid subtypes
+//+ with the specific scope constraints.
+//+ constriants contains the constraints for the owner topic.
//+-----------------------------------------------------------------------------
{
- "nameType" : [ "topic-psi-1", "topic-psi-2", "..." ],
- "constraints" : [ <simpleConstraint>, < ... > ],
- "scopeConstraints" : { <scopeConstraint> }
+ "nametypescopes" : [ {
+ "nametype" : [psi-1, psi-2, "..." ],
+ "scopeConstraints" : [ <scopeConstraints> ]
+ },
+ <...>
+ ]
+ "constraints" : [ <simpleConstraint>, < ... > ]
}
@@ -282,16 +280,26 @@
//+-----------------------------------------------------------------------------
//+ topicOccurrenceConstraint
-//+ The topicOccurrenceConstraint describes how the topic's occurrences have
-//+ to be defined.
-//+
-//+-----------------------------------------------------------------------------
-{
- "occurrenceType" : [ "topic-psi-1", "topic-psi-2", "..." ],
- "constraints" : [ <simpleConstraint>, < ... > ],
- "scopeConstraints" : { <scopeConstraint> },
- "dataConstraint" : "datatype",
- "uniqueConstraints" : [ <uniqueOccurrenceConstraint>, <...> ]
+//+ occurrenceTypes contains a list of a json-sub-object. This sub-object
+//+ contains an occurrenceType a specific list of scopeConstraints for
+//+ the occurrenceType and a scpecific datatypeConstraint which contains
+//+ the datatype for the occurrenceType.
+//+ The entire list of occurrenceTypes contains the not only the
+//+ original occurrenceType but also the subtypes of this occurrenceType.
+//+ constraints is a constraint list of depending to the owner topic.
+//+ unqiqueConstraint is a list of uniqeConstraints which also depends on
+//+ the owner topic.
+//+-----------------------------------------------------------------------------
+{
+ "occurrenceTypes" : [ {
+ "occurrenceType" : [ "psi-1", "psi-2", "..." ],
+ "scopeConstraints" : [ <scopeConstraints> ],
+ "datatypeConstraint" : "datatype",
+ },
+ <...>
+ ],
+ "constraints" : [ <simpleConstraints>, <...>],
+ "uniqueConstraint" : [ <uniqueConstraints>, <...> ]
}
@@ -303,7 +311,7 @@
//+ in an association of a certain associationtype (the objects owner).
//+-----------------------------------------------------------------------------
{
- "roleType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+ "roleType" : [ [ "topic-psi-1", "topic-psi-2", "..." ], ["subtype-1-psi-1", "..."], <...> ],
"cardMin" : "unsigned integer in string representation",
"cardMax" : "unsigend integer in string representation or the string MAX_INT"
}
@@ -312,17 +320,17 @@
//+-----------------------------------------------------------------------------
//+ rolePlayerConstraint
//+ Defines the player of a certain role with a given type in an association
-//+ with a given type.
-//+ playerType is the psi-list representation of the player-topic.
-//+ roleType is the is a list of topic-psis representing a topic which can
-//+ be a player in the given role.
+//+ of a given type.
+//+ palyers is the psi-list representation of a list of all available
+//+ players.
+//+ roleTypes is a list of topics represented by a list of psi-lists.
//+ cardMin and cardMax defines the number of times the topicType (= player)
//+ can be the player in a role of a given type (= roleTypes) in an
//+ association of a given type (= objects owner).
//+-----------------------------------------------------------------------------
{
- "playerType" : [ "topic-psi-1", "topic-psi-2", "..." ],
- "roleType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+ "players" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "topic-2-psi-1", "..."], <...> ]
+ "roleTypes" : [ [ "topic-psi-1", "topic-psi-2", "..." ], [ "subtype-psi-1", "..." ], <...> ],
"cardMin" : "unsigned integer in string representation",
"cardMax" : "unsigend integer in string representation or the string MAX_INT"
}
Modified: trunk/src/json/json_tmcl.lisp
==============================================================================
--- trunk/src/json/json_tmcl.lisp (original)
+++ trunk/src/json/json_tmcl.lisp Tue May 5 12:28:18 2009
@@ -11,14 +11,15 @@
(:use :cl :datamodel :constants :json-tmcl-constants)
(:export :get-constraints-of-fragment
:topictype-p
- :abstract-p))
+ :abstract-p
+ :list-subtypes))
(in-package :json-tmcl)
-;; -----------------------------------------------------------------------------
+;; =============================================================================
;; --- all fragment constraints ------------------------------------------------
-;; -----------------------------------------------------------------------------
+;; =============================================================================
(defun get-constraints-of-fragment(topic-psi &key (treat-as 'type))
(let ((associationtype (get-item-by-psi *associationtype-psi*))
(associationtype-constraint (get-item-by-psi *associationtype-constraint-psi*))
@@ -54,9 +55,9 @@
json-string)))))))
-;; -----------------------------------------------------------------------------
+;; =============================================================================
;; --- all association constraints ---------------------------------------------
-;; -----------------------------------------------------------------------------
+;; =============================================================================
(defun get-constraints-of-association (associationtype-topic)
"Returns a list of constraints which are describing associations of the
passed associationtype-topic."
@@ -94,7 +95,9 @@
(othertopictype-role (get-item-by-psi *othertopictype-role-psi*))
(otherroletype-role (get-item-by-psi *otherroletype-role-psi*))
(roletype (get-item-by-psi *roletype-psi*))
- (roletype-constraint (get-item-by-psi *roletype-constraint-psi*)))
+ (roletype-constraint (get-item-by-psi *roletype-constraint-psi*))
+ (topictype (get-item-by-psi *topictype-psi*))
+ (topictype-constraint (get-item-by-psi *topictype-constraint-psi*)))
(let ((otherrole-constraints
(loop for constraint-topic in constraint-topics
append (let ((players nil)
@@ -177,17 +180,21 @@
(uri (first (psis (getf involved-topic-tupple :otherrole))))
constraint-lists))
(let ((json-player
- (concatenate 'string "\"playerType\":"
- (json-exporter::identifiers-to-json-string (getf involved-topic-tupple :player))))
+ (concatenate 'string "\"players\":"
+ (topics-to-json-list
+ (list-instances (getf involved-topic-tupple :player) topictype topictype-constraint))))
(json-role
- (concatenate 'string "\"roleType\":"
- (json-exporter::identifiers-to-json-string (getf involved-topic-tupple :role))))
+ (concatenate 'string "\"roleTypes\":"
+ (topics-to-json-list
+ (getf (list-subtypes (getf involved-topic-tupple :role) roletype roletype-constraint) :subtypes))))
(json-otherplayer
- (concatenate 'string "\"otherPlayerType\":"
- (json-exporter::identifiers-to-json-string (getf involved-topic-tupple :player))))
+ (concatenate 'string "\"otherPlayers\":"
+ (topics-to-json-list
+ (list-instances (getf involved-topic-tupple :otherplayer) topictype topictype-constraint))))
(json-otherrole
(concatenate 'string "\"otherRoleType\":"
- (json-exporter::identifiers-to-json-string (getf involved-topic-tupple :role))))
+ (topics-to-json-list
+ (getf (list-subtypes (getf involved-topic-tupple :otherrole) roletype roletype-constraint) :subtypes))))
(card-min
(concatenate 'string "\"cardMin\":" (getf (first constraint-lists) :card-min)))
(card-max
@@ -212,7 +219,9 @@
(topictype-role (get-item-by-psI *topictype-role-psi*))
(roletype-role (get-item-by-psi *roletype-role-psi*))
(roletype (get-item-by-psi *roletype-psi*))
- (roletype-constraint (get-item-by-psi *roletype-constraint-psi*)))
+ (roletype-constraint (get-item-by-psi *roletype-constraint-psi*))
+ (topictype (get-item-by-psi *topictype-psi*))
+ (topictype-constraint (get-item-by-psi *topictype-constraint-psi*)))
(let ((roleplayer-constraints
(loop for constraint-topic in constraint-topics
append (let ((constraint-list
@@ -251,11 +260,11 @@
(topictype-p current-player)
(topictype-p current-role roletype roletype-constraint)
(list :player current-player
- :role current-role)))
+ :role current-role)))
: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
@@ -269,19 +278,21 @@
(uri (first (psis (getf role-player-tupple :role))))
(uri (first (psis (getf role-player-tupple :player))))
constraint-lists))
- (let ((json-player
- (concatenate 'string "\"playerType\":"
- (json-exporter::identifiers-to-json-string (getf role-player-tupple :player))))
+ (let ((json-players
+ (concatenate 'string "\"players\":"
+ (topics-to-json-list
+ (list-instances (getf role-player-tupple :player) topictype topictype-constraint))))
(json-role
- (concatenate 'string "\"roleType\":"
- (json-exporter::identifiers-to-json-string (getf role-player-tupple :role))))
+ (concatenate 'string "\"roleTypes\":"
+ (topics-to-json-list
+ (getf (list-subtypes (getf role-player-tupple :role) roletype roletype-constraint) :subtypes))))
(card-min
(concatenate 'string "\"cardMin\":" (getf (first constraint-lists) :card-min)))
(card-max
(concatenate 'string "\"cardMax\":" (getf (first constraint-lists) :card-max))))
(setf cleaned-roleplayer-constraints
(concatenate 'string cleaned-roleplayer-constraints
- "{" json-player "," json-role "," card-min "," card-max "},")))))
+ "{" json-players "," json-role "," card-min "," card-max "},")))))
(if (string= cleaned-roleplayer-constraints "[")
(setf cleaned-roleplayer-constraints "null")
(setf cleaned-roleplayer-constraints
@@ -325,12 +336,17 @@
collect (getf associationrole-constraint :constraint)))))
(when (> (length constraint-lists) 1)
(error "found contrary associationrole-constraints: ~a ~a~%" (uri (first (psis associationroletype-topic))) constraint-lists))
+ (let ((roletype-with-subtypes
+ (json:encode-json-to-string
+ (map 'list #'(lambda(topic)
+ (map 'list #'uri (psis topic)))
+ (getf (list-subtypes associationroletype-topic roletype roletype-constraint) :subtypes)))))
(setf cleaned-associationrole-constraints
(concatenate 'string
cleaned-associationrole-constraints
- "{\"roleType\":" (json-exporter::identifiers-to-json-string associationroletype-topic)
+ "{\"roleType\":" roletype-with-subtypes
",\"cardMin\":" (getf (first constraint-lists) :card-min)
- ",\"cardMax\":" (getf (first constraint-lists) :card-max) "},"))))
+ ",\"cardMax\":" (getf (first constraint-lists) :card-max) "},")))))
(if (string= cleaned-associationrole-constraints "[")
(setf cleaned-associationrole-constraints "null")
@@ -339,9 +355,9 @@
cleaned-associationrole-constraints)))))
-;; -----------------------------------------------------------------------------
+;; =============================================================================
;; --- all topic constraints ---------------------------------------------------
-;; -----------------------------------------------------------------------------
+;; =============================================================================
(defun get-constraints-of-topic (topic-instance &key(treat-as 'type))
"Returns a constraint list with the constraints:
subjectidentifier-constraints, subjectlocator-constraints,
@@ -425,7 +441,7 @@
"Transforms a list of simple constraint lists of the form
((:regexp <string> :card-min <string> :card-max <string>) <...>)
to a valid json list of the form
- [{\"regexp\":\"expr\",\"cardMin\":\"123\",\"cardMax\":\"456\"}, <...>]."
+ [{regexp: expr, cardMin: 123, cardMax: 456}, <...>]."
(let ((constraints "["))
(loop for constraint in simple-constraints
do (let ((constraint (concatenate 'string "{\"regexp\":"
@@ -446,12 +462,10 @@
(defun get-topicname-constraints(constraint-topics)
"Returns all topicname constraints as a list of the following form:
- ( ( :type <nametype-topic>
- :constraints ( ( :regexp <string> :card-min <string> :card-max <string>)
- <...>)
- :scopes ( ( :scope <scope-topic> :regexp <string> :card-min <string> :card-max <string>)
- <...>))
- <...>)."
+ [{nametypescopes:[{nameType: [psi-1, psi-2], scopeConstraints: [<scopeConstraint>]},
+ {nameType: [subtype-1-psi-1], scopeConstriants: [<scopeConstraints>]},
+ constraints: [<simpleConstraint>, <...>]},
+ <...>]."
(let ((constraint-role (get-item-by-psi *constraint-role-psi*))
(applies-to (get-item-by-psi *applies-to-psi*))
(nametype-role (get-item-by-psi *nametype-role-psi*))
@@ -466,16 +480,15 @@
append (loop for other-role in (roles (parent role))
when (eq nametype-role (instance-of other-role))
collect (let ((nametype-topic (player other-role))
- (constraint-list (get-constraint-topic-values constraint-topic)))
+ (constraint-list (get-constraint-topic-values constraint-topic)))
(list :type nametype-topic :constraint constraint-list))))))))
-
(let ((nametype-topics
- (remove-duplicates (map 'list #'(lambda(x)
- (let ((topicname-type
- (getf x :type)))
- (topictype-p topicname-type nametype nametype-constraint)
- topicname-type))
- topicname-constraints))))
+ (map 'list #'(lambda(x)
+ (let ((topicname-type
+ (getf x :type)))
+ (topictype-p topicname-type nametype nametype-constraint)
+ topicname-type))
+ topicname-constraints)))
(let ((cleaned-topicname-constraints "["))
(loop for nametype-topic in nametype-topics
do (let ((constraint-lists
@@ -487,17 +500,22 @@
(find-contrary-constraints constraint-lists)))
(when contrary-constraints
(error "found contrary topicname-constraints: ~a~%" contrary-constraints)))
- (let ((typescope-constraints
- (let ((current-scopes
- (get-typescope-constraints nametype-topic :what 'topicname)))
- (concatenate 'string "\"scopeConstraints\":" current-scopes)))
- (json-constraint-lists
- (concatenate 'string "\"constraints\":" (simple-constraints-to-json constraint-lists)))
- (type-topic
- (concatenate 'string "\"nameType\":"
- (json-exporter::identifiers-to-json-string nametype-topic))))
- (setf cleaned-topicname-constraints
- (concatenate 'string cleaned-topicname-constraints "{" type-topic "," json-constraint-lists "," typescope-constraints "},")))))
+ (let ((nametype-with-subtypes
+ (remove-if #'null (getf (list-subtypes nametype-topic nametype nametype-constraint) :subtypes))))
+ (let ((nametypescopes "\"nametypescopes\":["))
+ (loop for current-topic in nametype-with-subtypes
+ do (let ((current-json-string
+ (concatenate 'string "{\"nameType\":" (json-exporter::identifiers-to-json-string current-topic)
+ ",\"scopeConstraints\":" (get-typescope-constraints current-topic :what 'topicname) "}")))
+ (setf nametypescopes (concatenate 'string nametypescopes current-json-string ","))))
+ (if (string= nametypescopes "\"nametypescopes\"[")
+ (setf nametypescopes "null")
+ (setf nametypescopes
+ (concatenate 'string (subseq nametypescopes 0 (- (length nametypescopes) 1)) "]")))
+ (let ((json-constraint-lists
+ (concatenate 'string "\"constraints\":" (simple-constraints-to-json constraint-lists))))
+ (setf cleaned-topicname-constraints
+ (concatenate 'string cleaned-topicname-constraints "{" nametypescopes "," json-constraint-lists "},")))))))
(if (string= cleaned-topicname-constraints "[")
(setf cleaned-topicname-constraints "null")
(setf cleaned-topicname-constraints
@@ -548,24 +566,32 @@
(find-contrary-constraints constraint-lists)))
(when contrary-constraints
(error "found contrary topicname-constraints: ~a~%" contrary-constraints)))
- (let ((type-topic
- (concatenate 'string "\"occurrenceType\":"
- (json-exporter::identifiers-to-json-string occurrencetype-topic)))
- (typescope-constraints
- (let ((current-scopes
- (get-typescope-constraints occurrencetype-topic :what 'topicoccurrence)))
- (concatenate 'string "\"scopeConstraints\":" current-scopes)))
- (datatype-constraint
- (concatenate 'string "\"datatypeConstraint\":"
- (get-occurrence-datatype-constraint occurrencetype-topic)))
- (unique-constraints
- (concatenate 'string "\"uniqueConstraints\":"
- (get-simple-constraints unique-constraint-topics)))
- (json-constraint-lists
- (concatenate 'string "\"constraints\":" (simple-constraints-to-json constraint-lists))))
- (setf cleaned-topicoccurrence-constraints
- (concatenate 'string cleaned-topicoccurrence-constraints
- "{" type-topic "," json-constraint-lists "," typescope-constraints "," datatype-constraint "," unique-constraints "},")))))
+
+
+ (let ((occurrencetype-with-subtypes
+ (getf (list-subtypes occurrencetype-topic occurrencetype occurrencetype-constraint) :subtypes)))
+
+ (let ((occurrencetypes-json-string "\"occurrenceTypes\":["))
+ (loop for current-topic in occurrencetype-with-subtypes
+ do (let ((current-json-string
+ (concatenate 'string "{\"occurrenceType\":" (json-exporter::identifiers-to-json-string current-topic)
+ ",\"scopeConstraints\":" (get-typescope-constraints current-topic :what 'topicoccurrence)
+ ",\"datatypeConstraint\":" (get-occurrence-datatype-constraint current-topic) "}")))
+ (setf occurrencetypes-json-string (concatenate 'string occurrencetypes-json-string current-json-string ","))))
+
+ (if (string= occurrencetypes-json-string "\"occurrenceTypes\"[")
+ (setf occurrencetypes-json-string "null")
+ (setf occurrencetypes-json-string
+ (concatenate 'string (subseq occurrencetypes-json-string 0 (- (length occurrencetypes-json-string) 1)) "]")))
+ (let ((unique-constraints
+ (concatenate 'string "\"uniqueConstraints\":"
+ (get-simple-constraints unique-constraint-topics)))
+ (json-constraint-lists
+ (concatenate 'string "\"constraints\":" (simple-constraints-to-json constraint-lists))))
+ (let ((current-json-string
+ (concatenate 'string "{" occurrencetypes-json-string "," json-constraint-lists "," unique-constraints "}")))
+ (setf cleaned-topicoccurrence-constraints
+ (concatenate 'string cleaned-topicoccurrence-constraints current-json-string ","))))))))
(if (string= cleaned-topicoccurrence-constraints "[")
(setf cleaned-topicoccurrence-constraints "null")
(setf cleaned-topicoccurrence-constraints
@@ -609,9 +635,10 @@
a topicname, a topicoccurrence or an association. To specifiy of what kind
of element the scopes should be there is the key-variable what.
It can be set to 'topicname, 'topicoccurrence or 'association.
- The return value is of the form
- ( :scope <scope-topic>
- :constraint (:card-min <string> :card-max <string> ))."
+ The return value is of the form:
+ [{scopeTypes:[[[psi-1-1, psi-1-2], [subtype-1-psi-1, subtype-1-psi-2]], [[psi-2-1],
+ [subtype-1-psi-1], [subtype-2-psi-1]]], cardMin: <int-as-string>,
+ cardMax <int-as-string | MAX_INT>}, <...>]."
(let ((element-type-role-and-scope-constraint
(cond
((eq what 'topicname)
@@ -627,7 +654,8 @@
(get-item-by-psi *associationtypescope-constraint-psi*)))))
(scopetype-role (get-item-by-psi *scopetype-role-psi*))
(constraint-role (get-item-by-psi *constraint-role-psi*))
- (applies-to (get-item-by-psi *applies-to-psi*)))
+ (applies-to (get-item-by-psi *applies-to-psi*))
+ (scopetype (get-item-by-psi *scopetype-psi*)))
(when (and (= (length element-type-role-and-scope-constraint) 2)
(first element-type-role-and-scope-constraint)
(second element-type-role-and-scope-constraint))
@@ -677,13 +705,22 @@
constraint-lists))
(let ((card-min (getf (first constraint-lists) :card-min))
(card-max (getf (first constraint-lists) :card-max)))
- (let ((json-scopes "\"scopeTypes\":["))
- (dolist (item scopetype-group)
- (let ((json-list (json-exporter::identifiers-to-json-string item)))
- (setf json-scopes (concatenate 'string json-scopes json-list ","))))
- (setf json-scopes (subseq json-scopes 0 (- (length json-scopes) 1)))
+ (let ((json-scopes
+ (concatenate 'string "\"scopeTypes\":"
+
+ (let ((scopetypes-with-subtypes
+ (remove-if #'null
+ (loop for current-scopetype in scopetype-group
+ collect (getf (list-subtypes current-scopetype scopetype nil) :subtypes)))))
+
+ (json:encode-json-to-string
+ (map 'list #'(lambda(topic-group)
+ (map 'list #'(lambda(topic)
+ (map 'list #'uri (psis topic)))
+ topic-group))
+ scopetypes-with-subtypes))))))
(let ((current-json-string
- (concatenate 'string "{" json-scopes "],\"cardMin\":\"" card-min "\",\"cardMax\":\"" card-max "\"}")))
+ (concatenate 'string "{" json-scopes ",\"cardMin\":\"" card-min "\",\"cardMax\":\"" card-max "\"}")))
(setf cleaned-typescope-constraints
(concatenate 'string cleaned-typescope-constraints current-json-string ",")))))))
(if (string= cleaned-typescope-constraints "[")
@@ -693,9 +730,9 @@
cleaned-typescope-constraints)))))))
-;; -----------------------------------------------------------------------------
+;; =============================================================================
;; --- some basic helpers ------------------------------------------------------
-;; -----------------------------------------------------------------------------
+;; =============================================================================
(defun get-constraint-topic-values(topic)
"Returns all constraint values of the passed topic in the
following form (list :regexp regexp :card-min card-min :card-max card-max)"
@@ -946,11 +983,14 @@
current-checked-topics))
-(defun topictype-of-p (topic-instance type-instance &optional checked-topics)
+(defun topictype-of-p (topic-instance type-instance &optional (topictype (get-item-by-psi *topictype-psi*))
+ (topictype-constraint (get-item-by-psi *topictype-constraint-psi*))
+ checked-topics)
"Returns a list of all types and supertypes of this topic if this topic is a
- valid instance-topic of the type-topic called type-instance. TMCL 4.4.2"
+ valid instance-topic of the type-topic called type-instance. TMCL 4.4.2.
+ When the type-instance is set to nil there will be checked only if the
+ topic-instance is a valid instance."
(let ((current-checked-topics (append checked-topics (list topic-instance)))
- (topictype (get-item-by-psi *topictype-psi*))
(isas-of-this (get-direct-types-of-topic topic-instance))
(akos-of-this (get-direct-supertypes-of-topic topic-instance)))
@@ -962,7 +1002,7 @@
(return-from topictype-of-p nil))
(loop for isa-of-this in isas-of-this
- do (let ((found-topics (topictype-p isa-of-this)))
+ do (let ((found-topics (topictype-p isa-of-this topictype topictype-constraint)))
(when (not found-topics)
(return-from topictype-of-p nil))
(dolist (item found-topics)
@@ -970,13 +1010,15 @@
(loop for ako-of-this in akos-of-this
when (not (find ako-of-this current-checked-topics :test #'eq))
- do (let ((found-topics (topictype-of-p ako-of-this type-instance current-checked-topics)))
+ do (let ((found-topics (topictype-of-p ako-of-this type-instance topictype topictype-constraint current-checked-topics)))
(when (not found-topics)
(return-from topictype-of-p nil))
(dolist (item found-topics)
(pushnew item current-checked-topics))))
- (when (find type-instance current-checked-topics)
+ (if type-instance
+ (when (find type-instance current-checked-topics)
+ current-checked-topics)
current-checked-topics)))
@@ -1170,6 +1212,8 @@
(constraint-role (get-item-by-psi *constraint-role-psi*))
(othertopictype-role (get-item-by-psi *othertopictype-role-psi*))
(associationtype-role (get-item-by-psi *associationtype-role-psi*))
+ (associationtype (get-item-by-psi *associationtype-psi*))
+ (associationtype-constraint (get-item-by-psi *associationtype-constraint-psi*))
(roleplayer-constraint (get-item-by-psi *roleplayer-constraint-psi*))
(otherrole-constraint (get-item-by-psi *otherrole-constraint-psi*))
(all-possible-player-topics
@@ -1178,9 +1222,6 @@
(topictype-p topic-instance)
(loop for topic in (union (get-direct-types-of-topic topic-instance) (get-direct-supertypes-of-topic topic-instance))
append (topictype-p topic))))))
-
-
- ;what's with associationrole-constraints without a player-constraint???
(let ((all-available-associationtypes
(remove-duplicates
(loop for possible-player-topic in all-possible-player-topics
@@ -1197,5 +1238,81 @@
(eq applies-to (instance-of (parent c-role))))
append (loop for type-role in (roles (parent c-role))
when (eq associationtype-role (instance-of type-role))
- collect (player type-role)))))))))
- all-available-associationtypes)))
\ No newline at end of file
+ append (map 'list #'(lambda(x)
+ (topictype-p x associationtype associationtype-constraint)
+ x)
+ (getf (list-subtypes (player type-role) associationtype associationtype-constraint) :subtypes))))))))))
+ all-available-associationtypes)))
+
+
+(defun list-subtypes (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*))
+ (topictype-constraint (get-item-by-psi *topictype-constraint-psi*))
+ (checked-topics nil) (valid-subtypes nil))
+ "Returns all valid subtypes of a topic, e.g.:
+ nametype-constraint ako constraint .
+ first-name isa nametype .
+ first-name-1 ako first-name .
+ // ...
+ The return value is a named list of the form (:subtypes (<topic> <...>) :checked-topics (<topic> <...>)"
+ (let ((current-checked-topics (append checked-topics (list topic-instance))))
+
+ (handler-case (topictype-p topic-instance topictype topictype-constraint)
+ (condition () (return-from list-subtypes (list :subtypes nil :checked-topics current-checked-topics))))
+
+ (let ((subtype (get-item-by-psi *subtype-psi*))
+ (supertype (get-item-by-psi *supertype-psi*))
+ (supertype-subtype (get-item-by-psi *supertype-subtype-psi*))
+ (current-valid-subtypes (append valid-subtypes (list topic-instance))))
+ (loop for role in (player-in-roles topic-instance)
+ when (and (eq supertype (instance-of role))
+ (eq supertype-subtype (instance-of (parent role))))
+ do (loop for other-role in (roles (parent role))
+ do (when (and (eq subtype (instance-of other-role))
+ (not (find (player other-role) current-checked-topics)))
+ (let ((new-values
+ (list-subtypes (player other-role) topictype topictype-constraint current-checked-topics current-valid-subtypes)))
+ (dolist (item (getf new-values :subtypes))
+ (pushnew item current-valid-subtypes))
+ (dolist (item (getf new-values :checked-topics))
+ (pushnew item current-checked-topics))))))
+ (list :subtypes current-valid-subtypes :checked-topics current-checked-topics))))
+
+
+(defun list-instances (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*))
+ (topictype-constraint (get-item-by-psi *topictype-constraint-psi*)))
+ "Returns the topic-instance, all subtypes found by the function lis-subtypes and all direct
+ instances for the found subtypes."
+ (let ((all-subtypes-of-this
+ (getf (list-subtypes topic-instance topictype topictype-constraint) :subtypes))
+ (type (get-item-by-psi *type-psi*))
+ (instance (get-item-by-psi *instance-psi*))
+ (type-instance (get-item-by-psi *type-instance-psi*)))
+ (let ((all-instances-of-this
+ (remove-duplicates
+ (loop for subtype-of-this in all-subtypes-of-this
+ append (loop for role in (player-in-roles subtype-of-this)
+ when (and (eq type (instance-of role))
+ (eq type-instance (instance-of (parent role))))
+ append (loop for other-role in (roles (parent role))
+ when (eq instance (instance-of other-role))
+ collect (player other-role)))))))
+ (let ((all-subtypes-of-all-instances
+ (remove-if #'null
+ (remove-duplicates
+ (loop for subtype in all-instances-of-this
+ append (getf (list-subtypes subtype nil nil) :subtypes))))))
+ (remove-if #'null
+ (map 'list #'(lambda(x)
+ (handler-case (progn
+ (topictype-of-p x nil)
+ x)
+ (condition () nil)))
+ all-subtypes-of-all-instances))))))
+
+
+(defun topics-to-json-list (topics)
+ "Returns a json list of psi-lists."
+ (json:encode-json-to-string
+ (map 'list #'(lambda(topic)
+ (map 'list #'uri (psis topic)))
+ topics)))
\ No newline at end of file
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 May 5 12:28:18 2009
@@ -14,7 +14,7 @@
(defparameter *json-get-all-psis* "/json/psis/?$") ;the url to get all topic psis of isidorus -> localhost:8000/json/psis
(defparameter *json-get-summary-url* "/json/summary/?$") ;the url to get a summary od all topic stored in isidorus; you have to set the GET-parameter "start" for the start index of all topics within elephant and the GET-paramter "end" for the last index of the topic sequence -> http://localhost:8000/json/summary/?start=12&end=13
(defparameter *json-get-all-type-psis* "/json/tmcl/types/?$") ;returns a list of all psis that can be a type
-(defparameter *json-get-topic-stub-prefix* "/json/tmcl/topicstubs/(.+)$") ;the json prefix for getting some topic stub information of a topic and its "derived" topics
+(defparameter *json-get-topic-stub-prefix* "/json/topicstubs/(.+)$") ;the json prefix for getting some topic stub information of a topic
(defparameter *json-get-type-tmcl-prefix* "/json/tmcl/type/(.+)$") ;the json prefix for getting some tmcl information of a topic treated as a type
(defparameter *json-get-instance-tmcl-prefix* "/json/tmcl/instance/(.+)$") ;the json prefix for getting some tmcl information of a topic treated as an instance
(defparameter *ajax-user-interface-url* "/isidorus/?$") ;the url to the user interface; if you want to get all topics set start=0&end=nil -> localhost:8000/isidorus
1
0

[isidorus-cvs] r28 - in trunk: docs src src/ajax/javascripts src/json src/model src/rest_interface src/unit_tests
by Lukas Giessmann 04 May '09
by Lukas Giessmann 04 May '09
04 May '09
Author: lgiessmann
Date: Mon May 4 11:02:44 2009
New Revision: 28
Log:
added the tmcl-json-model to the json-model; added a rest-api for the json-tmcl part, so it is possible to get all tmcl-standard-constraints for a topic as a json-string; added the topicmap example "poems.xtm" with tmcl-constraints to the unit_tests folder.
Added:
trunk/src/json/json_tmcl.lisp
trunk/src/json/json_tmcl_constants.lisp
trunk/src/unit_tests/poems.xtm
Modified:
trunk/docs/xtm_json.txt
trunk/src/ajax/javascripts/make_fragment_node.js
trunk/src/constants.lisp
trunk/src/isidorus.asd
trunk/src/model/changes.lisp
trunk/src/rest_interface/rest-interface.lisp
trunk/src/rest_interface/set-up-json-interface.lisp
Modified: trunk/docs/xtm_json.txt
==============================================================================
--- trunk/docs/xtm_json.txt (original)
+++ trunk/docs/xtm_json.txt Mon May 4 11:02:44 2009
@@ -2,6 +2,7 @@
//+ Overview:
//+ *Part 1: XTM - data model
//+ *Part 2: Object summaries
+//+ *Part 3: TMCL - data model
//+-----------------------------------------------------------------------------
@@ -158,7 +159,7 @@
//+-----------------------------------------------------------------------------
//+ topicSummary
-//+ contains the topic id,subjetcIdentifiers, itemIdentities,
+//+ Contains the topic id,subjetcIdentifiers, itemIdentities,
//+ subjectLocators, nameSummaries and occurrenceSummaries
//+-----------------------------------------------------------------------------
{
@@ -173,229 +174,228 @@
+//+-----------------------------------------------------------------------------
+//+ Part 3: TMCL - data model
+//+ This part explains how the tmcl-rules/suggestions of isidorus are
+//+ sent via HTTP as JSON-data.
+//+-----------------------------------------------------------------------------
+
+
+//+-----------------------------------------------------------------------------
+//+ exclusiveInstances
+//+ This message constains a list of topics represented as a list of topic
+//+ psis which are exclusive instances for the owner.
+//+-----------------------------------------------------------------------------
+[ [ "topic-1-psi-1", "topic-2-psi-2", "..." ], [ "topic-2-psi", "..." ], <...> ]
+
+
+//+-----------------------------------------------------------------------------
+//+ simpleConstraint
+//+ This object contains a regexp member with the regular expression of the
+//+ constraint, a cardMin member with the minimum cardinality of
+//+ the referenced element which is represented as an unsignedInt
+//+ and a cardMax member which describes the maximum cardinality of this
+//+ element, this member contains an unsigendInt or the string
+//+ "MAX_INT".
+//+-----------------------------------------------------------------------------
+{
+ "regexp" : "regular expression",
+ "cardMin" : "unsigned integer in string representation",
+ "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+}
+
+
+//+-----------------------------------------------------------------------------
+//+ subjectIdentifierConstraint
+//+ This object contains a regexp member with the regular expression of the
+//+ subjectIdentifier, a cardMin member with the minimum cardinality of
+//+ this subjectIdentifier in a topic which is represented as an unsignedInt
+//+ and a cardMax member which describes the maximum cardinality of this
+//+ subjectIdentifier, this member contains an unsigendInt or the string
+//+ "MAX_INT".
+//+-----------------------------------------------------------------------------
+<simpleConstraint>
+
+
+//+-----------------------------------------------------------------------------
+//+ subjectLocatorConstraint
+//+ This object contains a regexp member with the regular expression of the
+//+ subjectLocator, a cardMin member with the minimum cardinality of
+//+ this subjectLocator in a topic which is represented as an unsignedInt
+//+ and a cardMax member which describes the maximum cardinality of this
+//+ subjectLocator, this member contains an unsigendInt or the string
+//+ "MAX_INT".
+//+-----------------------------------------------------------------------------
+<simepleConstraint>
+
+
+//+-----------------------------------------------------------------------------
+//+ scopeConstraint
+//+ The scopeConstraint-Object contains a list of all available scopes of
+//+ for an association/name/occurrence element - this depends where this
+//+ json-onbject is contained.
+//+ The member availableScopeTypes contains a list of topics in psi-list
+//+ representation which can be used as scope.
+//+ cardMin defines the minimum number of all scopes of the parent element
+//+ (association/name/occurrence).
+//+ cardMax defines the maximum number of all scopes of the parent element.
+//+-----------------------------------------------------------------------------
+{
+ "scopeTypes" : [ [ "topic-1-psi-1", "topic-1-psi-2", "..." ], [ "topic-2-psi-1", "..." ] <...> ],
+ "cardMin" : "unsigned integer in string representation",
+ "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+}
+
+
+//+-----------------------------------------------------------------------------
+//+ topicNameConstraint
+//+ The topicNameConstraint describes how the topic's names have to be
+//+ defined.
+//+ The nameType is a topic representation in form of a list of psis of the
+//+ topic representing the name's type.
+//+ regexp defines the content of the name.
+//+ cardMin defines the minimum number of names a topic must have.
+//+ cardMax defines the maximum number of names a topic must have.
+//+ nameTypeScopes describes how many scopes there must exist and of what
+//+ type the scopes have to be .
+//+-----------------------------------------------------------------------------
+{
+ "nameType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+ "constraints" : [ <simpleConstraint>, < ... > ],
+ "scopeConstraints" : { <scopeConstraint> }
+}
+//+-----------------------------------------------------------------------------
+//+ uniqueOccurrenceConstraint
+//+ This object owns a regexp member with the regular expression of the
+//+ occurrence which should be unique. So only occurrences that match the
+//+ occurrenceType and the regexp will be checked.
+//+ occurrenceType represents the topictype of the occurrence.
+//+ cardMin describes the minimum number of all matched occurrences within
+//+ all instances of this topictype's instances.
+//+ cardMax describes the maximum number of all matched occurrences within
+//+ all instances of this topictype's instances.
+//+-----------------------------------------------------------------------------
+<simpleConstraint>
+//+-----------------------------------------------------------------------------
+//+ topicOccurrenceConstraint
+//+ The topicOccurrenceConstraint describes how the topic's occurrences have
+//+ to be defined.
+//+
+//+-----------------------------------------------------------------------------
+{
+ "occurrenceType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+ "constraints" : [ <simpleConstraint>, < ... > ],
+ "scopeConstraints" : { <scopeConstraint> },
+ "dataConstraint" : "datatype",
+ "uniqueConstraints" : [ <uniqueOccurrenceConstraint>, <...> ]
+}
+//+-----------------------------------------------------------------------------
+//+ associationRoleConstraint
+//+ This object defines a list of psis of the roletype topic of which
+//+ the role is an instance of.
+//+ cardMin and cardMax defines the number of roles with the defined roletype
+//+ in an association of a certain associationtype (the objects owner).
+//+-----------------------------------------------------------------------------
+{
+ "roleType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+ "cardMin" : "unsigned integer in string representation",
+ "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+}
+//+-----------------------------------------------------------------------------
+//+ rolePlayerConstraint
+//+ Defines the player of a certain role with a given type in an association
+//+ with a given type.
+//+ playerType is the psi-list representation of the player-topic.
+//+ roleType is the is a list of topic-psis representing a topic which can
+//+ be a player in the given role.
+//+ cardMin and cardMax defines the number of times the topicType (= player)
+//+ can be the player in a role of a given type (= roleTypes) in an
+//+ association of a given type (= objects owner).
+//+-----------------------------------------------------------------------------
+{
+ "playerType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+ "roleType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+ "cardMin" : "unsigned integer in string representation",
+ "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+}
+//+-----------------------------------------------------------------------------
+//+ otherRoleConstraint
+//+ This JSON-Object defines the number and types of (other-) roles in an
+//+ association of a given type with a role of a give type.
+//+ roleType is a allowed role with the player topicType.
+//+ otherRoleType is the second role with the player otherTopicType.
+//+ 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", "..." ],
+ "cardMin" : "unsigned integer in string representation",
+ "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+}
+//+-----------------------------------------------------------------------------
+//+ associationConstraint
+//+ The associationConstraint describes how an association of a given type
+//+ has to be defined.
+//+ associationRoleTypeConstraint constains all available roletypes for this
+//+ association.
+//+ rolePlayerConstraint constains all players for certain roles of a given
+//+ type.
+//+ associationTypeScopes contains all available scopes for this association.
+//+-----------------------------------------------------------------------------
+{
+ "associationRoleConstraints" : [ <associationRoleConstraint>, <...> ],
+ "rolePlayerConstraints" : [ <rolePlayerConstraints>, <...> ],
+ "otherRoleConstraints" : [ <otherRoleConstraint>, <...> ],
+ "scopeConstraints" : { <scopeConstraint> }
+}
+//+-----------------------------------------------------------------------------
+//+ topicConstraint
+//+ The topicConstraint contains the members:
+//+ *subjectIdentifierConstraints which defines the subjectIdentifiers
+//+ *subjectLocatorConstraints which defines the subjectLocators
+//+ *topicNameConstraints which defines the topic names
+//+ *topicOccurrenceConstraints which defines the topic occurrences
+//+ *uniqueOccurrenceConstraints which defines the uniqueness of topic
+//+ occurrences
+//+-----------------------------------------------------------------------------
+{
+ "exclusiveInstances" : <exclusiveInstances>,
+ "subjectIdentifierConstraints" : [ <subjectIdentifierConstraint>, <...> ],
+ "subjectLocatorConstraints" : [ <subjectLocatorConstraint>, <...> ],
+ "topicNameConstraints" : [ <topoicNameConstriant>, <...> ],
+ "topicOccurrenceConstraints" : [ <topicOccurrenceConstraint>, <...> ],
+ "abstractConstraint" : <boolean>
+}
+
+
+//+-----------------------------------------------------------------------------
+//+ fragmentConstraint
+//+ This JSON-Object contains all constraints necessary for an entire
+//+ fragment but not the exclusive-instance-constraint.
+//+ The exclusive-instance-constraint should be sent before a
+//+ fragmentConstraint separately.
+//+ topicConstraint contains an object with all constraints of all baseTypes
+//+ of the mainTopic.
+//+ associationConstraints contains a list of all association constraints
+//+ depending on all baseTypes of the main topic.
+//+-----------------------------------------------------------------------------
{
- "topic" : {
- "id" : "t403",
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100" ],
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/standard/ISO+19115%3A+Geographic+Information+-+Metadata" ],
- "instanceOfs" : [ [ "http : //psi.egovpt.org/types/semanticstandard" ] ],
- "names" : [ {
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_n1" ],
- "type" : null,
- "scopes" : null,
- "value" : "ISO 19115",
- "variants" : [ {
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_n1_v1" ],
- "scopes" : [ [ "http : //www.topicmaps.org/xtm/1.0/core.xtm#display" ] ],
- "resourceRef" : null,
- "resourceData" : {
- "datatype" : "http : //www.w3.org/2001/XMLSchema#string",
- "value" : "Geographic Information - Metadata"
- }
- },
- {
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_n1_v2" ],
- "scopes" : [ [ "http : //www.topicmaps.org/xtm/1.0/core.xtm#sort" ] ],
- "resourceRef" : null,
- "resourceData" : {
- "datatype" : "http : //www.w3.org/2001/XMLSchema#string",
- "value" : "ISO-19115"
- }
- }
- ]
- }
- ],
- "occurrences" : [ {
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_o1" ],
- "type" : [ "http : //psi.egovpt.org/types/standardHasStatus" ],
- "scopes" : null,
- "resourceRef" : "http : //www.budabe.de/","resourceData" : null
- },
- {
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_o2" ],
- "type" : [ "http : //psi.egovpt.org/types/description" ],
- "scopes" : null,
- "resourceRef" : null,
- "resourceData" : {
- "datatype" : "http : //www.w3.org/2001/XMLSchema#string",
- "value" : "The ISO 19115 standard ..."
- }
- },
- {
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_o3" ],
- "type" : [ "http : //psi.egovpt.org/types/standardValidFromDate" ],
- "scopes" : null,
- "resourceRef" : null,
- "resourceData" : {
- "datatype" : "http : //www.w3.org/2001/XMLSchema#date",
- "value" : "2003-01-01"
- }
- },
- {
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_o4" ],
- "type" : [ "http : //psi.egovpt.org/types/links" ],
- "scopes" : null,
- "resourceRef" : "http : //www.editeur.org/standards/ISO19115.pdf",
- "resourceData" : null
- }
- ]
- },
- "topicStubs" : [ {
- "id" : "t227",
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t3a" ],
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/semanticstandard" ]
- },
- {
- "id" : "t73",
- "itemIdentities" : null,
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //www.topicmaps.org/xtm/1.0/core.xtm#display" ]
- },
- {
- "id" : "t67",
- "itemIdentities" : null,
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //www.topicmaps.org/xtm/1.0/core.xtm#sort" ]
- },
- {
- "id" : "t291",
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t51" ],
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/standardHasStatus" ]
- },
- {
- "id" : "t307",
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t53" ],
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/description" ]
- },
- {
- "id" : "t315",
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t54" ],
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/standardValidFromDate" ]
- },
- {
- "id" : "t323",
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t55" ],
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/links" ]
- },
- {
- "id" : "t433",
- "itemIdentities" : null,
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/subject/GeoData" ]
- },
- {
- "id" : "t363",
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t60" ],
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/standardIsAboutSubject" ]
- },
- {
- "id" : "t371",
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t61" ],
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/SubjectRoleType" ]
- },
- {
- "id" : "t421",
- "itemIdentities" : null,
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/subject/Semantic+Description" ]
- },
- {
- "id" : "t395",
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t64" ],
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/serviceUsesStandard" ]
- },
- {
- "id" : "t387",
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t63" ],
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/ServiceRoleType" ]
- },
- {
- "id" : "t451",
- "itemIdentities" : null,
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/service/Google+Maps",
- "http : //maps.google.com" ]
- },
- {
- "id" : "t379",
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t62" ],
- "subjectLocators" : null,
- "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/StandardRoleType" ]
- }
- ],
- "associations" : [ {
- "itemIdentities" : null,
- "type" : [ "http : //psi.egovpt.org/types/standardIsAboutSubject" ],
- "scopes" : null,
- "roles" : [ {
- "itemIdentities" : null,
- "type" : [ "http : //psi.egovpt.org/types/StandardRoleType" ],
- "topicRef" : [ "http : //psi.egovpt.org/standard/ISO+19115%3A+Geographic+Information+-+Metadata" ]
- },
- {
- "itemIdentities" : null,
- "type" : [ "http : //psi.egovpt.org/types/SubjectRoleType" ],
- "topicRef" : [ "http : //psi.egovpt.org/subject/GeoData" ]
- }
- ]
- },
- {
- "itemIdentities" : null,
- "type" : [ "http : //psi.egovpt.org/types/standardIsAboutSubject" ],
- "scopes" : null,
- "roles" : [ {
- "itemIdentities" : null,
- "type" : [ "http : //psi.egovpt.org/types/StandardRoleType" ],
- "topicRef" : [ "http : //psi.egovpt.org/standard/ISO+19115%3A+Geographic+Information+-+Metadata" ]
- },
- {
- "itemIdentities" : null,
- "type" : [ "http : //psi.egovpt.org/types/SubjectRoleType" ],
- "topicRef" : [ "http : //psi.egovpt.org/subject/Semantic+Description" ]
- }
- ]
- },
- {
- "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#assoc_7" ],
- "type" : [ "http : //psi.egovpt.org/types/serviceUsesStandard" ],
- "scopes" : null,
- "roles" : [ {
- "itemIdentities" : null,
- "type" : [ "http : //psi.egovpt.org/types/ServiceRoleType" ],
- "topicRef" : [ "http : //psi.egovpt.org/service/Google+Maps",
- "http : //maps.google.com" ]
- },
- {
- "itemIdentities" : null,
- "type" : [ "http : //psi.egovpt.org/types/StandardRoleType" ],
- "topicRef" : [ "http : //psi.egovpt.org/standard/ISO+19115%3A+Geographic+Information+-+Metadata" ]
- }
- ]
- }
- ],
- "tmIds" : [ "test-tm"]
+ "topicConstraints" : <topicConstraint>,
+ "associationsConstraints" : [ <associationConstraint>, <...> ]
}
Modified: trunk/src/ajax/javascripts/make_fragment_node.js
==============================================================================
--- trunk/src/ajax/javascripts/make_fragment_node.js (original)
+++ trunk/src/ajax/javascripts/make_fragment_node.js Mon May 4 11:02:44 2009
@@ -1296,7 +1296,7 @@
// --- the ajax-request error handler
function onFailureHandler(xhr)
{
- window.alert("Something went wrong ...\n" + xhr.status + ": " + xhr.statusText);
+
}
// --- the real ajax request
@@ -1305,6 +1305,6 @@
var request = new Ajax.Request(requestUrl,
{"method" : "get",
"onSuccess" : onSuccessHandler,
- "onFailure" : onFailureHandler
+ "onFailure" : function(xhr){ window.alert("Something went wrong ...\n" + xhr.status + ": " + xhr.statusText + "\n" + xhr.responseText); }
});
}
\ No newline at end of file
Modified: trunk/src/constants.lisp
==============================================================================
--- trunk/src/constants.lisp (original)
+++ trunk/src/constants.lisp Mon May 4 11:02:44 2009
@@ -15,6 +15,9 @@
:*isidorus-system*
:*type-instance-psi*
:*type-psi*
+ :*supertype-subtype-psi*
+ :*supertype-psi*
+ :*subtype-psi*
:*xtm2.0-ns*
:*xtm1.0-ns*
:*xtm1.0-xlink*))
@@ -36,4 +39,10 @@
(defparameter *instance-psi* "http://psi.topicmaps.org/iso13250/model/instance")
+(defparameter *supertype-subtype-psi* "http://psi.topicmaps.org/iso13250/model/supertype-subtype")
+
+(defparameter *supertype-psi* "http://psi.topicmaps.org/iso13250/model/supertype")
+
+(defparameter *subtype-psi* "http://psi.topicmaps.org/iso13250/model/subtype")
+
(defparameter *isidorus-system* (asdf:find-system "isidorus"))
Modified: trunk/src/isidorus.asd
==============================================================================
--- trunk/src/isidorus.asd (original)
+++ trunk/src/isidorus.asd Mon May 4 11:02:44 2009
@@ -127,7 +127,10 @@
"json"))
(:module "json"
:components ((:file "json_exporter")
- (:file "json_importer"))
+ (:file "json_importer")
+ (:file "json_tmcl_constants")
+ (:file "json_tmcl"
+ :depends-on ("json_tmcl_constants" "json_exporter")))
:depends-on ("model" "xml"))
(:module "ajax"
:components ((:static-file "isidorus.html")
Added: trunk/src/json/json_tmcl.lisp
==============================================================================
--- (empty file)
+++ trunk/src/json/json_tmcl.lisp Mon May 4 11:02:44 2009
@@ -0,0 +1,1201 @@
+;;+-----------------------------------------------------------------------------
+;;+ Isidorus
+;;+ (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
+;;+
+;;+ Isidorus is freely distributable under the LGPL license.
+;;+ You can find a detailed description in trunk/docs/LGPL-LICENSE.txt.
+;;+-----------------------------------------------------------------------------
+
+
+(defpackage :json-tmcl
+ (:use :cl :datamodel :constants :json-tmcl-constants)
+ (:export :get-constraints-of-fragment
+ :topictype-p
+ :abstract-p))
+
+(in-package :json-tmcl)
+
+
+;; -----------------------------------------------------------------------------
+;; --- all fragment constraints ------------------------------------------------
+;; -----------------------------------------------------------------------------
+(defun get-constraints-of-fragment(topic-psi &key (treat-as 'type))
+ (let ((associationtype (get-item-by-psi *associationtype-psi*))
+ (associationtype-constraint (get-item-by-psi *associationtype-constraint-psi*))
+ (topic
+ (let ((psi
+ (elephant:get-instance-by-value 'PersistentIdC 'uri topic-psi)))
+ (when psi
+ (identified-construct psi)))))
+ (when topic
+ (let ((topic-constraints
+ (let ((value
+ (get-constraints-of-topic topic :treat-as treat-as)))
+ (concatenate 'string "\"topicConstraints\":" value))))
+ (let ((available-associations ;what's with association which have only a associationrole-constraint?
+ (get-available-associations-of-topic topic :treat-as treat-as)))
+ (dolist (item available-associations)
+ (topictype-p item associationtype associationtype-constraint))
+ (let ((associations-constraints
+ (concatenate 'string "\"associationsConstraints\":"
+ (let ((inner-associations-constraints "["))
+ (loop for available-association in available-associations
+ do (let ((value
+ (get-constraints-of-association available-association)))
+ (setf inner-associations-constraints
+ (concatenate 'string inner-associations-constraints value ","))))
+ (if (string= inner-associations-constraints "[")
+ (setf inner-associations-constraints "null")
+ (setf inner-associations-constraints
+ (concatenate 'string (subseq inner-associations-constraints 0 (- (length inner-associations-constraints) 1)) "]")))))))
+ (let ((json-string
+ (concatenate 'string
+ "{" topic-constraints "," associations-constraints "}")))
+ json-string)))))))
+
+
+;; -----------------------------------------------------------------------------
+;; --- all association constraints ---------------------------------------------
+;; -----------------------------------------------------------------------------
+(defun get-constraints-of-association (associationtype-topic)
+ "Returns a list of constraints which are describing associations of the
+ passed associationtype-topic."
+ (let ((constraint-topics
+ (get-all-constraint-topics-of-association associationtype-topic)))
+ (let ((associationtypescope-constraints
+ (let ((value (get-typescope-constraints associationtype-topic :what 'association)))
+ (concatenate 'string "\"scopeConstraints\":" value)))
+ (associationrole-constraints
+ (let ((value
+ (get-associationrole-constraints (getf constraint-topics :associationrole-constraints))))
+ (concatenate 'string "\"associationRoleConstraints\":" value)))
+ (roleplayer-constraints
+ (let ((value
+ (get-roleplayer-constraints (getf constraint-topics :roleplayer-constraints))))
+ (concatenate 'string "\"rolePlayerConstraints\":" value)))
+ (otherrole-constraints
+ (let ((value
+ (get-otherrole-constraints (getf constraint-topics :otherrole-constraints))))
+ (concatenate 'string "\"otherRoleConstraints\":" value))))
+ (let ((json-string
+ (concatenate 'string "{" associationrole-constraints "," roleplayer-constraints ","
+ otherrole-constraints "," associationtypescope-constraints "}")))
+ json-string))))
+
+
+(defun get-otherrole-constraints (constraint-topics)
+ "Returns a list of the form
+ ((::role <topic> :player <topic> :otherrole <topic> :othertopic <topic> :card-min <string> :card-max <string>) <...>)
+ which describes an otherrole constraint for the parent-association of a give type."
+ (let ((applies-to (get-item-by-psi *applies-to-psi*))
+ (constraint-role (get-item-by-psi *constraint-role-psi*))
+ (topictype-role (get-item-by-psi *topictype-role-psi*))
+ (roletype-role (get-item-by-psi *roletype-role-psi*))
+ (othertopictype-role (get-item-by-psi *othertopictype-role-psi*))
+ (otherroletype-role (get-item-by-psi *otherroletype-role-psi*))
+ (roletype (get-item-by-psi *roletype-psi*))
+ (roletype-constraint (get-item-by-psi *roletype-constraint-psi*)))
+ (let ((otherrole-constraints
+ (loop for constraint-topic in constraint-topics
+ append (let ((players nil)
+ (roletypes nil)
+ (otherplayers nil)
+ (otherroletypes nil)
+ (constraint-list
+ (get-constraint-topic-values constraint-topic)))
+ (loop for role in (player-in-roles constraint-topic)
+ when (and (eq constraint-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ do (loop for other-role in (roles (parent role))
+ do (let ((current-player (player other-role))
+ (current-role (instance-of other-role)))
+ (cond
+ ((eq topictype-role current-role)
+ (push current-player players))
+ ((eq roletype-role current-role)
+ (push current-player roletypes))
+ ((eq othertopictype-role current-role)
+ (push current-player otherplayers))
+ ((eq otherroletype-role current-role)
+ (push current-player otherroletypes))))))
+ (when (and (append players roletypes otherplayers otherroletypes)
+ (or (not players) (not roletypes) (not otherplayers) (not otherroletypes)))
+ (error "otherroletype-constraint ~a is not complete:~%players: ~a~%roletypes: ~a~%otherplayers: ~a~%otherroletypes: ~a~%"
+ (uri (first (psis constraint-topic)))
+ (map 'list #'(lambda(x)(uri (first (psis x)))) players)
+ (map 'list #'(lambda(x)(uri (first (psis x)))) roletypes)
+ (map 'list #'(lambda(x)(uri (first (psis x)))) otherplayers)
+ (map 'list #'(lambda(x)(uri (first (psis x)))) otherroletypes)))
+ (let ((cross-product-1
+ (loop for player in players
+ append (loop for roletype in roletypes
+ collect (list :player player :role roletype))))
+ (cross-product-2
+ (loop for otherplayer in otherplayers
+ append (loop for otherroletype in otherroletypes
+ collect (list :otherplayer otherplayer :otherrole otherroletype)))))
+ (let ((cross-product
+ (loop for tupple-1 in cross-product-1
+ append (loop for tupple-2 in cross-product-2
+ collect (append tupple-1 tupple-2 (list :constraint constraint-list))))))
+ cross-product))))))
+ (let ((involved-topic-tupples
+ (remove-duplicates
+ (loop for otherrole-constraint in otherrole-constraints
+ collect (let ((player (getf otherrole-constraint :player))
+ (role-type (getf otherrole-constraint :role))
+ (otherplayer (getf otherrole-constraint :otherplayer))
+ (otherrole-type (getf otherrole-constraint :otherrole)))
+ (topictype-p player)
+ (topictype-p role-type roletype roletype-constraint)
+ (topictype-p otherplayer)
+ (topictype-p otherrole-type roletype roletype-constraint)
+ (list :player player
+ :role role-type
+ :otherplayer otherplayer
+ :otherrole otherrole-type)))
+ :test #'(lambda(x y)
+ (and (eq (getf x :player) (getf y :player))
+ (eq (getf x :role) (getf y :role))
+ (eq (getf x :otherplayer) (getf y :otherplayer))
+ (eq (getf x :otherrole) (getf y :otherrole)))))))
+ (let ((cleaned-otherrole-constraints "["))
+ (loop for involved-topic-tupple in involved-topic-tupples
+ do (let ((constraint-lists
+ (remove-duplicate-constraints
+ (loop for otherrole-constraint in otherrole-constraints
+ when (and (eq (getf otherrole-constraint :player) (getf involved-topic-tupple :player))
+ (eq (getf otherrole-constraint :role) (getf involved-topic-tupple :role))
+ (eq (getf otherrole-constraint :otherplayer) (getf involved-topic-tupple :otherplayer))
+ (eq (getf otherrole-constraint :otherrole) (getf involved-topic-tupple :otherrole)))
+ collect (getf otherrole-constraint :constraint)))))
+ (when (> (length constraint-lists) 1)
+ (error "found contrary otherrole-constraints:~%player: ~a~%role: ~a~%otherplayer: ~a~%otherrole: ~a~% ~a~%"
+ (uri (first (psis (getf involved-topic-tupple :player))))
+ (uri (first (psis (getf involved-topic-tupple :role))))
+ (uri (first (psis (getf involved-topic-tupple :otherplayer))))
+ (uri (first (psis (getf involved-topic-tupple :otherrole))))
+ constraint-lists))
+ (let ((json-player
+ (concatenate 'string "\"playerType\":"
+ (json-exporter::identifiers-to-json-string (getf involved-topic-tupple :player))))
+ (json-role
+ (concatenate 'string "\"roleType\":"
+ (json-exporter::identifiers-to-json-string (getf involved-topic-tupple :role))))
+ (json-otherplayer
+ (concatenate 'string "\"otherPlayerType\":"
+ (json-exporter::identifiers-to-json-string (getf involved-topic-tupple :player))))
+ (json-otherrole
+ (concatenate 'string "\"otherRoleType\":"
+ (json-exporter::identifiers-to-json-string (getf involved-topic-tupple :role))))
+ (card-min
+ (concatenate 'string "\"cardMin\":" (getf (first constraint-lists) :card-min)))
+ (card-max
+ (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 "},")))))
+ (if (string= cleaned-otherrole-constraints "[")
+ (setf cleaned-otherrole-constraints "null")
+ (setf cleaned-otherrole-constraints
+ (concatenate 'string (subseq cleaned-otherrole-constraints 0 (- (length cleaned-otherrole-constraints) 1)) "]")))
+ cleaned-otherrole-constraints)))))
+
+
+(defun get-roleplayer-constraints (constraint-topics)
+ "Returns a list of the form
+ ((:role <topic> :player <topic> :card-min <string> :card-max <string>) <...>)
+ which describes the cardinality of topctypes used as players in roles of given
+ types in an association of a given type which is also the parent if this list."
+ (let ((applies-to (get-item-by-psi *applies-to-psi*))
+ (constraint-role (get-item-by-psi *constraint-role-psi*))
+ (topictype-role (get-item-by-psI *topictype-role-psi*))
+ (roletype-role (get-item-by-psi *roletype-role-psi*))
+ (roletype (get-item-by-psi *roletype-psi*))
+ (roletype-constraint (get-item-by-psi *roletype-constraint-psi*)))
+ (let ((roleplayer-constraints
+ (loop for constraint-topic in constraint-topics
+ append (let ((constraint-list
+ (get-constraint-topic-values constraint-topic)))
+ (let ((players
+ (loop for role in (player-in-roles constraint-topic)
+ when (and (eq constraint-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ append (loop for other-role in (roles (parent role))
+ when (eq topictype-role (instance-of other-role))
+ collect (player other-role))))
+ (roles
+ (loop for role in (player-in-roles constraint-topic)
+ when (and (eq constraint-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ append (loop for other-role in (roles (parent role))
+ when (eq roletype-role (instance-of other-role))
+ collect (player other-role)))))
+ (when (or (and players (not roles))
+ (and roles (not players)))
+ (error "roleplayer-constraint ~a is not complete:~%players: ~a~%roles: ~a~%"
+ (uri (first (psis constraint-topic)))
+ (map 'list #'(lambda(x)(uri (first (psis x)))) players)
+ (map 'list #'(lambda(x)(uri (first (psis x)))) roles)))
+ (let ((cross-product
+ (loop for player in players
+ append (loop for role in roles
+ collect (list :player player :role role :constraint constraint-list)))))
+ cross-product))))))
+
+ (let ((role-player-tupples
+ (remove-duplicates
+ (loop for roleplayer-constraint in roleplayer-constraints
+ collect (let ((current-player (getf roleplayer-constraint :player))
+ (current-role (getf roleplayer-constraint :role)))
+ (topictype-p current-player)
+ (topictype-p current-role roletype roletype-constraint)
+ (list :player current-player
+ :role current-role)))
+ :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
+ (remove-duplicate-constraints
+ (loop for roleplayer-constraint in roleplayer-constraints
+ when (and (eq (getf roleplayer-constraint :player) (getf role-player-tupple :player))
+ (eq (getf roleplayer-constraint :role) (getf role-player-tupple :role)))
+ collect (getf roleplayer-constraint :constraint)))))
+ (when (> (length constraint-lists) 1)
+ (error "found contrary roleplayer-constraints:~%role: ~a~%player: ~a~% ~a ~%"
+ (uri (first (psis (getf role-player-tupple :role))))
+ (uri (first (psis (getf role-player-tupple :player))))
+ constraint-lists))
+ (let ((json-player
+ (concatenate 'string "\"playerType\":"
+ (json-exporter::identifiers-to-json-string (getf role-player-tupple :player))))
+ (json-role
+ (concatenate 'string "\"roleType\":"
+ (json-exporter::identifiers-to-json-string (getf role-player-tupple :role))))
+ (card-min
+ (concatenate 'string "\"cardMin\":" (getf (first constraint-lists) :card-min)))
+ (card-max
+ (concatenate 'string "\"cardMax\":" (getf (first constraint-lists) :card-max))))
+ (setf cleaned-roleplayer-constraints
+ (concatenate 'string cleaned-roleplayer-constraints
+ "{" json-player "," json-role "," card-min "," card-max "},")))))
+ (if (string= cleaned-roleplayer-constraints "[")
+ (setf cleaned-roleplayer-constraints "null")
+ (setf cleaned-roleplayer-constraints
+ (concatenate 'string (subseq cleaned-roleplayer-constraints 0 (- (length cleaned-roleplayer-constraints) 1)) "]")))
+ cleaned-roleplayer-constraints)))))
+
+
+(defun get-associationrole-constraints (constraint-topics)
+ "Returns a list of the form
+ ((:associationroletype <topic> :card-min <string> :card-max <string>), <...>)
+ which describes all associationrole-constraints of the passed
+ constraint-topics."
+ (let ((applies-to (get-item-by-psi *applies-to-psi*))
+ (roletype-role (get-item-by-psi *roletype-role-psi*))
+ (constraint-role (get-item-by-psi *constraint-role-psi*))
+ (roletype (get-item-by-psi *roletype-psi*))
+ (roletype-constraint (get-item-by-psi *roletype-constraint-psi*)))
+ (let ((associationrole-constraints
+ (loop for constraint-topic in constraint-topics
+ append (let ((constraint-list
+ (get-constraint-topic-values constraint-topic)))
+ (loop for role in (player-in-roles constraint-topic)
+ when (and (eq constraint-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ append (loop for other-role in (roles (parent role))
+ when (eq roletype-role (instance-of other-role))
+ collect (list :associationroletype (player other-role)
+ :constraint constraint-list)))))))
+ (let ((associationroletype-topics
+ (remove-duplicates (map 'list #'(lambda(x)
+ (let ((associationroletype (getf x :associationroletype)))
+ (topictype-p associationroletype roletype roletype-constraint)
+ associationroletype))
+ associationrole-constraints))))
+ (let ((cleaned-associationrole-constraints "["))
+ (loop for associationroletype-topic in associationroletype-topics
+ do (let ((constraint-lists
+ (remove-duplicate-constraints
+ (loop for associationrole-constraint in associationrole-constraints
+ when (eq associationroletype-topic (getf associationrole-constraint :associationroletype))
+ collect (getf associationrole-constraint :constraint)))))
+ (when (> (length constraint-lists) 1)
+ (error "found contrary associationrole-constraints: ~a ~a~%" (uri (first (psis associationroletype-topic))) constraint-lists))
+ (setf cleaned-associationrole-constraints
+ (concatenate 'string
+ cleaned-associationrole-constraints
+ "{\"roleType\":" (json-exporter::identifiers-to-json-string associationroletype-topic)
+ ",\"cardMin\":" (getf (first constraint-lists) :card-min)
+ ",\"cardMax\":" (getf (first constraint-lists) :card-max) "},"))))
+
+ (if (string= cleaned-associationrole-constraints "[")
+ (setf cleaned-associationrole-constraints "null")
+ (setf cleaned-associationrole-constraints
+ (concatenate 'string (subseq cleaned-associationrole-constraints 0 (- (length cleaned-associationrole-constraints) 1)) "]")))
+ cleaned-associationrole-constraints)))))
+
+
+;; -----------------------------------------------------------------------------
+;; --- all topic constraints ---------------------------------------------------
+;; -----------------------------------------------------------------------------
+(defun get-constraints-of-topic (topic-instance &key(treat-as 'type))
+ "Returns a constraint list with the constraints:
+ subjectidentifier-constraints, subjectlocator-constraints,
+ topicname-constraints, topicoccurrence-constraints and
+ uniqueoccurrence-constraints."
+ (let ((constraint-topics
+ (get-all-constraint-topics-of-topic topic-instance :treat-as treat-as)))
+ (let ((exclusive-instance-constraints
+ (let ((value
+ (get-exclusive-instance-constraints (getf constraint-topics :exclusive-instance-constraints))))
+ (concatenate 'string "\"exclusiveInstances\":" value)))
+ (subjectidentifier-constraints
+ (let ((value
+ (get-simple-constraints (getf constraint-topics :subjectidentifier-constraints) :error-msg-constraint-name "subjectidentifier")))
+ (concatenate 'string "\"subjectIdentifierConstraints\":" value)))
+ (subjectlocator-constraints
+ (let ((value
+ (get-simple-constraints (getf constraint-topics :subjectlocator-constraints) :error-msg-constraint-name "subjectlocator")))
+ (concatenate 'string "\"subjectLocatorConstraints\":" value)))
+ (topicname-constraints
+ (let ((value
+ (get-topicname-constraints (getf constraint-topics :topicname-constraints))))
+ (concatenate 'string "\"topicNameConstraints\":" value)))
+ (topicoccurrence-constraints
+ (let ((value
+ (get-topicoccurrence-constraints (getf constraint-topics :topicoccurrence-constraints)
+ (getf constraint-topics :uniqueoccurrence-constraints))))
+ (concatenate 'string "\"topicOccurrenceConstraints\":" value)))
+ (abstract-constraint
+ (concatenate 'string "\"abstractConstraint\":"
+ (if (getf constraint-topics :abstract-constraint)
+ "true"
+ "false"))))
+ (let ((json-string
+ (concatenate 'string "{" exclusive-instance-constraints "," subjectidentifier-constraints
+ "," subjectlocator-constraints "," topicname-constraints ","
+ topicoccurrence-constraints "," abstract-constraint "}")))
+ json-string))))
+
+
+(defun get-exclusive-instance-constraints(exclusive-instances-lists)
+ "Returns a list of psis which represents some topics."
+ (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+ (applies-to (get-item-by-psi *applies-to-psi*))
+ (topictype-role (get-item-by-psi *topictype-role-psi*)))
+ (let ((topics
+ (remove-duplicates
+ (loop for exclusive-instances-list in exclusive-instances-lists
+ append (let ((owner (getf exclusive-instances-list :owner))
+ (exclusive-constraints (getf exclusive-instances-list :exclusive-constraints)))
+ (loop for exclusive-constraint in exclusive-constraints
+ append (loop for role in (player-in-roles exclusive-constraint)
+ when (and (eq constraint-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ append (loop for other-role in (roles (parent role))
+ when (and (eq topictype-role (instance-of other-role))
+ (not (eq owner (player other-role))))
+ collect (player other-role)))))))))
+ (json:encode-json-to-string (map 'list #'(lambda(y)
+ (map 'list #'uri y))
+ (map 'list #'psis topics))))))
+
+
+(defun get-simple-constraints(constraint-topics &key (error-msg-constraint-name "uniqueoccurrence"))
+ "Returns a list of the form
+ ((:regexp <string> :card-min <string> :card-max <string>))
+ which contains the subjectidentifier, subjectlocator or
+ unique-occurrence constraints. This depends on the passed
+ constraint-topics."
+ (let ((all-values
+ (remove-duplicate-constraints
+ (loop for constraint-topic in constraint-topics
+ collect (get-constraint-topic-values constraint-topic)))))
+ (let ((contrary-constraints (find-contrary-constraints all-values)))
+ (when contrary-constraints
+ (error "found contrary ~a-constraints: ~a~%" error-msg-constraint-name contrary-constraints)))
+ (simple-constraints-to-json all-values)))
+
+
+(defun simple-constraints-to-json(simple-constraints)
+ "Transforms a list of simple constraint lists of the form
+ ((:regexp <string> :card-min <string> :card-max <string>) <...>)
+ to a valid json list of the form
+ [{\"regexp\":\"expr\",\"cardMin\":\"123\",\"cardMax\":\"456\"}, <...>]."
+ (let ((constraints "["))
+ (loop for constraint in simple-constraints
+ do (let ((constraint (concatenate 'string "{\"regexp\":"
+ (json:encode-json-to-string (getf constraint :regexp))
+ ",\"cardMin\":"
+ (json:encode-json-to-string (getf constraint :card-min))
+ ",\"cardMax\":"
+ (json:encode-json-to-string (getf constraint :card-max))
+ "}")))
+ (if (string= constraints "[")
+ (setf constraints (concatenate 'string constraints constraint))
+ (setf constraints (concatenate 'string constraints "," constraint)))))
+ (if (string= constraints "[")
+ (setf constraints "null")
+ (setf constraints (concatenate 'string constraints "]")))
+ constraints))
+
+
+(defun get-topicname-constraints(constraint-topics)
+ "Returns all topicname constraints as a list of the following form:
+ ( ( :type <nametype-topic>
+ :constraints ( ( :regexp <string> :card-min <string> :card-max <string>)
+ <...>)
+ :scopes ( ( :scope <scope-topic> :regexp <string> :card-min <string> :card-max <string>)
+ <...>))
+ <...>)."
+ (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+ (applies-to (get-item-by-psi *applies-to-psi*))
+ (nametype-role (get-item-by-psi *nametype-role-psi*))
+ (nametype (get-item-by-psi *nametype-psi*))
+ (nametype-constraint (get-item-by-psi *nametype-constraint-psi*)))
+ (let ((topicname-constraints
+ (remove-if #'null
+ (loop for constraint-topic in constraint-topics
+ append (loop for role in (player-in-roles constraint-topic)
+ when (and (eq constraint-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ append (loop for other-role in (roles (parent role))
+ when (eq nametype-role (instance-of other-role))
+ collect (let ((nametype-topic (player other-role))
+ (constraint-list (get-constraint-topic-values constraint-topic)))
+ (list :type nametype-topic :constraint constraint-list))))))))
+
+ (let ((nametype-topics
+ (remove-duplicates (map 'list #'(lambda(x)
+ (let ((topicname-type
+ (getf x :type)))
+ (topictype-p topicname-type nametype nametype-constraint)
+ topicname-type))
+ topicname-constraints))))
+ (let ((cleaned-topicname-constraints "["))
+ (loop for nametype-topic in nametype-topics
+ do (let ((constraint-lists
+ (remove-duplicate-constraints
+ (loop for topicname-constraint in topicname-constraints
+ when (eq nametype-topic (getf topicname-constraint :type))
+ collect (getf topicname-constraint :constraint)))))
+ (let ((contrary-constraints
+ (find-contrary-constraints constraint-lists)))
+ (when contrary-constraints
+ (error "found contrary topicname-constraints: ~a~%" contrary-constraints)))
+ (let ((typescope-constraints
+ (let ((current-scopes
+ (get-typescope-constraints nametype-topic :what 'topicname)))
+ (concatenate 'string "\"scopeConstraints\":" current-scopes)))
+ (json-constraint-lists
+ (concatenate 'string "\"constraints\":" (simple-constraints-to-json constraint-lists)))
+ (type-topic
+ (concatenate 'string "\"nameType\":"
+ (json-exporter::identifiers-to-json-string nametype-topic))))
+ (setf cleaned-topicname-constraints
+ (concatenate 'string cleaned-topicname-constraints "{" type-topic "," json-constraint-lists "," typescope-constraints "},")))))
+ (if (string= cleaned-topicname-constraints "[")
+ (setf cleaned-topicname-constraints "null")
+ (setf cleaned-topicname-constraints
+ (concatenate 'string (subseq cleaned-topicname-constraints 0 (- (length cleaned-topicname-constraints) 1)) "]")))
+ cleaned-topicname-constraints)))))
+
+
+(defun get-topicoccurrence-constraints(constraint-topics unique-constraint-topics)
+ "Returns all topicoccurrence constraints as a list of the following form:
+ ( ( :type <occurrencetype-topic>
+ :constraints ( ( :regexp <string> :card-min <string> :card-max <string>)
+ <...>)
+ :scopes ( ( :scope <scope-topic> :regexp <string> :card-min <string> :card-max <string>)
+ <...>)
+ :datatype <string>
+ :uniqe ( ( :regexp <string> :dard-min <string> :card-max <string> ) )
+ <...>)."
+ (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+ (applies-to (get-item-by-psi *applies-to-psi*))
+ (occurrencetype-role (get-item-by-psi *occurrencetype-role-psi*))
+ (occurrencetype (get-item-by-psi *occurrencetype-psi*))
+ (occurrencetype-constraint (get-item-by-psi *occurrencetype-constraint-psi*)))
+ (let ((topicoccurrence-constraints
+ (remove-if #'null
+ (loop for constraint-topic in constraint-topics
+ append (loop for role in (player-in-roles constraint-topic)
+ when (and (eq constraint-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ append (loop for other-role in (roles (parent role))
+ when (eq occurrencetype-role (instance-of other-role))
+ collect (let ((occurrencetype-topic (player other-role))
+ (constraint-list (get-constraint-topic-values constraint-topic)))
+ (list :type occurrencetype-topic :constraint constraint-list))))))))
+ (let ((occurrencetype-topics
+ (remove-duplicates (map 'list #'(lambda(x)
+ (let ((occurrence-type (getf x :type)))
+ (topictype-p occurrence-type occurrencetype occurrencetype-constraint)
+ occurrence-type))
+ topicoccurrence-constraints))))
+ (let ((cleaned-topicoccurrence-constraints "["))
+ (loop for occurrencetype-topic in occurrencetype-topics
+ do (let ((constraint-lists
+ (remove-duplicate-constraints
+ (loop for topicoccurrence-constraint in topicoccurrence-constraints
+ when (eq occurrencetype-topic (getf topicoccurrence-constraint :type))
+ collect (getf topicoccurrence-constraint :constraint)))))
+ (let ((contrary-constraints
+ (find-contrary-constraints constraint-lists)))
+ (when contrary-constraints
+ (error "found contrary topicname-constraints: ~a~%" contrary-constraints)))
+ (let ((type-topic
+ (concatenate 'string "\"occurrenceType\":"
+ (json-exporter::identifiers-to-json-string occurrencetype-topic)))
+ (typescope-constraints
+ (let ((current-scopes
+ (get-typescope-constraints occurrencetype-topic :what 'topicoccurrence)))
+ (concatenate 'string "\"scopeConstraints\":" current-scopes)))
+ (datatype-constraint
+ (concatenate 'string "\"datatypeConstraint\":"
+ (get-occurrence-datatype-constraint occurrencetype-topic)))
+ (unique-constraints
+ (concatenate 'string "\"uniqueConstraints\":"
+ (get-simple-constraints unique-constraint-topics)))
+ (json-constraint-lists
+ (concatenate 'string "\"constraints\":" (simple-constraints-to-json constraint-lists))))
+ (setf cleaned-topicoccurrence-constraints
+ (concatenate 'string cleaned-topicoccurrence-constraints
+ "{" type-topic "," json-constraint-lists "," typescope-constraints "," datatype-constraint "," unique-constraints "},")))))
+ (if (string= cleaned-topicoccurrence-constraints "[")
+ (setf cleaned-topicoccurrence-constraints "null")
+ (setf cleaned-topicoccurrence-constraints
+ (concatenate 'string (subseq cleaned-topicoccurrence-constraints 0 (- (length cleaned-topicoccurrence-constraints) 1)) "]")))
+ cleaned-topicoccurrence-constraints)))))
+
+
+(defun get-occurrence-datatype-constraint(occurrencetype-topic)
+ "Return a datatype qualifier as a string."
+ (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+ (applies-to (get-item-by-psi *applies-to-psi*))
+ (occurrencetype-role (get-item-by-psi *occurrencetype-role-psi*))
+ (datatype (get-item-by-psi *datatype-psi*))
+ (occurrencedatatype-constraint (get-item-by-psi *occurrencedatatype-constraint-psi*)))
+ (let ((datatype-constraints
+ (remove-duplicates
+ (loop for role in (player-in-roles occurrencetype-topic)
+ when (and (eq occurrencetype-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ append (loop for other-role in (roles (parent role))
+ when (and (eq constraint-role (instance-of other-role))
+ (topictype-of-p (player other-role) occurrencedatatype-constraint))
+ collect (player other-role))))))
+ (let ((datatype-constraint
+ (remove-duplicates
+ (map 'list #'(lambda(constraint-topic)
+ (loop for occurrence in (occurrences constraint-topic)
+ when (and (eq (instance-of occurrence) datatype)
+ (slot-boundp occurrence 'charvalue))
+ return (charvalue occurrence)))
+ datatype-constraints))))
+ (when (> (length datatype-constraint) 1)
+ (error "found contrary occurrence-datatype-constraints: ~a~%" datatype-constraints))
+ (if datatype-constraint
+ (json:encode-json-to-string (first datatype-constraint))
+ nil)))))
+
+
+(defun get-typescope-constraints(element-type-topic &key(what 'topicname))
+ "Returns a list of scopes for the element-typetopic which is the type topic of
+ a topicname, a topicoccurrence or an association. To specifiy of what kind
+ of element the scopes should be there is the key-variable what.
+ It can be set to 'topicname, 'topicoccurrence or 'association.
+ The return value is of the form
+ ( :scope <scope-topic>
+ :constraint (:card-min <string> :card-max <string> ))."
+ (let ((element-type-role-and-scope-constraint
+ (cond
+ ((eq what 'topicname)
+ (list (get-item-by-psi *nametype-role-psi*)
+ (get-item-by-psi *nametypescope-constraint-psi*)))
+ ((eq what 'topicoccurrence)
+ (list
+ (get-item-by-psi *occurrencetype-role-psi*)
+ (get-item-by-psi *occurrencetypescope-constraint-psi*)))
+ ((eq what 'association)
+ (list
+ (get-item-by-psi *associationtype-role-psi*)
+ (get-item-by-psi *associationtypescope-constraint-psi*)))))
+ (scopetype-role (get-item-by-psi *scopetype-role-psi*))
+ (constraint-role (get-item-by-psi *constraint-role-psi*))
+ (applies-to (get-item-by-psi *applies-to-psi*)))
+ (when (and (= (length element-type-role-and-scope-constraint) 2)
+ (first element-type-role-and-scope-constraint)
+ (second element-type-role-and-scope-constraint))
+ (let ((type-role (first element-type-role-and-scope-constraint))
+ (typescope-constraint (second element-type-role-and-scope-constraint)))
+ (let ((typescope-constraints
+ (loop for role in (player-in-roles element-type-topic)
+ when (and (eq type-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ append (loop for other-role in (roles (parent role))
+ when (and (eq constraint-role (instance-of other-role))
+ (topictype-of-p (player other-role) typescope-constraint))
+ collect (let ((scopes nil)
+ (constraint nil))
+ (loop for c-role in (player-in-roles (player other-role))
+ when (and (eq constraint-role (instance-of c-role))
+ (eq applies-to (instance-of (parent c-role))))
+ do (progn
+ (setf constraint (get-constraint-topic-values (player c-role)))
+ (loop for c-other-role in (roles (parent c-role))
+ when (eq scopetype-role (instance-of c-other-role))
+ do (push (player c-other-role) scopes))))
+ (list :scopes scopes :constraint constraint))))))
+ (let ((scopetype-groups
+ (remove-duplicates (map 'list #'(lambda(x)
+ (let ((scopes (getf x :scopes)))
+ (when scopes
+ scopes)))
+ typescope-constraints)
+ :test #'(lambda(x y)
+ (when (and (= (length x) (length y))
+ (= (length x) (length (intersection x y))))
+ t)))))
+ (let ((cleaned-typescope-constraints "["))
+ (loop for scopetype-group in scopetype-groups
+ do (let ((constraint-lists
+ (remove-duplicate-constraints
+ (loop for typescope-constraint in typescope-constraints
+ when (and (= (length (getf typescope-constraint :scopes))
+ (length scopetype-group))
+ (= (length (getf typescope-constraint :scopes))
+ (length (intersection (getf typescope-constraint :scopes) scopetype-group))))
+ collect (getf typescope-constraint :constraint)))))
+ (when (> (length constraint-lists) 1)
+ (error "found contrary scopetype-constraints for ~a: ~a~%"
+ (map 'list #'(lambda(x)(uri (first (psis x)))) scopetype-group)
+ constraint-lists))
+ (let ((card-min (getf (first constraint-lists) :card-min))
+ (card-max (getf (first constraint-lists) :card-max)))
+ (let ((json-scopes "\"scopeTypes\":["))
+ (dolist (item scopetype-group)
+ (let ((json-list (json-exporter::identifiers-to-json-string item)))
+ (setf json-scopes (concatenate 'string json-scopes json-list ","))))
+ (setf json-scopes (subseq json-scopes 0 (- (length json-scopes) 1)))
+ (let ((current-json-string
+ (concatenate 'string "{" json-scopes "],\"cardMin\":\"" card-min "\",\"cardMax\":\"" card-max "\"}")))
+ (setf cleaned-typescope-constraints
+ (concatenate 'string cleaned-typescope-constraints current-json-string ",")))))))
+ (if (string= cleaned-typescope-constraints "[")
+ (setf cleaned-typescope-constraints "null")
+ (setf cleaned-typescope-constraints
+ (concatenate 'string (subseq cleaned-typescope-constraints 0 (- (length cleaned-typescope-constraints) 1)) "]")))
+ cleaned-typescope-constraints)))))))
+
+
+;; -----------------------------------------------------------------------------
+;; --- some basic helpers ------------------------------------------------------
+;; -----------------------------------------------------------------------------
+(defun get-constraint-topic-values(topic)
+ "Returns all constraint values of the passed topic in the
+ following form (list :regexp regexp :card-min card-min :card-max card-max)"
+ (let ((regexp
+ (get-constraint-occurrence-value topic))
+ (card-min
+ (get-constraint-occurrence-value topic :what 'card-min))
+ (card-max
+ (get-constraint-occurrence-value topic :what 'card-max)))
+ (when (and (string/= "MAX_INT" card-max)
+ (> (parse-integer card-min) (parse-integer card-max)))
+ (error "card-min (~a) must be < card-max (~a)" card-min card-max))
+ (list :regexp regexp :card-min card-min :card-max card-max)))
+
+
+(defun get-constraint-occurrence-value(topic &key (what 'regexp))
+ "Checks the occurrence-value of a regexp, card-min or card-max
+ constriant-occurrence.
+ If what = 'regexp and the occurrence-value is empty there will be returned
+ the value '.*!'.
+ If what = 'card-min and the occurrence-value is empty there will be returned
+ the value '0'.
+ If what = 'card-max and the occurrence-value is empty there will be returned
+ the value 'MAX_INT'"
+ (let ((occurrence-type
+ (get-item-by-psi
+ (cond
+ ((eq what 'regexp)
+ *regexp-psi*)
+ ((eq what 'card-min)
+ *card-min-psi*)
+ ((eq what 'card-max)
+ *card-max-psi*)
+ (t
+ "")))))
+ (when occurrence-type
+ (let ((occurrence-value
+ (let ((occurrence
+ (find occurrence-type (occurrences topic) :key #'instance-of)))
+ (if (and occurrence
+ (slot-boundp occurrence 'charvalue)
+ (> (length (charvalue occurrence)) 0))
+ (charvalue occurrence)
+ (cond
+ ((eq what 'regexp)
+ ".*")
+ ((eq what 'card-min)
+ "0")
+ ((eq what 'card-max)
+ "MAX_INT"))))))
+ (cond
+ ((eq what 'card-min)
+ (let ((is-valid
+ (handler-case (let ((card-min
+ (parse-integer occurrence-value)))
+ (when (>= card-min 0)
+ t))
+ (condition () nil))))
+ (unless is-valid
+ (error "card-min in ~a is \"~a\" but should be >= 0"
+ (uri (first (psis topic)))
+ occurrence-value))))
+ ((eq what 'card-max)
+ (let ((is-valid
+ (handler-case (let ((card-max
+ (parse-integer occurrence-value)))
+ (when (>= card-max 0)
+ t))
+ (condition () (when (string= occurrence-value "MAX_INT")
+ t)))))
+ (unless is-valid
+ (error "card-max in ~a is \"~a\" but should be >= 0 or \"MAX_INT\""
+ (uri (first (psis topic)))
+ occurrence-value)))))
+ occurrence-value))))
+
+
+(defun find-contrary-constraints(constraint-lists)
+ "Returns a list which contains a list of minimum two contrary constraints
+ or nil if there are no contrary constraints.
+ The list is of the form
+ (list (list :regexp <regexp> :card-min <card-min> :card-max <card-max>) (list ...))."
+ (let ((current-constraint nil))
+ (loop for constraint-list in constraint-lists
+ do (progn
+ (when (> (length current-constraint) 0)
+ (return-from find-contrary-constraints current-constraint))
+ (setf current-constraint (remove-if #'null (map 'list #'(lambda(x)
+ (contrary-constraint-list x constraint-list))
+ constraint-lists)))))))
+
+(defun contrary-constraint-list (lst-1 lst-2)
+ "Returns both passed lists when they have the same
+ regular expression but different card-min or card-max values."
+ (when (and (typep lst-1 'list) (typep lst-2 'list)
+ (= 6 (length lst-1) (length lst-2)))
+ (when (and (string= (getf lst-1 :regexp) (getf lst-2 :regexp))
+ (or (string/= (getf lst-1 :card-min) (getf lst-2 :card-min))
+ (string/= (getf lst-1 :card-max) (getf lst-2 :card-max))))
+ (list lst-1 lst-2))))
+
+
+(defun remove-duplicate-constraints(constraint-lists)
+ "Removes duplicate constraints of the passed constraint list.
+ This list should have the form
+ (list (list :regexp <regexp> :card-min <card-min> :card-max <card-max>) (list ...)).
+ A constraint is defined as equal whan all three value (regexp, card-min and card-max
+ are equal."
+ (remove-duplicates constraint-lists :test #'eql-constraint-list))
+
+
+
+(defun eql-constraint-list (lst-1 lst-2)
+ "Compares two constraint lists of the form (list <string> <string> string>)
+ or (list <topic> <string> <string> <string>."
+ (when (and (typep lst-1 'list) (typep lst-2 'list)
+ (= 6 (length lst-1) (length lst-2)))
+ (and (string= (getf lst-1 :regexp) (getf lst-2 :regexp))
+ (string= (getf lst-1 :card-min) (getf lst-2 :card-min))
+ (string= (getf lst-1 :card-max) (getf lst-2 :card-max)))))
+
+
+;; --- checks if the given topic is a valid topictype --------------------------
+(defun get-direct-types-of-topic(topic-instance)
+ "Returns the direct types of the topic as a list passed to this function.
+ This function only returns the types of the type-instance-relationship -> TMDM 7.2"
+ (let ((type-instance (get-item-by-psi *type-instance-psi*))
+ (instance (get-item-by-psi *instance-psi*))
+ (type (get-item-by-psi *type-psi*)))
+ (let ((topic-types
+ (loop for role in (player-in-roles topic-instance)
+ when (eq instance (instance-of role))
+ collect (loop for other-role in (roles (parent role))
+ when (and (not (eq role other-role))
+ (eq type-instance (instance-of (parent role)))
+ (eq type (instance-of other-role)))
+ return (player other-role)))))
+ (when topic-types
+ (remove-if #'null topic-types)))))
+
+
+(defun get-direct-supertypes-of-topic(topic-instance)
+ "Returns the direct supertypes of the topic as a list passed to this function.
+ This function only returns the types of the supertype-subtype-relationship -> TMDM 7.3"
+ (let ((supertype-subtype (get-item-by-psi *supertype-subtype-psi*))
+ (supertype (get-item-by-psi *supertype-psi*))
+ (subtype (get-item-by-psi *subtype-psi*)))
+ (let ((supertypes
+ (loop for role in (player-in-roles topic-instance)
+ when (eq subtype (instance-of role))
+ append (loop for other-role in (roles (parent role))
+ when (and (not (eq role other-role))
+ (eq supertype-subtype (instance-of (parent role)))
+ (eq supertype (instance-of other-role)))
+ collect (player other-role)))))
+ (remove-if #'null supertypes))))
+
+
+(defun subtype-p (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*)) (checked-topics nil))
+ "Returns a list of all supertypes of the passed topic if the passed topic
+ is not an instanceOf any other topic but a subtype of some supertypes
+ of topictype or it is the topictype-topic itself."
+ ;(format t "~%~%subtype-p ~a~%" (uri (first (psis topic-instance))))
+ (let ((current-checked-topics (remove-duplicates (append checked-topics (list topic-instance)))))
+
+ (when (eq topictype topic-instance)
+ (return-from subtype-p current-checked-topics))
+
+ (when (get-direct-types-of-topic topic-instance)
+ (return-from subtype-p nil))
+
+ (let ((supertypes-of-this (get-direct-supertypes-of-topic topic-instance)))
+ (when (not supertypes-of-this)
+ (return-from subtype-p nil))
+ (when supertypes-of-this
+ (loop for supertype-of-this in supertypes-of-this
+ when (not (find supertype-of-this current-checked-topics :test #'eq))
+ do (let ((further-supertypes (subtype-p topictype supertype-of-this current-checked-topics)))
+ (when (not further-supertypes)
+ (return-from subtype-p nil))
+
+ (dolist (item further-supertypes)
+ (pushnew item current-checked-topics))))))
+
+ current-checked-topics))
+
+
+(defun topictype-p (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*))
+ (topictype-constraint (get-item-by-psi *topictype-constraint-psi*))
+ (checked-topics nil))
+ "Returns a list of all instanceOf-topics and all Supertypes of this topic
+ if this topic is a valid topic (-type). I.e. the passed topic is the
+ topictype or it is an instanceOf of the topictype or it is a subtype of
+ the topictype. TMDM 7.2 + TMDM 7.3"
+ ;(format t "~%~%topictype-p ~a~%" (uri (first (psis topic-instance))))
+ (let ((current-checked-topics (append checked-topics (list topic-instance)))
+ (akos-of-this (get-direct-supertypes-of-topic topic-instance))
+ (isas-of-this (get-direct-types-of-topic topic-instance)))
+
+ (when (eq topictype topic-instance)
+ (return-from topictype-p current-checked-topics))
+
+ (when (not (union akos-of-this isas-of-this :test #'eq))
+ (when topictype-constraint
+ ;(return-from topictype-p nil))
+ (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype)))))
+ (return-from topictype-p current-checked-topics))
+
+ (let ((akos-are-topictype nil))
+ (loop for ako-of-this in akos-of-this
+ when (not (find ako-of-this current-checked-topics))
+ do (let ((further-topics (topictype-p ako-of-this topictype topictype-constraint)))
+ (if further-topics
+ (progn
+ (dolist (item further-topics)
+ (pushnew item current-checked-topics))
+ (pushnew ako-of-this akos-are-topictype))
+ (when topictype-constraint
+ ;(return-from topictype-p nil)))))
+ (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype))))))))
+
+ (when isas-of-this
+ (let ((topictype-topics-of-isas nil))
+ (loop for isa-of-this in isas-of-this
+ do (let ((topic-akos (subtype-p isa-of-this topictype)))
+ (when topic-akos
+ (pushnew isa-of-this topictype-topics-of-isas)
+ (pushnew isa-of-this current-checked-topics)
+ (dolist (item topic-akos)
+ (pushnew item current-checked-topics)))))
+
+ (when (and (not topictype-topics-of-isas)
+ (not akos-are-topictype)
+ topictype-constraint)
+ ;(return-from topictype-p nil))
+ (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype)))))
+
+ (loop for isa-of-this in isas-of-this
+ when (and (not (find isa-of-this current-checked-topics :test #'eq))
+ (not (find isa-of-this topictype-topics-of-isas :test #'eq)))
+ do (let ((further-topic-types (topictype-p isa-of-this topictype topictype-constraint current-checked-topics)))
+ (if further-topic-types
+ (dolist (item further-topic-types)
+ (pushnew item current-checked-topics))
+ (when topictype-constraint
+ ;(return-from topictype-p nil))))))))
+ (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype)))))))))))
+ current-checked-topics))
+
+
+(defun topictype-of-p (topic-instance type-instance &optional checked-topics)
+ "Returns a list of all types and supertypes of this topic if this topic is a
+ valid instance-topic of the type-topic called type-instance. TMCL 4.4.2"
+ (let ((current-checked-topics (append checked-topics (list topic-instance)))
+ (topictype (get-item-by-psi *topictype-psi*))
+ (isas-of-this (get-direct-types-of-topic topic-instance))
+ (akos-of-this (get-direct-supertypes-of-topic topic-instance)))
+
+ (when (eq topic-instance topictype)
+ t)
+
+ (when (and (not isas-of-this)
+ (not akos-of-this))
+ (return-from topictype-of-p nil))
+
+ (loop for isa-of-this in isas-of-this
+ do (let ((found-topics (topictype-p isa-of-this)))
+ (when (not found-topics)
+ (return-from topictype-of-p nil))
+ (dolist (item found-topics)
+ (pushnew item current-checked-topics))))
+
+ (loop for ako-of-this in akos-of-this
+ when (not (find ako-of-this current-checked-topics :test #'eq))
+ do (let ((found-topics (topictype-of-p ako-of-this type-instance current-checked-topics)))
+ (when (not found-topics)
+ (return-from topictype-of-p nil))
+ (dolist (item found-topics)
+ (pushnew item current-checked-topics))))
+
+ (when (find type-instance current-checked-topics)
+ current-checked-topics)))
+
+
+;; --- gets all constraint topics ----------------------------------------------
+(defun get-direct-constraint-topics-of-topic (topic-instance)
+ "Returns all constraint topics defined for the passed topic-instance"
+ (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+ (topictype-role (get-item-by-psi *topictype-role-psi*))
+ (applies-to (get-item-by-psi *applies-to-psi*))
+ (abstract-topictype-constraint (get-item-by-psi *abstract-topictype-constraint-psi*))
+ (exclusive-instance-constraint (get-item-by-psi *exclusive-instance-psi*))
+ (subjectidentifier-constraint (get-item-by-psi *subjectidentifier-constraint-psi*))
+ (subjectlocator-constraint (get-item-by-psi *subjectlocator-constraint-psi*))
+ (topicname-constraint (get-item-by-psi *topicname-constraint-psi*))
+ (topicoccurrence-constraint (get-item-by-psi *topicoccurrence-constraint-psi*))
+ (uniqueoccurrence-constraint (get-item-by-psi *uniqueoccurrence-constraint-psi*))
+ (roleplayer-constraint (get-item-by-psi *roleplayer-constraint-psi*))
+ (otherrole-constraint (get-item-by-psi *otherrole-constraint-psi*))
+ (abstract-topictype-constraints nil)
+ (exclusive-instance-constraints nil)
+ (subjectidentifier-constraints nil)
+ (subjectlocator-constraints nil)
+ (topicname-constraints nil)
+ (topicoccurrence-constraints nil)
+ (uniqueoccurrence-constraints nil))
+
+ (loop for role in (player-in-roles topic-instance)
+ when (and (eq topictype-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ do (loop for other-role in (roles (parent role))
+ when (eq constraint-role (instance-of other-role))
+ do (let ((constraint-topic (player other-role)))
+ (cond
+ ((topictype-of-p constraint-topic abstract-topictype-constraint)
+ (pushnew constraint-topic abstract-topictype-constraints))
+ ((topictype-of-p constraint-topic exclusive-instance-constraint)
+ (pushnew constraint-topic exclusive-instance-constraints))
+ ((topictype-of-p constraint-topic subjectidentifier-constraint)
+ (pushnew constraint-topic subjectidentifier-constraints))
+ ((topictype-of-p constraint-topic subjectlocator-constraint)
+ (pushnew constraint-topic subjectlocator-constraints))
+ ((topictype-of-p constraint-topic topicname-constraint)
+ (pushnew constraint-topic topicname-constraints))
+ ((topictype-of-p constraint-topic topicoccurrence-constraint)
+ (pushnew constraint-topic topicoccurrence-constraints))
+ ((topictype-of-p constraint-topic uniqueoccurrence-constraint)
+ (pushnew constraint-topic uniqueoccurrence-constraints))
+ (t
+ (unless (or (topictype-of-p constraint-topic roleplayer-constraint)
+ (topictype-of-p constraint-topic otherrole-constraint))
+ (error "Constraint-Topic \"~a\" could not be handled" (uri (first (psis constraint-topic))))))))))
+ (list :abstract-topictype-constraints abstract-topictype-constraints
+ :exclusive-instance-constraints (list :exclusive-constraints exclusive-instance-constraints
+ :owner topic-instance)
+ :subjectidentifier-constraints subjectidentifier-constraints
+ :subjectlocator-constraints subjectlocator-constraints
+ :topicname-constraints topicname-constraints
+ :topicoccurrence-constraints topicoccurrence-constraints
+ :uniqueoccurrence-constraints uniqueoccurrence-constraints)))
+
+
+(defmethod get-all-constraint-topics-of-topic (topic-instance &key (treat-as 'type))
+ "Returns a list of constraint-topics of the topics-instance's base type(s).
+ If topic c is instanceOf a and b, there will be returned all
+ constraint-topics of the topic types a and b.
+ If treat-as is set to instance there will be only the constraints collected
+ defined for the supertypes or the types of the passed topic - all constraints
+ defined directly for the passed topic are ignored, unless the passed topic is
+ an instance of itself."
+ (let ((akos-and-isas-of-this
+ (remove-duplicates
+ (if (eql treat-as 'type)
+ (topictype-p topic-instance)
+ (loop for topic in (union (get-direct-types-of-topic topic-instance) (get-direct-supertypes-of-topic topic-instance))
+ append (topictype-p topic))))))
+ (let ((all-abstract-topictype-constraints nil)
+ (all-exclusive-instance-constraints nil)
+ (all-subjectidentifier-constraints nil)
+ (all-subjectlocator-constraints nil)
+ (all-topicname-constraints nil)
+ (all-topicoccurrence-constraints nil)
+ (all-uniqueoccurrence-constraints nil))
+ (loop for topic in akos-and-isas-of-this
+ do (let ((constraint-topics-of-topic (get-direct-constraint-topics-of-topic topic)))
+ (when (eq topic topic-instance)
+ (dolist (item (getf constraint-topics-of-topic :abstract-topictype-constraints))
+ (pushnew item all-abstract-topictype-constraints)))
+ (let ((exclusive-instance-constraints
+ (getf constraint-topics-of-topic :exclusive-instance-constraints)))
+ (when (getf exclusive-instance-constraints :exclusive-constraints)
+ (push exclusive-instance-constraints all-exclusive-instance-constraints)))
+ (dolist (item (getf constraint-topics-of-topic :subjectidentifier-constraints))
+ (pushnew item all-subjectidentifier-constraints))
+ (dolist (item (getf constraint-topics-of-topic :subjectlocator-constraints))
+ (pushnew item all-subjectlocator-constraints))
+ (dolist (item (getf constraint-topics-of-topic :topicname-constraints))
+ (pushnew item all-topicname-constraints))
+ (dolist (item (getf constraint-topics-of-topic :topicoccurrence-constraints))
+ (pushnew item all-topicoccurrence-constraints))
+ (dolist (item (getf constraint-topics-of-topic :uniqueoccurrence-constraints))
+ (pushnew item all-uniqueoccurrence-constraints))))
+ (list :abstract-topictype-constraints all-abstract-topictype-constraints
+ :exclusive-instance-constraints all-exclusive-instance-constraints
+ :subjectidentifier-constraints all-subjectidentifier-constraints
+ :subjectlocator-constraints all-subjectlocator-constraints
+ :topicname-constraints all-topicname-constraints
+ :topicoccurrence-constraints all-topicoccurrence-constraints
+ :uniqueoccurrence-constraints all-uniqueoccurrence-constraints))))
+
+
+(defun abstract-p (topic-instance)
+ "Returns t if this topic type is an abstract topic type."
+ (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+ (topictype-role (get-item-by-psi *topictype-role-psi*))
+ (applies-to (get-item-by-psi *applies-to-psi*))
+ (abstract-topictype-constraint (get-item-by-psi *abstract-topictype-constraint-psi*)))
+
+ (loop for role in (player-in-roles topic-instance)
+ when (and (eq topictype-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ return (loop for other-role in (roles (parent role))
+ when (and (eq constraint-role (instance-of other-role))
+ (eq abstract-topictype-constraint (player other-role)))
+ return t))))
+
+
+(defun get-direct-constraint-topics-of-association(associationtype-topic)
+ "Returns all direct constraint topics defined for associations if
+ the passed associationtype-topic"
+ (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+ (associationtype-role (get-item-by-psi *associationtype-role-psi*))
+ (applies-to (get-item-by-psi *applies-to-psi*))
+ (associationtypescope-constraint (get-item-by-psi *associationtypescope-constraint-psi*))
+ (associationrole-constraint (get-item-by-psi *associationrole-constraint-psi*))
+ (roleplayer-constraint (get-item-by-psi *roleplayer-constraint-psi*))
+ (otherrole-constraint (get-item-by-psi *otherrole-constraint-psi*))
+ (associationrole-constraints nil)
+ (roleplayer-constraints nil)
+ (otherrole-constraints nil))
+
+ (loop for role in (player-in-roles associationtype-topic)
+ when (and (eq associationtype-role (instance-of role))
+ (eq applies-to (instance-of (parent role))))
+ do (loop for other-role in (roles (parent role))
+ when (eq constraint-role (instance-of other-role))
+ do (let ((constraint-topic (player other-role)))
+ (cond
+ ((topictype-of-p constraint-topic associationtypescope-constraint)
+ t) ;do nothing
+ ((topictype-of-p constraint-topic associationrole-constraint)
+ (pushnew constraint-topic associationrole-constraints))
+ ((topictype-of-p constraint-topic roleplayer-constraint)
+ (pushnew constraint-topic roleplayer-constraints))
+ ((topictype-of-p constraint-topic otherrole-constraint)
+ (pushnew constraint-topic otherrole-constraints))
+ (t
+ (error "Constraint-Topic \"~a\" could not be handled" (uri (first (psis constraint-topic)))))))))
+
+ (list :associationrole-constraints associationrole-constraints
+ :roleplayer-constraints roleplayer-constraints
+ :otherrole-constraints otherrole-constraints)))
+
+
+(defun get-all-constraint-topics-of-association(associationtype-topic)
+ "Returns all constraint topics defined for associations if
+ the passed associationtype-topic."
+ (let ((akos-and-isas-of-this
+ (topictype-p associationtype-topic (get-item-by-psi *associationtype-psi*) (get-item-by-psi *associationtype-constraint-psi*))))
+ (let ((all-associationrole-constraints nil)
+ (all-roleplayer-constraints nil)
+ (all-otherrole-constraints nil))
+ (loop for topic in akos-and-isas-of-this
+ do (let ((constraint-topics-of-topic
+ (get-direct-constraint-topics-of-association topic)))
+ (dolist (item (getf constraint-topics-of-topic :associationrole-constraints))
+ (pushnew item all-associationrole-constraints))
+ (dolist (item (getf constraint-topics-of-topic :roleplayer-constraints))
+ (pushnew item all-roleplayer-constraints))
+ (dolist (item (getf constraint-topics-of-topic :otherrole-constraints))
+ (pushnew item all-otherrole-constraints))))
+ (list :associationrole-constraints all-associationrole-constraints
+ :roleplayer-constraints all-roleplayer-constraints
+ :otherrole-constraints all-otherrole-constraints))))
+
+
+(defun get-available-associations-of-topic(topic-instance &key (treat-as 'type))
+ "Returns a list of topics decribing the available associationtype for the
+ passed topic."
+ (let ((applies-to (get-item-by-psi *applies-to-psi*))
+ (topictype-role (get-item-by-psi *topictype-role-psi*))
+ (constraint-role (get-item-by-psi *constraint-role-psi*))
+ (othertopictype-role (get-item-by-psi *othertopictype-role-psi*))
+ (associationtype-role (get-item-by-psi *associationtype-role-psi*))
+ (roleplayer-constraint (get-item-by-psi *roleplayer-constraint-psi*))
+ (otherrole-constraint (get-item-by-psi *otherrole-constraint-psi*))
+ (all-possible-player-topics
+ (remove-duplicates
+ (if (eql treat-as 'type)
+ (topictype-p topic-instance)
+ (loop for topic in (union (get-direct-types-of-topic topic-instance) (get-direct-supertypes-of-topic topic-instance))
+ append (topictype-p topic))))))
+
+
+ ;what's with associationrole-constraints without a player-constraint???
+ (let ((all-available-associationtypes
+ (remove-duplicates
+ (loop for possible-player-topic in all-possible-player-topics
+ append (loop for role in (player-in-roles possible-player-topic)
+ when (and (or (eq topictype-role (instance-of role))
+ (eq othertopictype-role (instance-of role)))
+ (eq applies-to (instance-of (parent role))))
+ append (loop for other-role in (roles (parent role))
+ when (and (eq constraint-role (instance-of other-role))
+ (or (topictype-of-p (player other-role) roleplayer-constraint)
+ (topictype-of-p (player other-role) otherrole-constraint)))
+ append (loop for c-role in (player-in-roles (player other-role))
+ when (and (eq constraint-role (instance-of c-role))
+ (eq applies-to (instance-of (parent c-role))))
+ append (loop for type-role in (roles (parent c-role))
+ when (eq associationtype-role (instance-of type-role))
+ collect (player type-role)))))))))
+ all-available-associationtypes)))
\ No newline at end of file
Added: trunk/src/json/json_tmcl_constants.lisp
==============================================================================
--- (empty file)
+++ trunk/src/json/json_tmcl_constants.lisp Mon May 4 11:02:44 2009
@@ -0,0 +1,92 @@
+;;+-----------------------------------------------------------------------------
+;;+ Isidorus
+;;+ (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
+;;+
+;;+ Isidorus is freely distributable under the LGPL license.
+;;+ You can find a detailed description in trunk/docs/LGPL-LICENSE.txt.
+;;+-----------------------------------------------------------------------------
+
+
+(defpackage :json-tmcl-constants
+ (:use :cl)
+ (:export :*topictype-psi*
+ :*topictype-constraint-psi*
+ :*associationtype-psi*
+ :*associationtype-constraint-psi*
+ :*roletype-psi*
+ :*roletype-constraint-psi*
+ :*occurrencetype-psi*
+ :*occurrencetype-constraint-psi*
+ :*nametype-psi*
+ :*nametype-constraint-psi*
+ :*scopetype-psi*
+ :*topictype-role-psi*
+ :*applies-to-psi*
+ :*constraint-role-psi*
+ :*regexp-psi*
+ :*card-min-psi*
+ :*card-max-psi*
+ :*datatype-psi*
+ :*subjectidentifier-constraint-psi*
+ :*subjectlocator-constraint-psi*
+ :*abstract-topictype-constraint-psi*
+ :*exclusive-instance-psi*
+ :*topicname-constraint-psi*
+ :*topicoccurrence-constraint-psi*
+ :*occurrencedatatype-constraint-psi*
+ :*uniqueoccurrence-constraint-psi*
+ :*roleplayer-constraint-psi*
+ :*otherrole-constraint-psi*
+ :*nametype-role-psi*
+ :*scopetype-role-psi*
+ :*occurrencetype-role-psi*
+ :*othertopictype-role-psi*
+ :*otherroletype-role-psi*
+ :*associationtype-role-psi*
+ :*nametypescope-constraint-psi*
+ :*occurrencetypescope-constraint-psi*
+ :*associationtypescope-constraint-psi*
+ :*associationrole-constraint-psi*
+ :*roletype-role-psi*))
+
+(in-package :json-tmcl-constants)
+
+(defparameter *topictype-psi* "http://psi.topicmaps.org/tmcl/topic-type")
+(defparameter *topictype-constraint-psi* "http://psi.topicmaps.org/tmcl/topic-type-constraint")
+(defparameter *associationtype-psi* "http://psi.topicmaps.org/tmcl/association-type")
+(defparameter *associationtype-constraint-psi* "http://psi.topicmaps.org/tmcl/association-type-constraint")
+(defparameter *roletype-psi* "http://psi.topicmaps.org/tmcl/role-type")
+(defparameter *roletype-constraint-psi* "http://psi.topicmaps.org/tmcl/role-type-constraint")
+(defparameter *occurrencetype-psi* "http://psi.topicmaps.org/tmcl/occurrence-type")
+(defparameter *occurrencetype-constraint-psi* "http://psi.topicmaps.org/tmcl/occurrence-type-constraint")
+(defparameter *nametype-psi* "http://psi.topicmaps.org/tmcl/name-type")
+(defparameter *nametype-constraint-psi* "http://psi.topicmaps.org/tmcl/name-type-constraint")
+(defparameter *scopetype-psi* "http://psi.topicmaps.org/tmcl/scope-type")
+(defparameter *topictype-role-psi* "http://psi.topicmaps.org/tmcl/topic-type-role")
+(defparameter *applies-to-psi* "http://psi.topicmaps.org/tmcl/applies-to")
+(defparameter *constraint-role-psi* "http://psi.topicmaps.org/tmcl/constraint-role")
+(defparameter *regexp-psi* "http://psi.topicmaps.org/tmcl/reg-exp")
+(defparameter *card-min-psi* "http://psi.topicmaps.org/tmcl/card-min")
+(defparameter *card-max-psi* "http://psi.topicmaps.org/tmcl/card-max")
+(defparameter *datatype-psi* "http://psi.topicmaps.org/tmcl/datatype")
+(defparameter *subjectidentifier-constraint-psi* "http://psi.topicmaps.org/tmcl/subject-identifier-constraint")
+(defparameter *subjectlocator-constraint-psi* "http://psi.topicmaps.org/tmcl/subject-locator-constraint")
+(defparameter *abstract-topictype-constraint-psi* "http://psi.topicmaps.org/tmcl/abstract-topic-type-constraint")
+(defparameter *exclusive-instance-psi* "http://psi.topicmaps.org/tmcl/exclusive-instance")
+(defparameter *topicname-constraint-psi* "http://psi.topicmaps.org/tmcl/topic-name-constraint")
+(defparameter *topicoccurrence-constraint-psi* "http://psi.topicmaps.org/tmcl/topic-occurrence-constraint")
+(defparameter *occurrencedatatype-constraint-psi* "http://psi.topicmaps.org/tmcl/occurrence-datatype-constraint")
+(defparameter *uniqueoccurrence-constraint-psi* "http://psi.topicmaps.org/tmcl/unique-occurrence-constraint")
+(defparameter *roleplayer-constraint-psi* "http://psi.topicmaps.org/tmcl/role-player-constraint")
+(defparameter *otherrole-constraint-psi* "http://psi.topicmaps.org/tmcl/other-role-constraint")
+(defparameter *nametypescope-constraint-psi* "http://psi.topicmaps.org/tmcl/name-type-scope-constraint")
+(defparameter *occurrencetypescope-constraint-psi* "http://psi.topicmaps.org/tmcl/occurrence-type-scope-constraint")
+(defparameter *associationtypescope-constraint-psi* "http://psi.topicmaps.org/tmcl/association-type-scope-constraint")
+(defparameter *nametype-role-psi* "http://psi.topicmaps.org/tmcl/name-type-role")
+(defparameter *scopetype-role-psi* "http://psi.topicmaps.org/tmcl/scope-type-role")
+(defparameter *occurrencetype-role-psi* "http://psi.topicmaps.org/tmcl/occurrence-type-role")
+(defparameter *othertopictype-role-psi* "http://psi.topicmaps.org/tmcl/other-topic-type-role")
+(defparameter *otherroletype-role-psi* "http://psi.topicmaps.org/tmcl/other-role-type-role")
+(defparameter *associationtype-role-psi* "http://psi.topicmaps.org/tmcl/association-type-role")
+(defparameter *associationrole-constraint-psi* "http://psi.topicmaps.org/tmcl/association-role-constraint")
+(defparameter *roletype-role-psi* "http://psi.topicmaps.org/tmcl/role-type-role")
\ No newline at end of file
Modified: trunk/src/model/changes.lisp
==============================================================================
--- trunk/src/model/changes.lisp (original)
+++ trunk/src/model/changes.lisp Mon May 4 11:02:44 2009
@@ -286,4 +286,13 @@
(elephant:get-instances-by-value 'FragmentC 'topic topic)))
;; maybe there are more fragments of this topic in different revisions,
;; so we need to search the fragment with a certain revision
- (first (sort fragments #'> :key 'revision)))))))))
\ No newline at end of file
+ (let ((found-fragment
+ (if fragments
+ (first (sort fragments #'> :key 'revision))
+ ;; if there exist a topic but always no fragment, there will be generated a new fragment of the latest version for the searched topic
+ (make-instance 'FragmentC
+ :revision (first (sort (versions topic) #'> :key 'start-revision))
+ :associations (find-associations-for-topic topic)
+ :referenced-topics (find-referenced-topics topic)
+ :topic topic))))
+ found-fragment))))))))
\ No newline at end of file
Modified: trunk/src/rest_interface/rest-interface.lisp
==============================================================================
--- trunk/src/rest_interface/rest-interface.lisp (original)
+++ trunk/src/rest_interface/rest-interface.lisp Mon May 4 11:02:44 2009
@@ -28,7 +28,11 @@
:*json-get-prefix*
:*json-commit-url*
:*json-get-all-psis*
- :*json-get-summary-prefix**
+ :*json-get-summary-prefix*
+ :*json-get-all-type-psis*
+ :*json-get-topic-stub-prefix*
+ :*json-get-type-tmcl-prefix*
+ :*json-get-instance-tmcl-prefix*
:*ajax-user-interface-url*
:*ajax-user-interface-file-path*
:*ajax-javascript-directory-path*
@@ -110,11 +114,13 @@
-(defvar *acceptor*)
+(defvar *server-acceptor* nil)
(defun start-tm-engine (repository-path &key (conffile "atom/conf.lisp") (host-name "localhost") (port 8000))
"Start the Topic Map Engine on a given port, assuming a given
-hostname. Use the repository under repository-path"
+ hostname. Use the repository under repository-path"
+ (when *server-acceptor*
+ (error "Ther server is already running"))
(setf hunchentoot:*show-lisp-errors-p* t) ;for now
;(setf hunchentoot:*show-lisp-backtraces-p* t) ;hunchentoot 0.15.7
(setf hunchentoot:*hunchentoot-default-external-format*
@@ -125,12 +131,13 @@
(load conffile)
(publish-feed atom:*tm-feed*)
(set-up-json-interface)
- (setf *acceptor* (make-instance 'hunchentoot:acceptor :address host-name :port port))
+ (setf *server-acceptor* (make-instance 'hunchentoot:acceptor :address host-name :port port))
(setf hunchentoot:*lisp-errors-log-level* :info)
(setf hunchentoot:*message-log-pathname* "./hunchentoot-errors.log")
- (hunchentoot:start *acceptor*))
+ (hunchentoot:start *server-acceptor*))
(defun shutdown-tm-engine ()
"Shut down the Topic Map Engine"
- (hunchentoot:stop *acceptor*)
+ (hunchentoot:stop *server-acceptor*)
+ (setf *server-acceptor* nil)
(elephant:close-store))
\ No newline at end of file
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 Mon May 4 11:02:44 2009
@@ -13,6 +13,10 @@
(defparameter *json-commit-url* "/json/commit/?$") ;the url to commit a json fragment by "put" or "post"
(defparameter *json-get-all-psis* "/json/psis/?$") ;the url to get all topic psis of isidorus -> localhost:8000/json/psis
(defparameter *json-get-summary-url* "/json/summary/?$") ;the url to get a summary od all topic stored in isidorus; you have to set the GET-parameter "start" for the start index of all topics within elephant and the GET-paramter "end" for the last index of the topic sequence -> http://localhost:8000/json/summary/?start=12&end=13
+(defparameter *json-get-all-type-psis* "/json/tmcl/types/?$") ;returns a list of all psis that can be a type
+(defparameter *json-get-topic-stub-prefix* "/json/tmcl/topicstubs/(.+)$") ;the json prefix for getting some topic stub information of a topic and its "derived" topics
+(defparameter *json-get-type-tmcl-prefix* "/json/tmcl/type/(.+)$") ;the json prefix for getting some tmcl information of a topic treated as a type
+(defparameter *json-get-instance-tmcl-prefix* "/json/tmcl/instance/(.+)$") ;the json prefix for getting some tmcl information of a topic treated as an instance
(defparameter *ajax-user-interface-url* "/isidorus/?$") ;the url to the user interface; if you want to get all topics set start=0&end=nil -> localhost:8000/isidorus
(defparameter *ajax-user-interface-css-prefix* "/css") ;the url to the css files of the user interface
(defparameter *ajax-user-interface-css-directory-path* "ajax/css") ;the directory contains the css files
@@ -20,11 +24,14 @@
(defparameter *ajax-javascript-directory-path* "ajax/javascripts") ;the directory which contains all necessary javascript files
(defparameter *ajax-javascript-url-prefix* "/javascripts") ; the url prefix of all javascript files
-
(defun set-up-json-interface (&key (json-get-prefix *json-get-prefix*)
(json-get-all-psis *json-get-all-psis*)
(json-commit-url *json-commit-url*)
(json-get-summary-url *json-get-summary-url*)
+ (json-get-all-type-psis *json-get-all-type-psis*)
+ (json-get-topic-stub-prefix *json-get-topic-stub-prefix*)
+ (json-get-type-tmcl-prefix *json-get-type-tmcl-prefix*)
+ (json-get-instance-tmcl-prefix *json-get-instance-tmcl-prefix*)
(ajax-user-interface-url *ajax-user-interface-url*)
(ajax-user-interface-file-path *ajax-user-interface-file-path*)
(ajax-user-interface-css-prefix *ajax-user-interface-css-prefix*)
@@ -71,16 +78,103 @@
(create-regex-dispatcher json-get-prefix #'return-json-fragment)
hunchentoot:*dispatch-table*)
(push
+ (create-regex-dispatcher json-get-topic-stub-prefix #'return-topic-stub-of-psi)
+ hunchentoot:*dispatch-table*)
+ (push
+ (create-regex-dispatcher json-get-all-type-psis #'return-all-tmcl-types)
+ hunchentoot:*dispatch-table*)
+ (push
+ (create-regex-dispatcher json-get-type-tmcl-prefix #'(lambda(&optional psi)
+ (return-tmcl-info-of-psi 'json-tmcl::type psi)))
+ hunchentoot:*dispatch-table*)
+ (push
+ (create-regex-dispatcher json-get-instance-tmcl-prefix #'(lambda(&optional psi)
+ (return-tmcl-info-of-psi 'json-tmcl::instance psi)))
+ hunchentoot:*dispatch-table*)
+ (push
(create-regex-dispatcher json-commit-url #'json-commit)
hunchentoot:*dispatch-table*)
(push
(create-regex-dispatcher json-get-summary-url #'return-topic-summaries)
hunchentoot:*dispatch-table*))
-
;; =============================================================================
;; --- some handlers for the json-rest-interface -------------------------------
;; =============================================================================
+(defun return-all-tmcl-types(&optional param)
+ (declare (ignorable param))
+ (handler-case (let ((all-topics
+ (elephant:get-instances-by-class 'd:TopicC))
+ (topictype (get-item-by-psi json-tmcl-constants::*topictype-psi*))
+ (topictype-constraint (get-item-by-psi json-tmcl-constants::*topictype-constraint-psi*)))
+ (let ((all-types
+ (remove-if #'null
+ (map 'list #'(lambda(x)
+ (handler-case (progn
+ (json-tmcl::topictype-p x topictype topictype-constraint)
+ x)
+ (condition () nil))) all-topics))))
+ (let ((not-abstract-types
+ (remove-if #'null
+ (map 'list #'(lambda(x)
+ (unless (json-tmcl:abstract-p x)
+ x))
+ all-types))))
+ (setf (hunchentoot:content-type*) "application/json") ;RFC 4627
+ (json:encode-json-to-string
+ (map 'list #'(lambda(y)
+ (map 'list #'uri y))
+ (map 'list #'psis not-abstract-types))))))
+ (condition (err) (progn
+ (setf (hunchentoot:return-code*) hunchentoot:+http-internal-server-error+)
+ (setf (hunchentoot:content-type*) "text")
+ (format nil "Condition: \"~a\"" err)))))
+
+(defun return-topic-stub-of-psi(&optional psi)
+ "Returns a json string of a topic depending on the
+ passed psi as a topic-stub-construct."
+ (assert psi)
+ (let ((topic (d:get-item-by-psi psi)))
+ (if topic
+ (let ((topic-json
+ (handler-case (json-exporter::to-json-topicStub-string topic)
+ (condition (err) (progn
+ (setf (hunchentoot:return-code*) hunchentoot:+http-internal-server-error+)
+ (setf (hunchentoot:content-type*) "text")
+ (format nil "Condition: \"~a\"" err))))))
+ (setf (hunchentoot:content-type*) "application/json") ;RFC 4627
+ topic-json)
+ (progn
+ (setf (hunchentoot:return-code*) hunchentoot:+http-not-found+)
+ (setf (hunchentoot:content-type*) "text")
+ (format nil "Condition: Topic \"~a\" not found" psi)))))
+
+
+(defun return-tmcl-info-of-psi(treat-as &optional psi)
+ "Returns a json string which represents the defined tmcl-constraints of the
+ topic and the associations where this topic can be a player."
+ (assert 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." psi))))
+ (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
of psis and the entire list contains a list of topics"
@@ -102,14 +196,7 @@
(assert psi)
(let ((http-method (hunchentoot:request-method*)))
(if (eq http-method :GET)
- (let ((identifier (let ((pos (search "%23" psi)))
- (if pos
- (let ((str-1 (subseq psi 0 pos))
- (str-2 (if (> (length psi) (+ pos 3))
- (subseq psi (+ pos 3))
- "")))
- (concatenate 'string str-1 "#" str-2))
- psi))))
+ (let ((identifier (string-replace psi "%23" "#")))
(setf (hunchentoot:content-type*) "application/json") ;RFC 4627
(let ((fragment
(get-latest-fragment-of-topic identifier)))
@@ -120,7 +207,10 @@
(setf (hunchentoot:return-code*) hunchentoot:+http-internal-server-error+)
(setf (hunchentoot:content-type*) "text")
(format nil "Condition: \"~a\"" err))))
- "{}")))
+ (progn
+ (setf (hunchentoot:return-code*) hunchentoot:+http-not-found+)
+ (setf (hunchentoot:content-type*) "text")
+ (format nil "Topic \"~a\" not found" psi)))))
(setf (hunchentoot:return-code*) hunchentoot:+http-bad-request+))))
@@ -201,4 +291,27 @@
(concatenate 'string url-prefix
(subseq current-path-string start-position-of-relative-path last-position-of-current-path))))
(push (list :path current-path :url current-url) files-and-urls))))))
- files-and-urls)))
\ No newline at end of file
+ files-and-urls)))
+
+
+(defun string-replace (str search-str replace-str)
+ "replaces all sub-strings in str of the form search-str with
+ the string replace-str and returns the new generated string"
+ (if (= (length search-str) 0)
+ str
+ (progn
+ (let ((ret-str "")
+ (idx 0))
+ (loop
+ (if (string= str search-str
+ :start1 idx
+ :end1 (min (length str)
+ (+ idx (length search-str))))
+ (progn
+ (setf ret-str (concatenate 'string ret-str replace-str))
+ (incf idx (length search-str)))
+ (progn
+ (setf ret-str (concatenate 'string ret-str (subseq str idx (1+ idx))))
+ (incf idx)))
+ (unless (< idx (length str))
+ (return ret-str)))))))
\ No newline at end of file
Added: trunk/src/unit_tests/poems.xtm
==============================================================================
--- (empty file)
+++ trunk/src/unit_tests/poems.xtm Mon May 4 11:02:44 2009
@@ -0,0 +1,1857 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tm:topicMap version="2.0" xmlns:tm="http://www.topicmaps.org/xtm/">
+
+ <!-- === association-test ================================================ -->
+ <tm:topic id="test-scope-1">
+ <tm:subjectIdentifier href="test-scope-1"/>
+ <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="test-scope-2">
+ <tm:subjectIdentifier href="test-scope-2"/>
+ <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="written-by-test-scope-constraint">
+ <tm:subjectIdentifier href="written-by-test-scope-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#associationtypescope-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#written-by-test-scope-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#associationtype-role"/>
+ </tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#written-by-test-scope-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#scopetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#test-scope-1"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#written-by-test-scope-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#scopetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#test-scope-2"/>
+ </tm:role>
+ </tm:association>
+ <!-- === end association-test ============================================ -->
+
+
+ <!-- ===================================================================== -->
+ <!-- === TMCL meta-model topics ========================================== -->
+ <!-- ===================================================================== -->
+ <tm:topic id="topictype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-type"/> <!-- naming of psis: Prague, March 25-27, 2008, page 12 -->
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="occurrencetype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="associationtype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="roletype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-type"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="nametype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="scopetype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/scope-type"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- role types used to include the topictype metatypes in associations -->
+ <tm:topic id="topictype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="occurrencetype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="associationtype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="roletype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="otherroletype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/other-role-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="othertopictype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/other-topic-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="nametype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="scopetype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/scope-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- the constraint roletype -->
+ <tm:topic id="constraint-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/constraint-role"/>
+ <tm:instanceOf><tm:topicref href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- ===================================================================== -->
+ <!-- === TMCL model topics =============================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- the constraint topic is the common supertype of all constraint types
+ defined by TMCL. -->
+ <tm:topic id="constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- this occurrence type is used to type a single occurrence on each
+ constraint type. This occurrence holds the TMQL value used to
+ evaluate constraint instances for validity. -->
+ <tm:topic id="validation-expression">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/validation-expression"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- the association type used to bind different components into a
+ constraint -->
+ <tm:topic id="applies-to">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/applies-to"/>
+ <tm:instanceOf><tm:topicRef href="#associationtype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- the card min facet is used on many constraint types -->
+ <tm:topic id="card-min">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/card-min"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- the card max facet is used on many constraint types -->
+ <tm:topic id="card-max">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/card-max"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- the reg exp facet is used on many constraint types -->
+ <tm:topic id="regexp">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/reg-exp"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- the datatype facet is used on many constraint types -->
+ <tm:topic id="datatype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/datatype"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- ===================================================================== -->
+ <!-- === topics for super-subtype-associations (ako) ===================== -->
+ <!-- ===================================================================== -->
+
+ <tm:topic id="supertype-subtype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/iso13250/model/supertype-subtype"/>
+ </tm:topic>
+
+ <tm:topic id="supertype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/iso13250/model/supertype"/>
+ </tm:topic>
+
+ <tm:topic id="subtype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/iso13250/model/subtype"/>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === schema type and ?schema definitions ============================= -->
+ <!-- ===================================================================== -->
+
+ <!-- constraints can be bound to a schema -->
+ <tm:topic id="schema">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/schema"/>
+ <tm:instanceOf><tm:topicref href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === TMCL constraint types =========================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- topictype-constraint -->
+ <tm:topic id="topictype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-type-constraint"/>
+ </tm:topic> <!-- standard constraints doesn't own a valiadtion-expression-occurrence: Prague, March 25-27, 2008, page 34-36 -->
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#topictype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- associationtype-constraint -->
+ <tm:topic id="associationtype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#associationtype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- roletype-constraint -->
+ <tm:topic id="roletype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#roletype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- occurrencetype-constraint -->
+ <tm:topic id="occurrencetype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#occurrencetype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- nametype-constraint -->
+ <tm:topic id="nametype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#nametype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- abstract-topictype-constraint -->
+ <tm:topic id="abstract-topictype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/abstract-topic-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#abstract-topictype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- exclusive-instance -->
+ <tm:topic id="exclusive-instance">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/exclusive-instance"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#exclusive-instance"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === subjectidentifier/locator constraints =========================== -->
+ <!-- ===================================================================== -->
+
+ <!-- subjectlocator-constraint -->
+ <tm:topic id="subjectlocator-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/subject-locator-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#subjectlocator-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- subjectidentifier-constraint -->
+ <tm:topic id="subjectidentifier-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/subject-identifier-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#subjectidentifier-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === names/occurrences/associations/association roles ================ -->
+ <!-- ===================================================================== -->
+
+ <!-- topicname-constraint -->
+ <tm:topic id="topicname-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-name-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#topicname-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- topicoccurrence-constraint -->
+ <tm:topic id="topicoccurrence-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-occurrence-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- occurrencedatatype-constraint -->
+ <tm:topic id="occurrencedatatype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-datatype-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#occurrencedatatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- uniqueoccurrence-constraint -->
+ <tm:topic id="uniqueoccurrence-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/unique-occurrence-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#uniqueoccurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- associationrole-constraint -->
+ <tm:topic id="associationrole-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-role-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#associationrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- roleplayer-constraint -->
+ <tm:topic id="roleplayer-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-player-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#roleplayer-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- otherrole-constraint -->
+ <tm:topic id="otherrole-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/other-role-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === scopes ========================================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- nametypescope-constraint -->
+ <tm:topic id="nametypescope-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type-scope-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#nametypescope-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- occurrencetypescope-constraint -->
+ <tm:topic id="occurrencetypescope-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type-scope-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#occurrencetypescope-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- associationtypescope-constraint -->
+ <tm:topic id="associationtypescope-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type-scope-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#associationtypescope-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: type handling ==================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- only topics that are instances of topictype are allowed as topic
+ types -->
+ <tm:topic id="ttc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/ttc"/>
+ <tm:instanceOf><tm:topicRef href="#topictype-constraint"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- only topics that are instances of associationtype are allowed as
+ association types -->
+ <tm:topic id="atc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/atc"/>
+ <tm:instanceOf><tm:topicRef href="#associationtype-constraint"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- only topics that are instances of roletype are allowed as
+ association role types -->
+ <tm:topic id="rtc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/rtc"/>
+ <tm:instanceOf><tm:topicRef href="#roletype-constraint"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- only topics that are instances of occurrencetype are allowed as
+ occurrence types -->
+ <tm:topic id="otc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/otc"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype-constraint"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- only topics that are instances of nametype are allowed as
+ name types -->
+ <tm:topic id="ntc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/ntc"/>
+ <tm:instanceOf><tm:topicRef href="#nametype-constraint"/></tm:instanceOf>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: base types ======================================= -->
+ <!-- ===================================================================== -->
+
+ <!-- author -->
+ <tm:topic id="author">
+ <tm:subjectIdentifier href="http://some.where/base-psis/author"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="first-name">
+ <tm:subjectIdentifier href="http://some.where/base-psis/first-name"/>
+ <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="last-name">
+ <tm:subjectIdentifier href="http://some.where/base-psis/last-name"/>
+ <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="author-info">
+ <tm:subjectIdentifier href="http://some.where/base-psis/author-info"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- poem -->
+ <tm:topic id="poem">
+ <tm:subjectIdentifier href="http://some.where/base-psis/poem"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="title">
+ <tm:subjectIdentifier href="http://some.where/base-psis/title"/>
+ <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="poem-content">
+ <tm:subjectIdentifier href="http://some.where/base-psis/poem-content"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- poem scopes -->
+ <tm:topic id="de">
+ <tm:subjectIdentifier href="http://some.where/base-psis/de"/>
+ <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="en">
+ <tm:subjectIdentifier href="http://some.where/base-psis/en"/>
+ <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- association author-poem -->
+ <tm:topic id="written-by">
+ <tm:subjectIdentifier href="http://some.where/base-psis/written-by"/>
+ <tm:instanceOf><tm:topicRef href="#associationtype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="writer">
+ <tm:subjectIdentifier href="http://some.where/base-psis/writer"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="written">
+ <tm:subjectIdentifier href="http://some.where/base-psis/written"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: exclusive type constraint ======================== -->
+ <!-- ===================================================================== -->
+ <!-- same instances of the type author and title are not allowed -->
+ <tm:topic id="exc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/exc"/>
+ <tm:instanceOf><tm:topicRef href="#exclusive-instance"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#exc"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#exc"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: subjectIdentifier constraints ==================== -->
+ <!-- ===================================================================== -->
+ <!-- a topic of the type author has to have a psi of the form
+ "^http://some.where/psis/author/.+$"
+ and a topic of the type poem has to have a psi of the form
+ "^http://some.where/psis/poem/.+$".
+ further all topics can have mor psis of the form "^.+$" -->
+
+ <!-- subjectidentifier of author -->
+ <tm:topic id="sic-author">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/sic-author"/>
+ <tm:instanceOf><tm:topicRef href="#subjectidentifier-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://some.where/psis/author/.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#sic-author"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- subjectidentifier of poem -->
+ <tm:topic id="sic-poem">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/sic-poem"/>
+ <tm:instanceOf><tm:topicRef href="#subjectidentifier-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://some.where/psis/poem/.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#sic-poem"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- further subjectidentifiers of author and poem -->
+ <tm:topic id="sic-author-poem">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/sic-author-poem"/>
+ <tm:instanceOf><tm:topicRef href="#subjectidentifier-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">MAX_INT</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#sic-author-poem"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#sic-author-poem"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: subjectIdentifier constraints ==================== -->
+ <!-- ===================================================================== -->
+ <!-- all instances of author and poem are not allowed to own a
+ subjectLocator -->
+
+ <tm:topic id="slc-author-poem">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/slc-author-poem"/>
+ <tm:instanceOf><tm:topicRef href="#subjectlocator-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.*$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#slc-author-poem"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#slc-author-poem"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: names constraints ================================ -->
+ <!-- ===================================================================== -->
+ <!-- instances of the type author has to own a name of the type first-name
+ and one of the type last-name. both must be valid to the regular
+ expression "^.+$".
+ instances of the type poem has exactly one name of the type title
+ with the regular expression "^.+$" -->
+
+ <!-- author first name -->
+ <tm:topic id="author-first-name-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/author-first-name-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#author-first-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#author-first-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#nametype-role"/></tm:type>
+ <tm:topicRef href="#first-name"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- author last name -->
+ <tm:topic id="author-last-name-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/author-last-name-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#author-last-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#author-last-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#nametype-role"/></tm:type>
+ <tm:topicRef href="#last-name"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- poem title name -->
+ <tm:topic id="poem-title-name-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/poem-title-name-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#poem-title-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#poem-title-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#nametype-role"/></tm:type>
+ <tm:topicRef href="#title"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: occurences constraints =========================== -->
+ <!-- ===================================================================== -->
+ <!-- every instance of the topic author can have one occurrence of the type
+ author-info which contains a resourceRef (= datatype #anyURI) -->
+
+ <!-- author info occurrence -->
+ <tm:topic id="author-occurrence-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/author-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#author-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#author-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#author-info"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- author info occurrence datatype -->
+ <tm:topic id="author-info-occurrence-datatype-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/author-poem-occurrence-datatype-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencedatatype-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#datatype"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#anyURI</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#author-info-occurrence-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#author-info"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- all instances of the type poem has to have exactly one occurrence
+ of the type poem-content with the datatype string and the either
+ the scope en or de-->
+ <tm:topic id="poem-occurrence-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/poem-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#poem-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#poem-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#poem-content"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- poem content-occurrence datatype -->
+ <tm:topic id="poem-content-occurrence-datatype-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/poem-content-occurrence-datatype-constrai…"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencedatatype-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#datatype"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#string</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#poem-content-occurrence-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#poem-content"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- the poem-content-occurrence can only appear once per topictype,
+ so all topic with this occurrence type must have different
+ occurrence-values -->
+ <tm:topic id="unique-poem-occurrence-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/unique-poem-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#uniqueoccurrence-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.*$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#unique-poem-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#unique-poem-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#poem-content"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- add a scope to the occurrence "poem-content" -->
+ <tm:topic id="scoped-poem-occurrence-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/scoped-poem-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetypescope-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">2</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-poem-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#poem-content"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-poem-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+ <tm:topicRef href="#en"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#scoped-poem-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+ <tm:topicRef href="#de"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: association (-role) constraints ================== -->
+ <!-- ===================================================================== -->
+ <!-- there exists one asoociation of the type written-by between the types
+ author and poem. where one role is of type writer which has a player
+ of type author and another role of type written which owns a player of
+ type poem -->
+
+ <!-- the writer role has to appear exactly once in an association of type
+ written-by -->
+ <tm:topic id="writer-role-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/writer-role-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#associationrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#writer-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#writer-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#writer"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- the writer role owns a player of the type author -->
+ <tm:topic id="writer-role-player-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/writer-role-player-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#roleplayer-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#writer-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#writer-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#writer-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#writer"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- the written role has to appear exactly once in an association of type
+ written-by -->
+ <tm:topic id="written-role-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/written-role-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#associationrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#written"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- the written role owns a player of the type poem -->
+ <tm:topic id="written-role-player-constraint">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/written-role-player-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#roleplayer-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#written"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- otherrole-constraint:
+ If there is a role of the type written with a player of the type poem
+ there must be another role of the type writer with a player of the
+ type author.
+ In contrast if there is a role of the type writer with a player of the
+ type author there must be a role of the type written with a player of
+ the type poem.
+ So for this case there are two otherrole-constraints which handle this
+ both cases. -->
+
+ <tm:topic id="written-by-otherrole-constraint-for-writer">
+ <tm:subjectIdentifier href="written-by-otherrole-constraint-for-writer"/>
+ <tm:instanceOf><tm:topicRef href="#otherrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#writer"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#otherroletype-role"/></tm:type>
+ <tm:topicRef href="#written"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#othertopictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:topic id="written-by-otherrole-constraint-for-written">
+ <tm:subjectIdentifier href="written-by-otherrole-constraint-for-written"/>
+ <tm:instanceOf><tm:topicRef href="#otherrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#written-by"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#written"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#poem"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#otherroletype-role"/></tm:type>
+ <tm:topicRef href="#writer"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#othertopictype-role"/></tm:type>
+ <tm:topicRef href="#author"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === the "user's" topic map ========================================== -->
+ <!-- ===================================================================== -->
+ <tm:topic id="goethe">
+ <tm:subjectIdentifier href="http://some.where/psis/author/goethe"/> <!-- must have a psi of this form -->
+ <tm:subjectIdentifier href="http://some.where/psis/persons/goethe"/> <!-- can own psis of any form -->
+ <tm:instanceOf><tm:topicRef href="#author"/></tm:instanceOf> <!-- must be an instanceOf author -->
+ <tm:name>
+ <tm:type><tm:topicRef href="#first-name"/></tm:type> <!-- must contain a name of the type first-name -->
+ <tm:value>Johann Wolfgang</tm:value>
+ </tm:name>
+ <tm:name>
+ <tm:type><tm:topicRef href="#last-name"/></tm:type> <!-- must contain a name of the type last-name -->
+ <tm:value>von Goethe</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#author-info"/></tm:type> <!-- can own an occurrence of the type autor-info with the datatype anyURI -->
+ <tm:resourceRef href="http://de.wikipedia.org/wiki/Johann_Wolfgang_von_Goethe"/>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="schiller">
+ <tm:subjectIdentifier href="http://some.where/psis/author/schiller"/> <!-- must have a psi of this form -->
+ <tm:instanceOf><tm:topicRef href="#author"/></tm:instanceOf> <!-- must be an instanceOf author -->
+ <tm:name>
+ <tm:type><tm:topicRef href="#first-name"/></tm:type> <!-- must contain a name of the type first-name -->
+ <tm:value>Johann Christoph Friedrich</tm:value>
+ </tm:name>
+ <tm:name>
+ <tm:type><tm:topicRef href="#last-name"/></tm:type> <!-- must contain a name of the type last-name -->
+ <tm:value>von Schiller</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#author-info"/></tm:type> <!-- can own an occurrence of the type autor-info with the datatype anyURI -->
+ <tm:resourceRef href="http://de.wikipedia.org/wiki/Schiller"/>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="zauberlehrling">
+ <tm:subjectIdentifier href="http://some.where/psis/poem/zauberlehrling"/> <!-- must have a psi of this form -->
+ <tm:subjectIdentifier href="http://some.where/psis/der_zauberlehrling"/> <!-- can own psis of any form -->
+ <tm:instanceOf>
+ <tm:topicRef href="#poem"/><!--
+ <tm:topicRef href="#author"/>
+ <tm:topicRef href="#zauberlehrling"/>
+ <tm:topicRef href="#topictype-constraint"/>-->
+ </tm:instanceOf> <!-- must be an instanceOf poem -->
+ <tm:name>
+ <tm:type><tm:topicRef href="#title"/></tm:type> <!-- must have a name of the type title -->
+ <tm:value>Der Zauberlehrling</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#poem-content"/></tm:type> <!-- must have an occurrence of the type poem-content with the scope de or en -->
+ <tm:scope><tm:topicRef href="#de"/></tm:scope>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">Hat der alte Hexenmeister
+sich doch einmal wegbegeben!
+Und nun sollen seine Geister
+auch nach meinem Willen leben.
+Seine Wort und Werke
+merkt ich und den Brauch,
+und mit Geistesstärke
+tu ich Wunder auch.
+
+Walle! walle
+Manche Strecke,
+daß, zum Zwecke,
+Wasser fließe
+und mit reichem, vollem Schwalle
+zu dem Bade sich ergieße.
+
+Und nun komm, du alter Besen!
+Nimm die schlechten Lumpenhüllen;
+bist schon lange Knecht gewesen:
+nun erfülle meinen Willen!
+Auf zwei Beinen stehe,
+oben sei ein Kopf,
+eile nun und gehe
+mit dem Wassertopf!
+
+Walle! walle
+manche Strecke,
+daß, zum Zwecke,
+Wasser fließe
+und mit reichem, vollem Schwalle
+zu dem Bade sich ergieße.
+
+Seht, er läuft zum Ufer nieder,
+Wahrlich! ist schon an dem Flusse,
+und mit Blitzesschnelle wieder
+ist er hier mit raschem Gusse.
+Schon zum zweiten Male!
+Wie das Becken schwillt!
+Wie sich jede Schale
+voll mit Wasser füllt!
+
+Stehe! stehe!
+denn wir haben
+deiner Gaben
+vollgemessen! -
+Ach, ich merk es! Wehe! wehe!
+Hab ich doch das Wort vergessen!
+
+Ach, das Wort, worauf am Ende
+er das wird, was er gewesen.
+Ach, er läuft und bringt behende!
+Wärst du doch der alte Besen!
+Immer neue Güsse
+bringt er schnell herein,
+Ach! und hundert Flüsse
+stürzen auf mich ein.
+
+Nein, nicht länger
+kann ichs lassen;
+will ihn fassen.
+Das ist Tücke!
+Ach! nun wird mir immer bänger!
+Welche Mine! welche Blicke!
+
+O du Ausgeburt der Hölle!
+Soll das ganze Haus ersaufen?
+Seh ich über jede Schwelle
+doch schon Wasserströme laufen.
+Ein verruchter Besen,
+der nicht hören will!
+Stock, der du gewesen,
+steh doch wieder still!
+
+Willst am Ende
+gar nicht lassen?
+Will dich fassen,
+will dich halten
+und das alte Holz behende
+mit dem scharfen Beile spalten.
+
+Seht da kommt er schleppend wieder!
+Wie ich mich nur auf dich werfe,
+gleich, o Kobold, liegst du nieder;
+krachend trifft die glatte Schärfe.
+Wahrlich, brav getroffen!
+Seht, er ist entzwei!
+Und nun kann ich hoffen,
+und ich atme frei!
+
+Wehe! wehe!
+Beide Teile
+stehn in Eile
+schon als Knechte
+völlig fertig in die Höhe!
+Helft mir, ach! ihr hohen Mächte!
+
+Und sie laufen! Naß und nässer
+wirds im Saal und auf den Stufen.
+Welch entsetzliches Gewässer!
+Herr und Meister! hör mich rufen! -
+Ach, da kommt der Meister!
+Herr, die Not ist groß!
+Die ich rief, die Geister
+werd ich nun nicht los.
+
+"In die Ecke,
+Besen, Besen!
+Seids gewesen.
+Denn als Geister
+ruft euch nur zu diesem Zwecke,
+erst hervor der alte Meister."</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="erlkoenig">
+ <tm:subjectIdentifier href="http://some.where/psis/poem/erlkoenig"/> <!-- must have a psi of this form -->
+ <tm:instanceOf><tm:topicRef href="#poem"/></tm:instanceOf> <!-- must be an instanceOf poem -->
+ <tm:name>
+ <tm:type><tm:topicRef href="#title"/></tm:type> <!-- must have a name of the type title -->
+ <tm:value>Der Erlkönig</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#poem-content"/></tm:type> <!-- must have an occurrence of the type poem-content with the scope de or en -->
+ <tm:scope><tm:topicRef href="#en"/></tm:scope>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">Who rides there so late through the night dark and drear?
+The father it is, with his infant so dear;
+He holdeth the boy tightly clasp'd in his arm,
+He holdeth him safely, he keepeth him warm.
+
+"My son, wherefore seek'st thou thy face thus to hide?"
+"Look, father, the Erl-King is close by our side!
+Dost see not the Erl-King, with crown and with train?"
+"My son, 'tis the mist rising over the plain."
+
+"Oh, come, thou dear infant! oh come thou with me!
+For many a game I will play there with thee;
+On my strand, lovely flowers their blossoms unfold,
+My mother shall grace thee with garments of gold."
+
+"My father, my father, and dost thou not hear
+The words that the Erl-King now breathes in mine ear?"
+"Be calm, dearest child, 'tis thy fancy deceives;
+'Tis the sad wind that sighs through the withering leaves."
+
+"Wilt go, then, dear infant, wilt go with me there?
+My daughters shall tend thee with sisterly care
+My daughters by night their glad festival keep,
+They'll dance thee, and rock thee, and sing thee to sleep."
+
+"My father, my father, and dost thou not see,
+How the Erl-King his daughters has brought here for me?"
+"My darling, my darling, I see it aright,
+'Tis the aged grey willows deceiving thy sight."
+
+"I love thee, I'm charm'd by thy beauty, dear boy!
+And if thou'rt unwilling, then force I'll employ."
+"My father, my father, he seizes me fast,
+For sorely the Erl-King has hurt me at last."
+
+The father now gallops, with terror half wild,
+He grasps in his arms the poor shuddering child;
+He reaches his courtyard with toil and with dread,--
+The child in his arms finds he motionless, dead.</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <!-- some assocaitions between goethe and some of his poems,
+ currently there are no associations between the topic schiller
+ and any other topic, because there are no topic representing
+ a poem of schiller -->
+ <tm:association>
+ <tm:type><tm:topicRef href="#written-by"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#writer"/></tm:type>
+ <tm:topicRef href="#goethe"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#written"/></tm:type>
+ <tm:topicRef href="#zauberlehrling"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#written-by"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#writer"/></tm:type>
+ <tm:topicRef href="#goethe"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#written"/></tm:type>
+ <tm:topicRef href="#erlkoenig"/>
+ </tm:role>
+ </tm:association>
+
+</tm:topicMap>
1
0