Commit 240ca5ba7fd89681597bd05c106eb6e3634f4b14

Authored by Nathanael Jourdane
1 parent 74010bdb
Exists in master

Add the VOTable parser

src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableParser.java 0 → 100644
... ... @@ -0,0 +1,117 @@
  1 +/**
  2 + * This file is a part of EpnTAPClient.
  3 + * This program aims to provide EPN-TAP support for software clients, like CASSIS spectrum analyzer.
  4 + * See draft specifications: https://voparis-confluence.obspm.fr/pages/viewpage.action?pageId=559861
  5 + * Copyright (C) 2016 Institut de Recherche en Astrophysique et Planétologie.
  6 + *
  7 + * This program is free software: you can
  8 + * redistribute it and/or modify it under the terms of the GNU General Public License as published
  9 + * by the Free Software Foundation, either version 3 of the License, or (at your option) any later
  10 + * version. This program is distributed in the hope that it will be useful, but WITHOUT ANY
  11 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12 + * PURPOSE. See the GNU General Public License for more details. You should have received a copy of
  13 + * the GNU General Public License along with this program. If not, see
  14 + * <http://www.gnu.org/licenses/>.
  15 + */
  16 +package eu.omp.irap.vespa.epntapclient.votable.controller;
  17 +
  18 +import java.io.File;
  19 +import java.io.IOException;
  20 +
  21 +import javax.xml.bind.JAXBContext;
  22 +import javax.xml.bind.Unmarshaller;
  23 +import javax.xml.parsers.DocumentBuilder;
  24 +import javax.xml.parsers.DocumentBuilderFactory;
  25 +import javax.xml.parsers.ParserConfigurationException;
  26 +import javax.xml.transform.Transformer;
  27 +import javax.xml.transform.TransformerException;
  28 +import javax.xml.transform.TransformerFactory;
  29 +import javax.xml.transform.dom.DOMSource;
  30 +import javax.xml.transform.stream.StreamResult;
  31 +
  32 +import org.w3c.dom.Document;
  33 +import org.w3c.dom.NamedNodeMap;
  34 +import org.xml.sax.SAXException;
  35 +
  36 +import eu.omp.irap.vespa.epntapclient.utils.Log;
  37 +import eu.omp.irap.vespa.epntapclient.votable.model.VOTABLE;
  38 +
  39 +/**
  40 + * @author N. Jourdane
  41 + */
  42 +public class VOTableParser {
  43 +
  44 + /** The path of the VOTable to verify the VOTable XML file. */
  45 + private static final String VOTABLE_SHEMA = "http://www.ivoa.net/xml/VOTable/v";
  46 +
  47 + /**
  48 + * The version of the VOTable with which VOTables will be parsed with JAXB (ie. the last
  49 + * published VOTable version by IVOA).
  50 + */
  51 + private static final String JAXB_VOTABLE_VERSION = "1.3";
  52 +
  53 + /** The VOTable package where are the generated .java which represents the VOTable model. */
  54 + private static final String VOTABLE_MODEL_PACKAGE = "eu.omp.irap.vespa.epntapclient.votable.model";
  55 +
  56 + /**
  57 + * @param voTablePath The path of the VOTable.
  58 + * @return The VOTable resulting of the XML document.
  59 + * @throws Exception Can not parse the VOTable.
  60 + */
  61 + public static VOTABLE parseVOTable(String voTablePath) throws Exception {
  62 + changeVOTableSchemaLocation(voTablePath);
  63 + // TODO: modifier le nom de la 2ème balise INFO dans le XML plutôt que modifier le XSD.
  64 + VOTABLE voTable;
  65 + try {
  66 + JAXBContext jc = JAXBContext.newInstance(VOTABLE_MODEL_PACKAGE);
  67 + Unmarshaller unmarshaller = jc.createUnmarshaller();
  68 + voTable = (VOTABLE) unmarshaller.unmarshal(new File(voTablePath));
  69 + } catch (Exception e) {
  70 + throw new SAXException("Can not parse the VOTable.", e);
  71 + }
  72 +
  73 + return voTable;
  74 + }
  75 +
  76 + /**
  77 + * Change the version of the VOTable to the last supported version (1.3 as 2016/02/05). This
  78 + * allows JAXB to parse the VOTable even it's not the same namespace than the XSD. Because
  79 + * VOTables schemas are retro-compatibles, there is no problem to parse a VOTable with a XML
  80 + * schema with a higher version. In the same way, this method check if the file is a valid XML.
  81 + *
  82 + * @param voTablePath The path of the VOTable XML file.
  83 + * @throws Exception Can not read or write the XML file.
  84 + */
  85 + private static void changeVOTableSchemaLocation(String voTablePath)
  86 + throws Exception {
  87 + try {
  88 + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
  89 + DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
  90 + Document doc = docBuilder.parse(voTablePath);
  91 + NamedNodeMap votAttrs = doc.getFirstChild().getAttributes();
  92 +
  93 + String version = votAttrs.getNamedItem("version").getTextContent();
  94 + if (version != JAXB_VOTABLE_VERSION) {
  95 + Log.LOGGER.info("VOTable version is " + version + ", changing VOTable svhema to "
  96 + + JAXB_VOTABLE_VERSION);
  97 + votAttrs.getNamedItem("xmlns").setTextContent(VOTABLE_SHEMA + JAXB_VOTABLE_VERSION);
  98 + } else {
  99 + Log.LOGGER.info("VOTable version is " + version + ", everything is ok.");
  100 + }
  101 +
  102 + // write the content into xml file
  103 + Transformer transformer = TransformerFactory.newInstance().newTransformer();
  104 + StreamResult result = new StreamResult(new File(voTablePath));
  105 + transformer.transform(new DOMSource(doc), result);
  106 +
  107 + } catch (ParserConfigurationException pce) {
  108 + throw new Exception("Configuration error when parsing XML file " + voTablePath, pce);
  109 + } catch (TransformerException tfe) {
  110 + throw new Exception("Can not change VOTable version in XML file " + voTablePath, tfe);
  111 + } catch (IOException ioe) {
  112 + throw new Exception("Can read/write the XML file " + voTablePath, ioe);
  113 + } catch (SAXException sae) {
  114 + throw new Exception("Can not parse the XML file " + voTablePath, sae);
  115 + }
  116 + }
  117 +}
... ...