annotate examples/browser/web/js/jOWL.js @ 770:c54bc2ffbf92 tip

update tags
author convert-repo
date Fri, 16 Dec 2011 11:34:01 +0000
parents 901803e1305f
children
rev   line source
mas01mj@640 1 /**
mas01mj@640 2 * jOWL - a jQuery plugin for traversing and visualizing OWL-DL documents.
mas01mj@640 3 * Creator - David Decraene
mas01mj@640 4 * Version 1.0
mas01mj@640 5 * Website:
mas01mj@640 6 * http://Ontologyonline.org
mas01mj@640 7 * Licensed under the MIT license
mas01mj@640 8 * http://www.opensource.org/licenses/mit-license.php
mas01mj@640 9 * Verified with JSLint
mas01mj@640 10 * http://www.jslint.com/
mas01mj@640 11 */
mas01mj@640 12
mas01mj@640 13 jOWL = window.jOWL = function( resource, options ){ return jOWL.getResource( resource, options ); };
mas01mj@640 14 jOWL.version = "1.0";
mas01mj@640 15
mas01mj@640 16 /** for debugging compatibility */
mas01mj@640 17 try { console.log('...'); } catch(e) { console = window.console = { log: function() {} } }
mas01mj@640 18 if ($.browser.opera && opera.postError) { console = window.console = { log : function(){opera.postError(arguments); } }; }
mas01mj@640 19
mas01mj@640 20
mas01mj@640 21
mas01mj@640 22 (function($){
mas01mj@640 23
mas01mj@640 24 /**
mas01mj@640 25 * if no param: @return string of main namespaces
mas01mj@640 26 * if 1 param: assume a documentElement, parse namespaces
mas01mj@640 27 * if prefix & URI: Bind prefix to namespace URI
mas01mj@640 28 */
mas01mj@640 29 jOWL.NS = function(prefix, URI){
mas01mj@640 30 if(!arguments.length)
mas01mj@640 31 { return "xmlns:"+jOWL.NS.owl.prefix+"='"+jOWL.NS.owl()+"' xmlns:"+jOWL.NS.rdf.prefix+"='"+jOWL.NS.rdf()+"' xmlns:"+jOWL.NS.rdfs.prefix+"='"+jOWL.NS.rdfs()+"' xmlns:"+jOWL.NS.xsd.prefix+" ='"+jOWL.NS.xsd()+"'";}
mas01mj@640 32
mas01mj@640 33 if(arguments.length == 1){
mas01mj@640 34 var attr = prefix.get(0).attributes;
mas01mj@640 35 for(var i=0;i<attr.length;i++){
mas01mj@640 36 var nn = attr[i].nodeName.split(':');
mas01mj@640 37 if(nn.length == 2){
mas01mj@640 38 if(attr[i].nodeValue == jOWL.NS.owl.URI){ jOWL.NS.owl.prefix = nn[1];}
mas01mj@640 39 else if(attr[i].nodeValue == jOWL.NS.rdf.URI){ jOWL.NS.rdf.prefix = nn[1];}
mas01mj@640 40 else if(attr[i].nodeValue == jOWL.NS.rdfs.URI){ jOWL.NS.rdfs.prefix = nn[1];}
mas01mj@640 41 else if(attr[i].nodeValue == jOWL.NS.xsd.URI){ jOWL.NS.xsd.prefix = nn[1];}
mas01mj@640 42 else { jOWL.NS(nn[1], attr[i].nodeValue);}
mas01mj@640 43 }
mas01mj@640 44 }
mas01mj@640 45 jOWL.namespace = prefix.xmlAttr('xml:base') || prefix.xmlAttr('xmlns');
mas01mj@640 46 return;
mas01mj@640 47 }
mas01mj@640 48 jOWL.NS[prefix] = function(element){
mas01mj@640 49 if(element){
mas01mj@640 50 return (arguments.callee.prefix == 'base') ? element : arguments.callee.prefix + ":" + element;
mas01mj@640 51 }
mas01mj@640 52 return arguments.callee.URI;
mas01mj@640 53 };
mas01mj@640 54 jOWL.NS[prefix].prefix = prefix;
mas01mj@640 55 jOWL.NS[prefix].URI = URI;
mas01mj@640 56 };
mas01mj@640 57
mas01mj@640 58 var __ = jOWL.NS;
mas01mj@640 59
mas01mj@640 60 /** set Main namespaces */
mas01mj@640 61 __("owl", "http://www.w3.org/2002/07/owl#");
mas01mj@640 62 __("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
mas01mj@640 63 __("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
mas01mj@640 64 __("xsd", "http://www.w3.org/2001/XMLSchema#");
mas01mj@640 65
mas01mj@640 66 /** jQuery function additions for easy parsing of identities */
mas01mj@640 67 $.fn.extend({
mas01mj@640 68 /** Used for Opera compatibility when parsing xml attributes, nodeName must be checked, in contrast to native jquery call attr() */
mas01mj@640 69 xmlAttr : function(nodeName){
mas01mj@640 70 var t = this[0].attributes; if(!t){ return;}
mas01mj@640 71 for(var i =0;i<t.length;i++){
mas01mj@640 72 if(t[i].nodeName == nodeName){ return t[i].nodeValue;}
mas01mj@640 73 }
mas01mj@640 74 },
mas01mj@640 75 RDF_ID : function(match){
mas01mj@640 76 var res = this.xmlAttr(__.rdf('ID'));
mas01mj@640 77 if(!res){ return false;}
mas01mj@640 78 res = jOWL.resolveURI(res);
mas01mj@640 79 if(match){
mas01mj@640 80 return res.toLowerCase() == (jOWL.resolveURI(match.toString())).toLowerCase();}
mas01mj@640 81 return res;
mas01mj@640 82 },
mas01mj@640 83 RDF_Resource : function(match){
mas01mj@640 84 function getClassName(dom){
mas01mj@640 85 var cl = jOWL.Xpath(__.owl("Class"), dom);
mas01mj@640 86 if(cl.length == 1){ return new jOWL.Ontology.Class(cl).URI;}
mas01mj@640 87 return false;
mas01mj@640 88 }
mas01mj@640 89 if(!this.length){ return false;}
mas01mj@640 90 var rsrc = this.xmlAttr(__.rdf('resource'));
mas01mj@640 91 if(!rsrc){
mas01mj@640 92 var dom = this.get(0);
mas01mj@640 93 switch(dom.nodeName){
mas01mj@640 94 case __.rdfs("subClassOf"): rsrc = getClassName(dom); break;
mas01mj@640 95 case __.owl("disjointWith"): rsrc = getClassName(dom); break;
mas01mj@640 96 case __.owl("allValuesFrom"): rsrc = getClassName(dom); break;
mas01mj@640 97 case __.owl("someValuesFrom"): rsrc = getClassName(dom); break;
mas01mj@640 98 case __.owl("onProperty"):
mas01mj@640 99 var t = jOWL.Xpath(__.owl("ObjectProperty"), dom);
mas01mj@640 100 if(t.length === 0){ t = jOWL.Xpath(__.owl("DatatypeProperty"), dom);}
mas01mj@640 101 if(t.length === 0){ t = jOWL.Xpath(__.owl("FunctionalProperty"), dom);}
mas01mj@640 102 rsrc = t.xmlAttr(__.rdf('about')); break;
mas01mj@640 103 default: return false;
mas01mj@640 104 }
mas01mj@640 105 }
mas01mj@640 106 if(!rsrc){ return false;}
mas01mj@640 107 rsrc = jOWL.resolveURI(rsrc);
mas01mj@640 108 if(match){ return rsrc.toLowerCase() == (jOWL.resolveURI(match.toString())).toLowerCase();}
mas01mj@640 109 return rsrc;
mas01mj@640 110 },
mas01mj@640 111 RDF_About : function(match){
mas01mj@640 112 var res = this.xmlAttr(__.rdf('about'));
mas01mj@640 113 if(!res){ return false;}
mas01mj@640 114 res = jOWL.resolveURI(res);
mas01mj@640 115 if(match){
mas01mj@640 116 return res.toLowerCase() == (jOWL.resolveURI(match.toString())).toLowerCase();}
mas01mj@640 117 return res;
mas01mj@640 118 }
mas01mj@640 119 });
mas01mj@640 120
mas01mj@640 121 /** Check XPath implementation */
mas01mj@640 122 if( document.implementation.hasFeature("XPath", "3.0") ){
mas01mj@640 123 XMLDocument.prototype.selectNodes = function(cXPathString, xNode){
mas01mj@640 124 if( !xNode ){ xNode = this;}
mas01mj@640 125 var oNSResolver = this.createNSResolver(this.documentElement);
mas01mj@640 126 var aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); var aResult = []; for( var i = 0; i < aItems.snapshotLength; i++){ aResult[i] = aItems.snapshotItem(i);}
mas01mj@640 127 return aResult;
mas01mj@640 128 };
mas01mj@640 129 Element.prototype.selectNodes = function(cXPathString){
mas01mj@640 130 if(this.ownerDocument.selectNodes) { return this.ownerDocument.selectNodes(cXPathString, this);}
mas01mj@640 131 else{throw "For XML Elements Only";}
mas01mj@640 132 };
mas01mj@640 133 XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode){ if( !xNode ){ xNode = this;}
mas01mj@640 134 var xItems = this.selectNodes(cXPathString, xNode); if( xItems.length > 0 ){ return xItems[0];} else { return null;}
mas01mj@640 135 };
mas01mj@640 136 Element.prototype.selectSingleNode = function(cXPathString){
mas01mj@640 137 if(this.ownerDocument.selectSingleNode) { return this.ownerDocument.selectSingleNode(cXPathString, this);}
mas01mj@640 138 else{throw "For XML Elements Only";}
mas01mj@640 139 };
mas01mj@640 140 }
mas01mj@640 141
mas01mj@640 142 /** @return A jQuery array of xml elements */
mas01mj@640 143 jOWL.Xpath = function(selector, elem){
mas01mj@640 144 var node = null;
mas01mj@640 145 if(elem){ if(elem.each){ node = elem.get(0);} else { node = elem;} }
mas01mj@640 146 var arr = node ? node.selectNodes(selector) : jOWL.document.selectNodes(selector);
mas01mj@640 147 if($.browser.msie){ return $($.makeArray(arr));} return $(arr); //this is needed for IE, it returns a length of 1 on empty node array
mas01mj@640 148 };
mas01mj@640 149
mas01mj@640 150 /** @return a String array of class references */
mas01mj@640 151 jOWL.Xpath.classes = function(jnode){
mas01mj@640 152 var cl = [];
mas01mj@640 153 jOWL.Xpath(__.rdfs("subClassOf"), jnode)
mas01mj@640 154 .each(function(){
mas01mj@640 155 var res = $(this).RDF_Resource();
mas01mj@640 156 if(res){ cl.push(res);}
mas01mj@640 157 });
mas01mj@640 158
mas01mj@640 159 jOWL.Xpath(__.owl("intersectionOf")+"/"+__.owl("Class"), jnode)
mas01mj@640 160 .each(function(){
mas01mj@640 161 var p = $(this).RDF_About(); if(p){ cl.push(p);}
mas01mj@640 162 });
mas01mj@640 163 return cl;
mas01mj@640 164 };
mas01mj@640 165
mas01mj@640 166 /** Functions stored in jOWL.priv are intended for local access only, to avoid a closure function */
mas01mj@640 167 jOWL.priv = {
mas01mj@640 168 /** Arrray functions */
mas01mj@640 169 Array : {
mas01mj@640 170 isArray : function(array){
mas01mj@640 171 return Object.prototype.toString.call(array) === '[object Array]';
mas01mj@640 172 },
mas01mj@640 173 pushUnique : function(array, item){
mas01mj@640 174 if(jOWL.priv.Array.getIndex(array, item) === -1){ array.push(item); return true;}
mas01mj@640 175 return false;
mas01mj@640 176 },
mas01mj@640 177 getIndex : function(array, item){
mas01mj@640 178 for (var i=0; i<array.length; i++){ if(item == array[i]){ return i;} }
mas01mj@640 179 return -1;
mas01mj@640 180 },
mas01mj@640 181 /** Sorted array as input, returns the same array without duplicates. */
mas01mj@640 182 unique : function(array){
mas01mj@640 183 var result = []; var lastValue="";
mas01mj@640 184 for (var i=0; i<array.length; i++)
mas01mj@640 185 {
mas01mj@640 186 var curValue=array[i];
mas01mj@640 187 if(curValue != lastValue){ result[result.length] = curValue;}
mas01mj@640 188 lastValue=curValue;
mas01mj@640 189 }
mas01mj@640 190 return result;
mas01mj@640 191 }
mas01mj@640 192 }
mas01mj@640 193 };
mas01mj@640 194
mas01mj@640 195 /** Make values work with jOWL.Ontology.Array */
mas01mj@640 196 jOWL.Literal = function(value){
mas01mj@640 197 this.name = value;
mas01mj@640 198 };
mas01mj@640 199
mas01mj@640 200 /** Access to the owl:Ontology element, also the main coding namespace for ontology objects */
mas01mj@640 201 jOWL.Ontology = function(){
mas01mj@640 202 if(!(this instanceof arguments.callee)){ return new jOWL.Ontology();}
mas01mj@640 203 this.parse(jOWL.Xpath("/"+__.rdf("RDF")+"/"+__.owl("Ontology")));
mas01mj@640 204 return this;
mas01mj@640 205 };
mas01mj@640 206
mas01mj@640 207 /** 'superclass' for referencable ontology objects */
mas01mj@640 208 jOWL.Ontology.Thing = function(jnode){
mas01mj@640 209 this.parse(jnode);
mas01mj@640 210 };
mas01mj@640 211
mas01mj@640 212 jOWL.Ontology.Thing.prototype = {
mas01mj@640 213 jOWL : jOWL.version,
mas01mj@640 214 equals : function(id){
mas01mj@640 215 var URI = (typeof id == "string") ? jOWL.resolveURI(id) : id.URI;
mas01mj@640 216 return URI === this.URI;
mas01mj@640 217 },
mas01mj@640 218 /** Initialization */
mas01mj@640 219 parse : function(jnode){
mas01mj@640 220 if(!jnode.length){ return;}
mas01mj@640 221 var identifier;
mas01mj@640 222 if(typeof jnode == 'string'){
mas01mj@640 223 identifier = jnode;
mas01mj@640 224 jnode = $();
mas01mj@640 225 }
mas01mj@640 226 else {
mas01mj@640 227 identifier = jnode.RDF_ID() || jnode.RDF_About();
mas01mj@640 228 if(!identifier){identifier = "anonymousOntologyObject";
mas01mj@640 229 this.isAnonymous = true;
mas01mj@640 230 }
mas01mj@640 231 }
mas01mj@640 232 identifier = jOWL.resolveURI(identifier);
mas01mj@640 233 this.isExternal = jOWL.isExternal(identifier);
mas01mj@640 234 if(this.isExternal){this.baseURI = this.isExternal[0]; this.name = this.isExternal[1]; this.URI = this.baseURI+this.name;}
mas01mj@640 235 else { this.baseURI = jOWL.namespace; this.name = identifier; this.URI = this.name;}
mas01mj@640 236 this.jnode = jnode;
mas01mj@640 237 this.type = jnode.get(0).nodeName;
mas01mj@640 238 },
mas01mj@640 239 /** @return A jQuery array of elements matching the annotation (qualified name or annotation Property) */
mas01mj@640 240 annotations : function(annotation){
mas01mj@640 241 return jOWL.Xpath(annotation, this.jnode);
mas01mj@640 242 },
mas01mj@640 243 /** @return rdfs:comment annotations */
mas01mj@640 244 description : function(){
mas01mj@640 245 return $.map(this.annotations(__.rdfs('comment')), function(n){ return $(n).text();});
mas01mj@640 246 },
mas01mj@640 247 /**
mas01mj@640 248 @return Array of Arrays, where secondary array is of form: [0] = term (rdfs:label) , [1] = identifier, [2] = language; [3] = type of object
mas01mj@640 249 example:
mas01mj@640 250 [
mas01mj@640 251 ["bleu", "blue", "fr", "owl:Class"]
mas01mj@640 252 ]
mas01mj@640 253 */
mas01mj@640 254 terms : function(){
mas01mj@640 255 var terms = [], self = this;
mas01mj@640 256 if(jOWL.options.dictionary.addID && this.name != "anonymousOntologyObject"){ terms.push([this.name.beautify(), this.URI, jOWL.options.defaultlocale, this.type]);}
mas01mj@640 257 this.annotations(__.rdfs('label')).each(function(){
mas01mj@640 258 var lbl = $(this);
mas01mj@640 259 var locale = lbl.xmlAttr("xml:lang") || jOWL.options.defaultlocale;
mas01mj@640 260 var txt = lbl.text();
mas01mj@640 261 var match = false;
mas01mj@640 262 for(var i =0;i<terms.length;i++){
mas01mj@640 263 if(terms[i][0].toUpperCase() == txt.toUpperCase() && terms[i][2] == locale){ match = true;}
mas01mj@640 264 }
mas01mj@640 265 if(!match){ terms.push([lbl.text(), self.URI, locale, self.type]);}
mas01mj@640 266 });
mas01mj@640 267 return terms;
mas01mj@640 268 },
mas01mj@640 269 /** @return A representation name */
mas01mj@640 270 label : function(){
mas01mj@640 271 var label = false;
mas01mj@640 272 this.annotations(__.rdfs('label')).each(function(){
mas01mj@640 273 var $label = $(this);
mas01mj@640 274 if(jOWL.options.locale){
mas01mj@640 275 var lang = $label.xmlAttr('xml:lang') || jOWL.options.defaultlocale;
mas01mj@640 276 if(lang == jOWL.options.locale){ label = $label.text(); return false;}
mas01mj@640 277 } else { label = $label.text(); return false;}
mas01mj@640 278 });
mas01mj@640 279 if(label){ return label;}
mas01mj@640 280 if(this.name == "anonymousOntologyObject"){ return jOWL.Manchester(this) || "anonymous Object";}
mas01mj@640 281 if(jOWL.options.niceClassLabels && (this.isClass || this.isThing)){
mas01mj@640 282 return this.name.beautify();
mas01mj@640 283 }
mas01mj@640 284 return this.name;
mas01mj@640 285 },
mas01mj@640 286 /** Binds the Ontology element to the jQuery element for visual representation
mas01mj@640 287 * @return jQuery Element
mas01mj@640 288 */
mas01mj@640 289 bind : function(jqelem){
mas01mj@640 290 return jqelem.text(this.label()).attr('typeof', this.type).attr('title', this.URI);
mas01mj@640 291 }
mas01mj@640 292 };
mas01mj@640 293
mas01mj@640 294 jOWL.Ontology.prototype = jOWL.Ontology.Thing.prototype;
mas01mj@640 295
mas01mj@640 296 /** used for jOWL.Ontology.Individual.sourceof */
mas01mj@640 297 jOWL.priv.testObjectTarget = function(target, matchtarget){
mas01mj@640 298 if(target.isArray){
mas01mj@640 299 for(var i=0;i<target.length;i++){
mas01mj@640 300 if(jOWL.priv.testObjectTarget(target.get(i), matchtarget)){ return true;}
mas01mj@640 301 }
mas01mj@640 302 return false;
mas01mj@640 303 }
mas01mj@640 304 //if the target is a class, fetch individuals instead.
mas01mj@640 305 else if(target.isClass){
mas01mj@640 306 var a = target.individuals();
mas01mj@640 307 for(var i=0;i<a.length;i++){
mas01mj@640 308 if(a.get(i).URI == matchtarget){ return true;}
mas01mj@640 309 }
mas01mj@640 310 }
mas01mj@640 311 else if(target.URI == matchtarget){ return true;}
mas01mj@640 312 return false;
mas01mj@640 313 };
mas01mj@640 314
mas01mj@640 315 /** access to Individuals of the ontology*/
mas01mj@640 316 jOWL.Ontology.Individual = function(jnode, owlclass){
mas01mj@640 317 this.parse(jnode);
mas01mj@640 318 if(this.type == __.owl("Thing")){
mas01mj@640 319 var t = jOWL.Xpath(__.rdf('type'), this.jnode);
mas01mj@640 320 if(!t.length){ throw "unable to find a Class for the Individual "+this.name;}
mas01mj@640 321 this.Class = $(t[0]).RDF_Resource();
mas01mj@640 322 }
mas01mj@640 323 else {
mas01mj@640 324 this.Class = jOWL.resolveURI(jnode.get(0));
mas01mj@640 325 }
mas01mj@640 326 this.type = __.owl("Thing");
mas01mj@640 327 if(owlclass){ this.owlClass(owlclass);}
mas01mj@640 328 };
mas01mj@640 329
mas01mj@640 330 jOWL.Ontology.Individual.prototype = $.extend({}, jOWL.Ontology.Thing.prototype, {
mas01mj@640 331 isThing : true,
mas01mj@640 332 /** @return The owl:Class */
mas01mj@640 333 owlClass : function(owlclass){
mas01mj@640 334 if(owlclass){ jOWL.data(this.name, "class", owlclass);}
mas01mj@640 335 else {
mas01mj@640 336 var cl = jOWL.data(this.name, "class");
mas01mj@640 337 if(!cl){ cl = jOWL(this.Class); if(cl){ this.owlClass(cl);} }
mas01mj@640 338 return cl;
mas01mj@640 339 }
mas01mj@640 340 },
mas01mj@640 341 /** Access to restrictions */
mas01mj@640 342 sourceof : function(property, target, options){
mas01mj@640 343 options = $.extend({
mas01mj@640 344 inherited : true, // add restrictions specified on parents as well
mas01mj@640 345 transitive : true,
mas01mj@640 346 ignoreGenerics : false, //if a parent has an identical property, with another target 'Thing', skip that restriction
mas01mj@640 347 ignoreClasses : true,
mas01mj@640 348 valuesOnly : true
mas01mj@640 349 }, options);
mas01mj@640 350
mas01mj@640 351 var results = new jOWL.Ontology.Array();
mas01mj@640 352
mas01mj@640 353 this.jnode.children().filter(function(){return (this.prefix != __.rdfs.prefix && this.prefix != __.rdf.prefix && this.prefix != __.owl.prefix);})
mas01mj@640 354 .each(function(){
mas01mj@640 355 var restriction = new jOWL.Ontology.Restriction($(this));
mas01mj@640 356 var propertyMatch = property ? false : true;
mas01mj@640 357 var targetMatch = target ? false : true;
mas01mj@640 358
mas01mj@640 359 if(!propertyMatch){
mas01mj@640 360 if( property.isArray){ propertyMatch = property.contains(restriction.property);}
mas01mj@640 361 else { propertyMatch = (property.URI == restriction.property.URI);}
mas01mj@640 362 if(!propertyMatch){ return;}
mas01mj@640 363 }
mas01mj@640 364
mas01mj@640 365 if(!target){
mas01mj@640 366 if(options.transitive && restriction.property.isTransitive && !options.ignoreGenerics){
mas01mj@640 367 var rTarget = restriction.getTarget();
mas01mj@640 368 var transitives = rTarget.sourceof(restriction.property, null, options);
mas01mj@640 369 results.concat(transitives);
mas01mj@640 370 }
mas01mj@640 371 }
mas01mj@640 372 else {
mas01mj@640 373 if(restriction.property.isObjectProperty){
mas01mj@640 374 targetMatch = jOWL.priv.testObjectTarget(target, restriction.target);
mas01mj@640 375 if(!targetMatch && options.transitive && restriction.property.isTransitive){
mas01mj@640 376 var rTransitives = restriction.getTarget().sourceof(restriction.property, target, options);
mas01mj@640 377 if(rTransitives.length > 0){ targetMatch = true;}
mas01mj@640 378 }
mas01mj@640 379 }
mas01mj@640 380 else if(restriction.property.isDatatypeProperty){
mas01mj@640 381 targetMatch = restriction.property.assert(restriction.target, target);
mas01mj@640 382 }
mas01mj@640 383 else { targetMatch = (target == restriction.target);}
mas01mj@640 384 }
mas01mj@640 385 if(propertyMatch && targetMatch){ results.pushUnique(restriction);}
mas01mj@640 386
mas01mj@640 387 });
mas01mj@640 388 if(options.inherited){
mas01mj@640 389 var clRestrictions = this.owlClass().sourceof(property, target, options)
mas01mj@640 390 .each(function(){
mas01mj@640 391 //target can be a class, null, a duplicate individual...
mas01mj@640 392 var clRestr = this;
mas01mj@640 393 if(options.valuesOnly && clRestr.target === null){return;}
mas01mj@640 394 var clTarget = this.getTarget();
mas01mj@640 395 if(clTarget.isClass && options.ignoreClasses){ return;}
mas01mj@640 396
mas01mj@640 397 var containsProperty = false;
mas01mj@640 398 for(var i = 0;i<results.length;i++){
mas01mj@640 399 var restr = results.get(i);
mas01mj@640 400 if(restr.property.URI == clRestr.property.URI){
mas01mj@640 401 containsProperty = true;
mas01mj@640 402 if(!options.ignoreGenerics){
mas01mj@640 403 if(clRestr.target != restr.target){ results.pushUnique(clRestr);}
mas01mj@640 404 }
mas01mj@640 405 }
mas01mj@640 406 }
mas01mj@640 407 if(!containsProperty){ results.pushUnique(clRestr);}
mas01mj@640 408 });
mas01mj@640 409 }
mas01mj@640 410 return results;
mas01mj@640 411
mas01mj@640 412 },
mas01mj@640 413 localRestrictions : function(property, target){
mas01mj@640 414 return this.sourceof(property, target, {inherited : false, transitive : false });
mas01mj@640 415 },
mas01mj@640 416 /** Include generic will add transitivity reasoning */
mas01mj@640 417 valueRestrictions : function(includeGeneric){
mas01mj@640 418 return this.sourceof(null, null, {ignoreGenerics : !includeGeneric, valuesOnly : true });
mas01mj@640 419 }
mas01mj@640 420 });
mas01mj@640 421
mas01mj@640 422 /** jNode is of type owl:Restriction */
mas01mj@640 423 jOWL.Ontology.Restriction = function(jnode){
mas01mj@640 424
mas01mj@640 425 var jprop, prop, op, restrtype;
mas01mj@640 426
mas01mj@640 427 this.cachedTarget = null;
mas01mj@640 428
mas01mj@640 429 if(jnode.get(0).nodeName != __.owl("Restriction")){
mas01mj@640 430 this.property = jOWL(jOWL.resolveURI(jnode.get(0)), {type: "property"});
mas01mj@640 431 this.target = jnode.RDF_Resource() || jnode.text();
mas01mj@640 432 restrtype = "Individual";
mas01mj@640 433 }
mas01mj@640 434 else
mas01mj@640 435 {
mas01mj@640 436 jprop = jOWL.Xpath(__.owl("onProperty"), jnode);
mas01mj@640 437 prop = jprop.RDF_Resource(); if(!prop){ throw "no property found for the given owl:restriction";}
mas01mj@640 438 op = jprop.siblings();
mas01mj@640 439 restrtype = op.get(0).nodeName;
mas01mj@640 440 this.property = jOWL(prop, {type: "property"});
mas01mj@640 441 this.target = null; //string only
mas01mj@640 442 }
mas01mj@640 443
mas01mj@640 444 this.restriction = { minCard: false, maxCard : false, some: [], all : [], value : false };
mas01mj@640 445 this.type = jnode.get(0).nodeName;
mas01mj@640 446 this.isAnonymous = true;
mas01mj@640 447 this.isValueRestriction = (restrtype == __.owl('someValuesFrom') || restrtype == __.owl('allValuesFrom') || restrtype == __.owl('hasValue'));
mas01mj@640 448 this.isCardinalityRestriction = (restrtype == __.owl('cardinality') || restrtype == __.owl('maxCardinality') || restrtype == __.owl('minCardinality'));
mas01mj@640 449
mas01mj@640 450 if(!this.property || !restrtype){ throw "badly formed owl:restriction";}
mas01mj@640 451 switch(restrtype){
mas01mj@640 452 case __.owl('cardinality'): this.restriction.minCard = this.restriction.maxCard = parseInt(op.text(), 10); break;
mas01mj@640 453 case __.owl('maxCardinality'): this.restriction.maxCard = parseInt(op.text(), 10); break;
mas01mj@640 454 case __.owl('minCardinality'): this.restriction.minCard = parseInt(op.text(), 10); break;
mas01mj@640 455 case __.owl('hasValue'): var res = op.RDF_Resource(); if(res){ this.target = res;} break;
mas01mj@640 456 }
mas01mj@640 457 if(this.property.isObjectProperty){
mas01mj@640 458 if(this.isCardinalityRestriction && this.property.range){ this.target = this.property.range;}
mas01mj@640 459 else if(this.isValueRestriction){
mas01mj@640 460 var t = op.RDF_Resource();
mas01mj@640 461 if(t == "anonymousOntologyObject"){//nested groupings, anonymous classes
mas01mj@640 462 this.cachedTarget = new jOWL.Ontology.Class(jOWL.Xpath(__.owl("Class"), op));
mas01mj@640 463 }
mas01mj@640 464 this.target = t;
mas01mj@640 465 }
mas01mj@640 466 }
mas01mj@640 467
mas01mj@640 468 var suffix = this.target || this.restrtype;
mas01mj@640 469 this.name = this.property.name+'#'+suffix;
mas01mj@640 470 return this;
mas01mj@640 471 };
mas01mj@640 472
mas01mj@640 473 jOWL.Ontology.Restriction.prototype = {
mas01mj@640 474 jOWL : jOWL.version,
mas01mj@640 475 isRestriction : true,
mas01mj@640 476 bind : function(){return null;},
mas01mj@640 477 merge : function(crit){
mas01mj@640 478 if(this.isCardinalityRestriction && crit.isValueRestriction ){ this.target = crit.target; return true;}
mas01mj@640 479 else if(this.isValueRestriction && crit.isCardinalityRestriction){
mas01mj@640 480 switch(crit.restrtype){
mas01mj@640 481 case __.owl('cardinality'): this.restriction.minCard = this.restriction.maxCard = crit.restriction.minCard; return true;
mas01mj@640 482 case __.owl('minCardinality'): this.restriction.minCard = crit.restriction.minCard; return true;
mas01mj@640 483 case __.owl('maxCardinality'): this.restriction.maxCard = crit.restriction.maxCard; return true;
mas01mj@640 484 }
mas01mj@640 485 }
mas01mj@640 486 return false;
mas01mj@640 487 },
mas01mj@640 488 getTarget : function(){
mas01mj@640 489 if(!this.target){ return jOWL('Thing');}
mas01mj@640 490 if(this.cachedTarget){ return this.cachedTarget;}
mas01mj@640 491 this.cachedTarget = (this.property.isObjectProperty) ? jOWL(this.target) : new jOWL.Literal(this.target);
mas01mj@640 492 return this.cachedTarget;
mas01mj@640 493 },
mas01mj@640 494 equals : function(restr){
mas01mj@640 495 if(!restr.isRestriction){ return false;}
mas01mj@640 496 if(this.property.URI == restr.property.URI){
mas01mj@640 497 if(this.target == 'anonymousOntologyObject'){return false;}//oneof lists etc unsupported right now
mas01mj@640 498 if(this.target && this.target === restr.target){ return true;}
mas01mj@640 499 }
mas01mj@640 500 return false;
mas01mj@640 501 }
mas01mj@640 502 };
mas01mj@640 503
mas01mj@640 504 /** Datatype Logic, local functions */
mas01mj@640 505 jOWL.priv.Dt = function(options){
mas01mj@640 506 this.settings = $.extend({base: null, pattern : null, assert: function(b){return true;}, match: function(a, b){return true;}}, options);
mas01mj@640 507 this.base = jOWL.Ontology.Datatype[this.settings.base];
mas01mj@640 508 };
mas01mj@640 509
mas01mj@640 510 jOWL.priv.Dt.prototype = {
mas01mj@640 511 sanitize : function(b){
mas01mj@640 512 if(this.settings.sanitize){ return this.settings.sanitize(b);}
mas01mj@640 513 if(this.base && this.base.sanitize){ return this.base.sanitize(b);}
mas01mj@640 514 },
mas01mj@640 515 assert : function(b){
mas01mj@640 516 var v = this.sanitize(b); if(v !== undefined){ b = v;}
mas01mj@640 517 if(this.base && !this.base.assert(b)){ return false;}
mas01mj@640 518 if(this.settings.pattern && !this.settings.pattern.test(b)){ return false;}
mas01mj@640 519 return this.settings.assert(b);
mas01mj@640 520 },
mas01mj@640 521 match : function(a, b){
mas01mj@640 522 var v = this.sanitize(b); if(v !== undefined){ b = v;}
mas01mj@640 523 if(!this.assert(b)){ return false;}
mas01mj@640 524 if(this.base && !this.base.match(a, b)){ return false;}
mas01mj@640 525 return this.settings.match(a, b);
mas01mj@640 526 }
mas01mj@640 527 };
mas01mj@640 528
mas01mj@640 529 jOWL.Ontology.Datatype = function(URI, options){
mas01mj@640 530 jOWL.Ontology.Datatype[URI] = new jOWL.priv.Dt(options);
mas01mj@640 531 };
mas01mj@640 532
mas01mj@640 533 /** Datatype Definitions */
mas01mj@640 534 jOWL.Ontology.Datatype(__.xsd()+"integer", {sanitize : function(x){return parseInt(x, 10);}, assert : function(x){ return Math.round(x) == x;}, match : function(a, b){
mas01mj@640 535 var check = parseInt(a, 10);
mas01mj@640 536 if(!isNaN(check)){ return check == b;}
mas01mj@640 537 var arr = a.split('&&');
mas01mj@640 538 for(var i=0;i<arr.length;i++){ arr[i] = b+arr[i];}
mas01mj@640 539 try {
mas01mj@640 540 return eval(arr.join(' && '));
mas01mj@640 541 } catch(e){ return false;}
mas01mj@640 542 } });
mas01mj@640 543 jOWL.Ontology.Datatype(__.xsd()+"positiveInteger", {base: __.xsd()+"integer", assert : function(x){ return x > 0;} });
mas01mj@640 544 jOWL.Ontology.Datatype(__.xsd()+"decimal", {base: __.xsd()+"integer" });
mas01mj@640 545 jOWL.Ontology.Datatype(__.xsd()+"float", {base: __.xsd()+"integer" });
mas01mj@640 546 jOWL.Ontology.Datatype(__.xsd()+"double", {base: __.xsd()+"integer" });
mas01mj@640 547 jOWL.Ontology.Datatype(__.xsd()+"negativeInteger", {base: __.xsd()+"integer", assert : function(x){ return x < 0;} });
mas01mj@640 548 jOWL.Ontology.Datatype(__.xsd()+"nonNegativeInteger", {base: __.xsd()+"integer", assert : function(x){ return x >= 0;} });
mas01mj@640 549 jOWL.Ontology.Datatype(__.xsd()+"nonPositiveInteger", {base: __.xsd()+"integer", assert : function(x){ return x <= 0;} });
mas01mj@640 550 jOWL.Ontology.Datatype(__.xsd()+"string");
mas01mj@640 551
mas01mj@640 552 var URIPattern = /^([a-z0-9+.\-]+):(?:\/\/(?:((?:[a-z0-9-._~!$&'()*+,;=:]|%[0-9A-F]{2})*)@)?((?:[a-z0-9-._~!$&'()*+,;=]|%[0-9A-F]{2})*)(?::(\d*))?(\/(?:[a-z0-9-._~!$&'()*+,;=:@\/]|%[0-9A-F]{2})*)?|(\/?(?:[a-z0-9-._~!$&'()*+,;=:@]|%[0-9A-F]{2})+(?:[a-z0-9-._~!$&'()*+,;=:@\/]|%[0-9A-F]{2})*)?)(?:\?((?:[a-z0-9-._~!$&'()*+,;=:\/?@]|%[0-9A-F]{2})*))?(?:#((?:[a-z0-9-._~!$&'()*+,;=:\/?@]|%[0-9A-F]{2})*))?$/i;
mas01mj@640 553
mas01mj@640 554 jOWL.Ontology.Datatype(__.xsd()+"anyURI", {base: __.xsd()+"string", pattern : URIPattern });
mas01mj@640 555 jOWL.Ontology.Datatype(__.xsd()+"boolean", {sanitize : function(x){
mas01mj@640 556 if(typeof x == 'boolean'){ return x;}
mas01mj@640 557 if(x == 'true'){ return true;}
mas01mj@640 558 if(x == 'false'){ return false;}
mas01mj@640 559 }, assert : function(x){
mas01mj@640 560 return typeof x == 'boolean';
mas01mj@640 561 }, match: function(a, b){
mas01mj@640 562 if(a === "false"){ a = false;}
mas01mj@640 563 if(a === "true"){ a = true;}
mas01mj@640 564 return (a === b);
mas01mj@640 565 }});
mas01mj@640 566
mas01mj@640 567 /** 'superclass' for Properties */
mas01mj@640 568 jOWL.Ontology.Property = function(jnode){
mas01mj@640 569 var r = this.parseProperty(jnode);
mas01mj@640 570 if(r){ return r;}
mas01mj@640 571 };
mas01mj@640 572
mas01mj@640 573 jOWL.Ontology.Property.prototype = $.extend({}, jOWL.Ontology.Thing.prototype,{
mas01mj@640 574 isProperty : true,
mas01mj@640 575 parseProperty : function(jnode){
mas01mj@640 576 if(!jnode || typeof jnode == 'string'){
mas01mj@640 577 this.domain = this.range = null;
mas01mj@640 578 this.parse(jnode);
mas01mj@640 579 return;
mas01mj@640 580 }
mas01mj@640 581 if(jOWL.options.cacheProperties && jOWL.indices.IDs){
mas01mj@640 582 var res = jnode.RDF_ID() || jnode.RDF_About();
mas01mj@640 583 var c = jOWL.index('property').get(res);
mas01mj@640 584 if(c){ return c;}
mas01mj@640 585 }
mas01mj@640 586 this.parse(jnode);
mas01mj@640 587 this.domain= $(this.jnode.get(0).selectSingleNode(__.rdfs('domain'))).RDF_Resource();
mas01mj@640 588 this.range = $(this.jnode.get(0).selectSingleNode(__.rdfs('range'))).RDF_Resource();
mas01mj@640 589 }
mas01mj@640 590 });
mas01mj@640 591
mas01mj@640 592 /** access to Datatype properties */
mas01mj@640 593 jOWL.Ontology.DatatypeProperty = function(jnode){
mas01mj@640 594 var r = this.parseProperty(jnode);
mas01mj@640 595 if(r){ return r;}
mas01mj@640 596 if(this.type == __.owl("AnnotationProperty")){ this.range = __.xsd()+"string";}
mas01mj@640 597 };
mas01mj@640 598
mas01mj@640 599 jOWL.Ontology.DatatypeProperty.prototype = $.extend({}, jOWL.Ontology.Thing.prototype, jOWL.Ontology.Property.prototype, {
mas01mj@640 600 isDatatypeProperty : true,
mas01mj@640 601 /** check datatype values against this */
mas01mj@640 602 assert : function(targetValue, value){
mas01mj@640 603 var self = this;
mas01mj@640 604 var dt = jOWL.Ontology.Datatype[this.range];
mas01mj@640 605 if(!dt){
mas01mj@640 606 console.log(this.range+" datatype reasoning not implemented");
mas01mj@640 607 return true;
mas01mj@640 608 }
mas01mj@640 609 if(value === undefined){ return dt.assert(targetValue);}
mas01mj@640 610 else {return dt.match(value, targetValue);}
mas01mj@640 611 }
mas01mj@640 612 });
mas01mj@640 613
mas01mj@640 614 /** access to Object properties */
mas01mj@640 615 jOWL.Ontology.ObjectProperty = function(jnode){
mas01mj@640 616 var r = this.parseProperty(jnode);
mas01mj@640 617 if(r){ return r;}
mas01mj@640 618 var self = this;
mas01mj@640 619 jOWL.Xpath(__.rdf('type'), this.jnode).each(function(){
mas01mj@640 620 if($(this).RDF_Resource() == __.owl()+"TransitiveProperty"){ self.isTransitive = true;}
mas01mj@640 621 });
mas01mj@640 622 if(this.jnode.get(0).nodeName == __.owl("TransitiveProperty")){ self.isTransitive = true;}
mas01mj@640 623 };
mas01mj@640 624
mas01mj@640 625 jOWL.Ontology.ObjectProperty.prototype = $.extend({}, jOWL.Ontology.Thing.prototype, jOWL.Ontology.Property.prototype, {
mas01mj@640 626 isObjectProperty : true
mas01mj@640 627 });
mas01mj@640 628
mas01mj@640 629 /** access to an owl:Class */
mas01mj@640 630 jOWL.Ontology.Class = function(jnode){
mas01mj@640 631 this.parse(jnode);
mas01mj@640 632 };
mas01mj@640 633
mas01mj@640 634 /** @return jOWL Array of Restrictions */
mas01mj@640 635 jOWL.Xpath.restrictions = function(jnode){
mas01mj@640 636 var result = new jOWL.Ontology.Array();
mas01mj@640 637 jOWL.Xpath(__.rdfs("subClassOf")+"/"+__.owl("Restriction"), jnode)
mas01mj@640 638 .add(jOWL.Xpath(__.owl("intersectionOf")+"/"+__.owl("Restriction"), jnode))
mas01mj@640 639 .each(function(){
mas01mj@640 640 result.push(new jOWL.Ontology.Restriction($(this)));
mas01mj@640 641 });
mas01mj@640 642 return result;
mas01mj@640 643 };
mas01mj@640 644
mas01mj@640 645 /** Internal Use */
mas01mj@640 646 jOWL.Ontology.Intersection = function(jnode){
mas01mj@640 647 var self = this;
mas01mj@640 648 this.jnode = jnode;
mas01mj@640 649 this._arr = [];
mas01mj@640 650 this.URI = this.jnode.parent().RDF_ID();
mas01mj@640 651 this.matches = {};
mas01mj@640 652 jOWL.Xpath(__.owl("Restriction"), jnode).each(function(){
mas01mj@640 653 var restr = new jOWL.Ontology.Restriction($(this));
mas01mj@640 654 if(restr.isValueRestriction){self._arr.push(restr);}
mas01mj@640 655 });
mas01mj@640 656 jOWL.Xpath(__.owl('Class'), jnode).each(function(){
mas01mj@640 657 var uri = $(this).RDF_About();
mas01mj@640 658 if(uri){ self._arr.push(jOWL(uri));}
mas01mj@640 659 });
mas01mj@640 660 };
mas01mj@640 661
mas01mj@640 662 jOWL.Ontology.Intersection.prototype = {
mas01mj@640 663 isIntersection : true,
mas01mj@640 664 jOWL : jOWL.version,
mas01mj@640 665 match : function(id, cls, clRestr){
mas01mj@640 666 if(id == this.URI){ return false;}
mas01mj@640 667 if(this.matches[id] !== undefined){ return this.matches[id]; }//local cache
mas01mj@640 668
mas01mj@640 669 for(var i =0;i<this._arr.length;i++){
mas01mj@640 670 var entry = this._arr[i];
mas01mj@640 671 var m = false;
mas01mj@640 672 if(entry.isRestriction){
mas01mj@640 673 clRestr.each(function(){
mas01mj@640 674 if(this.equals(entry)){ m = true; return false;}
mas01mj@640 675 });
mas01mj@640 676 if(!m) {
mas01mj@640 677 this.matches[id] = false;
mas01mj@640 678 return false;
mas01mj@640 679 }
mas01mj@640 680 } else if(entry.isClass){
mas01mj@640 681 for(var j = 0;j<cls.length;j++){
mas01mj@640 682 if(entry.equals(cls[j])){m = true; break;}
mas01mj@640 683 var it = jOWL.index('ID')[cls[j]];
mas01mj@640 684 if(it){
mas01mj@640 685 var narr = jOWL.Xpath.classes(jOWL.index('ID')[cls[j]].jnode);
mas01mj@640 686 for (var z=0;z<narr.length ; z++){
mas01mj@640 687 if(entry.equals(narr[z])){m = true; break;}
mas01mj@640 688 }
mas01mj@640 689 }
mas01mj@640 690 }
mas01mj@640 691 if(!m){
mas01mj@640 692 this.matches[id] = false;
mas01mj@640 693 return false;
mas01mj@640 694 }
mas01mj@640 695 }
mas01mj@640 696 }
mas01mj@640 697 this.matches[id] = true;
mas01mj@640 698 return this.matches[id];
mas01mj@640 699 },
mas01mj@640 700 equals : function(isect){
mas01mj@640 701 if(!isect.isIntersection){ return false;}
mas01mj@640 702 for(var i =0;i<this._arr.length;i++){
mas01mj@640 703 var match = false;
mas01mj@640 704 for(var j = 0;j<isect._arr.length;j++){
mas01mj@640 705 if(isect._arr[j].equals(this._arr[i])){ match = true;}
mas01mj@640 706 }
mas01mj@640 707 if(!match){ return false;}
mas01mj@640 708 }
mas01mj@640 709 return true;
mas01mj@640 710 }
mas01mj@640 711 };
mas01mj@640 712
mas01mj@640 713 jOWL.Ontology.Class.prototype = $.extend({}, jOWL.Ontology.Thing.prototype, {
mas01mj@640 714 isClass : true,
mas01mj@640 715 /** @return A jOWL.Ontology.Array of individuals for this class & its subclasses */
mas01mj@640 716 individuals : function(){
mas01mj@640 717 var arr = new jOWL.Ontology.Array();
mas01mj@640 718 var q = new jOWL.SPARQL_DL("Type(?x, "+this.name+")").execute({async: false, onComplete: function(r){ arr = r.jOWLArray("?x");} });
mas01mj@640 719 return arr;
mas01mj@640 720 },
mas01mj@640 721 /** @return A jOWL.Ontology.Array of individuals (if oneOf list) */
mas01mj@640 722 oneOf : function(){
mas01mj@640 723 var arr = new jOWL.Ontology.Array();
mas01mj@640 724 var oneOf = this.jnode.children().filter(function(){return this.tagName == __.owl("oneOf");});
mas01mj@640 725 oneOf.children().each(function(){
mas01mj@640 726 arr.push(jOWL($(this).RDF_About()));
mas01mj@640 727 });
mas01mj@640 728 return arr;
mas01mj@640 729 },
mas01mj@640 730 /** @return A jOWL.Ontology.Array of direct children */
mas01mj@640 731 children : function(){
mas01mj@640 732 var that = this;
mas01mj@640 733 var oChildren = jOWL.data(this.name, "children");
mas01mj@640 734 if(oChildren){ return oChildren;}
mas01mj@640 735 oChildren = new jOWL.Ontology.Array();
mas01mj@640 736 if(this.oneOf().length){return oChildren;}
mas01mj@640 737 var URI = this.URI;
mas01mj@640 738
mas01mj@640 739 for(x in jOWL.index('ID')){
mas01mj@640 740 if(x === this.URI){ continue;}
mas01mj@640 741 var node = jOWL.index('ID')[x];
mas01mj@640 742 if(!node.isClass){continue;}
mas01mj@640 743 var cls = jOWL.Xpath.classes(node.jnode); //direct subClasses
mas01mj@640 744 for(var i=0;i<cls.length;i++){
mas01mj@640 745 if(this.equals(cls[i])){
mas01mj@640 746 oChildren.push(node);
mas01mj@640 747 }
mas01mj@640 748 }
mas01mj@640 749 var clRestr = jOWL.Xpath.restrictions(node.jnode);
mas01mj@640 750 var intersections = jOWL.index("intersection")[URI];
mas01mj@640 751 if(intersections){
mas01mj@640 752 intersections.each(function(){//fully defined Subclasses
mas01mj@640 753 if(this.match(x, cls, clRestr)){oChildren.push(node);}
mas01mj@640 754 });
mas01mj@640 755 }
mas01mj@640 756 }
mas01mj@640 757 //an ObjectProperty mentions this as domain
mas01mj@640 758 jOWL.index("property").each(function(){
mas01mj@640 759 if(this.domain == that.name){
mas01mj@640 760 var nodes = jOWL.Xpath('//'+__.owl('onProperty')+'[@'+__.rdf('resource')+'="#'+this.name+'"]/parent::'+__.owl('Restriction')+'/..');
mas01mj@640 761 nodes.filter(function(){ return (this.nodeName == __.owl('intersectionOf') || this.nodeName == __.rdfs('subClassOf'));
mas01mj@640 762 }).each(function(){
mas01mj@640 763 var cl = jOWL($(this.selectSingleNode('parent::'+__.owl('Class'))));
mas01mj@640 764 if(!oChildren.contains(cl) && cl.name != that.name && cl.name !== undefined){ oChildren.push(cl);}
mas01mj@640 765 });
mas01mj@640 766 }
mas01mj@640 767 });
mas01mj@640 768 //filter out redundancies
mas01mj@640 769 oChildren.filter(function(){
mas01mj@640 770 this.hierarchy(false);
mas01mj@640 771 return (this.parents().contains(URI));
mas01mj@640 772 });
mas01mj@640 773 jOWL.data(this.name, "children", oChildren);
mas01mj@640 774 return oChildren;
mas01mj@640 775 },
mas01mj@640 776 setParents : function(parents){
mas01mj@640 777 jOWL.data(this.name, "parents", parents); return parents;
mas01mj@640 778 },
mas01mj@640 779 /** @return A jOWL.Ontology.Array of parents, includes redundancies, to exclude do a hierarchy search first.*/
mas01mj@640 780 parents : function(){
mas01mj@640 781 var self = this;
mas01mj@640 782 var oParents = jOWL.data(this.name, "parents");
mas01mj@640 783 if(oParents){ return oParents;}
mas01mj@640 784
mas01mj@640 785 var temp = [];
mas01mj@640 786
mas01mj@640 787 var cls = jOWL.Xpath.classes(this.jnode);
mas01mj@640 788 for(var i=0;i<cls.length;i++){ jOWL.priv.Array.pushUnique(temp, cls[i]);}
mas01mj@640 789
mas01mj@640 790 var restr = jOWL.Xpath.restrictions(this.jnode);
mas01mj@640 791 restr.each(function(){
mas01mj@640 792 if(this.property.domain && this.property.domain != self.name){ jOWL.priv.Array.pushUnique(temp, this.property.domain);
mas01mj@640 793 }
mas01mj@640 794 });
mas01mj@640 795
mas01mj@640 796 var iSectLoop = function(){
mas01mj@640 797 if(this.match(self.URI, cls, restr)){
mas01mj@640 798 jOWL.priv.Array.pushUnique(temp, this.URI);
mas01mj@640 799 }
mas01mj@640 800
mas01mj@640 801 };
mas01mj@640 802
mas01mj@640 803 if(jOWL.options.reason){
mas01mj@640 804 for(resource in jOWL.index('intersection')){
mas01mj@640 805 jOWL.index('intersection')[resource].each(iSectLoop);
mas01mj@640 806 }
mas01mj@640 807 }
mas01mj@640 808
mas01mj@640 809 oParents = new jOWL.Ontology.Array( jOWL.getXML(temp), true);
mas01mj@640 810 if(!oParents.length){ oParents.push(jOWL('Thing'));}
mas01mj@640 811 else if(oParents.length > 1){ oParents.filter(function(){return this.name != ('Thing');});} //Remove Thing reference if other parents exist
mas01mj@640 812 jOWL.data(this.name, "parents", oParents);
mas01mj@640 813 return oParents;
mas01mj@640 814 },
mas01mj@640 815 /** @return ancestors to the class in a jOWL.Ontology.Array */
mas01mj@640 816 ancestors : function(){
mas01mj@640 817 return this.hierarchy(false).flatindex;
mas01mj@640 818 },
mas01mj@640 819 /**
mas01mj@640 820 Constructs the entire (parent) hierarchy for a class
mas01mj@640 821 @return a jOWL.Ontology.Array containing top nodes (classes directly subsumed by 'owl:Thing')
mas01mj@640 822 @param addInverse add a variable invParents (jOWL.Ontology.Array of child references) to each node with exception of the leaves (original concept)
mas01mj@640 823 */
mas01mj@640 824 hierarchy : function(addInverse){
mas01mj@640 825 var endNodes = new jOWL.Ontology.Array();
mas01mj@640 826 var self = this;
mas01mj@640 827 endNodes.flatindex = new jOWL.Ontology.Array();
mas01mj@640 828
mas01mj@640 829 function URIARR(p_arr, obj){
mas01mj@640 830 var add = true;
mas01mj@640 831 if(!obj){ obj = {}; add = false;}
mas01mj@640 832 if(p_arr.each){
mas01mj@640 833 p_arr.each(function(){
mas01mj@640 834 if(obj[this.URI]){return;}
mas01mj@640 835 if(this.URI == __.owl()+'Thing'){ return;}
mas01mj@640 836 if(add){ obj[this.URI] = true;}
mas01mj@640 837 if(this.parents){ URIARR(this.parents(), obj);}
mas01mj@640 838 });
mas01mj@640 839 }
mas01mj@640 840 return obj;
mas01mj@640 841 }
mas01mj@640 842
mas01mj@640 843 function traverse(concept){
mas01mj@640 844 var parents = concept.parents();
mas01mj@640 845 if(parents.length == 1 && parents.contains(__.owl()+'Thing')){ endNodes.pushUnique(concept); return;}
mas01mj@640 846 else
mas01mj@640 847 {
mas01mj@640 848 var asso = jOWL.options.reason ? URIARR(parents) : {};
mas01mj@640 849 parents.filter(function(){ return (!asso[this.URI]);}); //throw out redundancies
mas01mj@640 850 parents.each(function(){
mas01mj@640 851 var item = endNodes.flatindex.pushUnique(this);
mas01mj@640 852 if(addInverse){
mas01mj@640 853 if(!item.invParents){ item.invParents = new jOWL.Ontology.Array();}
mas01mj@640 854 item.invParents.pushUnique(concept);
mas01mj@640 855 }
mas01mj@640 856 traverse(item);
mas01mj@640 857 });
mas01mj@640 858 concept.setParents(parents);
mas01mj@640 859 }
mas01mj@640 860 }
mas01mj@640 861
mas01mj@640 862 traverse(this);
mas01mj@640 863 return endNodes;
mas01mj@640 864
mas01mj@640 865 },
mas01mj@640 866 /**
mas01mj@640 867 @param level depth to fetch children, Default 5
mas01mj@640 868 @return jOWL array of classes that are descendant
mas01mj@640 869 */
mas01mj@640 870 descendants : function(level){
mas01mj@640 871 level = (typeof level == 'number') ? level : 5;
mas01mj@640 872 var oDescendants = jOWL.data(this.name, "descendants");
mas01mj@640 873 if(oDescendants && oDescendants.level >= level){ return oDescendants;}
mas01mj@640 874 oDescendants = new jOWL.Ontology.Array();
mas01mj@640 875 oDescendants.level = level;
mas01mj@640 876
mas01mj@640 877 function descend(concept, i){
mas01mj@640 878 if(i <= level){
mas01mj@640 879 i++;
mas01mj@640 880 var ch = concept.children();
mas01mj@640 881 oDescendants.concat(ch);
mas01mj@640 882 ch.each(function(item){ descend(item, i);});
mas01mj@640 883 }
mas01mj@640 884 }
mas01mj@640 885
mas01mj@640 886 descend(this, 1);
mas01mj@640 887 jOWL.data(this.name, "descendants", oDescendants);
mas01mj@640 888 return oDescendants;
mas01mj@640 889 },
mas01mj@640 890 /** @return jOWL.Array of Restrictions, target is an individual, not a class or undefined (unless includeAll is specified) - deprecated */
mas01mj@640 891 valueRestrictions : function(includeAll, array){
mas01mj@640 892 return this.sourceof(null, null, {ignoreClasses : !includeAll});
mas01mj@640 893 },
mas01mj@640 894 /**
mas01mj@640 895 get all restrictions that satisfy the arguments
mas01mj@640 896 @param property property or array of properties, or null
mas01mj@640 897 @param target class, individuals of array of them, or null
mas01mj@640 898 @return jOWL.Array of Restrictions
mas01mj@640 899 */
mas01mj@640 900 sourceof : function(property, target, options){
mas01mj@640 901 options = $.extend({
mas01mj@640 902 inherited : true, // add restrictions specified on parents as well
mas01mj@640 903 transitive : true, //expand on transitive relations too
mas01mj@640 904 ignoreGenerics : true, //if a parent has an identical property, with another target 'Thing', skip that restriction
mas01mj@640 905 ignoreClasses : false, //only individuals should return
mas01mj@640 906 valuesOnly : true //do not return valueless criteria
mas01mj@640 907 }, options);
mas01mj@640 908 var self = this;
mas01mj@640 909 var crit = jOWL.data(this.name, "sourceof");
mas01mj@640 910 var jnode = this.jnode;
mas01mj@640 911
mas01mj@640 912 if(!crit){
mas01mj@640 913 crit = new jOWL.Ontology.Array();
mas01mj@640 914 var arr = jOWL.Xpath(__.rdfs("subClassOf")+"/"+__.owl("Restriction"), jnode)
mas01mj@640 915 .add(jOWL.Xpath(__.owl("intersectionOf")+"/"+__.owl("Restriction"), jnode));
mas01mj@640 916 arr.each(function(index, entry){
mas01mj@640 917 var cr = new jOWL.Ontology.Restriction($(entry));
mas01mj@640 918 var dupe = false;
mas01mj@640 919 crit.each(function(item, i){
mas01mj@640 920 if(this.property.name == cr.property.name){ dupe = item;}
mas01mj@640 921 });
mas01mj@640 922 if(dupe){ if(!dupe.merge(cr)){ crit.push(cr);} }
mas01mj@640 923 else { crit.push(cr);}
mas01mj@640 924 });
mas01mj@640 925 jOWL.data(self.name, "sourceof", crit);
mas01mj@640 926 }
mas01mj@640 927 var results = new jOWL.Ontology.Array();
mas01mj@640 928
mas01mj@640 929 crit.each(function(){
mas01mj@640 930
mas01mj@640 931 var propertyMatch = property ? false : true;
mas01mj@640 932 var targetMatch = target ? false : true;
mas01mj@640 933
mas01mj@640 934 if(!propertyMatch){
mas01mj@640 935 if(property.isArray){ propertyMatch = property.contains(this.property);}
mas01mj@640 936 else { propertyMatch = (property.URI == this.property.URI);}
mas01mj@640 937 }
mas01mj@640 938
mas01mj@640 939 if(!target){
mas01mj@640 940 if(options.transitive && this.property.isTransitive){
mas01mj@640 941 var rTarget = this.getTarget();
mas01mj@640 942 var transitives = rTarget.sourceof(this.property, null, options);
mas01mj@640 943 results.concat(transitives);
mas01mj@640 944 }
mas01mj@640 945 }
mas01mj@640 946
mas01mj@640 947 if(!targetMatch && !this.target){
mas01mj@640 948 targetMatch = !options.valuesOnly;
mas01mj@640 949 }
mas01mj@640 950
mas01mj@640 951 if(!targetMatch){
mas01mj@640 952 var targ = this.getTarget();
mas01mj@640 953 if(targ.isClass && options.ignoreClasses){ return;}
mas01mj@640 954 targetMatch = jOWL.priv.testObjectTarget(target, this.target);
mas01mj@640 955 if(!targetMatch && options.transitive && propertyMatch && this.property.isTransitive){
mas01mj@640 956 if(targ.isThing){
mas01mj@640 957 if(targ.sourceof(property, target).length){ targetMatch = true;}
mas01mj@640 958 }
mas01mj@640 959 }
mas01mj@640 960 }
mas01mj@640 961
mas01mj@640 962 if(propertyMatch && targetMatch){ results.pushUnique(this);}
mas01mj@640 963 });
mas01mj@640 964
mas01mj@640 965 if(!options.inherited){ return results;}
mas01mj@640 966
mas01mj@640 967 this.parents().each(function(){
mas01mj@640 968 if(this.sourceof){
mas01mj@640 969 this.sourceof(property, target, options).each(function(parentsource){
mas01mj@640 970 var ptarget = this.getTarget();
mas01mj@640 971 var containsProperty = false;
mas01mj@640 972 var tempArray = new jOWL.Ontology.Array();
mas01mj@640 973 results.filter(function(){
mas01mj@640 974 var restr = this, keep = true;
mas01mj@640 975 if(restr.property.URI == parentsource.property.URI){
mas01mj@640 976 containsProperty = true;
mas01mj@640 977 if(!options.ignoreGenerics){
mas01mj@640 978 if(parentsource.target != restr.target){ tempArray.push(parentsource);}
mas01mj@640 979 } else {
mas01mj@640 980 if(ptarget.isThing){
mas01mj@640 981 keep = restr.getTarget().isThing && parentsource.target != restr.target;
mas01mj@640 982 tempArray.push(parentsource);
mas01mj@640 983 }
mas01mj@640 984 }
mas01mj@640 985 }
mas01mj@640 986 return keep;
mas01mj@640 987 });
mas01mj@640 988 if(!containsProperty){ results.push(parentsource);}
mas01mj@640 989 results.concat(tempArray);
mas01mj@640 990 });
mas01mj@640 991 }
mas01mj@640 992 });
mas01mj@640 993 return results;
mas01mj@640 994 }
mas01mj@640 995 });
mas01mj@640 996
mas01mj@640 997 /** Utility object */
mas01mj@640 998 jOWL.Ontology.Array = function(arr, isXML){
mas01mj@640 999 var self = this;
mas01mj@640 1000 this.items = [];
mas01mj@640 1001 if(arr){
mas01mj@640 1002 if(isXML){ $.each(arr, function(){
mas01mj@640 1003 var entry = this.jOWL ? this : jOWL($(this));
mas01mj@640 1004 self.items.push(entry);});
mas01mj@640 1005 }
mas01mj@640 1006 else { this.items = arr;}
mas01mj@640 1007 }
mas01mj@640 1008 this.length = this.items.length;
mas01mj@640 1009 };
mas01mj@640 1010
mas01mj@640 1011 jOWL.Ontology.Array.prototype = {
mas01mj@640 1012 jOWL : jOWL.version,
mas01mj@640 1013 isArray : true,
mas01mj@640 1014 bind : function(listitem, fn){
mas01mj@640 1015 return this.map(function(){
mas01mj@640 1016 var syntax = listitem ? listitem.clone(true) : $('<span/>');
mas01mj@640 1017 var html = this.bind(syntax).append(document.createTextNode(' '));
mas01mj@640 1018 if(fn){ fn.call(html, html, this);}
mas01mj@640 1019 return html.get(0);
mas01mj@640 1020 });
mas01mj@640 1021 },
mas01mj@640 1022 concat : function(arr, ignoreUnique){
mas01mj@640 1023 var self = this;
mas01mj@640 1024 if(arr.each){ arr.each(function(){
mas01mj@640 1025 if(ignoreUnique){ self.push(this); }
mas01mj@640 1026 else { self.pushUnique(this); }
mas01mj@640 1027 });
mas01mj@640 1028 }
mas01mj@640 1029 else { self.items = self.items.concat(arr.items); this.length = self.items.length;}
mas01mj@640 1030 return this;
mas01mj@640 1031 },
mas01mj@640 1032 contains : function(o){
mas01mj@640 1033 return this.get(o) ? true: false;
mas01mj@640 1034 },
mas01mj@640 1035 each : function(fn, reverse){
mas01mj@640 1036 var i, self = this;
mas01mj@640 1037 var stop = false;
mas01mj@640 1038 if(reverse){
mas01mj@640 1039 for(i=this.items.length - 1; i>=0;i--){
mas01mj@640 1040 if(stop){ break;}
mas01mj@640 1041 (function(){
mas01mj@640 1042 var item = self.eq(i);
mas01mj@640 1043 if(fn.call(item, item, i) === false){ stop = true;}
mas01mj@640 1044 })();
mas01mj@640 1045 }
mas01mj@640 1046 }
mas01mj@640 1047 else {
mas01mj@640 1048 for(i=0;i<this.items.length;i++){
mas01mj@640 1049 if(stop){ break;}
mas01mj@640 1050 (function(){
mas01mj@640 1051 var item = self.eq(i);
mas01mj@640 1052 if(fn.call(item, item, i) === false){ stop = true;}
mas01mj@640 1053 })();}
mas01mj@640 1054 }
mas01mj@640 1055 return this;
mas01mj@640 1056 },
mas01mj@640 1057 eq : function(index){
mas01mj@640 1058 if(index < 0 || index > this.items.length -1){ return null;}
mas01mj@640 1059 return this.items[index];
mas01mj@640 1060 },
mas01mj@640 1061 filter : function(fn){
mas01mj@640 1062 var self = this;
mas01mj@640 1063 this.each(function(item, i){
mas01mj@640 1064 var q = fn.call(item, item, i);
mas01mj@640 1065 if(!q){ self.items.splice(i, 1);}
mas01mj@640 1066 }, true);
mas01mj@640 1067 this.length = this.items.length;
mas01mj@640 1068 return this;
mas01mj@640 1069 },
mas01mj@640 1070 getIndex : function(o){
mas01mj@640 1071 var found = -1;
mas01mj@640 1072 if(o.equals){
mas01mj@640 1073 this.each(function(a, i){
mas01mj@640 1074 if(this.equals && this.equals(o)){ found = i; return false;}
mas01mj@640 1075 });
mas01mj@640 1076 }
mas01mj@640 1077 else {
mas01mj@640 1078 if(typeof o == 'number'){ return o;}
mas01mj@640 1079 var name = typeof o == "string" ? o : o.name;
mas01mj@640 1080 var URI = o.URI || name;
mas01mj@640 1081
mas01mj@640 1082 this.each(function(a, i){
mas01mj@640 1083 if(this.URI){ if(this.URI == URI){ found = i;}}
mas01mj@640 1084 else if(this.name == name){ found = i;}
mas01mj@640 1085 });
mas01mj@640 1086 }
mas01mj@640 1087 return found;
mas01mj@640 1088 },
mas01mj@640 1089 get : function(o){
mas01mj@640 1090 return this.eq(this.getIndex(o));
mas01mj@640 1091 },
mas01mj@640 1092 map : function(fn){
mas01mj@640 1093 var arr = [];
mas01mj@640 1094 this.each(function(){ arr.push(fn.call(this, this));});
mas01mj@640 1095 return arr;
mas01mj@640 1096 },
mas01mj@640 1097 push : function(o){
mas01mj@640 1098 this.items.push(o);
mas01mj@640 1099 this.length = this.items.length;
mas01mj@640 1100 return this;
mas01mj@640 1101 },
mas01mj@640 1102 pushUnique : function(o){
mas01mj@640 1103 return this.get(o) || this.push(o).get(o);
mas01mj@640 1104 },
mas01mj@640 1105 toString : function(){
mas01mj@640 1106 return this.map(function(){return this.URI;}).join(', ');
mas01mj@640 1107 },
mas01mj@640 1108 /** Convert this array into an associative array with key = URI */
mas01mj@640 1109 associative : function(){
mas01mj@640 1110 var arr = {};
mas01mj@640 1111 this.each(function(){
mas01mj@640 1112 if(this.URI){ arr[this.URI] = this;}
mas01mj@640 1113 });
mas01mj@640 1114 return arr;
mas01mj@640 1115 }
mas01mj@640 1116 };
mas01mj@640 1117
mas01mj@640 1118
mas01mj@640 1119 jOWL.options = {reason: true, locale:false, defaultlocale: 'en',
mas01mj@640 1120 dictionary : { create: true, addID : true },
mas01mj@640 1121 onParseError : function(msg){alert("jOWL parseError: "+msg);}, cacheProperties : true, niceClassLabels : true};
mas01mj@640 1122 jOWL.document = null;
mas01mj@640 1123 jOWL.namespace = null;
mas01mj@640 1124 jOWL.indices = { //internal indices
mas01mj@640 1125 P : null, //jOWL array
mas01mj@640 1126 data : {},
mas01mj@640 1127 IDs : null,
mas01mj@640 1128 I : null, //Intersection
mas01mj@640 1129 T : null, //Thing
mas01mj@640 1130 D : null, //dictionary
mas01mj@640 1131 reset : function(){var i = jOWL.indices; i.data = {}; i.P = null; i.T = null; i.IDs = null; i.I = null;i.D = null;}
mas01mj@640 1132 };
mas01mj@640 1133
mas01mj@640 1134 jOWL.index = function(type, wipe){
mas01mj@640 1135 var i = jOWL.indices;
mas01mj@640 1136 switch (type)
mas01mj@640 1137 {
mas01mj@640 1138 /**jOWL indexes all elements with rdf:ID, and first order ontology elements specified with rdf:about
mas01mj@640 1139 @return Associative array with key = URI and value = jOWL object.
mas01mj@640 1140 */
mas01mj@640 1141 case "ID":
mas01mj@640 1142 if(i.IDs === null || wipe){
mas01mj@640 1143 if(wipe){ i.reset();}
mas01mj@640 1144 i.IDs = {};
mas01mj@640 1145 i.T = {};
mas01mj@640 1146 var start = new Date();
mas01mj@640 1147
mas01mj@640 1148 var rID = jOWL.Xpath("//*[@"+__.rdf("ID")+"]").each(function(){
mas01mj@640 1149 var jowl = jOWL.getResource($(this));
mas01mj@640 1150 if(jowl){
mas01mj@640 1151 i.IDs[jowl.URI] = jowl;
mas01mj@640 1152 if(jowl.isThing){
mas01mj@640 1153 if(!i.T[jowl.Class]){ i.T[jowl.Class] = new jOWL.Ontology.Array();}
mas01mj@640 1154 i.T[jowl.Class].push(jowl);
mas01mj@640 1155 }
mas01mj@640 1156 }
mas01mj@640 1157 });
mas01mj@640 1158
mas01mj@640 1159 var rAbout = jOWL.Xpath("/"+__.rdf("RDF")+"/*[@"+__.rdf("about")+"]").each(function(){
mas01mj@640 1160 var jnode = $(this);
mas01mj@640 1161 var jowl = jOWL.getResource($(this));
mas01mj@640 1162 if(!jowl){ return;}
mas01mj@640 1163 if(jowl.isClass || jowl.isProperty || jowl.isThing){
mas01mj@640 1164 if(i.IDs[jowl.URI]){ jnode.children().appendTo(i.IDs[jowl.URI].jnode); return;}
mas01mj@640 1165 i.IDs[jowl.URI] = jowl;
mas01mj@640 1166 if(jowl.isThing){
mas01mj@640 1167 if(!i.T[jowl.Class]){ i.T[jowl.Class] = new jOWL.Ontology.Array();}
mas01mj@640 1168 i.T[jowl.Class].push(jowl);
mas01mj@640 1169 }
mas01mj@640 1170 return;
mas01mj@640 1171 }
mas01mj@640 1172 });
mas01mj@640 1173 console.log("Loaded in "+(new Date().getTime() - start.getTime())+"ms");
mas01mj@640 1174 }
mas01mj@640 1175 return i.IDs;
mas01mj@640 1176 /** Generated together with ID index.
mas01mj@640 1177 * @return Associative Array, key = class, value = jOWL Array of individuals.
mas01mj@640 1178 */
mas01mj@640 1179 case "Thing":
mas01mj@640 1180 return i.T;
mas01mj@640 1181 case "intersection":
mas01mj@640 1182 if(i.I === null || wipe){
mas01mj@640 1183 var temp = new jOWL.Ontology.Array();
mas01mj@640 1184 i.I = {};
mas01mj@640 1185 jOWL.Xpath("//"+__.owl("intersectionOf")).each(function(){
mas01mj@640 1186 var isect = new jOWL.Ontology.Intersection($(this));
mas01mj@640 1187 if(!isect.URI){return;}
mas01mj@640 1188 var dupe = temp.get(isect);
mas01mj@640 1189 if(dupe){
mas01mj@640 1190 console.log("duplicate intersection found between : (Ignoring) "+isect.URI+" and "+dupe.URI);
mas01mj@640 1191 } else {
mas01mj@640 1192 if(!i.I[isect.URI]){i.I[isect.URI] = new jOWL.Ontology.Array();}
mas01mj@640 1193 temp.push(isect);
mas01mj@640 1194 i.I[isect.URI].push(isect);
mas01mj@640 1195 }
mas01mj@640 1196 });
mas01mj@640 1197 }
mas01mj@640 1198 return i.I;
mas01mj@640 1199 case "property":
mas01mj@640 1200 if(i.P === null || wipe)
mas01mj@640 1201 {
mas01mj@640 1202 jOWL.options.cacheProperties = false;
mas01mj@640 1203 i.P = new jOWL.Ontology.Array();
mas01mj@640 1204 for(x in i.IDs){
mas01mj@640 1205 var jowl = i.IDs[x];
mas01mj@640 1206 if(jowl.isProperty){ i.P.push(jowl);}
mas01mj@640 1207 }
mas01mj@640 1208 jOWL.options.cacheProperties = true;
mas01mj@640 1209 }
mas01mj@640 1210 return i.P;
mas01mj@640 1211 case "dictionary":
mas01mj@640 1212 /**Dictionary: Array of Arrays, where secondary array is of form: [0] = term, [1] = rdfID, [2] = locale */
mas01mj@640 1213 if(i.D === null || wipe)
mas01mj@640 1214 {
mas01mj@640 1215 i.D = [];
mas01mj@640 1216 for(x in i.IDs){
mas01mj@640 1217 var entry = i.IDs[x];
mas01mj@640 1218 i.D = i.D.concat(entry.terms());
mas01mj@640 1219 }
mas01mj@640 1220 }
mas01mj@640 1221 return i.D;
mas01mj@640 1222 }
mas01mj@640 1223 };
mas01mj@640 1224
mas01mj@640 1225 /** Internal Function, storing data in associative array (JSON),
mas01mj@640 1226 jquery data function cannot be used as expando data does not work in IE for ActiveX XMLhttprequest*/
mas01mj@640 1227 jOWL.data = function(rdfID, dtype, data){
mas01mj@640 1228 var d = jOWL.indices.data;
mas01mj@640 1229 if(!d[rdfID]){ d[rdfID] = {};}
mas01mj@640 1230 if(!data){ return d[rdfID][dtype];}
mas01mj@640 1231 d[rdfID][dtype] = data;
mas01mj@640 1232 };
mas01mj@640 1233
mas01mj@640 1234 /**
mas01mj@640 1235 * Initialize jOWL with an OWL-RDFS document.
mas01mj@640 1236 * @param path relative path to xml document
mas01mj@640 1237 * @param callback callback function to be called when loaded.
mas01mj@640 1238 * @options : optional settings:
mas01mj@640 1239 * onParseError : function(msg){} function to ba called when parsing fails
mas01mj@640 1240 * reason : true/false, turns on additional reasoning at the expense of performance
mas01mj@640 1241 * locale: set preferred language (if available), examples en, fr...
mas01mj@640 1242 */
mas01mj@640 1243 jOWL.load = function(path, callback, options){
mas01mj@640 1244 var that = this;
mas01mj@640 1245 if($.browser.msie && location.toString().indexOf('file') === 0){ //IE won't load local xml files otherwise
mas01mj@640 1246 var xml = document.createElement("xml");
mas01mj@640 1247 xml.validateOnParse = false; //IE throws DTD errors (for 'rdf:') on perfectly defined OWL files otherwise
mas01mj@640 1248 xml.src = path;
mas01mj@640 1249 xml.onreadystatechange = function(){
mas01mj@640 1250 if(xml.readyState == "interactive"){ var xmldoc = xml.XMLDocument; document.body.removeChild(xml);callback(that.parse(xmldoc, options));}
mas01mj@640 1251 };
mas01mj@640 1252 document.body.appendChild(xml);
mas01mj@640 1253 }
mas01mj@640 1254 else {
mas01mj@640 1255 $.get(path, function(xml){callback(that.parse(xml, options));});
mas01mj@640 1256 }
mas01mj@640 1257 };
mas01mj@640 1258
mas01mj@640 1259 /**
mas01mj@640 1260 * initialize jOWL with some OWL-RDFS syntax
mas01mj@640 1261 * @param doc Either an xmlString or an xmlDocument
mas01mj@640 1262 * @param options optional, onParseError(msg) : function to execute when parse fails
mas01mj@640 1263 * @returns false on failure, or the jOWL object
mas01mj@640 1264 */
mas01mj@640 1265 jOWL.parse = function(doc, options){
mas01mj@640 1266 jOWL.document = null;
mas01mj@640 1267 this.options = $.extend(jOWL.options, options);
mas01mj@640 1268 if(typeof doc == 'string'){ doc = jOWL.fromString(doc);}
mas01mj@640 1269 jOWL.document = doc;
mas01mj@640 1270 if($.browser.msie){
mas01mj@640 1271 if(doc.parseError.errorCode !== 0){ jOWL.options.onParseError(doc.parseError.reason); return false;}
mas01mj@640 1272 }
mas01mj@640 1273 else if(doc.documentElement.nodeName == 'parsererror'){jOWL.options.onParseError(doc.documentElement.firstChild.nodeValue); return false;}
mas01mj@640 1274 var root = $(doc.documentElement);
mas01mj@640 1275 jOWL.NS(root);
mas01mj@640 1276 if($.browser.msie){
mas01mj@640 1277 jOWL.document.setProperty("SelectionLanguage", "XPath");
mas01mj@640 1278 jOWL.document.setProperty("SelectionNamespaces", __());
mas01mj@640 1279 }
mas01mj@640 1280 this.index('ID', true);
mas01mj@640 1281 if(jOWL.options.cacheProperties){ this.index('property', true);}
mas01mj@640 1282 if(jOWL.options.dictionary.create){ jOWL.index("dictionary");}
mas01mj@640 1283 jOWL.Thing = new jOWL.Ontology.Thing($(jOWL.create(__.owl, "Class").attr(__.rdf, 'about', __.owl()+'Thing').node));
mas01mj@640 1284 jOWL.Thing.type = false;
mas01mj@640 1285 return this;
mas01mj@640 1286 };
mas01mj@640 1287
mas01mj@640 1288 /**
mas01mj@640 1289 * A String representation of the OWL-RDFS document
mas01mj@640 1290 * @param xmlNode optional, node to generate a string from, when unspecified the entire document
mas01mj@640 1291 */
mas01mj@640 1292 jOWL.toString = function(xmlNode){
mas01mj@640 1293 if(!xmlNode){ return jOWL.toString(jOWL.document);}
mas01mj@640 1294 if($.browser.msie){ return xmlNode.xml;}
mas01mj@640 1295 return new XMLSerializer().serializeToString(xmlNode);// Gecko-based browsers, Safari, Opera.
mas01mj@640 1296 };
mas01mj@640 1297
mas01mj@640 1298 /** create a document from string */
mas01mj@640 1299 jOWL.fromString = function(doc){
mas01mj@640 1300 var owldoc;
mas01mj@640 1301 if(document.implementation.createDocument){ owldoc = new DOMParser().parseFromString(doc, "text/xml");} // Mozilla and Netscape browsers
mas01mj@640 1302 else if(window.ActiveXObject){ // MSIE
mas01mj@640 1303 var xmldoc = new ActiveXObject("Microsoft.XMLDOM");
mas01mj@640 1304 xmldoc.async="false";
mas01mj@640 1305 xmldoc.validateOnParse = false;
mas01mj@640 1306 xmldoc.loadXML(doc);
mas01mj@640 1307 owldoc = xmldoc;
mas01mj@640 1308 }
mas01mj@640 1309 return owldoc;
mas01mj@640 1310 };
mas01mj@640 1311
mas01mj@640 1312 /** @return false if belongs to this namespace, or an array with length two, arr[0] == url, arr[1] == id */
mas01mj@640 1313 jOWL.isExternal = function(resource){
mas01mj@640 1314 var r = jOWL.resolveURI(resource, true);
mas01mj@640 1315 return r[0] != jOWL.namespace ? r : false;
mas01mj@640 1316 };
mas01mj@640 1317
mas01mj@640 1318 /**
mas01mj@640 1319 if a URI belongs to the loaded namespace, then strips the prefix url of, else preserves URI
mas01mj@640 1320 also able to parse and reference html (or jquery) elements for their URI.
mas01mj@640 1321 */
mas01mj@640 1322 jOWL.resolveURI = function(URI, array){
mas01mj@640 1323 if(typeof URI != "string"){
mas01mj@640 1324 var node = URI.jquery ? URI.get(0) : URI;
mas01mj@640 1325 URI = node.localName || node.baseName;
mas01mj@640 1326 if(node.namespaceURI){ URI = node.namespaceURI + URI;}
mas01mj@640 1327 return jOWL.resolveURI(URI, array);
mas01mj@640 1328 }
mas01mj@640 1329 var rs = URI, ns = jOWL.namespace;
mas01mj@640 1330 if(URI.indexOf('http') === 0){
mas01mj@640 1331 var tr = URI.indexOf('#');
mas01mj@640 1332 if(tr <= 0){ tr = URI.lastIndexOf('/');}
mas01mj@640 1333 if(tr > 0)
mas01mj@640 1334 {
mas01mj@640 1335 ns = URI.substring(0, tr+1);
mas01mj@640 1336 rs = URI.substring(tr+1);
mas01mj@640 1337 }
mas01mj@640 1338 } else if(URI.charAt(0) == '#'){ return URI.substring(1);}
mas01mj@640 1339 if(array){ return [ns, rs];}
mas01mj@640 1340 if(ns == jOWL.namespace){ return rs;}
mas01mj@640 1341 return URI;
mas01mj@640 1342 };
mas01mj@640 1343
mas01mj@640 1344 /**
mas01mj@640 1345 Main method to get an Ontology Object, access via jOWL(>String>, options);
mas01mj@640 1346 resource: rdfID/rdfResource<String> or jQuery node.
mas01mj@640 1347 */
mas01mj@640 1348 jOWL.getResource = function(resource, options){
mas01mj@640 1349 if(!jOWL.document){ throw "You must successfully load an ontology before you can find anything";}
mas01mj@640 1350 if(!resource){ throw "No resource specified";}
mas01mj@640 1351 var node;
mas01mj@640 1352 var opts = $.extend({}, options);
mas01mj@640 1353 if(typeof resource == 'string'){
mas01mj@640 1354 resource = jOWL.resolveURI(resource);
mas01mj@640 1355 if(resource == 'Thing' || resource == __.owl()+'Thing'){ return jOWL.Thing;}
mas01mj@640 1356 if(opts.type == 'property' && jOWL.options.cacheProperties){
mas01mj@640 1357 var c = jOWL.index('property').get(resource);
mas01mj@640 1358 if(c){ return c;}
mas01mj@640 1359 if(jOWL.isExternal(resource)){ console.log("undeclared resource: "+resource); return new jOWL.Ontology.Property(resource);}
mas01mj@640 1360 }
mas01mj@640 1361 var match = jOWL.index("ID")[resource];
mas01mj@640 1362 if(!match){ //try case insensitive
mas01mj@640 1363 for(caseIns in jOWL.index("ID")){
mas01mj@640 1364 if(caseIns.toLowerCase() == resource.replace(/ /g, "").toLowerCase()){ match = jOWL.index("ID")[caseIns]; break;}
mas01mj@640 1365 }
mas01mj@640 1366 }
mas01mj@640 1367 if(!match){
mas01mj@640 1368 if(jOWL.isExternal(resource)){
mas01mj@640 1369 console.log("undeclared resource: "+resource);
mas01mj@640 1370 return new jOWL.Ontology.Thing(resource);
mas01mj@640 1371 }
mas01mj@640 1372 console.log(resource+" not found");
mas01mj@640 1373 return null;
mas01mj@640 1374 }
mas01mj@640 1375 return match;
mas01mj@640 1376 }
mas01mj@640 1377 node = resource.jquery ? resource : $(resource);
mas01mj@640 1378 var jj = jOWL.type(node); if(!jj){ return null;}
mas01mj@640 1379 return new (jj)(node);
mas01mj@640 1380 };
mas01mj@640 1381
mas01mj@640 1382 /**
mas01mj@640 1383 * @param node jquery or html element.
mas01mj@640 1384 * @return the ontology type of the object.
mas01mj@640 1385 */
mas01mj@640 1386 jOWL.type = function(node){
mas01mj@640 1387 var xmlNode = node.jquery ? node.get(0) : node;
mas01mj@640 1388 switch(xmlNode.nodeName){
mas01mj@640 1389 case __.owl("Class") : return jOWL.Ontology.Class;
mas01mj@640 1390 case __.rdfs("Class") : return jOWL.Ontology.Class; //test
mas01mj@640 1391 case __.owl("Ontology") : return jOWL.Ontology;
mas01mj@640 1392 case __.owl("ObjectProperty") : return jOWL.Ontology.ObjectProperty;
mas01mj@640 1393 case __.owl("DatatypeProperty") : return jOWL.Ontology.DatatypeProperty;
mas01mj@640 1394 case __.owl("FunctionalProperty") : return jOWL.Ontology.Property;
mas01mj@640 1395 case __.rdf("Property") : return jOWL.Ontology.Property;
mas01mj@640 1396 case __.owl("InverseFunctionalProperty") : return jOWL.Ontology.ObjectProperty;
mas01mj@640 1397 case __.owl("TransitiveProperty") : return jOWL.Ontology.ObjectProperty;
mas01mj@640 1398 case __.owl("SymmetricProperty") : return jOWL.Ontology.ObjectProperty;
mas01mj@640 1399 //jOWL currently treats annotationproperties as string datatypeproperties.
mas01mj@640 1400 case __.owl("AnnotationProperty") : return jOWL.Ontology.DatatypeProperty;
mas01mj@640 1401 default :
mas01mj@640 1402 switch(xmlNode.namespaceURI){
mas01mj@640 1403 case __.owl(): if(xmlNode.nodeName == __.owl("Thing") ){ return jOWL.Ontology.Individual;} return false;
mas01mj@640 1404 case __.rdf(): return false;
mas01mj@640 1405 case __.rdfs(): return false;
mas01mj@640 1406 default : return jOWL.Ontology.Individual;
mas01mj@640 1407 }
mas01mj@640 1408 }
mas01mj@640 1409 };
mas01mj@640 1410
mas01mj@640 1411 /**
mas01mj@640 1412 @param rdfID <String> or Array<String>
mas01mj@640 1413 @return Array of DOM (xml) Nodes
mas01mj@640 1414 */
mas01mj@640 1415 jOWL.getXML = function(rdfID){
mas01mj@640 1416 var node = [];
mas01mj@640 1417 function fetchFromIndex(rdfID){
mas01mj@640 1418 var el = jOWL.index("ID")[rdfID];
mas01mj@640 1419 return el ? el : null;
mas01mj@640 1420 }
mas01mj@640 1421
mas01mj@640 1422 if(typeof rdfID == 'string'){ var q = fetchFromIndex(rdfID); if(q){ node.push(q);} }
mas01mj@640 1423 else if(jOWL.priv.Array.isArray(rdfID)){ //assume an array of string rdfIDs
mas01mj@640 1424 $.each(rdfID, function(){
mas01mj@640 1425 var el = fetchFromIndex(this); if(el){ node.push(el);}
mas01mj@640 1426 });
mas01mj@640 1427 }
mas01mj@640 1428 return node;
mas01mj@640 1429 };
mas01mj@640 1430
mas01mj@640 1431 /** Create new ontology elements */
mas01mj@640 1432 jOWL.create = function(namespace, name, document){
mas01mj@640 1433 var doc = document ? document : jOWL.document;
mas01mj@640 1434
mas01mj@640 1435 var el = {
mas01mj@640 1436 attr : function(namespace, name, value){
mas01mj@640 1437 if($.browser.msie){
mas01mj@640 1438 var attribute = doc.createNode(2, namespace(name), namespace());
mas01mj@640 1439 attribute.nodeValue = value;
mas01mj@640 1440 this.node.setAttributeNode(attribute);
mas01mj@640 1441 }
mas01mj@640 1442 else { this.node.setAttributeNS(namespace(), namespace(name), value);}
mas01mj@640 1443 return this;
mas01mj@640 1444 },
mas01mj@640 1445 appendTo : function(node){
mas01mj@640 1446 var n = node.node ? node.node : node;
mas01mj@640 1447 n.appendChild(this.node);
mas01mj@640 1448 return this;
mas01mj@640 1449 },
mas01mj@640 1450 text : function(text, cdata){
mas01mj@640 1451 var txt = cdata ? doc.createCDATASection(text) : doc.createTextNode(text);
mas01mj@640 1452 this.node.appendChild(txt);
mas01mj@640 1453 return this;
mas01mj@640 1454 }
mas01mj@640 1455 };
mas01mj@640 1456
mas01mj@640 1457 if($.browser.msie){ el.node = doc.createNode(1, namespace(name), namespace());}
mas01mj@640 1458 else { el.node = doc.createElementNS(namespace(), namespace(name));}
mas01mj@640 1459 return el;
mas01mj@640 1460 };
mas01mj@640 1461
mas01mj@640 1462 /** Create a blank ontology document */
mas01mj@640 1463 jOWL.create.document = function(href){
mas01mj@640 1464 var owl = [];
mas01mj@640 1465 var base = href || window.location.href+"#";
mas01mj@640 1466 owl.push('<?xml version="1.0"?>');
mas01mj@640 1467 owl.push('<'+__.rdf('RDF')+' xml:base="'+base+'" xmlns="'+base+'" '+__()+'>');
mas01mj@640 1468 owl.push(' <'+__.owl('Ontology')+' '+__.rdf('about')+'=""/>');
mas01mj@640 1469 owl.push('</'+__.rdf('RDF')+'>');
mas01mj@640 1470 return jOWL.fromString(owl.join('\n'));
mas01mj@640 1471 };
mas01mj@640 1472
mas01mj@640 1473 /** Extracts RDFa syntax from current page and feeds it to jOWL, simple implementation, only classes for the time being */
mas01mj@640 1474 jOWL.parseRDFa = function(fn, options){
mas01mj@640 1475 var entries = options.node ? $("[typeof]", options.node) : $("[typeof]");
mas01mj@640 1476 var doc = jOWL.create.document();
mas01mj@640 1477
mas01mj@640 1478 function property(p, node){
mas01mj@640 1479 var arr = [];
mas01mj@640 1480 $("[property="+p+"]", node).each(function(){ arr.push($(this).attr('content') || $(this).html());});
mas01mj@640 1481 if(node.attr('property') === p){ arr.push(node.attr('content') || node.html());}
mas01mj@640 1482 return arr;
mas01mj@640 1483 }
mas01mj@640 1484
mas01mj@640 1485 function rel(p, node){
mas01mj@640 1486 var arr = [];
mas01mj@640 1487 $("[rel="+p+"]", node).each(function(){ arr.push($(this).attr('resource'));});
mas01mj@640 1488 if(node.attr("rel") === p){ arr.push(node.attr('resource'));}
mas01mj@640 1489 return arr;
mas01mj@640 1490 }
mas01mj@640 1491
mas01mj@640 1492 function makeClass(node, ID){
mas01mj@640 1493 var cl = jOWL.create(__.owl, "Class", doc).attr(__.rdf, 'about', ID).appendTo(doc.documentElement);
mas01mj@640 1494
mas01mj@640 1495 var parents = property(__.rdfs("subClassOf"), node).concat(rel(__.rdfs("subClassOf"), node));
mas01mj@640 1496 for(var i = 0;i<parents.length;i++){
mas01mj@640 1497 var p = jOWL.create(__.rdfs, "subClassOf", doc).attr(__.rdf, "resource", parents[i]).appendTo(cl);
mas01mj@640 1498 }
mas01mj@640 1499 return cl;
mas01mj@640 1500 }
mas01mj@640 1501
mas01mj@640 1502 entries.each(function(){
mas01mj@640 1503 var node = $(this);
mas01mj@640 1504 var type = node.attr("typeof"), el;
mas01mj@640 1505
mas01mj@640 1506 if(type == __.owl("Class")){ el = makeClass(node, jOWL.resolveURI(node.attr("about")));}
mas01mj@640 1507
mas01mj@640 1508 $.each(property(__.rdfs('comment'), node), function(){
mas01mj@640 1509 jOWL.create(__.rdfs, "comment", doc).appendTo(el).text(this, true);
mas01mj@640 1510 });
mas01mj@640 1511
mas01mj@640 1512 $.each(property(__.rdfs('label'), node), function(){
mas01mj@640 1513 jOWL.create(__.rdfs, "label", doc).appendTo(el).text(this);
mas01mj@640 1514 });
mas01mj@640 1515 });
mas01mj@640 1516 jOWL.parse(doc, options);
mas01mj@640 1517 fn();
mas01mj@640 1518 };
mas01mj@640 1519
mas01mj@640 1520 /**
mas01mj@640 1521 Match part or whole of the rdfResource<String>
mas01mj@640 1522 Used for term searches, intend to (partially) replace it by a sparql-dl query later on
mas01mj@640 1523 options:
mas01mj@640 1524 filter: filter on a specific type, possible values: Class, Thing, ObjectProperty, DatatypeProperty
mas01mj@640 1525 exclude: exclude specific types, not fully implemented
mas01mj@640 1526 */
mas01mj@640 1527 jOWL.query = function(match, options){
mas01mj@640 1528 options = $.extend({exclude : false}, options);
mas01mj@640 1529 if(options.filter == 'Class'){ options.filter = __.owl("Class");}
mas01mj@640 1530 var that = this;
mas01mj@640 1531 //filter : [], exclude : false
mas01mj@640 1532 var items = new jOWL.Ontology.Array();
mas01mj@640 1533 var jsonobj = {};
mas01mj@640 1534 var test = jOWL.index("dictionary");
mas01mj@640 1535
mas01mj@640 1536 function store(item){
mas01mj@640 1537 var include = false, i = 0;
mas01mj@640 1538 if(options.filter){
mas01mj@640 1539 if(typeof options.filter == 'string'){ include = (options.filter == item[3]);}
mas01mj@640 1540 else { for(i = 0;i<options.filter.length;i++){ if(options.filter[i] == item[3]){ include = true;} } }
mas01mj@640 1541 }
mas01mj@640 1542 else if(options.exclude){
mas01mj@640 1543 include = true;
mas01mj@640 1544 if(typeof options.exclude == 'string'){ include = (options.exclude !== item[3]);}
mas01mj@640 1545 else { for(i = 0;i<options.exclude.length;i++){ if(options.exclude[i] == item[3]){ include = false;} } }
mas01mj@640 1546 }
mas01mj@640 1547 else { include = true;}
mas01mj@640 1548 if(!include){ return;}
mas01mj@640 1549 if(!jsonobj[item[1]]){ jsonobj[item[1]] = [];}
mas01mj@640 1550 jsonobj[item[1]].push( { term : item[0], locale: item[2], type: item[3] });
mas01mj@640 1551 }
mas01mj@640 1552
mas01mj@640 1553 for(var y = 0;y<test.length;y++){
mas01mj@640 1554 var item = test[y];
mas01mj@640 1555 var bool = options.exclude;
mas01mj@640 1556 var r = item[0].searchMatch(match);
mas01mj@640 1557 if(r > -1){
mas01mj@640 1558 if(options.locale){ if(options.locale == item[2]){ store(item);} }
mas01mj@640 1559 else { store(item);}
mas01mj@640 1560 }
mas01mj@640 1561 }
mas01mj@640 1562 return jsonobj;
mas01mj@640 1563 };
mas01mj@640 1564
mas01mj@640 1565 /**
mas01mj@640 1566 allows asynchronous looping over arrays (prevent bowser freezing).
mas01mj@640 1567 arr the array to loop asynchonrously over.
mas01mj@640 1568 options.modify(item) things to do with each item of the array
mas01mj@640 1569 options.onUpdate array the size of chewsize or smaller, containing processed entries
mas01mj@640 1570 options.onComplete(array of results) function triggered when looping has completed
mas01mj@640 1571 */
mas01mj@640 1572 jOWL.throttle =function(array, options){
mas01mj@640 1573 options = $.extend({
mas01mj@640 1574 modify : function(result){},
mas01mj@640 1575 //onUpdate : function(arr){},
mas01mj@640 1576 onComplete : function(arr){},
mas01mj@640 1577 async : true,
mas01mj@640 1578 chewsize : 5,
mas01mj@640 1579 startIndex : 0,
mas01mj@640 1580 timing : 5
mas01mj@640 1581 }, options);
mas01mj@640 1582 var temp = array.jOWL ? array.items : (array.jquery) ? $.makeArray(array) : array;
mas01mj@640 1583 var items = options.startIndex ? temp.slice(startIndex) : temp.concat(); //clone the array
mas01mj@640 1584 var results = [];
mas01mj@640 1585
mas01mj@640 1586 (function(){
mas01mj@640 1587 var count = options.chewsize;
mas01mj@640 1588 var a = [];
mas01mj@640 1589 while (count > 0 && items.length > 0)
mas01mj@640 1590 {
mas01mj@640 1591 var item = items.shift(); count--;
mas01mj@640 1592 var result = options.modify.call(item, item);
mas01mj@640 1593 if(result){ results.push(result); a.push(result);}
mas01mj@640 1594 }
mas01mj@640 1595 if(options.onUpdate){ options.onUpdate(a);}
mas01mj@640 1596
mas01mj@640 1597 if(items.length> 0){
mas01mj@640 1598 if(options.async){ setTimeout(arguments.callee, options.timing);}
mas01mj@640 1599 else {arguments.callee();}
mas01mj@640 1600 }
mas01mj@640 1601 else{ options.onComplete(results);}
mas01mj@640 1602 })();
mas01mj@640 1603 };
mas01mj@640 1604
mas01mj@640 1605 /** Creates a new resultobj for the SPARQL-DL functionality */
mas01mj@640 1606 jOWL.SPARQL_DL_Result = function(){
mas01mj@640 1607 this.assert = undefined;
mas01mj@640 1608 this.head = {}; //associative array of query parameters, with value jOWL Array of results
mas01mj@640 1609 this.results = []; //sparql-dl bindings
mas01mj@640 1610 this.isBound = false;
mas01mj@640 1611 };
mas01mj@640 1612
mas01mj@640 1613 jOWL.SPARQL_DL_Result.prototype = {
mas01mj@640 1614 sort : function(param){
mas01mj@640 1615 if(!param){ throw "parameter must be defined for sort function";}
mas01mj@640 1616 function sortResults(a, b){
mas01mj@640 1617 var o = a[param].name || a[param];
mas01mj@640 1618 var p = b[param].name || b[param];
mas01mj@640 1619 return (o < p) ? -1 : 1;
mas01mj@640 1620 }
mas01mj@640 1621 if(this.results){ this.results.sort(sortResults); }
mas01mj@640 1622 },
mas01mj@640 1623 jOWLArray : function(param){
mas01mj@640 1624 if(!param){ throw "parameter must be defined for jOWLArray function";}
mas01mj@640 1625 var arr = new jOWL.Ontology.Array();
mas01mj@640 1626 for(var i=0;i<this.results.length;i++){
mas01mj@640 1627 if(this.results[i][param]){ arr.pushUnique(this.results[i][param]);}
mas01mj@640 1628 }
mas01mj@640 1629 return arr;
mas01mj@640 1630 },
mas01mj@640 1631 /** Filter head Parameters */
mas01mj@640 1632 filter : function(param, arr){
mas01mj@640 1633 if(this.head[param] === undefined){this.head[param] = arr;}
mas01mj@640 1634 else {
mas01mj@640 1635 var self = this;
mas01mj@640 1636 this.head[param].filter(function(){ return (arr.contains(this));});
mas01mj@640 1637 arr.filter(function(){ return (self.head[param].contains(this));});
mas01mj@640 1638 }
mas01mj@640 1639 },
mas01mj@640 1640 /** Update result section, results = SPARQL_DL_Array */
mas01mj@640 1641 bind : function(results){
mas01mj@640 1642 if(!this.isBound){//new results
mas01mj@640 1643 this.results = this.results.concat(results.arr);
mas01mj@640 1644 this.isBound = true;
mas01mj@640 1645 return;
mas01mj@640 1646 }
mas01mj@640 1647 var multimapping = -1;
mas01mj@640 1648 for(x in results.mappings){ multimapping++; }
mas01mj@640 1649 var toAdd = [];
mas01mj@640 1650
mas01mj@640 1651 for(x in results.mappings){
mas01mj@640 1652 var otherKeys;
mas01mj@640 1653 if(multimapping){
mas01mj@640 1654 otherKeys = results.keyCentric(x);
mas01mj@640 1655 }
mas01mj@640 1656 for(var i = this.results.length-1;i>=0;i--){
mas01mj@640 1657 var valueX = this.results[i][x];
mas01mj@640 1658 if(valueX){
mas01mj@640 1659 if(!results.mappings[x].contains(valueX)){
mas01mj@640 1660 this.results.splice(i, 1);
mas01mj@640 1661 continue;
mas01mj@640 1662 }
mas01mj@640 1663 if(multimapping){
mas01mj@640 1664 var keyArr= otherKeys[valueX.URI];
mas01mj@640 1665 //ignoring the opposite for now (assuming original key x is unique (limits statements))
mas01mj@640 1666 //TODO: improve these result merging methods/flexibility
mas01mj@640 1667 for(var oK = 0; oK < keyArr.length;oK++){
mas01mj@640 1668 var obj = (oK === 0) ? this.results[i] : {};
mas01mj@640 1669 var valueY = keyArr[oK];
mas01mj@640 1670 obj[x] = valueX;
mas01mj@640 1671 for(yK in valueY){ obj[yK] = valueY[yK]; }
mas01mj@640 1672 toAdd.push(obj);
mas01mj@640 1673 }
mas01mj@640 1674 this.results.splice(i, 1);
mas01mj@640 1675 }
mas01mj@640 1676 }
mas01mj@640 1677 }
mas01mj@640 1678 }
mas01mj@640 1679 this.results = this.results.concat(toAdd);
mas01mj@640 1680 }
mas01mj@640 1681 };
mas01mj@640 1682 /** Creates a new query for the SPARQL-DL functionality */
mas01mj@640 1683 jOWL.SPARQL_DL_Query = function(syntax, parameters){
mas01mj@640 1684 this.parse(syntax);
mas01mj@640 1685 this.fill(parameters);
mas01mj@640 1686 this.entries = this.entries.sort(this.sort);
mas01mj@640 1687 };
mas01mj@640 1688
mas01mj@640 1689 jOWL.SPARQL_DL_Query.prototype = {
mas01mj@640 1690 parse : function(syntax){
mas01mj@640 1691 var r2 = /(\w+)[(]([^)]+)[)]/;
mas01mj@640 1692 var entries = syntax.match(/(\w+[(][^)]+[)])/g);
mas01mj@640 1693 if(!entries){ this.error = "invalid abstract sparql-dl syntax"; return;}
mas01mj@640 1694 entries = jOWL.priv.Array.unique(entries);
mas01mj@640 1695 for(var i = 0;i<entries.length;i++){
mas01mj@640 1696 var y = entries[i].match(r2);
mas01mj@640 1697 if(y.length != 3){ this.error = "invalid abstract sparql-dl syntax"; return;}
mas01mj@640 1698 entries[i] = [y[1], y[2].replace(/ /g, "").split(',')];
mas01mj@640 1699 }
mas01mj@640 1700 this.entries = entries;
mas01mj@640 1701 },
mas01mj@640 1702 fill : function(parameters){
mas01mj@640 1703 for(var i = 0;i<this.entries.length;i++){
mas01mj@640 1704 for(var j =0; j<this.entries[i][1].length; j++){
mas01mj@640 1705 var p = parameters[this.entries[i][1][j]];
mas01mj@640 1706 if(p !== undefined) { this.entries[i][1][j] = p;}
mas01mj@640 1707 else {
mas01mj@640 1708 p = this.entries[i][1][j];
mas01mj@640 1709 if(p.charAt(0) != '?')
mas01mj@640 1710 {
mas01mj@640 1711 if(this.entries[i][0] == "PropertyValue" && j == 2)
mas01mj@640 1712 {
mas01mj@640 1713 var m = p.match(/^["'](.+)["']$/);
mas01mj@640 1714 if(m && m.length == 2){ this.entries[i][1][j] = {test: m[1]}; break;}
mas01mj@640 1715 }
mas01mj@640 1716 this.entries[i][1][j] = jOWL(p);
mas01mj@640 1717 if(this.entries[i][1][j] === null){this.entries.error = "a parameter in the query was not found"; return;}
mas01mj@640 1718 }
mas01mj@640 1719 }
mas01mj@640 1720 }
mas01mj@640 1721 }
mas01mj@640 1722 },
mas01mj@640 1723 sort : function(a, b){
mas01mj@640 1724 var i;
mas01mj@640 1725 if(a[1].length == 1){ return (b[0] == 'PropertyValue') ? 1 : -1;}
mas01mj@640 1726 if(b[1].length == 1){ return (a[0] == 'PropertyValue') ? -1 : 1;}
mas01mj@640 1727 var avar = 0; for(i = 0;i<a[1].length;i++){ if(typeof a[1][i] == 'string'){ avar++;} }
mas01mj@640 1728 var bvar = 0; for(i = 0;i<a[1].length;i++){ if(typeof b[1][i] == 'string'){ bvar++;} }
mas01mj@640 1729 if(avar != bvar){ return avar - bvar;}
mas01mj@640 1730 if(a[0] == 'Type' && b[0] != 'Type'){ return -1;}
mas01mj@640 1731 if(a[0] != 'Type' && b[0] == 'Type'){ return 1;}
mas01mj@640 1732 return 0;
mas01mj@640 1733 }
mas01mj@640 1734 };
mas01mj@640 1735
mas01mj@640 1736 /** Private function */
mas01mj@640 1737 function _Binding(bindingarray){
mas01mj@640 1738 this.value = {};
mas01mj@640 1739 this.arr = bindingarray;
mas01mj@640 1740 }
mas01mj@640 1741
mas01mj@640 1742 _Binding.prototype = {
mas01mj@640 1743 bind : function(key, value){
mas01mj@640 1744 this.value[key] = value;
mas01mj@640 1745 if(!this.arr.mappings[key]){ this.arr.mappings[key] = new jOWL.Ontology.Array();}
mas01mj@640 1746 this.arr.mappings[key].push(value);
mas01mj@640 1747 return this;
mas01mj@640 1748 }
mas01mj@640 1749 };
mas01mj@640 1750
mas01mj@640 1751 /** Local Function, private access, Temp results */
mas01mj@640 1752 function SPARQL_DL_Array(keys){
mas01mj@640 1753 this.arr = [];
mas01mj@640 1754 this.mappings = {};
mas01mj@640 1755
mas01mj@640 1756 if(keys){
mas01mj@640 1757 for(var i =0;i<keys.length;i++){
mas01mj@640 1758 if(keys[i]){this.mappings[keys[i]] = new jOWL.Ontology.Array();}
mas01mj@640 1759 }
mas01mj@640 1760 }
mas01mj@640 1761 }
mas01mj@640 1762
mas01mj@640 1763 SPARQL_DL_Array.prototype = {
mas01mj@640 1764 add : function(binding){
mas01mj@640 1765 this.arr.push(binding.value);
mas01mj@640 1766 return binding;
mas01mj@640 1767 },
mas01mj@640 1768 push : function(key, value){
mas01mj@640 1769 var binding = new _Binding(this);
mas01mj@640 1770 binding.bind(key, value);
mas01mj@640 1771 this.arr.push(binding.value);
mas01mj@640 1772 return binding;
mas01mj@640 1773 },
mas01mj@640 1774 keyCentric : function(keyX){
mas01mj@640 1775 var arr = {};
mas01mj@640 1776 for(var i = this.arr.length-1;i>=0;i--){
mas01mj@640 1777 if(this.arr[i][keyX]){
mas01mj@640 1778 if(!arr[this.arr[i][keyX].URI]){ arr[this.arr[i][keyX].URI] = []; }
mas01mj@640 1779 arr[this.arr[i][keyX].URI].push(this.arr[i]);
mas01mj@640 1780 }
mas01mj@640 1781 }
mas01mj@640 1782 return arr;
mas01mj@640 1783 },
mas01mj@640 1784 get : function(key)
mas01mj@640 1785 {
mas01mj@640 1786 return (this.mappings[key]) ? this.mappings[key] : new jOWL.Ontology.Array();
mas01mj@640 1787 },
mas01mj@640 1788 getArray : function(){
mas01mj@640 1789 //check mappings for presence, discard arr entries based on that, return remainder.
mas01mj@640 1790 for(var i = this.arr.length - 1;i>=0;i--){
mas01mj@640 1791 var binding = this.arr[i], splice = false;
mas01mj@640 1792 for(key in binding){
mas01mj@640 1793 if(!splice){
mas01mj@640 1794 splice = (!this.mappings[key] || !this.mappings[key].contains(binding[key]));
mas01mj@640 1795 }
mas01mj@640 1796 }
mas01mj@640 1797 if(splice){
mas01mj@640 1798 this.arr.splice(i, 1);
mas01mj@640 1799 }
mas01mj@640 1800 }
mas01mj@640 1801 return this;
mas01mj@640 1802 }
mas01mj@640 1803 };
mas01mj@640 1804
mas01mj@640 1805 /**
mas01mj@640 1806 Support for abstract SPARQl-DL syntax
mas01mj@640 1807 options.onComplete: function triggered when all individuals have been looped over
mas01mj@640 1808 options.childDepth: depth to fetch children, default 5, impacts performance
mas01mj@640 1809 options.chewsize: arrays will be processed in smaller chunks (asynchronous), with size indicated by chewsize, default 10
mas01mj@640 1810 options.async: default true, query asynchronously
mas01mj@640 1811 parameters: prefill some sparql-dl parameters with jOWL objects
mas01mj@640 1812 execute: start query, results are passed through options.onComplete
mas01mj@640 1813 */
mas01mj@640 1814 jOWL.SPARQL_DL = function(syntax, parameters, options){
mas01mj@640 1815 if(!(this instanceof arguments.callee)){ return new jOWL.SPARQL_DL(syntax, parameters, options);}
mas01mj@640 1816 var self = this;
mas01mj@640 1817 this.parameters = $.extend({}, parameters);
mas01mj@640 1818 this.query = new jOWL.SPARQL_DL_Query(syntax, this.parameters).entries;
mas01mj@640 1819 this.result = new jOWL.SPARQL_DL_Result();
mas01mj@640 1820 this.options = $.extend({onComplete: function(results){}}, options);
mas01mj@640 1821 };
mas01mj@640 1822
mas01mj@640 1823 jOWL.SPARQL_DL.prototype = {
mas01mj@640 1824 error: function(msg){ this.result.error = msg; return this.options.onComplete(this.result);},
mas01mj@640 1825 /**
mas01mj@640 1826 if(options.async == false) then this method returns the result of options.onComplete,
mas01mj@640 1827 no matter what, result is always passed in options.onComplete
mas01mj@640 1828 */
mas01mj@640 1829 execute : function(options){
mas01mj@640 1830 var self = this;
mas01mj@640 1831 this.options = $.extend(this.options, options);
mas01mj@640 1832 if(this.query.error){ return this.error(this.query.error);}
mas01mj@640 1833
mas01mj@640 1834 var resultobj = this.result;
mas01mj@640 1835 var i = 0;
mas01mj@640 1836 var loopoptions = $.extend({}, this.options);
mas01mj@640 1837 loopoptions.onComplete = function(results){ i++; resultobj = results; loop(i);};
mas01mj@640 1838
mas01mj@640 1839 if(!this.query.length){
mas01mj@640 1840 resultobj.error = "no query found or query did not parse properly";
mas01mj@640 1841 return self.options.onComplete(resultobj);
mas01mj@640 1842 }
mas01mj@640 1843
mas01mj@640 1844 function loop(i){
mas01mj@640 1845 if(i < self.query.length){
mas01mj@640 1846 self.process(self.query[i], resultobj, loopoptions );
mas01mj@640 1847 }
mas01mj@640 1848 else {
mas01mj@640 1849 for(var j =0;j<resultobj.results.length;j++){ //Convert Literals into strings
mas01mj@640 1850 var b = resultobj.results[j];
mas01mj@640 1851 for(x in b){
mas01mj@640 1852 if(b[x] instanceof jOWL.Literal){b[x] = b[x].name;}
mas01mj@640 1853 }
mas01mj@640 1854 }
mas01mj@640 1855 return self.options.onComplete(resultobj);
mas01mj@640 1856 }
mas01mj@640 1857 }
mas01mj@640 1858 loop(i);
mas01mj@640 1859 },
mas01mj@640 1860 /** results are passed in the options.onComplete function */
mas01mj@640 1861 process: function(entry, resultobj, options){
mas01mj@640 1862 var self = this;
mas01mj@640 1863 options = $.extend({chewsize: 10, async : true, onComplete : function(results){}}, options);
mas01mj@640 1864 var q = entry[0];
mas01mj@640 1865 var sizes = {
mas01mj@640 1866 "Type": [__.owl('Thing'), __.owl('Class')],
mas01mj@640 1867 "DirectType": [__.owl('Thing'), __.owl('Class')],
mas01mj@640 1868 "PropertyValue" : [false, false, false],
mas01mj@640 1869 "Class": [false],
mas01mj@640 1870 "Thing": [false],
mas01mj@640 1871 "ObjectProperty": [false],
mas01mj@640 1872 "DatatypeProperty": [false],
mas01mj@640 1873 "SubClassOf" : [__.owl('Class'), __.owl('Class')],
mas01mj@640 1874 "DirectSubClassOf" : [__.owl('Class'), __.owl('Class')]
mas01mj@640 1875 };
mas01mj@640 1876
mas01mj@640 1877 if(!sizes[q]){ return self.error("'"+q+"' queries are not implemented");}
mas01mj@640 1878 if(sizes[q].length != entry[1].length){ return self.error("invalid SPARQL-DL "+q+" specifications, "+sizes[q].length+" parameters required");}
mas01mj@640 1879 for(var i = 0;i<entry[1].length;i++){
mas01mj@640 1880 var v = sizes[q][i];
mas01mj@640 1881 if(v){
mas01mj@640 1882 var m = entry[1][i];
mas01mj@640 1883 if(typeof m != 'string' && m.type != v){ return self.error("Parameter "+i+" in SPARQL-DL Query for "+q+" must be of the type: "+v);}
mas01mj@640 1884 }
mas01mj@640 1885 }
mas01mj@640 1886 if(q == "DirectType"){ options.childDepth = 0; return self.fn.Type.call(self, entry[1], resultobj, options);}
mas01mj@640 1887 else if(q == "DirectSubClassOf"){ options.childDepth = 1; return self.fn.SubClassOf.call(self, entry[1], resultobj, options);}
mas01mj@640 1888 return self.fn[q].call(self, entry[1], resultobj, options);
mas01mj@640 1889 },
mas01mj@640 1890 fn : {
mas01mj@640 1891 "SubClassOf" : function(syntax, resultobj, options){
mas01mj@640 1892 var atom = new jOWL.SPARQL_DL.DoubleAtom(syntax, resultobj.head);
mas01mj@640 1893 var results = new SPARQL_DL_Array();
mas01mj@640 1894
mas01mj@640 1895 if(atom.source.isURI() && atom.target.isURI()){//assert
mas01mj@640 1896 if(resultobj.assert !== false){
mas01mj@640 1897 var parents = atom.source.value.ancestors();
mas01mj@640 1898 resultobj.assert = parents.contains(atom.target.value);
mas01mj@640 1899 }
mas01mj@640 1900 return options.onComplete(resultobj);
mas01mj@640 1901 }
mas01mj@640 1902 else if(atom.source.isURI()){//get parents
mas01mj@640 1903 atom.source.value.ancestors().each(function(){
mas01mj@640 1904 results.push(atom.target.value, this);
mas01mj@640 1905 });
mas01mj@640 1906 resultobj.filter(atom.target.value, results.get(atom.target.value));
mas01mj@640 1907 resultobj.bind(results.getArray());
mas01mj@640 1908 return options.onComplete(resultobj);
mas01mj@640 1909 }
mas01mj@640 1910 else if(atom.target.isURI()){//get children
mas01mj@640 1911 atom.target.value.descendants(options.childDepth).each(function(){
mas01mj@640 1912 results.push(atom.source.value, this);
mas01mj@640 1913 });
mas01mj@640 1914 resultobj.filter(atom.source.value, results.get(atom.source.value));
mas01mj@640 1915 resultobj.bind(results.getArray());
mas01mj@640 1916 return options.onComplete(resultobj);
mas01mj@640 1917 }
mas01mj@640 1918 else{//both undefined
mas01mj@640 1919 return this.error('Unsupported SubClassOf query');
mas01mj@640 1920 }
mas01mj@640 1921 },
mas01mj@640 1922 "Type" : function(syntax, resultobj, options){
mas01mj@640 1923 var atom = new jOWL.SPARQL_DL.DoubleAtom(syntax, resultobj.head);
mas01mj@640 1924
mas01mj@640 1925 function addIndividual(cl){
mas01mj@640 1926 if(indivs[this.URI]){ return;}
mas01mj@640 1927 var b = results.push(atom.source.value, this);
mas01mj@640 1928 if(addTarget){ b.bind(atom.target.value, cl);}
mas01mj@640 1929 indivs[this.URI] = true;
mas01mj@640 1930 }
mas01mj@640 1931
mas01mj@640 1932 function traverse(node, match){
mas01mj@640 1933 var a = node.parents();
mas01mj@640 1934 var found = false;
mas01mj@640 1935 if(a.contains(match)){ found = true;}
mas01mj@640 1936 else {
mas01mj@640 1937 a.each(function(){
mas01mj@640 1938 if(this == jOWL.Thing){ return;}
mas01mj@640 1939 if(!found && traverse(this, match)){ found = true;} });
mas01mj@640 1940 }
mas01mj@640 1941 return found;
mas01mj@640 1942 }
mas01mj@640 1943
mas01mj@640 1944 if(atom.source.isURI() && atom.target.isURI()){//assert
mas01mj@640 1945 return jOWL.SPARQL_DL.priv.assert(resultobj, function(){
mas01mj@640 1946 var cl = atom.source.value.owlClass();
mas01mj@640 1947 if(cl.URI == atom.target.value.URI){ return true;}
mas01mj@640 1948 return traverse(cl, atom.target.value);
mas01mj@640 1949 }, options.onComplete);
mas01mj@640 1950 }
mas01mj@640 1951 else if(atom.source.getURIs() && !atom.target.getURIs()){//get class
mas01mj@640 1952 var results = new SPARQL_DL_Array();
mas01mj@640 1953 var addSource = !atom.source.isURI();
mas01mj@640 1954 var addTarget = !atom.target.isURI();
mas01mj@640 1955 atom.source.getURIs().each(function(){
mas01mj@640 1956 var b;
mas01mj@640 1957 if(addTarget){ b = results.push(atom.target.value, this.owlClass());}
mas01mj@640 1958 if(addSource){
mas01mj@640 1959 if(addTarget){ b.bind(atom.source.value, this);}
mas01mj@640 1960 else {results.push(atom.source.value, this);}
mas01mj@640 1961 }
mas01mj@640 1962 });
mas01mj@640 1963 if(addSource){ resultobj.filter(atom.source.value, results.get(atom.source.value));}
mas01mj@640 1964 if(addTarget){ resultobj.filter(atom.target.value, results.get(atom.target.value));}
mas01mj@640 1965 resultobj.bind(results.getArray());
mas01mj@640 1966 return options.onComplete(resultobj);
mas01mj@640 1967 }
mas01mj@640 1968 else if(atom.target.getURIs()){//get Individuals, slow
mas01mj@640 1969 var addTarget = !atom.target.isURI();
mas01mj@640 1970 var classlist = atom.target.getURIs(),
mas01mj@640 1971 classes = {}, indivs = {};
mas01mj@640 1972
mas01mj@640 1973 var results = new SPARQL_DL_Array();
mas01mj@640 1974
mas01mj@640 1975
mas01mj@640 1976 classlist.each(function(){ //expand list of classes, not very fast!
mas01mj@640 1977 if(classes[this.URI]){ return;}
mas01mj@640 1978 var oneOf = this.oneOf(), cl = this;
mas01mj@640 1979 if(oneOf.length){ oneOf.each(function(){ addIndividual.call(this, cl);});}
mas01mj@640 1980 else{ this.descendants(options.childDepth).each(function(){ //this is the slower call
mas01mj@640 1981 classes[this.URI] = true;
mas01mj@640 1982 }); }
mas01mj@640 1983 classes[this.URI] = true;
mas01mj@640 1984 });
mas01mj@640 1985
mas01mj@640 1986 for(x in classes){
mas01mj@640 1987 var individuals = jOWL.index("Thing")[x];
mas01mj@640 1988 if(individuals){
mas01mj@640 1989 var cl = jOWL.index('ID')[x];
mas01mj@640 1990 if(options.onUpdate){ options.onUpdate(individuals);}
mas01mj@640 1991 individuals.each(function(){
mas01mj@640 1992 addIndividual.call(this, cl);
mas01mj@640 1993 });
mas01mj@640 1994 }
mas01mj@640 1995 }
mas01mj@640 1996 resultobj.filter(atom.source.value, results.get(atom.source.value));
mas01mj@640 1997 resultobj.bind(results.getArray());
mas01mj@640 1998 return options.onComplete(resultobj);
mas01mj@640 1999 }
mas01mj@640 2000 return this.error('Unsupported Type query');
mas01mj@640 2001 },
mas01mj@640 2002 "Thing" : function(syntax, resultobj, options){
mas01mj@640 2003 jOWL.SPARQL_DL.priv.IDQuery(syntax[0], "isThing", resultobj, options);
mas01mj@640 2004 },
mas01mj@640 2005 "Class" : function(syntax, resultobj, options){ console.log('cl');
mas01mj@640 2006 jOWL.SPARQL_DL.priv.IDQuery(syntax[0], "isClass", resultobj, options);
mas01mj@640 2007 },
mas01mj@640 2008 "ObjectProperty" : function(syntax, resultobj, options){
mas01mj@640 2009 jOWL.SPARQL_DL.priv.PropertyQuery(syntax[0], jOWL.index("property").items, "isObjectProperty", resultobj, options);
mas01mj@640 2010 },
mas01mj@640 2011 "DatatypeProperty" : function(syntax, resultobj, options){
mas01mj@640 2012 jOWL.SPARQL_DL.priv.PropertyQuery(syntax[0], jOWL.index("property").items, "isDatatypeProperty", resultobj, options);
mas01mj@640 2013 },
mas01mj@640 2014 "PropertyValue" : function(syntax, resultobj, options){
mas01mj@640 2015 var atom = new jOWL.SPARQL_DL.TripleAtom(syntax, resultobj.head);
mas01mj@640 2016
mas01mj@640 2017 if(atom.source.isURI() && atom.property.isURI() && atom.target.isURI()){//assert
mas01mj@640 2018 if(resultobj.assert !== false){
mas01mj@640 2019 jOWL.SPARQL_DL.priv.PropertyValuegetSourceInfo(atom.source.value, atom.property.value, atom.target.value, resultobj, { assert : true });
mas01mj@640 2020 }
mas01mj@640 2021 return options.onComplete(resultobj);
mas01mj@640 2022 }
mas01mj@640 2023
mas01mj@640 2024 if(!atom.source.getURIs()){
mas01mj@640 2025 jOWL.SPARQL_DL.priv.IDQuery(atom.source.value, ["isClass", "isThing"], resultobj, options);
mas01mj@640 2026 return;
mas01mj@640 2027 }
mas01mj@640 2028 var filterTarget = atom.target.isVar() ? atom.target.value : false;
mas01mj@640 2029 var filterProperty = atom.property.isVar() ? atom.property.value : false;
mas01mj@640 2030 var filterSource = atom.source.isVar() ? atom.source.value : false;
mas01mj@640 2031 jOWL.SPARQL_DL.priv.PropertyValuegetSourceInfo(atom.source.getURIs(), atom.property.getURIs(), atom.target.getURIs(), resultobj,
mas01mj@640 2032 {
mas01mj@640 2033 filterTarget : filterTarget, filterProperty : filterProperty, filterSource : filterSource
mas01mj@640 2034 });
mas01mj@640 2035 return options.onComplete(resultobj);
mas01mj@640 2036 }
mas01mj@640 2037 }
mas01mj@640 2038 };
mas01mj@640 2039
mas01mj@640 2040 jOWL.SPARQL_DL.priv = {
mas01mj@640 2041 assert : function(resultobj, fn, onComplete){
mas01mj@640 2042 if(resultobj.assert !== false){
mas01mj@640 2043 resultobj.assert = fn();
mas01mj@640 2044 }
mas01mj@640 2045 onComplete(resultobj);
mas01mj@640 2046 },
mas01mj@640 2047 //reusable function
mas01mj@640 2048 PropertyValuegetSourceInfo : function(jSource, property, target, resultobj, options){
mas01mj@640 2049 if(!(jSource.isArray)){
mas01mj@640 2050 return jOWL.SPARQL_DL.priv.PropertyValuegetSourceInfo(new jOWL.Ontology.Array([jSource]), property, target, resultobj, options);
mas01mj@640 2051 }
mas01mj@640 2052
mas01mj@640 2053 options = $.extend({}, options);
mas01mj@640 2054 var results = new SPARQL_DL_Array([options.filterSource, options.filterProperty, options.filterTarget]),
mas01mj@640 2055 match = false;
mas01mj@640 2056 jSource.each(function(){
mas01mj@640 2057 var source = this;
mas01mj@640 2058 if(target && target.isArray && target.length == 1){
mas01mj@640 2059 var literal = target.get(0).test;
mas01mj@640 2060 if(literal){ target = literal;}//unwrap literal expressions
mas01mj@640 2061 }
mas01mj@640 2062 var restrictions = source.sourceof(property, target);
mas01mj@640 2063 if(options.assert){
mas01mj@640 2064 if(restrictions.length > 0){ match = true;}
mas01mj@640 2065 return;
mas01mj@640 2066 }
mas01mj@640 2067 if(!restrictions.length){ return;}
mas01mj@640 2068 restrictions.each(function(){
mas01mj@640 2069 var binding = new _Binding(results);
mas01mj@640 2070 if(options.filterSource){
mas01mj@640 2071 binding.bind(options.filterSource, source);
mas01mj@640 2072 if(!options.filterProperty && !options.filterTarget){ results.add(binding); return false;}
mas01mj@640 2073 }
mas01mj@640 2074 if(options.filterProperty){
mas01mj@640 2075 binding.bind(options.filterProperty, this.property);
mas01mj@640 2076 }
mas01mj@640 2077 if(options.filterTarget){
mas01mj@640 2078 binding.bind(options.filterTarget, this.getTarget());
mas01mj@640 2079 }
mas01mj@640 2080 results.add(binding);
mas01mj@640 2081 });
mas01mj@640 2082 return true;
mas01mj@640 2083 });
mas01mj@640 2084 if(options.assert){
mas01mj@640 2085 resultobj.assert = match;
mas01mj@640 2086 return resultobj.assert;
mas01mj@640 2087 }
mas01mj@640 2088 if(options.filterSource){ resultobj.filter(options.filterSource, results.get(options.filterSource));}
mas01mj@640 2089 if(options.filterProperty){ resultobj.filter(options.filterProperty, results.get(options.filterProperty));}
mas01mj@640 2090 if(options.filterTarget) { resultobj.filter(options.filterTarget, results.get(options.filterTarget));}
mas01mj@640 2091 resultobj.bind(results.getArray());
mas01mj@640 2092 },
mas01mj@640 2093 hasClassID: function(match, classID){
mas01mj@640 2094 if(Object.prototype.toString.call(classID) === '[object Array]'){
mas01mj@640 2095 for(var i =0;i<classID.length;i++){
mas01mj@640 2096 if(match[classID]){ return true;}
mas01mj@640 2097 }
mas01mj@640 2098 } else if(match[classID]){ return true;}
mas01mj@640 2099 return false;
mas01mj@640 2100 },
mas01mj@640 2101 IDQuery : function(parameter, classID, resultobj, options){
mas01mj@640 2102 var atom = new jOWL.SPARQL_DL.Atom(parameter, resultobj.head);
mas01mj@640 2103 if(atom.isURI()){
mas01mj@640 2104 return jOWL.SPARQL_DL.priv.assert(resultobj, function(){
mas01mj@640 2105 return jOWL.SPARQL_DL.priv.hasClassID(atom.getURIs().get(0), classID);
mas01mj@640 2106 }, options.onComplete);
mas01mj@640 2107 }
mas01mj@640 2108 var results = new SPARQL_DL_Array();
mas01mj@640 2109 for(x in jOWL.index("ID")){
mas01mj@640 2110 var match = jOWL.index("ID")[x];
mas01mj@640 2111 if(jOWL.SPARQL_DL.priv.hasClassID(match, classID)){ results.push(parameter, match);}
mas01mj@640 2112 }
mas01mj@640 2113 resultobj.filter(parameter, results.get(parameter));
mas01mj@640 2114 resultobj.bind(results.getArray());
mas01mj@640 2115 options.onComplete(resultobj);
mas01mj@640 2116 },
mas01mj@640 2117 PropertyQuery : function(parameter, index, className, resultobj, options){
mas01mj@640 2118 var atom = new jOWL.SPARQL_DL.Atom(parameter, resultobj.head);
mas01mj@640 2119 if(atom.isURI()){
mas01mj@640 2120 return jOWL.SPARQL_DL.priv.assert(resultobj, function(){
mas01mj@640 2121 return jOWL.SPARQL_DL.priv.hasClassID(atom.getURIs().get(0), className);
mas01mj@640 2122 }, options.onComplete);
mas01mj@640 2123 }
mas01mj@640 2124 var results = new SPARQL_DL_Array();
mas01mj@640 2125 var tr = new jOWL.throttle(index, $.extend({}, options, {
mas01mj@640 2126 modify : function(result){
mas01mj@640 2127 if(!result.jOWL){ result = jOWL(result);}
mas01mj@640 2128 if(jOWL.SPARQL_DL.priv.hasClassID(result, className)){results.push(parameter, result);}
mas01mj@640 2129 return false;
mas01mj@640 2130 },
mas01mj@640 2131 onComplete : function(){
mas01mj@640 2132 resultobj.filter(parameter, results.get(parameter));
mas01mj@640 2133 resultobj.bind(results.getArray());
mas01mj@640 2134 options.onComplete(resultobj);
mas01mj@640 2135 }
mas01mj@640 2136 }));
mas01mj@640 2137 }
mas01mj@640 2138 };
mas01mj@640 2139
mas01mj@640 2140 jOWL.SPARQL_DL.TripleAtom = function(syntax, store){
mas01mj@640 2141 this.source = new jOWL.SPARQL_DL.Atom(syntax[0], store);
mas01mj@640 2142 this.property = new jOWL.SPARQL_DL.Atom(syntax[1], store);
mas01mj@640 2143 this.target = new jOWL.SPARQL_DL.Atom(syntax[2], store);
mas01mj@640 2144 };
mas01mj@640 2145
mas01mj@640 2146 jOWL.SPARQL_DL.DoubleAtom = function(syntax, store){
mas01mj@640 2147 this.source = new jOWL.SPARQL_DL.Atom(syntax[0], store);
mas01mj@640 2148 this.target = new jOWL.SPARQL_DL.Atom(syntax[1], store);
mas01mj@640 2149 };
mas01mj@640 2150
mas01mj@640 2151
mas01mj@640 2152 jOWL.SPARQL_DL.Atom = function(syntax, store){
mas01mj@640 2153 this.value = syntax;
mas01mj@640 2154 this.type = 0;
mas01mj@640 2155 if(typeof syntax == 'string'){
mas01mj@640 2156 if(syntax.indexOf('?') === 0){
mas01mj@640 2157 this.type = this.VAR;
mas01mj@640 2158 if(store && store[syntax]){ this.mappings = store[syntax];}
mas01mj@640 2159 } else {
mas01mj@640 2160 this.type = this.LITERAL;
mas01mj@640 2161 }
mas01mj@640 2162 } else {
mas01mj@640 2163 this.type = this.URI;
mas01mj@640 2164 }
mas01mj@640 2165 };
mas01mj@640 2166
mas01mj@640 2167 jOWL.SPARQL_DL.Atom.prototype = {
mas01mj@640 2168 URI : 1, LITERAL : 2, VAR : 3,
mas01mj@640 2169 getURIs : function(){
mas01mj@640 2170 if(this.isURI()){return new jOWL.Ontology.Array([this.value]);}
mas01mj@640 2171 return this.mappings;
mas01mj@640 2172 },
mas01mj@640 2173 isVar : function(){return this.type == this.VAR;},
mas01mj@640 2174 isLiteral : function(){return this.type == this.LITERAL;},
mas01mj@640 2175 isURI : function(){ return this.type == this.URI;}
mas01mj@640 2176 };
mas01mj@640 2177
mas01mj@640 2178 /**
mas01mj@640 2179 * @return Associative array of parameters in the current documents URL
mas01mj@640 2180 */
mas01mj@640 2181 jOWL.getURLParameters = function(){
mas01mj@640 2182 var href = window.location.href.split("?", 2), param = {};
mas01mj@640 2183 if(href.length == 1){ return {};}
mas01mj@640 2184 var qstr = href[1].split('&');
mas01mj@640 2185 for(var i =0;i<qstr.length;i++){
mas01mj@640 2186 var arr = qstr[i].split("=");
mas01mj@640 2187 if(arr.length == 2){ param[arr[0]] = arr[1];}
mas01mj@640 2188 }
mas01mj@640 2189 return param;
mas01mj@640 2190 };
mas01mj@640 2191
mas01mj@640 2192 /**
mas01mj@640 2193 Without arguments this function will parse the current url and see if any parameters are defined, returns a JOWL object
mas01mj@640 2194 @return With argument it will return a string that identifies the potential permalink fr the given entry
mas01mj@640 2195 */
mas01mj@640 2196 jOWL.permalink = function(entry){
mas01mj@640 2197 if(!entry){
mas01mj@640 2198 var param = jOWL.getURLParameters();
mas01mj@640 2199 if(param.owlClass){ return jOWL(unescape(param.owlClass));}
mas01mj@640 2200 }
mas01mj@640 2201 else {
mas01mj@640 2202 if(!entry.URI){ return false;}
mas01mj@640 2203 var href = window.location.href.split("?", 2);
mas01mj@640 2204 if(window.location.search){ href = href[0];}
mas01mj@640 2205 if(entry.isClass){ return href+'?owlClass='+escape(entry.URI);}
mas01mj@640 2206 }
mas01mj@640 2207 return false;
mas01mj@640 2208 };
mas01mj@640 2209
mas01mj@640 2210 /** Convert an item into Manchester syntax, currently only for oneOf
mas01mj@640 2211 * @return String
mas01mj@640 2212 */
mas01mj@640 2213 jOWL.Manchester = function(owlElement){
mas01mj@640 2214 var syntax = [];
mas01mj@640 2215 if(owlElement.isClass){
mas01mj@640 2216 var oneOf = owlElement.oneOf().map(function(){ return this.label();});
mas01mj@640 2217 if(oneOf.length){ syntax.push("{ "+oneOf.join(", ")+" }");}
mas01mj@640 2218 }
mas01mj@640 2219 return syntax.join(", ");
mas01mj@640 2220 };
mas01mj@640 2221
mas01mj@640 2222 })(jQuery);
mas01mj@640 2223
mas01mj@640 2224 /**
mas01mj@640 2225 * @return 1 for exact match, 0 for partial match, -1 for no match.
mas01mj@640 2226 */
mas01mj@640 2227 String.prototype.searchMatch = function(matchstring, exact){
mas01mj@640 2228 if(this.search(new RegExp(matchstring, "i")) > -1){ return 1;} //contained within
mas01mj@640 2229 var c = 0; var arr = matchstring.match(new RegExp("\\w+", "ig"));
mas01mj@640 2230 for(var i = 0;i<arr.length;i++){ if(this.search(arr[i]) > -1){ c++;} }
mas01mj@640 2231 if(c == arr.length){ return 0;} //word shift
mas01mj@640 2232 return -1; //nomatch
mas01mj@640 2233 };
mas01mj@640 2234 /**
mas01mj@640 2235 * @return Modified String.
mas01mj@640 2236 */
mas01mj@640 2237 String.prototype.beautify = function(){
mas01mj@640 2238 var e1 = new RegExp("([a-z0-9])([A-Z])", "g");
mas01mj@640 2239 var e2 = new RegExp("([A-Z])([A-Z0-9])([a-z])", "g");
mas01mj@640 2240 var e3 = new RegExp("_", "g");
mas01mj@640 2241 return this.replace(e1, "$1 $2").replace(e2, "$1 $2$3").replace(e3, " ");
mas01mj@640 2242 };