
org.semantictools.frame.api.ContextBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of semantictools-context-renderer Show documentation
Show all versions of semantictools-context-renderer Show documentation
A library used to generate documentation for media types associated with a JSON-LD context
The newest version!
/*******************************************************************************
* Copyright 2012 Pearson Education
*
* 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.
******************************************************************************/
package org.semantictools.frame.api;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.semantictools.context.renderer.model.Container;
import org.semantictools.context.renderer.model.ContextProperties;
import org.semantictools.context.renderer.model.FrameConstraints;
import org.semantictools.context.renderer.model.JsonContext;
import org.semantictools.context.renderer.model.TermInfo;
import org.semantictools.context.renderer.model.TermInfo.TermCategory;
import org.semantictools.context.renderer.model.TermValue;
import org.semantictools.frame.model.BindVocabulary;
import org.semantictools.frame.model.Datatype;
import org.semantictools.frame.model.DublinCoreTerms;
import org.semantictools.frame.model.Enumeration;
import org.semantictools.frame.model.Field;
import org.semantictools.frame.model.Frame;
import org.semantictools.frame.model.NamedIndividual;
import org.semantictools.frame.model.OntologyInfo;
import org.semantictools.frame.model.RdfType;
import org.semantictools.frame.model.RestCategory;
import org.semantictools.frame.model.VannVocabulary;
import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.OWL2;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import com.hp.hpl.jena.vocabulary.XSD;
public class ContextBuilder {
private static final String CONTAINER = "http://www.w3.org/ns/ldp#Container";
private static final String PAGE = "http://www.w3.org/ns/ldp#Page";
private static final String nextPage = "http://www.w3.org/ns/ldp#nextPage";
private static final String NIL = "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil";
private OntModel model;
private TypeManager typeManager;
private OntProperty suggestedPrefix;
private Set history;
public ContextBuilder(TypeManager typeManager) {
this.model = typeManager.getOntModel();
this.typeManager = typeManager;
suggestedPrefix = model.getOntProperty("http://purl.org/semantictools/v1/vocab/bind#suggestedPrefix");
}
public JsonContext createContext(ContextProperties properties) {
history = new HashSet();
JsonContext context = new JsonContext();
context.setContextURI(properties.getContextURI());
context.setMediaType(properties.getMediaType());
context.setRootType(properties.getRdfTypeURI());
String typeURI = properties.getRdfTypeURI();
if (typeURI == null) {
return null;
}
addGraphTypes(context, properties);
Frame frame = typeManager.getFrameByUri(typeURI);
if (frame == null) {
throw new FrameNotFoundException(typeURI);
}
addType(properties, context, frame, false, true);
if (frame.isSubclassOf(CONTAINER)) {
Frame page = typeManager.getFrameByUri(PAGE);
addType(properties, context, page, false, true);
TermInfo term = new TermInfo("nil");
term.setIriValue(NIL);
context.add(term);
properties.getIdRefList().add(nextPage);
}
context.expand();
context.invertRewriteRules();
updateFrameConstraints(properties, context);
return context;
}
private void addGraphTypes(JsonContext context, ContextProperties properties) {
List graphTypes = properties.getGraphTypes();
if (!graphTypes.isEmpty()) {
for (String uri : graphTypes) {
Frame frame = typeManager.getFrameByUri(uri);
if (frame == null) {
throw new FrameNotFoundException(uri);
}
addType(properties, context, frame, false, true);
}
}
}
private void updateFrameConstraints(ContextProperties properties, JsonContext context) {
List list = properties.listFrameConstraints();
for (FrameConstraints c : list) {
String name = c.getClassURI();
TermInfo term = context.getTermInfoByShortName(name);
if (term != null) {
String uri = term.getIri();
uri = context.rewrite(uri);
c.setClassURI(uri);
properties.addFrameConstraints(c);
}
}
}
private boolean isStandard(String uri) {
return uri != null && uri.startsWith("http://www.w3.org/2001/XMLSchema#");
// return uri.startsWith("http://www.w3.org/2001/XMLSchema#") ||
// uri.startsWith("http://www.w3.org/2002/07/owl#");
}
private void addType(ContextProperties properties, JsonContext context, RdfType rdfType, boolean stubbed, boolean allFields) {
String typeURI = rdfType.getUri();
if (properties.getExcludedTypes().contains(typeURI)) {
return;
}
if (rdfType.canAsListType() && embedListMembers(properties)) {
// rdfType = rdfType.asListType().getElementType();
addType(properties, context, rdfType.asListType().getElementType(), stubbed, allFields);
}
if (isStandard(typeURI)) return;
String localName = rdfType.getLocalName();
String prefix = getPrefix(context, rdfType.getNamespace());
String iri = (prefix == null) ? typeURI : prefix + ":" + localName;
if (!context.containsTerm(localName)) {
context.add(localName, iri).setCategory(TermCategory.TYPE);
}
if (stubbed || history.contains(typeURI)) return;
Frame frame = typeManager.getFrameByUri(typeURI);
if (frame == null) {
// Since the frame was not found, the type is probably a Datatype.
// Let's confirm that the datatype exists.
Datatype datatype = typeManager.getDatatypeByUri(typeURI);
if (datatype == null) {
throw new FrameNotFoundException(typeURI);
}
return;
}
history.add(typeURI);
if (typeURI.equals(RDFS.Resource.getURI())) {
return;
}
FrameConstraints constraints = properties.getFrameConstraints(localName);
List fieldList = allFields ? frame.listAllFields() : frame.getDeclaredFields();
for (Field field : fieldList) {
if (constraints == null || constraints.isIncludedProperty(field.getURI())) {
addField(properties, context, field, frame);
}
}
addSubtypes(properties, context, frame);
}
/**
* Returns true if rdf:member is not represented as an idref.
*/
private boolean embedListMembers(ContextProperties properties) {
properties.isIdRef("http://www.w3.org/2000/01/rdf-schema#member");
return false;
}
private void addSubtypes(ContextProperties properties, JsonContext context, Frame frame) {
FrameConstraints c = properties.getFrameConstraints(frame.getLocalName());
List list = frame.listAllSubtypes();
for (Frame sub : list) {
if (properties.getExcludedTypes().contains(sub.getUri())) {
continue;
}
if (c != null) {
// If the supertype has constraints, then they must bubble down to
// subtypes. This means that the constraints cannot be null on the subtypes...
FrameConstraints cc = properties.getFrameConstraints(sub.getLocalName());
if (cc == null) {
cc = new FrameConstraints(sub.getLocalName());
properties.addFrameConstraints(cc);
}
cc.copyAll(c);
}
addType(properties, context, sub, false, false);
}
}
private void addField(ContextProperties properties, JsonContext context, Field field, Frame declaringFrame) {
OntProperty property = field.getProperty();
if (!isIncluded(field, properties, declaringFrame)) return;
boolean allFields = field.getDeclaringFrame() == declaringFrame;
String localName = property.getLocalName();
String propertyURI = property.getURI();
String iriValue = iriRef(context, property.getNameSpace(), property.getLocalName(), propertyURI);
TermInfo info = new TermInfo(localName);
info.setCategory(TermCategory.PROPERTY);
RdfType rdfType = field.getRdfType();
TermValue value = null;
if (rdfType == null) {
throw new RuntimeException("RDF type not defined for property: " + field.getLocalName());
}
if (rdfType.canAsListType()) {
value = new TermValue();
value.setContainer(Container.LIST);
}
// if (rdfType.canAsListType()) {
// rdfType = rdfType.asListType().getElementType();
// }
boolean uriRef = properties.isIdRef(property.getURI());
boolean enumerable =
rdfType != null &&
rdfType.canAsFrame() &&
(rdfType.asFrame().getCategory() == RestCategory.ENUMERABLE);
boolean stubbed = false;
// stubbed=true means that the object is stubbed out because it is coerced as an IRI reference only,
// or it is an enumerable type.
if (enumerable || uriRef ) {
if (value == null) {
value = new TermValue();
}
value.setType("@id");
stubbed = true;
}
if (properties.getOptionalProperties().contains(property.getURI())) {
if (value == null) {
value = new TermValue();
}
value.setMinCardinality(0);
}
if (
enumerable
|| (rdfType!=null && rdfType.canAsFrame() && rdfType.asFrame().hasInstances())
) {
addIndividuals(context, rdfType.asFrame());
}
addValueRestriction(context, field);
if (value != null) {
value.setId(iriValue);
info.setObjectValue(value);
} else {
info.setIriValue(iriValue);
}
addNamespace(context, field, property);
if (!context.containsTerm(localName)) {
context.add(info);
}
if (value != null && value.getContainer() == Container.LIST) {
addType(properties, context, rdfType, stubbed, allFields);
} else if (rdfType.canAsFrame()) {
addType(properties, context, rdfType, stubbed, allFields);
} else {
addNamespace(context, rdfType);
addType(properties, context, rdfType, true, allFields);
if (!properties.getExpandedValues().contains(propertyURI)) {
String propertyTypeURI = rdfType.getUri();
String typeIRI = iriRef(context, rdfType.getNamespace(), rdfType.getLocalName(), propertyTypeURI);
if (value == null) {
value = new TermValue();
}
value.setId(iriValue);
value.setType(typeIRI);
info.setObjectValue(value);
addNamespace(context, rdfType);
} else {
System.out.println("expanded value: " + info.getTermName());
}
}
coerceType(info, properties);
if (field.getType().canAs(OntProperty.class)) {
addPropertyHierarchy(context, field.getType().asProperty());
}
}
private void addPropertyHierarchy(JsonContext context, OntProperty property) {
String localName = property.getLocalName();
TermInfo info = context.getTermInfoByShortName(localName);
if (info == null) {
info = new TermInfo(localName);
String uri = property.getURI();
info.setIriValue(uri);
info.setCategory(TermCategory.PROPERTY);
TermValue value = new TermValue();
TermInfo namespace = addNamespace(context, property);
StringBuilder id = new StringBuilder();
id.append(namespace.getTermName());
id.append(":");
id.append(property.getLocalName());
value.setId(id.toString());
value.setType("@id");
info.setObjectValue(value);
context.add(info);
context.put(uri, info);
}
List extends OntProperty> list = property.listSubProperties(true).toList();
for (OntProperty p : list) {
addPropertyHierarchy(context, p);
}
}
private void addValueRestriction(JsonContext context, Field field) {
NamedIndividual value = field.getValueRestriction();
if (value != null) {
String uri = value.getUri();
TermInfo info = context.getTermInfoByURI(uri);
if (info == null) {
info = new TermInfo(value.getLocalName());
info.setCategory(TermCategory.INDIVIDUAL);
info.setIriValue(uri);
context.add(info);
}
}
}
private void coerceType(TermInfo info, ContextProperties properties) {
String key = info.getTermName() + ".@type";
String typeURI = properties.getProperty(key);
if (typeURI == null) return;
}
private TermInfo addNamespace(JsonContext context, NamedIndividual individual) {
String namespace = individual.getNamespaceURI();
TermInfo term = context.getTermInfoByURI(namespace);
if (term != null) return term;
String prefix = getPrefix(context, namespace);
OntologyInfo info = typeManager.getOntologyByNamespaceUri(namespace);
term = new TermInfo(prefix);
term.setIriValue(namespace);
term.setCategory(TermCategory.NAMESPACE);
context.add(term);
return term;
}
private TermInfo addNamespace(JsonContext context, RdfType rdfType) {
String namespace = rdfType.getNamespace();
TermInfo term = context.getTermInfoByURI(namespace);
if (term != null) return term;
OntologyInfo info = typeManager.getOntologyByNamespaceUri(namespace);
String prefix = info==null ?
TypeManager.getDefaultNamespacePrefix(namespace) :
info.getPrefix();
term = new TermInfo(prefix);
term.setIriValue(namespace);
term.setCategory(TermCategory.NAMESPACE);
context.add(term);
return term;
}
private boolean isIncluded(Field field, ContextProperties properties, Frame declaringFrame) {
String fieldType = field.getRdfType().getUri();
if (properties.getExcludedTypes().contains(fieldType)) return false;
List superList = declaringFrame.getSupertypeList();
for (Frame superFrame : superList) {
if (!isIncluded(field, properties, superFrame)) {
return false;
}
}
FrameConstraints constraints = properties.getFrameConstraints(declaringFrame.getLocalName());
return (constraints == null) || constraints.isIncludedProperty(field.getURI());
}
private void addIndividuals(JsonContext context, Frame frame) {
if (frame.getUri().startsWith("http://www.w3.org/1999/02/22-rdf-syntax-ns#") ||
frame.getUri().startsWith("http://www.w3.org/2000/01/rdf-schema#") ||
frame.getUri().startsWith("http://www.w3.org/2002/07/owl#")
) return;
if (frame.canAsEnumeration()) {
addIndividuals(context, frame.asEnumeration());
} else {
List list = frame.listInstances(false);
for (NamedIndividual n : list) {
String name = n.getLocalName();
String uri = n.getUri();
TermInfo term = context.getTermInfoByShortName(name);
if (term != null) {
String termURI = term.getIri();
if (!uri.equals(termURI)) {
// There is another entity with the same short name.
// Check to see if this entity is registered by another name.
term = context.getTermInfoByURI(uri);
if (term == null) {
// Not registered. So create a new term using a CURIE.
TermInfo nsTerm = addNamespace(context, n);
String prefix = nsTerm.getTermName();
name = prefix + ":" + name;
term = new TermInfo(name);
term.setIriValue(name);
context.add(term);
}
}
}
if (term == null) {
TermInfo nsTerm = addNamespace(context, n);
uri = nsTerm.getTermName() + ":" + name;
term = new TermInfo(name);
term.setIriValue(uri);
context.add(term);
}
}
}
}
private void addIndividuals(JsonContext context, Enumeration e) {
List list = e.getIndividualList();
for (NamedIndividual n : list) {
String name = n.getLocalName();
TermInfo term = new TermInfo(name);
term.setIriValue(n.getUri());
context.add(term);
}
}
private void addNamespace(JsonContext context, Field field, OntProperty property) {
String namespace = field.getProperty().getNameSpace();
String prefix = getPrefix(context, namespace);
TermInfo term = context.getTermInfoByShortName(prefix);
if (term != null) return;
term = new TermInfo(prefix);
term.setCategory(TermCategory.NAMESPACE);
term.setIriValue(namespace);
context.add(term);
}
private TermInfo addNamespace(JsonContext context, OntProperty property) {
String namespace = property.getNameSpace();
String prefix = getPrefix(context, namespace);
TermInfo term = context.getTermInfoByShortName(prefix);
if (term != null) {
return term;
}
term = new TermInfo(prefix);
term.setCategory(TermCategory.NAMESPACE);
term.setIriValue(namespace);
context.add(term);
return term;
}
private String iriRef(JsonContext context, String namespaceURI, String localName, String uri) {
if (typeManager.isStandardLiteralType(uri)) {
namespaceURI = XSD.getURI();
localName = XSD.xstring.getLocalName();
}
String prefix = getPrefix(context, namespaceURI);
if (prefix == null) {
return uri;
}
return prefix + ":" + localName;
}
private OntologyInfo createOntologyInfo(String namespaceURI) {
Model tmp = ModelFactory.createDefaultModel();
Resource namespaceResource = tmp.createResource(namespaceURI);
String ontologyURI = null;
String prefix = null;
String label = null;
// Check to see if the namespaceURI is listed as the subject in any statements
StmtIterator sequence = model.listStatements(namespaceResource, null, (RDFNode) null);
while (sequence.hasNext()) {
Statement s = sequence.next();
if (s.getPredicate().equals(RDF.type) && s.getObject().equals(OWL.Ontology)) {
ontologyURI = namespaceURI;
}
if (s.getPredicate().equals(RDFS.label) ||
s.getPredicate().equals(DublinCoreTerms.title)) {
label = s.getObject().asLiteral().getString();
}
if (s.getPredicate().equals(BindVocabulary.suggestedPrefix) ||
s.getPredicate().equals(VannVocabulary.preferredNamespacePrefix)) {
prefix = s.getObject().asLiteral().getString();
}
if ((ontologyURI != null) && (prefix!=null) ) {
break;
}
}
if (ontologyURI == null) {
// Check to see if the namespaceURI is referenced via the preferredNamespacePrefix
Literal object = tmp.createLiteral(namespaceURI);
sequence = model.listStatements(null, null, object);
if (sequence.hasNext()) {
Statement s = sequence.next();
Resource subject = s.getSubject();
ontologyURI = subject.getURI();
s = subject.getProperty(VannVocabulary.preferredNamespacePrefix);
if (s != null) {
prefix = s.getObject().asLiteral().getString();
} else {
s = subject.getProperty(BindVocabulary.suggestedPrefix);
if (s != null) {
prefix = s.getObject().asLiteral().getString();
}
}
if (prefix != null) {
s = subject.getProperty(DublinCoreTerms.title);
if (s == null) {
s = subject.getProperty(RDFS.label);
}
if (s == null) {
s = subject.getProperty(DublinCoreElements.title);
}
if (s != null) {
label = s.getObject().asLiteral().getString();
}
}
}
}
OntologyInfo info = new OntologyInfo();
info.setNamespaceUri(namespaceURI);
info.setOntologyURI(ontologyURI);
info.setPrefix(prefix);
info.setLabel(label);
return info;
}
private String getPrefix(JsonContext context, String namespaceURI) {
String prefix = null;
// Special handling for OWL namespace.
if (OWL2.NS.equals(namespaceURI)) {
OntologyInfo info = typeManager.getOntologyByNamespaceUri(namespaceURI);
prefix = info.getPrefix();
} else {
OntologyInfo info = typeManager.getOntologyByNamespaceUri(namespaceURI);
if (info == null) {
info = createOntologyInfo(namespaceURI);
typeManager.add(info);
prefix = info.getPrefix();
} else {
prefix = info.getPrefix();
}
}
if (prefix == null && namespaceURI.equals("http://www.w3.org/1999/02/22-rdf-syntax-ns#")) {
prefix = "rdf";
}
if (prefix !=null && !context.containsTerm(prefix)) {
String uri = namespaceURI;
context.add(prefix, uri).setCategory(TermCategory.NAMESPACE);
}
return prefix;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy