<commit_before>package org.flowable.app.service.editor;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.flowable.app.domain.editor.AbstractModel;
import org.flowable.app.domain.editor.AppDefinition;
import org.flowable.app.domain.editor.AppModelDefinition;
import org.flowable.app.domain.editor.Model;
import org.flowable.app.model.editor.AppDefinitionRepresentation;
import org.flowable.app.service.exception.BadRequestException;
import org.flowable.app.service.exception.InternalServerErrorException;
import org.flowable.editor.language.json.converter.BpmnJsonConverter;
import org.flowable.editor.language.json.converter.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.databind.node.ObjectNode;

@Service
@Transactional
public class AppDefinitionExportService extends BaseAppDefinitionService {

  private static final Logger logger = LoggerFactory.getLogger(AppDefinitionExportService.class);
  
  protected BpmnJsonConverter bpmnJsonConverter = new BpmnJsonConverter();

  public void exportAppDefinition(HttpServletResponse response, String modelId) throws IOException {

    if (modelId == null) {
      throw new BadRequestException("No application definition id provided");
    }

    Model appModel = modelService.getModel(modelId);
    AppDefinitionRepresentation appRepresentation = createAppDefinitionRepresentation(appModel);

    createAppDefinitionZip(response, appModel, appRepresentation);
  }

  public void exportDeployableAppDefinition(HttpServletResponse response, String modelId) throws IOException {

    if (modelId == null) {
      throw new BadRequestException("No application definition id provided");
    }

    Model appModel = modelService.getModel(modelId);
    AppDefinitionRepresentation appRepresentation = createAppDefinitionRepresentation(appModel);

    createAppDefinitionBar(response, appModel, appRepresentation);
  }

  protected void createAppDefinitionZip(HttpServletResponse response, Model appModel, AppDefinitionRepresentation appDefinition) {
    response.setHeader("Content-Disposition", "attachment; filename=" + appDefinition.getName() + ".zip");
    try {
      ServletOutputStream servletOutputStream = response.getOutputStream();
      response.setContentType("application/zip");

      ZipOutputStream zipOutputStream = new ZipOutputStream(servletOutputStream);

      createZipEntry(zipOutputStream, appModel.getName() + ".json", createModelEntryJson(appModel));

      List<AppModelDefinition> modelDefinitions = appDefinition.getDefinition().getModels();
      if (CollectionUtils.isNotEmpty(modelDefinitions)) {
        Map<String, Model> formMap = new HashMap<>();
        Map<String, Model> decisionTableMap = new HashMap<>();

        for (AppModelDefinition modelDef : modelDefinitions) {
          Model model = modelService.getModel(modelDef.getId());

          List<Model> referencedModels = modelRepository.findByParentModelId(model.getId());
          for (Model childModel : referencedModels) {
            if (Model.MODEL_TYPE_FORM == childModel.getModelType()) {
              formMap.put(childModel.getId(), childModel);

            } else if (Model.MODEL_TYPE_DECISION_TABLE == childModel.getModelType()) {
              decisionTableMap.put(childModel.getId(), childModel);
            }
          }

          createZipEntries(model, "bpmn-models", zipOutputStream);
        }

        for (Model formModel : formMap.values()) {
          createZipEntries(formModel, "form-models", zipOutputStream);
        }
        
        for (Model decisionTableModel : decisionTableMap.values()) {
          createZipEntries(decisionTableModel, "decision-table-models", zipOutputStream);
        }
      }

      zipOutputStream.close();

      // Flush and close stream<commit_msg>added decision table XML model to app export<commit_after>package org.flowable.app.service.editor;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.databind.JsonNode;
import org.flowable.app.domain.editor.AbstractModel;
import org.flowable.app.domain.editor.AppDefinition;
import org.flowable.app.domain.editor.AppModelDefinition;
import org.flowable.app.domain.editor.Model;
import org.flowable.app.model.editor.AppDefinitionRepresentation;
import org.flowable.app.service.exception.BadRequestException;
import org.flowable.app.service.exception.InternalServerErrorException;
import org.flowable.dmn.model.DmnDefinition;
import org.flowable.editor.language.json.converter.BpmnJsonConverter;
import org.flowable.editor.language.json.converter.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.databind.node.ObjectNode;

@Service
@Transactional
public class AppDefinitionExportService extends BaseAppDefinitionService {

  private static final Logger logger = LoggerFactory.getLogger(AppDefinitionExportService.class);
  
  protected BpmnJsonConverter bpmnJsonConverter = new BpmnJsonConverter();

  public void exportAppDefinition(HttpServletResponse response, String modelId) throws IOException {

    if (modelId == null) {
      throw new BadRequestException("No application definition id provided");
    }

    Model appModel = modelService.getModel(modelId);
    AppDefinitionRepresentation appRepresentation = createAppDefinitionRepresentation(appModel);

    createAppDefinitionZip(response, appModel, appRepresentation);
  }

  public void exportDeployableAppDefinition(HttpServletResponse response, String modelId) throws IOException {

    if (modelId == null) {
      throw new BadRequestException("No application definition id provided");
    }

    Model appModel = modelService.getModel(modelId);
    AppDefinitionRepresentation appRepresentation = createAppDefinitionRepresentation(appModel);

    createAppDefinitionBar(response, appModel, appRepresentation);
  }

  protected void createAppDefinitionZip(HttpServletResponse response, Model appModel, AppDefinitionRepresentation appDefinition) {
    response.setHeader("Content-Disposition", "attachment; filename=" + appDefinition.getName() + ".zip");
    try {
      ServletOutputStream servletOutputStream = response.getOutputStream();
      response.setContentType("application/zip");

      ZipOutputStream zipOutputStream = new ZipOutputStream(servletOutputStream);

      createZipEntry(zipOutputStream, appModel.getName() + ".json", createModelEntryJson(appModel));

      List<AppModelDefinition> modelDefinitions = appDefinition.getDefinition().getModels();
      if (CollectionUtils.isNotEmpty(modelDefinitions)) {
        Map<String, Model> formMap = new HashMap<>();
        Map<String, Model> decisionTableMap = new HashMap<>();

        for (AppModelDefinition modelDef : modelDefinitions) {
          Model model = modelService.getModel(modelDef.getId());

          List<Model> referencedModels = modelRepository.findByParentModelId(model.getId());
          for (Model childModel : referencedModels) {
            if (Model.MODEL_TYPE_FORM == childModel.getModelType()) {
              formMap.put(childModel.getId(), childModel);

            } else if (Model.MODEL_TYPE_DECISION_TABLE == childModel.getModelType()) {
              decisionTableMap.put(childModel.getId(), childModel);
            }
          }

          createZipEntries(model, "bpmn-models", zipOutputStream);
        }

        for (Model formModel : formMap.values()) {
          createZipEntries(formModel, "form-models", zipOutputStream);
        }
        
        for (Model decisionTableModel : decisionTableMap.values()) {
          createZipEntries(decisionTableModel, "decision-table-models", zipOutputStream);
          try {
            JsonNode decisionTableNode = objectMapper.readTree(decisionTableModel.getModelEditorJson());
            DmnDefinition dmnDefinition = dmnJsonConverter.convertToDmn(decisionTableNode, decisionTableModel.getId(),
                decisionTableModel.getVersion(), decisionTableModel.getLastUpdated());
            byte[] dmnXMLBytes = dmnXMLConverter.convertToXML(dmnDefinition);
            createZipEntry(zipOutputStream, "decision-table-models/" + decisionTableModel.getKey() + ".dmn", dmnXMLBytes);
          } catch (Exception e) {
            throw new InternalServerErrorException(String.format("Error converting decision table %s to XML",decisionTableModel.getName()));
          }
        }
      }

      zipOutputStream.close();

      // Flush and close stream
{'fraction_non_alphanumeric': 0.09385535617183252, 'fraction_numerical': 0.0004350190320826536, 'mean_word_length': 4.496712492528392, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 3}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5942212', 'n_tokens_mistral': 2397, 'n_tokens_neox': 2314, 'n_words': 456}