//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; // } //}