Package com.belladati.sdk.impl

Source Code of com.belladati.sdk.impl.BellaDatiServiceImpl$ReportList

package com.belladati.sdk.impl;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.reflect.Field;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import org.apache.http.client.utils.URIBuilder;
import org.apache.http.message.BasicNameValuePair;

import com.belladati.sdk.BellaDatiService;
import com.belladati.sdk.dashboard.Dashboard;
import com.belladati.sdk.dashboard.DashboardInfo;
import com.belladati.sdk.exception.InternalConfigurationException;
import com.belladati.sdk.filter.Filter;
import com.belladati.sdk.impl.AttributeValueImpl.InvalidAttributeValueException;
import com.belladati.sdk.impl.TableViewImpl.TableImpl;
import com.belladati.sdk.report.AttributeValue;
import com.belladati.sdk.report.Comment;
import com.belladati.sdk.report.Report;
import com.belladati.sdk.report.ReportInfo;
import com.belladati.sdk.user.User;
import com.belladati.sdk.util.CachedList;
import com.belladati.sdk.util.PaginatedIdList;
import com.belladati.sdk.util.PaginatedList;
import com.belladati.sdk.view.ViewType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

class BellaDatiServiceImpl implements BellaDatiService {

  /** The serialVersionUID */
  private static final long serialVersionUID = 9054278401541000710L;

  final BellaDatiClient client;
  final TokenHolder tokenHolder;

  private final transient PaginatedIdList<DashboardInfo> dashboardList = new DashboardList();

  private final transient PaginatedIdList<ReportInfo> reportList = new ReportList();

  private final transient Map<String, PaginatedList<Comment>> commentLists = Collections
    .synchronizedMap(new HashMap<String, PaginatedList<Comment>>());

  private final transient Map<String, Map<String, CachedListImpl<AttributeValue>>> reportAttributeValues = new HashMap<String, Map<String, CachedListImpl<AttributeValue>>>();

  BellaDatiServiceImpl(BellaDatiClient client, TokenHolder tokenHolder) {
    this.client = client;
    this.tokenHolder = tokenHolder;
  }

  @Override
  public PaginatedIdList<DashboardInfo> getDashboardInfo() {
    return dashboardList;
  }

  @Override
  public Dashboard loadDashboard(String id) {
    return new DashboardImpl(this, loadJson("api/dashboards/" + id));
  }

  @Override
  public Object loadDashboardThumbnail(String id) throws IOException {
    return loadImage("api/dashboards/" + id + "/thumbnail");
  }

  @Override
  public PaginatedIdList<ReportInfo> getReportInfo() {
    return reportList;
  }

  @Override
  public Report loadReport(String id) {
    return new ReportImpl(this, loadJson("api/reports/" + id));
  }

  @Override
  public Object loadReportThumbnail(String reportId) throws IOException {
    return loadImage("api/reports/" + reportId + "/thumbnail");
  }

  /**
   * Convenience method for other parts of the implementation to easily load
   * data through the API.
   *
   * @param uri URI to contact
   * @return the resulting JSON response
   */
  JsonNode loadJson(String uri) {
    return client.getJson(uri, tokenHolder);
  }

  /**
   * Loads an image from the given URI.
   *
   * @param relativeUrl the URI to load from
   * @return the image from the server
   * @throws IOException if the image cannot be loaded
   */
  private Object loadImage(String relativeUrl) throws IOException {
    ByteArrayInputStream bais = new ByteArrayInputStream(client.get(relativeUrl, tokenHolder));
    try {
      BufferedImage image = ImageIO.read(bais);
      if (image == null) {
        throw new IOException("Could not load image");
      }
      return image;
    } finally {
      bais.close();
    }
  }

  @Override
  public PaginatedList<Comment> getReportComments(String reportId) {
    PaginatedList<Comment> existing = commentLists.get(reportId);
    if (existing != null) {
      return existing;
    } else {
      synchronized (commentLists) {
        existing = commentLists.get(reportId);
        if (existing != null) {
          return existing;
        } else {
          PaginatedList<Comment> newList = new PaginatedListImpl<Comment>(this,
            "api/reports/" + reportId + "/comments", "comments") {
            @Override
            protected Comment parse(BellaDatiServiceImpl service, JsonNode node) {
              return new CommentImpl(service, node);
            }
          };
          commentLists.put(reportId, newList);
          return newList;
        }
      }
    }
  }

  @Override
  public void postComment(String reportId, String text) {
    client.post("api/reports/" + reportId + "/comments", tokenHolder,
      Collections.singletonList(new BasicNameValuePair("text", text)));
  }

  @Override
  public Object loadViewContent(String viewId, ViewType viewType, Filter<?>... filters) {
    return loadViewContent(viewId, viewType, Arrays.asList(filters));
  }

  @Override
  public Object loadViewContent(String viewId, ViewType viewType, Collection<Filter<?>> filters) {
    try {
      URIBuilder builder = new URIBuilder("api/reports/views/" + viewId + "/" + viewType.getUri());
      JsonNode json = loadJson(appendFilter(builder, filters).build().toString());
      if (viewType == ViewType.TABLE) {
        return new TableImpl(this, viewId, json, filters);
      }
      return json;
    } catch (URISyntaxException e) {
      throw new InternalConfigurationException(e);
    }
  }

  /**
   * Appends a filter parameter from the given filters to the URI builder.
   * Won't do anything if the filter collection is empty.
   *
   * @param builder the builder to append to
   * @param filters filters to append
   * @return the same builder, for chaining
   */
  URIBuilder appendFilter(URIBuilder builder, Collection<Filter<?>> filters) {
    if (filters.size() > 0) {
      ObjectNode filterNode = new ObjectMapper().createObjectNode();
      for (Filter<?> filter : filters) {
        filterNode.setAll(filter.toJson());
      }
      ObjectNode drilldownNode = new ObjectMapper().createObjectNode();
      drilldownNode.put("drilldown", filterNode);
      builder.addParameter("filter", drilldownNode.toString());
    }
    return builder;
  }

  @Override
  public synchronized CachedList<AttributeValue> getAttributeValues(String reportId, String attributeCode) {
    if (!reportAttributeValues.containsKey(reportId)) {
      // we don't have any values for this report yet, insert new map
      reportAttributeValues.put(reportId, new HashMap<String, CachedListImpl<AttributeValue>>());
    }

    Map<String, CachedListImpl<AttributeValue>> attributeValues = reportAttributeValues.get(reportId);

    CachedListImpl<AttributeValue> values = attributeValues.get(attributeCode);
    if (values == null) {
      // we don't have this attribute in our cache yet
      values = new CachedListImpl<AttributeValue>(this, "api/reports/" + reportId
        + "/filter/drilldownAttributeValues?code=" + attributeCode, "values") {
        @Override
        protected AttributeValue parse(BellaDatiServiceImpl service, JsonNode node) throws ParseException {
          try {
            return new AttributeValueImpl(node);
          } catch (InvalidAttributeValueException e) {
            throw new ParseException(node, e);
          }
        }
      };
      attributeValues.put(attributeCode, values);
    }
    return values;
  }

  @Override
  public User loadUser(String userId) {
    return new UserImpl(loadJson("api/users/" + userId));
  }

  @Override
  public Object loadUserImage(String userId) throws IOException {
    return loadImage("api/users/" + userId + "/image");
  }

  @Override
  public String toString() {
    return "BellaDati Service(server: " + client.getBaseUrl() + ", key: " + tokenHolder.getConsumerKey() + ", token: "
      + tokenHolder.getToken() + ")";
  }

  /** Deserialization. Sets up the element lists and maps as empty objects. */
  private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject();
    try {
      Field dashboardList = getClass().getDeclaredField("dashboardList");
      dashboardList.setAccessible(true);
      dashboardList.set(this, new DashboardList());

      Field reportList = getClass().getDeclaredField("reportList");
      reportList.setAccessible(true);
      reportList.set(this, new ReportList());

      Field commentLists = getClass().getDeclaredField("commentLists");
      commentLists.setAccessible(true);
      commentLists.set(this, Collections.synchronizedMap(new HashMap<String, PaginatedList<Comment>>()));

      Field reportAttributeValues = getClass().getDeclaredField("reportAttributeValues");
      reportAttributeValues.setAccessible(true);
      reportAttributeValues.set(this, new HashMap<String, Map<String, CachedListImpl<AttributeValue>>>());
    } catch (NoSuchFieldException e) {
      throw new InternalConfigurationException("Failed to set service fields", e);
    } catch (IllegalAccessException e) {
      throw new InternalConfigurationException("Failed to set service fields", e);
    } catch (SecurityException e) {
      throw new InternalConfigurationException("Failed to set service fields", e);
    } catch (IllegalArgumentException e) {
      throw new InternalConfigurationException("Failed to set service fields", e);
    }
  }

  /** Paginated list class for dashboards. */
  private class DashboardList extends PaginatedIdListImpl<DashboardInfo> {
    public DashboardList() {
      super(BellaDatiServiceImpl.this, "api/dashboards", "dashboards");
    }

    @Override
    protected DashboardInfo parse(BellaDatiServiceImpl service, JsonNode node) {
      return new DashboardInfoImpl(service, node);
    }
  }

  /** Paginated list class for reports. */
  private class ReportList extends PaginatedIdListImpl<ReportInfo> {
    public ReportList() {
      super(BellaDatiServiceImpl.this, "api/reports", "reports");
    }

    @Override
    protected ReportInfo parse(BellaDatiServiceImpl service, JsonNode node) {
      return new ReportInfoImpl(service, node);
    }
  }
}
TOP

Related Classes of com.belladati.sdk.impl.BellaDatiServiceImpl$ReportList

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.