/* * Eoulsan development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public License version 2.1 or * later and CeCILL-C. This should be distributed with the code. * If you do not have a copy, see: * * http://www.gnu.org/licenses/lgpl-2.1.txt * http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt * * Copyright for this code is held jointly by the Genomic platform * of the Institut de Biologie de l'École normale supérieure and * the individual authors. These should be listed in @author doc * comments. * * For more information on the Eoulsan project and its aims, * or to join the Eoulsan Google group, visit the home page * at: * * http://outils.genomique.biologie.ens.fr/eoulsan * */ package fr.ens.biologie.genomique.eoulsan.translators; import static com.google.common.base.Preconditions.checkNotNull; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; import fr.ens.biologie.genomique.eoulsan.Globals; import fr.ens.biologie.genomique.eoulsan.Settings; import fr.ens.biologie.genomique.eoulsan.data.DataFile; import fr.ens.biologie.genomique.eoulsan.translators.io.MultiColumnTranslatorReader; import fr.ens.biologie.genomique.eoulsan.translators.io.TranslatorOutputFormat; /** * This class implements utility methods for translators. * @since 2.0 * @author Laurent Jourdren */ public class TranslatorUtils { /** * Create a file with additional annotation. * @param inputFile input file * @param fieldToTranslate field to use with translator * @param translator translator to use * @throws FileNotFoundException if a file cannot be found * @throws IOException if an error occurs while creating the output file */ public static void addTranslatorFields(final File inputFile, final int fieldToTranslate, final Translator translator, final TranslatorOutputFormat of) throws FileNotFoundException, IOException { addTranslatorFields(new FileInputStream(inputFile), fieldToTranslate, translator, of); } /** * Create a file with additional annotation. * @param is input stream of the file * @param fieldToTranslate field to use with translator * @param translator translator to use * @throws IOException if an error occurs while creating the output file */ public static void addTranslatorFields(final InputStream is, final int fieldToTranslate, final Translator translator, final TranslatorOutputFormat of) throws IOException { if (is == null) { throw new NullPointerException("InputStream is null"); } if (translator == null) { throw new NullPointerException("Translator is null"); } if (of == null) { throw new NullPointerException("OutputFormat is null"); } List<String> translatorFieldnames = translator.getFields(); final BufferedReader reader = new BufferedReader(new InputStreamReader(is, Globals.DEFAULT_CHARSET)); String line; boolean first = true; while ((line = reader.readLine()) != null) { final List<String> fields = new ArrayList<>(Arrays.asList(line.split("\t"))); if (first) { // Write original file header for (String field : fields) { of.addHeaderField(field); } // Write original file header for (String translatorFieldname : translatorFieldnames) { of.addHeaderField(translatorFieldname); } first = false; } else { of.newLine(); // Write original file data for (String field1 : fields) { try { of.writeDouble(Double.parseDouble(field1)); } catch (NumberFormatException e) { of.writeText(field1); } } // Write annotation for (final String field : translatorFieldnames) { final String valueToTranslate = fields.get(fieldToTranslate); final String value; if (field == null) { value = null; } else { value = translator.translateField(valueToTranslate, field); } String link; if (value == null || !translator.isLinkInfo(field)) { link = null; } else { link = translator.getLinkInfo(value, field); } if (value == null) { of.writeEmpty(); } else { if (link == null) { of.writeText(value); } else { of.writeLink(value, link); } } } } } reader.close(); of.close(); } /** * Create a translator that contains one column named "EnsemblID" that * duplicate the Id if the the is an EnsemblID * @return a new translator */ private static Translator createDuplicatedEnsemblIdTranslator() { return new AbstractTranslator() { private static final String FIELD_NAME = "EnsemblID"; private final Pattern pattern = Pattern.compile("ENS[A-Z]+[0-9]{11}"); @Override public String translateField(final String id, final String field) { if (id == null || field == null) { return null; } if (FIELD_NAME.equals(field) && pattern.matcher(id).matches()) { return id; } return null; } @Override public List<String> getFields() { return Collections.singletonList(FIELD_NAME); } }; } /** * Update the links of a CommonLinksInfoTranslator from the content of a file. * @param translator the translator to update * @param linksFile the links file that can be null * @throws IOException if an error occurs while reading the link file */ private static void updateLinks(CommonLinksInfoTranslator translator, final DataFile linksFile) throws IOException { // Load annotation hypertext links if (linksFile != null) { // Check if the file exists if (!linksFile.exists()) { throw new IOException(linksFile + " doesn't exists."); } // Load the file translator.load(linksFile.open()); } } /** * Create a translator annotation from an additional annotation file and a * link file. * @param annotationFile the annotation file to use * @param linksFile the additional annotation hypertext links file * @return a Translator object with the additional annotation * @throws IOException if an error occurs while reading additional annotation */ public static Translator loadTranslator(final DataFile annotationFile, final DataFile linksFile) throws IOException { checkNotNull(annotationFile, "annotationFile argument cannot be null"); final Translator did = createDuplicatedEnsemblIdTranslator(); final CommonLinksInfoTranslator translator = new CommonLinksInfoTranslator(new ConcatTranslator(did, new MultiColumnTranslatorReader(annotationFile.open()).read())); // Load hypertext links updateLinks(translator, linksFile); return translator; } /** * Create a translator annotation from a link file. * @param linksFile the additional annotation hypertext links file * @return a Translator object with the additional annotation * @throws IOException if an error occurs while reading additional annotation */ public static Translator loadTranslator(final DataFile linksFile) throws IOException { final CommonLinksInfoTranslator translator = new CommonLinksInfoTranslator(createDuplicatedEnsemblIdTranslator()); // Load hypertext links updateLinks(translator, linksFile); return translator; } /** * Get the links file from the settings. * @param settings the settings object * @return a DataFile with the path to the link file or null if the link file * has not been defined in the settings */ public static DataFile getLinksFileFromSettings(final Settings settings) { if (settings == null) { throw new NullPointerException("settings argument cannot be null"); } final String value = settings.getAdditionalAnnotationHypertextLinksPath(); if (value == null) { return null; } return new DataFile(value); } // // Constructor // private TranslatorUtils() { } }