Skip to content

Commit

Permalink
Add reachability criteria annotation to the metadata of links
Browse files Browse the repository at this point in the history
* reachability criteria annotation added

* matching subject and checksubject field added to the link annotation
  • Loading branch information
constraintAutomaton authored Apr 11, 2024
1 parent 328f362 commit 5e6a9b0
Show file tree
Hide file tree
Showing 14 changed files with 250 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class ActorExtractLinksAll extends ActorExtractLinks {
return {
links: await ActorExtractLinks.collectStream(action.metadata, (quad, links) => {
for (const link of getNamedNodes(getTerms(quad))) {
links.push({ url: link.value });
links.push({ url: link.value, metadata: { producedByActor: { name: this.name }}});
}
}),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ describe('ActorExtractLinksAll', () => {
});

it('should be a ActorExtractLinksAll constructor', () => {
expect(new (<any> ActorExtractLinksAll)({ name: 'actor', bus }))
expect(new (<any>ActorExtractLinksAll)({ name: 'actor', bus }))
.toBeInstanceOf(ActorExtractLinksAll);
expect(new (<any> ActorExtractLinksAll)({ name: 'actor', bus }))
expect(new (<any>ActorExtractLinksAll)({ name: 'actor', bus }))
.toBeInstanceOf(ActorExtractLinks);
});

it('should not be able to create new ActorExtractLinksAll objects without \'new\'', () => {
expect(() => {
(<any> ActorExtractLinksAll)();
(<any>ActorExtractLinksAll)();
}).toThrow(`Class constructor ActorExtractLinksAll cannot be invoked without 'new'`);
});
});
Expand Down Expand Up @@ -75,7 +75,9 @@ describe('ActorExtractLinksAll', () => {
{ url: 'ex:p' },
{ url: 'ex:o5' },
{ url: 'ex:gx' },
],
].map((link) => {
return { ...link, metadata: { producedByActor: { name: actor.name }}};
}),
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@ export class ActorExtractLinksContentPolicies extends ActorExtractLinks
for (const variable of contentPolicy.variables) {
const term = binding.get(variable.name);
if (term && term.termType === 'NamedNode') {
const link: ILink = { url: term.value, transform };
const link: ILink = {
url: term.value,
transform,
metadata: { producedByActor: { name: this.name, traverseConditional: this.traverseConditional }},
};

// Mark in the context if the linked document's policies should be considered
link.context = new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: variable.withPolicies });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ describe('ActorExtractLinksContentPolicies', () => {
actor = new ActorExtractLinksContentPolicies({
name: 'actor',
bus,
actorInitQuery: <any> {},
actorInitQuery: <any>{},
traverseConditional: false,
});
(<any> actor).queryEngine = queryEngine;
(<any>actor).queryEngine = queryEngine;
input = stream([
quad('ex:s1', 'ex:px', 'ex:o1', 'ex:gx'),
quad('ex:s2', 'ex:p', '"o"', 'ex:g'),
Expand Down Expand Up @@ -190,18 +190,23 @@ describe('ActorExtractLinksContentPolicies', () => {
transform: undefined,
context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: false }),
},
],
].map((link) => {
return {
...link,
metadata: { producedByActor: { name: actor.name, traverseConditional: actor.traverseConditional }},
};
}),
});
});

it('should run with one content policy that produces matches and traverseConditional', async() => {
actor = new ActorExtractLinksContentPolicies({
name: 'actor',
bus,
actorInitQuery: <any> {},
actorInitQuery: <any>{},
traverseConditional: true,
});
(<any> actor).queryEngine = queryEngine;
(<any>actor).queryEngine = queryEngine;
const context = new ActionContext({
[KEY_CONTEXT_POLICIES.name]: [
new ContentPolicy(
Expand Down Expand Up @@ -229,7 +234,12 @@ describe('ActorExtractLinksContentPolicies', () => {
transform: undefined,
context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: false }),
},
],
].map((link) => {
return {
...link,
metadata: { producedByActor: { name: actor.name, traverseConditional: actor.traverseConditional }},
};
}),
});
});

Expand Down Expand Up @@ -263,7 +273,12 @@ describe('ActorExtractLinksContentPolicies', () => {
{ url: 'ex:match1', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: false }) },
{ url: 'ex:match3', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: false }) },
{ url: 'ex:match2Bis', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: false }) },
],
].map((link) => {
return {
...link,
metadata: { producedByActor: { name: actor.name, traverseConditional: actor.traverseConditional }},
};
}),
});
});

Expand Down Expand Up @@ -313,7 +328,12 @@ describe('ActorExtractLinksContentPolicies', () => {
transform: expect.anything(),
context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: false }),
},
],
].map((link) => {
return {
...link,
metadata: { producedByActor: { name: actor.name, traverseConditional: actor.traverseConditional }},
};
}),
});
expect(result.links[0].transform).toBeInstanceOf(Function);
expect(result.links[1].transform).toBeInstanceOf(Function);
Expand Down Expand Up @@ -359,7 +379,12 @@ describe('ActorExtractLinksContentPolicies', () => {
links: [
{ url: 'ex:match1', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: true }) },
{ url: 'ex:match3', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: true }) },
],
].map((link) => {
return {
...link,
metadata: { producedByActor: { name: actor.name, traverseConditional: actor.traverseConditional }},
};
}),
});
});

Expand All @@ -380,7 +405,12 @@ describe('ActorExtractLinksContentPolicies', () => {
links: [
{ url: 'ex:match1', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: true }) },
{ url: 'ex:match3', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: true }) },
],
].map((link) => {
return {
...link,
metadata: { producedByActor: { name: actor.name, traverseConditional: actor.traverseConditional }},
};
}),
});
});

Expand All @@ -393,7 +423,12 @@ describe('ActorExtractLinksContentPolicies', () => {
{ url: 'ex:match1', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: true }) },
{ url: 'ex:match3', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: true }) },
{ url: 'ex:match2Bis', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: false }) },
],
].map((link) => {
return {
...link,
metadata: { producedByActor: { name: actor.name, traverseConditional: actor.traverseConditional }},
};
}),
});
});

Expand All @@ -418,7 +453,12 @@ describe('ActorExtractLinksContentPolicies', () => {
{ url: 'ex:match2Bis', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: false }) },
{ url: 'ex:match1', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: true }) },
{ url: 'ex:match3', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: true }) },
],
].map((link) => {
return {
...link,
metadata: { producedByActor: { name: actor.name, traverseConditional: actor.traverseConditional }},
};
}),
});
});

Expand All @@ -432,7 +472,12 @@ describe('ActorExtractLinksContentPolicies', () => {
{ url: 'ex:match1', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: true }) },
{ url: 'ex:match3', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: true }) },
{ url: 'ex:match2Bis', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: false }) },
],
].map((link) => {
return {
...link,
metadata: { producedByActor: { name: actor.name, traverseConditional: actor.traverseConditional }},
};
}),
});
});

Expand All @@ -459,7 +504,12 @@ describe('ActorExtractLinksContentPolicies', () => {
},
// URL match2Bis will not match the query operation pattern
// { url: 'ex:match2Bis', context: new ActionContext({ [KEY_CONTEXT_WITHPOLICIES.name]: false }) },
],
].map((link) => {
return {
...link,
metadata: { producedByActor: { name: actor.name, traverseConditional: actor.traverseConditional }},
};
}),
});
});

Expand All @@ -483,7 +533,7 @@ describe('ActorExtractLinksContentPolicies', () => {
new ContentPolicy(
factory.createBgp([]),
[{ name: 'varUnknown', withPolicies: false }],
factory.createConstruct(<any> undefined, <any> undefined),
factory.createConstruct(<any>undefined, <any>undefined),
),
)).toBeTruthy();
});
Expand All @@ -493,7 +543,7 @@ describe('ActorExtractLinksContentPolicies', () => {
new ContentPolicy(
factory.createBgp([]),
[{ name: 'varUnknown', withPolicies: false }],
factory.createConstruct(<any> undefined, [
factory.createConstruct(<any>undefined, [
factory.createPattern(
DF.namedNode('ex:s1'),
DF.namedNode('ex:p1'),
Expand All @@ -519,7 +569,7 @@ describe('ActorExtractLinksContentPolicies', () => {
new ContentPolicy(
factory.createBgp([]),
[{ name: 'varUnknown', withPolicies: false }],
factory.createConstruct(<any> undefined, [
factory.createConstruct(<any>undefined, [
factory.createPattern(
DF.namedNode('ex:s1'),
DF.namedNode('ex:p1'),
Expand All @@ -545,7 +595,7 @@ describe('ActorExtractLinksContentPolicies', () => {
new ContentPolicy(
factory.createBgp([]),
[{ name: 'varUnknown', withPolicies: false }],
factory.createConstruct(<any> undefined, [
factory.createConstruct(<any>undefined, [
factory.createPattern(
DF.variable('varS'),
DF.namedNode('ex:p1'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ const DF = new DataFactory<RDF.BaseQuad>();
export class ActorExtractLinksTree extends ActorExtractLinks {
public static readonly aNodeType = DF.namedNode('https://w3id.org/tree#node');
public static readonly aRelation = DF.namedNode('https://w3id.org/tree#relation');
private static readonly rdfTypeNode = DF.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
public static readonly aView = DF.namedNode('https://w3id.org/tree#view');
public static readonly aSubset = DF.namedNode('http://rdfs.org/ns/void#subset');
public static readonly isPartOf = DF.namedNode('http://purl.org/dc/terms/isPartOf');
Expand All @@ -34,7 +33,7 @@ export class ActorExtractLinksTree extends ActorExtractLinks {
public async run(action: IActionExtractLinks): Promise<IActorExtractLinksOutput> {
return new Promise((resolve, reject) => {
const strictModeFlag: boolean | undefined =
action.context.get(KeysExtractLinksTree.strictTraversal);
action.context.get(KeysExtractLinksTree.strictTraversal);
const strictMode = strictModeFlag ?? true;
const metadata = action.metadata;
const currentNodeUrl = action.url;
Expand Down Expand Up @@ -70,7 +69,7 @@ export class ActorExtractLinksTree extends ActorExtractLinks {
const subjectOfRelation = relationNodeSubject.get(nodeValue);
if (subjectOfRelation && effectiveTreeDocumentSubject.has(subjectOfRelation)
) {
links.push({ url: link });
links.push({ url: link, metadata: { producedByActor: { name: this.name }}});
}
}

Expand Down Expand Up @@ -100,13 +99,13 @@ export class ActorExtractLinksTree extends ActorExtractLinks {
if (
(!strictMode || quad.subject.value === url) &&
(quad.predicate.equals(ActorExtractLinksTree.aView) ||
quad.predicate.equals(ActorExtractLinksTree.aSubset))) {
quad.predicate.equals(ActorExtractLinksTree.aSubset))) {
rootNodeEffectiveSubject.add(quad.object.value);
}

if (
(!strictMode || quad.object.value === url) &&
quad.predicate.equals(ActorExtractLinksTree.isPartOf)) {
quad.predicate.equals(ActorExtractLinksTree.isPartOf)) {
rootNodeEffectiveSubject.add(quad.subject.value);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('ActorExtractLinksExtractLinksTree', () => {

const result = await actor.run(action);

expect(result).toEqual({ links: [{ url: expectedUrl }]});
expect(result).toEqual({ links: [{ url: expectedUrl, metadata: { producedByActor: { name: actor.name }}}]});
});

it('should return the links of a TREE with multiple relations', async() => {
Expand All @@ -80,7 +80,7 @@ describe('ActorExtractLinksExtractLinksTree', () => {
const result = await actor.run(action);

expect(result).toEqual({ links: expectedUrl.map((value) => {
return { url: value };
return { url: value, metadata: { producedByActor: { name: actor.name }}};
}) });
});

Expand All @@ -99,7 +99,7 @@ describe('ActorExtractLinksExtractLinksTree', () => {

const result = await actor.run(action);

expect(result).toEqual({ links: [{ url: expectedUrl }]});
expect(result).toEqual({ links: [{ url: expectedUrl, metadata: { producedByActor: { name: actor.name }}}]});
});

it('should return the links of a TREE with multiple relations combining blank nodes and named nodes', async() => {
Expand All @@ -122,7 +122,7 @@ describe('ActorExtractLinksExtractLinksTree', () => {
const result = await actor.run(action);

expect(result).toEqual({ links: expectedUrl.map((value) => {
return { url: value };
return { url: value, metadata: { producedByActor: { name: actor.name }}};
}) });
});

Expand Down Expand Up @@ -152,7 +152,7 @@ describe('ActorExtractLinksExtractLinksTree', () => {

const result = await actor.run(action);

expect(result).toEqual({ links: [{ url: expectedUrl }]});
expect(result).toEqual({ links: [{ url: expectedUrl, metadata: { producedByActor: { name: actor.name }}}]});
}
});

Expand Down Expand Up @@ -181,7 +181,7 @@ describe('ActorExtractLinksExtractLinksTree', () => {

const result = await actor.run(action);

expect(result).toEqual({ links: [{ url: expectedUrl }]});
expect(result).toEqual({ links: [{ url: expectedUrl, metadata: { producedByActor: { name: actor.name }}}]});
}
});

Expand Down Expand Up @@ -213,7 +213,7 @@ describe('ActorExtractLinksExtractLinksTree', () => {

const result = await actor.run(action);

expect(result).toEqual({ links: [{ url: expectedUrl }]});
expect(result).toEqual({ links: [{ url: expectedUrl, metadata: { producedByActor: { name: actor.name }}}]});
}
});

Expand Down Expand Up @@ -241,7 +241,7 @@ describe('ActorExtractLinksExtractLinksTree', () => {
const result = await actor.run(action);

expect(result).toEqual({ links: expectedUrl.map((value) => {
return { url: value };
return { url: value, metadata: { producedByActor: { name: actor.name }}};
}) });
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import type { IActorArgs, IActorTest } from '@comunica/core';
export class ActorExtractLinksPredicates extends ActorExtractLinks {
private readonly checkSubject: boolean;
private readonly predicates: RegExp[];
private readonly stringPredicates: string[];

public constructor(args: IActorExtractLinksTraversePredicatesArgs) {
super(args);

this.stringPredicates = args.predicateRegexes;
this.predicates = args.predicateRegexes.map(stringRegex => new RegExp(stringRegex, 'u'));
}

Expand All @@ -25,7 +27,17 @@ export class ActorExtractLinksPredicates extends ActorExtractLinks {
if (!this.checkSubject || this.subjectMatches(quad.subject.value, action.url)) {
for (const regex of this.predicates) {
if (regex.test(quad.predicate.value)) {
links.push({ url: quad.object.value });
links.push({
url: quad.object.value,
metadata: {
producedByActor: {
name: this.name,
predicates: this.stringPredicates,
matchingPredicate: quad.predicate.value,
checkSubject: this.checkSubject,
},
},
});
break;
}
}
Expand Down
Loading

0 comments on commit 5e6a9b0

Please sign in to comment.