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,15 +16,12 @@
16 16
17 package eu.omp.irap.vespa.epntapclient.controller; 17 package eu.omp.irap.vespa.epntapclient.controller;
18 18
19 -import java.io.IOException;  
20 -  
21 -import org.xml.sax.SAXException;  
22 -  
23 import eu.omp.irap.vespa.epntapclient.utils.Const; 19 import eu.omp.irap.vespa.epntapclient.utils.Const;
24 import eu.omp.irap.vespa.epntapclient.utils.Log; 20 import eu.omp.irap.vespa.epntapclient.utils.Log;
25 import eu.omp.irap.vespa.epntapclient.utils.Queries; 21 import eu.omp.irap.vespa.epntapclient.utils.Queries;
26 import eu.omp.irap.vespa.epntapclient.view.EpnTapMainView; 22 import eu.omp.irap.vespa.epntapclient.view.EpnTapMainView;
27 import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableController; 23 import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableController;
  24 +import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException;
28 import eu.omp.irap.vespa.epntapclient.votable.view.VOTableView; 25 import eu.omp.irap.vespa.epntapclient.votable.view.VOTableView;
29 26
30 /** 27 /**
@@ -94,10 +91,9 @@ public class EpnTapController { @@ -94,10 +91,9 @@ public class EpnTapController {
94 91
95 /** 92 /**
96 * @param query The query to send to the selected service. 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 Log.LOGGER.info("Sending query: " + query + " on " + selectedServiceURL); 97 Log.LOGGER.info("Sending query: " + query + " on " + selectedServiceURL);
102 resultsController.fillTable(selectedServiceURL, "ADQL", query); 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,6 +37,9 @@ public class Log {
37 /** The logger. */ 37 /** The logger. */
38 public static final Logger LOGGER = Logger.getAnonymousLogger(); 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 /** Constructor to hide the implicit public one. */ 43 /** Constructor to hide the implicit public one. */
41 private Log() { 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,7 +19,6 @@ package eu.omp.irap.vespa.epntapclient.view;
19 import java.awt.BorderLayout; 19 import java.awt.BorderLayout;
20 import java.awt.event.ActionEvent; 20 import java.awt.event.ActionEvent;
21 import java.awt.event.ActionListener; 21 import java.awt.event.ActionListener;
22 -import java.util.logging.Level;  
23 22
24 import javax.swing.JButton; 23 import javax.swing.JButton;
25 import javax.swing.JLabel; 24 import javax.swing.JLabel;
@@ -28,6 +27,7 @@ import javax.swing.JTextArea; @@ -28,6 +27,7 @@ import javax.swing.JTextArea;
28 27
29 import eu.omp.irap.vespa.epntapclient.utils.Log; 28 import eu.omp.irap.vespa.epntapclient.utils.Log;
30 import eu.omp.irap.vespa.epntapclient.utils.Queries; 29 import eu.omp.irap.vespa.epntapclient.utils.Queries;
  30 +import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException;
31 31
32 /** 32 /**
33 * @author N. Jourdane 33 * @author N. Jourdane
@@ -68,8 +68,9 @@ public class RequestView extends JPanel implements ActionListener { @@ -68,8 +68,9 @@ public class RequestView extends JPanel implements ActionListener {
68 if (((JButton) evt.getSource()).getName() == "btnSend") { 68 if (((JButton) evt.getSource()).getName() == "btnSend") {
69 try { 69 try {
70 mainView.getController().sendQuery(queryArea.getText()); 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,7 +24,6 @@ import java.io.PrintWriter;
24 import java.io.UnsupportedEncodingException; 24 import java.io.UnsupportedEncodingException;
25 import java.net.HttpURLConnection; 25 import java.net.HttpURLConnection;
26 import java.net.MalformedURLException; 26 import java.net.MalformedURLException;
27 -import java.net.ProtocolException;  
28 import java.net.URL; 27 import java.net.URL;
29 import java.net.URLEncoder; 28 import java.net.URLEncoder;
30 import java.text.SimpleDateFormat; 29 import java.text.SimpleDateFormat;
@@ -32,6 +31,8 @@ import java.util.Date; @@ -32,6 +31,8 @@ import java.util.Date;
32 31
33 import eu.omp.irap.vespa.epntapclient.utils.Const; 32 import eu.omp.irap.vespa.epntapclient.utils.Const;
34 import eu.omp.irap.vespa.epntapclient.utils.Log; 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 * This class provide HTTP connection support to send requests through POST / GET protocols. 38 * This class provide HTTP connection support to send requests through POST / GET protocols.
@@ -50,26 +51,28 @@ public final class VOTableConnection { @@ -50,26 +51,28 @@ public final class VOTableConnection {
50 * @param targetURL The url of the registry to communicate (ie. "http://reg.g-vo.org"). 51 * @param targetURL The url of the registry to communicate (ie. "http://reg.g-vo.org").
51 * @param queryLanguage The language used for the queries (ie. "ADQL"). 52 * @param queryLanguage The language used for the queries (ie. "ADQL").
52 * @param query The query to ask to the registry. 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 * @return The path of the temporary XML file containing the http response. 56 * @return The path of the temporary XML file containing the http response.
55 */ 57 */
56 public static String sendQuery(String targetURL, String queryLanguage, 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 String voTablePath = Const.TMP_DIR + "/votable" + ft.format(new Date()) + ".xml"; 62 String voTablePath = Const.TMP_DIR + "/votable" + ft.format(new Date()) + ".xml";
61 63
62 String uri = targetURL + "/sync"; 64 String uri = targetURL + "/sync";
63 String parameters = "REQUEST=doQuery&LANG=" + queryLanguage + "&QUERY="; 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 Log.LOGGER.info("request: " + uri + "?" + parameters); 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 return voTablePath; 77 return voTablePath;
75 } 78 }
@@ -78,51 +81,72 @@ public final class VOTableConnection { @@ -78,51 +81,72 @@ public final class VOTableConnection {
78 * @param url The target URL of the request. 81 * @param url The target URL of the request.
79 * @param urlParameters The parameters of the request. 82 * @param urlParameters The parameters of the request.
80 * @param resultFileName The name of the file where the request response content is writed. 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 String inputLine; 89 String inputLine;
88 StringBuilder response = new StringBuilder(); 90 StringBuilder response = new StringBuilder();
89 URL obj; 91 URL obj;
  92 + String uri = url + "?" + urlParameters;
  93 +
90 try { 94 try {
91 - obj = new URL(url + "?" + urlParameters); 95 + obj = new URL(uri);
92 } catch (MalformedURLException e) { 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 HttpURLConnection con; 100 HttpURLConnection con;
98 - // TODO: Get the error message of the VOTableTable (VOTABLE/RESOURCE/INFO)  
99 101
100 try { 102 try {
101 con = (HttpURLConnection) obj.openConnection(); 103 con = (HttpURLConnection) obj.openConnection();
  104 + con.setRequestMethod("GET");
102 } catch (IOException e) { 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 try { 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,11 +17,9 @@
17 package eu.omp.irap.vespa.epntapclient.votable.controller; 17 package eu.omp.irap.vespa.epntapclient.votable.controller;
18 18
19 import java.io.IOException; 19 import java.io.IOException;
20 -import java.util.logging.Level;  
21 -  
22 -import org.xml.sax.SAXException;  
23 20
24 import eu.omp.irap.vespa.epntapclient.utils.Log; 21 import eu.omp.irap.vespa.epntapclient.utils.Log;
  22 +import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException.VOTableParsingException;
25 import eu.omp.irap.vespa.epntapclient.votable.model.Table; 23 import eu.omp.irap.vespa.epntapclient.votable.model.Table;
26 import eu.omp.irap.vespa.epntapclient.votable.model.VOTABLE; 24 import eu.omp.irap.vespa.epntapclient.votable.model.VOTABLE;
27 import eu.omp.irap.vespa.epntapclient.votable.view.VOTableView; 25 import eu.omp.irap.vespa.epntapclient.votable.view.VOTableView;
@@ -51,13 +49,10 @@ public class VOTableController { @@ -51,13 +49,10 @@ public class VOTableController {
51 */ 49 */
52 public VOTableController(String voTablePath) { 50 public VOTableController(String voTablePath) {
53 view = new VOTableView(); 51 view = new VOTableView();
54 -  
55 try { 52 try {
56 fillTable(voTablePath); 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,9 +68,8 @@ public class VOTableController {
73 68
74 try { 69 try {
75 fillTable(VOTableConnection.sendQuery(targetURL, queryLanguage, query)); 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,52 +77,52 @@ public class VOTableController {
83 * @param targetURL The url of the registry to communicate (ie. "http://reg.g-vo.org"). 77 * @param targetURL The url of the registry to communicate (ie. "http://reg.g-vo.org").
84 * @param queryLanguage The language used for the queries (ie. "ADQL"). 78 * @param queryLanguage The language used for the queries (ie. "ADQL").
85 * @param query The query to ask to the registry. 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 public void fillTable(String targetURL, String queryLanguage, String query) 83 public void fillTable(String targetURL, String queryLanguage, String query)
90 - throws IOException, SAXException { 84 + throws VOTableException {
91 fillTable(VOTableConnection.sendQuery(targetURL, queryLanguage, query)); 85 fillTable(VOTableConnection.sendQuery(targetURL, queryLanguage, query));
92 } 86 }
93 87
94 /** 88 /**
95 * @param voTablePath The path of the VOTable file. 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 try { 94 try {
101 voTable = VOTableParser.parseVOTable(voTablePath); 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 // TODO: Handle the case when there are more than 1 resource or table. 100 // TODO: Handle the case when there are more than 1 resource or table.
113 if (voTable.getRESOURCE().size() > 1) { 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 if ("ERROR".equals(voTable.getRESOURCE().get(0).getINFO().get(0).getValueAttribute())) { 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 if (voTable.getRESOURCE().get(0).getLINKAndTABLEOrRESOURCE().size() > 1) { 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 Table table = (Table) (voTable.getRESOURCE().get(0).getLINKAndTABLEOrRESOURCE().get(0)); 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,7 +73,7 @@ public class VOTableDataParser {
73 for (int i = 0; i < fields.size(); i++) { 73 for (int i = 0; i < fields.size(); i++) {
74 columnsName[i] = fields.get(i).getName(); 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 data = new ArrayList<>(); 78 data = new ArrayList<>();
79 79
@@ -185,7 +185,8 @@ public class VOTableDataParser { @@ -185,7 +185,8 @@ public class VOTableDataParser {
185 Object[] row = new Object[columnsName.length]; 185 Object[] row = new Object[columnsName.length];
186 186
187 Log.clearFile(); 187 Log.clearFile();
188 - for (int nValue = 0; cursor < bytes.length; nValue++) { 188 + int nValue = 0;
  189 + while (cursor < bytes.length) {
189 int nColumn = nValue % columnsName.length; 190 int nColumn = nValue % columnsName.length;
190 Field column = fields.get(nColumn); 191 Field column = fields.get(nColumn);
191 DataType dataType = column.getDatatype(); 192 DataType dataType = column.getDatatype();
@@ -247,6 +248,7 @@ public class VOTableDataParser { @@ -247,6 +248,7 @@ public class VOTableDataParser {
247 if (nColumn == columnsName.length - 1) { 248 if (nColumn == columnsName.length - 1) {
248 data.add(row); 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 @@ @@ -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,6 +20,7 @@ import java.io.File;
20 import java.io.IOException; 20 import java.io.IOException;
21 21
22 import javax.xml.bind.JAXBContext; 22 import javax.xml.bind.JAXBContext;
  23 +import javax.xml.bind.JAXBException;
23 import javax.xml.bind.Unmarshaller; 24 import javax.xml.bind.Unmarshaller;
24 import javax.xml.parsers.DocumentBuilder; 25 import javax.xml.parsers.DocumentBuilder;
25 import javax.xml.parsers.DocumentBuilderFactory; 26 import javax.xml.parsers.DocumentBuilderFactory;
@@ -35,6 +36,7 @@ import org.w3c.dom.NamedNodeMap; @@ -35,6 +36,7 @@ import org.w3c.dom.NamedNodeMap;
35 import org.xml.sax.SAXException; 36 import org.xml.sax.SAXException;
36 37
37 import eu.omp.irap.vespa.epntapclient.utils.Log; 38 import eu.omp.irap.vespa.epntapclient.utils.Log;
  39 +import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException.VOTableParsingException;
38 import eu.omp.irap.vespa.epntapclient.votable.model.VOTABLE; 40 import eu.omp.irap.vespa.epntapclient.votable.model.VOTABLE;
39 41
40 /** 42 /**
@@ -61,23 +63,24 @@ public final class VOTableParser { @@ -61,23 +63,24 @@ public final class VOTableParser {
61 /** 63 /**
62 * @param voTablePath The path of the VOTable. 64 * @param voTablePath The path of the VOTable.
63 * @return The VOTable resulting of the XML document. 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 try { 69 try {
69 changeVOTableSchemaLocation(voTablePath); 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 // TODO: Change the name of the 2nd INFO tag instead of editing the XSD file. 75 // TODO: Change the name of the 2nd INFO tag instead of editing the XSD file.
74 VOTABLE voTable; 76 VOTABLE voTable;
  77 + JAXBContext jc;
75 try { 78 try {
76 - JAXBContext jc = JAXBContext.newInstance(VOTABLE_MODEL_PACKAGE); 79 + jc = JAXBContext.newInstance(VOTABLE_MODEL_PACKAGE);
77 Unmarshaller unmarshaller = jc.createUnmarshaller(); 80 Unmarshaller unmarshaller = jc.createUnmarshaller();
78 voTable = (VOTABLE) unmarshaller.unmarshal(new File(voTablePath)); 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 return voTable; 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,6 +18,7 @@ package eu.omp.irap.vespa.epntapclient.votable.view;
18 18
19 import java.awt.BorderLayout; 19 import java.awt.BorderLayout;
20 import java.util.List; 20 import java.util.List;
  21 +import java.util.logging.Level;
21 22
22 import javax.swing.JOptionPane; 23 import javax.swing.JOptionPane;
23 import javax.swing.JPanel; 24 import javax.swing.JPanel;
@@ -28,13 +29,15 @@ import javax.swing.event.TableModelEvent; @@ -28,13 +29,15 @@ import javax.swing.event.TableModelEvent;
28 import javax.swing.event.TableModelListener; 29 import javax.swing.event.TableModelListener;
29 import javax.swing.table.DefaultTableModel; 30 import javax.swing.table.DefaultTableModel;
30 31
  32 +import eu.omp.irap.vespa.epntapclient.utils.Log;
  33 +
31 /** 34 /**
32 * The main class of the View of the application. 35 * The main class of the View of the application.
33 * 36 *
34 * @author N. Jourdane 37 * @author N. Jourdane
35 */ 38 */
36 public class VOTableView extends JPanel implements TableModelListener { 39 public class VOTableView extends JPanel implements TableModelListener {
37 - 40 + // TODO: Create classes VOTableGUI and VOTableCLI which implements an interface VOTableView
38 /** The serial version UID (affected with a random number). */ 41 /** The serial version UID (affected with a random number). */
39 private static final long serialVersionUID = -6131752938586134234L; 42 private static final long serialVersionUID = -6131752938586134234L;
40 43
@@ -99,11 +102,22 @@ public class VOTableView extends JPanel implements TableModelListener { @@ -99,11 +102,22 @@ public class VOTableView extends JPanel implements TableModelListener {
99 /** 102 /**
100 * Display an error. 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 @Override 123 @Override