/*******************************************************************************
* Copyright 2014 Miami-Dade County
*
* 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.sharegov.cirm;
import java.io.File;
import java.io.FileOutputStream;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import mjson.Json;
import org.hypergraphdb.HGEnvironment;
import org.hypergraphdb.app.owl.HGDBOWLManager;
import org.hypergraphdb.app.owl.HGDBOntologyFactory;
import org.hypergraphdb.app.owl.core.OWLDataFactoryHGDB;
import org.hypergraphdb.app.owl.core.OWLDataFactoryInternalsHGDB;
import org.hypergraphdb.app.owl.core.OWLObjectHGDB;
import org.hypergraphdb.app.owl.versioning.distributed.VDHGDBOntologyRepository;
import org.semanticweb.owlapi.model.AddAxiom;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAnnotation;
import org.semanticweb.owlapi.model.OWLAnnotationProperty;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLDataAllValuesFrom;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLDataHasValue;
import org.semanticweb.owlapi.model.OWLDataProperty;
import org.semanticweb.owlapi.model.OWLDataPropertyExpression;
import org.semanticweb.owlapi.model.OWLDataPropertyRangeAxiom;
import org.semanticweb.owlapi.model.OWLDataRange;
import org.semanticweb.owlapi.model.OWLDataSomeValuesFrom;
import org.semanticweb.owlapi.model.OWLDatatype;
import org.semanticweb.owlapi.model.OWLDatatypeRestriction;
import org.semanticweb.owlapi.model.OWLEntity;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObject;
import org.semanticweb.owlapi.model.OWLObjectAllValuesFrom;
import org.semanticweb.owlapi.model.OWLObjectComplementOf;
import org.semanticweb.owlapi.model.OWLObjectHasValue;
import org.semanticweb.owlapi.model.OWLObjectIntersectionOf;
import org.semanticweb.owlapi.model.OWLObjectInverseOf;
import org.semanticweb.owlapi.model.OWLObjectOneOf;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.model.OWLObjectPropertyRangeAxiom;
import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom;
import org.semanticweb.owlapi.model.OWLObjectUnionOf;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyChange;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.model.OWLProperty;
import org.semanticweb.owlapi.model.OWLPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLPropertyAssertionObject;
import org.semanticweb.owlapi.model.OWLPropertyDomainAxiom;
import org.semanticweb.owlapi.model.OWLPropertyExpression;
import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom;
import org.semanticweb.owlapi.model.PrefixManager;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.util.DefaultPrefixManager;
import org.semanticweb.owlapi.util.OWLEntityRemover;
import org.semanticweb.owlapi.util.ShortFormProvider;
import org.semanticweb.owlapi.vocab.OWL2Datatype;
import org.sharegov.cirm.owl.OWLObjectPropertyCondition;
import org.sharegov.cirm.owl.OwlRepo;
import org.sharegov.cirm.owl.SynchronizedOWLManager;
import org.sharegov.cirm.owl.SynchronizedOWLOntologyManager;
import org.sharegov.cirm.rest.OntoAdmin;
import org.sharegov.cirm.utils.Base64;
import org.sharegov.cirm.utils.CustomOWLOntologyIRIMapper;
import org.sharegov.cirm.utils.DLQueryParser;
import org.sharegov.cirm.utils.GenUtils;
/**
* <p>
* Represents the OWL environment used by the applications.
* </p>
*
* <p>
* Also contains static utility methods for working with OWL.
* </p>
*
* @author Borislav Iordanov
*
*/
public class OWL
{
/** The order of this static var init is important(dependencies) so its defined before all others. **/
private static Pattern prefixedPattern = Pattern.compile("\\w+\\:[A-Za-z0-9\\%\\-\\._~]+");
private static volatile OWLObjectPropertyCondition DEFAULT_STOP_EXPANSION_CONDITION;
public static boolean DBG_HGDB_ENTITY_CREATION = false;
private static volatile OWLOntologyManager manager;
private static volatile OWLDataFactory factory;
private static volatile OntologyLoader loader;
private static volatile PrefixManager prefixManager = null;
private static volatile boolean initialized = false;
private static synchronized void init()
{
if (!initialized) {
initChecked();
}
}
private static synchronized void initChecked()
{
if (!initialized)
{
if (StartUp.getConfig().has("metaDatabaseLocation"))
{
if (!VDHGDBOntologyRepository.hasInstance())
{
//Initialisation of repository location before everything else:
if (HGEnvironment.exists(StartUp.getConfig().at("metaDatabaseLocation").asString()))
{
VDHGDBOntologyRepository.setHypergraphDBLocation(StartUp.getConfig().at("metaDatabaseLocation").asString());
}
else
{
//Refs clinit will trigger a call to owl.init
OwlRepo repo = Refs.owlRepo.resolve();
if (!VDHGDBOntologyRepository.hasInstance())
{
// TODO: hard-coded list, we need to have this in bootstrap JSON config.
repo.createRepositoryFromDefaultPeer(
StartUp.getConfig().at("metaDatabaseLocation").asString(),
new HashSet<IRI>(Arrays.asList(
IRI.create("http://www.miamidade.gov/ontology"),
IRI.create("http://www.miamidade.gov/cirm/legacy"))));
}
}
VDHGDBOntologyRepository.getInstance();
}
manager = SynchronizedOWLOntologyManager.synchronizedManager(HGDBOWLManager.createOWLOntologyManager());
if (DBG_HGDB_ENTITY_CREATION)
OWLDataFactoryInternalsHGDB.DBG = true;
}
else
manager = SynchronizedOWLManager.createOWLOntologyManager();
manager.setSilentMissingImportsHandling(false);
//factory = SynchronizedOWLDataFactory.synchronizedFactory(manager.getOWLDataFactory());
factory = manager.getOWLDataFactory();
//Assert Factory is SynchronizedOWLDataFactory or HGDB and threadsafe.
OWLDataFactoryHGDB.getInstance().ignoreOntologyScope(true);
loader = new OntologyLoader(manager);
if (StartUp.getConfig().has("customIRIMappingFile"))
{
String customIRIMappingFile = StartUp.getConfig().at("customIRIMappingFile").asString();
manager.addIRIMapper(CustomOWLOntologyIRIMapper.createFrom(new File(customIRIMappingFile)));
}
DEFAULT_STOP_EXPANSION_CONDITION = getInitializedDefaultStopExpansionCondition(factory);
initialized = true;
}
}
private static OWLObjectPropertyCondition getInitializedDefaultStopExpansionCondition(OWLDataFactory factory)
{
Set<OWLObjectProperty> stopExpansionProps = new HashSet<OWLObjectProperty>();
if (StartUp.getConfig().has("stopExpansionConditionIRI"))
{
for(Object iri : StartUp.getConfig().at("stopExpansionConditionIRI").asList())
{
stopExpansionProps.add(factory.getOWLObjectProperty(IRI.create((String)iri)));
}
}
return new OWLObjectPropertyCondition(stopExpansionProps);
}
public static OWLOntologyManager manager() { init(); return manager; }
public static OntologyLoader loader() { init(); return loader; }
public static PrefixManager prefixManager()
{
init();
// We don't care about
if (prefixManager == null)
{
DefaultPrefixManager pm = new DefaultPrefixManager(manager.getOntologyFormat(ontology()).asPrefixOWLOntologyFormat());
if (StartUp.getConfig().has("ontologyPrefixes"))
for (Map.Entry<String, Json> e : StartUp.getConfig().at("ontologyPrefixes", Json.object()).asJsonMap().entrySet())
if (!e.getKey().equals(":") && pm.getPrefix(e.getKey()) != null && !e.getValue().asString().equals(pm.getPrefix(e.getKey())))
throw new RuntimeException("Prefix clash between default ontology and startup configuration: " + e.getKey());
else
pm.setPrefix(e.getKey(), e.getValue().asString());
prefixManager = pm;
// if (!StartUp.getConfig().has("metaDatabaseLocation") && manager.getOntologyFormat(ontology()) != null &&
// manager.getOntologyFormat(ontology()).isPrefixOWLOntologyFormat())
// prefixManager = new DefaultPrefixManager(manager.getOntologyFormat(ontology()).asPrefixOWLOntologyFormat());
// else
// {
// DefaultPrefixManager pm = new DefaultPrefixManager();
// for (Map.Entry<String, Json> e : StartUp.getConfig().at("ontologyPrefixes", Json.object()).asJsonMap().entrySet())
// pm.setPrefix(e.getKey(), e.getValue().asString());
// prefixManager = pm;
// }
}
return prefixManager;
}
public static void saveOntology(OWLOntology ontology, File destination)
{
FileOutputStream out = null;
try
{
out = new FileOutputStream(destination);
ontology.getOWLOntologyManager().saveOntology(ontology, out);
}
catch (Exception ex)
{
throw new RuntimeException(ex);
}
finally
{
if (out != null) { try { out.close(); } catch (Throwable t) { } }
}
}
@SuppressWarnings("unchecked")
public static <T> T findImplementation(Class<T> clazz, IRI indIri)
{
OWLNamedIndividual I = individual(indIri);
for (OWLIndividual x : I.getObjectPropertyValues(objectProperty("hasImplementation"), ontology()))
{
OWLNamedIndividual impl = (OWLNamedIndividual)x;
Class<?> cl;
try
{
cl = Class.forName(impl.getIRI().getFragment());
if (!clazz.isAssignableFrom(cl))
continue;
return (T)cl.newInstance();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
return null;
}
@SuppressWarnings("unchecked")
public static <T> T getImplementation(IRI indIri)
{
OWLNamedIndividual ind = individual(indIri);
OWLNamedIndividual implIndividual = (OWLNamedIndividual)
objectProperty(ind, "hasImplementation");
if (implIndividual == null)
throw new RuntimeException("Missing 'hasImplementation' property for individual " +
indIri);
Class<?> cl;
try
{
cl = Class.forName(implIndividual.getIRI().getFragment());
return (T)cl.newInstance();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
public static OWLDataFactory dataFactory()
{
init();
return factory;
}
public static IRI fullIri(String s)
{
if (prefixedPattern.matcher(s).matches() && !s.startsWith("mailto:"))
{
return prefixManager().getIRI(s);
}
return fullIri(s, StartUp.getConfig().at("nameBase").asString());
}
public static IRI fullIri(String s, String ontologyIri)
{
IRI oi = IRI.create(ontologyIri);
if (s == null || s.length() == 0)
return oi;
else if (s.charAt(0) == '/' || s.charAt(0) == '#')
return oi.resolve(s);
else if (s.startsWith("mailto:"))
return IRI.create(s);
else if (!s.startsWith("http://"))
return oi.resolve("#" + s);
else
return IRI.create(s);
}
public static IRI businessObjectId(String type, String id)
{
return IRI.create(Refs.boIriPrefix.resolve() + type + "/" + id + "#bo");
}
public static String businessObjectId(OWLOntology bonto)
{
String A [] = bonto.getOntologyID().getOntologyIRI().toString().split("/");
return A[A.length - 1];
}
/**
* Checks, if the IRI's fragment is "bo".
* @param iri
* @return
*/
public static boolean isBusinessObject(IRI iri)
{
return "bo".equals(iri.getFragment());
}
public static boolean isBusinessObjectOntology(OWLOntology O)
{
String iri = O.getOntologyID().getOntologyIRI().toString();
String [] parts = iri.split("/");
return iri.indexOf("miamidade.gov/bo") > -1 && parts.length > 0 &&
parts[parts.length - 1].matches("\\d+");
}
public static boolean isBusinessObject(OWLIndividual ind)
{
return ind instanceof OWLNamedIndividual &&
isBusinessObject(((OWLNamedIndividual)ind).getIRI());
}
/**
* Parses the id value as long value from a business ontology IRI that ends with /ANYLONGNUMBER#bo.
* @param boIri
* @return an id as long value parsed between "/" and "#bo".
* @throws NumberFormatException, IndexOutOfBounds if
*/
public static long parseIDFromBusinessOntologyIRI(IRI boIri) {
String boIriStr = boIri.toString();
int poundSignIndex = boIriStr.lastIndexOf("#bo");
int lastSlashIndex = boIriStr.lastIndexOf('/');
String idStr = boIriStr.substring(lastSlashIndex + 1, poundSignIndex);
long id = Long.parseLong(idStr);
return id;
}
public static OWLNamedIndividual businessObject(OWLOntology boOntology)
{
//System.out.println(boOntology.getOntologyID().getOntologyIRI().resolve("#bo"));
//System.out.println(dataFactory());
return boOntology.getOWLOntologyManager().getOWLDataFactory().getOWLNamedIndividual(boOntology.getOntologyID().getOntologyIRI().resolve("#bo"));
}
/**
* Will return an OWLClass with an iri based on iriBase
*
* @param boIri
* @return
*/
public static OWLClass businessObjectType(IRI boIri)
{
// boIri.toURI().getPath() should give something like "/bo/CLASSNAME/BOID"
return owlClass(boIri.toURI().getPath().split("/")[2]);
}
public static OWLReasoner reasoner()
{
return reasoner(ontology());
}
public static OWLReasoner reasoner(OWLOntology ontology)
{
return loader().getReasoner(ontology);
}
public static OWLOntology ontology(String iri)
{
return OWL.loader().get(iri);
}
public static OWLOntology ontology()
{
return loader().get(Refs.defaultOntologyIRI.resolve());
}
public static Set<OWLOntology> ontologies()
{
return ontology().getImportsClosure();
}
/**
* Returns the NamedIndividual for a given IRI fragment by assuming the fragment is unique for
* legacy and county ontology. The import closure of meta will be scanned.
* The method will retrurn the first matched named individual and ignore if more than one exists.
*
* @throws IllegalStateException, if no named individual could be found.
* @param iRIfragment an fragment of an IRI. Without pound sign.
* @param factory
* @return the found NamedIndividual or NULL if not found.
*/
public static OWLNamedIndividual findNamedIndividualByFragment(String iRIfragment) {
Map<String, Object> ontoPrefixes = StartUp.getConfig().at("ontologyPrefixes").asMap();
for (Object prefixIri : ontoPrefixes.values()) {
IRI indIRI = IRI.create("" + prefixIri + iRIfragment);
if (ontology().containsIndividualInSignature(indIRI, true)) {
return individual(indIRI);
}
}
System.err.println("getNamedIndividualFromFragment: No individual in any loaded ontologies could be found for iriFragment " + iRIfragment + " returning null.");
return null;
//throw new IllegalStateException("No individual in any loaded ontologies could be found for iriFragment " + iRIfragment);
}
/**
* <p>Return the main ontology or this business object's own ontology
* if this is a business object indeed (i.e. its IRI follows the naming
* convention for business objects.)
* </p>
*/
/* public static OWLOntology ontology(OWLNamedIndividual object)
{
if (isBusinessObject(object.getIRI()))
return new OperationService().getBusinessObjectOntology(object.getIRI()).getOntology();
else
return ontology();
} */
public static OWLNamedIndividual individual(IRI id)
{
if (id == null) throw new NullPointerException("IRI id was null");
return dataFactory().getOWLNamedIndividual(id);
}
public static boolean isObjectProperty(IRI id)
{
OWLObjectProperty prop = dataFactory().getOWLObjectProperty(id);
for (OWLOntology o : ontologies())
{
if (o.isDeclared(prop))
return true;
}
return false;
}
public static boolean isDataProperty(IRI id)
{
OWLDataProperty prop = dataFactory().getOWLDataProperty(id);
for (OWLOntology o : ontologies())
{
if (o.isDeclared(prop))
return true;
}
return false;
}
public static boolean isAnnotation(IRI id)
{
OWLAnnotationProperty prop = dataFactory().getOWLAnnotationProperty(id);
for (OWLOntology o : ontologies())
{
if (o.isDeclared(prop))
return true;
}
return false;
}
public static PropertyType getPropertyType (IRI id){
OWLObjectProperty propO = dataFactory().getOWLObjectProperty(id);
OWLDataProperty propD = dataFactory().getOWLDataProperty(id);
OWLAnnotationProperty propA = dataFactory().getOWLAnnotationProperty(id);
for (OWLOntology o : ontologies())
{
if (o.getSignature().contains(propO))
return PropertyType.OBJECT;
else if (o.getSignature().contains(propD))
return PropertyType.DATA;
else if (o.getSignature().contains(propA))
return PropertyType.ANNOTATION;
}
return PropertyType.UNKNOWN;
}
public static OWLObjectProperty objectProperty(IRI id)
{
return dataFactory().getOWLObjectProperty(id);
}
public static OWLDataProperty dataProperty(IRI id)
{
return dataFactory().getOWLDataProperty(id);
}
public static OWLNamedIndividual objectProperty(OWLNamedIndividual ind,
String id,
OWLOntology O)
{
Set<OWLIndividual> S = ind.getObjectPropertyValues(objectProperty(id), O);
return S.isEmpty() ? null : S.iterator().next().asOWLNamedIndividual();
}
/**
*
* @param ind
* @param id
* @return the first objectPropertyValue the reasoner returns for the given ind and objectProperty name (id).
*/
public static OWLNamedIndividual objectProperty(OWLNamedIndividual ind, String id)
{
OWLObjectProperty prop = objectProperty(id);
if (prop == null)
throw new NullPointerException("No object property with ID '" + id + "'");
Set<OWLNamedIndividual> S = reasoner().getObjectPropertyValues(ind, prop).getFlattened();
if (S.isEmpty())
return null;
else
return S.iterator().next();
}
public static Set<OWLAnnotation> annotations(OWLNamedIndividual ind)
{
Set<OWLAnnotation> S = new HashSet<OWLAnnotation>();
for (OWLOntology O : ontology().getImportsClosure())
S.addAll(ind.getAnnotations(O));
return S;
}
public static Map<OWLPropertyExpression<?,?>, Set<OWLObject>> allProperties(OWLIndividual ind)
{
return allProperties(ind, ontology(), true, true);
}
public static Map<OWLPropertyExpression<?,?>, Set<OWLObject>> allProperties(OWLIndividual ind, OWLOntology ontology)
{
return allProperties(ind, ontology, true, true);
}
@SuppressWarnings("unchecked")
public static Map<OWLPropertyExpression<?,?>, Set<OWLObject>> allProperties(OWLIndividual ind,
OWLOntology ontology,
boolean collectDataProperties,
boolean collectObjectProperties)
{
HashMap<OWLPropertyExpression<?,?>, Set<OWLObject>> M =
new HashMap<OWLPropertyExpression<?,?>, Set<OWLObject>>();
for (OWLOntology o : ontology.getImportsClosure())
{
// Need to add one by one and make sure entries of one ontology don't overwrite entries
// another in the import chain.
if (collectObjectProperties) for (Map.Entry<OWLObjectPropertyExpression, Set<OWLIndividual>> e : ind.getObjectPropertyValues(o).entrySet())
{
Set<OWLObject> S = M.get(e.getKey());
if (S == null)
M.put(e.getKey(), (Set<OWLObject>)(Set<?>)e.getValue());
else
S.addAll(e.getValue());
}
if (collectDataProperties) for (Map.Entry<OWLDataPropertyExpression, Set<OWLLiteral>> e : ind.getDataPropertyValues(o).entrySet())
{
Set<OWLObject> S = M.get(e.getKey());
if (S == null)
M.put(e.getKey(), (Set<OWLObject>)(Set<?>)e.getValue());
else
S.addAll(e.getValue());
}
}
return M;
}
@SuppressWarnings("unchecked")
public static Set<OWLLiteral> dataProperties(OWLNamedIndividual ind, String id)
{
OWLDataProperty prop = dataProperty(id);
if (prop == null)
throw new NullPointerException("No data property with ID '" + id + "'");
Map<OWLPropertyExpression<?, ?>, Set<OWLObject>> props = allProperties(ind, ontology(), true, false);
Set<OWLLiteral> S = (Set<OWLLiteral>)(Set<?>)props.get(prop);
return S == null ? Collections.EMPTY_SET : S;
//return reasoner().getDataPropertyValues(ind, prop);
}
public static OWLLiteral dataProperty(OWLNamedIndividual ind, String id)
{
Set<OWLLiteral> S = dataProperties(ind, id);
if (S.isEmpty())
return null;
else
return S.iterator().next();
}
public static OWLClass owlClass(IRI id)
{
return dataFactory().getOWLClass(id);
}
public static OWLNamedIndividual individual(String id)
{
return dataFactory().getOWLNamedIndividual(fullIri(id));
}
public static OWLLiteral literal(String literal)
{
return dataFactory().getOWLLiteral(literal);
}
public static OWLObjectProperty objectProperty(String id)
{
return dataFactory().getOWLObjectProperty(fullIri(id));
}
public static OWLDataProperty dataProperty(String id)
{
return dataFactory().getOWLDataProperty(fullIri(id));
}
public static OWLClass owlClass(String id)
{
return owlClass(fullIri(id));
}
public static OWLAnnotationProperty annotationProperty(String id)
{
return annotationProperty(fullIri(id));
}
public static OWLAnnotationProperty annotationProperty(IRI id)
{
return dataFactory().getOWLAnnotationProperty(id);
}
public synchronized static String getAnnotation(OWLEntity entity, OWLAnnotationProperty aprop)
{
for (OWLOntology o : ontologies())
{
Set<OWLAnnotation> anns = entity.getAnnotations(o, aprop);
if (!anns.isEmpty())
return ((OWLLiteral)anns.iterator().next().getValue()).getLiteral();
}
return null;
}
public static synchronized String getEntityLabel(OWLOntology O, OWLEntity entity)
{
Set<OWLAnnotation> anns = entity.getAnnotations(O,
annotationProperty("http://www.w3.org/2000/01/rdf-schema#label"));
if (!anns.isEmpty())
return ((OWLLiteral)anns.iterator().next().getValue()).getLiteral();
else
return entity.getIRI().getFragment();
}
public static synchronized String getEntityLabel(OWLEntity entity)
{
for (OWLOntology o : ontologies())
{
Set<OWLAnnotation> anns = entity.getAnnotations(o,
annotationProperty("http://www.w3.org/2000/01/rdf-schema#label"));
if (!anns.isEmpty())
return ((OWLLiteral)anns.iterator().next().getValue()).getLiteral();
}
return entity.getIRI().getFragment();
}
public static Json annotate(OWLEntity object, Json x)
{
for (OWLOntology o : ontologies())
{
x = annotate(o, object, x, null);
}
return x;
}
public static Json annotate(OWLEntity object, Json x, ShortFormProvider sp)
{
for (OWLOntology o : ontologies())
{
x = annotate(o, object, x, sp);
}
return x;
}
public static synchronized Json annotate(OWLOntology ontology, OWLEntity object, Json x)
{
return annotate(ontology, object, x, null);
}
public static synchronized Json annotate(OWLOntology ontology, OWLEntity object, Json x, ShortFormProvider sp)
{
if (sp == null) sp = OWLObjectMapper.DEFAULT_SHORTFORM_PROVIDER;
Set<OWLAnnotation> annotations = object.getAnnotations(ontology);
for (OWLAnnotation ann : annotations)
{
if (ann.getProperty() == null || ann.getValue() == null)
continue;
String annName = sp.getShortForm(ann.getProperty()); //was .getIRI().getFragment();
if (annName == null)
{
String [] A = ann.getProperty().getIRI().toString().split("/");
annName = A[A.length - 1];
}
String annValue = ((OWLLiteral)ann.getValue()).getLiteral();
x.set(annName, annValue);
}
if (!x.has("label"))
x.set("label", sp.getShortForm(object)); // was object.getIRI().getFragment());
return x;
}
/**
* Convert a Json value to an OWL literal using the first range of the
* the data property. If the dataproperty has no ranges defined, the given OWL2Datatype is used.
* If a OWL2Datatype is given and the dataproperty has ranges defined a match is enforced.
* If no OWL2Datatype is given, the first range that is an OWLDatatype will be used for the literal.
* (see @link #toLiteral(OWLDataRange, Json) for details on how the mapping
* is performed).
* @param prop
* @param value
* @param builtinDatatype if null, first range will become literal datatype; if given it must match range.
* @return an OWlLiteral or null, if the range does not match the given datatype or no OWLDatatype was found in the range.
*/
public static OWLLiteral toLiteral(OWLDataProperty prop, String value, OWL2Datatype builtinDatatype)
{
// Parse out if the value is an ISO date and convert it to the format XML datafactory accepts.
if (builtinDatatype == null)
{
try { return OWL.dateLiteral(GenUtils.parseDate(value), OWL2Datatype.XSD_DATE_TIME_STAMP); }
catch (Throwable t) { }
}
//TODO we could validate here, if the value string matches the builtinDatatype.
Set<OWLDataRange> ranges = prop.getRanges(ontologies());
if (ranges.isEmpty() && builtinDatatype != null) {
return dataFactory().getOWLLiteral(value, builtinDatatype);
}
for (OWLDataRange range : ranges)
{
if ((builtinDatatype == null && range instanceof OWLDatatype)
|| (builtinDatatype != null && range.equals(builtinDatatype)))
{
return dataFactory().getOWLLiteral(value, (OWLDatatype)range);
}
}
return null;
}
// public static OWLLiteral toLiteral(OWL2Datatype builtinDatatype, Json value)
// {
// if (range instanceof OWLDatatype)
// {
// String v = value.asString();
//// OWLDatatype type = (OWLDatatype)range;
//// if (type.isBoolean())
//// {
//// if (v.equalsIgnoreCase("on") || v.equalsIgnoreCase("yes") ||
//// v.equalsIgnoreCase("t") ||
//// v.equalsIgnoreCase("true"))
//// v = "true";
//// else
//// v = "false";
//// }
// return dataFactory().getOWLLiteral(v, builtinDatatype);
// }
// else
// return null;
// }
// forming class expressions
public static OWLObjectSomeValuesFrom some(OWLObjectPropertyExpression prop, OWLClassExpression clexpr)
{
checkImplementation(prop, clexpr);
return dataFactory().getOWLObjectSomeValuesFrom(prop, clexpr);
}
public static OWLObjectSomeValuesFrom someObject(String propName, OWLClassExpression clexpr)
{
checkImplementation(clexpr);
return some(objectProperty(propName), clexpr);
}
public static OWLDataSomeValuesFrom some(OWLDataPropertyExpression prop, OWLDataRange range)
{
checkImplementation(prop, range);
return dataFactory().getOWLDataSomeValuesFrom(prop, range);
}
public static OWLDataSomeValuesFrom someData(String prop, OWLDataRange range)
{
checkImplementation(range);
return some(dataProperty(prop), range);
}
public static OWLDataHasValue has(OWLDataPropertyExpression prop, OWLLiteral literal)
{
checkImplementation(prop, literal);
return dataFactory().getOWLDataHasValue(prop, literal);
}
public static OWLDataHasValue hasData(String prop, OWLLiteral literal)
{
checkImplementation(literal);
return has(dataProperty(prop), literal);
}
public static OWLObjectHasValue has(OWLObjectPropertyExpression prop, OWLIndividual individual)
{
checkImplementation(prop, individual);
return dataFactory().getOWLObjectHasValue(prop, individual);
}
public static OWLObjectHasValue hasObject(String prop, OWLIndividual individual)
{
checkImplementation(individual);
return has(objectProperty(prop), individual);
}
public static OWLObjectAllValuesFrom only(OWLObjectPropertyExpression prop, OWLClassExpression cl)
{
checkImplementation(prop, cl);
return dataFactory().getOWLObjectAllValuesFrom(prop, cl);
}
public static OWLDataAllValuesFrom only(OWLDataPropertyExpression prop, OWLDataRange range)
{
checkImplementation(prop, range);
return dataFactory().getOWLDataAllValuesFrom(prop, range);
}
public static OWLObjectComplementOf not(OWLClassExpression cl)
{
checkImplementation(cl);
return dataFactory().getOWLObjectComplementOf(cl);
}
public static OWLObjectIntersectionOf and(OWLClassExpression...classExpressions)
{
checkImplementation(classExpressions);
return dataFactory().getOWLObjectIntersectionOf(classExpressions);
}
public static OWLObjectUnionOf or(OWLClassExpression...classExpressions)
{
checkImplementation(classExpressions);
return dataFactory().getOWLObjectUnionOf(classExpressions);
}
public static OWLObjectOneOf oneOf(OWLIndividual...individuals)
{
checkImplementation(individuals);
return dataFactory().getOWLObjectOneOf(individuals);
}
/**
* <p>
* Using the main ontology imports closure, collect all object property values. This
* is normally performed by the reasoner (see {@link #objectProperties(OWLNamedIndividual, String)}
* method), but because of performance issues, when we know there aren't any properties inferred
* we can use this method.
*
* </p>
* @param ind
* @param prop
* @return
*/
public static Set<OWLIndividual> collectObjectProperties(OWLIndividual ind, OWLObjectProperty prop)
{
Set<OWLIndividual> S = new HashSet<OWLIndividual>();
for (OWLOntology O : ontology().getImportsClosure())
S.addAll(ind.getObjectPropertyValues(prop, O));
return S;
}
public static Set<OWLNamedIndividual> objectProperties(OWLNamedIndividual ind, String id)
{
return reasoner().getObjectPropertyValues(ind, objectProperty(id)).getFlattened();
}
public static OWLObjectInverseOf inverse(OWLObjectPropertyExpression expr)
{
checkImplementation(expr);
return dataFactory().getOWLObjectInverseOf(expr);
}
public static OWLObjectInverseOf inverse(String prop)
{
return inverse(objectProperty(prop));
}
public static String hash(String s)
{
try
{
MessageDigest algorithm = MessageDigest.getInstance("SHA-1");
algorithm.reset();
algorithm.update(s.getBytes());
byte[] digest = algorithm.digest();
// System.out.println("Digest size:" + digest.length);
return Base64.encode(digest, false);
}
catch (NoSuchAlgorithmException e)
{
System.out.println("Cannot SHA-1 hash, algorithm not found.");
e.printStackTrace();
}
return s;
}
public static String hash(OWLLiteral literal)
{
return hash(literal.getLiteral());
}
public static Map<String, OWLLiteral> hash(Map<OWLDataPropertyExpression, Set<OWLLiteral>> data)
{
Map<String, OWLLiteral> result = new HashMap<String, OWLLiteral>();
for(Set<OWLLiteral> set : data.values())
{
for(OWLLiteral literal: set)
{
String hash = hash(literal);
if(result.containsKey(hash) && !result.get(hash).equals(literal))
System.err.println("Hash collision occured!!!Hash=" + hash + " value= "+ literal.getLiteral());
else
result.put(hash, literal);
}
}
return result;
}
public static OWLPropertyAssertionAxiom<?, ?> assertProperty(OWLIndividual i, OWLProperty p, OWLPropertyAssertionObject value)
{
checkImplementation(i, p, value);
if (p instanceof OWLDataProperty && value instanceof OWLLiteral)
return (OWLPropertyAssertionAxiom<OWLDataPropertyExpression,OWLLiteral>) dataFactory().getOWLDataPropertyAssertionAxiom((OWLDataProperty) p, i ,(OWLLiteral) value);
else if (p instanceof OWLObjectProperty && value instanceof OWLIndividual)
return (OWLPropertyAssertionAxiom<OWLObjectPropertyExpression,OWLIndividual>) dataFactory().getOWLObjectPropertyAssertionAxiom((OWLObjectProperty) p, i ,(OWLIndividual) value);
else return null;
}
public static OWLClassAssertionAxiom assertClass(OWLIndividual i, OWLClassExpression e)
{
checkImplementation(i, e);
return dataFactory().getOWLClassAssertionAxiom(e, i);
}
public static Date addDaysToDate(Date start, float days, boolean useWorkWeek)
{
Date result = null;
int seconds = (int) (86400 * days);
Calendar c = Calendar.getInstance();
Set<OWLLiteral> holidays = new HashSet<OWLLiteral>();
for(OWLNamedIndividual holiday: reasoner()
.getInstances(owlClass("Observed_County_Holiday"), false).getFlattened())
{
for(OWLLiteral date: reasoner().getDataPropertyValues(holiday, dataProperty("hasDate")))
{
if (date != null)
holidays.add(date);
}
}
c.setTime(start);
if (!useWorkWeek)
{
c.add(Calendar.SECOND, seconds);
result = c.getTime();
}
else
{
int diff = seconds % 86400;
for(int workSeconds = 0; workSeconds < seconds-diff;)
{
c.add(Calendar.SECOND, 86400);
int dow = c.get(Calendar.DAY_OF_WEEK);
if(!( dow == Calendar.SATURDAY
|| dow == Calendar.SUNDAY))
{
OWLLiteral literal = dateLiteral(c.getTime());
if(!holidays.contains(literal))
workSeconds = workSeconds + 86400;
}
}
c.add(Calendar.SECOND, diff);
result = c.getTime();
}
return result;
}
public static Date parseDate(OWLLiteral value)
{
return parseDate(value.getLiteral());
}
public static Date parseDate(String value)
{
try
{
// parse ISO 8601 date
return DatatypeFactory.newInstance().newXMLGregorianCalendar(value).toGregorianCalendar().getTime();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
public static OWLLiteral dateLiteral(Date date, OWL2Datatype d)
{
OWLDataFactory factory = dataFactory();
OWLLiteral result = factory.getOWLLiteral("", d);
if(date == null)
return result;
try
{
//see:
//http://download.oracle.com/javase/6/docs/api/javax/xml/datatype/XMLGregorianCalendar.html#getXMLSchemaType()
Calendar c = Calendar.getInstance();
c.setTime(date);
XMLGregorianCalendar x = DatatypeFactory.newInstance().newXMLGregorianCalendar();
if(c instanceof GregorianCalendar)
if(DatatypeConstants.DATE.getNamespaceURI().equals(d.getIRI().toString()))
{
x.setYear(c.get(Calendar.YEAR));
x.setMonth(c.get(Calendar.MONTH));
x.setDay(c.get(Calendar.DAY_OF_MONTH));
result = factory.getOWLLiteral(x.toXMLFormat(),d);
}
else
result = factory.getOWLLiteral(DatatypeFactory.newInstance().newXMLGregorianCalendar((GregorianCalendar)c).toXMLFormat(), d);
}catch(Exception e)
{
System.out.println("Exception occured while attempting to extract a xsd date value");
e.printStackTrace(System.err);
}
return result;
}
public static OWLLiteral dateLiteral(Date date)
{
OWLDataFactory factory = dataFactory();
OWLLiteral result = factory.getOWLLiteral("", OWL2Datatype.XSD_DATE_TIME);
if(date == null)
return result;
try
{
DateFormat f = new SimpleDateFormat("yyyy-MM-dd'T00:00:00'");
result = factory.getOWLLiteral(f.format(date), OWL2Datatype.XSD_DATE_TIME);
}catch(Exception e)
{
System.out.println("Exception occured while attempting to extract a xsd date value");
e.printStackTrace(System.err);
}
return result;
}
public static String unescape(OWLLiteral literal){
String str = literal.getLiteral();
StringWriter out = new StringWriter(str.length() * 2);
int sz = str.length();
StringBuffer unicode = new StringBuffer(4);
boolean hadSlash = false;
boolean inUnicode = false;
for (int i = 0; i < sz; i++) {
char ch = str.charAt(i);
if (inUnicode) {
// if in unicode, then we're reading unicode
// values in somehow
unicode.append(ch);
if (unicode.length() == 4) {
// unicode now contains the four hex digits
// which represents our unicode character
try {
int value = Integer.parseInt(unicode.toString(), 16);
out.write((char) value);
unicode.setLength(0);
inUnicode = false;
hadSlash = false;
} catch (NumberFormatException nfe) {
throw nfe;
}
}
continue;
}
if (hadSlash) {
// handle an escaped value
hadSlash = false;
switch (ch) {
case '\\':
out.write('\\');
break;
case '\'':
out.write('\'');
break;
case '\"':
out.write('"');
break;
case 'r':
out.write('\r');
break;
case 'f':
out.write('\f');
break;
case 't':
out.write('\t');
break;
case 'n':
out.write('\n');
break;
case 'b':
out.write('\b');
break;
case 'u':
{
// uh-oh, we're in unicode country....
inUnicode = true;
break;
}
default :
out.write(ch);
break;
}
continue;
} else if (ch == '\\') {
hadSlash = true;
continue;
}
out.write(ch);
}
if (hadSlash) {
// then we're in the weird case of a \ at the end of the
// string, let's output it anyway.
out.write('\\');
}
return out.toString();
}
public static void deleteIndividuals(OWLOntology o, OWLClass cl)
{
OWLOntologyManager manager = o.getOWLOntologyManager();//manager();
Set<OWLIndividual> S = cl.getIndividuals(o);
for (OWLIndividual i : S)
{
System.out.println("Removing " + i);
OWLEntityRemover remover = new OWLEntityRemover(manager, Collections.singleton(o));
remover.visit(i.asOWLNamedIndividual());
manager.applyChanges(remover.getChanges());
}
}
public static void copyIndividuals(Set<OWLNamedIndividual> S, OWLOntology src, OWLOntology dest)
{
OWLOntologyManager manager = src.getOWLOntologyManager();//manager();
List<OWLOntologyChange> changes = new ArrayList<OWLOntologyChange>();
for (OWLNamedIndividual i : S)
{
System.out.println("Adding " + i);
for (OWLAxiom a : src.getAxioms(i))
changes.add(new AddAxiom(dest, a));
for (OWLAxiom ann : i.asOWLNamedIndividual().getAnnotationAssertionAxioms(src))
changes.add(new AddAxiom(dest, ann));
manager.applyChanges(changes);
}
}
/**
* Tries to put Json objects where only string iris were before..
* Example: a servicecase contains 4 activities with outcome C-CLOSED.
* Only the first serialized one will be an object, all others are iri-strings.
* This method will find that one full object and set it to the other 3 locations, replacing the iri-strings were.
*
* @param x
* @param jsonMap may be and mostly should be null; used for recursion.
* @return
*/
public static Json resolveIris(Json x, Map<String, Json> jsonMap)
{
if(jsonMap == null)
jsonMap = gatherIris(x, null);
//System.out.println("resolve`");
if(x.isObject())
for(Map.Entry<String, Json> entry: x.asJsonMap().entrySet())
{
if(entry.getValue().isString() &&
!entry.getKey().equals("iri")
&& (entry.getValue().asString().startsWith(Refs.nameBase.resolve())
|| entry.getValue().asString().startsWith(Refs.defaultOntologyIRI.resolve())
)
&& entry.getValue() != null)
{
try
{
x.set(entry.getKey(), jsonMap.get(entry.getValue().asString()));
}
catch (Throwable t)
{
System.err.println("OWL.resolveIris error ignored " + t);
System.err.println("Json x was " + x + " entry.getKey() was " + entry.getKey()
+ " entry.getValue() was " + entry.getValue());
GenUtils.logStackTrace(t.getStackTrace(), 10);
}
}
else if(entry.getValue().isArray() || entry.getValue().isObject())
resolveIris(entry.getValue(), jsonMap);
}
else if(x.isArray())
{
for (int i = 0; i < x.asJsonList().size(); i++)
{
Json el = x.at(i);
if (el.isString() &&
(el.asString().contains(Refs.nameBase.resolve())
|| el.asString().contains(Refs.defaultOntologyIRI.resolve())
) && jsonMap.containsKey(el.asString()))
x.asJsonList().set(i, jsonMap.get(el.asString()));
else
resolveIris(el, jsonMap);
}
}
return x;
}
/**
* Finds all objects containing an iri property and createa a map from String iri to object recursively.
* If two objects with the same iri exist, the latter visited wins! No error is printed.
* @param x
* @param jsonMap
* @return
*/
public static Map<String, Json> gatherIris(Json x, Map<String,Json> jsonMap)
{
if(jsonMap == null)
jsonMap = new HashMap<String, Json>();
if(x.isObject())
for(Map.Entry<String, Json> entry: x.asJsonMap().entrySet())
{
if(entry.getKey().equals("iri"))
{
jsonMap.put(entry.getValue().asString(), x);
}
else if(entry.getValue().isArray() || entry.getValue().isObject())
{
gatherIris(entry.getValue(), jsonMap);
}
}
else if(x.isArray())
for(Json j : x.asJsonList())
{
gatherIris(j, jsonMap);
}
return jsonMap;
}
public static Json toBoJson(Json metaJson)
{
Json boJson = Json.object().set("type",metaJson.at("type")).set("boid",metaJson.at("boid")).set("iri",metaJson.at("iri"));
Json properties = Json.object();
if(metaJson.isObject())
{
for(Map.Entry<String, Json> entry: metaJson.asJsonMap().entrySet())
{
if(entry.getKey().equals("type")
|| entry.getKey().equals("boid")
|| entry.getKey().equals("label")
|| entry.getKey().equals("iri"))
continue;
else
properties.set(entry.getKey(), entry.getValue());
}
}
boJson.set("properties", properties);
return boJson;
}
private static String unprefix(String s)
{
if (s.startsWith("http://") || s.startsWith("https://"))
return s;
int idx = s.indexOf(':');
if (idx > 0)
return s.substring(idx + 1);
else
return s;
}
public static Json unprefix(Json json)
{
if (json.isArray())
for (Json x : json.asJsonList())
unprefix(x);
else if (json.isObject())
{
for (String propname : json.dup().asJsonMap().keySet())
{
Json val = json.at(propname);
boolean isdate = false;
try { GenUtils.parseDate(val.asString()); isdate = true; } catch (Throwable t) {}
if (val.isString() && !isdate)
val = Json.make(unprefix(val.asString()));
else if (val.isObject() || val.isArray())
val = unprefix(val);
json.delAt(propname).set(unprefix(propname), val);
}
}
return json;
}
public static Json prefix(Json json)
{
Set<OWLProperty<?,?>> properties = new HashSet<OWLProperty<?,?>>();
properties.addAll(ontology().getDataPropertiesInSignature(true));
properties.addAll(ontology().getObjectPropertiesInSignature(true));
return prefix(json, properties);
}
/**
* Converts an IRI to a prefixed form, using the prefixmanager.
* @param iri
* @return e.g. "legacy:hasAnswerObject", "mdc:County"
*/
public static String prefixedIRI(IRI iri) {
String prefixIRI = prefixManager().getPrefixIRI(iri);
if (prefixIRI == null) throw new IllegalStateException("IRI not prefixable: " + iri);
return prefixIRI;
}
public static Json prefix(Json json, Set<OWLProperty<?,?>> properties)
{
// All prefixes that are equivalent to the default prefix are ignored because
// obviously they are not needed since the resulting IRI will be the same. This
// is not some sort of optimization. Those properties are referred to in Java
// code and that code is refers to property names without the prefixes so we have
// to make sure we don't put them.
String defaultPrefixValue = "";
for(Map.Entry<String,String> prefixes : prefixManager().getPrefixName2PrefixMap().entrySet())
if (prefixes.getKey().equals(":")) { defaultPrefixValue = prefixes.getValue(); break; }
if(json.isObject())
{
Iterator<Map.Entry<String, Json>> iterator = json.asJsonMap().entrySet().iterator();
Map<String,String> rename = new HashMap<String,String>();
while(iterator.hasNext())
{
Map.Entry<String, Json> entry = iterator.next();
for(Map.Entry<String,String> prefixes : prefixManager().getPrefixName2PrefixMap().entrySet())
{
if(!prefixes.getKey().equals(":") &&
!prefixes.getValue().equals(defaultPrefixValue)
&& (properties.contains(dataProperty(prefixes.getValue() + entry.getKey()))
|| properties.contains(objectProperty(prefixes.getValue() + entry.getKey()))))
{
rename.put(entry.getKey(),prefixes.getKey()+ entry.getKey());
break;
}
}
if(entry.getValue().isArray() || entry.getValue().isObject())
{
prefix(entry.getValue(), properties);
}
}
for(Map.Entry<String,String> r: rename.entrySet())
{
json.set(r.getValue(),json.atDel(r.getKey()));
}
}
else if(json.isArray())
for(Json j : json.asJsonList())
{
prefix(j, properties);
}
return json;
}
public static OWLClassExpression parseDL(String expression, OWLOntology ontology)
{
DLQueryParser parser = DLQueryParser.getParser(ontology,
(DefaultPrefixManager)prefixManager());
try
{
return parser.parseClassExpression(expression);
}
catch (Exception ex)
{
throw new RuntimeException(ex);
}
finally
{
if (isBusinessObjectOntology(ontology)) {
System.out.println("Disposing DL parser for BO " + ontology);
DLQueryParser.disposeCachedParser(ontology);
}
}
}
/**
* Return the set of sub and equivalent classes.
* @param expression
* @param ontology
* @return
*/
public static Set<OWLClass> querySubsumedClasses(String expression, OWLOntology ontology)
{
OWLReasoner reasoner = reasoner(ontology);
DLQueryParser parser = DLQueryParser.getParser(ontology,
(DefaultPrefixManager)prefixManager());
try
{
synchronized (reasoner) {
// sync to prevent onto changes to occur during parsing and getSubclasses
OWLClassExpression clexpr = parser.parseClassExpression(expression);
HashSet<OWLClass> S = new HashSet<OWLClass>();
S.addAll(reasoner.getEquivalentClasses(clexpr).getEntities());
S.addAll(reasoner.getSubClasses(clexpr, false).getFlattened());
return S;
}
}
catch (Exception ex)
{
throw new RuntimeException(ex);
}
finally
{
if (isBusinessObjectOntology(ontology)) {
System.out.println("Disposing DL parser for BO " + ontology);
DLQueryParser.disposeCachedParser(ontology);
}
}
}
public static Set<OWLNamedIndividual> queryIndividuals(String expression)
{
return queryIndividuals(expression, ontology());
}
public static Set<OWLNamedIndividual> queryIndividuals(String expression, String fragmentRegexp, OWLOntology ontology)
{
try {
Pattern.compile(fragmentRegexp);
} catch (Exception e ) { throw new RuntimeException(e); };
Set<OWLNamedIndividual> s = queryIndividuals(expression, ontology);
return filterIndividuals(fragmentRegexp, s);
}
public static Set<OWLNamedIndividual> filterIndividuals(String fragmentRegexp, Set<OWLNamedIndividual> s)
{
Set<OWLNamedIndividual> result = new HashSet<OWLNamedIndividual>((s.size() + 11) / 2);
Pattern p;
try {
p = Pattern.compile(fragmentRegexp);
} catch (Exception e ) { throw new RuntimeException(e); };
for (OWLNamedIndividual i : s)
{
if (p.matcher(i.getIRI().getFragment()).matches())
result.add(i);
}
return result;
}
public static Set<OWLNamedIndividual> queryIndividuals(String expression, OWLOntology ontology)
{
OWLReasoner reasoner = reasoner(ontology);
DLQueryParser parser = DLQueryParser.getParser(ontology,
(DefaultPrefixManager)prefixManager());
try
{
OWLClassExpression clexpr = parser.parseClassExpression(expression);
return reasoner.getInstances(clexpr, false).getFlattened();
}
catch (Exception ex)
{
throw new RuntimeException(ex);
}
finally
{
if (isBusinessObjectOntology(ontology)) {
System.out.println("Disposing DL parser for BO " + ontology);
DLQueryParser.disposeCachedParser(ontology);
}
}
}
public static <T> Set<T> set(T...args)
{
HashSet<T> S = new HashSet<T>();
for (T x : args) S.add(x);
return S;
}
public static Json toJSON(OWLObject object)
{
OWLObjectToJson o2j = new OWLObjectToJson(DEFAULT_STOP_EXPANSION_CONDITION);
return o2j.map(ontology(), object, null);
}
public static Json toJSON(OWLObject object, ShortFormProvider sp)
{
OWLObjectToJson o2j = new OWLObjectToJson(DEFAULT_STOP_EXPANSION_CONDITION);
return o2j.map(ontology(), object, sp);
}
/**
* @param object
* @param expandProtectedIndividuals if false, protected individuals will be included but not expanded. Use for Group/AccessPolicy.
* @return
*/
public static Json toJSON(OWLObject object, OWLObjectPropertyCondition stopExpansionCondition)
{
OWLObjectToJson o2j = new OWLObjectToJson(stopExpansionCondition);
return o2j.map(ontology(), object, null);
}
public static Json toJSON(OWLOntology ontology, OWLObject object, ShortFormProvider sp)
{
OWLObjectToJson o2j = new OWLObjectToJson(DEFAULT_STOP_EXPANSION_CONDITION);
return o2j.map(ontology, object, sp);
}
public static Json toJSON(OWLOntology ontology, OWLObject object)
{
OWLObjectToJson o2j = new OWLObjectToJson(DEFAULT_STOP_EXPANSION_CONDITION);
return o2j.map(ontology, object, null);
}
public static Json toJSON(OWLOntology ontology, OWLObject object, OWLObjectPropertyCondition stopExpansionCondition)
{
OWLObjectToJson o2j = new OWLObjectToJson(stopExpansionCondition);
return o2j.map(ontology, object, null);
}
public static OWLClass getPropertyType(Set<OWLOntology> ontologies, OWLObjectProperty prop)
{
for(OWLOntology ontology : ontologies) {
for (OWLObjectPropertyRangeAxiom ax : ontology.getObjectPropertyRangeAxioms(prop))
{
OWLClassExpression range = ax.getRange();
if (range instanceof OWLClass)
return (OWLClass)range;
}
}
// String is the default data type for any data property.
return OWL.dataFactory().getOWLThing();
}
public static OWLClass getPropertyType(OWLOntology ontology, OWLObjectProperty prop)
{
for (OWLObjectPropertyRangeAxiom ax : ontology.getObjectPropertyRangeAxioms(prop))
{
OWLClassExpression range = ax.getRange();
if (range instanceof OWLClass)
return (OWLClass)range;
}
// String is the default data type for any data property.
return OWL.dataFactory().getOWLThing();
}
public static OWLDatatype getPropertyType(Set<OWLOntology> ontologies, OWLDataProperty prop)
{
for(OWLOntology ontology : ontologies) {
for (OWLDataPropertyRangeAxiom ax : ontology.getDataPropertyRangeAxioms(prop))
{
OWLDataRange range = ax.getRange();
switch (range.getDataRangeType())
{
case DATATYPE:
return (OWLDatatype)range;
case DATATYPE_RESTRICTION:
return ((OWLDatatypeRestriction)range).getDatatype();
}
}
}
// String is the default data type for any data property.
return OWL.dataFactory().getOWLDatatype(OWL2Datatype.XSD_STRING.getIRI());
}
public static OWLDatatype getPropertyType(OWLOntology ontology, OWLDataProperty prop)
{
for (OWLDataPropertyRangeAxiom ax : ontology.getDataPropertyRangeAxioms(prop))
{
OWLDataRange range = ax.getRange();
switch (range.getDataRangeType())
{
case DATATYPE:
return (OWLDatatype)range;
case DATATYPE_RESTRICTION:
return ((OWLDatatypeRestriction)range).getDatatype();
}
}
// String is the default data type for any data property.
return OWL.dataFactory().getOWLDatatype(OWL2Datatype.XSD_STRING.getIRI());
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static boolean isPropertyInDomain(OWLOntology ontology, OWLProperty prop, OWLClass domain)
{
String id = domain.toStringID();
OWLReasoner reasoner = OWL.reasoner(ontology);
Set<?> S = (prop instanceof OWLDataProperty) ?
ontology.getDataPropertyDomainAxioms((OWLDataProperty)prop) :
ontology.getObjectPropertyDomainAxioms((OWLObjectProperty)prop);
for (OWLPropertyDomainAxiom ax : (Set<OWLPropertyDomainAxiom>)S)
{
if (ax.getDomain().equals(domain) ||
reasoner.getSubClasses(ax.getDomain(), false).getFlattened().contains(domain))
return true;
}
return false;
}
public static Set<OWLProperty<?,?>> getClassProperties(Set<OWLOntology> ontologies, OWLClass cl)
{
Set<OWLProperty<?,?>> result = new HashSet<OWLProperty<?,?>>();
for(OWLOntology ontology : ontologies)
{
for (OWLObjectProperty prop : ontology.getObjectPropertiesInSignature())
if (isPropertyInDomain(ontology, prop, cl))
result.add(prop);
for (OWLDataProperty prop : ontology.getDataPropertiesInSignature())
if (isPropertyInDomain(ontology, prop, cl))
result.add(prop);
}
return result;
}
public static Set<OWLProperty<?,?>> getClassProperties(OWLOntology ontology, OWLClass cl)
{
Set<OWLProperty<?,?>> result = new HashSet<OWLProperty<?,?>>();
for (OWLObjectProperty prop : ontology.getObjectPropertiesInSignature())
if (isPropertyInDomain(ontology, prop, cl))
result.add(prop);
for (OWLDataProperty prop : ontology.getDataPropertiesInSignature())
if (isPropertyInDomain(ontology, prop, cl))
result.add(prop);
return result;
}
/**
* Checks if owlobjects are HGDB, iff the datafactory is a HGDB factory.
* @param e
*/
private static void checkImplementation(OWLObject... e)
{
if (factory instanceof HGDBOntologyFactory)
{
for (OWLObject owlObject : e)
{
if (!(owlObject instanceof OWLObjectHGDB))
{
System.err.println("Ignoring that " + e + " is not a OWLObjectHGDB. Check trace to change implementation and use the BO factory: ");
new Exception().printStackTrace(System.err);
}
}
}
}
/**
* Utility method to coerce a json prop into an individual.
* OWLIndividuals are represented as a String containing its iri
* when the individual is contained more than once in the ontology in
* order to avoid infinite recursion when representing the ontology as json.
* @param j - the json containing the property to be checked.
* @param propName - the name of the property
* @return the individual represented in the value of the property.
*/
public static OWLNamedIndividual individual(Json j, String propName)
{
OWLNamedIndividual result = null;
if(j.isNull())
return result;
else if(j.has(propName) && j.at(propName).isString())
result = OWL.individual(j.at(propName).asString());
else if(j.has(propName) && j.at(propName).isObject())
result = OWL.individual(j.at(propName).at("iri").asString());
return result;
}
// hasLegacyInterface(?t, MD-PWS) -> hasDataConstraint(?t, hasDetailsMax500)
// private static SWRLRule addrule()
// {
// Set<SWRLAtom> body = new HashSet<SWRLAtom>(), head = new HashSet<SWRLAtom>();
// body.add(dataFactory().getSWRLObjectPropertyAtom(OWL.objectProperty("legacy:hasLegacyInterface"),
// dataFactory().getSWRLVariable(fullIri("legacy:t")), dataFactory().getSWRLIndividualArgument(OWL.individual("legacy:MD-PWS"))));
// head.add(dataFactory().getSWRLObjectPropertyAtom(OWL.objectProperty("hasDataConstraint"),
// dataFactory().getSWRLVariable(fullIri("legacy:t")), dataFactory().getSWRLIndividualArgument(OWL.individual("legacy:hasDetailsMax500"))));
// return dataFactory().getSWRLRule(body, head);
// }
public static void main(String [] args)
{
// if( (args.length > 0) )
// StartUp.getConfig() = Json.read(GenUtils.readTextFile(new File("c:/work/cirmservices/conf/devconfig.json")));
// System.out.println("Using config " + StartUp.getConfig().toString());
// System.out.println(OWL.queryIndividuals("hasLegacyInterface value MDC-CMS"));
OWL.init();
OWLOntology O = ontology();
Set<OWLNamedIndividual> pwtypes = queryIndividuals("legacy:hasLegacyInterface value legacy:MD-PWS", O);
for (OWLNamedIndividual ind : pwtypes)
{
System.out.println("ADd to " + ind);
manager().applyChange(new AddAxiom(O, dataFactory().getOWLObjectPropertyAssertionAxiom(objectProperty("hasDataConstraint"),
ind, individual("legacy:hasDetailsMax500"))));
}
if (pwtypes.isEmpty())
System.out.println("No types found!");
else
{
VDHGDBOntologyRepository.getInstance().getVersionControlledOntology(O).commit("boris", "Apply hasDataConstraint on hasDetails rule for all PW cases.");
OntoAdmin oadmin = new OntoAdmin();
oadmin.push(O.getOntologyID().getOntologyIRI().toString());
}
OWLSubObjectPropertyOfAxiom axiom = null;
// Set<OWLClassExpression> S = new HashSet<OWLClassExpression>();
// for (OWLClassExpression ind:expr.getOperands())
// S.add(R(ind));
}
}