Package org.cyclop.service.exporter.intern

Source Code of org.cyclop.service.exporter.intern.CsvQueryResultExporterImpl

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.cyclop.service.exporter.intern;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;

import org.cyclop.common.AppConfig;
import org.cyclop.model.CqlColumnValue;
import org.cyclop.model.CqlDataType;
import org.cyclop.model.CqlExtendedColumnName;
import org.cyclop.model.CqlQuery;
import org.cyclop.model.CqlQueryResult;
import org.cyclop.model.exception.ServiceException;
import org.cyclop.service.cassandra.QueryService;
import org.cyclop.service.converter.DataConverter;
import org.cyclop.service.converter.DataExtractor;
import org.cyclop.service.exporter.CsvQueryResultExporter;
import org.cyclop.validation.EnableValidation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.datastax.driver.core.DataType;
import com.datastax.driver.core.Row;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

/** @author Maciej Miklas */
@Named
@EnableValidation
public class CsvQueryResultExporterImpl implements CsvQueryResultExporter {

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

  @Inject
  private DataExtractor extractor;

  @Inject
  private DataConverter converter;

  @Inject
  private AppConfig.QueryExport conf;

  @Inject
  private QueryService queryService;

  @Override
  public String exportAsCsv(CqlQuery query) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    exportAsCsv(query, bos);
    try {
      String resStr = new String(bos.toByteArray(), conf.encoding);
      return resStr;
    } catch (UnsupportedEncodingException e) {
      throw new ServiceException("Encoding: " + conf.encoding + " caused error during export: " + e.getMessage(),
          e);
    }
  }

  @Override
  public void exportAsCsv(CqlQuery query, OutputStream output) {
    LOG.debug("Starting CSV export for {}", query);

    PrintWriter out = new PrintWriter(output);
    CqlQueryResult result = queryService.execute(query, false);

    // header
    appendHeader(query, out);

    // column names
    ImmutableList<CqlExtendedColumnName> columns = result.rowMetadata.columns;
    appendColumns(out, columns);
    out.append(conf.separatorRow);

    // content
    for (Row row : result) {
      appendRow(out, row, columns);
      out.append(conf.separatorRow);
    }

    out.flush();
    out.close();
  }

  private void appendRow(PrintWriter out, Row row, List<CqlExtendedColumnName> cols) {
    LOG.debug("Appending next row");
    Iterator<CqlExtendedColumnName> it = cols.iterator();
    while (it.hasNext()) {
      CqlExtendedColumnName column = it.next();
      CqlDataType dataType = column.dataType;

      if (dataType.name == DataType.Name.SET || dataType.name == DataType.Name.LIST) {
        appendCollection(out, row, column);

      } else if (dataType.name == DataType.Name.MAP) {
        appendMap(out, row, column);
      } else {
        appendSingleValue(out, row, column);
      }

      if (it.hasNext()) {
        out.append(conf.separatorColumn);
      }
    }
  }

  private void appendMap(PrintWriter out, Row row, CqlExtendedColumnName column) {
    ImmutableSet<Map.Entry<CqlColumnValue, CqlColumnValue>> displayMap = extractor.extractMap(row, column)
        .entrySet();
    Iterator<Map.Entry<CqlColumnValue, CqlColumnValue>> it = displayMap.iterator();

    LOG.trace("Appending: {}", displayMap);

    StringBuilder mapBuf = new StringBuilder();
    while (it.hasNext()) {
      Map.Entry<CqlColumnValue, CqlColumnValue> entry = it.next();

      CqlColumnValue key = entry.getKey();
      String keyText = esc(converter.convert(key.value));
      mapBuf.append(keyText);

      mapBuf.append(conf.separatorMap);

      CqlColumnValue val = entry.getValue();
      String valText = esc(converter.convert(val.value));
      mapBuf.append(valText);

      if (it.hasNext()) {
        mapBuf.append(conf.separatorList);
      }
    }

    String mapVal = esc(mapBuf.toString());
    LOG.trace("Appended map: {}", mapVal);
    out.append(mapVal);
  }

  private void appendCollection(PrintWriter out, Row row, CqlExtendedColumnName column) {
    ImmutableList<CqlColumnValue> content = extractor.extractCollection(row, column);
    LOG.trace("Appending {}", content);
    Iterator<CqlColumnValue> contentIt = content.iterator();
    StringBuilder listBuild = new StringBuilder();
    while (contentIt.hasNext()) {
      CqlColumnValue cqlColumnValue = contentIt.next();
      String valText = esc(converter.convert(cqlColumnValue.value));
      listBuild.append(valText);
      if (contentIt.hasNext()) {
        listBuild.append(conf.separatorList);
      }
    }
    String colVal = esc(listBuild.toString());
    LOG.trace("Append collection: {}", colVal);
    out.append(colVal);
  }

  private void appendSingleValue(PrintWriter out, Row row, CqlExtendedColumnName column) {
    CqlColumnValue cqlColumnValue = extractor.extractSingleValue(row, column);
    String valText = esc(converter.convert(cqlColumnValue.value));
    LOG.trace("Append single value: {}", valText);
    out.append(valText);
  }

  private void appendHeader(CqlQuery query, PrintWriter out) {
    String headerVal = prep(query.part);
    LOG.trace("Append header: {}", headerVal);
    out.append(headerVal);
    out.append(conf.separatorQuery);
  }

  private void appendColumns(PrintWriter out, List<CqlExtendedColumnName> columns) {
    if (columns.isEmpty()) {
      return;
    }

    LOG.trace("Appending {}", columns);

    Iterator<CqlExtendedColumnName> commonColsIt = columns.iterator();
    while (commonColsIt.hasNext()) {
      CqlExtendedColumnName next = commonColsIt.next();
      out.append(prep(esc(next.toDisplayString())));

      if (commonColsIt.hasNext()) {
        out.append(conf.separatorColumn);
      }
    }
  }

  private String prep(String val) {
    if (val == null) {
      val = "";
    }
    if (conf.trim) {
      val = val.trim();
    }

    if (conf.removeCrChars) {
      val = val.replaceAll("[\n\r]", "");
    }

    return val;
  }

  private String esc(String val) {
    return conf.valueBracketStart + prep(val) + conf.valueBracketEnd;
  }
}
TOP

Related Classes of org.cyclop.service.exporter.intern.CsvQueryResultExporterImpl

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.