Commit 285505bef9aa4b24212d5d4255580250464709ad

Authored by Nathanael Jourdane
1 parent 1f971475
Exists in master

Remove complex code from panel controllers, let their superclasses do the stuff.

Showing 21 changed files with 268 additions and 295 deletions   Show diff stats
src/main/java/eu/omp/irap/vespa/epntapclient/EpnTapController.java
@@ -16,84 +16,83 @@ @@ -16,84 +16,83 @@
16 16
17 package eu.omp.irap.vespa.epntapclient; 17 package eu.omp.irap.vespa.epntapclient;
18 18
  19 +import java.util.List;
19 import java.util.logging.Level; 20 import java.util.logging.Level;
20 import java.util.logging.Logger; 21 import java.util.logging.Logger;
21 22
22 import eu.omp.irap.vespa.epntapclient.service.Queries; 23 import eu.omp.irap.vespa.epntapclient.service.Queries;
23 import eu.omp.irap.vespa.epntapclient.service.ServiceCore; 24 import eu.omp.irap.vespa.epntapclient.service.ServiceCore;
24 import eu.omp.irap.vespa.votable.Consts; 25 import eu.omp.irap.vespa.votable.Consts;
25 -import eu.omp.irap.vespa.votable.controller.VOTableException;  
26 import eu.omp.irap.vespa.votable.controller.VOTableController; 26 import eu.omp.irap.vespa.votable.controller.VOTableController;
  27 +import eu.omp.irap.vespa.votable.controller.VOTableException;
  28 +import eu.omp.irap.vespa.votable.utils.StringJoiner;
27 29
28 /** 30 /**
29 * The main controller which manage views and controllers. 31 * The main controller which manage views and controllers.
30 * 32 *
31 * @author N. Jourdane 33 * @author N. Jourdane
32 */ 34 */
33 -public class EpnTapController { 35 +public abstract class EpnTapController {
34 36
35 /** The logger for the class EpnTapController. */ 37 /** The logger for the class EpnTapController. */
36 private static final Logger LOGGER = Logger.getLogger(EpnTapController.class.getName()); 38 private static final Logger LOGGER = Logger.getLogger(EpnTapController.class.getName());
37 39
38 - /** The controller of the VOTable displaying the list of services. */  
39 - private VOTableController servicesCtrl;  
40 -  
41 - /** The controller of the VOTable displaying the result. */  
42 - private VOTableController resultsCtrl;  
43 -  
44 - /** The request controller, to manage requests. */  
45 - private RequestCtrl requestCtrl;  
46 -  
47 /** 40 /**
48 * The path of the VOTable to parse. Will be affected to a temporary folder if not assigned 41 * The path of the VOTable to parse. Will be affected to a temporary folder if not assigned
49 * through the controller. 42 * through the controller.
50 */ 43 */
51 private String voTablePath; 44 private String voTablePath;
52 45
  46 + /** The request controller, to manage requests. */
  47 + private RequestCtrl requestCtrl;
  48 +
  49 + /** The controller of the VOTable displaying the result. */
  50 + private VOTableController resultsCtrl;
  51 +
  52 + /** The controller of the VOTable displaying the list of services. */
  53 + private VOTableController servicesCtrl;
  54 +
53 55
54 /** 56 /**
55 * Method constructor, which initialize servicesController, resultsController and mainView. 57 * Method constructor, which initialize servicesController, resultsController and mainView.
56 */ 58 */
57 public EpnTapController() { 59 public EpnTapController() {
  60 + // TODO: Should not init controllers, because the default ctrl is called by subclasses.
58 String query = String.format(Queries.SELECT_ALL_TAP_SERVICES_WHERE_CORE, 61 String query = String.format(Queries.SELECT_ALL_TAP_SERVICES_WHERE_CORE,
59 ServiceCore.EPNCORE); 62 ServiceCore.EPNCORE);
60 servicesCtrl = new VOTableController(Consts.DEFAULT_REGISTRY_URL, query); 63 servicesCtrl = new VOTableController(Consts.DEFAULT_REGISTRY_URL, query);
61 } 64 }
62 65
63 /** 66 /**
64 - * Get the services from the XML path or the targetURL / query.  
65 - */  
66 - public void readServices() {  
67 - try {  
68 - servicesCtrl.readTable();  
69 - } catch (VOTableException e) {  
70 - displayError("Can not get services.", e);  
71 - }  
72 - }  
73 -  
74 - /**  
75 - * display an error with the logger. 67 + * Display an error with the logger.
76 * 68 *
77 * @param message A small error message. 69 * @param message A small error message.
78 * @param e The error. 70 * @param e The error.
79 */ 71 */
80 - @SuppressWarnings("static-method") 72 + @SuppressWarnings("static-method") // Because the method is overrided by a subclass.
81 public void displayError(String message, Exception e) { 73 public void displayError(String message, Exception e) {
82 LOGGER.log(Level.SEVERE, message, e); 74 LOGGER.log(Level.SEVERE, message, e);
83 } 75 }
84 76
85 /** 77 /**
86 - * Send the query to the specified service, download the result and update the voTable path.  
87 - *  
88 - * @param query An ADQL query to send.  
89 - * @param tableServiceURL the URL of the service.  
90 - * @throws VOTableException Can not get the VOTable. 78 + * @return The request controller.
91 */ 79 */
92 - public void sendQuery(String query, String tableServiceURL)  
93 - throws VOTableException {  
94 - resultsCtrl = new VOTableController(tableServiceURL, query);  
95 - resultsCtrl.readTable();  
96 - voTablePath = resultsCtrl.getVOTablePath(); 80 + public RequestCtrl getRequestCtrl() {
  81 + return requestCtrl;
  82 + }
  83 +
  84 + /**
  85 + * @return The controller of the VOTable which displays the result of the query.
  86 + */
  87 + public VOTableController getResultsCtrl() {
  88 + return resultsCtrl;
  89 + }
  90 +
  91 + /**
  92 + * @return The controller of the VOTable which displays the list of services.
  93 + */
  94 + public VOTableController getServicesCtrl() {
  95 + return servicesCtrl;
97 } 96 }
98 97
99 /** 98 /**
@@ -104,24 +103,45 @@ public class EpnTapController { @@ -104,24 +103,45 @@ public class EpnTapController {
104 } 103 }
105 104
106 /** 105 /**
107 - * @return The controller of the VOTable which displays the result of the query. 106 + * Get the services from the XML path or the targetURL / query.
108 */ 107 */
109 - public VOTableController getResultsController() {  
110 - return resultsCtrl; 108 + public void readServices() {
  109 + // Here getServicesCtrl() is used instead of class field servicesCtrl to get the
  110 + // subclass field, since subclasses overrides getServicesCtrl().
  111 + try {
  112 + getServicesCtrl().readTable();
  113 + } catch (VOTableException e) {
  114 + displayError("Can not get services.", e);
  115 + }
111 } 116 }
112 117
113 - /**  
114 - * @return The controller of the VOTable which displays the list of services.  
115 - */  
116 - public VOTableController getServicesController() {  
117 - return servicesCtrl; 118 + public void sendQuery(List<String> tableNames, List<String> servicesUrls) {
  119 + // Here getRequestCtrl() and getResultsCtrl() are used instead of class fields requestCtrl
  120 + // and resultCtrl to get the subclass field, since subclasses overrides getRequestCtrl() and
  121 + // getResultsCtrl().
  122 + try {
  123 + LOGGER.info("Sending queries on " + StringJoiner.join(servicesUrls));
  124 + for (int i = 0; i < tableNames.size(); i++) {
  125 + String query = getRequestCtrl().getQuery(tableNames.get(i));
  126 + getResultsCtrl().updateVOTable(servicesUrls.get(i), query);
  127 + }
  128 + } catch (VOTableException e) {
  129 + displayError("Can not update the VOTable.", e);
  130 + }
  131 +
118 } 132 }
119 133
120 /** 134 /**
121 - * @return The request controller. 135 + * Send the query to the specified service, download the result and update the voTable path.
  136 + *
  137 + * @param query An ADQL query to send.
  138 + * @param tableServiceURL the URL of the service.
  139 + * @throws VOTableException Can not get the VOTable.
122 */ 140 */
123 - public RequestCtrl getRequestCtrl() {  
124 - return requestCtrl; 141 + public void sendQuery(String query, String tableServiceURL) throws VOTableException {
  142 + resultsCtrl = new VOTableController(tableServiceURL, query);
  143 + resultsCtrl.readTable();
  144 + voTablePath = resultsCtrl.getVOTablePath();
125 } 145 }
126 146
127 } 147 }
src/main/java/eu/omp/irap/vespa/epntapclient/EpnTapMainApp.java
@@ -63,7 +63,7 @@ public class EpnTapMainApp { @@ -63,7 +63,7 @@ public class EpnTapMainApp {
63 63
64 /** 64 /**
65 * Creates runnable used to run the application GUI. 65 * Creates runnable used to run the application GUI.
66 - * 66 + *
67 * @param voTableView The VOTable main view, created by the controller. 67 * @param voTableView The VOTable main view, created by the controller.
68 * @param title The title of the application window. 68 * @param title The title of the application window.
69 * @return The runnable. 69 * @return The runnable.
src/main/java/eu/omp/irap/vespa/epntapclient/RequestCtrl.java
@@ -20,6 +20,7 @@ import java.util.ArrayList; @@ -20,6 +20,7 @@ import java.util.ArrayList;
20 import java.util.HashMap; 20 import java.util.HashMap;
21 import java.util.List; 21 import java.util.List;
22 import java.util.Map; 22 import java.util.Map;
  23 +import java.util.logging.Logger;
23 24
24 import com.google.gson.JsonArray; 25 import com.google.gson.JsonArray;
25 import com.google.gson.JsonObject; 26 import com.google.gson.JsonObject;
@@ -33,25 +34,40 @@ import eu.omp.irap.vespa.votable.utils.StringJoiner; @@ -33,25 +34,40 @@ import eu.omp.irap.vespa.votable.utils.StringJoiner;
33 */ 34 */
34 public class RequestCtrl { 35 public class RequestCtrl {
35 36
  37 + /** The text in the query to replaced by the actual table name. */
  38 + private static final String KEYWORD_TABLE_NAME_ = "#tablename#";
  39 +
  40 + /** The logger for the class RequestCtrl. */
  41 + private static final Logger LOGGER = Logger.getLogger(RequestCtrl.class.getName());
  42 +
  43 + /** The query template to get granules. */
  44 + private static final String QUERY_TEMPLATE = "SELECT DISTINCT TOP %s %s FROM "
  45 + + KEYWORD_TABLE_NAME_ + "%s";
  46 +
36 /** The URL of the resolver used for the `target name` field. */ 47 /** The URL of the resolver used for the `target name` field. */
37 private static final String RESOLVER_URL = "http://voparis-registry.obspm.fr/ssodnet/1/autocomplete"; 48 private static final String RESOLVER_URL = "http://voparis-registry.obspm.fr/ssodnet/1/autocomplete";
38 49
39 - /** The text in the query to replaced by the actual table name. */  
40 - protected static final String TABLE_NAME_KEYWORD = "#tablename#"; 50 + /** The names of the columns used in the SELECT keyword in the query. */
  51 + protected List<String> columnNames;
41 52
42 - /** The query template to get granules. */  
43 - private static final String QUERY = "SELECT DISTINCT TOP %s %s FROM " + TABLE_NAME_KEYWORD  
44 - + "%s"; 53 + /** The maximum number of rows returned by the query. */
  54 + protected int nbMaxResult;
45 55
46 /** The parameters fields for the request. */ 56 /** The parameters fields for the request. */
47 protected Map<String, Object> parameters = new HashMap<>(); 57 protected Map<String, Object> parameters = new HashMap<>();
48 58
49 - /** The maximum number of rows returned by the query. */  
50 - private int nbMaxResult; 59 + /**
  60 + * The query to send, with the name of the table is replaced by {@link #KEYWORD_TABLE_NAME_}.
  61 + */
  62 + protected String query;
51 63
52 64
53 - /** Constructor of RequestCtrl. */ 65 + /** Default constructor of RequestCtrl. */
54 public RequestCtrl() { 66 public RequestCtrl() {
  67 + List<String> newColumnNames = new ArrayList<>();
  68 + newColumnNames.add("target_name");
  69 + newColumnNames.add("target_class");
  70 + columnNames = newColumnNames;
55 nbMaxResult = 20; 71 nbMaxResult = 20;
56 } 72 }
57 73
@@ -60,35 +76,9 @@ public class RequestCtrl { @@ -60,35 +76,9 @@ public class RequestCtrl {
60 * 76 *
61 * @param nbMaxResult The maximum number of rows returned by the query. 77 * @param nbMaxResult The maximum number of rows returned by the query.
62 */ 78 */
63 - public RequestCtrl(int nbMaxResult) { 79 + public RequestCtrl(int nbMaxResult, List<String> columnNames) {
64 this.nbMaxResult = nbMaxResult; 80 this.nbMaxResult = nbMaxResult;
65 - }  
66 -  
67 - /**  
68 - * Build an ADQL from the table name, the parameter values and the max results.  
69 - *  
70 - * @param tableName The names of the tables, to put in the FROM keyword.  
71 - * @return The query.  
72 - */  
73 - public String buildQuery(List<String> columnNames) {  
74 - StringJoiner addJoin = new StringJoiner(" AND ");  
75 - for (Map.Entry<String, Object> param : parameters.entrySet()) {  
76 - if (param.getValue() instanceof ArrayList) {  
77 - StringJoiner orJoin = new StringJoiner(" OR ");  
78 - @SuppressWarnings("unchecked")  
79 - List<String> possibleValues = (List<String>) param.getValue();  
80 - for (String possibleValue : possibleValues) {  
81 - orJoin.add(param.getKey() + " LIKE '" + possibleValue + "'");  
82 - }  
83 - addJoin.add("(" + orJoin + ")");  
84 - } else if (param.getValue() instanceof String) {  
85 - addJoin.add(param.getKey() + " LIKE '" + param.getValue() + "'");  
86 - } else {  
87 - addJoin.add(param.getKey() + " = " + param.getValue().toString());  
88 - }  
89 - }  
90 - String where = addJoin.isEmpty() ? "" : " WHERE " + addJoin;  
91 - return String.format(QUERY, nbMaxResult, StringJoiner.join(columnNames), where); 81 + this.columnNames = columnNames;
92 } 82 }
93 83
94 /** 84 /**
@@ -114,23 +104,15 @@ public class RequestCtrl { @@ -114,23 +104,15 @@ public class RequestCtrl {
114 return targetNames; 104 return targetNames;
115 } 105 }
116 106
117 - /**  
118 - * Update a parameter in the query. If the parameter do not exists yet, create it.  
119 - *  
120 - * @param paramName The name of the parameter.  
121 - * @param paramValue The value of the parameter.  
122 - */  
123 - public void updateParameter(String paramName, Object paramValue) {  
124 - parameters.put(paramName, paramValue); 107 + public List<String> getColumnNames() {
  108 + return columnNames;
125 } 109 }
126 110
127 /** 111 /**
128 - * Remove a parameter from the query.  
129 - *  
130 - * @param paramName The name of the parameter to remove. 112 + * @return The maximum number of rows returned by the query.
131 */ 113 */
132 - public void removeParameter(String paramName) {  
133 - parameters.remove(paramName); 114 + public int getNbMaxResult() {
  115 + return nbMaxResult;
134 } 116 }
135 117
136 /** 118 /**
@@ -142,11 +124,22 @@ public class RequestCtrl { @@ -142,11 +124,22 @@ public class RequestCtrl {
142 return parameters; 124 return parameters;
143 } 125 }
144 126
  127 + public String getQuery(String tableName) {
  128 + return query.replace(KEYWORD_TABLE_NAME_, tableName);
  129 + }
  130 +
145 /** 131 /**
146 - * @return The maximum number of rows returned by the query. 132 + * Remove a parameter from the query.
  133 + *
  134 + * @param paramName The name of the parameter to remove.
147 */ 135 */
148 - public int getNbMaxResult() {  
149 - return nbMaxResult; 136 + public void removeParameter(String paramName) {
  137 + parameters.remove(paramName);
  138 + LOGGER.info("removed " + paramName);
  139 + }
  140 +
  141 + public void setColumnNames(List<String> columnNames) {
  142 + this.columnNames = columnNames;
150 } 143 }
151 144
152 /** 145 /**
@@ -158,4 +151,46 @@ public class RequestCtrl { @@ -158,4 +151,46 @@ public class RequestCtrl {
158 nbMaxResult = nbRows; 151 nbMaxResult = nbRows;
159 } 152 }
160 153
  154 + public void setQuery(String query) {
  155 + this.query = query;
  156 + }
  157 +
  158 + /**
  159 + * Update a parameter in the query. If the parameter do not exists yet, create it.
  160 + *
  161 + * @param paramName The name of the parameter.
  162 + * @param paramValue The value of the parameter.
  163 + */
  164 + public void updateParameter(String paramName, Object paramValue) {
  165 + parameters.put(paramName, paramValue);
  166 + LOGGER.info("updated " + paramName + ": " + paramValue);
  167 +
  168 + }
  169 +
  170 + /**
  171 + * Update the ADQL query, from the column names, the table name, the parameter values and the
  172 + * max results.
  173 + */
  174 + public void updateQuery() {
  175 + StringJoiner addJoin = new StringJoiner(" AND ");
  176 + for (Map.Entry<String, Object> param : parameters.entrySet()) {
  177 + if (param.getValue() instanceof ArrayList) {
  178 + StringJoiner orJoin = new StringJoiner(" OR ");
  179 + @SuppressWarnings("unchecked")
  180 + List<String> possibleValues = (List<String>) param.getValue();
  181 + for (String possibleValue : possibleValues) {
  182 + orJoin.add(param.getKey() + " LIKE '" + possibleValue + "'");
  183 + }
  184 + addJoin.add("(" + orJoin + ")");
  185 + } else if (param.getValue() instanceof String) {
  186 + addJoin.add(param.getKey() + " LIKE '" + param.getValue() + "'");
  187 + } else {
  188 + addJoin.add(param.getKey() + " = " + param.getValue().toString());
  189 + }
  190 + }
  191 + String where = addJoin.isEmpty() ? "" : " WHERE " + addJoin;
  192 + query = String.format(QUERY_TEMPLATE, nbMaxResult, StringJoiner.join(columnNames), where);
  193 +
  194 + }
  195 +
161 } 196 }
src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainpanel/MainPanelCtrl.java
@@ -17,8 +17,6 @@ @@ -17,8 +17,6 @@
17 package eu.omp.irap.vespa.epntapclient.gui.mainpanel; 17 package eu.omp.irap.vespa.epntapclient.gui.mainpanel;
18 18
19 import java.util.List; 19 import java.util.List;
20 -import java.util.logging.Level;  
21 -import java.util.logging.Logger;  
22 20
23 import javax.swing.JOptionPane; 21 import javax.swing.JOptionPane;
24 22
@@ -26,26 +24,21 @@ import eu.omp.irap.vespa.epntapclient.EpnTapController; @@ -26,26 +24,21 @@ import eu.omp.irap.vespa.epntapclient.EpnTapController;
26 import eu.omp.irap.vespa.epntapclient.gui.requestpanel.RequestPanelCtrl; 24 import eu.omp.irap.vespa.epntapclient.gui.requestpanel.RequestPanelCtrl;
27 import eu.omp.irap.vespa.epntapclient.gui.resultpanel.ResultPanelCtrl; 25 import eu.omp.irap.vespa.epntapclient.gui.resultpanel.ResultPanelCtrl;
28 import eu.omp.irap.vespa.epntapclient.gui.servicespanel.ServicesPanelCtrl; 26 import eu.omp.irap.vespa.epntapclient.gui.servicespanel.ServicesPanelCtrl;
29 -import eu.omp.irap.vespa.votable.controller.VOTableException;  
30 -import eu.omp.irap.vespa.votable.utils.StringJoiner;  
31 27
32 /** 28 /**
33 * @author N. Jourdane 29 * @author N. Jourdane
34 */ 30 */
35 public class MainPanelCtrl extends EpnTapController implements MainPanelListener { 31 public class MainPanelCtrl extends EpnTapController implements MainPanelListener {
36 32
37 - /** The logger for the class GUIController. */  
38 - private static final Logger LOGGER = Logger.getLogger(MainPanelCtrl.class.getName());  
39 -  
40 /** The controller of the request panel. */ 33 /** The controller of the request panel. */
41 private RequestPanelCtrl requestPanelCtrl; 34 private RequestPanelCtrl requestPanelCtrl;
42 35
  36 + /** The controller of the result panel. */
  37 + private ResultPanelCtrl resultsPanelCtrl;
  38 +
43 /** The controller of the services panel. */ 39 /** The controller of the services panel. */
44 private ServicesPanelCtrl servicesPanelCtrl; 40 private ServicesPanelCtrl servicesPanelCtrl;
45 41
46 - /** The controller of the result panel. */  
47 - private ResultPanelCtrl resultPanelCtrl;  
48 -  
49 /** The main view of the application. */ 42 /** The main view of the application. */
50 private MainPanelView view; 43 private MainPanelView view;
51 44
@@ -55,57 +48,44 @@ public class MainPanelCtrl extends EpnTapController implements MainPanelListener @@ -55,57 +48,44 @@ public class MainPanelCtrl extends EpnTapController implements MainPanelListener
55 */ 48 */
56 public MainPanelCtrl() { 49 public MainPanelCtrl() {
57 servicesPanelCtrl = new ServicesPanelCtrl(this); 50 servicesPanelCtrl = new ServicesPanelCtrl(this);
58 - resultPanelCtrl = new ResultPanelCtrl(); 51 + resultsPanelCtrl = new ResultPanelCtrl(this);
59 requestPanelCtrl = new RequestPanelCtrl(this); 52 requestPanelCtrl = new RequestPanelCtrl(this);
60 view = new MainPanelView(this); 53 view = new MainPanelView(this);
61 } 54 }
62 55
63 @Override 56 @Override
64 - public void readServices() {  
65 - try {  
66 - servicesPanelCtrl.readTable();  
67 - } catch (VOTableException e) {  
68 - displayError("Can not get services.", e);  
69 - }  
70 - view.getServicesPanel().fillTable(servicesPanelCtrl.getVOTableData()); 57 + public void displayError(String message, Exception e) {
  58 + super.displayError(message, e);
  59 + JOptionPane.showMessageDialog(view, e.getMessage(), message, JOptionPane.ERROR_MESSAGE);
71 } 60 }
72 61
73 /** 62 /**
74 - * Send the specified query to the selected service and update the result table content.  
75 - *  
76 - * @param query The query to send. 63 + * @return The controller of the request panel.
77 */ 64 */
78 - public void sendQuery(String query) {  
79 - List<String> selectedServicesUrls = servicesPanelCtrl.getSelectedServicesUrls();  
80 - LOGGER.info("Sending query: " + query + " on " + StringJoiner.join(selectedServicesUrls));  
81 - try {  
82 - resultPanelCtrl.updateVOTable(StringJoiner.join(selectedServicesUrls), query);  
83 - view.getResultsPanel().fillTable(resultPanelCtrl.getVOTableData());  
84 - } catch (VOTableException e) {  
85 - displayError("Can not send the query.", e);  
86 - LOGGER.log(Level.WARNING, "Can not send query.", e);  
87 - } 65 + @Override
  66 + public RequestPanelCtrl getRequestCtrl() {
  67 + return requestPanelCtrl;
88 } 68 }
89 69
90 /** 70 /**
91 - * @return The controller of the request panel. 71 + * @return The controller of the result panel.
92 */ 72 */
93 - public RequestPanelCtrl getRequestPanelCtrl() {  
94 - return requestPanelCtrl; 73 + @Override
  74 + public ResultPanelCtrl getResultsCtrl() {
  75 + return resultsPanelCtrl;
95 } 76 }
96 77
97 /** 78 /**
98 * @return The controller of the service panel. 79 * @return The controller of the service panel.
99 */ 80 */
100 - public ServicesPanelCtrl getServicePanelCtrl() { 81 + @Override
  82 + public ServicesPanelCtrl getServicesCtrl() {
101 return servicesPanelCtrl; 83 return servicesPanelCtrl;
102 } 84 }
103 85
104 - /**  
105 - * @return The controller of the result panel.  
106 - */  
107 - public ResultPanelCtrl getResultPanelCtrl() {  
108 - return resultPanelCtrl; 86 + @Override
  87 + public List<String> getTableNames() {
  88 + return servicesPanelCtrl.getTablesNames();
109 } 89 }
110 90
111 /** 91 /**
@@ -116,35 +96,18 @@ public class MainPanelCtrl extends EpnTapController implements MainPanelListener @@ -116,35 +96,18 @@ public class MainPanelCtrl extends EpnTapController implements MainPanelListener
116 } 96 }
117 97
118 @Override 98 @Override
119 - public void displayError(String message, Exception e) {  
120 - LOGGER.log(Level.SEVERE, message, e);  
121 - JOptionPane.showMessageDialog(view, e.getMessage(), message, JOptionPane.ERROR_MESSAGE);  
122 - }  
123 -  
124 - @Override  
125 - public void updateQuery() {  
126 - requestPanelCtrl.updateQueryArea(); 99 + public void readServices() {
  100 + super.readServices();
  101 + view.getServicesPanel().fillTable(servicesPanelCtrl.getVOTableData());
127 } 102 }
128 103
129 @Override 104 @Override
130 public void sendQuery() { 105 public void sendQuery() {
131 - List<String> servicesUrls = servicesPanelCtrl.getSelectedServicesUrls();  
132 - List<String> tableNames = servicesPanelCtrl.getSelectedTablesNames();  
133 - servicesUrls.addAll(servicesPanelCtrl.getCustomServicesUrls());  
134 - tableNames.addAll(servicesPanelCtrl.getCustomTablesNames());  
135 - try {  
136 - for (int i = 0; i < servicesUrls.size(); i++) {  
137 - String query = requestPanelCtrl.getQuery(tableNames.get(i));  
138 - resultPanelCtrl.updateVOTable(servicesUrls.get(i), query);  
139 - }  
140 - } catch (VOTableException e) {  
141 - displayError("Can not update the VOTable.", e);  
142 - }  
143 - resultPanelCtrl.getView().fillTable(resultPanelCtrl.getVOTableData()); 106 + sendQuery(servicesPanelCtrl.getTablesNames(), servicesPanelCtrl.getServicesUrls());
144 } 107 }
145 108
146 @Override 109 @Override
147 - public List<String> getTableNames() {  
148 - return servicesPanelCtrl.getSelectedTablesNames(); 110 + public void updateQuery() {
  111 + requestPanelCtrl.updateQuery();
149 } 112 }
150 } 113 }
src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainpanel/MainPanelListener.java
@@ -23,9 +23,11 @@ import java.util.List; @@ -23,9 +23,11 @@ import java.util.List;
23 */ 23 */
24 public interface MainPanelListener { 24 public interface MainPanelListener {
25 25
26 - void updateQuery(); 26 + List<String> getTableNames();
27 27
28 void sendQuery(); 28 void sendQuery();
29 29
30 - List<String> getTableNames(); 30 + void updateQuery();
  31 +
  32 + void displayError(String message, Exception e);
31 } 33 }
src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainpanel/MainPanelView.java
@@ -54,9 +54,9 @@ public class MainPanelView extends JPanel { @@ -54,9 +54,9 @@ public class MainPanelView extends JPanel {
54 */ 54 */
55 55
56 public MainPanelView(MainPanelCtrl mainPanelCtrl) { 56 public MainPanelView(MainPanelCtrl mainPanelCtrl) {
57 - servicesPanel = mainPanelCtrl.getServicePanelCtrl().getView();  
58 - resultPanel = mainPanelCtrl.getResultPanelCtrl().getView();  
59 - requestPanel = mainPanelCtrl.getRequestPanelCtrl().getView(); 57 + servicesPanel = mainPanelCtrl.getServicesCtrl().getView();
  58 + resultPanel = mainPanelCtrl.getResultsCtrl().getView();
  59 + requestPanel = mainPanelCtrl.getRequestCtrl().getView();
60 buildMainView(); 60 buildMainView();
61 } 61 }
62 62
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/RequestPanelCtrl.java
@@ -16,13 +16,6 @@ @@ -16,13 +16,6 @@
16 16
17 package eu.omp.irap.vespa.epntapclient.gui.requestpanel; 17 package eu.omp.irap.vespa.epntapclient.gui.requestpanel;
18 18
19 -import java.util.ArrayList;  
20 -import java.util.List;  
21 -import java.util.logging.Level;  
22 -import java.util.logging.Logger;  
23 -  
24 -import javax.swing.JOptionPane;  
25 -  
26 import eu.omp.irap.vespa.epntapclient.RequestCtrl; 19 import eu.omp.irap.vespa.epntapclient.RequestCtrl;
27 import eu.omp.irap.vespa.epntapclient.gui.mainpanel.MainPanelListener; 20 import eu.omp.irap.vespa.epntapclient.gui.mainpanel.MainPanelListener;
28 21
@@ -31,9 +24,6 @@ import eu.omp.irap.vespa.epntapclient.gui.mainpanel.MainPanelListener; @@ -31,9 +24,6 @@ import eu.omp.irap.vespa.epntapclient.gui.mainpanel.MainPanelListener;
31 */ 24 */
32 public class RequestPanelCtrl extends RequestCtrl implements RequestPanelListener { 25 public class RequestPanelCtrl extends RequestCtrl implements RequestPanelListener {
33 26
34 - /** The logger for the class RequestPanelCtrl. */  
35 - private static final Logger LOGGER = Logger.getLogger(RequestPanelCtrl.class.getName());  
36 -  
37 /** The controller of the main panel. */ 27 /** The controller of the main panel. */
38 private MainPanelListener listener; 28 private MainPanelListener listener;
39 29
@@ -48,21 +38,28 @@ public class RequestPanelCtrl extends RequestCtrl implements RequestPanelListene @@ -48,21 +38,28 @@ public class RequestPanelCtrl extends RequestCtrl implements RequestPanelListene
48 */ 38 */
49 public RequestPanelCtrl(MainPanelListener listener) { 39 public RequestPanelCtrl(MainPanelListener listener) {
50 this.listener = listener; 40 this.listener = listener;
  41 + // TODO: Add panel to enter column names and the max results.
51 view = new RequestPanelView(this); 42 view = new RequestPanelView(this);
52 } 43 }
53 44
54 /** 45 /**
55 - * @return The view of the request panel. 46 + * @return The view of the request panel. Used in MainPanelCtrl to add panels in the main
  47 + * window.
56 */ 48 */
57 public RequestPanelView getView() { 49 public RequestPanelView getView() {
58 return view; 50 return view;
59 } 51 }
60 52
61 - /**  
62 - * @return The text contained in the query area.  
63 - */  
64 - public String getQuery(String tableName) {  
65 - return view.getQueryArea().getText().replace(TABLE_NAME_KEYWORD, tableName); 53 + @Override
  54 + public void onParameterRemoved(String paramName) {
  55 + removeParameter(paramName);
  56 + updateQuery();
  57 + }
  58 +
  59 + @Override
  60 + public void onParameterUpdated(String paramName, Object paramValue) {
  61 + updateParameter(paramName, paramValue);
  62 + updateQuery();
66 } 63 }
67 64
68 @Override 65 @Override
@@ -71,35 +68,12 @@ public class RequestPanelCtrl extends RequestCtrl implements RequestPanelListene @@ -71,35 +68,12 @@ public class RequestPanelCtrl extends RequestCtrl implements RequestPanelListene
71 } 68 }
72 69
73 /** 70 /**
74 - * Update the query area with a working ADQL query, based on the parameters list. 71 + * Update the query and the query area with a working ADQL query, based on the parameters list.
75 */ 72 */
76 - public void updateQueryArea() {  
77 - // TODO: several services  
78 - // TODO: Add panel to enter column names.  
79 - List<String> columnNames = new ArrayList<>();  
80 - columnNames.add("target_name");  
81 - columnNames.add("target_class");  
82 - String query = buildQuery(columnNames);  
83 - view.updateQueryArea(query);  
84 - }  
85 -  
86 - @Override  
87 - public void onParameterRemoved(String paramName) {  
88 - removeParameter(paramName);  
89 - updateQueryArea();  
90 - LOGGER.info("removed " + paramName);  
91 - }  
92 -  
93 @Override 73 @Override
94 - public void onParameterChanged(String paramName, Object paramValue) {  
95 - updateParameter(paramName, paramValue);  
96 - updateQueryArea();  
97 - LOGGER.info("uploaded " + paramName + ": " + paramValue); 74 + public void updateQuery() {
  75 + super.updateQuery();
  76 + view.updateQueryArea(query);
98 } 77 }
99 78
100 - @Override  
101 - public void onError(Exception e) {  
102 - LOGGER.log(Level.SEVERE, e.getMessage(), e);  
103 - JOptionPane.showMessageDialog(view, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);  
104 - }  
105 } 79 }
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/RequestPanelListener.java
@@ -39,13 +39,5 @@ public interface RequestPanelListener { @@ -39,13 +39,5 @@ public interface RequestPanelListener {
39 * @param paramName The name of the changed parameter. 39 * @param paramName The name of the changed parameter.
40 * @param paramValue The new value of the parameter. 40 * @param paramValue The new value of the parameter.
41 */ 41 */
42 - void onParameterChanged(String paramName, Object paramValue);  
43 -  
44 - /**  
45 - * Display an error to the user.  
46 - *  
47 - * @param e The error to display to the user.  
48 - */  
49 - public void onError(Exception e);  
50 - 42 + void onParameterUpdated(String paramName, Object paramValue);
51 } 43 }
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/paramfield/DataProductTypeField.java
@@ -85,7 +85,7 @@ public class DataProductTypeField extends ParamField { @@ -85,7 +85,7 @@ public class DataProductTypeField extends ParamField {
85 if (DataProductType.ALL.equals(item)) { 85 if (DataProductType.ALL.equals(item)) {
86 requestPanelListener.onParameterRemoved(paramName); 86 requestPanelListener.onParameterRemoved(paramName);
87 } else { 87 } else {
88 - requestPanelListener.onParameterChanged(paramName, item.query()); 88 + requestPanelListener.onParameterUpdated(paramName, item.query());
89 } 89 }
90 } 90 }
91 91
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/paramfield/DateRangeField.java
@@ -92,7 +92,7 @@ public class DateRangeField extends ParamField implements TextFieldListener { @@ -92,7 +92,7 @@ public class DateRangeField extends ParamField implements TextFieldListener {
92 try { 92 try {
93 long date = df.parse(field.getText()).getTime(); 93 long date = df.parse(field.getText()).getTime();
94 date = Math.round(date / 86400000.0 + 2440587.5); // to JD 94 date = Math.round(date / 86400000.0 + 2440587.5); // to JD
95 - requestPanelListener.onParameterChanged(paramName + field.getName(), 95 + requestPanelListener.onParameterUpdated(paramName + field.getName(),
96 date); 96 date);
97 field.setBackground(Color.WHITE); 97 field.setBackground(Color.WHITE);
98 } catch (@SuppressWarnings("unused") ParseException e) { 98 } catch (@SuppressWarnings("unused") ParseException e) {
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/paramfield/FloatField.java
@@ -62,7 +62,7 @@ public class FloatField extends ParamField implements TextFieldListener { @@ -62,7 +62,7 @@ public class FloatField extends ParamField implements TextFieldListener {
62 } else { 62 } else {
63 try { 63 try {
64 float value = Float.parseFloat(textField.getText()); 64 float value = Float.parseFloat(textField.getText());
65 - requestPanelListener.onParameterChanged(paramName, value); 65 + requestPanelListener.onParameterUpdated(paramName, value);
66 textField.setBackground(Color.WHITE); 66 textField.setBackground(Color.WHITE);
67 } catch (@SuppressWarnings("unused") NumberFormatException e) { 67 } catch (@SuppressWarnings("unused") NumberFormatException e) {
68 textField.setBackground(Color.PINK); 68 textField.setBackground(Color.PINK);
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/paramfield/FloatRangeField.java
@@ -70,7 +70,7 @@ public class FloatRangeField extends ParamField implements TextFieldListener { @@ -70,7 +70,7 @@ public class FloatRangeField extends ParamField implements TextFieldListener {
70 requestPanelListener.onParameterRemoved(paramName + field.getName()); 70 requestPanelListener.onParameterRemoved(paramName + field.getName());
71 } else { 71 } else {
72 try { 72 try {
73 - requestPanelListener.onParameterChanged(paramName + field.getName(), 73 + requestPanelListener.onParameterUpdated(paramName + field.getName(),
74 Float.parseFloat(field.getText())); 74 Float.parseFloat(field.getText()));
75 field.setBackground(Color.WHITE); 75 field.setBackground(Color.WHITE);
76 } catch (@SuppressWarnings("unused") NumberFormatException e) { 76 } catch (@SuppressWarnings("unused") NumberFormatException e) {
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/paramfield/StringField.java
@@ -54,9 +54,9 @@ public class StringField extends ParamField implements TextFieldListener { @@ -54,9 +54,9 @@ public class StringField extends ParamField implements TextFieldListener {
54 @Override 54 @Override
55 public void update(JTextField textField) { 55 public void update(JTextField textField) {
56 if (textField.getText().isEmpty()) { 56 if (textField.getText().isEmpty()) {
57 - requestPanelListener.onParameterChanged(paramName, null); 57 + requestPanelListener.onParameterUpdated(paramName, null);
58 } else { 58 } else {
59 - requestPanelListener.onParameterChanged(paramName, textField.getText()); 59 + requestPanelListener.onParameterUpdated(paramName, textField.getText());
60 } 60 }
61 } 61 }
62 } 62 }
63 \ No newline at end of file 63 \ No newline at end of file
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/paramfield/TargetClassField.java
@@ -70,7 +70,7 @@ public class TargetClassField extends ParamField { @@ -70,7 +70,7 @@ public class TargetClassField extends ParamField {
70 if (TargetClass.ALL.equals(value)) { 70 if (TargetClass.ALL.equals(value)) {
71 requestPanelListener.onParameterRemoved(paramName); 71 requestPanelListener.onParameterRemoved(paramName);
72 } else { 72 } else {
73 - requestPanelListener.onParameterChanged(paramName, value.query()); 73 + requestPanelListener.onParameterUpdated(paramName, value.query());
74 } 74 }
75 } 75 }
76 76
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/paramfield/TargetNameField.java
@@ -93,14 +93,9 @@ public class TargetNameField extends ParamField implements TextFieldListener { @@ -93,14 +93,9 @@ public class TargetNameField extends ParamField implements TextFieldListener {
93 } 93 }
94 94
95 @Override 95 @Override
96 - public void onParameterChanged(String paramName, Object paramValue) { 96 + public void onParameterUpdated(String paramName, Object paramValue) {
97 /** No ParameterChanged event, we just want the field itself. */ 97 /** No ParameterChanged event, we just want the field itself. */
98 } 98 }
99 -  
100 - @Override  
101 - public void onError(Exception e) {  
102 - /** No Error event, we just want the field itself. */  
103 - }  
104 }, paraName); 99 }, paraName);
105 } 100 }
106 101
@@ -128,7 +123,7 @@ public class TargetNameField extends ParamField implements TextFieldListener { @@ -128,7 +123,7 @@ public class TargetNameField extends ParamField implements TextFieldListener {
128 if (content.isEmpty()) { 123 if (content.isEmpty()) {
129 requestPanelListener.onParameterRemoved(paramName); 124 requestPanelListener.onParameterRemoved(paramName);
130 } else { 125 } else {
131 - requestPanelListener.onParameterChanged(paramName, content); 126 + requestPanelListener.onParameterUpdated(paramName, content);
132 } 127 }
133 } 128 }
134 } 129 }
src/main/java/eu/omp/irap/vespa/epntapclient/gui/resultpanel/ResultPanelCtrl.java
@@ -20,13 +20,10 @@ import java.io.File; @@ -20,13 +20,10 @@ import java.io.File;
20 import java.io.IOException; 20 import java.io.IOException;
21 import java.nio.file.Files; 21 import java.nio.file.Files;
22 import java.nio.file.Paths; 22 import java.nio.file.Paths;
23 -import java.util.logging.Level;  
24 import java.util.logging.Logger; 23 import java.util.logging.Logger;
25 24
26 -import javax.swing.JOptionPane;  
27 - 25 +import eu.omp.irap.vespa.epntapclient.gui.mainpanel.MainPanelListener;
28 import eu.omp.irap.vespa.votable.controller.VOTableController; 26 import eu.omp.irap.vespa.votable.controller.VOTableController;
29 -import eu.omp.irap.vespa.votable.controller.VOTableException.CantSaveVOTableException;  
30 import eu.omp.irap.vespa.votable.utils.StringJoiner; 27 import eu.omp.irap.vespa.votable.utils.StringJoiner;
31 28
32 /** 29 /**
@@ -40,38 +37,42 @@ public class ResultPanelCtrl extends VOTableController implements ResultPanelLis @@ -40,38 +37,42 @@ public class ResultPanelCtrl extends VOTableController implements ResultPanelLis
40 /** The result panel view. */ 37 /** The result panel view. */
41 private ResultPanelView view; 38 private ResultPanelView view;
42 39
  40 + /** The listener of the main panel. */
  41 + private MainPanelListener listener;
  42 +
43 43
44 /** 44 /**
45 * Constructor of ResultPanelCtrl. 45 * Constructor of ResultPanelCtrl.
46 */ 46 */
47 - public ResultPanelCtrl() { 47 + public ResultPanelCtrl(MainPanelListener listener) {
  48 + this.listener = listener;
48 view = new ResultPanelView(this); 49 view = new ResultPanelView(this);
49 } 50 }
50 51
51 @Override 52 @Override
52 - public void onDownloadButtonClicked(File file) throws CantSaveVOTableException { 53 + public void onDownloadButtonClicked(File file) {
53 try { 54 try {
54 Files.copy(Paths.get(voTablePath), Paths.get(file.getAbsolutePath())); 55 Files.copy(Paths.get(voTablePath), Paths.get(file.getAbsolutePath()));
55 } catch (IOException e) { 56 } catch (IOException e) {
56 - throw new CantSaveVOTableException(file.getAbsolutePath(), e); 57 + listener.displayError("Can not save the VOTable file.", e);
57 } 58 }
58 } 59 }
59 60
60 /** 61 /**
61 - * @return The view of the result panel. 62 + * @return The view of the result panel. Used in MainPanelCtrl to add panels in the main window.
62 */ 63 */
63 public ResultPanelView getView() { 64 public ResultPanelView getView() {
64 return view; 65 return view;
65 } 66 }
66 67
67 @Override 68 @Override
68 - public void onRowsSelected() {  
69 - LOGGER.info("Selected row: " + StringJoiner.join(view.getSelectedRows())); 69 + public void updateVOTable(String newTargetURL, String newQuery)
  70 + throws eu.omp.irap.vespa.votable.controller.VOTableException {
  71 + view.fillTable(voTableData);
70 } 72 }
71 73
72 @Override 74 @Override
73 - public void onError(Exception e) {  
74 - LOGGER.log(Level.SEVERE, e.getMessage(), e);  
75 - JOptionPane.showMessageDialog(view, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); 75 + public void onRowsSelected() {
  76 + LOGGER.info("Selected row: " + StringJoiner.join(view.getSelectedRows()));
76 } 77 }
77 } 78 }
src/main/java/eu/omp/irap/vespa/epntapclient/gui/resultpanel/ResultPanelListener.java
@@ -33,12 +33,5 @@ public interface ResultPanelListener extends VOTableViewListener { @@ -33,12 +33,5 @@ public interface ResultPanelListener extends VOTableViewListener {
33 * place where save the VOTable. 33 * place where save the VOTable.
34 * @throws CantSaveVOTableException The VOTable can not be saved at the specified location. 34 * @throws CantSaveVOTableException The VOTable can not be saved at the specified location.
35 */ 35 */
36 - public void onDownloadButtonClicked(File file) throws CantSaveVOTableException;  
37 -  
38 - /**  
39 - * Display an error to the user.  
40 - *  
41 - * @param e The error to display to the user.  
42 - */  
43 - public void onError(Exception e); 36 + public void onDownloadButtonClicked(File file);
44 } 37 }
src/main/java/eu/omp/irap/vespa/epntapclient/gui/resultpanel/ResultPanelView.java
@@ -25,7 +25,6 @@ import javax.swing.JFileChooser; @@ -25,7 +25,6 @@ import javax.swing.JFileChooser;
25 import javax.swing.JLabel; 25 import javax.swing.JLabel;
26 import javax.swing.JPanel; 26 import javax.swing.JPanel;
27 27
28 -import eu.omp.irap.vespa.votable.controller.VOTableException.CantSaveVOTableException;  
29 import eu.omp.irap.vespa.votable.view.VOTableView; 28 import eu.omp.irap.vespa.votable.view.VOTableView;
30 29
31 /** 30 /**
@@ -100,11 +99,7 @@ public class ResultPanelView extends VOTableView { @@ -100,11 +99,7 @@ public class ResultPanelView extends VOTableView {
100 public void actionPerformed(ActionEvent evt) { 99 public void actionPerformed(ActionEvent evt) {
101 final JFileChooser fc = new JFileChooser(); 100 final JFileChooser fc = new JFileChooser();
102 fc.showOpenDialog(ResultPanelView.this); 101 fc.showOpenDialog(ResultPanelView.this);
103 - try {  
104 - listener.onDownloadButtonClicked(fc.getSelectedFile());  
105 - } catch (CantSaveVOTableException e) {  
106 - listener.onError(e);  
107 - } 102 + listener.onDownloadButtonClicked(fc.getSelectedFile());
108 } 103 }
109 }); 104 });
110 } 105 }
src/main/java/eu/omp/irap/vespa/epntapclient/gui/servicespanel/ServicesPanelCtrl.java
@@ -49,6 +49,12 @@ public class ServicesPanelCtrl extends VOTableController implements ServicesPane @@ -49,6 +49,12 @@ public class ServicesPanelCtrl extends VOTableController implements ServicesPane
49 private ServicesPanelView view; 49 private ServicesPanelView view;
50 50
51 /** The list of services table names selected by the user on the service panel. */ 51 /** The list of services table names selected by the user on the service panel. */
  52 + private List<String> tablesNames;
  53 +
  54 + /** The list of services target Urls selected by the user on the service panel. */
  55 + private List<String> servicesUrls;
  56 +
  57 + /** The list of services table names selected by the user on the service panel. */
52 private List<String> selectedTablesNames; 58 private List<String> selectedTablesNames;
53 59
54 /** The list of services target Urls selected by the user on the service panel. */ 60 /** The list of services target Urls selected by the user on the service panel. */
@@ -79,7 +85,8 @@ public class ServicesPanelCtrl extends VOTableController implements ServicesPane @@ -79,7 +85,8 @@ public class ServicesPanelCtrl extends VOTableController implements ServicesPane
79 } 85 }
80 86
81 /** 87 /**
82 - * @return The view of the services panel. 88 + * @return The view of the services panel. Used in MainPanelCtrl to add panels in the main
  89 + * window.
83 */ 90 */
84 public ServicesPanelView getView() { 91 public ServicesPanelView getView() {
85 return view; 92 return view;
@@ -88,43 +95,34 @@ public class ServicesPanelCtrl extends VOTableController implements ServicesPane @@ -88,43 +95,34 @@ public class ServicesPanelCtrl extends VOTableController implements ServicesPane
88 /** 95 /**
89 * @return The list of services table names selected by the user on the service panel. 96 * @return The list of services table names selected by the user on the service panel.
90 */ 97 */
91 - public List<String> getSelectedTablesNames() {  
92 - return selectedTablesNames; 98 + public List<String> getTablesNames() {
  99 + return tablesNames;
93 } 100 }
94 101
95 /** 102 /**
96 * @return The list of services target Urls selected by the user on the service panel. 103 * @return The list of services target Urls selected by the user on the service panel.
97 */ 104 */
98 - public List<String> getSelectedServicesUrls() {  
99 - return selectedServicesUrls;  
100 - }  
101 -  
102 - /**  
103 - * @return The list of services table names entered by the user in the text field.  
104 - */  
105 - public List<String> getCustomTablesNames() {  
106 - return customTablesNames;  
107 - }  
108 -  
109 - /**  
110 - * @return The list of services target Urls entered by the user in the text field.  
111 - */  
112 - public List<String> getCustomServicesUrls() {  
113 - return customServicesUrls; 105 + public List<String> getServicesUrls() {
  106 + return servicesUrls;
114 } 107 }
115 108
116 @Override 109 @Override
117 public void onRowsSelected() { 110 public void onRowsSelected() {
118 - List<String> servicesUrls = new ArrayList<>();  
119 - List<String> tableNames = new ArrayList<>(); 111 + List<String> newServicesUrls = new ArrayList<>();
  112 + List<String> newTablesNames = new ArrayList<>();
120 113
121 for (int row : view.getSelectedRows()) { 114 for (int row : view.getSelectedRows()) {
122 - servicesUrls.add((String) view.getValueAt(SERVICE_URL_COLUMN_POSITION, row));  
123 - tableNames.add((String) view.getValueAt(TABLE_NAME_COLUMN_POSITION, row)); 115 + newServicesUrls.add((String) view.getValueAt(SERVICE_URL_COLUMN_POSITION, row));
  116 + newTablesNames.add((String) view.getValueAt(TABLE_NAME_COLUMN_POSITION, row));
124 } 117 }
125 118
126 - selectedServicesUrls = servicesUrls;  
127 - selectedTablesNames = tableNames; 119 + selectedServicesUrls = newServicesUrls;
  120 + selectedTablesNames = newTablesNames;
  121 +
  122 + servicesUrls = customServicesUrls;
  123 + tablesNames = customTablesNames;
  124 + servicesUrls.addAll(selectedServicesUrls);
  125 + tablesNames.addAll(customTablesNames);
128 126
129 listener.updateQuery(); 127 listener.updateQuery();
130 LOGGER.info("Updated selected services URLs: " + StringJoiner.join(selectedServicesUrls)); 128 LOGGER.info("Updated selected services URLs: " + StringJoiner.join(selectedServicesUrls));
@@ -137,16 +135,23 @@ public class ServicesPanelCtrl extends VOTableController implements ServicesPane @@ -137,16 +135,23 @@ public class ServicesPanelCtrl extends VOTableController implements ServicesPane
137 String customTableName = view.getTableNameTextField().getText(); 135 String customTableName = view.getTableNameTextField().getText();
138 136
139 if (!customServiceUrl.isEmpty() && !customTableName.isEmpty()) { 137 if (!customServiceUrl.isEmpty() && !customTableName.isEmpty()) {
140 - List<String> servicesUrls = new ArrayList<>();  
141 - List<String> tableNames = new ArrayList<>(); 138 + List<String> newServicesUrls = new ArrayList<>();
  139 + List<String> newTablesNames = new ArrayList<>();
142 140
143 - servicesUrls.addAll(Arrays.asList(customServiceUrl.split(CUSTOM_SERVICES_SEPARATOR)));  
144 - tableNames.addAll(Arrays.asList(customTableName.split(CUSTOM_SERVICES_SEPARATOR))); 141 + newServicesUrls
  142 + .addAll(Arrays.asList(customServiceUrl.split(CUSTOM_SERVICES_SEPARATOR)));
  143 + newTablesNames.addAll(Arrays.asList(customTableName.split(CUSTOM_SERVICES_SEPARATOR)));
145 144
146 - if (servicesUrls.size() == tableNames.size()) { 145 + if (newServicesUrls.size() == newTablesNames.size()) {
147 // TODO: regex to check valid url / table name 146 // TODO: regex to check valid url / table name
148 - customServicesUrls = servicesUrls;  
149 - customTablesNames = tableNames; 147 + customServicesUrls = newServicesUrls;
  148 + customTablesNames = newTablesNames;
  149 +
  150 + servicesUrls = selectedServicesUrls;
  151 + tablesNames = selectedTablesNames;
  152 + servicesUrls.addAll(customServicesUrls);
  153 + tablesNames.addAll(customTablesNames);
  154 +
150 LOGGER.info( 155 LOGGER.info(
151 "Updated custom services URLs: " + StringJoiner.join(customServicesUrls)); 156 "Updated custom services URLs: " + StringJoiner.join(customServicesUrls));
152 LOGGER.info("Updated custom tables names: " + StringJoiner.join(customTablesNames)); 157 LOGGER.info("Updated custom tables names: " + StringJoiner.join(customTablesNames));
src/test/java/eu/omp/irap/vespa/epntapclient/EpnTapConnectionTest.java
@@ -34,7 +34,6 @@ import eu.omp.irap.vespa.epntapclient.voresource.VOResourceException; @@ -34,7 +34,6 @@ import eu.omp.irap.vespa.epntapclient.voresource.VOResourceException;
34 import eu.omp.irap.vespa.epntapclient.voresource.model.Resource; 34 import eu.omp.irap.vespa.epntapclient.voresource.model.Resource;
35 import eu.omp.irap.vespa.epntapclient.votable.model.VOTABLE; 35 import eu.omp.irap.vespa.epntapclient.votable.model.VOTABLE;
36 import eu.omp.irap.vespa.votable.controller.VOTableException; 36 import eu.omp.irap.vespa.votable.controller.VOTableException;
37 -import eu.omp.irap.vespa.votable.utils.Debug;  
38 import eu.omp.irap.vespa.votable.votabledata.VOTableData; 37 import eu.omp.irap.vespa.votable.votabledata.VOTableData;
39 38
40 /** 39 /**
@@ -348,7 +347,6 @@ public class EpnTapConnectionTest { @@ -348,7 +347,6 @@ public class EpnTapConnectionTest {
348 assertEquals(8, granules.size()); 347 assertEquals(8, granules.size());
349 Granule mars = null; 348 Granule mars = null;
350 for (Granule granule : granules) { 349 for (Granule granule : granules) {
351 - System.out.println(Debug.toJson(granule));  
352 if ("Mars".equals(granule.getGranuleUid())) { 350 if ("Mars".equals(granule.getGranuleUid())) {
353 mars = granule; 351 mars = granule;
354 } 352 }
src/test/java/eu/omp/irap/vespa/epntapclient/granule/GranuleTest.java
@@ -83,12 +83,12 @@ public class GranuleTest { @@ -83,12 +83,12 @@ public class GranuleTest {
83 } 83 }
84 84
85 @Test 85 @Test
86 - public void isNotValidTest() { 86 + public static void isNotValidTest() {
87 assertFalse("The incomplete granule is valid.", createIncompleteGranule().isValid()); 87 assertFalse("The incomplete granule is valid.", createIncompleteGranule().isValid());
88 } 88 }
89 89
90 @Test 90 @Test
91 - public void isValidTest() { 91 + public static void isValidTest() {
92 assertTrue("The complete granule is not valid.", createCompleteGranule().isValid()); 92 assertTrue("The complete granule is not valid.", createCompleteGranule().isValid());
93 } 93 }
94 94