/**
  * Generates the file name of the done file, if supported by the underlying input type
  *
  * @param user the user who uploaded or will upload the file
  * @param inputType the file set type
  * @param fileUserIdentifier the file identifier
  * @param fileType the file type
  * @return the file name, starting with the directory path
  */
 protected String generateDoneFileName(
     Person user, BatchInputFileSetType inputType, String fileUserIdentifier, Date creationDate) {
   if (!isFileUserIdentifierProperlyFormatted(fileUserIdentifier)) {
     throw new IllegalArgumentException(
         "The file set identifier is not properly formatted: " + fileUserIdentifier);
   }
   return inputType.getDoneFileDirectoryPath()
       + File.separator
       + inputType.getDoneFileName(user, fileUserIdentifier, creationDate);
 }
  protected Map<String, File> copyStreamsToTemporaryDirectory(
      Person user,
      BatchInputFileSetType inputType,
      String fileUserIdentifier,
      Map<String, InputStream> typeToStreamMap,
      Date creationDate)
      throws FileStorageException {
    Map<String, File> tempFiles = new HashMap<String, File>();

    String tempDirectoryName = getTempDirectoryName();
    File tempDirectory = new File(tempDirectoryName);
    if (!tempDirectory.exists() || !tempDirectory.isDirectory()) {
      LOG.error(
          "Temporary Directory " + tempDirectoryName + " does not exist or is not a directory");
      throw new RuntimeException(
          "Temporary Directory " + tempDirectoryName + " does not exist or is not a directory");
    }

    byte[] buf = new byte[1024];

    try {
      for (String fileType : inputType.getFileTypes()) {
        String tempFileName =
            generateTempFileName(user, inputType, fileUserIdentifier, fileType, creationDate);
        InputStream source = typeToStreamMap.get(fileType);
        File tempFile = new File(tempFileName);
        copyInputStreamToFile(source, tempFile, buf);
        tempFiles.put(fileType, tempFile);
      }
    } catch (IOException e) {
      LOG.error("Error creating temporary files", e);
      throw new FileStorageException("Error creating temporary files", e);
    }
    return tempFiles;
  }
 /**
  * Generates the file name of a file (not the done file)
  *
  * @param user the user who uploaded or will upload the file
  * @param inputType the file set type
  * @param fileUserIdentifier the file identifier
  * @param fileType the file type
  * @return the file name, starting with the directory path
  */
 protected String generateTempFileName(
     Person user,
     BatchInputFileSetType inputType,
     String fileUserIdentifier,
     String fileType,
     Date creationDate) {
   if (!isFileUserIdentifierProperlyFormatted(fileUserIdentifier)) {
     throw new IllegalArgumentException(
         "The file set identifier is not properly formatted: " + fileUserIdentifier);
   }
   return getTempDirectoryName()
       + File.separator
       + inputType.getFileName(
           fileType, user.getPrincipalName(), fileUserIdentifier, creationDate);
 }
  /**
   * @see
   *     org.kuali.kfs.sys.batch.service.BatchInputFileSetService#isBatchInputTypeActive(org.kuali.kfs.sys.batch.BatchInputFileSetType)
   */
  public boolean isBatchInputTypeActive(BatchInputFileSetType batchInputFileSetType) {
    if (batchInputFileSetType == null) {
      LOG.error("an invalid(null) argument was given");
      throw new IllegalArgumentException("an invalid(null) argument was given");
    }
    List<String> activeInputTypes =
        new ArrayList<String>(
            SpringContext.getBean(ParameterService.class)
                .getParameterValuesAsString(
                    KfsParameterConstants.FINANCIAL_SYSTEM_BATCH.class,
                    SystemGroupParameterNames.ACTIVE_INPUT_TYPES_PARAMETER_NAME));

    boolean activeBatchType = false;
    if (activeInputTypes.size() > 0
        && activeInputTypes.contains(batchInputFileSetType.getFileSetTypeIdentifer())) {
      activeBatchType = true;
    }

    return activeBatchType;
  }
  /**
   * @see
   *     org.kuali.kfs.sys.batch.service.BatchInputFileSetService#save(org.kuali.rice.kim.api.identity.Person,
   *     org.kuali.kfs.sys.batch.BatchInputFileSetType, java.lang.String, java.util.Map)
   */
  public Map<String, String> save(
      Person user,
      BatchInputFileSetType inputType,
      String fileUserIdentifier,
      Map<String, InputStream> typeToStreamMap)
      throws AuthorizationException, FileStorageException {
    // add a step for file directory checking
    prepareDirectories(getRequiredDirectoryNames());

    Date creationDate = SpringContext.getBean(DateTimeService.class).getCurrentDate();
    // check user is authorized to upload a file for the batch type
    Map<String, File> typeToTempFiles =
        copyStreamsToTemporaryDirectory(
            user, inputType, fileUserIdentifier, typeToStreamMap, creationDate);

    // null the map, because it's full of exhausted input streams that are useless
    typeToStreamMap = null;

    if (!inputType.validate(typeToTempFiles)) {
      deleteTempFiles(typeToTempFiles);
      LOG.error(
          "Upload file validation failed for user "
              + user.getName()
              + " identifier "
              + fileUserIdentifier);
      throw new ValidationException(
          "File validation failed: " + GlobalVariables.getMessageMap().getErrorMessages());
    }

    byte[] buf = new byte[1024];

    Map<String, String> typeToFileNames = new LinkedHashMap<String, String>();
    Map<String, File> typeToFiles = new LinkedHashMap<String, File>();
    try {
      for (String fileType : inputType.getFileTypes()) {
        File tempFile = typeToTempFiles.get(fileType);
        String saveFileName =
            inputType.getDirectoryPath(fileType) + File.separator + tempFile.getName();
        try {
          InputStream fileContents = new FileInputStream(tempFile);
          File fileToSave = new File(saveFileName);

          copyInputStreamToFile(fileContents, fileToSave, buf);
          fileContents.close();
          typeToFileNames.put(fileType, saveFileName);
          typeToFiles.put(fileType, fileToSave);
        } catch (IOException e) {
          LOG.error("unable to save contents to file " + saveFileName, e);
          throw new RuntimeException("errors encountered while writing file " + saveFileName, e);
        }
      }
    } finally {
      deleteTempFiles(typeToTempFiles);
    }

    String doneFileName =
        inputType.getDoneFileDirectoryPath()
            + File.separator
            + inputType.getDoneFileName(user, fileUserIdentifier, creationDate);
    File doneFile = new File(doneFileName);
    try {
      doneFile.createNewFile();

      typeToFiles.put(KFSConstants.DONE_FILE_TYPE, doneFile);
    } catch (IOException e) {
      LOG.error("unable to create done file", e);
      throw new RuntimeException("unable to create done file", e);
    }

    inputType.process(typeToFiles);

    return typeToFileNames;
  }