io.konig.core.showl.ShowlNodeShape Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of konig-core Show documentation
Show all versions of konig-core Show documentation
A library for core classes (Graph, Vertex, Edge, etc.)
package io.konig.core.showl;
import java.util.ArrayList;
/*
* #%L
* Konig Core
* %%
* Copyright (C) 2015 - 2018 Gregory McFall
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.impl.URIImpl;
import io.konig.core.Context;
import io.konig.core.OwlReasoner;
import io.konig.core.impl.RdfUtil;
import io.konig.core.util.IriTemplate;
import io.konig.core.util.ValueFormat.Element;
import io.konig.core.util.ValueFormat.ElementType;
import io.konig.core.vocab.Konig;
import io.konig.shacl.NodeKind;
import io.konig.shacl.Shape;
/**
* A particular instance of a SHACL NodeShape.
* The instance may be bound to a particular location with a graph via the accessor, and it may
* be bound to a particular DataSource.
*
* @author Greg McFall
*
*/
public class ShowlNodeShape implements Traversable {
private ShowlPropertyShape accessor;
private ShowlClass owlClass;
private Shape shape;
private Map properties = new HashMap<>();
private Map derivedProperties = null;
private Map inProperties = null;
private List selectedJoins;
private ShowlDataSource shapeDataSource;
private boolean unmapped;
public ShowlNodeShape(ShowlPropertyShape accessor, Shape shape, ShowlClass owlClass) {
derivedProperties = new HashMap<>();
this.accessor = accessor;
this.shape = shape;
setOwlClass(owlClass);
if (accessor != null) {
accessor.setValueShape(this);
}
}
/**
* Get the key through which the specified source node is joined according to the given join condition.
* @param sourceNode The source node whose key is being requested
* @param join The join condition for the key.
*/
public ShowlPropertyShape keyProperty(ShowlNodeShape sourceNode, ShowlJoinCondition join) {
if (join instanceof ShowlFromCondition) {
for (ShowlJoinCondition j : getSelectedJoins()) {
if (j == join) {
continue;
}
ShowlNodeShape otherNode = j.otherNode(sourceNode);
if (otherNode != null) {
return j.propertyOf(sourceNode);
}
}
} else {
return join.propertyOf(sourceNode);
}
return null;
}
public Set joinProperties(ShowlNodeShape otherNode) throws ShowlProcessingException {
Set set = new HashSet<>();
for (ShowlDirectPropertyShape p : getProperties()) {
ShowlMapping mapping = p.getSelectedMapping();
if (mapping == null) {
throw new ShowlProcessingException("Mapping not found for " + p.getPath());
}
ShowlPropertyShape otherProperty = mapping.findOther(p);
if (otherNode == otherProperty.getDeclaringShape()) {
addMappedProperty(set, otherProperty, p);
}
}
return set;
}
/**
* Get all the properties mapped to this NodeShape via a given join condition.
*/
public Set joinProperties(ShowlJoinCondition join) throws ShowlProcessingException {
Set set = new HashSet<>();
if (join instanceof ShowlFromCondition) {
ShowlFromCondition from = (ShowlFromCondition) join;
join = from.getDerivedFrom();
}
for (ShowlDirectPropertyShape p : getProperties()) {
ShowlMapping mapping = p.getSelectedMapping();
if (mapping == null) {
throw new ShowlProcessingException("Mapping not found for " + p.getPath());
}
if (mapping.getJoinCondition() == join) {
ShowlPropertyShape other = mapping.findOther(p);
addMappedProperty(set, other, p);
}
}
return set;
}
private void addMappedProperty(Set set, ShowlPropertyShape other, ShowlPropertyShape target) {
if ((other instanceof ShowlDirectPropertyShape) ||
(other instanceof ShowlStaticPropertyShape) ||
(other.getValueShape() != null)
) {
set.add(other);
return;
} else {
ShowlPropertyShape peer = other.getPeer();
if (peer instanceof ShowlDirectPropertyShape) {
set.add(other);
return;
}
if (other instanceof ShowlTemplatePropertyShape) {
addTemplateParameters(set, (ShowlTemplatePropertyShape) other, target);
return;
}
}
throw new ShowlProcessingException("Mapping not supported for " + target.getPath());
}
public ShowlPropertyShape enumSourceKey(OwlReasoner reasoner) {
if (accessor != null && reasoner.isEnumerationClass(owlClass.getId())) {
ShowlMapping mapping = accessor.getSelectedMapping();
if (mapping != null) {
ShowlPropertyShape otherAccessor = mapping.findOther(accessor);
ShowlNodeShape sourceNode = otherAccessor.getValueShape();
if (sourceNode != null) {
for (ShowlPropertyShape p : sourceNode.allOutwardProperties()) {
if (reasoner.isInverseFunctionalProperty(p.getPredicate())) {
if (p.isDirect()) {
return p;
}
ShowlPropertyShape peer = p.getPeer();
if (peer instanceof ShowlDirectPropertyShape) {
return peer;
}
}
}
}
}
}
return null;
}
private void addTemplateParameters(Set set, ShowlTemplatePropertyShape other, ShowlPropertyShape target) {
IriTemplate template = other.getTemplate();
Context context = template.getContext();
ShowlNodeShape node = other.getDeclaringShape();
for (Element e : template.toList()) {
if (e.getType() == ElementType.VARIABLE) {
URI varId = new URIImpl(context.expandIRI(e.getText()));
List outSet = node.out(varId);
for (ShowlPropertyShape p : outSet) {
addMappedProperty(set, p, target);
}
}
}
}
public void addInwardProperty(ShowlInwardPropertyShape p) {
if (inProperties == null) {
inProperties = new HashMap<>();
}
inProperties.put(p.getPredicate(), p);
}
public ShowlInwardPropertyShape getInwardProperty(URI predicate) {
return inProperties==null ? null : inProperties.get(predicate);
}
public Collection getInwardProperties() {
return inProperties==null ? Collections.emptyList() : inProperties.values();
}
@Deprecated
public boolean isNamedRoot() {
return accessor == null && findProperty(Konig.id) != null && hasDataSource();
}
public Collection getProperties() {
return properties.values();
}
public Set allOutwardProperties() {
Set set = new HashSet<>();
set.addAll(getProperties());
for (List list : getDerivedProperties()) {
set.addAll(list);
}
return set;
}
public void addProperty(ShowlDirectPropertyShape p) {
properties.put(p.getPredicate(), p);
}
public ShowlDirectPropertyShape getProperty(URI predicate) {
return properties.get(predicate);
}
public ShowlDerivedPropertyList getDerivedProperty(URI predicate) {
ShowlDerivedPropertyList list = derivedProperties.get(predicate);
return list == null ? (ShowlDerivedPropertyList) Collections.EMPTY_LIST : list;
}
public Resource getId() {
return shape.getId();
}
public Shape getShape() {
return shape;
}
public ShowlClass getOwlClass() {
return owlClass;
}
public boolean hasDataSource() {
return shape != null && !shape.getShapeDataSource().isEmpty();
}
public void setOwlClass(ShowlClass owlClass) {
if (this.owlClass != owlClass) {
if (this.owlClass != null) {
this.owlClass.getTargetClassOf().remove(this);
}
this.owlClass = owlClass;
if (owlClass != null) {
owlClass.addTargetClassOf(this);
}
}
}
public boolean hasAncestor(Resource shapeId) {
if (shape.getId().equals(shapeId)) {
return true;
}
if (accessor != null) {
return accessor.getDeclaringShape().hasAncestor(shapeId);
}
return false;
}
public ShowlPropertyShape getAccessor() {
return accessor;
}
public void addDerivedProperty(ShowlDerivedPropertyShape p) {
ShowlDerivedPropertyList list = derivedProperties.get(p.getPredicate());
if (list == null) {
list = new ShowlDerivedPropertyList(p.getPredicate());
derivedProperties.put(p.getPredicate(), list);
}
list.add(p);
}
public List out(URI predicate) {
ShowlDirectPropertyShape direct = properties.get(predicate);
ShowlDerivedPropertyList indirect = derivedProperties.get(predicate);
if (direct==null && indirect==null) {
return Collections.emptyList();
}
List list = new ArrayList<>();
if (direct != null) {
list.add(direct);
}
if (indirect!=null) {
list.addAll(indirect);
}
return list;
}
/**
* Find an outward property.
*/
@Deprecated
public ShowlPropertyShape findProperty(URI predicate) {
ShowlPropertyShape p = getProperty(predicate);
if (p == null) {
List list = derivedProperties.get(predicate);
if (list != null && list.size() == 1) {
p = list.get(0);
}
}
return p;
}
public Collection getDerivedProperties() {
return derivedProperties.values();
}
@Override
public String getPath() {
if (accessor == null) {
return "{" + RdfUtil.localName(shape.getId()) + "}";
}
return accessor.getPath();
}
public String toString() {
return getPath();
}
public ShowlNodeShape getRoot() {
if (accessor == null) {
return this;
}
return accessor.getDeclaringShape().getRoot();
}
public void addSelectedJoin(ShowlJoinCondition join) {
if (selectedJoins==null) {
selectedJoins = new ArrayList<>();
}
selectedJoins.add(join);
}
public List getSelectedJoins() {
return selectedJoins == null ? Collections.emptyList() : selectedJoins;
}
/**
* Returns true if there are no shapes that are candidates as sources from which this node may
* be derived.
*/
public boolean isUnmapped() {
return unmapped;
}
public void setUnmapped(boolean unmapped) {
this.unmapped = unmapped;
}
public NodeKind getNodeKind() {
return shape == null ? null : shape.getNodeKind();
}
public ShowlStaticPropertyShape staticProperty(ShowlProperty property) {
URI predicate = property.getPredicate();
ShowlDerivedPropertyList list = derivedProperties.get(predicate);
if (list != null) {
for (ShowlDerivedPropertyShape p : list) {
if (p instanceof ShowlStaticPropertyShape) {
return (ShowlStaticPropertyShape) p;
}
}
}
if (list == null) {
list = new ShowlDerivedPropertyList(predicate);
derivedProperties.put(predicate, list);
}
ShowlStaticPropertyShape p = new ShowlStaticPropertyShape(this, property);
list.add(p);
return p;
}
public ShowlDataSource getShapeDataSource() {
return shapeDataSource;
}
public void setShapeDataSource(ShowlDataSource shapeDataSource) {
this.shapeDataSource = shapeDataSource;
}
}