/*******************************************************************************
* 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.rdb;
import static org.sharegov.cirm.OWL.and;
import static org.sharegov.cirm.OWL.dataProperty;
import static org.sharegov.cirm.OWL.has;
import static org.sharegov.cirm.OWL.individual;
import static org.sharegov.cirm.OWL.objectProperty;
import static org.sharegov.cirm.OWL.oneOf;
import static org.sharegov.cirm.OWL.or;
import static org.sharegov.cirm.OWL.owlClass;
import static org.sharegov.cirm.OWL.reasoner;
import static org.sharegov.cirm.OWL.some;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLProperty;
import org.semanticweb.owlapi.reasoner.NodeSet;
import org.sharegov.cirm.Refs;
import org.sharegov.cirm.OWL;
import org.sharegov.cirm.utils.DirectRef;
import org.sharegov.cirm.utils.ObjectRef;
import org.sharegov.cirm.utils.SingletonRef;
/**
*
* This class is deprecated use the RelationalOWLMapper instead.
* @see RelationalOWLMapper
* @deprecated
*
*/
public class Mapping
{
private Map<OWLClass, OWLNamedIndividual> tableMapping;
private Map<OWLNamedIndividual, Map<OWLProperty<?, ?>, OWLNamedIndividual>> columnMapping;
private Map<Map<OWLObjectProperty,OWLNamedIndividual>,OWLNamedIndividual> hasOne;
private Map<OWLObjectProperty, Map<OWLClass,OWLNamedIndividual>> hasMany;
private List<OWLClass> unmapped;
public Mapping()
{
tableMapping = tableMappings();
columnMapping = columnMapping(tableMapping);
hasOne = hasOne();
hasMany = hasMany(tableMapping);
unmapped = new Vector<OWLClass>();
}
public Map<OWLObjectProperty, Map<OWLClass, OWLNamedIndividual>> getHasMany()
{
return hasMany;
}
public Map<OWLClass, OWLNamedIndividual> getTableMapping()
{
return tableMapping;
}
public Map<OWLClass, OWLNamedIndividual> getTableMapping(Set<? extends OWLClassExpression> types)
{
Map<OWLClass, OWLNamedIndividual> mapping = new LinkedHashMap<OWLClass, OWLNamedIndividual>();
outer:
for(OWLClassExpression c : types)
{
if (! (c instanceof OWLClass))
continue;
OWLClass cl = (OWLClass)c;
if(unmapped.contains(cl))
continue;
if(tableMapping.containsKey((OWLClass)c))
{
mapping.put(cl, tableMapping.get(cl));
continue;
}
for(OWLClass mapped: tableMapping.keySet())
{
if(reasoner().isEntailed(OWL.dataFactory().getOWLSubClassOfAxiom(cl,mapped)))
{
mapping.put(cl, tableMapping.get(mapped));
tableMapping.put(cl, tableMapping.get(mapped));
continue outer;
}
}
unmapped.add(cl);
}
return mapping;
}
public Map<OWLNamedIndividual, Map<OWLProperty<?, ?>, OWLNamedIndividual>> getColumnMapping()
{
return columnMapping;
}
public Map<Map<OWLObjectProperty, OWLNamedIndividual>, OWLNamedIndividual> getHasOne()
{
return hasOne;
}
public static SingletonRef<Mapping> ref =
new SingletonRef<Mapping>(new ObjectRef<Mapping>(DirectRef.make(Mapping.class)));
public static Mapping getInstance() { return ref.resolve(); }
public static OWLNamedIndividual pun(OWLClass c)
{
return individual(c.getIRI());
}
public static OWLNamedIndividual pun(OWLClassExpression c)
{
return pun(c.asOWLClass());
}
public static OWLClass pun(OWLNamedIndividual i)
{
return owlClass(i.getIRI());
}
public static Map<OWLClass, OWLNamedIndividual> tableMapping(Set<? extends OWLClassExpression> types)
{
Map<OWLClass, OWLNamedIndividual> mapping = new LinkedHashMap<OWLClass, OWLNamedIndividual>();
OWLClassExpression q = and(owlClass(Refs.OWLClass), some(objectProperty(Concepts.hasTableMapping),owlClass(Concepts.DBTable)));
NodeSet<OWLNamedIndividual> S = OWL.reasoner().getInstances(q, false);
for (OWLNamedIndividual i : S.getFlattened())
{
OWLClass mapped = owlClass(i.getIRI());
for(OWLClassExpression c : types)
{
if (! (c instanceof OWLClass))
continue;
if(c.equals(mapped) ||
reasoner().isEntailed(OWL.dataFactory().getOWLSubClassOfAxiom(c,mapped)))
{
mapping.put(c.asOWLClass(), objectProperty(i, Concepts.hasTableMapping));
}
}
}
return mapping;
}
public static Map<OWLNamedIndividual, Map<OWLProperty<?, ?>, OWLNamedIndividual>> columnMapping(
Map<OWLClass, OWLNamedIndividual> tableMapping)
{
Map<OWLNamedIndividual, Map<OWLProperty<?, ?>, OWLNamedIndividual>> mapping = new LinkedHashMap<OWLNamedIndividual, Map<OWLProperty<?, ?>, OWLNamedIndividual>>();
OWLClassExpression q = and(owlClass(Refs.OWLProperty), some(objectProperty(Concepts.hasColumnMapping), and(
or(owlClass(Concepts.DBPrimaryKey), owlClass(Concepts.DBNoKey)),
some(objectProperty(Concepts.hasTable), oneOf(tableMapping.values().toArray(new OWLIndividual[tableMapping.values().size()]))))));
//has(objectProperty(Concepts.hasTable), table))));
NodeSet<OWLNamedIndividual> S = reasoner().getInstances(q, false);
for (OWLNamedIndividual i : S.getFlattened())
{
for(OWLNamedIndividual c : reasoner().getObjectPropertyValues(i, objectProperty(Concepts.hasColumnMapping)).getFlattened())
{
OWLNamedIndividual table = reasoner().getObjectPropertyValues(c,objectProperty(Concepts.hasTable)).getFlattened().iterator().next();
Map<OWLProperty<?, ?>, OWLNamedIndividual> columns = new LinkedHashMap<OWLProperty<?, ?>, OWLNamedIndividual>();
if(mapping.containsKey(table))
{
columns = mapping.get(table);
}
if(reasoner().getTypes(i, false).getFlattened().contains(owlClass(Refs.OWLDataProperty)))
{
columns
.put(dataProperty(i.getIRI()),
reasoner().getObjectPropertyValues(i, objectProperty(Concepts.hasColumnMapping))
.getFlattened().iterator().next());
}else
{
columns
.put(objectProperty(i.getIRI()),
reasoner().getObjectPropertyValues(i, objectProperty(Concepts.hasColumnMapping))
.getFlattened().iterator().next());
}
mapping.put(table, columns);
}
}
return mapping;
}
public static Set<OWLNamedIndividual> columnIRI(OWLNamedIndividual table)
{
Set<OWLNamedIndividual> columns = new HashSet<OWLNamedIndividual>();
OWLClassExpression q =
and(
or(owlClass(Concepts.DBPrimaryKey), owlClass(Concepts.DBNoKey)),
and(owlClass(Concepts.IRIKey)),
has(objectProperty(Concepts.hasTable), table));
NodeSet<OWLNamedIndividual> S = reasoner().getInstances(q, false);
for (OWLNamedIndividual i : S.getFlattened())
columns.add(i);
return columns;
}
public static Map<Map<OWLObjectProperty,OWLNamedIndividual>, Map<OWLClass, OWLNamedIndividual>> hasOne(
Map<OWLObjectPropertyExpression, Set<OWLIndividual>> objectPropertyValues, OWLOntology o, OWLIndividual fktable, Map<OWLClass,OWLNamedIndividual> tableMapping)
{
Map<Map<OWLObjectProperty,OWLNamedIndividual>, Map<OWLClass, OWLNamedIndividual>> result = new LinkedHashMap<Map<OWLObjectProperty,OWLNamedIndividual>, Map<OWLClass, OWLNamedIndividual>>();
OWLClassExpression q =
and(
owlClass(Refs.OWLProperty),
some(objectProperty(Concepts.hasOne),owlClass(Refs.OWLClass))
);
NodeSet<OWLNamedIndividual> S = reasoner().getInstances(q, false);
for(OWLNamedIndividual i : S.getFlattened())
{
OWLObjectProperty property = objectProperty(i.getIRI());
if(objectPropertyValues.containsKey(property))
{
OWLNamedIndividual l = objectPropertyValues.get(property).iterator().next().asOWLNamedIndividual();
Set<OWLClassExpression> types = l.getTypes(o);
if (!types.isEmpty() && types.size() == 1)
{
OWLClassExpression cle = types.iterator().next();
if(cle instanceof OWLClass)
{
Map<OWLClass,OWLNamedIndividual> tbm = new HashMap<OWLClass, OWLNamedIndividual>();
tbm.put(cle.asOWLClass(), tableMapping.get(cle.asOWLClass()));
Set<OWLNamedIndividual> columns = reasoner().getObjectPropertyValues(i,
objectProperty(Concepts.hasColumnMapping)).getFlattened();
OWLClassExpression q2 = and(
owlClass("DBForeignKey"),
has( objectProperty("hasTable"), fktable),
oneOf(columns.toArray(new OWLIndividual[columns.size()]) )
);
OWLNamedIndividual column = reasoner().getInstances(q2, false).getFlattened().iterator().next();
Map<OWLObjectProperty, OWLNamedIndividual> columnMapping = new HashMap<OWLObjectProperty, OWLNamedIndividual>();
columnMapping.put(property, column);
result.put(columnMapping, tbm);
}
}
}
}
return result;
}
public static Map<Map<OWLObjectProperty,OWLNamedIndividual>,OWLNamedIndividual> hasOne()
{
Map<Map<OWLObjectProperty,OWLNamedIndividual>,OWLNamedIndividual> result = new LinkedHashMap<Map<OWLObjectProperty,OWLNamedIndividual>,OWLNamedIndividual> ();
OWLClassExpression q =
and(
owlClass(Refs.OWLProperty),
some(objectProperty(Concepts.hasOne),owlClass(Refs.OWLClass)),
some(objectProperty(Concepts.hasColumnMapping), owlClass("DBForeignKey")
)
);
NodeSet<OWLNamedIndividual> S = reasoner().getInstances(q, false);
for(OWLNamedIndividual i : S.getFlattened())
{
OWLObjectProperty property = objectProperty(i.getIRI());
Set<OWLNamedIndividual> foreignKeyColumns = reasoner().getObjectPropertyValues(i,objectProperty(Concepts.hasColumnMapping)).getFlattened();
for(OWLNamedIndividual foreignKeyColumn : foreignKeyColumns)
{
Set<OWLNamedIndividual> foreignKeyTables = reasoner().getObjectPropertyValues(foreignKeyColumn,objectProperty(Concepts.hasTable)).getFlattened();
for(OWLNamedIndividual foreignKeyTable : foreignKeyTables)
{
Map<OWLObjectProperty,OWLNamedIndividual> propertyToForeignTable = new LinkedHashMap<OWLObjectProperty, OWLNamedIndividual>();
propertyToForeignTable.put(property, foreignKeyTable);
result.put(propertyToForeignTable, foreignKeyColumn);
}
}
break;
}
return result;
}
public static Map<OWLObjectProperty,OWLNamedIndividual> hasOne(OWLIndividual fkTable, OWLIndividual key) {
Map<OWLObjectProperty,OWLNamedIndividual> result = new LinkedHashMap<OWLObjectProperty, OWLNamedIndividual>();
OWLClassExpression q = and(
owlClass(Refs.OWLObjectProperty),
some(objectProperty(Concepts.hasOne),owlClass(Refs.OWLClass)),
oneOf(key)
);
NodeSet<OWLNamedIndividual> S = reasoner().getInstances(q, false);
for(OWLNamedIndividual i : S.getFlattened()) {
OWLObjectProperty property = objectProperty(i.getIRI());
Set<OWLNamedIndividual> aaa = reasoner().getObjectPropertyValues(i, objectProperty(Concepts.hasColumnMapping)).getFlattened();
OWLClassExpression q2 = and(
owlClass("DBForeignKey"),
has( objectProperty("hasTable"), fkTable ),
oneOf( aaa.toArray(new OWLIndividual[aaa.size()]) )
);
NodeSet<OWLNamedIndividual> S2 = reasoner().getInstances(q2, false);
for(OWLNamedIndividual j : S2.getFlattened()) {
result.put(property, j);
}
}
return result;
}
public static Set<OWLObjectProperty> hasMany(OWLIndividual key) {
Set<OWLObjectProperty> result = new HashSet<OWLObjectProperty>();
OWLClassExpression q = and(
owlClass(Refs.OWLProperty),
some(objectProperty(Concepts.hasMany),owlClass(Refs.OWLClass)),
oneOf(key)
);
NodeSet<OWLNamedIndividual> S = reasoner().getInstances(q, false);
for(OWLNamedIndividual i : S.getFlattened())
{
OWLObjectProperty property = objectProperty(i.getIRI());
result.add(property);
}
return result;
}
public static Map<OWLObjectProperty, Map<OWLClass,OWLNamedIndividual>> hasMany(Map<OWLClass, OWLNamedIndividual> tableMapping)
{
Map<OWLObjectProperty, Map<OWLClass,OWLNamedIndividual>> result = new LinkedHashMap<OWLObjectProperty,Map<OWLClass,OWLNamedIndividual>>();
OWLClassExpression q =
and(
owlClass(Refs.OWLProperty)
,
some(objectProperty(Concepts.hasMany),owlClass(Refs.OWLClass))
);
NodeSet<OWLNamedIndividual> S = reasoner().getInstances(q, false);
for(OWLNamedIndividual i : S.getFlattened())
{
OWLObjectProperty property = objectProperty(i.getIRI());
Set<OWLNamedIndividual> classes = reasoner().getObjectPropertyValues(i,objectProperty(Concepts.hasMany)).getFlattened();
for (OWLNamedIndividual iclass : classes)
{
OWLClass cle = owlClass(iclass.getIRI());
Map<OWLClass,OWLNamedIndividual> tbm = new HashMap<OWLClass, OWLNamedIndividual>();
tbm.put(cle.asOWLClass(), tableMapping.get(cle.asOWLClass()));
result.put(property, tbm);
}
}
return result;
}
public static Map<OWLObjectProperty, Map<OWLClass,OWLNamedIndividual>> hasMany(Map<OWLObjectPropertyExpression, Set<OWLIndividual>> objectPropertyValues, OWLOntology o, OWLIndividual table, Map<OWLClass, OWLNamedIndividual> tableMapping)
{
Map<OWLObjectProperty, Map<OWLClass,OWLNamedIndividual>> result = new LinkedHashMap<OWLObjectProperty,Map<OWLClass,OWLNamedIndividual>>();
OWLClassExpression q =
and(
owlClass(Refs.OWLProperty)
,
some(objectProperty(Concepts.hasMany),owlClass(Refs.OWLClass))
);
NodeSet<OWLNamedIndividual> S = reasoner().getInstances(q, false);
for(OWLNamedIndividual i : S.getFlattened())
{
OWLObjectProperty property = objectProperty(i.getIRI());
if(objectPropertyValues.containsKey(property))
{
OWLNamedIndividual l = objectPropertyValues.get(property).iterator().next().asOWLNamedIndividual();
Set<OWLClassExpression> types = l.getTypes(o);
if (!types.isEmpty() && types.size() == 1)
{
OWLClassExpression cle = types.iterator().next();
if(cle instanceof OWLClass)
{
Map<OWLClass,OWLNamedIndividual> tbm = new HashMap<OWLClass, OWLNamedIndividual>();
tbm.put(cle.asOWLClass(), tableMapping.get(cle.asOWLClass()));
result.put(property, tbm);
}
}
}
}
return result;
}
public static OWLNamedIndividual join(OWLNamedIndividual tableA, OWLNamedIndividual tableB)
{
//Check if many-to-many
OWLNamedIndividual joinTable = null;
OWLClassExpression q =
and(
has(objectProperty(Concepts.isJoinedWithTable), tableA)
,
has(objectProperty(Concepts.isJoinedWithTable), tableB)
);
NodeSet<OWLNamedIndividual> S = reasoner().getInstances(q, false);
for (OWLNamedIndividual i : S.getFlattened())
{
joinTable = i;
break;
}
if(joinTable == null)
{
q =
has(objectProperty(Concepts.isJoinedWithTable), tableA);
//Check if many-to-one
S = reasoner().getInstances(q, false);
if(!S.isEmpty() && S.getFlattened().contains(tableB))
{
joinTable = tableB;
}
}
return joinTable;
}
public static OWLNamedIndividual joinColumnIRI(OWLNamedIndividual joinColumn, OWLNamedIndividual joinTable)
{
OWLNamedIndividual columnIRI = null;
OWLClassExpression q =
and(
owlClass(Concepts.DBForeignKey)
,
has(objectProperty(Concepts.hasTable), joinTable)
,
has(objectProperty(Concepts.hasJoinColumn), joinColumn)
);
NodeSet<OWLNamedIndividual> S = reasoner().getInstances(q, false);
for (OWLNamedIndividual i : S.getFlattened())
{
columnIRI = i;
break;
}
return columnIRI;
}
public static Map<OWLClass, OWLNamedIndividual> tableMappings()
{
Map<OWLClass, OWLNamedIndividual> mapping = new LinkedHashMap<OWLClass, OWLNamedIndividual>();
OWLClassExpression q = and(owlClass(Refs.OWLClass), some(objectProperty(Concepts.hasTableMapping),owlClass(Concepts.DBTable)));
NodeSet<OWLNamedIndividual> S = OWL.reasoner().getInstances(q, false);
for (OWLNamedIndividual i : S.getFlattened())
{
OWLClass mapped = owlClass(i.getIRI());
mapping.put(mapped, objectProperty(i, Concepts.hasTableMapping));
}
return mapping;
}
public static OWLNamedIndividual table(OWLClassExpression c, Map<OWLClass, OWLNamedIndividual> tableMapping)
{
if(c != null
&& c instanceof OWLClass
&& tableMapping.containsKey(c.asOWLClass()))
return tableMapping.get(c.asOWLClass());
else
return null;
}
public static OWLNamedIndividual table(Set<? extends OWLClassExpression> types, Map<OWLClass, OWLNamedIndividual> tableMapping)
{
if(types.size() == 1)
return table(types.iterator().next(), tableMapping);
else
for(OWLClassExpression type: types)
{
OWLNamedIndividual table = table(type, tableMapping);
if(table != null)
return table;
}
return null;
}
}