Package org.saiku.web.rest.resources

Source Code of org.saiku.web.rest.resources.QueryResource

/*
* 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.web.rest.resources;

import org.saiku.olap.dto.*;
import org.saiku.olap.dto.filter.SaikuFilter;
import org.saiku.olap.dto.resultset.CellDataSet;
import org.saiku.olap.query.IQuery;
import org.saiku.olap.util.ObjectUtil;
import org.saiku.olap.util.SaikuProperties;
import org.saiku.olap.util.formatter.CellSetFormatter;
import org.saiku.olap.util.formatter.FlattenedCellSetFormatter;
import org.saiku.olap.util.formatter.HierarchicalCellSetFormatter;
import org.saiku.olap.util.formatter.ICellSetFormatter;
import org.saiku.service.olap.OlapDiscoverService;
import org.saiku.service.olap.OlapQueryService;
import org.saiku.service.util.exception.SaikuServiceException;
import org.saiku.web.rest.objects.MdxQueryObject;
import org.saiku.web.rest.objects.SavedQuery;
import org.saiku.web.rest.objects.SelectionRestObject;
import org.saiku.web.rest.objects.resultset.QueryResult;
import org.saiku.web.rest.util.RestUtil;
import org.saiku.web.rest.util.ServletUtil;
import org.saiku.web.svg.PdfReport;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.type.TypeFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.StringReader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;

import javax.servlet.ServletException;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

/**
* QueryServlet contains all the methods required when manipulating an OLAP Query.
*/
@Component
@Path("/saiku/{username}/query")
@XmlAccessorType(XmlAccessType.NONE)
public class QueryResource {

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

  private OlapQueryService olapQueryService;
  private OlapDiscoverService olapDiscoverService;
  private ISaikuRepository repository;

  @Autowired
  public void setOlapQueryService(OlapQueryService olapqs) {
    olapQueryService = olapqs;
  }

  //@Autowired
  public void setRepository(ISaikuRepository repository) {
    this.repository = repository;
  }


  //@Autowired
  public void setOlapDiscoverService(OlapDiscoverService olapds) {
    olapDiscoverService = olapds;
  }


  /**
   * Return a list of open queries.
   */
  @GET
  @Produces({ "application/json" })
  public List<String> getQueries() {
    return olapQueryService.getQueries();
  }

  @GET
  @Produces({ "application/json" })
  @Path("/{queryname}")
  public SaikuQuery getQuery(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "\tGET");
    }
    return olapQueryService.getQuery(queryName);
  }

  /**
   * Delete query from the query pool.
   *
   * @return a HTTP 410(Works) or HTTP 404(Call failed).
   */
  @DELETE
  @Path("/{queryname}")
  public Status deleteQuery(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "\tDELETE");
    }
    try {
      olapQueryService.deleteQuery(queryName);
      return Status.GONE;
    } catch (Exception e) {
      LOG.error("Cannot delete query (" + queryName + ")", e);
      return Status.NOT_FOUND;
    }
  }

  /**
   * Create a new Saiku Query.
   *
   * @param connectionName the name of the Saiku connection.
   * @param cubeName       the name of the cube.
   * @param catalogName    the catalog name.
   * @param schemaName     the name of the schema.
   * @param queryName      the name you want to assign to the query.
   * @return a query model.
   * @see
   */
  @POST
  @Produces({ "application/json" })
  @Path("/{queryname}")
  public SaikuQuery createQuery(
      @FormParam("connection") String connectionName,
      @FormParam("cube") String cubeName,
      @FormParam("catalog") String catalogName,
      @FormParam("schema") String schemaName,
      @FormParam("xml") String xmlOld,
      @PathParam("queryname") String queryName,
      MultivaluedMap<String, String> formParams) throws ServletException {
    try {
      String file = null;
      String xml = null;
      if (formParams != null) {
        xml = formParams.containsKey("xml") ? formParams.getFirst("xml") : xmlOld;
        file = formParams.containsKey("file") ? formParams.getFirst("file") : null;
        if (StringUtils.isNotBlank(file)) {
          Response f = repository.getResource(file);
          xml = new String((byte[]) f.getEntity());
        }
      } else {
        xml = xmlOld;
      }
      if (LOG.isDebugEnabled()) {
        LOG.debug("TRACK\t" + "\t/query/" + queryName + "\tPOST\t xml:" + (xml == null) + " file:" + file);
      }
      SaikuCube cube = new SaikuCube(connectionName, cubeName, cubeName, cubeName, catalogName, schemaName);
      if (StringUtils.isNotBlank(xml)) {
        String query = ServletUtil.replaceParameters(formParams, xml);
        return olapQueryService.createNewOlapQuery(queryName, query);
      }
      return olapQueryService.createNewOlapQuery(queryName, cube);
    } catch (Exception e) {
      throw new WebApplicationException(e);
    }
  }

  @GET
  @Produces({ "application/json" })
  @Path("/{queryname}/properties")
  public Properties getProperties(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/properties\tGET");
    }
    return olapQueryService.getProperties(queryName);
  }


  @POST
  @Produces({ "application/json" })
  @Path("/{queryname}/properties")
  public Properties setProperties(
      @PathParam("queryname") String queryName,
      @FormParam("properties") String properties) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/properties\tPOST");
    }
    try {
      Properties props = new Properties();
      StringReader sr = new StringReader(properties);
      props.load(sr);
      return olapQueryService.setProperties(queryName, props);
    } catch (Exception e) {
      LOG.error("Cannot set properties for query (" + queryName + ")", e);
      return null;
    }

  }

  @POST
  @Produces({ "application/json" })
  @Path("/{queryname}/properties/{propertyKey}")
  public Properties setProperties(
      @PathParam("queryname") String queryName,
      @PathParam("propertyKey") String propertyKey,
      @FormParam("propertyValue") String propertyValue) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/properties/" + propertyKey + "\tPOST");
    }
    try {
      Properties props = new Properties();
      props.put(propertyKey, propertyValue);
      return olapQueryService.setProperties(queryName, props);
    } catch (Exception e) {
      LOG.error("Cannot set property (" + propertyKey + " ) for query (" + queryName + ")", e);
      return null;
    }

  }

  @GET
  @Path("/{queryname}/mdx")
  public MdxQueryObject getMDXQuery(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/mdx/\tGET");
    }
    try {
      String mdx = olapQueryService.getMDXQuery(queryName);
      return new MdxQueryObject(mdx);
    } catch (Exception e) {
      LOG.error("Cannot get mdx for query (" + queryName + ")", e);
      return null;
    }
  }

  @POST
  @Consumes("application/x-www-form-urlencoded")
  @Path("/{queryname}/mdx")
  public void setMDXQuery(@PathParam("queryname") String queryName, @FormParam("mdx") String mdx) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/mdx/\tPOST");
    }
    try {
      olapQueryService.setMdx(queryName, mdx);
    } catch (Exception e) {
      LOG.error("Cannot set mdx for query (" + queryName + ")", e);
    }
  }

  @GET
  @Produces({ "application/json" })
  @Path("/{queryname}/xml")
  public SavedQuery getQueryXml(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/xml/\tGET");
    }
    try {
      String xml = olapQueryService.getQueryXml(queryName);
      return new SavedQuery(queryName, null, xml);
    } catch (Exception e) {
      LOG.error("Cannot get xml for query (" + queryName + ")", e);
      return null;
    }

  }

  @GET
  @Produces({ "application/vnd.ms-excel" })
  @Path("/{queryname}/export/xls")
  public Response getQueryExcelExport(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/export/xls/\tGET");
    }
    return getQueryExcelExport(queryName, "flattened");
  }

  @GET
  @Produces({ "application/vnd.ms-excel" })
  @Path("/{queryname}/export/xls/{format}")
  public Response getQueryExcelExport(
      @PathParam("queryname") String queryName,
      @PathParam("format") @DefaultValue("flattened") String format) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/export/xls/" + format + "\tGET");
    }
    try {
      byte[] doc = olapQueryService.getExport(queryName, "xls", format);
      String name = SaikuProperties.WEBEXPORTEXCELNAME + "." + SaikuProperties.WEBEXPORTEXCELFORMAT;
      return Response.ok(doc, MediaType.APPLICATION_OCTET_STREAM).header(
          "content-disposition",
          "attachment; filename = " + name).header(
          "content-length", doc.length).build();
    } catch (Exception e) {
      LOG.error("Cannot get excel for query (" + queryName + ")", e);
      return Response.serverError().build();
    }
  }

  @GET
  @Produces({ "text/csv" })
  @Path("/{queryname}/export/csv")
  public Response getQueryCsvExport(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/export/csv\tGET");
    }
    return getQueryCsvExport(queryName, "flattened");
  }

  @GET
  @Produces({ "text/csv" })
  @Path("/{queryname}/export/csv/{format}")
  public Response getQueryCsvExport(
      @PathParam("queryname") String queryName,
      @PathParam("format") String format) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/export/csv/" + format + "\tGET");
    }
    try {
      byte[] doc = olapQueryService.getExport(queryName, "csv", format);
      String name = SaikuProperties.WEBEXPORTCSVNAME;
      return Response.ok(doc, MediaType.APPLICATION_OCTET_STREAM).header(
          "content-disposition",
          "attachment; filename = " + name + ".csv").header(
          "content-length", doc.length).build();
    } catch (Exception e) {
      LOG.error("Cannot get csv for query (" + queryName + ")", e);
      return Response.serverError().build();
    }
  }


  @POST
  @Produces({ "application/pdf" })
  @Path("/{queryname}/export/pdf")
  public Response exportPdfWithChart(
      @PathParam("queryname") String queryName,
      @PathParam("svg") @DefaultValue("") String svg) {
    return exportPdfWithChartAndFormat(queryName, null, svg);
  }

  @GET
  @Produces({ "application/pdf" })
  @Path("/{queryname}/export/pdf")
  public Response exportPdf(@PathParam("queryname") String queryName) {
    return exportPdfWithChartAndFormat(queryName, null, null);
  }

  @GET
  @Produces({ "application/pdf" })
  @Path("/{queryname}/export/pdf/{format}")
  public Response exportPdfWithFormat(
      @PathParam("queryname") String queryName,
      @PathParam("format") String format) {
    return exportPdfWithChartAndFormat(queryName, format, null);
  }

  @POST
  @Produces({ "application/pdf" })
  @Path("/{queryname}/export/pdf/{format}")
  public Response exportPdfWithChartAndFormat(
      @PathParam("queryname") String queryName,
      @PathParam("format") String format,
      @FormParam("svg") @DefaultValue("") String svg) {

    try {
      PdfReport pdf = new PdfReport();
      CellDataSet cs = null;
      if (StringUtils.isNotBlank(format)) {
        cs = olapQueryService.execute(queryName, format);
      } else {
        cs = olapQueryService.execute(queryName);
      }

      byte[] doc = pdf.pdf(cs, svg);
      return Response.ok(doc).type("application/pdf").header(
          "content-disposition",
          "attachment; filename = export.pdf").header(
          "content-length", doc.length).build();
    } catch (Exception e) {
      LOG.error("Error exporting query to  PDF", e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }

  @DELETE
  @Path("/{queryname}/result")
  public Status cancel(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/result\tDELETE");
    }
    try {

      olapQueryService.cancel(queryName);
      return Response.Status.OK;
    } catch (Exception e) {
      LOG.error("Cannot execute query (" + queryName + ")", e);
      return Response.Status.INTERNAL_SERVER_ERROR;
    }
  }

  @GET
  @Produces({ "application/json" })
  @Path("/{queryname}/result")
  public QueryResult execute(@PathParam("queryname") String queryName,
                             @QueryParam("limit") @DefaultValue("0") int limit) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/result\tGET");
    }
    try {

      CellDataSet cs = olapQueryService.execute(queryName);
      return RestUtil.convert(cs, limit);
    } catch (Exception e) {
      LOG.error("Cannot execute query (" + queryName + ")", e);
      String error = ExceptionUtils.getRootCauseMessage(e);
      return new QueryResult(error);
    }
  }

  @POST
  @Produces({ "application/json" })
  @Path("/{queryname}/result/{format}")
  public QueryResult executeMdx(
      @PathParam("queryname") String queryName,
      @PathParam("format") String formatter,
      @FormParam("mdx") String mdx,
      @FormParam("limit") @DefaultValue("0") int limit) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/result" + formatter + "\tPOST");
    }
    try {
      ICellSetFormatter icf;
      formatter = formatter == null ? "" : formatter.toLowerCase();
      if (formatter.equals("flat")) {
        icf = new CellSetFormatter();
      } else if (formatter.equals("hierarchical")) {
        icf = new HierarchicalCellSetFormatter();
      } else if (formatter.equals("flattened")) {
        icf = new FlattenedCellSetFormatter();
      } else {
        icf = new FlattenedCellSetFormatter();
      }

      olapQueryService.qm2mdx(queryName);

      if (olapQueryService.isMdxDrillthrough(queryName, mdx)) {
        Long start = (new Date()).getTime();
        ResultSet rs = olapQueryService.drillthrough(queryName, mdx);
        QueryResult rsc = RestUtil.convert(rs);
        Long runtime = (new Date()).getTime() - start;
        rsc.setRuntime(runtime.intValue());
        return rsc;
      }
      CellDataSet cs = olapQueryService.executeMdx(queryName, mdx, icf);
      return RestUtil.convert(cs, limit);
    } catch (Exception e) {
      LOG.error("Cannot execute query (" + queryName + ") using mdx:\n" + mdx, e);
      String error = ExceptionUtils.getRootCauseMessage(e);
      return new QueryResult(error);
    }
  }


  @POST
  @Produces({ "application/json" })
  @Path("/{queryname}/result")
  public QueryResult executeMdx(
      @PathParam("queryname") String queryName,
      @FormParam("mdx") String mdx,
      @FormParam("limit") @DefaultValue("0") int limit) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/result\tPOST\t" + mdx);
    }
    try {
      return executeMdx(queryName, null, mdx, limit);
    } catch (Exception e) {
      LOG.error("Cannot execute query (" + queryName + ") using mdx:\n" + mdx, e);
      String error = ExceptionUtils.getRootCauseMessage(e);
      return new QueryResult(error);
    }
  }

  @GET
  @Produces({ "application/json" })
  @Path("/{queryname}/result/metadata/dimensions/{dimension}/hierarchies/{hierarchy}/levels/{level}")
  public List<SimpleCubeElement> getLevelMembers(
      @PathParam("queryname") String queryName,
      @PathParam("dimension") String dimensionName,
      @PathParam("hierarchy") String hierarchyName,
      @PathParam("level") String levelName,
      @QueryParam("result") @DefaultValue("true") boolean result,
      @QueryParam("search") String searchString,
      @QueryParam("searchlimit") @DefaultValue("-1") int searchLimit) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t"
                + "\t/query/" + queryName + "/result/metadata/dimensions/" + dimensionName
                + "/hierarchies/" + hierarchyName + "/levels/" + levelName + "\tGET");
    }
    try {
      List<SimpleCubeElement> ms = olapQueryService
          .getResultMetadataMembers(queryName, result, dimensionName, hierarchyName, levelName, searchString,
              searchLimit);
      return ms;
    } catch (Exception e) {
      LOG.error("Cannot execute query (" + queryName + ")", e);
      String error = ExceptionUtils.getRootCauseMessage(e);
      throw new WebApplicationException(Response.serverError().entity(error).build());
    }
  }

  @POST
  @Produces({ "application/json" })
  @Path("/{queryname}/qm2mdx")
  public SaikuQuery transformQm2Mdx(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/qm2mdx\tPOST\t");
    }
    try {
      olapQueryService.qm2mdx(queryName);
      return olapQueryService.getQuery(queryName);
    } catch (Exception e) {
      LOG.error("Cannot transform Qm2Mdx query (" + queryName + ")", e);
    }
    return null;
  }

  @GET
  @Produces({ "application/json" })
  @Path("/{queryname}/explain")
  public QueryResult getExplainPlan(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/explain\tGET");
    }
    QueryResult rsc;
    ResultSet rs = null;
    try {
      Long start = (new Date()).getTime();
      rs = olapQueryService.explain(queryName);
      rsc = RestUtil.convert(rs);
      Long runtime = (new Date()).getTime() - start;
      rsc.setRuntime(runtime.intValue());

    } catch (Exception e) {
      LOG.error("Cannot get explain plan for query (" + queryName + ")", e);
      String error = ExceptionUtils.getRootCauseMessage(e);
      rsc = new QueryResult(error);

    }
    // no need to close resultset, its an EmptyResultset
    return rsc;

  }

  @GET
  @Produces({ "application/json" })
  @Path("/{queryname}/drillthrough")
  public QueryResult drillthrough(
      @PathParam("queryname") String queryName,
      @QueryParam("maxrows") @DefaultValue("100") Integer maxrows,
      @QueryParam("position") String position,
      @QueryParam("returns") String returns) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/drillthrough\tGET");
    }
    QueryResult rsc;
    ResultSet rs = null;
    try {
      Long start = (new Date()).getTime();
      if (position == null) {
        rs = olapQueryService.drillthrough(queryName, maxrows, returns);
      } else {
        String[] positions = position.split(":");
        List<Integer> cellPosition = new ArrayList<Integer>();

        for (String p : positions) {
          Integer pInt = Integer.parseInt(p);
          cellPosition.add(pInt);
        }

        rs = olapQueryService.drillthrough(queryName, cellPosition, maxrows, returns);
      }
      rsc = RestUtil.convert(rs);
      Long runtime = (new Date()).getTime() - start;
      rsc.setRuntime(runtime.intValue());

    } catch (Exception e) {
      LOG.error("Cannot execute query (" + queryName + ")", e);
      String error = ExceptionUtils.getRootCauseMessage(e);
      rsc = new QueryResult(error);

    } finally {
      if (rs != null) {
        Statement statement = null;
        Connection con = null;
        try {
          statement = rs.getStatement();
          con = rs.getStatement().getConnection();
        } catch (Exception e) {
          throw new SaikuServiceException(e);
        } finally {
          try {
            rs.close();
            if (statement != null) {
              statement.close();
            }
          } catch (Exception ee) {
            LOG.error("Could not close statement", ee);
          }


          rs = null;
        }
      }
    }
    return rsc;

  }


  @GET
  @Produces({ "text/csv" })
  @Path("/{queryname}/drillthrough/export/csv")
  public Response getDrillthroughExport(
      @PathParam("queryname") String queryName,
      @QueryParam("maxrows") @DefaultValue("100") Integer maxrows,
      @QueryParam("position") String position,
      @QueryParam("returns") String returns) {
    if (LOG.isDebugEnabled()) {
      LOG.debug(
          "TRACK\t" + "\t/query/" + queryName + "/drillthrough/export/csv (maxrows:" + maxrows + " position" + position
          + ")\tGET");
    }
    ResultSet rs = null;

    try {
      if (position == null) {
        rs = olapQueryService.drillthrough(queryName, maxrows, returns);
      } else {
        String[] positions = position.split(":");
        List<Integer> cellPosition = new ArrayList<Integer>();

        for (String p : positions) {
          Integer pInt = Integer.parseInt(p);
          cellPosition.add(pInt);
        }

        rs = olapQueryService.drillthrough(queryName, cellPosition, maxrows, returns);
      }
      byte[] doc = olapQueryService.exportResultSetCsv(rs);
      String name = SaikuProperties.WEBEXPORTCSVNAME;
      return Response.ok(doc, MediaType.APPLICATION_OCTET_STREAM).header(
          "content-disposition",
          "attachment; filename = " + name + "-drillthrough.csv").header(
          "content-length", doc.length).build();


    } catch (Exception e) {
      LOG.error("Cannot export drillthrough query (" + queryName + ")", e);
      return Response.serverError().build();
    } finally {
      if (rs != null) {
        try {
          Statement statement = rs.getStatement();
          statement.close();
          rs.close();
        } catch (SQLException e) {
          throw new SaikuServiceException(e);
        } finally {
          rs = null;
        }
      }
    }


  }

  @GET
  @Produces({ "application/json" })
  @Path("/{queryname}/result/{format}")
  public QueryResult execute(
      @PathParam("queryname") String queryName,
      @PathParam("format") String formatter,
      @QueryParam("limit") @DefaultValue("0") int limit) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/result" + formatter + "\tGET");
    }
    try {
      CellDataSet cs = olapQueryService.execute(queryName, formatter);
      return RestUtil.convert(cs, limit);
    } catch (Exception e) {
      LOG.error("Cannot execute query (" + queryName + ")", e);
      String error = ExceptionUtils.getRootCauseMessage(e);
      return new QueryResult(error);
    }
  }


  /**
   * Return a list of dimensions for an axis in a query.
   *
   * @param queryName the name of the query.
   * @param axisName  the name of the axis.
   * @return a list of available dimensions.
   * @see DimensionRestPojo
   */
  @GET
  @Produces({ "application/json" })
  @Path("/{queryname}/axis/{axis}")
  public List<SaikuDimensionSelection> getAxisInfo(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "\tGET");
    }
    return olapQueryService.getAxisSelection(queryName, axisName);
  }

  /**
   * Remove all dimensions and selections on an axis
   *
   * @param queryName the name of the query.
   * @param axisName  the name of the axis.
   */
  @DELETE
  @Produces({ "application/json" })
  @Path("/{queryname}/axis/{axis}")
  public Response clearAxis(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName) {
    try {
      if (LOG.isDebugEnabled()) {
        LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "\tDELETE");
      }
      axisName = StringUtils.isNotBlank(axisName) ? axisName.toUpperCase() : null;
      if (axisName != null) {
        IQuery query = olapQueryService.clearAxis(queryName, axisName);
        return Response.ok().entity(ObjectUtil.convert(query)).build();

      }
      throw new Exception("Clear Axis: Axis name cannot be null");
    } catch (Exception e) {
      LOG.error("Cannot clear axis for query (" + queryName + ")", e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }

  @DELETE
  @Produces({ "application/json" })
  @Path("/{queryname}/axis/")
  public void clearAllAxisSelections(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis\tDELETE");
    }
    olapQueryService.resetQuery(queryName);
  }

  @PUT
  @Produces({ "application/json" })
  @Path("/{queryname}/swapaxes")
  public SaikuQuery swapAxes(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/swapaxes\tPUT");
    }
    IQuery query = olapQueryService.swapAxes(queryName);
    return ObjectUtil.convert(query);
  }

  @POST
  @Produces({ "application/json" })
  @Path("/{queryname}/cell/{position}/{value}")
  public Status setCell(@PathParam("queryname") String queryName,
                        @PathParam("position") String position,
                        @PathParam("value") String value) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/cell/" + position + "/" + value + "\tGET");
    }
    String[] positions = position.split(":");
    List<Integer> cellPosition = new ArrayList<Integer>();

    for (String p : positions) {
      Integer pInt = Integer.parseInt(p);
      cellPosition.add(pInt);
    }

    olapQueryService.setCellValue(queryName, cellPosition, value);
    return Status.OK;

  }

  /**
   * Return a dimension and its selections for an axis in a query.
   *
   * @param queryName the name of the query.
   * @param axis      the name of the axis.
   * @param dimension the name of the axis.
   * @return a list of available dimensions.
   * @see DimensionRestPojo
   */
  @GET
  @Produces({ "application/json" })
  @Path("/{queryname}/axis/{axis}/dimension/{dimension}")
  public SaikuDimensionSelection getAxisDimensionInfo(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axis,
      @PathParam("dimension") String dimension) {
    try {
      if (LOG.isDebugEnabled()) {
        LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axis + "/dimension/" + dimension + "\tGET");
      }
      return olapQueryService.getAxisDimensionSelections(queryName, axis, dimension);
    } catch (Exception e) {
      LOG.error("Cannot decode dimension " + dimension + " for query (" + queryName + ")", e);
      return olapQueryService.getAxisDimensionSelections(queryName, axis, dimension);
    }
  }

  /**
   * Move a dimension from one axis to another.
   *
   * @param queryName     the name of the query.
   * @param axisName      the name of the axis.
   * @param dimensionName the name of the dimension.
   * @return HTTP 200 or HTTP 500.
   * @see Status
   */
  @POST
  @Path("/{queryname}/axis/{axis}/dimension/{dimension}")
  public Response moveDimension(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("dimension") String dimensionName,
      @FormParam("position") @DefaultValue("-1") int position) {
    try {
      if (LOG.isDebugEnabled()) {
        LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/dimension/" + dimensionName + "\tPOST");
      }
      olapQueryService.moveDimension(queryName, axisName, dimensionName, position);
      return Response.ok().build();
    } catch (Exception e) {
      LOG.error("Cannot move dimension " + dimensionName + " for query (" + queryName + ")", e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }

  /**
   * Delete a dimension.
   *
   * @return
   */
  @DELETE
  @Path("/{queryname}/axis/{axis}/dimension/{dimension}")
  public Response deleteDimension(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("dimension") String dimensionName) {
    try {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/dimension/" + dimensionName + "\tDELETE");
      }
      olapQueryService.removeDimension(queryName, axisName, dimensionName);
      return Response.ok().build();
    } catch (Exception e) {
      LOG.error("Cannot remove dimension " + dimensionName + " for query (" + queryName + ")", e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }

  @PUT
  @Consumes("application/x-www-form-urlencoded")
  @Path("/{queryname}/zoomin")
  public SaikuQuery zoomIn(
      @PathParam("queryname") String queryName,
      @FormParam("selections") String positionListString) {
    try {

      if (LOG.isDebugEnabled()) {
        LOG.debug("TRACK\t" + "\t/query/" + queryName + "/zoomIn\tPUT");
      }
      List<List<Integer>> realPositions = new ArrayList<List<Integer>>();
      if (StringUtils.isNotBlank(positionListString)) {
        ObjectMapper mapper = new ObjectMapper();
        String[] positions = mapper.readValue(positionListString, TypeFactory.arrayType(String.class));
        if (positions != null && positions.length > 0) {
          for (String position : positions) {
            String[] rPos = position.split(":");
            List<Integer> cellPosition = new ArrayList<Integer>();

            for (String p : rPos) {
              Integer pInt = Integer.parseInt(p);
              cellPosition.add(pInt);
            }
            realPositions.add(cellPosition);
          }
        }
      }
      IQuery query = olapQueryService.zoomIn(queryName, realPositions);
      return ObjectUtil.convert(query);

    } catch (Exception e) {
      LOG.error("Cannot updates selections for query (" + queryName + ")", e);
      throw new WebApplicationException(e);
    }
  }

  @PUT
  @Consumes("application/x-www-form-urlencoded")
  @Path("/{queryname}/axis/{axis}/dimension/{dimension}/")
  public Response updateSelections(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("dimension") String dimensionName,
      @FormParam("selections") String selectionJSON) {
    try {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/dimension/" + dimensionName + "\tPUT\t");
      }

      if (selectionJSON != null) {
        ObjectMapper mapper = new ObjectMapper();
        List<SelectionRestObject> selections =
            mapper.readValue(selectionJSON, TypeFactory.collectionType(ArrayList.class, SelectionRestObject.class));

        // remove stuff first, then add, removing removes all selections for that level first
        for (SelectionRestObject selection : selections) {
          if (selection.getType() != null && "member".equals(selection.getType().toLowerCase())) {
            if (selection.getAction() != null && "delete".equals(selection.getAction().toLowerCase())) {
              olapQueryService.removeMember(queryName, dimensionName, selection.getUniquename(), "MEMBER");
            }
          }
          if (selection.getType() != null && "level".equals(selection.getType().toLowerCase())) {
            if (selection.getAction() != null && "delete".equals(selection.getAction().toLowerCase())) {
              olapQueryService
                  .removeLevel(queryName, dimensionName, selection.getHierarchy(), selection.getUniquename());
            }
          }
        }
        for (SelectionRestObject selection : selections) {
          if (selection.getType() != null && "member".equals(selection.getType().toLowerCase())) {
            if (selection.getAction() != null && "add".equals(selection.getAction().toLowerCase())) {
              olapQueryService.includeMember(queryName, dimensionName, selection.getUniquename(), "MEMBER",
                  selection.getTotalsFunction(), -1);
            }
          }
          if (selection.getType() != null && "level".equals(selection.getType().toLowerCase())) {
            if (selection.getAction() != null && "add".equals(selection.getAction().toLowerCase())) {
              olapQueryService
                  .includeLevel(queryName, dimensionName, selection.getHierarchy(), selection.getUniquename(),
                      selection.getTotalsFunction());
            }
          }
        }
        SaikuDimensionSelection dimsels = getAxisDimensionInfo(queryName, axisName, dimensionName);
        if (dimsels != null && dimsels.getSelections().size() == 0) {
          moveDimension(queryName, "UNUSED", dimensionName, -1);
        }
        return Response.ok().build();
      }
      throw new Exception("Form did not contain 'selections' parameter");
    } catch (Exception e) {
      LOG.error("Cannot updates selections for query (" + queryName + ")", e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }

  }


  @DELETE
  @Consumes("application/x-www-form-urlencoded")
  @Path("/{queryname}/axis/{axis}/dimension/{dimension}/member/")
  public Response removeMembers(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("dimension") String dimensionName,
      MultivaluedMap<String, String> formParams) {
    try {
      if (LOG.isDebugEnabled()) {
        LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/dimension/" + dimensionName + "\tPUT");
      }
      if (formParams.containsKey("selections")) {
        LinkedList<String> sels = (LinkedList<String>) formParams.get("selections");
        String selectionJSON = (String) sels.getFirst();
        ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
        List<SelectionRestObject> selections =
            mapper.readValue(selectionJSON, TypeFactory.collectionType(ArrayList.class, SelectionRestObject.class));
        for (SelectionRestObject member : selections) {
          removeMember("MEMBER", queryName, axisName, dimensionName, member.getUniquename());
        }
        return Response.ok().build();
      }
      throw new Exception("Form did not contain 'selections' parameter");
    } catch (Exception e) {
      LOG.error("Cannot updates selections for query (" + queryName + ")", e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }

  /**
   * Move a member.
   *
   * @return
   */
  @POST
  @Path("/{queryname}/axis/{axis}/dimension/{dimension}/member/{member}")
  public Response includeMember(
      @FormParam("selection") @DefaultValue("MEMBER") String selectionType,
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("dimension") String dimensionName,
      @PathParam("member") String uniqueMemberName,
      @FormParam("position") @DefaultValue("-1") int position,
      @FormParam("memberposition") @DefaultValue("-1") int memberposition) {
    try {
      if (LOG.isDebugEnabled()) {
        LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/dimension/" + dimensionName + "/member/"
                  + uniqueMemberName + "\tPOST");
      }
      olapQueryService.moveDimension(queryName, axisName, dimensionName, position);

      boolean ret =
          olapQueryService.includeMember(queryName, dimensionName, uniqueMemberName, selectionType, memberposition);
      if (ret) {
        return Response.ok().status(Status.CREATED).build();
      } else {
        throw new Exception("Couldn't include member " + dimensionName);

      }
    } catch (Exception e) {
      LOG.error("Cannot include member " + dimensionName + " for query (" + queryName + ")", e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }

  @DELETE
  @Path("/{queryname}/axis/{axis}/dimension/{dimension}/member/{member}")
  public Response removeMember(
      @FormParam("selection") @DefaultValue("MEMBER") String selectionType,
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("dimension") String dimensionName,
      @PathParam("member") String uniqueMemberName) {

    try {
      if (LOG.isDebugEnabled()) {
        LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/dimension/" + dimensionName + "/member/"
                  + uniqueMemberName + "\tDELETE");
      }
      boolean ret = olapQueryService.removeMember(queryName, dimensionName, uniqueMemberName, selectionType);
      if (ret) {
        SaikuDimensionSelection dimsels =
            olapQueryService.getAxisDimensionSelections(queryName, axisName, dimensionName);
        if (dimsels != null && dimsels.getSelections().size() == 0) {
          olapQueryService.moveDimension(queryName, "UNUSED", dimensionName, -1);
        }
        return Response.ok().build();
      } else {
        throw new Exception("Cannot remove member " + dimensionName + " for query (" + queryName + ")");
      }
    } catch (Exception e) {
      LOG.error("Cannot remove member " + dimensionName + " for query (" + queryName + ")", e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }

  @PUT
  @Path("/{queryname}/axis/{axis}/dimension/{dimension}/children")
  public Response includeChildren(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("dimension") String dimensionName,
      @FormParam("member") String uniqueMemberName) {

    try {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/dimension/" + dimensionName + "/children/"
            + uniqueMemberName + "\tPOST");
      }

      boolean ret = olapQueryService.includeChildren(queryName, dimensionName, uniqueMemberName);
      if (ret) {
        return Response.ok().status(Status.CREATED).build();
      } else {
        throw new Exception("Couldn't include children for " + uniqueMemberName);

      }
    } catch (Exception e) {
      LOG.error("Cannot include children for " + dimensionName + " for query (" + queryName + ")", e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }

  @DELETE
  @Path("/{queryname}/axis/{axis}/dimension/{dimension}/children")
  public Response removeChildren(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("dimension") String dimensionName,
      @FormParam("member") String uniqueMemberName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/dimension/" + dimensionName + "/children/"
                + uniqueMemberName + "\tDELETE");
    }
    try {
      boolean ret = olapQueryService.removeChildren(queryName, dimensionName, uniqueMemberName);
      if (ret) {
        return Response.ok().status(Status.GONE).build();
      } else {
        throw new Exception("Couldn't remove children for " + uniqueMemberName);

      }
    } catch (Exception e) {
      LOG.error("Cannot remove children for " + dimensionName + " for query (" + queryName + ")", e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }


  @POST
  @Path("/{queryname}/axis/{axis}/dimension/{dimension}/hierarchy/{hierarchy}/{level}")
  public Response includeLevel(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("dimension") String dimensionName,
      @PathParam("hierarchy") String uniqueHierarchyName,
      @PathParam("level") String uniqueLevelName,
      @FormParam("position") @DefaultValue("-1") int position) {

    try {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/dimension/" + dimensionName + "/hierarchy/"
            + uniqueHierarchyName + "/" + uniqueLevelName + "\tPOST");
      }
      olapQueryService.moveDimension(queryName, axisName, dimensionName, position);
      boolean ret = olapQueryService.includeLevel(queryName, dimensionName, uniqueHierarchyName, uniqueLevelName);
      if (ret) {
        return Response.ok().status(Status.CREATED).build();
      } else {
        throw new Exception("Something went wrong including level: " + uniqueLevelName);
      }
    } catch (Exception e) {
      LOG.error("Cannot include level of hierarchy " + uniqueHierarchyName + " for query (" + queryName + ")", e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }

  @DELETE
  @Path("/{queryname}/axis/{axis}/dimension/{dimension}/hierarchy/{hierarchy}/{level}")
  public Response removeLevel(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("dimension") String dimensionName,
      @PathParam("hierarchy") String uniqueHierarchyName,
      @PathParam("level") String uniqueLevelName) {
    try {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/dimension/" + dimensionName + "/hierarchy/"
            + uniqueHierarchyName + "/" + uniqueLevelName + "\tDELETE");
      }
      boolean ret = olapQueryService.removeLevel(queryName, dimensionName, uniqueHierarchyName, uniqueLevelName);

      if (ret) {
        SaikuDimensionSelection dimsels =
            olapQueryService.getAxisDimensionSelections(queryName, axisName, dimensionName);
        if (dimsels != null && dimsels.getSelections().size() == 0) {
          olapQueryService.moveDimension(queryName, "UNUSED", dimensionName, -1);
        }
        return Response.ok().build();
      } else {
        LOG.error("Cannot remove level of hierarchy " + uniqueHierarchyName + " for query (" + queryName + ")");
      }
      throw new Exception(
          "Something went wrong removing level: " + uniqueLevelName + " from " + uniqueHierarchyName + " for query ("
          + queryName + ")");
    } catch (Exception e) {
      LOG.error("Cannot include level of hierarchy " + uniqueHierarchyName + " for query (" + queryName + ")", e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }


  @PUT
  @Produces({ "application/json" })
  @Path("/{queryname}/tag")
  public Status activateTag(
      @PathParam("queryname") String queryName,
      @FormParam("tag") String tagJSON) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/tags\tPUT");
    }
    try {
      ObjectMapper mapper = new ObjectMapper();
      mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
      SaikuTag tag = mapper.readValue(tagJSON, SaikuTag.class);

      olapQueryService.setTag(queryName, tag);
      return Status.OK;
    } catch (Exception e) {
      LOG.error("Cannot add tag " + tagJSON + " for query (" + queryName + ")", e);
    }
    return Status.INTERNAL_SERVER_ERROR;

  }

  @DELETE
  @Produces({ "application/json" })
  @Path("/{queryname}/tag")
  public Status deactivateTag(
      @PathParam("queryname") String queryName,
      @PathParam("tagname") String tagName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/tags\tPUT");
    }
    try {
      olapQueryService.disableTag(queryName);
      return Status.OK;
    } catch (Exception e) {
      LOG.error("Cannot remove tag " + tagName + " for query (" + queryName + ")", e);
    }
    return Status.INTERNAL_SERVER_ERROR;

  }


  @GET
  @Produces({ "application/json" })
  @Path("/{queryname}/filter")
  public Response getFilter(
      @PathParam("queryname") String queryName,
      @QueryParam("dimension") String dimension,
      @QueryParam("hierarchy") String hierarchy,
      @QueryParam("level") String level) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/filter\tGET");
    }
    try {
      SaikuFilter t = olapQueryService.getFilter(queryName, "new", dimension, hierarchy, level);
      return Response.ok(t).build();
    } catch (Exception e) {
      LOG.error("Cannot get filter for query (" + queryName + ")", e);
      String error = ExceptionUtils.getRootCauseMessage(e);
      return Response.serverError().entity(error).build();
    }
  }


  @PUT
  @Produces({ "application/json" })
  @Path("/{queryname}/filter")
  public Response activateFilter(
      @PathParam("queryname") String queryName,
      @FormParam("filter") String filterJSON) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/tags\tPUT");
    }
    try {
      ObjectMapper mapper = new ObjectMapper();
      mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
      SaikuFilter filter = mapper.readValue(filterJSON, SaikuFilter.class);
      SaikuQuery sq = olapQueryService.applyFilter(queryName, filter);
      return Response.ok(sq).build();
    } catch (Exception e) {
      LOG.error("Cannot activate filter for query (" + queryName + "), json:" + filterJSON, e);
      String error = ExceptionUtils.getRootCauseMessage(e);
      return Response.serverError().entity(error).build();
    }

  }

  @DELETE
  @Produces({ "application/json" })
  @Path("/{queryname}/filter")
  public Response deactivateFilter(@PathParam("queryname") String queryName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/tags\tPUT");
    }
    try {
      SaikuQuery sq = olapQueryService.removeFilter(queryName);
      return Response.ok(sq).build();
    } catch (Exception e) {
      LOG.error("Cannot remove filter for query (" + queryName + ")", e);
      String error = ExceptionUtils.getRootCauseMessage(e);
      return Response.serverError().entity(error).build();
    }
  }

  @POST
  @Produces({ "application/json" })
  @Path("/{queryname}/axis/{axis}/sort/{sortorder}/{sortliteral}")
  public void sortAxis(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("sortorder") String sortOrder,
      @PathParam("sortliteral") String sortLiteral) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/sort/" + sortOrder + "/" + sortLiteral
                + "\tPOST");
    }
    olapQueryService.sortAxis(queryName, axisName, sortLiteral, sortOrder);
  }

  @PUT
  @Produces({ "application/json" })
  @Path("/{queryname}/axis/{axis}/show_totals/{function}")
  public SaikuQuery showGrandTotals(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("function") String functionName
  ) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/show_totals/" + functionName + "\tPUT");
    }
    IQuery query = olapQueryService.showGrandTotals(queryName, axisName, functionName);
    return ObjectUtil.convert(query);
  }

  @DELETE
  @Produces({ "application/json" })
  @Path("/{queryname}/axis/{axis}/sort")
  public void clearSortAxis(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/sort/\tDELETE");
    }
    olapQueryService.clearSort(queryName, axisName);
  }

  @POST
  @Produces({ "application/json" })
  @Path("/{queryname}/axis/{axis}/limit/{limitfunction}")
  public void limitAxis(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @PathParam("limitfunction") String limitfunction,
      @FormParam("n") String n,
      @FormParam("sortliteral") String sortLiteral) {
    if (LOG.isDebugEnabled()) {
      LOG.debug(
          "TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/limit/" + limitfunction + "(" + n + ", sort:"
          + sortLiteral + "\tPOST");
    }
    olapQueryService.limitAxis(queryName, axisName, limitfunction, n, sortLiteral);
  }

  @DELETE
  @Produces({ "application/json" })
  @Path("/{queryname}/axis/{axis}/limit")
  public void clearLimitAxis(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/limit/\tDELETE");
    }
    olapQueryService.clearLimit(queryName, axisName);
  }

  @POST
  @Produces({ "application/json" })
  @Path("/{queryname}/axis/{axis}/filter")
  public void filterAxis(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName,
      @FormParam("filterCondition") String filterCondition) {
    if (LOG.isDebugEnabled()) {
      LOG.debug(
          "TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/filter/ (" + filterCondition + " )\tPOST");
    }
    olapQueryService.filterAxis(queryName, axisName, filterCondition);
  }

  @DELETE
  @Produces({ "application/json" })
  @Path("/{queryname}/axis/{axis}/filter")
  public void clearFilter(
      @PathParam("queryname") String queryName,
      @PathParam("axis") String axisName) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("TRACK\t" + "\t/query/" + queryName + "/axis/" + axisName + "/filter/\tDELETE");
    }
    olapQueryService.clearFilter(queryName, axisName);
  }

}
TOP

Related Classes of org.saiku.web.rest.resources.QueryResource

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.