Package org.saiku.web.rest.resources

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

/*
* 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.SaikuSelection.Type;
import org.saiku.olap.util.SaikuProperties;
import org.saiku.service.olap.OlapQueryService;
import org.saiku.service.util.KeyValue;
import org.saiku.service.util.exception.SaikuServiceException;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemManager;
import org.apache.commons.vfs.VFS;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.type.TypeFactory;
import org.olap4j.mdx.ParseTreeWriter;
import org.olap4j.mdx.SelectNode;
import org.olap4j.mdx.parser.impl.DefaultMdxParserImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.URLDecoder;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
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}/tags")
@XmlAccessorType(XmlAccessType.NONE)
public class BasicTagRepositoryResource {

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

  private OlapQueryService olapQueryService;

  private FileObject repo;

  public void setPath(String path) throws Exception {

    FileSystemManager fileSystemManager;
    try {
      if (!path.endsWith("" + File.separatorChar)) {
        path += File.separatorChar;
      }
      fileSystemManager = VFS.getManager();
      FileObject fileObject;
      fileObject = fileSystemManager.resolveFile(path);
      if (fileObject == null) {
        throw new IOException("File cannot be resolved: " + path);
      }
      if (!fileObject.exists()) {
        throw new IOException("File does not exist: " + path);
      }
      repo = fileObject;
    } catch (Exception e) {
      LOG.error("Error setting path: " + path, e);
    }

  }

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

  @GET
  @Path("/{cubeIdentifier}")
  @Produces({ "application/json" })
  public List<SaikuTag> getSavedTags(
      @PathParam("cubeIdentifier") String cubeIdentifier) {
    List<SaikuTag> allTags = new ArrayList<SaikuTag>();
    try {
      if (repo != null) {
        File[] files = new File(repo.getName().getPath()).listFiles();
        for (File file : files) {
          if (!file.isHidden()) {

            String filename = file.getName();
            if (filename.endsWith(".tag")) {
              filename = filename.substring(0, filename.length() - ".tag".length());
              if (filename.equals(cubeIdentifier)) {
                FileReader fi = new FileReader(file);
                BufferedReader br = new BufferedReader(fi);
                ObjectMapper om = new ObjectMapper();
                om.setVisibilityChecker(om.getVisibilityChecker().withFieldVisibility(Visibility.ANY));

                List<SaikuTag> tags = om.readValue(file, TypeFactory.collectionType(ArrayList.class, SaikuTag.class));
                allTags.addAll(tags);
              }
            }
          }
        }

      } else {
        throw new Exception("repo URL is null");
      }
    } catch (Exception e) {
      LOG.error(this.getClass().getName(), e);

    }
    Collections.sort(allTags);
    return allTags;
  }

  /**
   * Delete Query.
   *
   * @param queryName - The name of the query.
   * @return A GONE Status if the query was deleted, otherwise it will return a NOT FOUND Status code.
   */
  @DELETE
  @Produces({ "application/json" })
  @Path("/{cubeIdentifier}/{tagName}")
  public Status deleteTag(
      @PathParam("cubeIdentifier") String cubeIdentifier,
      @PathParam("tagName") String tagName) {
    try {
      if (repo != null) {
        List<SaikuTag> tags = getSavedTags(cubeIdentifier);
        List<SaikuTag> remove = new ArrayList<SaikuTag>();
        for (SaikuTag tag : tags) {
          if (tag.getName().equals(tagName)) {
            remove.add(tag);
          }
        }
        tags.removeAll(remove);
        ObjectMapper om = new ObjectMapper();
        om.setVisibilityChecker(om.getVisibilityChecker().withFieldVisibility(Visibility.ANY));

        String uri = repo.getName().getPath();
        if (!uri.endsWith("" + File.separatorChar)) {
          uri += File.separatorChar;
        }
        if (!cubeIdentifier.endsWith(".tag")) {
          cubeIdentifier += ".tag";
        }

        File tagFile = new File(uri + URLDecoder.decode(cubeIdentifier, "UTF-8"));
        if (tagFile.exists()) {
          tagFile.delete();
        } else {
          tagFile.createNewFile();
        }
        om.writeValue(tagFile, tags);
        return Status.GONE;

      }
      throw new Exception("Cannot delete tag :" + tagName);
    } catch (Exception e) {
      LOG.error("Cannot delete tag (" + tagName + ")", e);
      return Status.NOT_FOUND;
    }
  }

  @POST
  @Produces({ "application/json" })
  @Path("/{cubeIdentifier}/{tagname}")
  public SaikuTag saveTag(
      @PathParam("tagname") String tagName,
      @PathParam("cubeIdentifier") String cubeIdentifier,
      @FormParam("queryname") String queryName,
      @FormParam("positions") String positions) {
    try {
      List<List<Integer>> cellPositions = new ArrayList<List<Integer>>();
      for (String position : positions.split(",")) {
        String[] ps = position.split(":");
        List<Integer> cellPosition = new ArrayList<Integer>();

        for (String p : ps) {
          Integer pInt = Integer.parseInt(p);
          cellPosition.add(pInt);
        }
        cellPositions.add(cellPosition);
      }
      SaikuTag t = olapQueryService.createTag(queryName, tagName, cellPositions);

      if (repo != null) {
        List<SaikuTag> tags = getSavedTags(cubeIdentifier);
        if (!cubeIdentifier.endsWith(".tag")) {
          cubeIdentifier += ".tag";
        }
        List<SaikuTag> remove = new ArrayList<SaikuTag>();
        for (SaikuTag tag : tags) {
          if (tag.getName().equals(tagName)) {
            remove.add(tag);
          }
        }
        tags.removeAll(remove);

        tags.add(t);
        ObjectMapper om = new ObjectMapper();
        om.setVisibilityChecker(om.getVisibilityChecker().withFieldVisibility(Visibility.ANY));

        String uri = repo.getName().getPath();
        if (!uri.endsWith("" + File.separatorChar)) {
          uri += File.separatorChar;
        }
        File tagFile = new File(uri + URLDecoder.decode(cubeIdentifier, "UTF-8"));
        if (tagFile.exists()) {
          tagFile.delete();
        } else {
          tagFile.createNewFile();
        }
        om.writeValue(tagFile, tags);
        return t;
      }
    } catch (Exception e) {
      LOG.error("Cannot add tag " + tagName + " for query (" + queryName + ")", e);
    }
    return null;

  }

  @GET
  @Produces({ "application/json" })
  @Path("/{cubeIdentifier}/{tagName}")
  public SaikuTag getTag(
      @PathParam("cubeIdentifier") String cubeIdentifier,
      @PathParam("tagName") String tagName) {
    try {
      if (repo != null) {
        List<SaikuTag> tags = getSavedTags(cubeIdentifier);
        for (SaikuTag tag : tags) {
          if (tag.getName().equals(tagName)) {
            return tag;
          }
        }
      }
    } catch (Exception e) {
      LOG.error("Cannot get tag " + tagName + " for " + cubeIdentifier, e);
    }
    return null;
  }

  @GET
  @Produces({ "text/csv" })
  @Path("/{cubeIdentifier}/{tagName}/export/csv")
  public Response getDrillthroughExport(
      @PathParam("cubeIdentifier") String cubeIdentifier,
      @PathParam("tagName") String tagName,
      @QueryParam("maxrows") @DefaultValue("0") Integer maxrows,
      @QueryParam("returns") String returns,
      @QueryParam("connection") String connection,
      @QueryParam("catalog") String catalog,
      @QueryParam("schema") String schema,
      @QueryParam("cube") String cube,
      @QueryParam("additional") String additional
  ) {
    ResultSet rs = null;

    try {

      List<Integer> cellPosition = new ArrayList<Integer>();
      cellPosition.add(0);
      List<KeyValue<String, String>> additionalColumns = new ArrayList<KeyValue<String, String>>();
      if (additional != null) {
        for (String kvs : additional.split(",")) {
          String[] kv = kvs.split(":");
          if (kv.length == 2) {
            additionalColumns.add(new KeyValue<String, String>(kv[0], kv[1]));
          }
        }
      }

      SaikuTag tag = getTag(cubeIdentifier, tagName);
      if (tag != null) {
        String queryName = UUID.randomUUID().toString();
        SaikuCube saikuCube = new SaikuCube(connection, cube, cube, cube, catalog, schema);
        olapQueryService.createNewOlapQuery(queryName, saikuCube);
        SaikuQuery q = olapQueryService.simulateTag(queryName, tag);
        if (!cube.startsWith("[")) {
          cube = "[" + cube + "]";
        }
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        boolean first = true;
        for (SaikuTuple tuple : tag.getSaikuTuples()) {
          String mdx = null;
          for (SaikuMember member : tuple.getSaikuMembers()) {
            if (mdx == null) {
              mdx = "SELECT (" + member.getUniqueName();
            } else {
              mdx += ", " + member.getUniqueName();
            }
          }
          boolean where = true;
          if (tag.getSaikuDimensionSelections() != null) {
            for (SaikuDimensionSelection sdim : tag.getSaikuDimensionSelections()) {
              if (sdim.getSelections().size() > 1) {
                where = false;
              }
            }
          }
          if (where) {
            mdx += ") ON COLUMNS from " + cube;
            SelectNode sn = new DefaultMdxParserImpl().parseSelect(q.getMdx());
            final Writer writer = new StringWriter();
            sn.getFilterAxis().unparse(new ParseTreeWriter(new PrintWriter(writer)));
            if (StringUtils.isNotBlank(writer.toString())) {
              mdx += "\r\nWHERE " + writer.toString();
            }
            System.out.println("Executing... :" + mdx);
            olapQueryService.executeMdx(queryName, mdx);
            rs = olapQueryService.drillthrough(queryName, cellPosition, maxrows, returns);
            byte[] doc = olapQueryService.exportResultSetCsv(rs, ",", "\"", first, additionalColumns);
            first = false;
            outputStream.write(doc);
          } else {
            if (tag.getSaikuDimensionSelections() != null) {
              for (SaikuDimensionSelection sdim : tag.getSaikuDimensionSelections()) {
                for (SaikuSelection ss : sdim.getSelections()) {
                  if (ss.getType() == Type.MEMBER) {
                    String newmdx = mdx;
                    newmdx += "," + ss.getUniqueName() + ") ON COLUMNS from " + cube;
                    System.out.println("Executing... :" + newmdx);
                    olapQueryService.executeMdx(queryName, newmdx);
                    rs = olapQueryService.drillthrough(queryName, cellPosition, maxrows, returns);
                    byte[] doc = olapQueryService.exportResultSetCsv(rs, ",", "\"", first, additionalColumns);
                    first = false;
                    outputStream.write(doc);
                  }
                }
              }
            }
          }
        }


        byte[] csv = outputStream.toByteArray();

        String name = SaikuProperties.WEBEXPORTCSVNAME;
        return Response.ok(csv, MediaType.APPLICATION_OCTET_STREAM).header(
            "content-disposition",
            "attachment; filename = " + name + "-drillthrough.csv").header(
            "content-length", csv.length).build();
      }

    } catch (Exception e) {
      LOG.error("Cannot export drillthrough tag (" + tagName + ")", 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;
        }
      }
    }
    return Response.serverError().build();
  }


}
TOP

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

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.