//package org.olap4j.driver.olap4ld.linkeddata;
//
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Map;
//
//import org.olap4j.OlapException;
//import org.olap4j.driver.olap4ld.helper.Olap4ldLinkedDataUtil;
//import org.semanticweb.yars.nx.Node;
//
///**
// * Converts from relational algebra plans to physical access plans.
// *
// * Assumes a pre-filled repository on which to compute OLAP-to-SPARQL algorithm.
// *
// * Also, assumes that query plan for each type of operator only contains one instance (since
// * attributes are simply overridden).
// *
// * @author benedikt
// */
//public class Olap2SparqlSesameVisitor implements
// LogicalOlapOperatorQueryPlanVisitor {
//
// // Input to OLAP operator
// private List<Node[]> slicedDimensions = new ArrayList<Node[]>();
// private List<Node[]> rollupslevels = new ArrayList<Node[]>();
// private List<Node[]> rollupshierarchies = new ArrayList<Node[]>();
// private List<List<Node[]>> membercombinations = new ArrayList<List<Node[]>>();
// private List<Node[]> hierarchysignature = new ArrayList<Node[]>();
// private List<Node[]> projectedMeasures = new ArrayList<Node[]>();
//
// // For the moment, we know the repo (we could wrap it also)
// private EmbeddedSesameEngine engine;
// private PhysicalOlapIterator _root;
//
// /**
// * Constructor.
// *
// * Assumes that repo is filled, already.
// *
// * @param repo
// * A repository filled with all available cubes.
// *
// */
// public Olap2SparqlSesameVisitor(EmbeddedSesameEngine engine) {
// this.engine = engine;
// }
//
// /**
// * For now, we assume exactly two children.
// */
// public void visit(DrillAcrossOp op) throws QueryException {
// throw new UnsupportedOperationException("Drill-Across is not supported by the Olap2SparqlSesameVisitor!");
// }
//
// public void visit(RollupOp o) throws QueryException {
// // For rollup,
// RollupOp so = (RollupOp) o;
//
// // Question is, are there sliced dimensions contained, already? No. Only
// // rolled-up dimensions.
// // Are there dimensions mentioned, that are not roll-up but stay on the
// // lowest level? Should be.
// this.rollupslevels = so.rollupslevels;
// this.rollupshierarchies = so.rollupshierarchies;
// }
//
// public void visit(SliceOp o) throws QueryException {
// SliceOp so = (SliceOp) o;
//
// // we do not need to do anything with SliceOp
// // We assume that slice is called only once per query plan.
// this.slicedDimensions = so.slicedDimensions;
// }
//
// public void visit(DiceOp o) throws QueryException {
// DiceOp dop = (DiceOp) o;
//
// // Question: Is that corresponding to OLAP-2-SPARQL algorithm? Yes.
// this.membercombinations = dop.membercombinations;
// // Hierarchy signature needed for max_level_height
// this.hierarchysignature = dop.hierarchysignature;
// }
//
// /**
// * ProjectionOp is defined to remove all measures apart from those
// * mentioned.
// *
// *
// */
// public void visit(ProjectionOp o) throws QueryException {
// ProjectionOp po = (ProjectionOp) o;
//
// this.projectedMeasures = po.projectedMeasures;
// }
//
// public void visit(BaseCubeOp o) throws QueryException {
// LogicalOlapOperatorQueryPlanVisitor r2a = new Olap2SparqlSesameDerivedDatasetVisitor(this.engine);
// o.accept(r2a);
// this._root = (PhysicalOlapIterator) r2a.getNewRoot();
// }
//
// @Override
// public void visit(ConvertCubeOp op) throws QueryException {
//
// LogicalOlapOperatorQueryPlanVisitor r2a = new Olap2SparqlSesameDerivedDatasetVisitor(this.engine);
// op.accept(r2a);
// this._root = (PhysicalOlapIterator) r2a.getNewRoot();
//
// }
//
// @Override
// public void visit(Object op) throws QueryException {
// // TODO Auto-generated method stub
// throw new UnsupportedOperationException(
// "visit(Object op) not implemented!");
// }
//
// /**
// * After iteration, create new root. I want to have simple SPARQL query +
// * load RDF to store.
// */
// public Object getNewRoot() {
//
// try {
// Restrictions restrictions = new Restrictions();
//
// List<Node[]> measures = _root.getMeasures(restrictions);
// List<Node[]> dimensions = _root.getDimensions(restrictions);
// //List<Node[]> hierarchies = _root.getHierarchies(restrictions);
// List<Node[]> levels = _root.getLevels(restrictions);
// //List<Node[]> members = _root.getMembers(restrictions);
//
// // Build slicesrollups
// Map<String, Integer> dimensionmap = Olap4ldLinkedDataUtil
// .getNodeResultFields(dimensions.get(0));
// Map<String, Integer> levelmap = Olap4ldLinkedDataUtil
// .getNodeResultFields(levels.get(0));
//
// // First, we have to create slicesrollups
// List<Node[]> slicesrollups = new ArrayList<Node[]>();
// slicesrollups.add(levels.get(0));
//
// List<Integer> levelheights = new ArrayList<Integer>();
// // Header
// levelheights.add(-1);
//
// /*
// * Note, since we start from the list of dimensions of the cube, the
// * result dimensions will be in the ordering of the cube (and not the
// * MDX query).
// */
//
// // Find dimensions not in sliced and not in rolluplevel.
// List<Node[]> basedimensions = new ArrayList<Node[]>();
// // Header
// basedimensions.add(dimensions.get(0));
// for (Node[] dimension : dimensions) {
//
// // If in rollupslevels, add and continue.
// boolean contained = false;
// for (int i = 1; i < rollupslevels.size(); i++) {
//
// Map<String, Integer> rollupshierarchiesmap = Olap4ldLinkedDataUtil
// .getNodeResultFields(rollupshierarchies.get(0));
//
// Node[] rolluplevel = rollupslevels.get(i);
// Node[] rollupshierarchy = rollupshierarchies.get(i);
// if (dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")]
// .toString().equals(
// rolluplevel[levelmap
// .get("?DIMENSION_UNIQUE_NAME")]
// .toString())) {
// contained = true;
// slicesrollups.add(rolluplevel);
//
// /*
// * This is how you get levelHeight: HIERARCHY_MAX_LEVEL_NUMBER - LEVEL_NUMBER.
// * OR: Hierarchy.maxdepth - Level.depth.
// */
// Integer levelHeight = (new Integer(
// rollupshierarchy[rollupshierarchiesmap
// .get("?HIERARCHY_MAX_LEVEL_NUMBER")]
// .toString()) - new Integer(
// rolluplevel[levelmap.get("?LEVEL_NUMBER")]
// .toString()));
// levelheights.add(levelHeight);
// continue;
// }
// }
// for (Node[] sliceddimension : slicedDimensions) {
// if (dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")]
// .toString().equals(
// sliceddimension[dimensionmap
// .get("?DIMENSION_UNIQUE_NAME")]
// .toString())) {
// contained = true;
// }
// }
// // As usual also check whether Measure dimension.
// if (!contained
// && !dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")]
// .toString()
// .equals(Olap4ldLinkedDataUtil.MEASURE_DIMENSION_NAME)) {
// basedimensions.add(dimension);
// }
// }
//
// // Find lowest level of basedimensions and add
// boolean first = true;
// for (Node[] basedimension : basedimensions) {
// if (first) {
// first = false;
// continue;
// }
// // Search for lowest level
// Node[] baselevel = null;
// first = true;
// for (Node[] level : levels) {
// if (first) {
// first = false;
// continue;
// }
// if (basedimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")]
// .toString().equals(
// level[levelmap.get("?DIMENSION_UNIQUE_NAME")]
// .toString())) {
// if (baselevel == null) {
// baselevel = level;
// }
// int baselevelnumber = new Integer(
// baselevel[levelmap.get("?LEVEL_NUMBER")].toString());
// int levelnumber = new Integer(
// level[levelmap.get("?LEVEL_NUMBER")].toString());
//
// if (baselevelnumber < levelnumber) {
// baselevel = level;
// }
// }
// }
// slicesrollups.add(baselevel);
// levelheights.add(0);
// }
//
// // Tests?
// // slicesrollups should contain a dimension for each apart from slices.
// // Remember measure dimension that never gets sliced or rolled-up
// int slicesrollupsshouldbesize = (dimensions.size() - 2)
// - (slicedDimensions.size() - 1);
//
// if (slicesrollups.size() - 1 != slicesrollupsshouldbesize) {
// throw new UnsupportedOperationException(
// "Slicesrollups not properly created!");
// }
//
// // Create projections
//
// List<Node[]> projections;
// if (projectedMeasures.isEmpty()) {
// projections = measures;
// } else {
// projections = projectedMeasures;
// }
//
// // Currently, we should have retrieved the data, already, therefore, we
// // only have one node.
// // We use the OLAP-2-SPARQL algorithm.
// this._root = new Olap2SparqlAlgorithmSesameIterator(this._root,
// this.engine, slicesrollups,
// levelheights, projections, membercombinations,
// hierarchysignature);
//
// } catch (OlapException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// return _root;
// }
//}