Commit cff9c551 authored by Laurent Wouters's avatar Laurent Wouters
Browse files

Implementing the FoaF views

parent a53089ae623a
......@@ -28,6 +28,16 @@ echo "=========================================="
(cd "$ROOT/views-dbpedia"; npm install)
(cd "$ROOT/views-dbpedia"; npm run build)
echo ""
echo "=========================================="
echo "= Building @logilab/views-foaf"
echo "=========================================="
(cd "$ROOT/views-foaf"; rm -rf build)
(cd "$ROOT/views-foaf"; rm -rf node_modules/@types/rdflib)
(cd "$ROOT/views-foaf"; rm -rf node_modules/@logilab/libview)
(cd "$ROOT/views-foaf"; npm install)
(cd "$ROOT/views-foaf"; npm run build)
echo ""
echo "=========================================="
echo "= Building @logilab/ld-browser"
......
......@@ -21,6 +21,7 @@
"author": "LOGILAB <contact@logilab.fr>",
"license": "LGPL-3.0",
"dependencies": {
"@types/node": "^10.5.3",
"@types/rdflib": "file:../rdflib-types",
"rdflib": "^0.17.0"
},
......
......@@ -21,5 +21,6 @@
import * as application from "./application";
import * as definition from "./view-def";
import * as implementation from "./view-impl";
import * as rdf from "./rdf-utils";
export { application, definition, implementation };
export { application, definition, implementation, rdf };
/*******************************************************************************
* Copyright 2003-2018 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
* contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
*
* This file is part of CubicWeb.
*
* CubicWeb is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 2.1 of the License, or (at your option)
* any later version.
*
* CubicWeb is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
import { RdfStore, RDF, Term, NamedNode } from "rdflib";
let _rdf = require("rdflib");
const $rdf: RDF = _rdf;
/**
* Gets the value for the propert of a resource
* @param store The RDF store containing the data
* @param resource The resource
* @param property The property
*/
export function getValueOf(
store: RdfStore,
resource: string,
property: string
): Term {
return store.any(
$rdf.sym(resource),
$rdf.sym(property),
undefined,
undefined
);
}
/**
* Gets the values for the propert of a resource
* @param store The RDF store containing the data
* @param resource The resource
* @param property The property
*/
export function getValuesOf(
store: RdfStore,
resource: string,
property: string
): Term[] {
return store.each(
$rdf.sym(resource),
$rdf.sym(property),
undefined,
undefined
);
}
/**
* A single RDF entity that may have aliases
*/
export class RdfEntity {
/**
* The parent manager
*/
private manager: RdfEntityStore;
/**
* The first alias for this entity
*/
private aliases: NamedNode[];
/**
* All the uris for this node
*/
public readonly uris: string[];
/**
* The main uri for this entity
*/
public readonly uri: string;
/**
* Initializes this entity
* @param manager The parent manager
* @param first The first alias for this entity
*/
constructor(manager: RdfEntityStore, first: NamedNode) {
this.manager = manager;
this.aliases = [first];
this.uris = [first.uri];
this.uri = first.uri;
}
/**
* Adds an alias to this node
* @param node The new alias
*/
public addAlias(node: NamedNode): void {
this.aliases.push(node);
this.uris.push(node.uri);
}
public getEntityForE(property: RdfEntity): RdfEntity {
let r = this.getEntitiesForE(property);
return r.length == 0 ? null : r[0];
}
public getEntityForS(property: string): RdfEntity {
let r = this.getEntitiesForS(property);
return r.length == 0 ? null : r[0];
}
public getEntityForN(property: NamedNode): RdfEntity {
let r = this.getEntitiesForN(property);
return r.length == 0 ? null : r[0];
}
public getEntitiesForE(property: RdfEntity): RdfEntity[] {
return this.getValuesForE(property)
.filter((node: Term) => node.termType == "NamedNode")
.map((node: NamedNode) => this.manager.getFromNode(node));
}
public getEntitiesForS(property: string): RdfEntity[] {
return this.getValuesForS(property)
.filter((node: Term) => node.termType == "NamedNode")
.map((node: NamedNode) => this.manager.getFromNode(node));
}
public getEntitiesForN(property: NamedNode): RdfEntity[] {
return this.getValuesForN(property)
.filter((node: Term) => node.termType == "NamedNode")
.map((node: NamedNode) => this.manager.getFromNode(node));
}
public getValueForE(property: RdfEntity): Term {
let r = this.getValuesForE(property);
return r.length == 0 ? null : r[0];
}
public getValueForS(property: string): Term {
let r = this.getValuesForS(property);
return r.length == 0 ? null : r[0];
}
public getValueForN(property: NamedNode): Term {
let r = this.getValuesForN(property);
return r.length == 0 ? null : r[0];
}
public getValuesForE(property: RdfEntity): Term[] {
let results: Term[] = [];
property.aliases.map((alias: NamedNode) => {
let values = this.getValuesForN(alias);
values.map((value: Term) => {
if (results.indexOf(value) < 0) results.push(value);
});
});
return results;
}
public getValuesForS(property: string): Term[] {
return this.getValuesForN($rdf.sym(property));
}
public getValuesForN(property: NamedNode): Term[] {
let results: Term[] = [];
for (var i = 0; i != this.aliases.length; i++) {
let values = this.manager.store.each(
this.aliases[i],
property,
undefined,
undefined
);
values.map((value: Term) => {
if (results.indexOf(value) < 0) results.push(value);
});
}
return results;
}
}
/**
* A store for RDF entities
*/
export class RdfEntityStore {
/**
* The underlying RDF store
*/
public readonly store: RdfStore;
/**
* The known RDF entities
*/
private entities: { [name: string]: RdfEntity };
/**
* Initializes this store
* @param store The underlying store
*/
constructor(store: RdfStore) {
this.store = store;
this.entities = {};
}
/**
* Gets an entity
* @param uri The resource URI
*/
public getFromUri(uri: string): RdfEntity {
if (this.entities.hasOwnProperty(uri)) return this.entities[uri];
let result = new RdfEntity(this, $rdf.sym(uri));
this.entities[uri] = result;
this.resolveAliases(result);
return result;
}
/**
* Gets an entity
* @param node The named node
*/
public getFromNode(node: NamedNode): RdfEntity {
if (this.entities.hasOwnProperty(node.uri)) return this.entities[node.uri];
let result = new RdfEntity(this, node);
this.entities[node.uri] = result;
this.resolveAliases(result);
return result;
}
/**
* Resolves all the aliases for an entity
* @param entity The entity
*/
private resolveAliases(entity: RdfEntity) {
let sameas = $rdf.sym("http://www.w3.org/2002/07/owl#sameAs");
let aliases: string[] = [];
let nodes: NamedNode[] = [];
aliases.push(entity.uri);
nodes.push($rdf.sym(aliases[0]));
for (var i = 0; i != aliases.length; i++) {
let others = this.store.each(nodes[i], sameas, undefined, undefined);
others.map((other: Term) => {
if (other.termType == "NamedNode") {
let named = other as NamedNode;
if (aliases.indexOf(named.uri) < 0) {
aliases.push(named.uri);
nodes.push(named);
entity.addAlias(named);
this.entities[named.uri] = entity;
}
}
});
}
}
}
......@@ -23,7 +23,6 @@
"license": "LGPL-3.0",
"dependencies": {
"@logilab/libview": "file:../libview",
"@types/node": "^10.5.3",
"@types/rdflib": "file:../rdflib-types",
"rdflib": "^0.17.0",
"vue": "^2.5.16"
......
......@@ -18,10 +18,8 @@
* with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
import { definition, application, implementation } from "@logilab/libview";
import { RdfStore, RDF, Term } from "rdflib";
let _rdf = require("rdflib");
const $rdf: RDF = _rdf;
import { definition, application, implementation, rdf } from "@logilab/libview";
import { RdfStore, Term } from "rdflib";
/**
* The descritptor for the default Dbpedia person view
......@@ -36,31 +34,18 @@ const DESCRIPTOR_PERSON: definition.ViewDescriptor = {
}
};
/**
* Determines whether the RDF store with the specified primary topic matches a trait:
* Has a primary topic
* @param store The RDF store
* @param primaryTopic The primary topic
*/
function hasTraitHasPrimary(store: RdfStore, primaryTopic: string): boolean {
return primaryTopic != null;
interface FoaFPerson {
name: string;
gender: string;
}
/**
* Determines whether the RDF store with the specified primary topic matches a trait:
* The primary topic is a person in DBPedia
* @param store The RDF store
* @param primaryTopic The primary topic
*/
function hasTraitDbPediaPerson(store: RdfStore, primaryTopic: string): boolean {
if (!hasTraitHasPrimary(store, primaryTopic)) return false;
let a = store.each(
$rdf.sym(primaryTopic),
$rdf.sym("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"),
$rdf.sym("http://dbpedia.org/ontology/Person"),
undefined
);
return a != null && a != undefined && a.length > 0;
function loadPerson(rdfStore: RdfStore, target: string) {
let store = new rdf.RdfEntityStore(rdfStore);
let root = store.getFromUri(target);
let focus = root.getEntityForS("http://xmlns.com/foaf/0.1/focus");
if (focus != null) root = focus;
}
class FoaFPersonRendering implements implementation.ViewImplementation {
......@@ -72,7 +57,22 @@ class FoaFPersonRendering implements implementation.ViewImplementation {
}
priorityFor(store: RdfStore, target: string): number {
return hasTraitDbPediaPerson(store, target) ? 10 : -1;
if (target == null) return -1;
let focus = rdf.getValueOf(
store,
target,
"http://xmlns.com/foaf/0.1/focus"
);
if (focus != null && focus != undefined) target = focus.value;
let types = rdf.getValuesOf(
store,
target,
"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
);
let isPerson = types
.map((type: Term) => type.value == "http://xmlns.com/foaf/0.1/Person")
.reduce((acc: boolean, matched: boolean) => acc || matched, false);
return isPerson ? 10 : -1;
}
render(
......@@ -86,21 +86,6 @@ class FoaFPersonRendering implements implementation.ViewImplementation {
}
}
/**
* Gets the value for the propert of a resource
* @param store The RDF store containing the data
* @param resource The resource
* @param property The property
*/
function getValueOf(store: RdfStore, resource: string, property: string): Term {
return store.any(
$rdf.sym(resource),
$rdf.sym(property),
undefined,
undefined
);
}
/**
* Export the view
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment