io.konig.cadl.CubeReasoner 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.cadl;
/*
* #%L
* Konig Core
* %%
* Copyright (C) 2015 - 2019 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.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.openrdf.model.URI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.konig.core.impl.RdfUtil;
import io.konig.core.showl.ShowlClass;
import io.konig.core.showl.ShowlManager;
/**
* A reasoner that sets properties of the cube based on heuristics.
* The reasoner performs two functions:
*
* - Set formulas for dimensions, levels and attributes.
*
- Define the
rollUpTo
relationships between levels
*
*
* The reasoner uses the heuristic rules described below.
* In these descriptions, ?source
denotes the variable used
* for a cadl:source
of the Cube.
*
*
* -
* If the local name
source
is case-insenstive-equal to the local name of
* a unique owl:Class, then that owl:Class is set as the `cadl:valueType`
* of the source.
*
* -
* If the local name of a Dimension ends with the suffix "Dim" (e.g. "accountDim"), then let
* let dimName be the part of the name preceding the suffix (e.g. "account"). Otherwise, let
* dimName be the entire local name of the Dimension. If dimName uniquely matches the local name of
* a property of ?source, then the formula for the dimension has the form: ?source.{dimName}
*
* -
* If the local name of a Level is equal to the
dimName
value for the declaring
* Dimension, then the formula for the Level is identical to the formula for the Dimension.
*
* -
* Let levelB be some Level. If the local name of levelB uniquely matches the local name of
* a property of a preceding Level (call it levelA), then
*
* -
* The formula of the levelB is given by {formula-of-levelA}.{local-name-of-levelB}
*
* - The relationship, levelA cadl:rolesUpTo levelB is asserted.
*
*
* -
* Let attrName be the local name of an Attribute. If attrName uniquely matches the local name
* of a property of the declaring Level, then the formula for the Attribute shall be given by
* {levelFormula}.{attrName}
*
* -
* Let dim be a Dimension whose rdf:type is xsd:dateTime. Then the following rules apply.
*
* -
* If the name of a Level is case-insensitive-equal to a time unit (such as "DAY"),
* then the formula for the Level is given by: DATE_TRUNC({levelName}, {formula-of-dim})
*
* -
* The levels of dim shall be sorted by granularity and roll-up relationships established
* based on that order.
*
*
*
*
* @author Greg McFall
*
*/
public class CubeReasoner {
private static Logger logger = LoggerFactory.getLogger(CubeReasoner.class);
private ShowlManager showlManager;
private Map> classesByLocalName;
public CubeReasoner(ShowlManager classManager) {
this.showlManager = classManager;
}
public void visit(Cube cube) {
buildMap();
setSourceType(cube);
}
private void setSourceType(Cube cube) {
if (cube.getSource().getValueType() == null) {
Variable source = cube.getSource();
URI sourceId = source.getId();
if (sourceId != null) {
String key = sourceId.getLocalName().toLowerCase();
Set set = classesByLocalName.get(key);
if (set != null && set.size()==1) {
URI classId = set.iterator().next().getId();
source.setValueType(classId);
if (logger.isTraceEnabled()) {
logger.trace(
"setSourceType - Set {} as Value Type of {}",
curie(classId), sourceId);
}
}
}
}
}
private Object curie(URI id) {
return RdfUtil.optionalCurie(showlManager.getReasoner().getGraph().getNamespaceManager(), id);
}
private void buildMap() {
if (classesByLocalName == null) {
classesByLocalName = new HashMap<>();
for (ShowlClass owlClass : showlManager.listClasses()) {
URI classId = owlClass.getId();
String key = classId.getLocalName().toLowerCase();
Set set = classesByLocalName.get(key);
if (set == null) {
set = new HashSet<>();
classesByLocalName.put(key, set);
}
set.add(owlClass);
}
}
}
}