Commit 4dd689795a6fc63baef1cb14a6fc4716c26fcbb9
1 parent
a7aff3e3
Exists in
master
Improve Exception management and display better error messages for the user.
Showing
9 changed files
with
208 additions
and
95 deletions
Show diff stats
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 | ... | ... |