/*
//$Id: MetadataTest.java 482 2012-01-05 23:27:27Z jhyde $
//
//Licensed to Julian Hyde under one or more contributor license
//agreements. See the NOTICE file distributed with this work for
//additional information regarding copyright ownership.
//
//Julian Hyde licenses this file to you 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.olap4j;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import junit.framework.TestCase;
import org.olap4j.CellSetFormatterTest.Format;
import org.olap4j.driver.olap4ld.Olap4ldUtil;
import org.olap4j.driver.olap4ld.helper.Olap4ldLinkedDataUtil;
import org.olap4j.driver.olap4ld.linkeddata.BaseCubeOp;
import org.olap4j.driver.olap4ld.linkeddata.ConvertCubeOp;
import org.olap4j.driver.olap4ld.linkeddata.DrillAcrossOp;
import org.olap4j.driver.olap4ld.linkeddata.EmbeddedSesameEngine;
import org.olap4j.driver.olap4ld.linkeddata.LinkedDataCubesEngine;
import org.olap4j.driver.olap4ld.linkeddata.LogicalOlapOp;
import org.olap4j.driver.olap4ld.linkeddata.LogicalOlapQueryPlan;
import org.olap4j.driver.olap4ld.linkeddata.PhysicalOlapQueryPlan;
import org.olap4j.driver.olap4ld.linkeddata.ProjectionOp;
import org.olap4j.driver.olap4ld.linkeddata.ReconciliationCorrespondence;
import org.olap4j.driver.olap4ld.linkeddata.Restrictions;
import org.olap4j.driver.olap4ld.linkeddata.SliceOp;
import org.olap4j.layout.RectangularCellSetFormatter;
import org.olap4j.layout.TraditionalCellSetFormatter;
import org.semanticweb.yars.nx.Node;
import org.semanticweb.yars.nx.Resource;
/**
* Tests on executing drill-across.
*
*
* @version $Id: MetadataTest.java 482 2012-01-05 23:27:27Z jhyde $
*/
public class Convert_Cube_QueryTest extends TestCase {
private LinkedDataCubesEngine lde;
public Convert_Cube_QueryTest() throws SQLException {
Olap4ldUtil.prepareLogging();
// Logging
// For debugging purposes
Olap4ldUtil._log.setLevel(Level.CONFIG);
// For monitoring usage
// Olap4ldUtil._log.setLevel(Level.INFO);
// For warnings (and errors) only
// Olap4ldUtil._log.setLevel(Level.WARNING);
Olap4ldUtil._isDebug = false;
try {
// Must have settings without influence on query processing
URL serverUrlObject = new URL("http://example.de");
List<String> datastructuredefinitions = new ArrayList<String>();
List<String> datasets = new ArrayList<String>();
lde = new EmbeddedSesameEngine(serverUrlObject,
datastructuredefinitions, datasets, "EMBEDDEDSESAME");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void setUp() throws SQLException {
}
protected void tearDown() throws Exception {
}
public void executeGDP_Mioeur2eur() throws OlapException {
// First: GDP and main components
Node gdpdsuri = new Resource(
"http://estatwrap.ontologycentral.com/id/nama_gdp_c#ds");
Restrictions gdprestrictions = new Restrictions();
gdprestrictions.cubeNamePattern = gdpdsuri;
// Base-cube
// XXX: We need to make sure that only the lowest members are queried
// from each cube.
// In order to fill the engine with data
List<Node[]> gdpcube = lde.getCubes(gdprestrictions);
assertEquals(2, gdpcube.size());
Map<String, Integer> gdpcubemap = Olap4ldLinkedDataUtil
.getNodeResultFields(gdpcube.get(0));
System.out.println("CUBE_NAME: "
+ gdpcube.get(1)[gdpcubemap.get("?CUBE_NAME")]);
List<Node[]> gdpcubemeasures = lde.getMeasures(gdprestrictions);
List<Node[]> gdpcubedimensions = lde.getDimensions(gdprestrictions);
assertEquals(true, gdpcubedimensions.size() > 1);
List<Node[]> gdpcubehierarchies = lde.getHierarchies(gdprestrictions);
List<Node[]> gdpcubelevels = lde.getLevels(gdprestrictions);
List<Node[]> gdpcubemembers = lde.getMembers(gdprestrictions);
BaseCubeOp gdpbasecube = new BaseCubeOp(gdpdsuri.toString());
// Projection
// Since we do not remove any measure from the cubes, we do not need
// projection.
// XXX: We will see how the query processor handles it if no projection
// is called.
// Dice
// For now, we do not do any dice since we slice over most dimensions
// XXX: However, the results may be wrong, if we do not ensure the
// constraint
// that base cube only queries for those members that are on the lowest
// level.
// Slice
// XXX: Since in MDX, we probably cannot distinguish between dimensions
// for specific cubes
// {indic_na, sex, age, esa95}
// Roll-up
// XXX: We do not need roll-up
List<Node[]> mio_eur2eur_inputmembers = new ArrayList<Node[]>();
mio_eur2eur_inputmembers
.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#unit"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/unit#MIO_EUR") });
// mio_eur2eur_inputmembers.add(new Node[] {new
// Resource("http://purl.org/linked-data/sdmx/2009/measure#obsValue"),
// new Variable("value1")});
List<Node[]> mio_eur2eur_outputmembers = new ArrayList<Node[]>();
mio_eur2eur_outputmembers.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#unit"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/unit#EUR") });
// mio_eur2eur_outputmembers.add(new Node[] {new Variable("outputcube"),
// new
// Resource("http://purl.org/linked-data/sdmx/2009/measure#obsValue"),
// new Variable("value2")});
String mio_eur2eur_function = "(1000000 * x)";
ReconciliationCorrespondence mio_eur2eur_correspondence = new ReconciliationCorrespondence(
"mio_eur2eur", mio_eur2eur_inputmembers, null,
mio_eur2eur_outputmembers, mio_eur2eur_function);
// Convert-context
LogicalOlapOp convertgdp = new ConvertCubeOp(gdpbasecube,
mio_eur2eur_correspondence);
LogicalOlapQueryPlan myplan = new LogicalOlapQueryPlan(convertgdp);
String result = executeStatement(myplan);
assertContains(
"http://estatwrap.ontologycentral.com/dic/geo#UK; http://estatwrap.ontologycentral.com/dic/indic_na#P7; http://estatwrap.ontologycentral.com/dic/unit#EUR; 2010; 5.59686E11; ",
result);
}
/**
* First try of a pipeline. Using Estatwrap data. Computes GDP per capita.
*
* @throws OlapException
*/
public void executeGDP_Per_Capita_Compared() {
try {
// First: GDP and main components - Current prices dataset
Node gdpdsuri = new Resource(
"http://estatwrap.ontologycentral.com/id/nama_gdp_c#ds");
Restrictions gdprestrictions = new Restrictions();
gdprestrictions.cubeNamePattern = gdpdsuri;
// Base-cube
// XXX: We need to make sure that only the lowest members are
// queried
// from each cube.
// In order to fill the engine with data
List<Node[]> gdpcube = lde.getCubes(gdprestrictions);
assertEquals(2, gdpcube.size());
Map<String, Integer> gdpcubemap = Olap4ldLinkedDataUtil
.getNodeResultFields(gdpcube.get(0));
System.out.println("CUBE_NAME: "
+ gdpcube.get(1)[gdpcubemap.get("?CUBE_NAME")]);
List<Node[]> gdpcubemeasures = lde.getMeasures(gdprestrictions);
List<Node[]> gdpcubedimensions = lde.getDimensions(gdprestrictions);
assertEquals(true, gdpcubedimensions.size() > 1);
List<Node[]> gdpcubehierarchies = lde
.getHierarchies(gdprestrictions);
List<Node[]> gdpcubelevels = lde.getLevels(gdprestrictions);
List<Node[]> gdpcubemembers = lde.getMembers(gdprestrictions);
// Base-cube
BaseCubeOp gdpbasecube = new BaseCubeOp(gdpdsuri.toString());
// Projection
// Since we do not remove any measure from the cubes, we do not need
// projection.
// XXX: We will see how the query processor handles it if no
// projection
// is called.
// Dice
// For now, we do not do any dice since we slice over most
// dimensions
// XXX: However, the results may be wrong, if we do not ensure the
// constraint
// that base cube only queries for those members that are on the
// lowest
// level.
// Slice
// XXX: Since in MDX, we probably cannot distinguish between
// dimensions
// for specific cubes
// {indic_na, sex, age, esa95}
// Roll-up
// XXX: We do not need roll-up
List<Node[]> mio_eur2eur_inputmembers = new ArrayList<Node[]>();
mio_eur2eur_inputmembers
.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#unit"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/unit#MIO_EUR") });
// mio_eur2eur_inputmembers.add(new Node[] {new
// Resource("http://purl.org/linked-data/sdmx/2009/measure#obsValue"),
// new Variable("value1")});
List<Node[]> mio_eur2eur_outputmembers = new ArrayList<Node[]>();
mio_eur2eur_outputmembers
.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#unit"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/unit#EUR") });
// mio_eur2eur_outputmembers.add(new Node[] {new
// Variable("outputcube"),
// new
// Resource("http://purl.org/linked-data/sdmx/2009/measure#obsValue"),
// new Variable("value2")});
String mio_eur2eur_function = "(1000000 * x)";
ReconciliationCorrespondence mio_eur2eur_correspondence = new ReconciliationCorrespondence(
"mio_eur2eur", mio_eur2eur_inputmembers, null,
mio_eur2eur_outputmembers, mio_eur2eur_function);
// Mioeur2eur(dataset): Converting MIO_EUR to EUR in GDP dataset
LogicalOlapOp mio_eur2eur_op = new ConvertCubeOp(gdpbasecube,
mio_eur2eur_correspondence);
// Dice mioeur2eur for B1G.
// No dice necessary, directly possible with convert-context
// List<Node[]> dicehierarchysignatureB1G = null;
// List<List<Node[]>> dicemembercombinationsB1G = null;
// LogicalOlapOp b1g = new DiceOp(mioeur2eur,
// dicehierarchysignatureB1G,
// dicemembercombinationsB1G);
// Slice indic_na.
// No slice necessary, directly possible with convert-context
// List<Node[]> sliceB1G = null;
// LogicalOlapOp slicedb1g = new SliceOp(b1g, sliceB1G);
// Dice mioeur2eur for D21_M_D31.
// No dice necessary, directly possible with convert-context
// List<Node[]> dicehierarchysignatureD21_M_D31 = null;
// List<List<Node[]>> dicemembercombinationsD21_M_D31 = null;
// LogicalOlapOp d21_m_d31 = new DiceOp(mioeur2eur,
// dicehierarchysignatureD21_M_D31,
// dicemembercombinationsD21_M_D31);
// Slice indic_na.
// List<Node[]> sliceD21_M_D31 = null;
// LogicalOlapOp slicedd21_m_d31 = new SliceOp(d21_m_d31,
// sliceD21_M_D31);
// Drill-across B1G and D21...
// LogicalOlapOp drillacross = new DrillAcrossOp(slicedb1g,
// slicedd21_m_d31);
// Computing Nominal GDP from single parts in new EUR dataset.
// XXX: ComplexMeasureOp
// LogicalOlapOp computegdp = new ConvertContextOp(drillacross, 1,
// domainUri);
List<Node[]> computegdp_inputmembers1 = new ArrayList<Node[]>();
computegdp_inputmembers1
.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#indic_na"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/indic_na#B1G") });
List<Node[]> computegdp_inputmembers2 = new ArrayList<Node[]>();
computegdp_inputmembers2
.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#indic_na"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/indic_na#D21_M_D31") });
List<Node[]> computegdp_outputmembers = new ArrayList<Node[]>();
computegdp_outputmembers
.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#indic_na"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/indic_na#NGDP") });
String computegdp_function = "(x1 + x2)";
ReconciliationCorrespondence computegdp_correspondence = new ReconciliationCorrespondence(
"computegdp", computegdp_inputmembers1,
computegdp_inputmembers2, computegdp_outputmembers,
computegdp_function);
// String computegdp = "{" +
// "?obs1 <http://ontologycentral.com/2009/01/eurostat/ns#indic_na> <http://estatwrap.ontologycentral.com/dic/indic_na#B1G> .\n"
// +
// "?obs1 <http://purl.org/linked-data/sdmx/2009/measure#obsValue> ?value1 .\n"
// +
// "?obs2 <http://ontologycentral.com/2009/01/eurostat/ns#indic_na> <http://estatwrap.ontologycentral.com/dic/indic_na#D21_M_D31> .\n"
// +
// "?obs2 <http://purl.org/linked-data/sdmx/2009/measure#obsValue> ?value2 .\n"
// +
// "?newvalue <http://www.aifb.kit.edu/project/ld-retriever/qrl#bindas> \"(?value1 + ?value2)\" ."
// +
// "} => {" +
// "_:newobs <http://ontologycentral.com/2009/01/eurostat/ns#indic_na> <http://estatwrap.ontologycentral.com/dic/indic_na#NGDP> .\n"
// +
// "_:newobs <http://purl.org/linked-data/sdmx/2009/measure#obsValue> ?newvalue "
// +
// "} . ";
// Computing Nominal GDP from single parts in new EUR dataset.
LogicalOlapOp computegdp_op = new ConvertCubeOp(mio_eur2eur_op,
mio_eur2eur_op, computegdp_correspondence);
/*
* Should contain: http://estatwrap.ontologycentral.com/dic/geo#UK;
* http://estatwrap.ontologycentral.com/dic/indic_na#NGDP;
* http://estatwrap.ontologycentral.com/dic/unit#MIO_EUR; 2010;
* 1731809.0;
*/
// XXX Would I need to add to DSD: eurostat:indic_na
// dic_indic_na:NGDP;
// ?
// Second: Population dataset
Node populationuri = new Resource(
"http://estatwrap.ontologycentral.com/id/demo_pjan#ds");
Restrictions populationrestrictions = new Restrictions();
populationrestrictions.cubeNamePattern = populationuri;
// Base-cube
// XXX: We need to make sure that only the lowest members are
// queried
// from each cube.
// In order to fill the engine with data
// XXX: Should be part of base-cube operator
List<Node[]> populationcube = lde.getCubes(populationrestrictions);
assertEquals(2, populationcube.size());
Map<String, Integer> populationcubemap = Olap4ldLinkedDataUtil
.getNodeResultFields(populationcube.get(0));
System.out
.println("CUBE_NAME: "
+ populationcube.get(1)[populationcubemap
.get("?CUBE_NAME")]);
List<Node[]> populationcubemeasures = lde
.getMeasures(populationrestrictions);
List<Node[]> populationcubedimensions = lde
.getDimensions(populationrestrictions);
assertEquals(true, populationcubedimensions.size() > 1);
List<Node[]> populationcubehierarchies = lde
.getHierarchies(populationrestrictions);
List<Node[]> populationcubelevels = lde
.getLevels(populationrestrictions);
List<Node[]> populationcubemembers = lde
.getMembers(populationrestrictions);
BaseCubeOp populationbasecube = new BaseCubeOp(
populationuri.toString());
// XXX Would I need to add: Add indicator and unit to population
// dataset
// Compute "slice" of population that does not use sex and age
// dimensions
// List<Node[]> slicesexage = null;
// LogicalOlapOp slicedsexage = new SliceOp(populationbasecube,
// slicesexage);
// Drill-across gdp and population dataset
// LogicalOlapOp drillacrossgdppopulation = new DrillAcrossOp(
// slicedsexage, computegdp);
List<Node[]> computegdppercapita_inputmembers1 = new ArrayList<Node[]>();
computegdppercapita_inputmembers1
.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#indic_na"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/indic_na#NGDP") });
computegdppercapita_inputmembers1
.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#unit"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/unit#EUR") });
List<Node[]> computegdppercapita_inputmembers2 = new ArrayList<Node[]>();
computegdppercapita_inputmembers2
.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#sex"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/sex#T") });
computegdppercapita_inputmembers2
.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#age"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/age#TOTAL") });
List<Node[]> computegdppercapita_outputmembers = new ArrayList<Node[]>();
computegdppercapita_outputmembers
.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#indic_na"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/indic_na#NGDPH") });
computegdppercapita_outputmembers
.add(new Node[] {
new Resource(
"http://ontologycentral.com/2009/01/eurostat/ns#unit"),
new Resource(
"http://estatwrap.ontologycentral.com/dic/unit#EUR_HAB") });
String computegdppercapita_function = "(x1 / x2)";
ReconciliationCorrespondence computegdppercapita_correspondence = new ReconciliationCorrespondence(
"computegdppercapita", computegdppercapita_inputmembers1,
computegdppercapita_inputmembers2,
computegdppercapita_outputmembers,
computegdppercapita_function);
// Compute GDP per Capita from GDP and Population
// XXX: ComplexMeasureOp
LogicalOlapOp computegdppercapita_op = new ConvertCubeOp(
computegdp_op, populationbasecube,
computegdppercapita_correspondence);
// XXX: Complex: Compare with:
// http://estatwrap.ontologycentral.com/id/nama_aux_gph#ds
// Third: GDP per Capita
Node gdpalreadycomputeduri = new Resource(
"http://estatwrap.ontologycentral.com/id/nama_aux_gph#ds");
Restrictions gdpalreadycomputedrestrictions = new Restrictions();
gdpalreadycomputedrestrictions.cubeNamePattern = gdpalreadycomputeduri;
// Base-cube
// XXX: We need to make sure that only the lowest members are
// queried
// from each cube.
// In order to fill the engine with data
// XXX: Should be part of base-cube operator
List<Node[]> gdpalreadycomputedcube = lde
.getCubes(gdpalreadycomputedrestrictions);
assertEquals(2, gdpalreadycomputedcube.size());
Map<String, Integer> gdpalreadycomputedcubemap = Olap4ldLinkedDataUtil
.getNodeResultFields(gdpalreadycomputedcube.get(0));
System.out.println("CUBE_NAME: "
+ gdpalreadycomputedcube.get(1)[gdpalreadycomputedcubemap
.get("?CUBE_NAME")]);
List<Node[]> gdpalreadycomputedcubemeasures = lde
.getMeasures(gdpalreadycomputedrestrictions);
List<Node[]> gdpalreadycomputedcubedimensions = lde
.getDimensions(gdpalreadycomputedrestrictions);
assertEquals(true, gdpalreadycomputedcubedimensions.size() > 1);
List<Node[]> gdpalreadycomputedcubehierarchies = lde
.getHierarchies(gdpalreadycomputedrestrictions);
List<Node[]> gdpalreadycomputedcubelevels = lde
.getLevels(gdpalreadycomputedrestrictions);
List<Node[]> gdpalreadycomputedcubemembers = lde
.getMembers(gdpalreadycomputedrestrictions);
BaseCubeOp gdpalreadycomputedbasecube = new BaseCubeOp(
gdpalreadycomputeduri.toString());
// Slice
List<Node[]> gdpalreadycomputedbasecubesliceddimensions = new ArrayList<Node[]>();
gdpalreadycomputedbasecubesliceddimensions
.add(gdpalreadycomputedcubedimensions.get(0));
SliceOp gdpalreadycomputedbasecubesliced = new SliceOp(
gdpalreadycomputedbasecube,
gdpalreadycomputedbasecubesliceddimensions);
DrillAcrossOp comparegdppercapita_op = new DrillAcrossOp(
computegdppercapita_op, gdpalreadycomputedbasecubesliced);
LogicalOlapQueryPlan myplan = new LogicalOlapQueryPlan(
comparegdppercapita_op);
System.out.println("Logical Query Plan:" + myplan.toString());
String result = executeStatement(myplan);
// We see that reasoning is done, since there are both dimensions
// geo and allbus still in the data.
assertContains(
"http://estatwrap.ontologycentral.com/dic/geo#UK; http://estatwrap.ontologycentral.com/dic/geo#UK; http://estatwrap.ontologycentral.com/dic/indic_na#NGDPH; http://estatwrap.ontologycentral.com/dic/unit#EUR_HAB; 2010; 27704.423967820803,27800;",
result);
} catch (OlapException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* To execute this query would require me to implement "with member" to be
* both drill-across and compound measure. In MDX, we "declaratively" define
* "percentage of nos". This I want to do with convert-cube/merge-cubes
* declarations, which would be "equivalent" to the MDX query and which
* would simply be a declarative definition of new datasets from existing
* datasets (though for now without reasoning capability thus merge-cubes
* requires explicit sharing).
*
* @throws OlapException
*/
public void test_GdpGrowthRate_vs_EmploymentFearMetric() {
try {
// First: Real GDP Growth Rate
Node gdpgrowthdsuri = new Resource(
"http://estatwrap.ontologycentral.com/id/tec00115#ds");
Restrictions gdprestrictions = new Restrictions();
gdprestrictions.cubeNamePattern = gdpgrowthdsuri;
// Base-cube
// We need to make sure that only the lowest members are queried
// from each cube. We assume a "lean" dataset.
// In order to fill the engine with data
List<Node[]> gdpcube = lde.getCubes(gdprestrictions);
assertEquals(2, gdpcube.size());
Map<String, Integer> gdpcubemap = Olap4ldLinkedDataUtil
.getNodeResultFields(gdpcube.get(0));
System.out.println("CUBE_NAME: "
+ gdpcube.get(1)[gdpcubemap.get("?CUBE_NAME")]);
List<Node[]> gdpcubemeasures = lde.getMeasures(gdprestrictions);
List<Node[]> gdpcubedimensions = lde.getDimensions(gdprestrictions);
assertEquals(true, gdpcubedimensions.size() > 1);
List<Node[]> gdpcubehierarchies = lde
.getHierarchies(gdprestrictions);
List<Node[]> gdpcubelevels = lde.getLevels(gdprestrictions);
List<Node[]> gdpcubemembers = lde.getMembers(gdprestrictions);
// Base-cube
BaseCubeOp gdpbasecube = new BaseCubeOp(gdpgrowthdsuri.toString());
// Convert-Cube / Merge-Cubes
// XXX: Not yet needed since manual drill-across.
// Slice
List<Node[]> gdpsliceddimensions = new ArrayList<Node[]>();
System.out.println("DIMENSION_UNIQUE_NAMES:");
Map<String, Integer> gdpdimensionmap = Olap4ldLinkedDataUtil
.getNodeResultFields(gdpcubedimensions.get(0));
// Header
gdpsliceddimensions.add(gdpcubedimensions.get(0));
for (Node[] nodes : gdpcubedimensions) {
String dimensionname = nodes[gdpdimensionmap
.get("?DIMENSION_UNIQUE_NAME")].toString();
System.out.println(dimensionname);
if (dimensionname
.equals("http://ontologycentral.com/2009/01/eurostat/ns#unit")) {
gdpsliceddimensions.add(nodes);
}
}
// Here, projection would be needed.
SliceOp gdpsliced = new SliceOp(gdpbasecube, gdpsliceddimensions);
// Second: Unemployment dataset
Node unemploymentdsuri = new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/ZA4570v590.rdf#ds");
Restrictions unemploymentdsrestrictions = new Restrictions();
unemploymentdsrestrictions.cubeNamePattern = unemploymentdsuri;
// Base-cube
// Here, the data will be loaded. In order to fill the engine with
// data
List<Node[]> unemploymentcube = lde
.getCubes(unemploymentdsrestrictions);
assertEquals(2, unemploymentcube.size());
Map<String, Integer> unemploymentcubemap = Olap4ldLinkedDataUtil
.getNodeResultFields(unemploymentcube.get(0));
System.out.println("CUBE_NAME: "
+ unemploymentcube.get(1)[unemploymentcubemap
.get("?CUBE_NAME")]);
List<Node[]> unemploymentcubemeasures = lde
.getMeasures(unemploymentdsrestrictions);
List<Node[]> unemploymentcubedimensions = lde
.getDimensions(unemploymentdsrestrictions);
assertEquals(true, unemploymentcubedimensions.size() > 1);
List<Node[]> unemploymentcubehierarchies = lde
.getHierarchies(unemploymentdsrestrictions);
List<Node[]> unemploymentcubelevels = lde
.getLevels(unemploymentdsrestrictions);
List<Node[]> unemploymentcubemembers = lde
.getMembers(unemploymentdsrestrictions);
BaseCubeOp unemploymentbasecube = new BaseCubeOp(
unemploymentdsuri.toString());
// First pre-processing
// Convert-Cube / Merge-Cubes
// COMPUTE_YES
ReconciliationCorrespondence computeyes_correspondence;
List<Node[]> computeyes_inputmembers1 = new ArrayList<Node[]>();
computeyes_inputmembers1
.add(new Node[] {
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/vocab.rdf#variable"),
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/variable.rdf#v590_2") });
List<Node[]> computeyes_inputmembers2 = new ArrayList<Node[]>();
computeyes_inputmembers2
.add(new Node[] {
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/vocab.rdf#variable"),
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/variable.rdf#v590_3") });
List<Node[]> computeyes_outputmembers = new ArrayList<Node[]>();
computeyes_outputmembers
.add(new Node[] {
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/vocab.rdf#variable"),
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/variable.rdf#v590_2+3") });
String computeyes_function = "(x1 + x2)";
computeyes_correspondence = new ReconciliationCorrespondence(
"computeyes", computeyes_inputmembers1,
computeyes_inputmembers2, computeyes_outputmembers,
computeyes_function);
LogicalOlapOp computeyes_op = new ConvertCubeOp(
unemploymentbasecube, unemploymentbasecube,
computeyes_correspondence);
// COMPUTE\_PERCENTAGENOS
ReconciliationCorrespondence computepercentagenos_correspondence;
List<Node[]> computepercentagenos_inputmembers1 = new ArrayList<Node[]>();
computepercentagenos_inputmembers1
.add(new Node[] {
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/vocab.rdf#variable"),
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/variable.rdf#v590_1") });
List<Node[]> computepercentagenos_inputmembers2 = new ArrayList<Node[]>();
computepercentagenos_inputmembers2
.add(new Node[] {
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/vocab.rdf#variable"),
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/variable.rdf#v590_2+3") });
List<Node[]> computepercentagenos_outputmembers = new ArrayList<Node[]>();
computepercentagenos_outputmembers
.add(new Node[] {
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/vocab.rdf#variable"),
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/variable.rdf#v590_2+3") });
// Not yet needed since manual drill-across:
// computepercentagenos_outputmembers
// .add(new Node[] {
// new Resource(
// "http://ontologycentral.com/2009/01/eurostat/ns#indic_na"),
// new Resource(
// "http://estatwrap.ontologycentral.com/dic/indic_na#RGDPG") });
String computepercentagenos_function = "(x1 / (x1 + x2))";
computepercentagenos_correspondence = new ReconciliationCorrespondence(
"computepercentagenos", computepercentagenos_inputmembers1,
computepercentagenos_inputmembers2,
computepercentagenos_outputmembers,
computepercentagenos_function);
// Compute GDP per Capita from GDP and Population
LogicalOlapOp computepercentagenos_op = new ConvertCubeOp(
unemploymentbasecube, computeyes_op,
computepercentagenos_correspondence);
// Slice
List<Node[]> computepercentagenosslicesliceddimensions = new ArrayList<Node[]>();
System.out.println("DIMENSION_UNIQUE_NAMES:");
Map<String, Integer> computepercentagenosslicedimensionmap = Olap4ldLinkedDataUtil
.getNodeResultFields(unemploymentcubedimensions.get(0));
// Header
computepercentagenosslicesliceddimensions
.add(unemploymentcubedimensions.get(0));
for (Node[] nodes : unemploymentcubedimensions) {
String dimensionname = nodes[computepercentagenosslicedimensionmap
.get("?DIMENSION_UNIQUE_NAME")].toString();
System.out.println(dimensionname);
if (dimensionname
.equals("http://lod.gesis.org/lodpilot/ALLBUS/vocab.rdf#variable")
|| dimensionname
.equals("http://ontologycentral.com/2009/01/eurostat/ns#indic_na")) {
computepercentagenosslicesliceddimensions.add(nodes);
}
}
SliceOp computepercentagenosslicesliced = new SliceOp(
computepercentagenos_op,
computepercentagenosslicesliceddimensions);
// LogicalOlapQueryPlan myplan = new LogicalOlapQueryPlan(
// computepercentagenosslicesliced);
//
// System.out.println("Logical Query Plan:"+myplan.toString());
//
// String result = executeStatement(myplan);
//
// assertContains(
// "http://estatwrap.ontologycentral.com/dic/geo#UK; http://estatwrap.ontologycentral.com/dic/indic_na#NGDPH; http://estatwrap.ontologycentral.com/dic/unit#EUR_HAB; 2010; 27800; 27704.423967820803;",
// result);
// Drill-across gdp and unemployment dataset
DrillAcrossOp comparegdppercapita_op = new DrillAcrossOp(gdpsliced,
computepercentagenosslicesliced);
LogicalOlapQueryPlan myplan = new LogicalOlapQueryPlan(
comparegdppercapita_op);
System.out.println("Logical Query Plan:" + myplan.toString());
String result = executeStatement(myplan);
// Result as in ISEM paper
assertContains(
"http://dbpedia.org/resource/Germany; http://dbpedia.org/resource/Germany; 1980; 0.927512355848434925864909;",
result);
// Result as manually computed
assertContains(
"http://estatwrap.ontologycentral.com/dic/geo#DE; http://lod.gesis.org/lodpilot/ALLBUS/geo.rdf#00; 2008; 1.1,0.826589595375722543352601;",
result);
} catch (OlapException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void test_SMALLGdpGrowthRate_vs_EmploymentFearMetric() {
try {
// Second: Unemployment dataset
Node unemploymentdsuri = new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/ZA4570v590.rdf#ds");
Restrictions unemploymentdsrestrictions = new Restrictions();
unemploymentdsrestrictions.cubeNamePattern = unemploymentdsuri;
// Base-cube
// Here, the data will be loaded. In order to fill the engine with
// data
List<Node[]> unemploymentcube = lde
.getCubes(unemploymentdsrestrictions);
assertEquals(2, unemploymentcube.size());
Map<String, Integer> unemploymentcubemap = Olap4ldLinkedDataUtil
.getNodeResultFields(unemploymentcube.get(0));
System.out.println("CUBE_NAME: "
+ unemploymentcube.get(1)[unemploymentcubemap
.get("?CUBE_NAME")]);
List<Node[]> unemploymentcubemeasures = lde
.getMeasures(unemploymentdsrestrictions);
List<Node[]> unemploymentcubedimensions = lde
.getDimensions(unemploymentdsrestrictions);
assertEquals(true, unemploymentcubedimensions.size() > 1);
List<Node[]> unemploymentcubehierarchies = lde
.getHierarchies(unemploymentdsrestrictions);
List<Node[]> unemploymentcubelevels = lde
.getLevels(unemploymentdsrestrictions);
List<Node[]> unemploymentcubemembers = lde
.getMembers(unemploymentdsrestrictions);
BaseCubeOp unemploymentbasecube = new BaseCubeOp(
unemploymentdsuri.toString());
// First pre-processing
// Convert-Cube / Merge-Cubes
// COMPUTE_YES
ReconciliationCorrespondence computeyes_correspondence;
List<Node[]> computeyes_inputmembers1 = new ArrayList<Node[]>();
computeyes_inputmembers1
.add(new Node[] {
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/vocab.rdf#variable"),
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/variable.rdf#v590_2") });
List<Node[]> computeyes_inputmembers2 = new ArrayList<Node[]>();
computeyes_inputmembers2
.add(new Node[] {
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/vocab.rdf#variable"),
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/variable.rdf#v590_3") });
List<Node[]> computeyes_outputmembers = new ArrayList<Node[]>();
computeyes_outputmembers
.add(new Node[] {
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/vocab.rdf#variable"),
new Resource(
"http://lod.gesis.org/lodpilot/ALLBUS/variable.rdf#v590_2+3") });
String computeyes_function = "(x1 + x2)";
computeyes_correspondence = new ReconciliationCorrespondence(
"computeyes", computeyes_inputmembers1,
computeyes_inputmembers2, computeyes_outputmembers,
computeyes_function);
LogicalOlapOp computeyes_op = new ConvertCubeOp(
unemploymentbasecube, unemploymentbasecube,
computeyes_correspondence);
// Slice
List<Node[]> computepercentagenosslicesliceddimensions = new ArrayList<Node[]>();
System.out.println("DIMENSION_UNIQUE_NAMES:");
Map<String, Integer> computepercentagenosslicedimensionmap = Olap4ldLinkedDataUtil
.getNodeResultFields(unemploymentcubedimensions.get(0));
// Header
computepercentagenosslicesliceddimensions
.add(unemploymentcubedimensions.get(0));
for (Node[] nodes : unemploymentcubedimensions) {
String dimensionname = nodes[computepercentagenosslicedimensionmap
.get("?DIMENSION_UNIQUE_NAME")].toString();
System.out.println(dimensionname);
if (dimensionname
.equals("http://lod.gesis.org/lodpilot/ALLBUS/vocab.rdf#variable")
|| dimensionname
.equals("http://ontologycentral.com/2009/01/eurostat/ns#indic_na")) {
computepercentagenosslicesliceddimensions.add(nodes);
}
}
SliceOp computepercentagenosslicesliced = new SliceOp(
computeyes_op, computepercentagenosslicesliceddimensions);
LogicalOlapQueryPlan myplan = new LogicalOlapQueryPlan(
computepercentagenosslicesliced);
System.out.println("Logical Query Plan:" + myplan.toString());
String result = executeStatement(myplan);
// Result as in ISEM paper
assertContains(
"http://dbpedia.org/resource/Germany; http://dbpedia.org/resource/Germany; 1980; 0.927512355848434925864909;",
result);
// Result as manually computed
assertContains(
"http://estatwrap.ontologycentral.com/dic/geo#DE; http://lod.gesis.org/lodpilot/ALLBUS/geo.rdf#00; 2008; 1.1,0.826589595375722543352601;",
result);
} catch (OlapException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Tries to get worldbank data from Sarven.
*
* @throws OlapException
*/
public void executeGDP_per_Capita_Worldbank() throws OlapException {
String domainUri = "http://141.52.218.13:8080/QB-Slicer/rest/mioeur2eur?dsUri=";
// First: GDP current dataset
Node gdpdsuri = new Resource(
"http://worldbank.270a.info/dataset/NY.GDP.MKTP.CD");
gdpdsuri = new Resource("http://imf.270a.info/dataset/PGI");
Restrictions gdprestrictions = new Restrictions();
gdprestrictions.cubeNamePattern = gdpdsuri;
// Base-cube
// XXX: We need to make sure that only the lowest members are queried
// from each cube.
// In order to fill the engine with data
List<Node[]> gdpcube = lde.getCubes(gdprestrictions);
assertEquals(2, gdpcube.size());
Map<String, Integer> gdpcubemap = Olap4ldLinkedDataUtil
.getNodeResultFields(gdpcube.get(0));
System.out.println("CUBE_NAME: "
+ gdpcube.get(1)[gdpcubemap.get("?CUBE_NAME")]);
List<Node[]> gdpcubemeasures = lde.getMeasures(gdprestrictions);
List<Node[]> gdpcubedimensions = lde.getDimensions(gdprestrictions);
assertEquals(true, gdpcubedimensions.size() > 1);
List<Node[]> gdpcubehierarchies = lde.getHierarchies(gdprestrictions);
List<Node[]> gdpcubelevels = lde.getLevels(gdprestrictions);
List<Node[]> gdpcubemembers = lde.getMembers(gdprestrictions);
// Base-cube
BaseCubeOp gdpbasecube = new BaseCubeOp(gdpdsuri.toString());
LogicalOlapQueryPlan myplan = new LogicalOlapQueryPlan(gdpbasecube);
String result = executeStatement(myplan);
assertContains(
"http://estatwrap.ontologycentral.com/dic/geo#UK; http://estatwrap.ontologycentral.com/dic/indic_na#NGDPH; http://estatwrap.ontologycentral.com/dic/unit#EUR_HAB; 2010; 27704.423967820803;",
result);
}
/**
* Here we check whether we can call Base-Cube without any other operation
* or simply Drill-Across operation.
*
* The reason is that our "compile" should not make problems with:
*
* 1) We may have Slice/Dice/etc. over BaseCube -> No problem. 2) We may
* have Convert-Cube etc. over BaseCube -> No problem. 3) We may have
* Drill-Across over BaseCube -> Problem. 4) We may have Base-Cube directly
* -> Problem.
*
*/
public void testOfBaseCubeDrillAcross() {
try {
// Third: GDP per Capita
Node gdpalreadycomputeduri = new Resource(
"http://estatwrap.ontologycentral.com/id/nama_aux_gph#ds");
Restrictions gdpalreadycomputedrestrictions = new Restrictions();
gdpalreadycomputedrestrictions.cubeNamePattern = gdpalreadycomputeduri;
// Base-cube
// XXX: We need to make sure that only the lowest members are
// queried
// from each cube.
// In order to fill the engine with data
// XXX: Should be part of base-cube operator
List<Node[]> gdpalreadycomputedcube = lde
.getCubes(gdpalreadycomputedrestrictions);
assertEquals(2, gdpalreadycomputedcube.size());
Map<String, Integer> gdpalreadycomputedcubemap = Olap4ldLinkedDataUtil
.getNodeResultFields(gdpalreadycomputedcube.get(0));
System.out.println("CUBE_NAME: "
+ gdpalreadycomputedcube.get(1)[gdpalreadycomputedcubemap
.get("?CUBE_NAME")]);
List<Node[]> gdpalreadycomputedcubemeasures = lde
.getMeasures(gdpalreadycomputedrestrictions);
BaseCubeOp gdpalreadycomputedbasecube = new BaseCubeOp(
gdpalreadycomputeduri.toString());
// Projection needed
List<Node[]> gdppcprojectedmeasures = new ArrayList<Node[]>();
Map<String, Integer> gdpdimensionmap = Olap4ldLinkedDataUtil
.getNodeResultFields(gdpalreadycomputedcubemeasures.get(0));
// Header
gdppcprojectedmeasures.add(gdpalreadycomputedcubemeasures.get(0));
for (Node[] nodes : gdpalreadycomputedcubemeasures) {
String measurename = nodes[gdpdimensionmap
.get("?MEASURE_UNIQUE_NAME")].toString();
System.out.println(measurename);
if (measurename.equals("http://purl.org/linked-data/sdmx/2009/measure#obsValue")) {
gdppcprojectedmeasures.add(nodes);
}
}
ProjectionOp gdpalreadycomputedprojected = new ProjectionOp(gdpalreadycomputedbasecube, gdppcprojectedmeasures);
LogicalOlapQueryPlan myplan = new LogicalOlapQueryPlan(
gdpalreadycomputedprojected);
System.out.println("Logical Query Plan:" + myplan.toString());
String result = executeStatement(myplan);
assertContains(
"http://lod.gesis.org/lodpilot/ALLBUS/geo.rdf#00; http://lod.gesis.org/lodpilot/ALLBUS/geo.rdf#00; http://estatwrap.ontologycentral.com/dic/indic_na#NGDPH; http://estatwrap.ontologycentral.com/dic/unit#PPS_HAB; 2010; 29200;",
result);
} catch (OlapException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void assertContains(String seek, String s) {
if (s.indexOf(seek) < 0) {
fail("expected to find '" + seek + "' in '" + s + "'");
}
}
private String executeStatement(LogicalOlapQueryPlan queryplan) {
String resultString = "";
try {
// For now, we simply return plan
System.out.println("--------------");
System.out.println("Logical plan:" + queryplan.toString());
// Execute query return representation of physical query plan
List<Node[]> result = this.lde.executeOlapQuery(queryplan);
PhysicalOlapQueryPlan execplan = this.lde.getExecplan();
System.out.println("Physical plan:" + execplan.toString());
System.out.println("Result:");
for (Node[] nodes : result) {
for (Node node : nodes) {
resultString += node.toString() + "; ";
System.out.print(node.toString() + "; ");
}
resultString += "\n";
System.out.println();
}
System.out.println("--------------");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return resultString;
}
/**
* Converts a {@link CellSet} to text.
*
* @param cellSet
* Query result
* @param format
* Format
* @return Result as text
*/
static String toString(CellSet cellSet, Format format) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
switch (format) {
case TRADITIONAL:
new TraditionalCellSetFormatter().format(cellSet, pw);
break;
case COMPACT_RECTANGULAR:
case RECTANGULAR:
new RectangularCellSetFormatter(
format == Format.COMPACT_RECTANGULAR).format(cellSet, pw);
break;
}
pw.flush();
return sw.toString();
}
}
// End MetadataTest.java