public String resolveOutputFilePath() {

    String fileName =
        RepositoryFilenameUtils.getBaseName(scheduleRequest.getInputFile()); // default file name
    if (!StringUtils.isEmpty(scheduleRequest.getJobName())) {
      fileName = scheduleRequest.getJobName(); // use job name as file name if exists
    }
    String fileNamePattern = "/" + fileName + ".*";

    String outputFilePath = scheduleRequest.getOutputFile();
    if (StringUtils.isNotBlank(outputFilePath) && isValidOutputPath(outputFilePath)) {
      return outputFilePath + fileNamePattern; // return if valid
    }

    // evaluate fallback output paths
    String[] fallBackPaths =
        new String[] {
          getUserSettingOutputPath(), // user setting
          getSystemSettingOutputPath(), // system setting
          getUserHomeDirectoryPath() // home directory
        };

    for (String path : fallBackPaths) {
      if (StringUtils.isNotBlank(path) && isValidOutputPath(path)) {
        return path + fileNamePattern; // return the first valid path
      }
    }

    return null; // it should never reach here
  }
 /**
  * Computes the bundle path from the bundle
  *
  * @param bundle
  * @return
  */
 protected String computeBundlePath(final ImportSource.IRepositoryFileBundle bundle) {
   String bundlePath = bundle.getPath();
   bundlePath = RepositoryFilenameUtils.separatorsToRepository(bundlePath);
   if (bundlePath.startsWith(RepositoryFile.SEPARATOR)) {
     bundlePath = bundlePath.substring(1);
   }
   return bundlePath;
 }
  /**
   * Copies the file bundle into the repository
   *
   * @param bundle
   * @param bundlePath
   * @param bundlePathName
   * @param file
   * @param comment
   */
  protected boolean copyFileToRepository(
      final ImportSource.IRepositoryFileBundle bundle,
      final String bundlePathName,
      final String repositoryPath,
      final RepositoryFile file,
      final String comment) {
    // Compute the file extension
    final String name = bundle.getFile().getName();
    final String ext = RepositoryFilenameUtils.getExtension(name);
    if (StringUtils.isEmpty(ext)) {
      log.debug("Skipping file without extension: " + bundlePathName);
      return false;
    }

    // Check the mime type
    final String mimeType = bundle.getMimeType();
    if (mimeType == null) {
      log.debug("Skipping file without mime-type: " + bundlePathName);
      return false;
    }

    // Find the converter
    final Converter converter = converters.get(ext);
    if (converter == null) {
      log.debug("Skipping file without converter: " + bundlePathName);
      return false;
    }

    // Copy the file into the repository
    try {
      log.trace("copying file to repository: " + bundlePathName);
      IRepositoryFileData data =
          converter.convert(bundle.getInputStream(), bundle.getCharset(), mimeType);
      if (null == file) {
        final boolean hidden = !executableTypes.contains(ext.toLowerCase());
        log.trace("\tsetting hidden=" + hidden + " for file with extension " + ext.toLowerCase());
        createFile(bundle, repositoryPath, hidden, data, comment);
      } else {
        repository.updateFile(file, data, comment);
      }
      return true;
    } catch (IOException e) {
      log.warn(
          messages.getString("DefaultImportHandler.WARN_0003_IOEXCEPTION", name),
          e); // TODO make sure string
      // exists
      return false;
    }
  }
  /**
   * Returns the Id of the parent folder of the file path provided
   *
   * @param repositoryPath
   * @return
   */
  protected Serializable getParentId(final String repositoryPath) {
    Assert.notNull(repositoryPath);
    Assert.notNull(parentIdCache);

    final String parentPath = RepositoryFilenameUtils.getFullPathNoEndSeparator(repositoryPath);
    Serializable parentFileId = parentIdCache.get(parentPath);
    if (parentFileId == null) {
      final RepositoryFile parentFile = repository.getFile(parentPath);
      Assert.notNull(parentFile);
      parentFileId = parentFile.getId();
      Assert.notNull(parentFileId);
      parentIdCache.put(parentPath, parentFileId);
    }
    return parentFileId;
  }
  public OutputStream getOutputStream() throws Exception {
    String tempOutputFilePath = outputFilePath;
    String extension = RepositoryFilenameUtils.getExtension(tempOutputFilePath);
    if ("*".equals(extension)) { // $NON-NLS-1$
      tempOutputFilePath = tempOutputFilePath.substring(0, tempOutputFilePath.lastIndexOf('.'));
      if (streamingAction != null) {
        String mimeType = streamingAction.getMimeType(null);
        if (mimeType != null && MimeHelper.getExtension(mimeType) != null) {
          tempOutputFilePath += MimeHelper.getExtension(mimeType);
        }
      }
    }

    RepositoryFileOutputStream outputStream =
        new RepositoryFileOutputStream(tempOutputFilePath, autoCreateUniqueFilename, true);
    outputStream.addListener(this);
    return outputStream;
  }
    protected void initialize() {
      try {
        ZipEntry entry = zipInputStream.getNextEntry();
        while (entry != null) {
          final String entryName = RepositoryFilenameUtils.separatorsToRepository(entry.getName());
          File tempFile = null;
          boolean isDir = entry.isDirectory();
          if (!isDir) {
            if (!solutionHelper.isInApprovedExtensionList(entryName)) {
              zipInputStream.closeEntry();
              entry = zipInputStream.getNextEntry();
              continue;
            }
            tempFile = File.createTempFile("zip", null);
            tempFile.deleteOnExit();
            FileOutputStream fos = new FileOutputStream(tempFile);
            IOUtils.copy(zipInputStream, fos);
            fos.close();
          }
          File file = new File(entryName);
          RepositoryFile repoFile =
              new RepositoryFile.Builder(file.getName()).folder(isDir).hidden(false).build();
          String parentDir =
              new File(entryName).getParent() == null
                  ? RepositoryFile.SEPARATOR
                  : new File(entryName).getParent() + RepositoryFile.SEPARATOR;
          IRepositoryFileBundle repoFileBundle =
              new RepositoryFileBundle(repoFile, null, parentDir, tempFile, "UTF-8", null);

          if (file.getName().equals("exportManifest.xml")) {
            initializeAclManifest(repoFileBundle);
          } else {
            files.add(repoFileBundle);
          }
          zipInputStream.closeEntry();
          entry = zipInputStream.getNextEntry();
        }
        zipInputStream.close();
      } catch (IOException exception) {
        final String errorMessage =
            Messages.getInstance().getErrorString("", exception.getLocalizedMessage());
        log.trace(errorMessage);
      }
    }
  /**
   * Processes the list of files and performs any processing required to import that data into the
   * repository. If during processing it handles file(s) which should not be handled by downstream
   * import handlers, then it should remove them from the set of files provided.
   *
   * @param importFileSet the set of files to be imported - any files handled to completion by this
   *     Import Handler should remove this files from this list
   * @param comment the import comment provided
   * @param overwrite indicates if the process is authorized to overwrite existing content in the
   *     repository
   * @throws ImportException indicates a significant error during import processing
   */
  @Override
  public void doImport(
      final Iterable<ImportSource.IRepositoryFileBundle> importFileSet,
      final String destinationPath,
      final String comment,
      final boolean overwrite)
      throws ImportException {
    if (null == importFileSet || StringUtils.isEmpty(destinationPath)) {
      throw new IllegalArgumentException();
    }

    // Ensure the destination path is valid
    Assert.notNull(
        getParentId(RepositoryFilenameUtils.normalize(destinationPath + RepositoryFile.SEPARATOR)));

    // Iterate through the file set
    for (Iterator<IRepositoryFileBundle> iterator = importFileSet.iterator();
        iterator.hasNext(); ) {
      final ImportSource.IRepositoryFileBundle bundle =
          (ImportSource.IRepositoryFileBundle) iterator.next();

      // Make sure we don't try to do anything in a system-defined folder
      final String bundlePathName =
          RepositoryFilenameUtils.concat(computeBundlePath(bundle), bundle.getFile().getName());
      if (isSystemPath(bundlePathName)) {
        log.trace("Skipping [" + bundlePathName + "] since it is in admin / system folders");
        continue;
      }
      final String repositoryFilePath =
          RepositoryFilenameUtils.concat(destinationPath, bundlePathName);
      log.trace("Processing [" + bundlePathName + "]");

      // See if the destination already exists in the repository
      final RepositoryFile file = repository.getFile(repositoryFilePath);
      if (file != null) {
        if (file.isFolder() != bundle.getFile().isFolder()) {
          log.warn(
              "Entry already exists in the repository - but it is a "
                  + (file.isFolder() ? "folder" : "file")
                  + " and the entry to be imported is a "
                  + (bundle.getFile().isFolder() ? "folder" : "file"));
        }

        if (!overwrite) {
          log.trace("File already exists in repository and overwrite is false - skipping");
        } else if (file.isFolder()) {
          log.trace("Folder already exists - skip");
        } else {
          // It is a file we can overwrite...
          log.trace("Updating...");
          copyFileToRepository(bundle, bundlePathName, repositoryFilePath, file, comment);
        }
        // We handled this file (even if by doing nothing)
        iterator.remove();
        continue;
      }

      // The file doesn't exist - if it is a folder then this is easy
      if (bundle.getFile().isFolder()) {
        log.trace("Creating folder [" + bundlePathName + "]");
        final Serializable parentId = getParentId(repositoryFilePath);
        if (bundle.getAcl() != null) {
          repository.createFolder(parentId, bundle.getFile(), bundle.getAcl(), comment);
        } else {
          repository.createFolder(parentId, bundle.getFile(), comment);
        }
        iterator.remove();
      } else {
        // It is a file ...
        if (copyFileToRepository(bundle, bundlePathName, repositoryFilePath, null, comment)) {
          iterator.remove();
        }
      }
    }
  }
  public void importFile(IPlatformImportBundle bundle)
      throws PlatformImportException, DomainIdNullException, DomainAlreadyExistsException,
          DomainStorageException, IOException {

    RepositoryFileImportBundle importBundle = (RepositoryFileImportBundle) bundle;
    ZipInputStream zipImportStream = new ZipInputStream(bundle.getInputStream());
    SolutionRepositoryImportSource importSource =
        new SolutionRepositoryImportSource(zipImportStream);
    LocaleFilesProcessor localeFilesProcessor = new LocaleFilesProcessor();
    setOverwriteFile(bundle.overwriteInRepository());
    // importSession.set(ImportSession.getSession());

    IPlatformImporter importer = PentahoSystem.get(IPlatformImporter.class);

    cachedImports = new HashMap<String, RepositoryFileImportBundle.Builder>();

    // Process Manifest Settings
    ExportManifest manifest = getImportSession().getManifest();
    String manifestVersion = null;
    if (manifest != null) {
      manifestVersion = manifest.getManifestInformation().getManifestVersion();
    }
    // Process Metadata
    if (manifest != null) {

      // import the users
      Map<String, List<String>> roleToUserMap = importUsers(manifest.getUserExports());
      // import the roles
      importRoles(manifest.getRoleExports(), roleToUserMap);

      List<ExportManifestMetadata> metadataList = manifest.getMetadataList();
      for (ExportManifestMetadata exportManifestMetadata : metadataList) {

        String domainId = exportManifestMetadata.getDomainId();
        boolean overWriteInRepository = isOverwriteFile();
        RepositoryFileImportBundle.Builder bundleBuilder =
            new RepositoryFileImportBundle.Builder()
                .charSet("UTF-8")
                .hidden(false)
                // let the parent bundle control whether or not to preserve DSW settings
                .preserveDsw(bundle.isPreserveDsw())
                .overwriteFile(overWriteInRepository)
                .mime("text/xmi+xml")
                .withParam("domain-id", domainId);

        cachedImports.put(exportManifestMetadata.getFile(), bundleBuilder);
      }

      // Process Mondrian
      List<ExportManifestMondrian> mondrianList = manifest.getMondrianList();
      for (ExportManifestMondrian exportManifestMondrian : mondrianList) {

        String catName = exportManifestMondrian.getCatalogName();
        Parameters parametersMap = exportManifestMondrian.getParameters();
        StringBuilder parametersStr = new StringBuilder();
        for (String s : parametersMap.keySet()) {
          parametersStr.append(s).append("=").append(parametersMap.get(s)).append(sep);
        }

        RepositoryFileImportBundle.Builder bundleBuilder =
            new RepositoryFileImportBundle.Builder()
                .charSet("UTF_8")
                .hidden(false)
                .name(catName)
                .overwriteFile(isOverwriteFile())
                .mime("application/vnd.pentaho.mondrian+xml")
                .withParam("parameters", parametersStr.toString())
                .withParam("domain-id", catName); // TODO: this is
        // definitely
        // named wrong
        // at the very
        // least.
        // pass as param if not in parameters string
        String xmlaEnabled = "" + exportManifestMondrian.isXmlaEnabled();
        bundleBuilder.withParam("EnableXmla", xmlaEnabled);

        cachedImports.put(exportManifestMondrian.getFile(), bundleBuilder);

        String annotationsFile = exportManifestMondrian.getAnnotationsFile();
        if (annotationsFile != null) {
          RepositoryFileImportBundle.Builder annotationsBundle =
              new RepositoryFileImportBundle.Builder()
                  .path(
                      MondrianCatalogRepositoryHelper.ETC_MONDRIAN_JCR_FOLDER
                          + RepositoryFile.SEPARATOR
                          + catName)
                  .name("annotations.xml")
                  .charSet("UTF_8")
                  .overwriteFile(isOverwriteFile())
                  .mime("text/xml")
                  .hidden(false)
                  .withParam("domain-id", catName);
          cachedImports.put(annotationsFile, annotationsBundle);
        }
      }
    }

    importMetaStore(manifest, bundle.overwriteInRepository());

    for (IRepositoryFileBundle file : importSource.getFiles()) {
      String fileName = file.getFile().getName();
      String actualFilePath = file.getPath();
      if (manifestVersion != null) {
        fileName = ExportFileNameEncoder.decodeZipFileName(fileName);
        actualFilePath = ExportFileNameEncoder.decodeZipFileName(actualFilePath);
      }
      String repositoryFilePath =
          RepositoryFilenameUtils.concat(
              PentahoPlatformImporter.computeBundlePath(actualFilePath), fileName);

      if (this.cachedImports.containsKey(repositoryFilePath)) {

        byte[] bytes = IOUtils.toByteArray(file.getInputStream());
        RepositoryFileImportBundle.Builder builder = cachedImports.get(repositoryFilePath);
        builder.input(new ByteArrayInputStream(bytes));

        importer.importFile(build(builder));
        continue;
      }
      RepositoryFileImportBundle.Builder bundleBuilder = new RepositoryFileImportBundle.Builder();

      InputStream bundleInputStream = null;

      String decodedFilePath = file.getPath();
      RepositoryFile decodedFile = file.getFile();
      if (manifestVersion != null) {
        decodedFile =
            new RepositoryFile.Builder(decodedFile)
                .path(decodedFilePath)
                .name(fileName)
                .title(fileName)
                .build();
        decodedFilePath = ExportFileNameEncoder.decodeZipFileName(file.getPath());
      }

      if (file.getFile().isFolder()) {
        bundleBuilder.mime("text/directory");
        bundleBuilder.file(decodedFile);
        fileName = repositoryFilePath;
        repositoryFilePath = importBundle.getPath();
      } else {
        byte[] bytes = IOUtils.toByteArray(file.getInputStream());
        bundleInputStream = new ByteArrayInputStream(bytes);
        // If is locale file store it for later processing.
        if (localeFilesProcessor.isLocaleFile(file, importBundle.getPath(), bytes)) {
          log.trace("Skipping [" + repositoryFilePath + "], it is a locale property file");
          continue;
        }
        bundleBuilder.input(bundleInputStream);
        bundleBuilder.mime(solutionHelper.getMime(fileName));

        String filePath =
            (decodedFilePath.equals("/") || decodedFilePath.equals("\\")) ? "" : decodedFilePath;
        repositoryFilePath = RepositoryFilenameUtils.concat(importBundle.getPath(), filePath);
      }

      bundleBuilder.name(fileName);
      bundleBuilder.path(repositoryFilePath);

      String sourcePath;
      if (decodedFilePath.startsWith("/")) {
        sourcePath = RepositoryFilenameUtils.concat(decodedFilePath.substring(1), fileName);
      } else {
        if (file.getFile().isFolder()) {
          sourcePath = fileName;
        } else {
          sourcePath = RepositoryFilenameUtils.concat(decodedFilePath, fileName);
        }
      }

      // This clause was added for processing ivb files so that it would not try process acls on
      // folders that the user
      // may not have rights to such as /home or /public
      if (manifest != null
          && manifest.getExportManifestEntity(sourcePath) == null
          && file.getFile().isFolder()) {
        continue;
      }

      getImportSession().setCurrentManifestKey(sourcePath);

      bundleBuilder.charSet(bundle.getCharset());
      bundleBuilder.overwriteFile(bundle.overwriteInRepository());
      bundleBuilder.hidden(isFileHidden(bundle, sourcePath));
      bundleBuilder.applyAclSettings(bundle.isApplyAclSettings());
      bundleBuilder.retainOwnership(bundle.isRetainOwnership());
      bundleBuilder.overwriteAclSettings(bundle.isOverwriteAclSettings());
      bundleBuilder.acl(getImportSession().processAclForFile(sourcePath));
      IPlatformImportBundle platformImportBundle = build(bundleBuilder);
      importer.importFile(platformImportBundle);

      if (bundleInputStream != null) {
        bundleInputStream.close();
        bundleInputStream = null;
      }
    }
    if (manifest != null) {
      List<JobScheduleRequest> scheduleList = manifest.getScheduleList();
      if (scheduleList != null) {
        SchedulerResource schedulerResource = new SchedulerResource();
        for (JobScheduleRequest jobScheduleRequest : scheduleList) {
          try {
            Response response = createSchedulerJob(schedulerResource, jobScheduleRequest);
            if (response.getStatus() == Response.Status.OK.getStatusCode()) {
              if (response.getEntity() != null) {
                // get the schedule job id from the response and add it to the import session
                ImportSession.getSession()
                    .addImportedScheduleJobId(response.getEntity().toString());
              }
            }
          } catch (Exception e) {
            // there is a scenario where if the file scheduled has a space in the path, that it
            // won't work. the di server
            // replaces spaces with underscores and the export mechanism can't determine if it needs
            // this to happen or not
            // so, if we failed to import and there is a space in the path, try again but this time
            // with replacing the space(s)
            if (jobScheduleRequest.getInputFile().contains(" ")
                || jobScheduleRequest.getOutputFile().contains(" ")) {
              log.info(
                  "Could not import schedule, attempting to replace spaces with underscores and retrying: "
                      + jobScheduleRequest.getInputFile());

              jobScheduleRequest.setInputFile(
                  jobScheduleRequest.getInputFile().replaceAll(" ", "_"));
              jobScheduleRequest.setOutputFile(
                  jobScheduleRequest.getOutputFile().replaceAll(" ", "_"));
              try {
                Response response = createSchedulerJob(schedulerResource, jobScheduleRequest);
                if (response.getStatus() == Response.Status.OK.getStatusCode()) {
                  if (response.getEntity() != null) {
                    // get the schedule job id from the response and add it to the import session
                    ImportSession.getSession()
                        .addImportedScheduleJobId(response.getEntity().toString());
                  }
                }
              } catch (Exception ex) {
                throw new PlatformImportException(
                    Messages.getInstance()
                        .getString(
                            "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE",
                            e.getMessage()));
              }
            } else {
              throw new PlatformImportException(
                  Messages.getInstance()
                      .getString(
                          "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE",
                          e.getMessage()));
            }
          }
        }
      }

      // Add Pentaho Connections
      List<org.pentaho.database.model.DatabaseConnection> datasourceList =
          manifest.getDatasourceList();
      if (datasourceList != null) {
        IDatasourceMgmtService datasourceMgmtSvc = PentahoSystem.get(IDatasourceMgmtService.class);
        for (org.pentaho.database.model.DatabaseConnection databaseConnection : datasourceList) {
          if (databaseConnection.getDatabaseType() == null) {
            // don't try to import the connection if there is no type it will cause an error
            // However, if this is the DI Server, and the connection is defined in a ktr, it will
            // import automatically
            log.warn(
                "Can't import connection "
                    + databaseConnection.getName()
                    + " because it doesn't have a databaseType");
            continue;
          }
          try {
            IDatabaseConnection existingDBConnection =
                datasourceMgmtSvc.getDatasourceByName(databaseConnection.getName());
            if (existingDBConnection != null && existingDBConnection.getName() != null) {
              if (isOverwriteFile()) {
                databaseConnection.setId(existingDBConnection.getId());
                datasourceMgmtSvc.updateDatasourceByName(
                    databaseConnection.getName(), databaseConnection);
              }
            } else {
              datasourceMgmtSvc.createDatasource(databaseConnection);
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    }
    // Process locale files.
    localeFilesProcessor.processLocaleFiles(importer);
  }