private String join(final Map<Row, List<String>> csvMap) {
   StringBuilder sb = new StringBuilder();
   for (Map.Entry<Row, List<String>> rowEntry : csvMap.entrySet()) {
     sb.append(Joiner.on(";").join(rowEntry.getValue()));
     sb.append("\n");
   }
   return sb.toString();
 }
  private String[] createXLSRowComments(List<String> selects, QueryResultRow row) {
    List<String> commentsData = new ArrayList<>();
    PartRevision part = row.getPartRevision();
    PartIteration lastIteration = part.getLastIteration();

    for (String select : selects) {

      if (select.equals(QueryField.CTX_SERIAL_NUMBER)) {
        String path = row.getPath();
        if (path != null && !path.isEmpty()) {
          commentsData.add(path);
        }

      } else if (select.startsWith(QueryField.PART_REVISION_ATTRIBUTES_PREFIX)) {
        String attributeSelectType =
            select
                .substring(0, select.indexOf("."))
                .substring(QueryField.PART_REVISION_ATTRIBUTES_PREFIX.length());
        String attributeSelectName = select.substring(select.indexOf(".") + 1);
        StringBuilder commentsSbattr = new StringBuilder();

        if (lastIteration != null) {
          List<InstanceAttribute> attributes = lastIteration.getInstanceAttributes();
          if (attributes != null) {
            for (InstanceAttribute attribute : attributes) {
              InstanceAttributeDescriptor attributeDescriptor =
                  new InstanceAttributeDescriptor(attribute);

              if (attributeDescriptor.getName().equals(attributeSelectName)
                  && attributeDescriptor.getStringType().equals(attributeSelectType)) {
                commentsSbattr.append(attribute.getId() + "|");
              }
            }
          }
        }

        String commentsContent = commentsSbattr.toString().trim();
        if (commentsContent.length() > 0) {
          commentsContent = commentsContent.substring(0, commentsContent.lastIndexOf("|"));
        }
        commentsData.add(commentsContent);

      } else if (select.startsWith(QueryField.PATH_DATA_ATTRIBUTES_PREFIX)) {
        String attributeSelectType =
            select
                .substring(0, select.indexOf("."))
                .substring(QueryField.PATH_DATA_ATTRIBUTES_PREFIX.length());
        String attributeSelectName = select.substring(select.indexOf(".") + 1);
        PathDataIteration pdi = row.getPathDataIteration();
        StringBuilder commentsSbpattr = new StringBuilder();

        if (pdi != null) {
          List<InstanceAttribute> attributes = pdi.getInstanceAttributes();
          if (attributes != null) {
            for (InstanceAttribute attribute : attributes) {
              InstanceAttributeDescriptor attributeDescriptor =
                  new InstanceAttributeDescriptor(attribute);

              if (attributeDescriptor.getName().equals(attributeSelectName)
                  && attributeDescriptor.getStringType().equals(attributeSelectType)) {
                commentsSbpattr.append(attribute.getId() + "|");
              }
            }
          }
        }

        String commentsContent = commentsSbpattr.toString().trim();
        if (commentsContent.length() > 0) {
          commentsContent = commentsContent.substring(0, commentsContent.lastIndexOf("|"));
        }
        commentsData.add(commentsContent);

      } else {
        commentsData.add("");
      }
    }

    String commentsRowData = StringUtils.join(commentsData, ";");
    return commentsRowData.split(";");
  }
  private String[] createXLSRow(List<String> selects, QueryResultRow row, String baseURL) {
    List<String> data = new ArrayList<>();
    PartRevision part = row.getPartRevision();
    PartIteration lastCheckedInIteration = part.getLastCheckedInIteration();
    PartIteration lastIteration = part.getLastIteration();
    QueryContext context = row.getContext();

    for (String select : selects) {

      switch (select) {
        case QueryField.CTX_PRODUCT_ID:
          String productId = context != null ? context.getConfigurationItemId() : "";
          data.add(productId);
          break;
        case QueryField.CTX_SERIAL_NUMBER:
          String serialNumber = context != null ? context.getSerialNumber() : "";
          data.add(serialNumber != null ? serialNumber : "");
          break;
        case QueryField.PART_MASTER_NUMBER:
          data.add(part.getPartNumber());
          break;
        case QueryField.PART_MASTER_NAME:
          String sName = part.getPartName();
          data.add(sName != null ? sName : "");
          break;
        case QueryField.PART_MASTER_TYPE:
          String sType = part.getType();
          data.add(sType != null ? sType : "");
          break;
        case QueryField.PART_REVISION_MODIFICATION_DATE:
          data.add(
              (lastIteration != null && lastIteration.getModificationDate() != null)
                  ? simpleDateFormat.format(lastIteration.getModificationDate())
                  : "");
          break;
        case QueryField.PART_REVISION_CREATION_DATE:
          data.add(
              (part.getCreationDate() != null)
                  ? simpleDateFormat.format(part.getCreationDate())
                  : "");
          break;
        case QueryField.PART_REVISION_CHECKOUT_DATE:
          data.add(
              (part.getCheckOutDate() != null)
                  ? simpleDateFormat.format(part.getCheckOutDate())
                  : "");
          break;
        case QueryField.PART_REVISION_CHECKIN_DATE:
          data.add(
              (lastCheckedInIteration != null && lastCheckedInIteration.getCheckInDate() != null)
                  ? simpleDateFormat.format(lastCheckedInIteration.getCheckInDate())
                  : "");
          break;
        case QueryField.PART_REVISION_VERSION:
          data.add(part.getVersion() != null ? part.getVersion() : "");
          break;
        case QueryField.PART_REVISION_LIFECYCLE_STATE:
          data.add(part.getLifeCycleState() != null ? part.getLifeCycleState() : "");
          break;
        case QueryField.PART_REVISION_STATUS:
          data.add(part.getStatus().toString());
          break;
        case QueryField.AUTHOR_LOGIN:
          User user = part.getAuthor();
          data.add(user.getLogin());
          break;
        case QueryField.AUTHOR_NAME:
          User userAuthor = part.getAuthor();
          data.add(userAuthor.getName());
          break;
        case QueryField.CTX_DEPTH:
          data.add(row.getDepth() + "");
          break;
        case QueryField.CTX_AMOUNT:
          data.add(row.getAmount() + "");
          break;
        case QueryField.PART_ITERATION_LINKED_DOCUMENTS:
          StringBuilder sb = new StringBuilder();
          if (lastCheckedInIteration != null) {
            Set<DocumentLink> linkedDocuments = lastCheckedInIteration.getLinkedDocuments();
            for (DocumentLink documentLink : linkedDocuments) {
              DocumentRevision targetDocument = documentLink.getTargetDocument();
              sb.append(
                  baseURL
                      + "/documents/"
                      + targetDocument.getWorkspaceId()
                      + "/"
                      + targetDocument.getId()
                      + "/"
                      + targetDocument.getVersion()
                      + " ");
            }
          }
          data.add(sb.toString());
          break;

        case QueryField.CTX_P2P_SOURCE:
          Map<String, List<PartLinkList>> sources = row.getSources();
          String sourcePartLinksAsString = Tools.getPartLinksAsExcelString(sources);
          data.add(sourcePartLinksAsString);
          break;

        case QueryField.CTX_P2P_TARGET:
          Map<String, List<PartLinkList>> targets = row.getTargets();
          String targetPartLinksAsString = Tools.getPartLinksAsExcelString(targets);
          data.add(targetPartLinksAsString);
          break;

        default:
          if (select.startsWith(QueryField.PART_REVISION_ATTRIBUTES_PREFIX)) {
            String attributeSelectType =
                select
                    .substring(0, select.indexOf("."))
                    .substring(QueryField.PART_REVISION_ATTRIBUTES_PREFIX.length());
            String attributeSelectName = select.substring(select.indexOf(".") + 1);
            String attributeValue = "";
            StringBuilder sbattr = new StringBuilder();

            if (lastIteration != null) {
              List<InstanceAttribute> attributes = lastIteration.getInstanceAttributes();
              if (attributes != null) {
                for (InstanceAttribute attribute : attributes) {
                  InstanceAttributeDescriptor attributeDescriptor =
                      new InstanceAttributeDescriptor(attribute);
                  if (attributeDescriptor.getName().equals(attributeSelectName)
                      && attributeDescriptor.getStringType().equals(attributeSelectType)) {

                    attributeValue = attribute.getValue() + "";
                    if (attributeDescriptor.getType() == InstanceAttributeDescriptor.Type.DATE) {
                      attributeValue =
                          attribute.getValue() != null
                              ? attributeDateFormat.format(attribute.getValue())
                              : "";
                    } else if (attribute instanceof InstanceListOfValuesAttribute) {
                      attributeValue =
                          ((InstanceListOfValuesAttribute) attribute).getSelectedName();
                    }
                    sbattr.append(attributeValue + "|");
                  }
                }
              }
            }
            String content = sbattr.toString().trim();
            if (content.length() > 0) {
              content = content.substring(0, content.lastIndexOf("|"));
            }
            data.add(content);
          }
          if (select.startsWith(QueryField.PATH_DATA_ATTRIBUTES_PREFIX)) {
            String attributeSelectType =
                select
                    .substring(0, select.indexOf("."))
                    .substring(QueryField.PATH_DATA_ATTRIBUTES_PREFIX.length());
            String attributeSelectName = select.substring(select.indexOf(".") + 1);
            String attributeValue = "";
            PathDataIteration pdi = row.getPathDataIteration();
            StringBuilder sbpdattr = new StringBuilder();

            if (pdi != null) {
              List<InstanceAttribute> attributes = pdi.getInstanceAttributes();
              if (attributes != null) {
                for (InstanceAttribute attribute : attributes) {
                  InstanceAttributeDescriptor attributeDescriptor =
                      new InstanceAttributeDescriptor(attribute);
                  if (attributeDescriptor.getName().equals(attributeSelectName)
                      && attributeDescriptor.getStringType().equals(attributeSelectType)) {

                    attributeValue = attribute.getValue() + "";
                    if (attributeDescriptor.getType() == InstanceAttributeDescriptor.Type.DATE) {
                      attributeValue =
                          attribute.getValue() != null
                              ? attributeDateFormat.format(attribute.getValue())
                              : "";
                    } else if (attribute instanceof InstanceListOfValuesAttribute) {
                      attributeValue =
                          ((InstanceListOfValuesAttribute) attribute).getSelectedName();
                    }
                    sbpdattr.append(attributeValue + "|");
                  }
                }
              }
            }
            String content = sbpdattr.toString().trim();
            if (content.length() > 0) {
              content = content.substring(0, content.lastIndexOf("|"));
            }
            data.add(content);
          }
      }
    }

    String rowData = StringUtils.join(data, ";");
    return rowData.split(";");
  }