diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableParser.java b/src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableParser.java new file mode 100644 index 0000000..3ed8a2b --- /dev/null +++ b/src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableParser.java @@ -0,0 +1,117 @@ +/** + * This file is a part of EpnTAPClient. + * This program aims to provide EPN-TAP support for software clients, like CASSIS spectrum analyzer. + * See draft specifications: https://voparis-confluence.obspm.fr/pages/viewpage.action?pageId=559861 + * Copyright (C) 2016 Institut de Recherche en Astrophysique et Planétologie. + * + * 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/>. + */ +package eu.omp.irap.vespa.epntapclient.votable.controller; + +import java.io.File; +import java.io.IOException; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.xml.sax.SAXException; + +import eu.omp.irap.vespa.epntapclient.utils.Log; +import eu.omp.irap.vespa.epntapclient.votable.model.VOTABLE; + +/** + * @author N. Jourdane + */ +public class VOTableParser { + + /** The path of the VOTable to verify the VOTable XML file. */ + private static final String VOTABLE_SHEMA = "http://www.ivoa.net/xml/VOTable/v"; + + /** + * The version of the VOTable with which VOTables will be parsed with JAXB (ie. the last + * published VOTable version by IVOA). + */ + private static final String JAXB_VOTABLE_VERSION = "1.3"; + + /** The VOTable package where are the generated .java which represents the VOTable model. */ + private static final String VOTABLE_MODEL_PACKAGE = "eu.omp.irap.vespa.epntapclient.votable.model"; + + /** + * @param voTablePath The path of the VOTable. + * @return The VOTable resulting of the XML document. + * @throws Exception Can not parse the VOTable. + */ + public static VOTABLE parseVOTable(String voTablePath) throws Exception { + changeVOTableSchemaLocation(voTablePath); + // TODO: modifier le nom de la 2ème balise INFO dans le XML plutôt que modifier le XSD. + VOTABLE voTable; + try { + JAXBContext jc = JAXBContext.newInstance(VOTABLE_MODEL_PACKAGE); + Unmarshaller unmarshaller = jc.createUnmarshaller(); + voTable = (VOTABLE) unmarshaller.unmarshal(new File(voTablePath)); + } catch (Exception e) { + throw new SAXException("Can not parse the VOTable.", e); + } + + return voTable; + } + + /** + * Change the version of the VOTable to the last supported version (1.3 as 2016/02/05). This + * allows JAXB to parse the VOTable even it's not the same namespace than the XSD. Because + * VOTables schemas are retro-compatibles, there is no problem to parse a VOTable with a XML + * schema with a higher version. In the same way, this method check if the file is a valid XML. + * + * @param voTablePath The path of the VOTable XML file. + * @throws Exception Can not read or write the XML file. + */ + private static void changeVOTableSchemaLocation(String voTablePath) + throws Exception { + try { + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); + Document doc = docBuilder.parse(voTablePath); + NamedNodeMap votAttrs = doc.getFirstChild().getAttributes(); + + String version = votAttrs.getNamedItem("version").getTextContent(); + if (version != JAXB_VOTABLE_VERSION) { + Log.LOGGER.info("VOTable version is " + version + ", changing VOTable svhema to " + + JAXB_VOTABLE_VERSION); + votAttrs.getNamedItem("xmlns").setTextContent(VOTABLE_SHEMA + JAXB_VOTABLE_VERSION); + } else { + Log.LOGGER.info("VOTable version is " + version + ", everything is ok."); + } + + // write the content into xml file + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + StreamResult result = new StreamResult(new File(voTablePath)); + transformer.transform(new DOMSource(doc), result); + + } catch (ParserConfigurationException pce) { + throw new Exception("Configuration error when parsing XML file " + voTablePath, pce); + } catch (TransformerException tfe) { + throw new Exception("Can not change VOTable version in XML file " + voTablePath, tfe); + } catch (IOException ioe) { + throw new Exception("Can read/write the XML file " + voTablePath, ioe); + } catch (SAXException sae) { + throw new Exception("Can not parse the XML file " + voTablePath, sae); + } + } +} -- libgit2 0.21.2