Commit 4dd689795a6fc63baef1cb14a6fc4716c26fcbb9

Authored by Nathanael Jourdane
1 parent a7aff3e3
Exists in master

Improve Exception management and display better error messages for the user.

src/main/java/eu/omp/irap/vespa/epntapclient/controller/EpnTapController.java
... ... @@ -16,15 +16,12 @@
16 16  
17 17 package eu.omp.irap.vespa.epntapclient.controller;
18 18  
19   -import java.io.IOException;
20   -
21   -import org.xml.sax.SAXException;
22   -
23 19 import eu.omp.irap.vespa.epntapclient.utils.Const;
24 20 import eu.omp.irap.vespa.epntapclient.utils.Log;
25 21 import eu.omp.irap.vespa.epntapclient.utils.Queries;
26 22 import eu.omp.irap.vespa.epntapclient.view.EpnTapMainView;
27 23 import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableController;
  24 +import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException;
28 25 import eu.omp.irap.vespa.epntapclient.votable.view.VOTableView;
29 26  
30 27 /**
... ... @@ -94,10 +91,9 @@ public class EpnTapController {
94 91  
95 92 /**
96 93 * @param query The query to send to the selected service.
97   - * @throws SAXException Can not change the VOTable schema location.
98   - * @throws IOException If VOTable can not be parsed or there is more than one VOTable.
  94 + * @throws VOTableException Can not fill the Table
99 95 */
100   - public void sendQuery(String query) throws IOException, SAXException {
  96 + public void sendQuery(String query) throws VOTableException {
101 97 Log.LOGGER.info("Sending query: " + query + " on " + selectedServiceURL);
102 98 resultsController.fillTable(selectedServiceURL, "ADQL", query);
103 99 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/utils/Log.java
... ... @@ -37,6 +37,9 @@ public class Log {
37 37 /** The logger. */
38 38 public static final Logger LOGGER = Logger.getAnonymousLogger();
39 39  
  40 + /** The log message displayed when errors appends. */
  41 + public static String ERROR_MSG = "-- error --\n%1s\nbecause:\n%2s\n-- end of error --\n";
  42 +
40 43 /** Constructor to hide the implicit public one. */
41 44 private Log() {
42 45 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/view/RequestView.java
... ... @@ -19,7 +19,6 @@ package eu.omp.irap.vespa.epntapclient.view;
19 19 import java.awt.BorderLayout;
20 20 import java.awt.event.ActionEvent;
21 21 import java.awt.event.ActionListener;
22   -import java.util.logging.Level;
23 22  
24 23 import javax.swing.JButton;
25 24 import javax.swing.JLabel;
... ... @@ -28,6 +27,7 @@ import javax.swing.JTextArea;
28 27  
29 28 import eu.omp.irap.vespa.epntapclient.utils.Log;
30 29 import eu.omp.irap.vespa.epntapclient.utils.Queries;
  30 +import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException;
31 31  
32 32 /**
33 33 * @author N. Jourdane
... ... @@ -68,8 +68,9 @@ public class RequestView extends JPanel implements ActionListener {
68 68 if (((JButton) evt.getSource()).getName() == "btnSend") {
69 69 try {
70 70 mainView.getController().sendQuery(queryArea.getText());
71   - } catch (Exception e) {
72   - Log.LOGGER.log(Level.SEVERE, "Can not send query after clicking on the button.", e);
  71 + } catch (VOTableException e) {
  72 + Log.LOGGER.warning(
  73 + "Can not send query when clicking on the send button:\n" + e.getMessage());
73 74 }
74 75 }
75 76 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableConnection.java
... ... @@ -24,7 +24,6 @@ import java.io.PrintWriter;
24 24 import java.io.UnsupportedEncodingException;
25 25 import java.net.HttpURLConnection;
26 26 import java.net.MalformedURLException;
27   -import java.net.ProtocolException;
28 27 import java.net.URL;
29 28 import java.net.URLEncoder;
30 29 import java.text.SimpleDateFormat;
... ... @@ -32,6 +31,8 @@ import java.util.Date;
32 31  
33 32 import eu.omp.irap.vespa.epntapclient.utils.Const;
34 33 import eu.omp.irap.vespa.epntapclient.utils.Log;
  34 +import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException.BadRequestException;
  35 +import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException.HTTPRequestException;
35 36  
36 37 /**
37 38 * This class provide HTTP connection support to send requests through POST / GET protocols.
... ... @@ -50,26 +51,28 @@ public final class VOTableConnection {
50 51 * @param targetURL The url of the registry to communicate (ie. "http://reg.g-vo.org").
51 52 * @param queryLanguage The language used for the queries (ie. "ADQL").
52 53 * @param query The query to ask to the registry.
53   - * @throws IOException If the query can not be sent or got a bad response code.
  54 + * @throws HTTPRequestException Can not send the query.
  55 + * @throws BadRequestException The response code is not 200.
54 56 * @return The path of the temporary XML file containing the http response.
55 57 */
56 58 public static String sendQuery(String targetURL, String queryLanguage,
57   - String query) throws IOException {
  59 + String query) throws HTTPRequestException, BadRequestException {
58 60  
59   - SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd_hhmmss_S");
  61 + SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd_hhmmss_SSS");
60 62 String voTablePath = Const.TMP_DIR + "/votable" + ft.format(new Date()) + ".xml";
61 63  
62 64 String uri = targetURL + "/sync";
63 65 String parameters = "REQUEST=doQuery&LANG=" + queryLanguage + "&QUERY=";
64   - parameters += URLEncoder.encode(query, Const.CHARACTER_SET).replace("+", "%20")
65   - .replace(".", "%2E").replace("-", "%2D").replace("*", "%2A").replace("_", "%5F");
  66 + try {
  67 + parameters += URLEncoder.encode(query, Const.CHARACTER_SET).replace("+", "%20")
  68 + .replace(".", "%2E").replace("-", "%2D").replace("*", "%2A")
  69 + .replace("_", "%5F");
  70 + } catch (UnsupportedEncodingException e) {
  71 + throw new HTTPRequestException("Can not encode URI " + uri, e);
  72 + }
66 73  
67 74 Log.LOGGER.info("request: " + uri + "?" + parameters);
68   - int responseCode = VOTableConnection.sendGet(uri, parameters, voTablePath);
69   - if (responseCode != HttpURLConnection.HTTP_OK) {
70   - throw new IOException(
71   - "The query:\n" + query + "\n got a bad response code: " + responseCode);
72   - }
  75 + VOTableConnection.sendGet(uri, parameters, voTablePath);
73 76  
74 77 return voTablePath;
75 78 }
... ... @@ -78,51 +81,72 @@ public final class VOTableConnection {
78 81 * @param url The target URL of the request.
79 82 * @param urlParameters The parameters of the request.
80 83 * @param resultFileName The name of the file where the request response content is writed.
81   - * @return The response code of the request (200 if successful).
82   - * @throws IOException Can not connect to the specified URL.
83   - * @throws IllegalArgumentException Can not send the specified request.
  84 + * @throws HTTPRequestException Can not send the request.
  85 + * @throws BadRequestException If the
84 86 */
85   - private static int sendGet(String url, String urlParameters, String resultFileName)
86   - throws IOException {
  87 + private static void sendGet(String url, String urlParameters, String resultFileName)
  88 + throws HTTPRequestException, BadRequestException {
87 89 String inputLine;
88 90 StringBuilder response = new StringBuilder();
89 91 URL obj;
  92 + String uri = url + "?" + urlParameters;
  93 +
90 94 try {
91   - obj = new URL(url + "?" + urlParameters);
  95 + obj = new URL(uri);
92 96 } catch (MalformedURLException e) {
93   - Log.LOGGER.severe("The URL is not correctly formated: " + e.getMessage());
94   - throw e;
  97 + throw new HTTPRequestException("The uri " + uri + "is not correctly formated", e);
95 98 }
96 99  
97 100 HttpURLConnection con;
98   - // TODO: Get the error message of the VOTableTable (VOTABLE/RESOURCE/INFO)
99 101  
100 102 try {
101 103 con = (HttpURLConnection) obj.openConnection();
  104 + con.setRequestMethod("GET");
102 105 } catch (IOException e) {
103   - Log.LOGGER.severe("Can not connect to the specified URL: " + e.getMessage());
104   - throw e;
  106 + throw new HTTPRequestException("Can not open HTTP GET connection with uri " + uri, e);
105 107 }
106 108  
  109 + con.setRequestProperty("User-Agent", USER_AGENT);
  110 + int code = -1;
  111 +
107 112 try {
108   - con.setRequestMethod("GET");
109   - } catch (ProtocolException e) {
110   - Log.LOGGER.severe("Not a valid HTTP method: " + e.getMessage());
111   - throw e;
  113 + code = con.getResponseCode();
  114 + } catch (IOException e) {
  115 + throw new HTTPRequestException("Can not get the HTTP response code", e);
112 116 }
113 117  
114   - con.setRequestProperty("User-Agent", USER_AGENT);
115   - int responseCode = con.getResponseCode();
116   - BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
  118 + if (code != HttpURLConnection.HTTP_OK
  119 + && code != HttpURLConnection.HTTP_BAD_REQUEST) {
  120 + throw new HTTPRequestException("The server returned a bad response code: " + code);
  121 + }
117 122  
118   - while ((inputLine = in.readLine()) != null) {
119   - response.append(inputLine);
  123 + try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
  124 + while ((inputLine = in.readLine()) != null) {
  125 + response.append(inputLine);
  126 + }
  127 + in.close();
  128 + } catch (IOException e1) {
  129 + try (BufferedReader in = new BufferedReader(
  130 + new InputStreamReader(con.getErrorStream()))) {
  131 + while ((inputLine = in.readLine()) != null) {
  132 + response.append(inputLine);
  133 + }
  134 + in.close();
  135 + } catch (IOException e2) {
  136 + throw new HTTPRequestException("Can not get the error stream.", e2);
  137 + }
  138 + if (code != HttpURLConnection.HTTP_BAD_REQUEST) {
  139 + throw new HTTPRequestException(
  140 + "The server returned a bad response code (not 200 neither 400).", e1);
  141 + }
120 142 }
121   - new BufferedReader(new InputStreamReader(con.getInputStream())).close();
122 143  
123   - printRequestResult(response, resultFileName);
  144 + try {
  145 + printRequestResult(response, resultFileName);
  146 + } catch (IOException e) {
  147 + throw new HTTPRequestException("Can not print the result in a file.", e);
  148 + }
124 149  
125   - return responseCode;
126 150 }
127 151  
128 152 /**
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableController.java
... ... @@ -17,11 +17,9 @@
17 17 package eu.omp.irap.vespa.epntapclient.votable.controller;
18 18  
19 19 import java.io.IOException;
20   -import java.util.logging.Level;
21   -
22   -import org.xml.sax.SAXException;
23 20  
24 21 import eu.omp.irap.vespa.epntapclient.utils.Log;
  22 +import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException.VOTableParsingException;
25 23 import eu.omp.irap.vespa.epntapclient.votable.model.Table;
26 24 import eu.omp.irap.vespa.epntapclient.votable.model.VOTABLE;
27 25 import eu.omp.irap.vespa.epntapclient.votable.view.VOTableView;
... ... @@ -51,13 +49,10 @@ public class VOTableController {
51 49 */
52 50 public VOTableController(String voTablePath) {
53 51 view = new VOTableView();
54   -
55 52 try {
56 53 fillTable(voTablePath);
57   - } catch (Exception e) {
58   - view.displayError("VOTable can not be displayed.\nReason:\n", e.getMessage());
59   - Log.LOGGER.log(Level.SEVERE, "VOTable can not be displayed.", e);
60   -
  54 + } catch (VOTableException e) {
  55 + view.displayError("Can not fil the VOTable.", e);
61 56 }
62 57 }
63 58  
... ... @@ -73,9 +68,8 @@ public class VOTableController {
73 68  
74 69 try {
75 70 fillTable(VOTableConnection.sendQuery(targetURL, queryLanguage, query));
76   - } catch (Exception e) {
77   - view.displayError("VOTable can not be displayed.\nReason:\n", e.getMessage());
78   - Log.LOGGER.log(Level.SEVERE, "VOTable can not be displayed.", e);
  71 + } catch (VOTableException e) {
  72 + Log.LOGGER.info("VOTableController error: " + e.getMessage());
79 73 }
80 74 }
81 75  
... ... @@ -83,52 +77,52 @@ public class VOTableController {
83 77 * @param targetURL The url of the registry to communicate (ie. "http://reg.g-vo.org").
84 78 * @param queryLanguage The language used for the queries (ie. "ADQL").
85 79 * @param query The query to ask to the registry.
86   - * @throws IOException If VOTable can not be parsed or there is more than one VOTable.
87   - * @throws SAXException Can not change the VOTable schema location.
  80 + * @throws VOTableException Can not send the query or VOTable can not be parsed or can not fill
  81 + * the JTable.
88 82 */
89 83 public void fillTable(String targetURL, String queryLanguage, String query)
90   - throws IOException, SAXException {
  84 + throws VOTableException {
91 85 fillTable(VOTableConnection.sendQuery(targetURL, queryLanguage, query));
92 86 }
93 87  
94 88 /**
95 89 * @param voTablePath The path of the VOTable file.
96   - * @throws IOException If VOTable can not be parsed or there is more than one VOTable.
97   - * @throws SAXException Can not change the VOTable schema location.
  90 + * @throws VOTableException Can not fill the VOTable data in the JTable.
98 91 */
99   - public void fillTable(String voTablePath) throws IOException, SAXException {
  92 + public void fillTable(String voTablePath) throws VOTableException {
  93 +
100 94 try {
101 95 voTable = VOTableParser.parseVOTable(voTablePath);
102   - } catch (IOException e) {
103   - view.displayError("Can not parse the VOTable", "Can not parse the VOTable.\nReason:\n" +
104   - e.getMessage());
105   - Log.LOGGER.log(Level.SEVERE, "Can not parse the VOTable.", e);
106   - } catch (SAXException e) {
107   - view.displayError("Can not change the VOTable schema location",
108   - "Can not change the VOTable schema location.\nReason:\n" + e.getMessage());
109   - Log.LOGGER.log(Level.SEVERE, "Can not change the VOTable schema location.", e);
  96 + } catch (VOTableParsingException e1) {
  97 + view.displayError("Can not parse the VOTable.", e1);
110 98 }
111 99  
112 100 // TODO: Handle the case when there are more than 1 resource or table.
113 101 if (voTable.getRESOURCE().size() > 1) {
114   - view.displayError("Several resources",
115   - "VOTable with more than one resource are not yet supported.\n"
116   - + "See VOTable file for debug:\n" + voTablePath);
  102 + view.displayError("VOTable with more than one resource are not yet supported.\n"
  103 + + "See VOTable file for more informations: " + voTablePath);
  104 + return;
117 105 }
118   - // TODO: Iterate over all potential errors
  106 + // TODO: Iterate over all potential ERROR tags
119 107 if ("ERROR".equals(voTable.getRESOURCE().get(0).getINFO().get(0).getValueAttribute())) {
120   - view.displayError("Bad query", "There is an error on the query:\n"
121   - + voTable.getRESOURCE().get(0).getINFO().get(0).getValue());
  108 + String errorInfo = voTable.getRESOURCE().get(0).getINFO().get(0).getValue();
  109 + view.displayError("The query is not valid.\n" + errorInfo);
  110 + return;
122 111 }
123 112 if (voTable.getRESOURCE().get(0).getLINKAndTABLEOrRESOURCE().size() > 1) {
124   - view.displayError("Several tables",
125   - "VOTable with more than one table are not yet supported. See VOTable file for debug:\n"
126   - + voTablePath);
  113 + view.displayError("VOTable with more than one table are not yet supported.\n"
  114 + + "See VOTable file for more informations: " + voTablePath);
  115 + return;
127 116 }
128 117 Table table = (Table) (voTable.getRESOURCE().get(0).getLINKAndTABLEOrRESOURCE().get(0));
129 118  
130   - VOTableDataParser dataParser = new VOTableDataParser(table);
131   - view.fillTable(dataParser.getColumnsName(), dataParser.getDataArray());
  119 + VOTableDataParser dataParser;
  120 + try {
  121 + dataParser = new VOTableDataParser(table);
  122 + view.fillTable(dataParser.getColumnsName(), dataParser.getDataArray());
  123 + } catch (IOException e) {
  124 + throw new VOTableException("Can not fill the VOTable data in the JTable.", e);
  125 + }
132 126 }
133 127  
134 128 /**
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableDataParser.java
... ... @@ -73,7 +73,7 @@ public class VOTableDataParser {
73 73 for (int i = 0; i < fields.size(); i++) {
74 74 columnsName[i] = fields.get(i).getName();
75 75 }
76   - Log.LOGGER.info("Columns name: \n " + new Gson().toJson(columnsName));
  76 + Log.LOGGER.info("Columns name: " + new Gson().toJson(columnsName));
77 77  
78 78 data = new ArrayList<>();
79 79  
... ... @@ -185,7 +185,8 @@ public class VOTableDataParser {
185 185 Object[] row = new Object[columnsName.length];
186 186  
187 187 Log.clearFile();
188   - for (int nValue = 0; cursor < bytes.length; nValue++) {
  188 + int nValue = 0;
  189 + while (cursor < bytes.length) {
189 190 int nColumn = nValue % columnsName.length;
190 191 Field column = fields.get(nColumn);
191 192 DataType dataType = column.getDatatype();
... ... @@ -247,6 +248,7 @@ public class VOTableDataParser {
247 248 if (nColumn == columnsName.length - 1) {
248 249 data.add(row);
249 250 }
  251 + nValue++;
250 252 }
251 253  
252 254 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableException.java 0 โ†’ 100644
... ... @@ -0,0 +1,76 @@
  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 +
  17 +package eu.omp.irap.vespa.epntapclient.votable.controller;
  18 +
  19 +import java.util.logging.Level;
  20 +
  21 +import eu.omp.irap.vespa.epntapclient.utils.Log;
  22 +
  23 +/**
  24 + * VOTable Exception class.
  25 + *
  26 + * @author N. Jourdane
  27 + */
  28 +@SuppressWarnings({ "javadoc", "serial" })
  29 +public class VOTableException extends Exception {
  30 + public VOTableException() {
  31 + Log.LOGGER.log(Level.SEVERE, "A VOTable error occured.");
  32 + }
  33 +
  34 + public VOTableException(String message) {
  35 + Log.LOGGER.log(Level.SEVERE, message);
  36 + }
  37 +
  38 + public VOTableException(String message, Exception e) {
  39 + Log.LOGGER.log(Level.SEVERE, String.format(Log.ERROR_MSG, message, e.getMessage()));
  40 + }
  41 +
  42 + public VOTableException(Exception e) {
  43 + Log.LOGGER.log(Level.SEVERE, e.getMessage());
  44 + }
  45 +
  46 + public static class HTTPRequestException extends VOTableException {
  47 + public HTTPRequestException(String message) {
  48 + Log.LOGGER.log(Level.SEVERE, message);
  49 + }
  50 +
  51 + public HTTPRequestException(String message, Exception e) {
  52 + Log.LOGGER.log(Level.SEVERE, String.format(Log.ERROR_MSG, message, e.getMessage()));
  53 + }
  54 + }
  55 +
  56 + public static class VOTableParsingException extends VOTableException {
  57 + public VOTableParsingException(String message, Exception e) {
  58 + Log.LOGGER.log(Level.SEVERE, String.format(Log.ERROR_MSG, message, e.getMessage()));
  59 + }
  60 + }
  61 +
  62 + public static class BadRequestException extends VOTableException {
  63 + private String info;
  64 +
  65 + public BadRequestException(String message, String info) {
  66 + super(message);
  67 + this.info = info;
  68 + Log.LOGGER.log(Level.WARNING, message + "\nDetails: " + info);
  69 + }
  70 +
  71 + public String getInfo() {
  72 + return info;
  73 + }
  74 + }
  75 +
  76 +}
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableParser.java
... ... @@ -20,6 +20,7 @@ import java.io.File;
20 20 import java.io.IOException;
21 21  
22 22 import javax.xml.bind.JAXBContext;
  23 +import javax.xml.bind.JAXBException;
23 24 import javax.xml.bind.Unmarshaller;
24 25 import javax.xml.parsers.DocumentBuilder;
25 26 import javax.xml.parsers.DocumentBuilderFactory;
... ... @@ -35,6 +36,7 @@ import org.w3c.dom.NamedNodeMap;
35 36 import org.xml.sax.SAXException;
36 37  
37 38 import eu.omp.irap.vespa.epntapclient.utils.Log;
  39 +import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException.VOTableParsingException;
38 40 import eu.omp.irap.vespa.epntapclient.votable.model.VOTABLE;
39 41  
40 42 /**
... ... @@ -61,23 +63,24 @@ public final class VOTableParser {
61 63 /**
62 64 * @param voTablePath The path of the VOTable.
63 65 * @return The VOTable resulting of the XML document.
64   - * @throws IOException Can not parse the VOTable.
65   - * @throws SAXException Can not change the VOTable schema location.
  66 + * @throws VOTableParsingException Can not parse the VOTable.
66 67 */
67   - public static VOTABLE parseVOTable(String voTablePath) throws IOException, SAXException {
  68 + public static VOTABLE parseVOTable(String voTablePath) throws VOTableParsingException {
68 69 try {
69 70 changeVOTableSchemaLocation(voTablePath);
70   - } catch (Exception e1) {
71   - throw new IOException("Can not change the VOTable schema location.", e1);
  71 + } catch (IOException e1) {
  72 + throw new VOTableParsingException("Can not change the VOTable schema location.", e1);
72 73 }
  74 +
73 75 // TODO: Change the name of the 2nd INFO tag instead of editing the XSD file.
74 76 VOTABLE voTable;
  77 + JAXBContext jc;
75 78 try {
76   - JAXBContext jc = JAXBContext.newInstance(VOTABLE_MODEL_PACKAGE);
  79 + jc = JAXBContext.newInstance(VOTABLE_MODEL_PACKAGE);
77 80 Unmarshaller unmarshaller = jc.createUnmarshaller();
78 81 voTable = (VOTABLE) unmarshaller.unmarshal(new File(voTablePath));
79   - } catch (Exception e) {
80   - throw new SAXException("Can not parse the VOTable.", e);
  82 + } catch (JAXBException e) {
  83 + throw new VOTableParsingException("Can not change the VOTable schema location.", e);
81 84 }
82 85  
83 86 return voTable;
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/votable/view/VOTableView.java
... ... @@ -18,6 +18,7 @@ package eu.omp.irap.vespa.epntapclient.votable.view;
18 18  
19 19 import java.awt.BorderLayout;
20 20 import java.util.List;
  21 +import java.util.logging.Level;
21 22  
22 23 import javax.swing.JOptionPane;
23 24 import javax.swing.JPanel;
... ... @@ -28,13 +29,15 @@ import javax.swing.event.TableModelEvent;
28 29 import javax.swing.event.TableModelListener;
29 30 import javax.swing.table.DefaultTableModel;
30 31  
  32 +import eu.omp.irap.vespa.epntapclient.utils.Log;
  33 +
31 34 /**
32 35 * The main class of the View of the application.
33 36 *
34 37 * @author N. Jourdane
35 38 */
36 39 public class VOTableView extends JPanel implements TableModelListener {
37   -
  40 + // TODO: Create classes VOTableGUI and VOTableCLI which implements an interface VOTableView
38 41 /** The serial version UID (affected with a random number). */
39 42 private static final long serialVersionUID = -6131752938586134234L;
40 43  
... ... @@ -99,11 +102,22 @@ public class VOTableView extends JPanel implements TableModelListener {
99 102 /**
100 103 * Display an error.
101 104 *
102   - * @param title The title of the window.
103   - * @param message The error message to display.
  105 + * @param message The error message displayed in the window.
  106 + */
  107 + public void displayError(String message) {
  108 + JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE);
  109 + Log.LOGGER.log(Level.WARNING, message);
  110 + }
  111 +
  112 + /**
  113 + * Display an error.
  114 + *
  115 + * @param message The error message displayed in the window.
  116 + * @param e The exception displayed in the log for debug.
104 117 */
105   - public void displayError(String title, String message) {
106   - JOptionPane.showMessageDialog(this, message, title, JOptionPane.ERROR_MESSAGE);
  118 + public void displayError(String message, Exception e) {
  119 + JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE);
  120 + Log.LOGGER.log(Level.SEVERE, String.format(Log.ERROR_MSG, message, e.getMessage()));
107 121 }
108 122  
109 123 @Override
... ...