Package org.saiku.olap.query

Source Code of org.saiku.olap.query.MdxQuery

/*
* Copyright 2014 OSBI Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.saiku.olap.query;

import org.saiku.olap.dto.SaikuCube;
import org.saiku.olap.dto.SaikuTag;
import org.saiku.olap.dto.filter.SaikuFilter;
import org.saiku.olap.util.exception.SaikuOlapException;
import org.saiku.olap.util.formatter.ICellSetFormatter;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.olap4j.*;
import org.olap4j.mdx.SelectNode;
import org.olap4j.mdx.parser.MdxParser;
import org.olap4j.mdx.parser.MdxParserFactory;
import org.olap4j.mdx.parser.MdxValidator;
import org.olap4j.metadata.Catalog;
import org.olap4j.metadata.Cube;
import org.olap4j.metadata.Database;
import org.olap4j.metadata.Schema;
import org.olap4j.query.QueryAxis;
import org.olap4j.query.QueryDimension;
import org.olap4j.type.CubeType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.Map;
import java.util.Properties;

import mondrian.rolap.RolapConnection;

/**
* MdxQuery.
*/
public class MdxQuery implements IQuery {

  private static final Logger LOG = LoggerFactory.getLogger(MdxQuery.class);

  @NotNull
  private final Properties properties = new Properties();
  private String mdx;
  private SaikuCube cube;
  private final OlapConnection connection;
  private final String name;
  private Scenario scenario;
  private CellSet cellset;
  @Nullable
  private OlapStatement statement;

  private ICellSetFormatter formatter;

  public MdxQuery(OlapConnection con, SaikuCube cube, String name, String mdx) {
    this.cube = cube;
    this.connection = con;
    this.name = name;
    this.mdx = mdx;
  }

  public String getName() {
    return name;
  }

  public SaikuCube getSaikuCube() {
    try {
      Cube c = getCube();
      cube = new SaikuCube(
          cube.getConnection(),
          c.getUniqueName(),
          c.getName(),
          c.getCaption(),
          cube.getCatalog(),
          c.getSchema().getName());
    } catch (Exception e) {
      // we tried, but it just doesn't work, so let's return the last working cube
    }
    return cube;
  }

  public String getMdx() {
    return mdx;
  }

  public void setMdx(String mdx) {
    this.mdx = mdx;
  }

  public void resetQuery() {
    this.mdx = "";
  }

  public void setProperties(Properties props) {
    this.properties.putAll(props);
  }

  @NotNull
  public Properties getProperties() {
    Properties props = this.properties;
    props.put(QueryProperties.KEY_IS_DRILLTHROUGH, isDrillThroughEnabled().toString());
    props.put("org.saiku.connection.scenario", Boolean.toString(false));
    try {
      props.put("org.saiku.query.explain", Boolean.toString(connection.isWrapperFor(RolapConnection.class)));
    } catch (Exception e) {
      props.put("org.saiku.query.explain", Boolean.toString(false));
    }
    return props;
  }

  public String toXml() {
    QuerySerializer qs = new QuerySerializer(this);
    return qs.createXML();
  }

  @NotNull
  public Boolean isDrillThroughEnabled() {
    try {
      Cube cube = getCube();
      return cube != null && cube.isDrillThroughEnabled();
    } catch (Exception e) {
      if (cube == null) {
        LOG.error("Cube is null");
      } else {
        LOG.error("Could not detect drillthrough", e.getCause());
      }
    }
    return false;
  }

  public CellSet execute() throws Exception {
    try {
      if (statement != null) {
        statement.close();
        statement = null;
      }

      OlapConnection con = connection;
      con.setCatalog(getSaikuCube().getCatalog());
      OlapStatement stmt = con.createStatement();
      this.statement = stmt;

      return stmt.executeOlapQuery(mdx);
    } finally {
      if (statement != null) {
        statement.close();
        statement = null;
      }
    }
  }

  @NotNull
  public QueryType getType() {
    return QueryType.MDX;
  }

  public void swapAxes() {
    throw new UnsupportedOperationException();
  }

  @NotNull
  public Map<Axis, QueryAxis> getAxes() {
    throw new UnsupportedOperationException();
  }

  @NotNull
  public QueryAxis getAxis(Axis axis) {
    throw new UnsupportedOperationException();
  }

  @NotNull
  public QueryAxis getAxis(String name) throws SaikuOlapException {
    throw new UnsupportedOperationException();
  }

  @Nullable
  public Cube getCube() {
    final MdxParserFactory parserFactory =
        connection.getParserFactory();
    MdxParser mdxParser =
        parserFactory.createMdxParser(connection);
    MdxValidator mdxValidator =
        parserFactory.createMdxValidator(connection);

    String mdx = getMdx();
    try {

      if (mdx != null && mdx.length() > 0 && mdx.toUpperCase().contains("FROM")) {
        SelectNode select =
            mdxParser.parseSelect(getMdx());
        select = mdxValidator.validateSelect(select);
        CubeType cubeType = (CubeType) select.getFrom().getType();
        return cubeType.getCube();
      }
    } catch (Exception e) {
      LOG.debug("Parsing MDX to get the Cube failed. Using fallback scenario.", e);
    }
    try {
      // ok seems like we failed to get the cube, lets try it differently
      if (connection != null && mdx != null && mdx.length() > 0) {
        for (Database db : connection.getOlapDatabases()) {
          Catalog cat = db.getCatalogs().get(cube.getCatalog());
          if (cat != null) {
            for (Schema schema : cat.getSchemas()) {
              for (Cube cub : schema.getCubes()) {
                if (cub.getName().equals(cube.getName()) || cub.getUniqueName().equals(cube.getName())) {
                  return cub;
                }
              }
            }
          }
        }
      }
    } catch (OlapException e) {
      e.printStackTrace();
    }


    return null;
  }

  @NotNull
  public QueryAxis getUnusedAxis() {
    throw new UnsupportedOperationException();
  }

  public void moveDimension(QueryDimension dimension, Axis axis) {
    throw new UnsupportedOperationException();
  }

  public void moveDimension(QueryDimension dimension, Axis axis, int position) {
    throw new UnsupportedOperationException();
  }

  @NotNull
  public QueryDimension getDimension(String name) {
    throw new UnsupportedOperationException();
  }

  public void resetAxisSelections(QueryAxis axis) {
    throw new UnsupportedOperationException();
  }

  public void clearAllQuerySelections() {
    throw new UnsupportedOperationException();
  }

  public void clearAxis(String axisName) throws SaikuOlapException {
    throw new UnsupportedOperationException();
  }

  public void setScenario(Scenario scenario) {
    this.scenario = scenario;
  }

  public Scenario getScenario() {
    return scenario;
  }

  public void setTag(SaikuTag tag) {
    throw new UnsupportedOperationException();
  }

  @Nullable
  public SaikuTag getTag() {
    return null;
  }

  public void removeTag() {
  }

  public void storeCellset(CellSet cs) {
    this.cellset = cs;

  }

  public CellSet getCellset() {
    return cellset;
  }

  public void setStatement(OlapStatement os) {
    this.statement = os;

  }

  @Nullable
  public OlapStatement getStatement() {
    return this.statement;
  }

  public void cancel() throws Exception {
    if (this.statement != null && !this.statement.isClosed()) {
      statement.close();
    }
    this.statement = null;
  }

  public void setFilter(SaikuFilter filter) {
    throw new UnsupportedOperationException();
  }

  @Nullable
  public SaikuFilter getFilter() {
    return null;
  }

  public void removeFilter() {
  }

  public OlapConnection getConnection() {
    return this.connection;
  }

  public void storeFormatter(ICellSetFormatter formatter) {
    this.formatter = formatter;

  }

  public ICellSetFormatter getFormatter() {
    return formatter;
  }

  public void setTotalFunction(String uniqueLevelName, String value) {

  }

  @NotNull
  public String getTotalFunction(String uniqueLevelName) {
    return "";
  }

  @NotNull
  public Map<String, String> getTotalFunctions() {
    return Collections.emptyMap();
  }

}
TOP

Related Classes of org.saiku.olap.query.MdxQuery

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.