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.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import org.apache.http.NameValuePair;
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.dataset.AttributeValue;
import com.belladati.sdk.dataset.DataSet;
import com.belladati.sdk.dataset.DataSetInfo;
import com.belladati.sdk.dataset.data.DataRow;
import com.belladati.sdk.dataset.data.DataTable;
import com.belladati.sdk.dataset.source.DataSource;
import com.belladati.sdk.dataset.source.DataSourceImport;
import com.belladati.sdk.dataset.source.DataSourcePendingImport;
import com.belladati.sdk.exception.InternalConfigurationException;
import com.belladati.sdk.exception.dataset.data.UnknownServerColumnException;
import com.belladati.sdk.exception.server.NotFoundException;
import com.belladati.sdk.exception.server.UnexpectedResponseException;
import com.belladati.sdk.filter.Filter;
import com.belladati.sdk.impl.AttributeValueImpl.InvalidAttributeValueException;
import com.belladati.sdk.impl.DataSourceImportImpl.InvalidDataSourceImportException;
import com.belladati.sdk.intervals.DateUnit;
import com.belladati.sdk.intervals.Interval;
import com.belladati.sdk.intervals.TimeUnit;
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.ViewLoader;
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;

  public static final String DATE_TIME_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz";

  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 PaginatedIdList<DataSetInfo> dataSetList = new DataSetList();

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

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

  private final transient Map<String, CachedListImpl<DataSource>> dataSourceList = new HashMap<String, CachedListImpl<DataSource>>();

  private final transient Map<String, CachedListImpl<DataSourceImport>> dataSourceImportList = new HashMap<String, CachedListImpl<DataSourceImport>>();

  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) {
    return createViewLoader(viewId, viewType).addFilters(filters).loadContent();
  }

  @Override
  public ViewLoader createViewLoader(String viewId, ViewType viewType) {
    return new ViewLoaderImpl(this, viewId, viewType);
  }

  @Override
  public CachedList<DataSource> getDataSources(String id) throws NotFoundException {
    CachedListImpl<DataSource> list = dataSourceList.get(id);
    if (list == null) {
      // we don't have this data set's sources in our cache yet
      list = new CachedListImpl<DataSource>(this, "api/dataSets/" + id + "/dataSources", "dataSources") {
        @Override
        protected DataSource parse(BellaDatiServiceImpl service, JsonNode node) throws ParseException {
          return new DataSourceImpl(service, node);
        }
      };
      dataSourceList.put(id, list);
    }
    return list;
  }

  @Override
  public CachedList<DataSourceImport> getDataSourceImports(String id) throws NotFoundException {
    CachedListImpl<DataSourceImport> list = dataSourceImportList.get(id);
    if (list == null) {
      // we don't have this data set's sources in our cache yet
      list = new CachedListImpl<DataSourceImport>(this, "api/dataSets/dataSources/" + id + "/executions", "executions") {
        @Override
        protected DataSourceImport parse(BellaDatiServiceImpl service, JsonNode node) throws ParseException {
          try {
            return new DataSourceImportImpl(node);
          } catch (InvalidDataSourceImportException e) {
            throw new ParseException(node, e);
          }
        }
      };
      dataSourceImportList.put(id, list);
    }
    return list;
  }

  @Override
  public DataSourcePendingImport setupDataSourceImport(String id, Date date) {
    return new DataSourcePendingImportImpl(this, id, date);
  }

  /**
   * 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;
  }

  /**
   * Appends a date/time definition parameter to the URI builder. Won't do
   * anything if both intervals are <tt>null</tt>.
   *
   * @param builder the builder to append to
   * @param dateInterval date interval to append, or <tt>null</tt>
   * @param timeInterval time interval to append, or <tt>null</tt>
   * @return the same builder, for chaining
   */
  URIBuilder appendDateTime(URIBuilder builder, Interval<DateUnit> dateInterval, Interval<TimeUnit> timeInterval) {
    if (dateInterval != null || timeInterval != null) {
      ObjectNode dateTimeNode = new ObjectMapper().createObjectNode();
      if (dateInterval != null) {
        dateTimeNode.setAll(dateInterval.toJson());
      }
      if (timeInterval != null) {
        dateTimeNode.setAll(timeInterval.toJson());
      }
      builder.addParameter("dateTimeDefinition", dateTimeNode.toString());
    }
    return builder;
  }

  /**
   * Appends a locale language parameter to the URI builder. Won't do anything
   * if the locale is <tt>null</tt>.
   *
   * @param builder the builder to append to
   * @param locale the locale to append
   * @return the same builder, for chaining
   */
  URIBuilder appendLocale(URIBuilder builder, Locale locale) {
    if (locale != null) {
      builder.addParameter("lang", locale.getLanguage());
    }
    return builder;
  }

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

    Map<String, CachedListImpl<AttributeValue>> attributeValues = dataSetAttributeValues.get(dataSetId);

    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/dataSets/" + dataSetId + "/attributes/" + attributeCode
        + "/values", "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() + ")";
  }

  @Override
  public PaginatedIdList<DataSetInfo> getDataSetInfo() {
    return dataSetList;
  }

  @Override
  public DataSet loadDataSet(String id) throws NotFoundException {
    return new DataSetImpl(this, loadJson("api/dataSets/" + id));
  }

  @Override
  public void uploadData(String id, DataTable data) {
    List<DataRow> rows = data.getRows();
    if (rows.size() == 0) {
      // if we don't have data, do nothing
      return;
    }
    try {
      client.postUpload("api/import/" + id, tokenHolder, data.toJson().toString());
    } catch (UnexpectedResponseException e) {
      if (e.getResponseCode() == 400) {
        Pattern codePattern = Pattern.compile(".*?'(.*?)'.*");
        Matcher codeMatcher = codePattern.matcher(e.getResponseContent());
        if (codeMatcher.matches()) {
          throw new UnknownServerColumnException(id, codeMatcher.group(1));
        }
      }
      throw new UnexpectedResponseException(e.getResponseCode(), e.getResponseContent(), e);
    }
  }

  /** 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 dataSetList = getClass().getDeclaredField("dataSetList");
      dataSetList.setAccessible(true);
      dataSetList.set(this, new DataSetList());

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

      Field reportAttributeValues = getClass().getDeclaredField("dataSetAttributeValues");
      reportAttributeValues.setAccessible(true);
      reportAttributeValues.set(this, new HashMap<String, Map<String, CachedListImpl<AttributeValue>>>());

      Field dataSourceList = getClass().getDeclaredField("dataSourceList");
      dataSourceList.setAccessible(true);
      dataSourceList.set(this, new HashMap<String, CachedListImpl<DataSource>>());

      Field dataSourceImportList = getClass().getDeclaredField("dataSourceImportList");
      dataSourceImportList.setAccessible(true);
      dataSourceImportList.set(this, new HashMap<String, CachedListImpl<DataSourceImport>>());
    } 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);
    }
  }

  /** Paginated list class for data sets. */
  private class DataSetList extends PaginatedIdListImpl<DataSetInfo> {
    public DataSetList() {
      super(BellaDatiServiceImpl.this, "api/dataSets", "dataSets");
    }

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

  @Override
  public byte[] post(String uri) throws URISyntaxException {
    return post(uri, Collections.<String, String> emptyMap());
  }

  @Override
  public byte[] post(String uri, Map<String, String> uriParameters) throws URISyntaxException {
    return postForm(uri, uriParameters, Collections.<String, String> emptyMap());
  }

  @Override
  public byte[] post(String uri, byte[] content) throws URISyntaxException {
    return post(uri, Collections.<String, String> emptyMap(), content);
  }

  @Override
  public byte[] post(String uri, Map<String, String> uriParameters, byte[] content) throws URISyntaxException {
    URIBuilder builder = new URIBuilder(uri);
    for (Entry<String, String> entry : uriParameters.entrySet()) {
      builder.addParameter(entry.getKey(), entry.getValue());
    }
    return client.postData(builder.build().toString(), tokenHolder, content);
  }

  @Override
  public byte[] postForm(String uri, Map<String, String> formParameters) throws URISyntaxException {
    return postForm(uri, Collections.<String, String> emptyMap(), formParameters);
  }

  @Override
  public byte[] postForm(String uri, Map<String, String> uriParameters, Map<String, String> formParameters)
    throws URISyntaxException {
    URIBuilder builder = new URIBuilder(uri);
    for (Entry<String, String> entry : uriParameters.entrySet()) {
      builder.addParameter(entry.getKey(), entry.getValue());
    }
    List<NameValuePair> formParams = new ArrayList<NameValuePair>();
    for (Entry<String, String> entry : formParameters.entrySet()) {
      formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
    }
    return client.post(builder.build().toString(), tokenHolder, formParams);
  }

  @Override
  public byte[] get(String uri) throws URISyntaxException {
    return get(uri, Collections.<String, String> emptyMap());
  }

  @Override
  public byte[] get(String uri, Map<String, String> uriParameters) throws URISyntaxException {
    URIBuilder builder = new URIBuilder(uri);
    for (Entry<String, String> entry : uriParameters.entrySet()) {
      builder.addParameter(entry.getKey(), entry.getValue());
    }
    return client.get(builder.build().toString(), tokenHolder);
  }
}
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.