src/main/java/fr/insee/eno/postprocessing/fo/FOInsertCoverPagePostprocessor.java
public class FOInsertCoverPagePostprocessor implements Postprocessor {

	private static final Logger logger = LoggerFactory.getLogger(FOInsertCoverPagePostprocessor.class);

	private XslTransformation saxonService = new XslTransformation();

	private static final String styleSheetPath = Constants.TRANSFORMATIONS_COVER_PAGE_FO_4PDF;

	@Override
	public File process(File input, byte[] parameters, String survey) throws Exception {

		File outputForFOFile = new File(input.getParent(),
				Constants.BASE_NAME_FORM_FILE +
				Constants.COVER_PAGE_FO_EXTENSION);
		logger.debug("Output folder for basic-form : " + outputForFOFile.getAbsolutePath());
		String surveyName = survey;
		String formName = getFormName(input);

		InputStream FO_XSL = Constants.getInputStreamFromPath(styleSheetPath);

		InputStream inputStream = FileUtils.openInputStream(input);
		OutputStream outputStream = FileUtils.openOutputStream(outputForFOFile);

		try {
			saxonService.transformFOToStep4FO(inputStream, outputStream, FO_XSL, surveyName, formName, parameters);
		}catch(Exception e) {
			String errorMessage = String.format("An error was occured during the %s transformation. %s : %s",
					toString(),
					e.getMessage(),
					Utils.getErrorLocation(styleSheetPath,e));
			logger.error(errorMessage);
			throw new EnoGenerationException(errorMessage);
		}

		inputStream.close();
		outputStream.close();
		FO_XSL.close();
		logger.info("End of InsertCoverPage post-processing " + outputForFOFile.getAbsolutePath());

		return outputForFOFile;
	}

	private String getFormName(File input) {
		return FilenameUtils.getBaseName(input.getParentFile().getParent());
	}

	public String toString() {
		return PostProcessing.FO_INSERT_COVER_PAGE.name();
	}

}
src/main/java/fr/insee/eno/postprocessing/fo/FOInsertAccompanyingMailsPostprocessor.java
public class FOInsertAccompanyingMailsPostprocessor implements Postprocessor {

	private static final Logger logger = LoggerFactory.getLogger(FOInsertAccompanyingMailsPostprocessor.class);

	private XslTransformation saxonService = new XslTransformation();

	private static final String styleSheetPath = Constants.TRANSFORMATIONS_ACCOMPANYING_MAILS_FO_4PDF;

	@Override
	public File process(File input, byte[] parameters, String survey) throws Exception {

		File outputForFOFile = new File(input.getParent(),
				Constants.BASE_NAME_FORM_FILE +
				Constants.FINAL_PDF_EXTENSION);
		logger.debug("Output folder for basic-form : " + outputForFOFile.getAbsolutePath());

		String surveyName = survey;
		String formName = getFormName(input);

		InputStream FO_XSL = Constants.getInputStreamFromPath(styleSheetPath);

		InputStream inputStream = FileUtils.openInputStream(input);
		OutputStream outputStream = FileUtils.openOutputStream(outputForFOFile);

		try {
			saxonService.transformFOToStep4FO(inputStream, outputStream, FO_XSL, surveyName, formName, parameters);
		}catch(Exception e) {
			String errorMessage = String.format("An error was occured during the %s transformation. %s : %s",
					toString(),
					e.getMessage(),
					Utils.getErrorLocation(styleSheetPath,e));
			logger.error(errorMessage);
			throw new EnoGenerationException(errorMessage);
		}

		inputStream.close();
		outputStream.close();
		FO_XSL.close();
		logger.info("End of InsertAccompanyingMails post-processing " + outputForFOFile.getAbsolutePath());

		return outputForFOFile;
	}

	private String getFormName(File input) {
		return FilenameUtils.getBaseName(input.getParentFile().getParent());
	}

	public String toString() {
		return PostProcessing.FO_INSERT_ACCOMPANYING_MAILS.name();
	}

}
src/main/java/fr/insee/eno/generation/DDI2FOGenerator.java
public class DDI2FOGenerator implements Generator {

	private static final Logger logger = LoggerFactory.getLogger(DDI2FOGenerator.class);

	private XslTransformation saxonService = new XslTransformation();

	private static final String styleSheetPath = Constants.TRANSFORMATIONS_DDI2FO_DDI2FO_XSL;

	@Override
	public File generate(File finalInput, byte[] parameters, String surveyName) throws Exception {
		logger.info("DDI2FO Target : START");
		logger.debug("Arguments : finalInput : " + finalInput + " surveyName " + surveyName);
		String formNameFolder = null;
		String outputBasicFormPath = null;

		formNameFolder = getFormNameFolder(finalInput);

		logger.debug("formNameFolder : " + formNameFolder);

		outputBasicFormPath = Constants.TEMP_FOLDER_PATH + "/" + surveyName + "/" + formNameFolder + "/form";
		logger.debug("Output folder for basic-form : " + outputBasicFormPath);

		String outputForm = outputBasicFormPath + "/form.fo";


		try (InputStream isTRANSFORMATIONS_DDI2FO_DDI2PDF_XSL = Constants
				.getInputStreamFromPath(styleSheetPath);
			 InputStream isFinalInput = FileUtils.openInputStream(finalInput);
				OutputStream osOutputForm = FileUtils.openOutputStream(new File(outputForm));) {
			
			saxonService.transformDDI2FO(isFinalInput, osOutputForm, isTRANSFORMATIONS_DDI2FO_DDI2PDF_XSL, parameters);
		}catch(Exception e) {
			String errorMessage = String.format("An error was occured during the %s transformation. %s : %s",
					in2out(),
					e.getMessage(),
					Utils.getErrorLocation(styleSheetPath,e));
			logger.error(errorMessage);
			throw new EnoGenerationException(errorMessage);
		}

		return new File(outputForm);
	}

	/**
	 * @param finalInput
	 * @return
	 */
	private String getFormNameFolder(File finalInput) {
		String formNameFolder;
		formNameFolder = FilenameUtils.getBaseName(finalInput.getAbsolutePath());
		formNameFolder = FilenameUtils.removeExtension(formNameFolder);
		formNameFolder = formNameFolder.replace(XslParameters.TITLED_EXTENSION, "");
		return formNameFolder;
	}

	public String in2out() {
		return "ddi2fo";
	}

}
src/main/java/fr/insee/eno/preprocessing/DDICleaningPreprocessor.java
public class DDICleaningPreprocessor implements Preprocessor {

	private static final Logger logger = LoggerFactory.getLogger(DDICleaningPreprocessor.class);

	private XslTransformation saxonService = new XslTransformation();

	private static final String styleSheetPath = Constants.UTIL_DDI_CLEANING_XSL;

	@Override
	public File process(File inputFile, byte[] parametersFile, String survey, String in2out) throws Exception {
		logger.info("DDIPreprocessing Target : START");

		String cleaningOutput=null;
		String cleaningInput = inputFile.getAbsolutePath();
		cleaningOutput = FilenameUtils.removeExtension(cleaningInput) + Constants.CLEANED_EXTENSION;

		logger.debug("Cleaned output file to be created : " + cleaningOutput);
		logger.debug("Cleaning : -Input : " + cleaningInput + " -Output : " + cleaningOutput + " -Stylesheet : "
				+ styleSheetPath);

		InputStream isCleaningIn = FileUtils.openInputStream(new File(cleaningInput));
		OutputStream osCleaning = FileUtils.openOutputStream(new File(cleaningOutput));
		InputStream isUTIL_DDI_CLEANING_XSL = Constants.getInputStreamFromPath(styleSheetPath);

		try {
			saxonService.transformCleaning(isCleaningIn, isUTIL_DDI_CLEANING_XSL, osCleaning, in2out);
		}catch(Exception e) {
			String errorMessage = String.format("An error was occured during the %s transformation. %s : %s",
					toString(),
					e.getMessage(),
					Utils.getErrorLocation(styleSheetPath,e));
			logger.error(errorMessage);
			throw new EnoGenerationException(errorMessage);
		}

		isCleaningIn.close();
		isUTIL_DDI_CLEANING_XSL.close();
		osCleaning.close();

		logger.debug("DDIPreprocessing Cleaning: END");
		return new File(cleaningOutput);
	}

	public String toString() {
		return PreProcessing.DDI_CLEANING.name();
	}


}
src/main/java/fr/insee/eno/postprocessing/fo/FOTableColumnPostprocessorFake.java
public class FOTableColumnPostprocessorFake implements Postprocessor {

	private static final Logger logger = LoggerFactory.getLogger(FOTableColumnPostprocessorFake.class);

	@Override
	public File process(File input, byte[] parameters, String survey) throws Exception {

		File outputForFOFile = new File(input.getParent(),
				Constants.BASE_NAME_FORM_FILE +
				Constants.TABLE_COL_SIZE_PDF_EXTENSION);
		logger.debug("Output folder for basic-form : " + outputForFOFile.getAbsolutePath());

		FileUtils.copyFile(input, outputForFOFile);

		logger.debug("End of TableColumn post-processing (Fake)");
		return outputForFOFile;

	}

	public String toString() {
		return PostProcessing.FO_TABLE_COLUMN.name();
	}
}
src/main/java/fr/insee/eno/preprocessing/DDITitlingPreprocessor.java
public class DDITitlingPreprocessor implements Preprocessor {

	private static final Logger logger = LoggerFactory.getLogger(DDITitlingPreprocessor.class);

	private XslTransformation saxonService = new XslTransformation();

	private static final String styleSheetPath = Constants.UTIL_DDI_TITLING_XSL;

	@Override
	public File process(File inputFile, byte[] parametersFile, String survey, String in2out) throws Exception {
		logger.info("DDIPreprocessing Target : START");

		String outputTitling = null;
		String titlingInput = inputFile.getAbsolutePath();

		outputTitling = titlingInput.replace(Constants.CLEANED_EXTENSION, Constants.FINAL_EXTENSION);

		logger.debug("Titling : -Input : " + titlingInput + " -Output : " + outputTitling + " -Stylesheet : "
				+ styleSheetPath + " -Parameters : "
				+ (parametersFile == null ? "Default parameters" : "Provided parameters"));

		InputStream isCleaningTitling = FileUtils.openInputStream(new File(titlingInput));
		InputStream isUTIL_DDI_TITLING_XSL = Constants.getInputStreamFromPath(styleSheetPath);
		OutputStream osTitling = FileUtils.openOutputStream(new File(outputTitling));

		try {
			saxonService.transformTitling(isCleaningTitling, isUTIL_DDI_TITLING_XSL, osTitling, parametersFile);
		}catch(Exception e) {
			String errorMessage = String.format("An error was occured during the %s transformation. %s : %s",
					toString(),
					e.getMessage(),
					Utils.getErrorLocation(styleSheetPath,e));
			logger.error(errorMessage);
			throw new EnoGenerationException(errorMessage);
		}

		isCleaningTitling.close();
		isUTIL_DDI_TITLING_XSL.close();
		osTitling.close();
		logger.debug("DDIPreprocessing titling: END");
		return new File(outputTitling);
	}

	public String toString() {
		return PreProcessing.DDI_TITLING.name();
	}

}
src/main/java/fr/insee/eno/postprocessing/fo/FOEditStructurePagesPostprocessor.java
public class FOEditStructurePagesPostprocessor implements Postprocessor {

	private static final Logger logger = LoggerFactory.getLogger(FOEditStructurePagesPostprocessor.class);

	private XslTransformation saxonService = new XslTransformation();

	private static final String styleSheetPath = Constants.TRANSFORMATIONS_EDIT_STRUCTURE_PAGES_FO_4PDF;

	@Override
	public File process(File input, byte[] parameters, String survey) throws Exception {

		File outputForFOFile = new File(input.getParent(),
				Constants.BASE_NAME_FORM_FILE +
				Constants.EDIT_STRUCTURE_FO_EXTENSION);
		logger.debug("Output folder for basic-form : " + outputForFOFile.getAbsolutePath());

		String surveyName = survey;
		String formName = getFormName(input);
		InputStream FO_XSL = Constants.getInputStreamFromPath(styleSheetPath);

		InputStream inputStream = FileUtils.openInputStream(input);
		OutputStream outputStream = FileUtils.openOutputStream(outputForFOFile);

		try {
			saxonService.transformFOToStep4FO(inputStream, outputStream, FO_XSL, surveyName, formName, parameters);
		}catch(Exception e) {
			String errorMessage = String.format("An error was occured during the %s transformation. %s : %s",
					toString(),
					e.getMessage(),
					Utils.getErrorLocation(styleSheetPath,e));
			logger.error(errorMessage);
			throw new EnoGenerationException(errorMessage);
		}

		inputStream.close();
		outputStream.close();
		FO_XSL.close();
		logger.info("End of EditStructurePages post-processing " + outputForFOFile.getAbsolutePath());

		return outputForFOFile;
	}

	private String getFormName(File input) {
		return FilenameUtils.getBaseName(input.getParentFile().getParent());
	}

	public String toString() {
		return PostProcessing.FO_EDIT_STRUCTURE_PAGES.name();
	}

}
src/main/java/fr/insee/eno/service/GenerationService.java
public class GenerationService {

	private static final Logger logger = LoggerFactory.getLogger(GenerationService.class);

	private final Preprocessor[] preprocessors;
	private final Generator generator;
	private final Postprocessor[] postprocessors;

	private byte[] parameters;
	private byte[] metadata;
	private byte[] specificTreatment;
	private byte[] mapping;
	
	private boolean cleaningFolder;

	@Inject
	public GenerationService(final Preprocessor[] preprocessors, final Generator generator,
			final Postprocessor[] postprocessors) {
		this.preprocessors = preprocessors;
		this.generator = generator;
		this.postprocessors = postprocessors;
		this.cleaningFolder = true;
	}

	@Inject
	public GenerationService(final Preprocessor preprocessor, final Generator generator,
			final Postprocessor[] postprocessors) {
		this.preprocessors = new Preprocessor[] { preprocessor };
		this.generator = generator;
		this.postprocessors = postprocessors;
		this.cleaningFolder = true;
	}

	@Inject
	public GenerationService(final Preprocessor preprocessor, final Generator generator,
			final Postprocessor postprocessor) {
		this.preprocessors = new Preprocessor[] { preprocessor };
		this.generator = generator;
		this.postprocessors = new Postprocessor[] { postprocessor };
		this.cleaningFolder = true;
	}

	/**
	 * Launch every step needed in order to generate the target questionnaire.
	 * 
	 * @param inputFile
	 *            The source file
	 * 
	 * @return The generated file
	 * @throws Exception
	 *             bim
	 */
	public File generateQuestionnaire(File inputFile, String surveyName) throws Exception {
		logger.info(this.toString());
		logger.info("Generating questionnaire for: " + surveyName);

		String tempFolder = System.getProperty("java.io.tmpdir") + "/" + surveyName;
		logger.debug("Temp folder: " + tempFolder);
		if(cleaningFolder) {
			cleanTempFolder(surveyName);
		}
		File preprocessResultFileName = null;
		
		preprocessResultFileName = this.preprocessors[0].process(inputFile, parameters, surveyName,generator.in2out());	
		
		for (int i = 1; i < preprocessors.length; i++) {
			preprocessResultFileName = this.preprocessors[i].process(preprocessResultFileName, parameters, surveyName,
					generator.in2out());
		}

		File generatedForm = this.generator.generate(preprocessResultFileName, parameters, surveyName);
		File outputForm = this.postprocessors[0].process(generatedForm, parameters, metadata, specificTreatment, mapping, surveyName);
		for (int i = 1; i < postprocessors.length; i++) {
			outputForm = this.postprocessors[i].process(outputForm, parameters, metadata, specificTreatment, mapping,surveyName);
		}
		File finalForm = new File(outputForm.getParent()+Constants.BASE_NAME_FORM_FILE+"."+FilenameUtils.getExtension(outputForm.getAbsolutePath()));
		if(!finalForm.equals(outputForm)) {
			Files.move(outputForm, finalForm);
		}
		logger.debug("Path to generated questionnaire: " + finalForm.getAbsolutePath());

		return finalForm;
	}
	
	
	public void setParameters(ByteArrayOutputStream parametersBAOS) {
		this.parameters = parametersBAOS.toByteArray();
	}	

	public void setParameters(InputStream parametersIS) throws IOException {
		if(parametersIS!=null) {
			this.parameters = IOUtils.toByteArray(parametersIS);
		}
	}
	
	public void setMetadata(InputStream metadataIS) throws IOException {
		if(metadataIS!=null) {
			this.metadata = IOUtils.toByteArray(metadataIS);
		}
	}
	
	public void setSpecificTreatment(InputStream specificTreatmentIS) throws IOException {
		if(specificTreatmentIS!=null) {
			this.specificTreatment = IOUtils.toByteArray(specificTreatmentIS);
		}
	}
	
	public void setMapping(InputStream mappingIS) throws IOException {
		if(mappingIS!=null) {
			this.mapping = IOUtils.toByteArray(mappingIS);
		}
	}

	public byte[] getParameters() {
		return parameters;
	}
	public byte[] getMetadata() {
		return metadata;
	}
	public byte[] getSpecificTreatment() {
		return specificTreatment;
	}
	public byte[] getMapping() {
		return mapping;
	}
	
	public void setCleaningFolder(boolean cleaning) {
		this.cleaningFolder = cleaning;
	}
	


	/**
	 * Clean the temp dir if it exists
	 * 
	 * @throws IOException
	 * 
	 */
	public void cleanTempFolder(String name) throws IOException {
		if (Constants.TEMP_FOLDER_PATH != null) {
			File folderTemp = new File(Constants.TEMP_FOLDER_PATH + "/" + name);
			cleanTempFolder(folderTemp);
		} else {
			logger.debug("Temp Folder is null");
		}
	}

	/**
	 * Clean the temp dir if it exists
	 * 
	 * @throws IOException
	 * 
	 */
	public void cleanTempFolder() throws IOException {
		if (Constants.TEMP_FOLDER_PATH != null) {
			File folderTemp = new File(Constants.TEMP_FOLDER_PATH);
			cleanTempFolder(folderTemp);
		} else {
			logger.debug("Temp Folder is null");
		}
	}

	/**
	 * Clean the temp dir if it exists
	 * 
	 * @throws IOException
	 * 
	 */
	private void cleanTempFolder(File folder) throws IOException {
		FolderCleaner cleanService = new FolderCleaner();
		if (folder != null) {
			cleanService.cleanOneFolder(folder);
		} else {
			logger.debug("Temp Folder is null");
		}
	}

	@Override
	public String toString() {
		return "GenerationService [preprocessors=" + Arrays.toString(preprocessors) + ", generator=" + generator.in2out()
				+ ", postprocessors=" + Arrays.toString(postprocessors) + "]";
	}
	
	

}
src/main/java/fr/insee/eno/preprocessing/Preprocessor.java
public interface Preprocessor {

	/**
	 * This method handles the preprocessing of an input file. TODO Exception is
	 * also weak, change to a more robust Exception
	 * 
	 * @param inputFile
	 *            The file to preprocess
	 * @param parameters
	 *            An optional parameters file
	 * @param survey
	 *            An optional parameters file
	 * @return the preprocessed file
	 * @throws Exception
	 *             when it goes wrong
	 */
	public File process(File inputFile, byte[] parameters, String survey, String in2out) throws Exception;

	public String toString();
}
src/main/java/fr/insee/eno/postprocessing/fo/FOMailingPostprocessor.java
public class FOMailingPostprocessor implements Postprocessor {

	private static final Logger logger = LoggerFactory.getLogger(FOMailingPostprocessor.class);

	private XslTransformation saxonService = new XslTransformation();

	private static final String styleSheetPath = Constants.TRANSFORMATIONS_CUSTOMIZATION_FO_4PDF_2;

	@Override
	public File process(File input, byte[] parameters, String surveyName) throws Exception {

		File outputForFOFile = new File(input.getParent(),
				Constants.BASE_NAME_FORM_FILE +
				Constants.MAILING_FO_EXTENSION);
		logger.debug("Output folder for basic-form : " + outputForFOFile.getAbsolutePath());	
		

		InputStream FO_XSL = Constants.getInputStreamFromPath(styleSheetPath);
		
		InputStream inputStream = FileUtils.openInputStream(input);
		OutputStream outputStream = FileUtils.openOutputStream(outputForFOFile);
		try {
			saxonService.transformFOToStep1FO(inputStream, outputStream, FO_XSL);
		}catch(Exception e) {
			String errorMessage = String.format("An error was occured during the %s transformation. %s : %s",
					toString(),
					e.getMessage(),
					Utils.getErrorLocation(styleSheetPath,e));
			logger.error(errorMessage);
			throw new EnoGenerationException(errorMessage);
		}
		
		inputStream.close();
		outputStream.close();
		FO_XSL.close();
		logger.info("End of Mailing post-processing : ");

		return outputForFOFile;
	}

	public String toString() {
		return PostProcessing.FO_MAILING.name();
	}

}
src/main/java/fr/insee/eno/preprocessing/DDIMarkdown2XhtmlPreprocessor.java
public class DDIMarkdown2XhtmlPreprocessor implements Preprocessor {

	private static final Logger logger = LoggerFactory.getLogger(DDIMarkdown2XhtmlPreprocessor.class);

	private XslTransformation saxonService = new XslTransformation();

	private static final String styleSheetPath = Constants.UTIL_DDI_MD2XHTML_XSL;

	@Override
	public File process(File input, byte[] parameters, String survey, String in2out) throws Exception {

		logger.info("DDIMarkdown2XhtmlPreprocessor Target : START");
		String md2xhtmlOutput = FilenameUtils.removeExtension(input.getPath()) + Constants.MD_EXTENSION;
		// ----- mw2xhtml
		logger.debug("Markdown to XHTML : -Input : " + input + " -Output : " + md2xhtmlOutput + " -Stylesheet : "
				+ Constants.UTIL_DDI_MD2XHTML_XSL + " -Parameters : " + Constants.sUB_TEMP_FOLDER(survey));

		InputStream isDDI_MW2XHTML_XSL = Constants.getInputStreamFromPath(styleSheetPath);
		InputStream isInputFile = FileUtils.openInputStream(input);

		OutputStream osTEMP_NULL_TMP = FileUtils.openOutputStream(new File(md2xhtmlOutput));

		try {
			saxonService.transformMw2XHTML(isInputFile, isDDI_MW2XHTML_XSL, osTEMP_NULL_TMP,
					Constants.SUB_TEMP_FOLDER_FILE(survey));
		}catch(Exception e) {
			String errorMessage = String.format("An error was occured during the Markdown2Xhtml transformation. %s : %s",
					e.getMessage(),
					Utils.getErrorLocation(styleSheetPath,e));
			logger.error(errorMessage);
			throw new EnoGenerationException(errorMessage);
		}
		isInputFile.close();
		isDDI_MW2XHTML_XSL.close();
		osTEMP_NULL_TMP.close();

		// ----- tweak-xhtml-for-ddi
		// tweak-xhtml-for-ddi-input = mw2xhtml-output

		String outputTweakXhtmlForDdi = FilenameUtils.removeExtension(input.getPath()) + Constants.MD2_EXTENSION;

		logger.debug("Tweak-xhtml-for-ddi : -Input : " + md2xhtmlOutput + " -Output : " + outputTweakXhtmlForDdi
				+ " -Stylesheet : " + Constants.UTIL_DDI_TWEAK_XHTML_FOR_DDI_XSL + " -Parameters : "
				+ (parameters == null ? "Default parameters" : "Provided parameters"));

		InputStream isTweakXhtmlForDdi = FileUtils.openInputStream(new File(md2xhtmlOutput));
		InputStream isUTIL_DDI_TWEAK_XHTML_FOR_DDI_XSL = Constants
				.getInputStreamFromPath(Constants.UTIL_DDI_TWEAK_XHTML_FOR_DDI_XSL);
		OutputStream osTweakXhtmlForDdi = FileUtils.openOutputStream(new File(outputTweakXhtmlForDdi));
		try {
			saxonService.transformTweakXhtmlForDdi(isTweakXhtmlForDdi, isUTIL_DDI_TWEAK_XHTML_FOR_DDI_XSL,
					osTweakXhtmlForDdi, Constants.SUB_TEMP_FOLDER_FILE(survey));
		}catch(Exception e) {
			String errorMessage = "An error has occurred during the Markdown2Xhtml transformation. "+e.getMessage();
			logger.error(errorMessage);
			throw new EnoGenerationException(errorMessage);
		}
		isTweakXhtmlForDdi.close();
		isUTIL_DDI_TWEAK_XHTML_FOR_DDI_XSL.close();
		osTweakXhtmlForDdi.close();

		logger.debug("DDIMarkdown2XhtmlPreprocessor : END");
		return new File(outputTweakXhtmlForDdi);

	}

}
src/main/java/fr/insee/eno/postprocessing/fo/FOSpecificTreatmentPostprocessor.java
public class FOSpecificTreatmentPostprocessor implements Postprocessor {

	private static final Logger logger = LoggerFactory.getLogger(FOSpecificTreatmentPostprocessor.class);

	private XslTransformation saxonService = new XslTransformation();

	@Override
	public File process(File input, byte[] parameters, String survey) throws Exception {
		return this.process(input, parameters, null, null, survey);
	}

	@Override
	public File process(File input, byte[] parametersFile, byte[] metadata, String survey) throws Exception {
		return this.process(input, parametersFile, metadata, null, survey);
	}

	@Override
	public File process(File input, byte[] parametersFile, byte[] metadata, byte[] specificTreatmentXsl, String survey) throws Exception {

		File outputForFOFile = new File(input.getParent(),
				Constants.BASE_NAME_FORM_FILE +
				Constants.SPECIFIC_TREAT_PDF_EXTENSION);
		logger.debug("Output folder for basic-form : " + outputForFOFile.getAbsolutePath());

		InputStream specificTreatmentXslIS = null;

		if(specificTreatmentXsl!=null) {
			specificTreatmentXslIS = new ByteArrayInputStream(specificTreatmentXsl);
			InputStream inputStream = FileUtils.openInputStream(input);
			OutputStream outputStream = FileUtils.openOutputStream(outputForFOFile);

			try {
				saxonService.transformWithPDFSpecificTreatment(inputStream, outputStream, specificTreatmentXslIS, parametersFile);
			}catch(Exception e) {
				String errorMessage = String.format("An error was occured during the %s transformation. %s : %s",
						toString(),
						e.getMessage(),
						Utils.getErrorLocation("specific file passed in params",e));
				logger.error(errorMessage);
				throw new EnoGenerationException(errorMessage);
			}
			inputStream.close();
			outputStream.close();
			specificTreatmentXslIS.close();

		}
		else {
			logger.info("Not specific treatment in params : simply copying this file" + input.getAbsolutePath());
			FileUtils.copyFile(input, outputForFOFile);
		}
		logger.info("End of specific treatment post-processing " + outputForFOFile.getAbsolutePath());

		return outputForFOFile;
	}

	public String toString() {
		return PostProcessing.FO_SPECIFIC_TREATMENT.name();
	}

}
src/main/java/fr/insee/eno/preprocessing/DDIMultimodalSelectionPreprocessor.java
public class DDIMultimodalSelectionPreprocessor implements Preprocessor {
	
	private static final Logger logger = LoggerFactory.getLogger(DDIMultimodalSelectionPreprocessor.class);

	private XslTransformation saxonService = new XslTransformation();

	private static final String styleSheetPath = Constants.UTIL_DDI_MULTIMODAL_SELECTION_XSL;

	@Override
	public File process(File inputFile, byte[] parametersFile, String survey, String in2out) throws Exception {
		logger.info("DDIPreprocessing Target : START");

		String sUB_TEMP_FOLDER = Constants.sUB_TEMP_FOLDER(survey);
		String modalSelectionOutput=null;
		String multimodalInput = inputFile.getAbsolutePath();
		modalSelectionOutput = sUB_TEMP_FOLDER + "\\" + FilenameUtils.getBaseName(multimodalInput) + Constants.MULTIMODAL_EXTENSION;

		logger.debug("Modal DDI output file to be created : " + modalSelectionOutput);
		logger.debug("Multimodal Selection : -Input : " + multimodalInput + " -Output : " + modalSelectionOutput + " -Stylesheet : "
				+ styleSheetPath + " -Parameters : " + (parametersFile == null ? "Default parameters" : "Provided parameters"));

		InputStream isMultimodalIn = FileUtils.openInputStream(new File(multimodalInput));
		OutputStream osModalSelection = FileUtils.openOutputStream(new File(modalSelectionOutput));
		InputStream isUTIL_DDI_MULTIMODAL_SELECTION_XSL = Constants.getInputStreamFromPath(styleSheetPath);

		try {
			saxonService.transformModalSelection(isMultimodalIn, isUTIL_DDI_MULTIMODAL_SELECTION_XSL, osModalSelection, parametersFile);
		}catch(Exception e) {
			String errorMessage = String.format("An error has occurred during the %s transformation. %s : %s",
					toString(),
					e.getMessage(),
					Utils.getErrorLocation(styleSheetPath,e));
			logger.error(errorMessage);
			throw new EnoGenerationException(errorMessage);
		}

		isMultimodalIn.close();
		isUTIL_DDI_MULTIMODAL_SELECTION_XSL.close();
		osModalSelection.close();

		logger.debug("DDIPreprocessing Multimodal Selection: END");
		return new File(modalSelectionOutput);
	}

	public String toString() {
		return PreProcessing.DDI_MULTIMODAL_SELECTION.name();
	}

	
}
src/main/java/fr/insee/eno/preprocessing/DDIDereferencingPreprocessor.java
public class DDIDereferencingPreprocessor implements Preprocessor {

	private static final Logger logger = LoggerFactory.getLogger(DDIDereferencingPreprocessor.class);

	private XslTransformation saxonService = new XslTransformation();

	private static final String styleSheetPath = Constants.UTIL_DDI_DEREFERENCING_XSL;

	@Override
	public File process(File inputFile, byte[] parametersFile, String survey, String in2out) throws Exception {
		logger.info("DDIPreprocessing Target : START");

		String sUB_TEMP_FOLDER = Constants.sUB_TEMP_FOLDER(survey);
		// ----- Dereferencing
		logger.debug("Dereferencing : -Input : " + inputFile + " -Output : " + Constants.tEMP_NULL_TMP(sUB_TEMP_FOLDER)
		+ " -Stylesheet : " + styleSheetPath + " -Parameters : " + sUB_TEMP_FOLDER);

		InputStream isDDI_DEREFERENCING_XSL = Constants.getInputStreamFromPath(styleSheetPath);
		InputStream isInputFile = FileUtils.openInputStream(inputFile);
		OutputStream osTEMP_NULL_TMP = FileUtils.openOutputStream(Constants.tEMP_NULL_TMP(sUB_TEMP_FOLDER));

		try {
			saxonService.transformDereferencing(isInputFile, isDDI_DEREFERENCING_XSL, osTEMP_NULL_TMP,
					Constants.SUB_TEMP_FOLDER_FILE(survey));
		}catch(Exception e) {
			String errorMessage = String.format("An error was occured during the %s transformation. %s : %s",
					toString(),
					e.getMessage(),
					Utils.getErrorLocation(styleSheetPath,e));
			logger.error(errorMessage);
			throw new EnoGenerationException(errorMessage);
		}

		isInputFile.close();
		isDDI_DEREFERENCING_XSL.close();
		osTEMP_NULL_TMP.close();
		// ----- Cleaning
		logger.debug("Cleaning target");
		File f = Constants.SUB_TEMP_FOLDER_FILE(survey);
		File[] matchCleaningInput = f.listFiles(new FilenameFilter() {

			@Override
			public boolean accept(File dir, String name) {
				return !(name.startsWith("null")||name.contains("-modal")) && name.endsWith(".tmp");
			}
		});

		String cleaningInput = null;

		logger.debug("Searching matching files in : " + sUB_TEMP_FOLDER);
		for (File file : matchCleaningInput) {
			if(!file.isDirectory()) {
				cleaningInput = file.getAbsolutePath();
				logger.debug("Found : " + cleaningInput);
			}
		}
		if(cleaningInput==null) {
			throw new EnoGenerationException("DDIDereferencing produced no file.");
		}

		logger.debug("DDIPreprocessing Dereferencing : END");
		return new File(cleaningInput);
	}

	public String toString() {
		return PreProcessing.DDI_DEREFERENCING.name();
	}


}
src/main/java/fr/insee/eno/postprocessing/Postprocessor.java
public interface Postprocessor {

	File process(File input, byte[] parametersFile, String survey) throws Exception;

	default File process(File input, byte[] parametersFile, byte[] metadata, String survey) throws Exception{
		return this.process(input,parametersFile,survey);
	}
	
	default File process(File input, byte[] parametersFile, byte[] metadata, byte[] specificTreatmentXsl, String survey) throws Exception{
		return this.process(input,parametersFile,metadata,survey);
	}
	
	default File process(File input, byte[] parametersFile, byte[] metadata, byte[] specificTreatmentXsl, byte[] mapping, String survey) throws Exception{
		return this.process(input,parametersFile,metadata,specificTreatmentXsl,survey);
	}
	
	public String toString();
}
src/main/java/fr/insee/eno/postprocessing/fo/FOInsertEndQuestionPostprocessor.java
public class FOInsertEndQuestionPostprocessor implements Postprocessor {

	private static final Logger logger = LoggerFactory.getLogger(FOInsertEndQuestionPostprocessor.class);

	private XslTransformation saxonService = new XslTransformation();

	private static final String styleSheetPath = Constants.TRANSFORMATIONS_END_QUESTION_FO_4PDF;

	@Override
	public File process(File input, byte[] parameters, String survey) throws Exception {

		File outputForFOFile = new File(input.getParent(),
				Constants.BASE_NAME_FORM_FILE +
				Constants.END_QUESTION_FO_EXTENSION);
		logger.debug("Output folder for basic-form : " + outputForFOFile.getAbsolutePath());

		String surveyName = survey;
		String formName = getFormName(input);

		InputStream FO_XSL = Constants.getInputStreamFromPath(styleSheetPath);

		InputStream inputStream = FileUtils.openInputStream(input);
		OutputStream outputStream = FileUtils.openOutputStream(outputForFOFile);

		try {
			saxonService.transformFOToStep4FO(inputStream, outputStream, FO_XSL, surveyName, formName, parameters);
		}catch(Exception e) {
			String errorMessage = String.format("An error was occured during the %s transformation. %s : %s",
					toString(),
					e.getMessage(),
					Utils.getErrorLocation(styleSheetPath,e));
			logger.error(errorMessage);
			throw new EnoGenerationException(errorMessage);
		}

		inputStream.close();
		outputStream.close();
		FO_XSL.close();
		logger.info("End of InsertEndQuestion post-processing " + outputForFOFile.getAbsolutePath());

		return outputForFOFile;
	}

	private String getFormName(File input) {
		return FilenameUtils.getBaseName(input.getParentFile().getParent());
	}

	public String toString() {
		return PostProcessing.FO_INSERT_END_QUESTION.name();
	}

}


Question: package fr.insee.eno.main;
import java.io.File;
import org.junit.jupiter.api.Test;
import fr.insee.eno.generation.DDI2FOGenerator;
import fr.insee.eno.postprocessing.Postprocessor;
import fr.insee.eno.postprocessing.fo.FOEditStructurePagesPostprocessor;
import fr.insee.eno.postprocessing.fo.FOInsertAccompanyingMailsPostprocessor;
import fr.insee.eno.postprocessing.fo.FOInsertCoverPagePostprocessor;
import fr.insee.eno.postprocessing.fo.FOInsertEndQuestionPostprocessor;
import fr.insee.eno.postprocessing.fo.FOMailingPostprocessor;
import fr.insee.eno.postprocessing.fo.FOSpecificTreatmentPostprocessor;
import fr.insee.eno.postprocessing.fo.FOTableColumnPostprocessorFake;
import fr.insee.eno.service.GenerationService;
import fr.insee.eno.preprocessing.DDICleaningPreprocessor;
import fr.insee.eno.preprocessing.DDIDereferencingPreprocessor;
import fr.insee.eno.preprocessing.DDIMarkdown2XhtmlPreprocessor;
import fr.insee.eno.preprocessing.DDIMultimodalSelectionPreprocessor;
import fr.insee.eno.preprocessing.DDITitlingPreprocessor;
import fr.insee.eno.preprocessing.Preprocessor;




public class DummyTestDDI2FO {
	
	private DDI2FOGenerator ddi2fo = new DDI2FOGenerator();
	
	@Test
	public void mainTest() {		
		String basePathDDI2FO = "src/test/resources/ddi-to-fo";
		
		Preprocessor[] preprocessors = {

				new DDIMultimodalSelectionPreprocessor(),
				new DDIMarkdown2XhtmlPreprocessor(),
				new DDIDereferencingPreprocessor(),
				new DDICleaningPreprocessor(),
				new DDITitlingPreprocessor()};
		
		Postprocessor[] postprocessors = { 
				new FOMailingPostprocessor(),
				new FOTableColumnPostprocessorFake(),
				new FOInsertEndQuestionPostprocessor(),
				new FOEditStructurePagesPostprocessor(),
				new FOSpecificTreatmentPostprocessor(),
				new FOInsertCoverPagePostprocessor(),
				new FOInsertAccompanyingMailsPostprocessor()};
		
Answer: 		GenerationService genServiceDDI2PDF = new GenerationService(preprocessors, ddi2fo, postprocessors);