package com.github.lindenb.jvarkit.util.vcf; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Attribute; import javax.xml.stream.events.EndElement; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; import htsjdk.variant.variantcontext.Allele; import htsjdk.variant.variantcontext.VariantContext; import htsjdk.variant.variantcontext.VariantContextBuilder; import htsjdk.variant.vcf.VCFHeader; public class XMLVcfReader { private XMLEventReader in; private Allele parseAllele(StartElement root) throws XMLStreamException { boolean isRef=false; Attribute att=root.getAttributeByName(new QName("isRef")); if(att!=null && att.getValue().equals("true")) { isRef=true; } return Allele.create(in.getElementText(), isRef); } private VariantContext variant(StartElement root) throws XMLStreamException { String chrom=null; List<Allele> alleles=new ArrayList<Allele>(); while(in.hasNext()) { XMLEvent evt=in.nextEvent(); if(evt.isStartElement()) { StartElement SE=evt.asStartElement(); if(SE.getName().getLocalPart().equals("chrom")) { chrom=in.getElementText().trim(); } else if(SE.getName().getLocalPart().equals("allele")) { alleles.add(parseAllele(SE)); } } } VariantContextBuilder b=new VariantContextBuilder("", chrom, 0, 0, alleles); return b.make(); } private List<Object> _list(StartElement root) throws XMLStreamException { List<Object> L=new ArrayList<Object>(); while(in.hasNext()) { XMLEvent evt=in.nextEvent(); if(evt.isStartElement()) { StartElement E=evt.asStartElement(); L.add(_any(E)); } else if(evt.isEndElement()) { EndElement E=evt.asEndElement(); if(E.getName().equals(root.getName())) { return L; } } } throw new IllegalStateException("unclosed list"); } private Map<String,Object> _object(StartElement root) throws XMLStreamException { Map<String,Object> hash=new LinkedHashMap<String,Object>(); while(in.hasNext()) { XMLEvent evt=in.nextEvent(); if(evt.isStartElement()) { StartElement E=evt.asStartElement(); Attribute att=E.getAttributeByName(new QName("key")); if(att==null) throw new XMLStreamException("key missing"); if(hash.containsKey(att.getValue())) { throw new XMLStreamException("duplicate key "+att); } hash.put(att.getValue(), _any(E)); } else if(evt.isEndElement()) { EndElement E=evt.asEndElement(); if(E.getName().equals(root.getName())) { return hash; } } } throw new IllegalStateException("unclosed object"); } private Object _any(StartElement root) throws XMLStreamException { String name=root.getName().getLocalPart(); if(name.equals("list")) { return _list(root); } else if(name.equals("object")) { return _object(root); } throw new IllegalStateException("undefined "+name); } public XMLVcfReader(InputStream in) throws IOException { try { XMLInputFactory xif=XMLInputFactory.newFactory(); this.in=xif.createXMLEventReader(in); } catch(XMLStreamException err) { throw new IOException(err); } } public VCFHeader readHeader() throws IOException { return null; } public void close() throws IOException { if(in!=null) { try {in.close();} catch(XMLStreamException err) {throw new IOException(err);} in=null; } } public VariantContext next()throws IOException { if(in==null) return null; try { while(in.hasNext()) { XMLEvent evt=in.nextEvent(); if(evt.isStartElement()) { StartElement E=evt.asStartElement(); if(E.getName().getLocalPart().equals("variant")) { return variant(E); } } } close(); return null; } catch(XMLStreamException err) { throw new IOException(err); } } }