ai.grakn.kb.internal.concept.RoleImpl Maven / Gradle / Ivy
/*
* GRAKN.AI - THE KNOWLEDGE GRAPH
* Copyright (C) 2018 Grakn Labs Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package ai.grakn.kb.internal.concept;
import ai.grakn.concept.RelationshipType;
import ai.grakn.concept.Role;
import ai.grakn.concept.Type;
import ai.grakn.kb.internal.cache.Cache;
import ai.grakn.kb.internal.cache.Cacheable;
import ai.grakn.kb.internal.structure.Casting;
import ai.grakn.kb.internal.structure.VertexElement;
import ai.grakn.util.CommonUtil;
import ai.grakn.util.Schema;
import org.apache.tinkerpop.gremlin.structure.Direction;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
*
* An {@link ai.grakn.concept.SchemaConcept} which defines a {@link Role} which can be played in a {@link RelationshipType}.
*
*
*
* This {@link ai.grakn.concept.SchemaConcept} defines the roles which make up a {@link RelationshipType}.
* It has some additional functionality:
* 1. It cannot play a {@link Role} to itself.
* 2. It is special in that it is unique to {@link RelationshipType}s.
*
*
* @author fppt
*
*/
public class RoleImpl extends SchemaConceptImpl implements Role {
private final Cache> cachedDirectPlayedByTypes = Cache.createSessionCache(this, Cacheable.set(), () -> this.neighbours(Direction.IN, Schema.EdgeLabel.PLAYS).collect(Collectors.toSet()));
private final Cache> cachedRelationTypes = Cache.createSessionCache(this, Cacheable.set(), () -> this.neighbours(Direction.IN, Schema.EdgeLabel.RELATES).collect(Collectors.toSet()));
private RoleImpl(VertexElement vertexElement) {
super(vertexElement);
}
private RoleImpl(VertexElement vertexElement, Role type) {
super(vertexElement, type);
}
public static RoleImpl get(VertexElement vertexElement){
return new RoleImpl(vertexElement);
}
public static RoleImpl create(VertexElement vertexElement, Role type) {
RoleImpl role = new RoleImpl(vertexElement, type);
vertexElement.tx().txCache().trackForValidation(role);
return role;
}
@Override
public Stream relationships() {
return cachedRelationTypes.get().stream();
}
/**
* Caches a new relation type which this role will be part of. This may result in a DB hit if the cache has not been
* initialised.
*
* @param newRelationshipType The new relation type to cache in the role.
*/
void addCachedRelationType(RelationshipType newRelationshipType){
cachedRelationTypes.ifPresent(set -> set.add(newRelationshipType));
}
/**
* Removes an old relation type which this role is no longer part of. This may result in a DB hit if the cache has
* not been initialised.
*
* @param oldRelationshipType The new relation type to cache in the role.
*/
void deleteCachedRelationType(RelationshipType oldRelationshipType){
cachedRelationTypes.ifPresent(set -> set.remove(oldRelationshipType));
}
/**
*
* @return A list of all the Concept Types which can play this role.
*/
@Override
public Stream players() {
return cachedDirectPlayedByTypes.get().stream().flatMap(Type::subs);
}
void addCachedDirectPlaysByType(Type newType){
cachedDirectPlayedByTypes.ifPresent(set -> set.add(newType));
}
void deleteCachedDirectPlaysByType(Type oldType){
cachedDirectPlayedByTypes.ifPresent(set -> set.remove(oldType));
}
/**
*
* @return Get all the roleplayers of this role type
*/
public Stream rolePlayers(){
return relationships().
flatMap(RelationshipType::instances).
map(relation -> RelationshipImpl.from(relation).reified()).
flatMap(CommonUtil::optionalToStream).
flatMap(relation -> relation.castingsRelation(this));
}
@Override
boolean deletionAllowed(){
return super.deletionAllowed() &&
!neighbours(Direction.IN, Schema.EdgeLabel.RELATES).findAny().isPresent() && // This role is not linked t any relation type
!neighbours(Direction.IN, Schema.EdgeLabel.PLAYS).findAny().isPresent() && // Nothing can play this role
!rolePlayers().findAny().isPresent(); // This role has no role players
}
@Override
void trackRolePlayers() {
//TODO: track the super change when the role super changes
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy