package org.olap4j.driver.olap4ld.linkeddata; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.olap4j.OlapException; import org.olap4j.driver.olap4ld.Olap4ldUtil; import org.olap4j.driver.olap4ld.helper.Olap4ldLinkedDataUtil; import org.semanticweb.yars.nx.BNode; import org.semanticweb.yars.nx.Literal; import org.semanticweb.yars.nx.Node; import org.semanticweb.yars.nx.Resource; import org.semanticweb.yars.nx.Variable; /** * Convert operator from paper * * @author benedikt * */ public class ConvertSparqlDerivedDatasetIterator implements PhysicalOlapIterator { // The different metadata parts List<Node[]> cubes; List<Node[]> measures; List<Node[]> dimensions; List<Node[]> hierarchies; List<Node[]> levels; List<Node[]> members; Map<String, Integer> cubemap = null; Map<String, Integer> dimensionmap = null; Map<String, Integer> measuremap = null; Map<String, Integer> hierarchymap = null; Map<String, Integer> levelmap = null; Map<String, Integer> membermap = null; private Iterator<Node[]> outputiterator; private PhysicalOlapIterator inputiterator1; private PhysicalOlapIterator inputiterator2; // private String conversionfunction; private ReconciliationCorrespondence conversioncorrespondence; private LinkedDataCubesEngine engine; private String triples; private String newdataset; private String dataset1; private String dataset2; private DataFuProgram dataFuProgram; private List<Node[]> results; public ConvertSparqlDerivedDatasetIterator(LinkedDataCubesEngine engine, PhysicalOlapIterator inputiterator1, PhysicalOlapIterator inputiterator2, ReconciliationCorrespondence conversioncorrespondence) { this.engine = engine; this.inputiterator1 = inputiterator1; this.inputiterator2 = inputiterator2; this.conversioncorrespondence = conversioncorrespondence; // Basics try { Restrictions restriction = new Restrictions(); cubemap = Olap4ldLinkedDataUtil.getNodeResultFields(inputiterator1 .getCubes(restriction).get(0)); // Assume cube to be index 1 dataset1 = inputiterator1.getCubes(restriction).get(1)[cubemap .get("?CUBE_NAME")].toString(); if (inputiterator2 != null) { dataset2 = inputiterator2.getCubes(restriction).get(1)[cubemap .get("?CUBE_NAME")].toString(); } } catch (OlapException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } String domainUri = "http://localhost/deriveddataset/"; // We use hash of combination conversionfunction + datasets newdataset = domainUri + "dataset" + (dataset1 + dataset2).hashCode() + "/conversionfunction" + conversioncorrespondence.getname().hashCode(); // Metadata prepareMetadata(); // Data prepareData(); } private void prepareData() { this.dataFuProgram = createDataFuProgram(); } /** * * @param conversioncorrespondence2 * @return Array with first element the body, second the head. */ private DataFuProgram createDataFuProgram() { // We assume one or two cubes, only. List<Node[]> bodypatterns = createBody(); List<Node[]> headpatterns = createHead(); DataFuProgram dataFuProgramObject = new DataFuProgram(bodypatterns, headpatterns); return dataFuProgramObject; } private List<Node[]> createBody() { /* * The bodypatterns should contain: All graph patterns for c1. All * bindas patterns. Dataset and structure graph patterns. All missing * dimensions/measures graph patterns. */ List<Node[]> bodypatterns = new ArrayList<Node[]>(); // Dataset Triples // Heuristically, the variable we get from the first pattern // subject. Node obsvariable = new Variable("inputcube1"); Node obsvariable2 = null; if (dataset2 != null) { // The second variable we get from the next variable. obsvariable2 = new Variable("inputcube2"); } bodypatterns.add(new Node[] { obsvariable, new Resource("http://purl.org/linked-data/cube#dataSet"), new Resource(dataset1) }); // DSD. Use ?dsd1 for 1, ?dsd2 for 2. // Dsd seems not to be given to new datasets. Therefore, the // construct query does not work. Instead, we add the dsd separately // (adding triples). bodypatterns.add(new Node[] { new Resource(dataset1), new Resource("http://purl.org/linked-data/cube#structure"), new Variable("dsd1") }); if (dataset2 != null) { bodypatterns.add(new Node[] { obsvariable2, new Resource("http://purl.org/linked-data/cube#dataSet"), new Resource(dataset2) }); // DSD. bodypatterns.add(new Node[] { new Resource(dataset2), new Resource("http://purl.org/linked-data/cube#structure"), new Variable("dsd2") }); } // Inputmembers Triples List<Node[]> inputmembers1 = conversioncorrespondence .getInputmembers1(); for (Node[] nodes : inputmembers1) { bodypatterns.add(new Node[] { obsvariable, nodes[0], nodes[1] }); } if (dataset2 != null) { List<Node[]> inputmembers2 = conversioncorrespondence .getInputmembers2(); for (Node[] nodes : inputmembers2) { bodypatterns .add(new Node[] { obsvariable2, nodes[0], nodes[1] }); } } // Dimension Triples: // All missing dimensions graph patterns for c1 // For each dimension add dataset graph pattern if of // specific dataset and not already contained in atoms. /* * for now, we assume that every dimension used in the second cube is * fixed since otherwise the metadata of the result cube would not be * correct */ // We assume dimensions and measures that we go through coming from // first cube (otherwise metadata may not make sense anyway, sometimes). Restrictions restrictions = new Restrictions(); List<Node[]> dimensions = null; try { dimensions = this.inputiterator1.getDimensions(restrictions); } catch (OlapException e) { // TODO Auto-generated catch block e.printStackTrace(); } Boolean first = true; for (Node[] dimension : dimensions) { if (first) { first = false; continue; } // Since we do not know how measure is encoded, compare strings. if (dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")] .toString().equals( Olap4ldLinkedDataUtil.MEASURE_DIMENSION_NAME)) { continue; } if (!isPatternContained(bodypatterns, obsvariable, dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")], null)) { bodypatterns.add(new Node[] { obsvariable, dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")], Olap4ldLinkedDataUtil .makeUriToVariable(dimension[dimensionmap .get("?DIMENSION_UNIQUE_NAME")]) }); if (dataset2 != null) { bodypatterns.add(new Node[] { obsvariable2, dimension[dimensionmap .get("?DIMENSION_UNIQUE_NAME")], Olap4ldLinkedDataUtil .makeUriToVariable(dimension[dimensionmap .get("?DIMENSION_UNIQUE_NAME")]) }); } } } // Measure Triples: List<Node[]> measures = null; try { measures = this.inputiterator1.getMeasures(restrictions); } catch (OlapException e) { // TODO Auto-generated catch block e.printStackTrace(); } // First is header for (int i = 1; i < measures.size(); i++) { Node[] measure = measures.get(i); /* * Here we deal with the problem that cubes coming in will possibly * have many "implicit" measures. For now, we assume those to be * disregarded. */ // Note we disregard all implicit measures (since while deriving // datasets, we do not create new ones for them). if (measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString() .contains("AGGFUNC")) { continue; } if (!isPatternContained(bodypatterns, obsvariable, measure[measuremap.get("?MEASURE_UNIQUE_NAME")], null)) { if (dataset2 == null) { bodypatterns.add(new Node[] { obsvariable, measure[measuremap.get("?MEASURE_UNIQUE_NAME")], new Variable("inputvalue" + i) }); } else { /* * Weakness: We assume the second cube to have the same * measures as the first cube. */ bodypatterns.add(new Node[] { obsvariable, measure[measuremap.get("?MEASURE_UNIQUE_NAME")], new Variable("input1value" + i) }); bodypatterns.add(new Node[] { obsvariable2, measure[measuremap.get("?MEASURE_UNIQUE_NAME")], new Variable("input2value" + i) }); } } } // Function Triples: // First is header for (int i = 1; i < measures.size(); i++) { Node[] measure = measures.get(i); // No extended measures. This means, currently, we are not // considering aggregations. // Note we disregard all implicit measures (since while deriving // datasets, we do not create new ones for them). if (measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString() .contains("AGGFUNC")) { continue; } // Replace variable in function String function = conversioncorrespondence.getFunction(); if (dataset2 == null) { function = function.replace("x", "?inputvalue" + i); } else { function = function.replace("x1", "?input1value" + i).replace( "x2", "?input2value" + i); } bodypatterns .add(new Node[] { new Variable("outputvalue" + i), new Resource( "http://www.aifb.kit.edu/project/ld-retriever/qrl#bindas"), new Literal(function) }); } return bodypatterns; } private List<Node[]> createHead() { List<Node[]> headpatterns = new ArrayList<Node[]>(); // Heuristically, the variable we create ourselves Node outputblanknodevariable = new BNode("_:outputcube"); // Dataset Triples: // Dataset and structure graph patterns. headpatterns.add(new Node[] { outputblanknodevariable, new Resource("http://purl.org/linked-data/cube#dataSet"), new Resource(newdataset) }); // DSD. For now, assume same dsd as other dataset. // Dsd seems not to be given to new datasets. Therefore, the // construct query does not work. Instead, we add the dsd separately // (adding triples). // Solution: Has to be propagated in select (!) headpatterns.add(new Node[] { new Resource(newdataset), new Resource("http://purl.org/linked-data/cube#structure"), new Variable("dsd1") }); // Outputmembers Triples: List<Node[]> outputmembers = conversioncorrespondence .getOutputmembers(); for (Node[] nodes : outputmembers) { headpatterns.add(new Node[] { outputblanknodevariable, nodes[0], nodes[1] }); } // Dimension Triples: Restrictions restrictions = new Restrictions(); // We assume dimensions and measures that we go through coming from // first cube (otherwise metadata may not make sense anyway, sometimes). List<Node[]> dimensions = null; try { dimensions = this.inputiterator1.getDimensions(restrictions); } catch (OlapException e) { // TODO Auto-generated catch block e.printStackTrace(); } boolean first = true; for (Node[] dimension : dimensions) { if (first) { first = false; continue; } // disregard measure dimension if (dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")] .toString().equals( Olap4ldLinkedDataUtil.MEASURE_DIMENSION_NAME)) { continue; } // This would mean, every dim in inputmembers also has to be in // outputmembers if (!isPatternContained(headpatterns, outputblanknodevariable, dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")], null)) { headpatterns.add(new Node[] { outputblanknodevariable, dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")], Olap4ldLinkedDataUtil .makeUriToVariable(dimension[dimensionmap .get("?DIMENSION_UNIQUE_NAME")]) }); } } // Measure Triples: List<Node[]> measures = null; try { measures = this.inputiterator1.getMeasures(restrictions); } catch (OlapException e) { // TODO Auto-generated catch block e.printStackTrace(); } // ** For each measure add dataset graph pattern if not already // contained in Data-Fu program and not implicit measure // First is header for (int i = 1; i < measures.size(); i++) { Node[] measure = measures.get(i); // No extended measures. This means, currently, we are not // considering aggregations. // Note we disregard all implicit measures (since while deriving // datasets, we do not create new ones for them). if (measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString() .contains("AGGFUNC")) { continue; } if (!isPatternContained(headpatterns, outputblanknodevariable, measure[measuremap.get("?MEASURE_UNIQUE_NAME")], null)) { headpatterns.add(new Node[] { outputblanknodevariable, measure[measuremap.get("?MEASURE_UNIQUE_NAME")], new Variable("outputvalue" + i) }); } } return headpatterns; } private void executeSPARQLSelectQuery() { // Select query for the output Node newobsvariable = new Variable("c1"); /* * Select: 1) Add variables for each dimension and measure. Where: 1) * Add graph pattern for specific new dataset. * * 2) Add graph patterns for each dimension and measure */ String prefixes = "PREFIX qb:<http://purl.org/linked-data/cube#> " + "PREFIX olap4ld:<http://purl.org/olap4ld/>"; String select = ""; boolean first = true; for (Node[] dimension : dimensions) { if (first) { first = false; continue; } if (dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")] .toString().equals( Olap4ldLinkedDataUtil.MEASURE_DIMENSION_NAME)) { continue; } // Create variable and add Node dimensionvariable = Olap4ldLinkedDataUtil .makeUriToVariable(dimension[dimensionmap .get("?DIMENSION_UNIQUE_NAME")]); // What to do with it? Add to a map select += " " + dimensionvariable.toN3() + " "; } // ** For each measure add dataset graph pattern if not already // contained in Data-Fu program first = true; for (Node[] measure : measures) { if (first) { first = false; continue; } // Note we disregard all implicit measures (since while deriving // datasets, we do not create new ones for them). if (measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString() .contains("AGGFUNC")) { continue; } // Create variable and add Node measurevariable = Olap4ldLinkedDataUtil .makeUriToVariable(measure[measuremap .get("?MEASURE_UNIQUE_NAME")]); // What to do with it? Add to a map select += " " + measurevariable.toN3() + " "; } // String where = "?obs1 qb:dataSet <" // + newdataset // + ">. " // + // "?obs1 <http://purl.org/linked-data/sdmx/2009/measure#obsValue> ?boneg_eur. " // + // "?obs1 <http://ontologycentral.com/2009/01/eurostat/ns#geo> ?geo. " // + // "?obs1 <http://ontologycentral.com/2009/01/eurostat/ns#unit> ?unit1. " // + // "?obs1 <http://ontologycentral.com/2009/01/eurostat/ns#indic_na> ?indic_na1. " // + "?obs1 <http://purl.org/dc/terms/date> ?time. \n"; String where = ""; // * 1) Add graph pattern for specific new dataset. where += newobsvariable.toN3() + " qb:dataSet <" + newdataset + ">. \n"; // * 2) Add graph patterns for each dimension and measure first = true; for (Node[] dimension : dimensions) { if (first) { first = false; continue; } if (dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")] .toString().equals( Olap4ldLinkedDataUtil.MEASURE_DIMENSION_NAME)) { continue; } // Create variable and add Node dimensionvariable = Olap4ldLinkedDataUtil .makeUriToVariable(dimension[dimensionmap .get("?DIMENSION_UNIQUE_NAME")]); // What to do with it? Add to a map Resource dimensionresource = new Resource( dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")] .toString()); where += newobsvariable.toN3() + " " + dimensionresource.toN3() + " " + dimensionvariable.toN3() + ". \n"; } // ** For each measure add dataset graph pattern if not already // contained in Data-Fu program first = true; for (Node[] measure : measures) { if (first) { first = false; continue; } // Note we disregard all implicit measures (since while deriving // datasets, we do not create new ones for them). if (measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString() .contains("AGGFUNC")) { continue; } // Create variable and add Node measurevariable = Olap4ldLinkedDataUtil .makeUriToVariable(measure[measuremap .get("?MEASURE_UNIQUE_NAME")]); // What to do with it? Add to a map Resource measureresource = new Resource( measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString()); where += newobsvariable.toN3() + " " + measureresource.toN3() + " " + measurevariable.toN3() + ". \n"; } String observationquery = prefixes + " select " + select + " where {" + where + " }"; Olap4ldUtil._log.config("SPARQL SELECT query: " + observationquery); this.results = this.engine.executeSparqlSelectQuery(observationquery, false); } private void executeSPARQLConstructQuery() { List<Node[]> bodypatterns = dataFuProgram.bodypatterns; List<Node[]> headpatterns = dataFuProgram.headpatterns; // Construct query to create triples String constructquery = ""; // ** PREFIXES String prefixes = "PREFIX qb:<http://purl.org/linked-data/cube#> " + "PREFIX olap4ld:<http://purl.org/olap4ld/>"; // ** where { { // ** select // ** Select: // String select = // "?geo ?unit1 ?indic_na1 ?time ((?boneg * 1000000) as ?boneg_eur) "; // ** Add select variables for every dimension and measure which is // not // mentioned as predicate in body. String select = ""; // body head String body = ""; for (Node[] bodypattern : bodypatterns) { // Only if not bindas. if (!bodypattern[1] .toN3() .equals("<http://www.aifb.kit.edu/project/ld-retriever/qrl#bindas>")) { body += bodypattern[0].toN3() + " " + bodypattern[1].toN3() + " " + bodypattern[2].toN3() + " . \n"; } } String head = ""; for (Node[] nodes : headpatterns) { head += nodes[0].toN3() + " " + nodes[1].toN3() + " " + nodes[2].toN3() + " . \n"; } // Add dsd select += " ?dsd1 ?dsd2 "; // Build hashmap from dimension or measure node and variable node. HashMap<Node, Node> selectbodymap = new HashMap<Node, Node>(); // Do I not simply need to go through bodypatterns and add all // variables? for (Node[] nodes : bodypatterns) { if (nodes[2] instanceof Variable) { selectbodymap.put(nodes[1], nodes[2]); } } // add bindas variables: Look for qrl:bindas; use subject as // variable to select; create select // http://www.aifb.kit.edu/project/ld-retriever/qrl#bindas for (Node[] bodypattern : bodypatterns) { if (bodypattern[1] .toN3() .equals("<http://www.aifb.kit.edu/project/ld-retriever/qrl#bindas>")) { // Add directly to select without quotes (toString()) select += " (" + bodypattern[2].toString() + " as " + bodypattern[0].toN3() + ") "; } } // Create full select Set<Entry<Node, Node>> selectbodyset = selectbodymap.entrySet(); for (Entry<Node, Node> entry : selectbodyset) { select += " " + entry.getValue().toN3() + " "; } constructquery = prefixes + "construct { " + head + " } where { { select " + select + " where {" + body + " } } }"; Olap4ldUtil._log.info("SPARQL CONSTRUCT query: " + constructquery); this.engine.executeSparqlConstructQuery(constructquery); } // Old // private void prepareData(List<Node[]> bodypatterns, // List<Node[]> headpatterns) { // try { // // // We assume one or two cubes, only. // // RepositoryConnection con = this.repo.getConnection(); // // // Construct query to create triples // String constructquery = ""; // // // ** PREFIXES // String prefixes = "PREFIX qb:<http://purl.org/linked-data/cube#> " // + "PREFIX olap4ld:<http://purl.org/olap4ld/>"; // // ** construct { // // ** Head: // // String headold = "_:obs qb:dataSet <" // // + newdataset // // + ">. " // // + // // // "_:obs <http://purl.org/linked-data/sdmx/2009/measure#obsValue> ?boneg_eur. " // // + // // "_:obs <http://ontologycentral.com/2009/01/eurostat/ns#geo> ?geo. " // // + // // // "_:obs <http://ontologycentral.com/2009/01/eurostat/ns#unit> <http://estatwrap.ontologycentral.com/dic/unit#EUR>. " // // + // // // "_:obs <http://ontologycentral.com/2009/01/eurostat/ns#indic_na> ?indic_na1. " // // + "_:obs <http://purl.org/dc/terms/date> ?time."; // String head = ""; // // ** Add head from Data-Fu program // for (Node[] headpattern : headpatterns) { // String headgraphpatternstring = headpattern[0].toN3() + " " // + headpattern[1].toN3() + " " + headpattern[2].toN3() // + ". \n"; // head += headgraphpatternstring; // } // // // ** For output cube, add dataset graph patterns (_:obs qb:dataSet // // <newdataset>.) // // // We assume that always only one new dataset is created // // // Heuristically, the variables for the cubes, we get from the // // pattern // // subject. The first from the first, the second by going through // // (apart from qrl:bindas) // Node obsvariable = headpatterns.get(0)[0]; // // head += obsvariable.toN3() + " qb:dataSet <" + newdataset + ">. \n"; // // // DSD. For now, assume same dsd as other dataset. // // Dsd seems not to be given to new datasets. Therefore, the // // construct query does not work. Instead, we add the dsd separately // // (adding triples). // // Solution: Has to be propagated in select (!) // head += "<" + newdataset + ">" + " qb:structure ?dsd1. \n"; // // // ** For each dimension add dataset graph pattern if not already // // contained in Data-Fu program or Measure Dimension. // // // XXX: A cleaner way would be to specifically refer to the metadata // // of the first input iterator // Restrictions restrictions = new Restrictions(); // // // We assume dimensions and measures that we go through coming from // // first cube (otherwise metadata may not make sense anyway, // // sometimes). // List<Node[]> dimensions = null; // List<Node[]> measures = null; // try { // dimensions = this.inputiterator1.getDimensions(restrictions); // measures = this.inputiterator1.getMeasures(restrictions); // } catch (OlapException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // // boolean first = true; // for (Node[] dimension : dimensions) { // if (first) { // first = false; // continue; // } // // if (dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")] // .toString().equals( // Olap4ldLinkedDataUtil.MEASURE_DIMENSION_NAME)) { // continue; // } // // /* // * Although we create the headpatterns, since it does not make // * sense to add graph patterns for dimensions to head for which // * there is not pendant in body, we go through bodypatterns. // */ // if (!isPatternContained(bodypatterns, null, // dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")], // null)) { // head += obsvariable.toN3() // + " " // + dimension[dimensionmap // .get("?DIMENSION_UNIQUE_NAME")].toN3() // + " " // + Olap4ldLinkedDataUtil.makeUriToVariable( // dimension[dimensionmap // .get("?DIMENSION_UNIQUE_NAME")] // ).toN3() + ". \n"; // // } // } // // ** For each measure add dataset graph pattern if not already // // contained in Data-Fu program and not implicit measure // first = true; // for (Node[] measure : measures) { // if (first) { // first = false; // continue; // } // // No extended measures. This means, currently, we are not // // considering aggregations. // if (measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString() // .contains("AGGFUNC")) { // continue; // } // // if (!isPatternContained(bodypatterns, null, // measure[measuremap.get("?MEASURE_UNIQUE_NAME")], null)) { // head += obsvariable.toN3() // + " " // + measure[measuremap.get("?MEASURE_UNIQUE_NAME")] // .toN3() // + " " // + Olap4ldLinkedDataUtil.makeUriToVariable( // measure[measuremap // .get("?MEASURE_UNIQUE_NAME")] // ).toN3() + ". \n"; // } // } // // ** } // // ** where { { // // ** select // // ** Select: // // String select = // // "?geo ?unit1 ?indic_na1 ?time ((?boneg * 1000000) as ?boneg_eur) "; // // ** Add select variables for every dimension and measure which is // // not // // mentioned as predicate in body. // String select = ""; // // // Add dsd // select += " ?dsd1 ?dsd2 "; // // // Build hashmap from dimension or measure node and variable node. // HashMap<Node, Node> selectbodymap = new HashMap<Node, Node>(); // // first = true; // for (Node[] dimension : dimensions) { // if (first) { // first = false; // continue; // } // if (dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")] // .toString().equals( // Olap4ldLinkedDataUtil.MEASURE_DIMENSION_NAME)) { // continue; // } // // if (!isPatternContained(bodypatterns, null, // dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")], // null)) { // // Create variable and add // Node dimensionvariable = Olap4ldLinkedDataUtil // .makeUriToVariable(dimension[dimensionmap // .get("?DIMENSION_UNIQUE_NAME")]); // // What to do with it? Add to a map // Resource dimensionresource = new Resource( // dimension[dimensionmap // .get("?DIMENSION_UNIQUE_NAME")].toString()); // selectbodymap.put(dimensionresource, dimensionvariable); // } // } // // ** For each measure add dataset graph pattern if not already // // contained in Data-Fu program // first = true; // for (Node[] measure : measures) { // if (first) { // first = false; // continue; // } // if (measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString() // .contains("AGGFUNC")) { // continue; // } // // if (!isPatternContained(bodypatterns, null, // measure[measuremap.get("?MEASURE_UNIQUE_NAME")], null)) { // // Create variable and add // Node measurevariable = Olap4ldLinkedDataUtil // .makeUriToVariable(measure[measuremap // .get("?MEASURE_UNIQUE_NAME")]); // // What to do with it? Add to a map // Resource measureresource = new Resource( // measure[measuremap.get("?MEASURE_UNIQUE_NAME")] // .toString()); // selectbodymap.put(measureresource, measurevariable); // } // } // // // ** Add all variables from objects in body which are not constants // // for (Node[] bodypattern : bodypatterns) { // // We add variable to map if no constant // if (bodypattern[2].toN3().startsWith("?")) { // selectbodymap.put(bodypattern[1], bodypattern[2]); // } // } // // // add bindas variables: Look for qrl:bindas; use subject as // // variable to select; create select // // http://www.aifb.kit.edu/project/ld-retriever/qrl#bindas // for (Node[] bodypattern : bodypatterns) { // if (bodypattern[1] // .toN3() // .equals("<http://www.aifb.kit.edu/project/ld-retriever/qrl#bindas>")) { // // Add directly to select // select += " (" + bodypattern[2].toString() + " as " // + bodypattern[0].toN3() + ") "; // } // } // // // Create full select // Set<Entry<Node, Node>> selectbodyset = selectbodymap.entrySet(); // for (Entry<Node, Node> entry : selectbodyset) { // select += " " + entry.getValue().toN3() + " "; // } // // // ** where { // // ** Body: // // String bodyold = "?obs1 qb:dataSet <" // // + dataset // // + ">. " // // + // // // "?obs1 <http://purl.org/linked-data/sdmx/2009/measure#obsValue> ?boneg. " // // + // // "?obs1 <http://ontologycentral.com/2009/01/eurostat/ns#geo> ?geo. " // // + // // "?obs1 <http://ontologycentral.com/2009/01/eurostat/ns#unit> ?unit1. " // // + // // // "?obs1 <http://ontologycentral.com/2009/01/eurostat/ns#indic_na> ?indic_na1. " // // + "?obs1 <http://purl.org/dc/terms/date> ?time. " // // + // // // "FILTER (?unit1 = <http://estatwrap.ontologycentral.com/dic/unit#MIO_EUR>)"; // String body = ""; // // // ** Add body from Data-Fu program apart from "bindas" // for (Node[] bodypattern : bodypatterns) { // // Have to check on prefixed version, also? // if (bodypattern[1] // .toN3() // .equals("<http://www.aifb.kit.edu/project/ld-retriever/qrl#bindas>")) { // continue; // } // String bodygraphpattern = bodypattern[0].toN3() + " " // + bodypattern[1].toN3() + " " + bodypattern[2].toN3() // + ". \n"; // body += bodygraphpattern; // } // // // Heuristically, the variable we get from the first pattern // // subject. // obsvariable = bodypatterns.get(0)[0]; // // // The second variable we get from the next variable. // Node obsvariable2 = null; // // if (dataset2 != null) { // // Then we should find one additional apart from those using // // specific properties. // for (Node[] bodypattern : bodypatterns) { // if (!bodypattern[1] // .toN3() // .equals("<http://www.aifb.kit.edu/project/ld-retriever/qrl#bindas>") // && !bodypattern[0].equals(bodypatterns.get(0)[0])) { // obsvariable2 = bodypattern[0]; // } // } // } // // body += obsvariable.toN3() + " qb:dataSet <" + dataset1 + ">. \n"; // // // DSD. Use ?dsd1 for 1, ?dsd2 for 2. // // Dsd seems not to be given to new datasets. Therefore, the // // construct query does not work. Instead, we add the dsd separately // // (adding triples). // body += "<" + dataset1 + ">" + " qb:structure ?dsd1. \n"; // // if (dataset2 != null) { // body += obsvariable2.toN3() + " qb:dataSet <" + dataset2 // + ">. \n"; // // // DSD. // body += "<" + dataset2 + ">" + " qb:structure ?dsd2. \n"; // } // // // ** For each dimension add dataset graph pattern if of // // specific dataset and not already contained in Data-Fu program // /* // * for now, we assume that every dimension used in the second cube // * is fixed since otherwise the metadata of the result cube would // * not be correct // */ // first = true; // for (Node[] dimension : dimensions) { // if (first) { // first = false; // continue; // } // if (dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")] // .toString().equals( // Olap4ldLinkedDataUtil.MEASURE_DIMENSION_NAME)) { // continue; // } // // if (!isPatternContained(bodypatterns, null, // dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")], // null)) { // body += obsvariable.toN3() // + " " // + dimension[dimensionmap // .get("?DIMENSION_UNIQUE_NAME")].toN3() // + " " // + Olap4ldLinkedDataUtil.makeUriToVariable( // dimension[dimensionmap // .get("?DIMENSION_UNIQUE_NAME")] // ).toN3() + ". \n"; // if (dataset2 != null) { // body += obsvariable2.toN3() // + " " // + dimension[dimensionmap // .get("?DIMENSION_UNIQUE_NAME")].toN3() // + " " // + Olap4ldLinkedDataUtil.makeUriToVariable( // dimension[dimensionmap // .get("?DIMENSION_UNIQUE_NAME")] // ).toN3() + ". \n"; // } // } // } // // ** For each measure add dataset graph pattern if not already // // contained in Data-Fu program // first = true; // for (Node[] measure : measures) { // if (first) { // first = false; // continue; // } // if (measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString() // .contains("AGGFUNC")) { // continue; // } // // if (!isPatternContained(bodypatterns, null, // measure[measuremap.get("?MEASURE_UNIQUE_NAME")], null)) { // body += obsvariable.toN3() // + " " // + measure[measuremap.get("?MEASURE_UNIQUE_NAME")] // .toN3() // + " " // + Olap4ldLinkedDataUtil.makeUriToVariable( // measure[measuremap // .get("?MEASURE_UNIQUE_NAME")] // ).toN3() + ". \n"; // if (dataset2 != null) { // body += obsvariable2.toN3() // + " " // + measure[measuremap // .get("?MEASURE_UNIQUE_NAME")].toN3() // + " " // + Olap4ldLinkedDataUtil.makeUriToVariable( // measure[measuremap // .get("?MEASURE_UNIQUE_NAME")] // ).toN3() + ". \n"; // } // } // } // // ** } } } // // constructquery = prefixes + "construct { " + head // + " } where { { select " + select + " where {" + body // + " } } }"; // // Olap4ldUtil._log.config("SPARQL query: " + constructquery); // // GraphQuery graphquery = con.prepareGraphQuery( // org.openrdf.query.QueryLanguage.SPARQL, constructquery); // // StringWriter stringout = new StringWriter(); // RDFWriter w = Rio.createWriter(RDFFormat.RDFXML, stringout); // graphquery.evaluate(w); // // this.triples = stringout.toString(); // // if (Olap4ldUtil._isDebug) { // // Olap4ldUtil._log.config("Loaded triples: " + triples); // // } // // Insert query to load triples // // String insertquery = // // // "PREFIX olap4ld:<http://purl.org/olap4ld/> INSERT DATA { GRAPH <http://manually> { " // // + triples + " } }"; // // // // Olap4ldUtil._log.config("SPARQL query: " + insertquery); // // // // Update updateQuery = con.prepareUpdate(QueryLanguage.SPARQL, // // insertquery); // // updateQuery.execute(); // // // Would not work: prolog error // // ByteArrayInputStream inputstream = new // // ByteArrayInputStream(w.toString().getBytes()); // // // UTF-8 encoding seems important // InputStream stream = new ByteArrayInputStream( // triples.getBytes("UTF-8")); // // // Add to triple store // con.add(stream, "", RDFFormat.RDFXML); // // // Loaded really? // if (Olap4ldUtil._isDebug) { // String filename = "dataset" + (dataset1 + dataset2).hashCode() // + "-conversionfunction" + this.conversioncorrespondence; // // Olap4ldLinkedDataUtil // .dumpRDF( // repo, // "/media/84F01919F0191352/Projects/2014/paper/paper-macro-modelling/experiments/" // + filename + ".n3", RDFFormat.NTRIPLES); // } // // con.close(); // // } catch (RepositoryException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (MalformedURLException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (MalformedQueryException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (QueryEvaluationException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (RDFHandlerException e1) { // // TODO Auto-generated catch block // e1.printStackTrace(); // } catch (RDFParseException e1) { // // TODO Auto-generated catch block // e1.printStackTrace(); // } // } private void prepareMetadata() { try { Restrictions restriction = new Restrictions(); // Cubes will be new cube this.cubes = new ArrayList<Node[]>(); boolean first = true; for (Node[] cube : inputiterator1.getCubes(restriction)) { if (first) { first = false; this.cubes.add(cube); continue; } // ?CATALOG_NAME ?SCHEMA_NAME ?CUBE_NAME ?CUBE_TYPE // ?CUBE_CAPTION ?DESCRIPTION Node[] newCube = new Node[6]; newCube[cubemap.get("?CATALOG_NAME")] = cube[cubemap .get("?CATALOG_NAME")]; newCube[cubemap.get("?SCHEMA_NAME")] = cube[cubemap .get("?SCHEMA_NAME")]; newCube[cubemap.get("?CUBE_NAME")] = new Resource(newdataset); newCube[cubemap.get("?CUBE_TYPE")] = cube[cubemap .get("?CUBE_TYPE")]; newCube[cubemap.get("?CUBE_CAPTION")] = cube[cubemap .get("?CUBE_CAPTION")]; newCube[cubemap.get("?DESCRIPTION")] = cube[cubemap .get("?DESCRIPTION")]; this.cubes.add(newCube); } // Measures will be all measures of first cube this.measures = new ArrayList<Node[]>(); measuremap = Olap4ldLinkedDataUtil .getNodeResultFields(inputiterator1 .getMeasures(restriction).get(0)); first = true; for (Node[] node : inputiterator1.getMeasures(restriction)) { if (first) { first = false; this.measures.add(node); continue; } // Only those which are not implicit. // XXX: This distinguishing of implicit, explicit and real measure is confusing. if (node[measuremap.get("?MEASURE_UNIQUE_NAME")].toString() .contains("AGGFUNC")) { continue; } // Schema: (From XMLA/Linked Data Engine) // Measures: ?CATALOG_NAME ?SCHEMA_NAME ?CUBE_NAME // ?MEASURE_UNIQUE_NAME ?MEASURE_NAME ?MEASURE_CAPTION // ?DATA_TYPE ?MEASURE_IS_VISIBLE ?MEASURE_AGGREGATOR // ?EXPRESSION Node[] newnode = new Node[10]; newnode[measuremap.get("?CATALOG_NAME")] = node[measuremap .get("?CATALOG_NAME")]; newnode[measuremap.get("?SCHEMA_NAME")] = node[measuremap .get("?SCHEMA_NAME")]; newnode[measuremap.get("?CUBE_NAME")] = new Resource(newdataset); newnode[measuremap.get("?MEASURE_UNIQUE_NAME")] = node[measuremap .get("?MEASURE_UNIQUE_NAME")]; newnode[measuremap.get("?MEASURE_NAME")] = node[measuremap .get("?MEASURE_NAME")]; newnode[measuremap.get("?MEASURE_CAPTION")] = node[measuremap .get("?MEASURE_CAPTION")]; newnode[measuremap.get("?DATA_TYPE")] = node[measuremap .get("?DATA_TYPE")]; newnode[measuremap.get("?MEASURE_IS_VISIBLE")] = node[measuremap .get("?MEASURE_IS_VISIBLE")]; newnode[measuremap.get("?MEASURE_AGGREGATOR")] = node[measuremap .get("?MEASURE_AGGREGATOR")]; newnode[measuremap.get("?EXPRESSION")] = node[measuremap .get("?EXPRESSION")]; this.measures.add(newnode); } // Dimensions will be all dimensions from first cube this.dimensions = new ArrayList<Node[]>(); dimensionmap = Olap4ldLinkedDataUtil .getNodeResultFields(inputiterator1.getDimensions( restriction).get(0)); first = true; for (Node[] node : inputiterator1.getDimensions(restriction)) { if (first) { first = false; this.dimensions.add(node); continue; } // Schema: (From XMLA/Linked Data Engine) // Dimensions: ?CATALOG_NAME ?SCHEMA_NAME ?CUBE_NAME // ?DIMENSION_NAME ?DIMENSION_UNIQUE_NAME ?DIMENSION_CAPTION // ?DIMENSION_ORDINAL ?DIMENSION_TYPE ?DESCRIPTION Node[] newnode = new Node[9]; newnode[dimensionmap.get("?CATALOG_NAME")] = node[dimensionmap .get("?CATALOG_NAME")]; newnode[dimensionmap.get("?SCHEMA_NAME")] = node[dimensionmap .get("?SCHEMA_NAME")]; newnode[dimensionmap.get("?CUBE_NAME")] = new Resource( newdataset); newnode[dimensionmap.get("?DIMENSION_NAME")] = node[dimensionmap .get("?DIMENSION_NAME")]; newnode[dimensionmap.get("?DIMENSION_UNIQUE_NAME")] = node[dimensionmap .get("?DIMENSION_UNIQUE_NAME")]; newnode[dimensionmap.get("?DIMENSION_CAPTION")] = node[dimensionmap .get("?DIMENSION_CAPTION")]; newnode[dimensionmap.get("?DIMENSION_ORDINAL")] = node[dimensionmap .get("?DIMENSION_ORDINAL")]; newnode[dimensionmap.get("?DIMENSION_TYPE")] = node[dimensionmap .get("?DIMENSION_TYPE")]; newnode[dimensionmap.get("?DESCRIPTION")] = node[dimensionmap .get("?DESCRIPTION")]; this.dimensions.add(newnode); } // Hierarchies will be all hierarchies from first cube this.hierarchies = new ArrayList<Node[]>(); hierarchymap = Olap4ldLinkedDataUtil .getNodeResultFields(inputiterator1.getHierarchies( restriction).get(0)); first = true; for (Node[] node : inputiterator1.getHierarchies(restriction)) { if (first) { first = false; this.hierarchies.add(node); continue; } Node[] newnode = new Node[9]; // Schema: (From XMLA/Linked Data Engine) // Hierarchies: ?CATALOG_NAME ?SCHEMA_NAME ?CUBE_NAME // ?DIMENSION_UNIQUE_NAME ?HIERARCHY_UNIQUE_NAME ?HIERARCHY_NAME // ?HIERARCHY_CAPTION ?DESCRIPTION ?HIERARCHY_MAX_LEVEL_NUMBER newnode[hierarchymap.get("?CATALOG_NAME")] = node[hierarchymap .get("?CATALOG_NAME")]; newnode[hierarchymap.get("?SCHEMA_NAME")] = node[hierarchymap .get("?SCHEMA_NAME")]; newnode[hierarchymap.get("?CUBE_NAME")] = new Resource( newdataset); newnode[hierarchymap.get("?DIMENSION_UNIQUE_NAME")] = node[hierarchymap .get("?DIMENSION_UNIQUE_NAME")]; newnode[hierarchymap.get("?HIERARCHY_UNIQUE_NAME")] = node[hierarchymap .get("?HIERARCHY_UNIQUE_NAME")]; newnode[hierarchymap.get("?HIERARCHY_NAME")] = node[hierarchymap .get("?HIERARCHY_NAME")]; newnode[hierarchymap.get("?HIERARCHY_CAPTION")] = node[hierarchymap .get("?HIERARCHY_CAPTION")]; newnode[hierarchymap.get("?DESCRIPTION")] = node[hierarchymap .get("?DESCRIPTION")]; newnode[hierarchymap.get("?HIERARCHY_MAX_LEVEL_NUMBER")] = node[hierarchymap .get("?HIERARCHY_MAX_LEVEL_NUMBER")]; this.hierarchies.add(newnode); } // Levels will be all levels from first cube this.levels = new ArrayList<Node[]>(); levelmap = Olap4ldLinkedDataUtil.getNodeResultFields(inputiterator1 .getLevels(restriction).get(0)); first = true; for (Node[] node : inputiterator1.getLevels(restriction)) { if (first) { first = false; this.levels.add(node); continue; } // Schema: (From XMLA/Linked Data Engine) // Levels: ?CATALOG_NAME ?SCHEMA_NAME ?CUBE_NAME // ?DIMENSION_UNIQUE_NAME ?HIERARCHY_UNIQUE_NAME // ?LEVEL_UNIQUE_NAME ?LEVEL_CAPTION ?LEVEL_NAME ?DESCRIPTION // ?LEVEL_NUMBER ?LEVEL_CARDINALITY ?LEVEL_TYPE Node[] newnode = new Node[12]; newnode[levelmap.get("?CATALOG_NAME")] = node[levelmap .get("?CATALOG_NAME")]; newnode[levelmap.get("?SCHEMA_NAME")] = node[levelmap .get("?SCHEMA_NAME")]; newnode[levelmap.get("?CUBE_NAME")] = new Resource(newdataset); newnode[levelmap.get("?DIMENSION_UNIQUE_NAME")] = node[levelmap .get("?DIMENSION_UNIQUE_NAME")]; newnode[levelmap.get("?HIERARCHY_UNIQUE_NAME")] = node[levelmap .get("?HIERARCHY_UNIQUE_NAME")]; newnode[levelmap.get("?LEVEL_UNIQUE_NAME")] = node[levelmap .get("?LEVEL_UNIQUE_NAME")]; newnode[levelmap.get("?LEVEL_CAPTION")] = node[levelmap .get("?LEVEL_CAPTION")]; newnode[levelmap.get("?LEVEL_NAME")] = node[levelmap .get("?LEVEL_NAME")]; newnode[levelmap.get("?DESCRIPTION")] = node[levelmap .get("?DESCRIPTION")]; newnode[levelmap.get("?LEVEL_NUMBER")] = node[levelmap .get("?LEVEL_NUMBER")]; newnode[levelmap.get("?LEVEL_CARDINALITY")] = node[levelmap .get("?LEVEL_CARDINALITY")]; newnode[levelmap.get("?LEVEL_TYPE")] = node[levelmap .get("?LEVEL_TYPE")]; this.levels.add(newnode); } // Members will be all members of first cube this.members = new ArrayList<Node[]>(); membermap = Olap4ldLinkedDataUtil .getNodeResultFields(inputiterator1.getMembers(restriction) .get(0)); first = true; for (Node[] node : inputiterator1.getMembers(restriction)) { if (first) { first = false; this.members.add(node); continue; } // Schema: (From XMLA/Linked Data Engine) // Members: ?CATALOG_NAME ?SCHEMA_NAME ?CUBE_NAME // ?DIMENSION_UNIQUE_NAME ?HIERARCHY_UNIQUE_NAME // ?LEVEL_UNIQUE_NAME ?LEVEL_NUMBER ?MEMBER_UNIQUE_NAME // ?MEMBER_NAME ?MEMBER_CAPTION ?MEMBER_TYPE ?PARENT_UNIQUE_NAME // ?PARENT_LEVEL Node[] newnode = new Node[13]; newnode[membermap.get("?CATALOG_NAME")] = node[membermap .get("?CATALOG_NAME")]; newnode[membermap.get("?SCHEMA_NAME")] = node[membermap .get("?SCHEMA_NAME")]; newnode[membermap.get("?CUBE_NAME")] = new Resource(newdataset); newnode[membermap.get("?DIMENSION_UNIQUE_NAME")] = node[membermap .get("?DIMENSION_UNIQUE_NAME")]; newnode[membermap.get("?HIERARCHY_UNIQUE_NAME")] = node[membermap .get("?HIERARCHY_UNIQUE_NAME")]; newnode[membermap.get("?LEVEL_UNIQUE_NAME")] = node[membermap .get("?LEVEL_UNIQUE_NAME")]; newnode[membermap.get("?LEVEL_NUMBER")] = node[membermap .get("?LEVEL_NUMBER")]; newnode[membermap.get("?MEMBER_UNIQUE_NAME")] = node[membermap .get("?MEMBER_UNIQUE_NAME")]; newnode[membermap.get("?MEMBER_NAME")] = node[membermap .get("?MEMBER_NAME")]; newnode[membermap.get("?MEMBER_CAPTION")] = node[membermap .get("?MEMBER_CAPTION")]; newnode[membermap.get("?MEMBER_TYPE")] = node[membermap .get("?MEMBER_TYPE")]; newnode[membermap.get("?PARENT_UNIQUE_NAME")] = node[membermap .get("?PARENT_UNIQUE_NAME")]; newnode[membermap.get("?PARENT_LEVEL")] = node[membermap .get("?PARENT_LEVEL")]; this.members.add(newnode); } } catch (OlapException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } } @Deprecated private void executeSelectQueryForOutput(List<Node[]> bodypatterns, List<Node[]> headpatterns) { List<Node[]> myBindings = new ArrayList<Node[]>(); // Select query for the output Node newobsvariable = bodypatterns.get(0)[0]; /* * Select: 1) Add variables for each dimension and measure. Where: 1) * Add graph pattern for specific new dataset. 2) Add graph patterns for * each dimension and measure */ String prefixes = "PREFIX qb:<http://purl.org/linked-data/cube#> " + "PREFIX olap4ld:<http://purl.org/olap4ld/>"; String select = ""; boolean first = true; for (Node[] dimension : dimensions) { if (first) { first = false; continue; } if (dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")] .toString().equals( Olap4ldLinkedDataUtil.MEASURE_DIMENSION_NAME)) { continue; } // Create variable and add Node dimensionvariable = Olap4ldLinkedDataUtil .makeUriToVariable(dimension[dimensionmap .get("?DIMENSION_UNIQUE_NAME")]); // What to do with it? Add to a map select += " " + dimensionvariable.toN3() + " "; } // ** For each measure add dataset graph pattern if not already // contained in Data-Fu program first = true; for (Node[] measure : measures) { if (first) { first = false; continue; } // Note we disregard all implicit measures (since while deriving // datasets, we do not create new ones for them). if (measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString() .contains("AGGFUNC")) { continue; } // Create variable and add Node measurevariable = Olap4ldLinkedDataUtil .makeUriToVariable(measure[measuremap .get("?MEASURE_UNIQUE_NAME")]); // What to do with it? Add to a map select += " " + measurevariable.toN3() + " "; } // String where = "?obs1 qb:dataSet <" // + newdataset // + ">. " // + // "?obs1 <http://purl.org/linked-data/sdmx/2009/measure#obsValue> ?boneg_eur. " // + // "?obs1 <http://ontologycentral.com/2009/01/eurostat/ns#geo> ?geo. " // + // "?obs1 <http://ontologycentral.com/2009/01/eurostat/ns#unit> ?unit1. " // + // "?obs1 <http://ontologycentral.com/2009/01/eurostat/ns#indic_na> ?indic_na1. " // + "?obs1 <http://purl.org/dc/terms/date> ?time. \n"; String where = ""; // * 1) Add graph pattern for specific new dataset. where += newobsvariable.toN3() + " qb:dataSet <" + newdataset + ">. \n"; // * 2) Add graph patterns for each dimension and measure first = true; for (Node[] dimension : dimensions) { if (first) { first = false; continue; } if (dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")] .toString().equals( Olap4ldLinkedDataUtil.MEASURE_DIMENSION_NAME)) { continue; } // Create variable and add Node dimensionvariable = Olap4ldLinkedDataUtil .makeUriToVariable(dimension[dimensionmap .get("?DIMENSION_UNIQUE_NAME")]); // What to do with it? Add to a map Resource dimensionresource = new Resource( dimension[dimensionmap.get("?DIMENSION_UNIQUE_NAME")] .toString()); where += newobsvariable.toN3() + " " + dimensionresource.toN3() + " " + dimensionvariable.toN3() + ". \n"; } // ** For each measure add dataset graph pattern if not already // contained in Data-Fu program first = true; for (Node[] measure : measures) { if (first) { first = false; continue; } // Note we disregard all implicit measures (since while deriving // datasets, we do not create new ones for them). if (measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString() .contains("AGGFUNC")) { continue; } // Create variable and add Node measurevariable = Olap4ldLinkedDataUtil .makeUriToVariable(measure[measuremap .get("?MEASURE_UNIQUE_NAME")]); // What to do with it? Add to a map Resource measureresource = new Resource( measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString()); where += newobsvariable.toN3() + " " + measureresource.toN3() + " " + measurevariable.toN3() + ". \n"; } String observationquery = prefixes + " select " + select + " where {" + where + " }"; Olap4ldUtil._log.config("SPARQL query: " + observationquery); // ByteArrayOutputStream boas = new ByteArrayOutputStream(); // FileOutputStream fos = new // FileOutputStream("/home/benedikt/Workspaces/Git-Repositories/olap4ld/OLAP4LD-trunk/resources/result.srx"); this.outputiterator = this.engine.executeSparqlSelectQuery(observationquery, false) .iterator(); } /** * This basically is an ASK implementation for specific triple patterns. * * @param bodypatterns * @param object * @param string * @param object2 * @return */ private boolean isPatternContained(List<Node[]> patterns, Node subject, Node predicate, Node object) { for (Node[] bodypattern : patterns) { boolean subjectcontained = true; if (subject != null && !subject.equals(bodypattern[0])) { subjectcontained = false; } boolean predicatecontained = true; if (predicate != null && !predicate.equals(bodypattern[1])) { predicatecontained = false; } boolean objectcontained = true; if (object != null && !object.equals(bodypattern[2])) { objectcontained = false; } if (subjectcontained && predicatecontained && objectcontained) { return true; } } return false; } public String dumpRDF() { return this.triples; } /** * Always true. */ public boolean hasNext() { if (this.results == null) { try { init(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } return outputiterator.hasNext(); } public Object next() { if (this.results == null) { try { init(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } return outputiterator.next(); } @Override public void remove() { // TODO Auto-generated method stub } @Override public void init() throws Exception { // From bodypatterns and headpatterns of data-fu program, create SPARQL // query. // Should not be run every time again. if (this.results == null) { // Need to make sure that I also init the input operators. inputiterator1.init(); if (inputiterator2 != null) { inputiterator2.init(); } // This is specific to EmbeddedSesameEngine. EmbeddedSesameEngine engine_embeddedsesame = (EmbeddedSesameEngine) this.engine; // Check if already existing. If so, do not create again if (!engine_embeddedsesame.isLoaded(new URL(newdataset))) { Olap4ldUtil._log .info("Execute logical query plan: Create and load derived dataset."); long time = System.currentTimeMillis(); executeSPARQLConstructQuery(); // After loading, we need to do all the rest. engine_embeddedsesame.runNormalizationAlgorithm(); //this.engine.runOWLReasoningAlgorithm(); engine_embeddedsesame.setLoaded(new URL(newdataset)); time = System.currentTimeMillis() - time; Olap4ldUtil._log .info("Execute logical query plan: Create and load derived dataset finished in " + time + "ms."); } executeSPARQLSelectQuery(); } this.outputiterator = this.results.iterator(); } @Override public void close() throws Exception { // TODO Auto-generated method stub } public String toString() { if (inputiterator2 == null) { return "Convert-Cube (" + inputiterator1.toString() + ", " + dataFuProgram.toString() + ")"; } else { return "Merge-Cubes (" + inputiterator1.toString() + ", " + inputiterator2.toString() + ", " + dataFuProgram.toString() + ")"; } } @Override public void accept(LogicalOlapOperatorQueryPlanVisitor v) throws QueryException { // TODO Auto-generated method stub } @Override public List<Node[]> getCubes(Restrictions restrictions) throws OlapException { return cubes; } @Override public List<Node[]> getDimensions(Restrictions restrictions) throws OlapException { return dimensions; } @Override public List<Node[]> getMeasures(Restrictions restrictions) throws OlapException { // XXX: Actually, we already distinguished measures when creating the metadata. // So, no change. // Convert-Cube would only take the non-aggregated measures List<Node[]> newmeasures = new ArrayList<Node[]>(); newmeasures.add(measures.get(0)); for (int i = 1; i < measures.size(); i++) { Node[] measure = measures.get(i); /* * Here we deal with the problem that cubes coming in will possibly * have many "implicit" measures. For now, we assume those to be * disregarded. */ if (measure[measuremap.get("?MEASURE_UNIQUE_NAME")].toString() .contains("AGGFUNC")) { continue; } newmeasures.add(measure); } return newmeasures; } @Override public List<Node[]> getHierarchies(Restrictions restrictions) throws OlapException { return hierarchies; } @Override public List<Node[]> getLevels(Restrictions restrictions) throws OlapException { return levels; } @Override public List<Node[]> getMembers(Restrictions restrictions) throws OlapException { return members; } /** * Represents data fu program with bodypatterns and headpatterns. * * @author benedikt * */ class DataFuProgram { public List<Node[]> bodypatterns; public List<Node[]> headpatterns; public DataFuProgram(List<Node[]> bodypatterns, List<Node[]> headpatterns) { this.bodypatterns = bodypatterns; this.headpatterns = headpatterns; } public String toString() { // Return Data-Fu query String dataFuProgram = "Convert-Cube: { \n"; for (Node[] nodes : bodypatterns) { dataFuProgram += nodes[0].toN3() + " " + nodes[1].toN3() + " " + nodes[2].toN3() + " . \n"; } dataFuProgram += " } => { \n"; for (Node[] nodes : headpatterns) { dataFuProgram += nodes[0].toN3() + " " + nodes[1].toN3() + " " + nodes[2].toN3() + " . \n"; } dataFuProgram += "} "; Olap4ldUtil._log.config("Linked-Data-Fu-Program: " + dataFuProgram); return dataFuProgram; } } }