package org.molgenis.annotation.cmd.utils; import java.io.*; import java.util.Date; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; import static org.apache.commons.io.FilenameUtils.removeExtension; public class VcfValidator { private String vcfValidatorLocation; public VcfValidator(String vcfValidatorLocation) { this.vcfValidatorLocation = vcfValidatorLocation; } /** * Validation method that calls the perl executable of the vcf-validator. Logs vcf validation output into a log file * * @param vcfFile The VCF file generated by the annotation process * @return Success or fail message * @throws IOException */ public String validateVCF(File vcfFile) throws IOException { BufferedWriter bufferedWriter = null; Scanner inputScanner = null; Scanner errorScanner = null; try { ProcessBuilder processBuilder = new ProcessBuilder(vcfValidatorLocation, vcfFile.getAbsolutePath(), "-u", "-d").directory(new File(vcfValidatorLocation).getParentFile()); Process proc = processBuilder.start(); // Checks if vcf-tools is present if (vcfValidatorLocation == null || !new File(vcfValidatorLocation).exists()) { return "No vcf-validator present, skipping validation."; } String line = ""; Integer errorCount = null; Pattern p = Pattern.compile("(\\d+)\\s*errors\\s*total"); String fileNameWithoutExtension = removeExtension(vcfFile.getName()); File logFile = new File(fileNameWithoutExtension + "-validation.log"); if (!logFile.exists()) { logFile.createNewFile(); } Date date = new Date(); bufferedWriter = new BufferedWriter( new OutputStreamWriter(new FileOutputStream(logFile.getAbsolutePath()), "UTF-8")); bufferedWriter.write("### Validation report for " + vcfFile.getName() + "\n"); bufferedWriter.write("### Validation date: " + date + "\n"); inputScanner = new Scanner(proc.getInputStream(), "UTF-8"); errorScanner = new Scanner(proc.getErrorStream(), "UTF-8"); while (proc.isAlive() || inputScanner.hasNext() || errorScanner.hasNext()) { while (errorScanner.hasNext()) { line = errorScanner.nextLine(); bufferedWriter.append("ERR> " + line + "\n"); } while (inputScanner.hasNext()) { line = inputScanner.nextLine(); bufferedWriter.append(line + "\n"); Matcher m = p.matcher(line); if (m.find()) { errorCount = Integer.parseInt(m.group(1)); } } } bufferedWriter.write("\n##################################################\n"); if (errorCount != null && errorCount == 0) { return "VCF file [" + vcfFile.getName() + "] passed validation."; } else { return "VCF file [" + vcfFile.getName() + "] did not pass validation, see the log for more details."; } } catch (IOException e) { throw new RuntimeException("Something went wrong: " + e); } finally { tryClose(bufferedWriter); tryClose(inputScanner); tryClose(errorScanner); } } private void tryClose(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (Exception ignore) { } } } }