/******************************************************************************* * GenPlay, Einstein Genome Analyzer * Copyright (C) 2009, 2014 Albert Einstein College of Medicine * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * Authors: Julien Lajugie <julien.lajugie@einstein.yu.edu> * Nicolas Fourel <nicolas.fourel@einstein.yu.edu> * Eric Bouhassira <eric.bouhassira@einstein.yu.edu> * * Website: <http://genplay.einstein.yu.edu> ******************************************************************************/ package edu.yu.einstein.genplay.core.DAS; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import edu.yu.einstein.genplay.core.manager.project.ProjectManager; import edu.yu.einstein.genplay.core.multiGenome.utils.FormattedMultiGenomeName; import edu.yu.einstein.genplay.core.multiGenome.utils.ShiftCompute; import edu.yu.einstein.genplay.dataStructure.chromosome.Chromosome; import edu.yu.einstein.genplay.dataStructure.enums.AlleleType; import edu.yu.einstein.genplay.dataStructure.enums.Strand; import edu.yu.einstein.genplay.dataStructure.gene.Gene; import edu.yu.einstein.genplay.dataStructure.gene.SimpleGene; import edu.yu.einstein.genplay.dataStructure.list.chromosomeWideList.SCWListView.SCWListViewBuilder; import edu.yu.einstein.genplay.dataStructure.list.chromosomeWideList.SCWListView.generic.GenericSCWListViewBuilder; import edu.yu.einstein.genplay.dataStructure.list.chromosomeWideList.geneListView.GeneListViewBuilder; import edu.yu.einstein.genplay.dataStructure.list.listView.ListView; import edu.yu.einstein.genplay.dataStructure.list.listView.ListViewBuilder; import edu.yu.einstein.genplay.dataStructure.scoredChromosomeWindow.ScoredChromosomeWindow; /** * Parse a DNS XML file and extract the list of {@link Gene} * <br/>See <a href="http://www.biodas.org/documents/spec.html">http://www.biodas.org/documents/spec.html</a> * @author Julien Lajugie */ public class GeneHandler extends DefaultHandler { private final ListViewBuilder<Gene> geneLVBuilder; // list of genes private String currentMarkup = null; // current XML markup private String previousGroupID = null; private String groupID; // a group define a gene for the different exons private int start; // start position private int end; // stop position private float score; // score private Strand orientation; // strand private String name; // name private final Chromosome chromosome; // chromosome being extracted private SCWListViewBuilder exonLVBuilder; // builders for the list view of exon private String genomeName; // for multi-genome project only. Name of the genome on which the data were mapped private AlleleType alleleType; // for multi-genome project only. Type of allele for synchronization /** * Creates an instance of {@link GeneHandler} * @param chromosome current {@link Chromosome} */ public GeneHandler(Chromosome chromosome) { super(); geneLVBuilder = new GeneListViewBuilder(); this.chromosome = chromosome; } @Override public void characters(char[] ch, int start, int length) { if (currentMarkup != null) { String elementValue = new String(ch, start, length); if (currentMarkup.equals("START")) { this.start = Integer.parseInt(elementValue); } else if (currentMarkup.equals("END")) { end = Integer.parseInt(elementValue); } else if (currentMarkup.equals("ORIENTATION")) { orientation = Strand.get(elementValue.charAt(0)); } else if (currentMarkup.equals("SCORE")) { // if the score is not specified we set a NaN score value if (elementValue.trim().equals("-")) { score = Float.NaN; } else { score = Float.parseFloat(elementValue); } } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equalsIgnoreCase("FEATURE")) { // case where it's the first gene of the document if (previousGroupID == null) { previousGroupID = groupID; exonLVBuilder = new GenericSCWListViewBuilder(); } else if (!groupID.equalsIgnoreCase(previousGroupID)) { // if we have a new group we add the previous gene to the list ListView<ScoredChromosomeWindow> exonList = exonLVBuilder.getListView(); int start = exonList.get(0).getStart(); int stop = exonList.get(exonList.size() - 1).getStop(); // TODO check if we can retrieve the overall score of the gene Gene gene = new SimpleGene(name, orientation, start, stop, Float.NaN, exonList); geneLVBuilder.addElementToBuild(gene); previousGroupID = groupID; exonLVBuilder = new GenericSCWListViewBuilder(); } exonLVBuilder.addElementToBuild(getMultiGenomePosition(start), getMultiGenomePosition(end), score); } } /** * @return the alleleType */ public AlleleType getAlleleType() { return alleleType; } /** * @return the List of {@link Gene} */ public final ListView<Gene> getGeneList() { return geneLVBuilder.getListView(); } /** * @return the name of the genome on which the data were mapped. For multi-genome project only */ public String getGenomeName() { return genomeName; } /** * @param position current position * @return the associated associated meta genome position */ private int getMultiGenomePosition (int position) { if (ProjectManager.getInstance().isMultiGenomeProject()) { return ShiftCompute.getPosition(genomeName, alleleType, position, chromosome, FormattedMultiGenomeName.META_GENOME_NAME); } else { return position; } } /** * @param alleleType the alleleType to set */ public void setAlleleType(AlleleType alleleType) { this.alleleType = alleleType; } /** * @param genomeName for multi-genome project only. Name of the genome on which the data were mapped */ public void setGenomeName(String genomeName) { this.genomeName = genomeName; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("FEATURE")) { if(attributes.getLength() > 0) { name = attributes.getValue("label"); } } else if (qName.equalsIgnoreCase("START")) { currentMarkup = "START"; } else if (qName.equalsIgnoreCase("END")) { currentMarkup = "END"; } else if (qName.equalsIgnoreCase("SCORE")) { currentMarkup = "SCORE"; } else if (qName.equalsIgnoreCase("ORIENTATION")) { currentMarkup = "ORIENTATION"; } else if (qName.equalsIgnoreCase("GROUP")) { currentMarkup = "GROUP"; if(attributes.getLength() > 0) { groupID = attributes.getValue("id"); } } else { currentMarkup = null; } } }