From ea7906cde1fe323e36789a15eecd957e253fcddb Mon Sep 17 00:00:00 2001 From: hansonr Date: Sun, 31 Mar 2019 21:40:37 -0500 Subject: [PATCH] JSON refactoring of a few methods; fixing JavaScript issues --- src/jalview/ext/ensembl/EnsemblRestClient.java | 86 +++++++-------------- src/jalview/fts/service/pdb/PDBFTSRestClient.java | 52 ++++++++----- src/jalview/javascript/json/JSON.java | 20 ++--- src/jalview/javascript/web/ClientResponse.java | 60 ++++++++++---- src/jalview/javascript/web/WebResource.java | 11 ++- src/jalview/urls/IdentifiersUrlProvider.java | 12 +-- src/jalview/util/JSONUtils.java | 71 ++++++----------- src/jalview/util/Platform.java | 77 ++++++++++++++++++ 8 files changed, 235 insertions(+), 154 deletions(-) diff --git a/src/jalview/ext/ensembl/EnsemblRestClient.java b/src/jalview/ext/ensembl/EnsemblRestClient.java index 56d63bb..9a647f4 100644 --- a/src/jalview/ext/ensembl/EnsemblRestClient.java +++ b/src/jalview/ext/ensembl/EnsemblRestClient.java @@ -21,8 +21,6 @@ package jalview.ext.ensembl; import jalview.bin.Cache; -import jalview.javascript.json.JSON; -import jalview.util.JSONUtils; import jalview.util.Platform; import jalview.util.StringUtils; @@ -30,8 +28,6 @@ import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; @@ -282,10 +278,12 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher * in milliseconds * @return * @throws IOException + * @throws ParseException */ - private BufferedReader getHttpResponse(URL url, List ids, - int readTimeout) throws IOException + private Object getJSON(URL url, List ids, int readTimeout) + throws IOException, ParseException { + if (readTimeout < 0) { readTimeout = DEFAULT_READ_TIMEOUT; @@ -294,10 +292,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher HttpURLConnection connection = null; int responseCode = 0; - if (Platform.isJS()) - { - JSON.setAjax(url); - } + Platform.setAjaxJSON(url); while (retriesLeft > 0) { @@ -325,15 +320,12 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher InputStream response = connection.getInputStream(); - if (Platform.isJS()) - { - return JSON.getJSONReader(response); - } - - // System.out.println(getClass().getName() + " took " - // + (System.currentTimeMillis() - now) + "ms to fetch"); + Platform.timeCheck(null, Platform.TIME_MARK); + Object ret = Platform.parseJSON(response); + Platform.timeCheck("EnsemblRestClient.getJSON " + url, + Platform.TIME_MARK); - return new BufferedReader(new InputStreamReader(response, "UTF-8")); + return ret; } /** @@ -515,50 +507,26 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher url = getUrl(ids); } - Reader br = null; - try - { - Platform.timeCheck(null, Platform.TIME_MARK); - - br = (url == null ? null : getHttpResponse(url, ids, msDelay)); - - Object ret = (br == null ? null : JSONUtils.parse(br)); - - Platform.timeCheck("EnsemblRestClient.getJSON " + url, - Platform.TIME_MARK); + Object json = (url == null ? null : getJSON(url, ids, msDelay)); - if (ret != null && mapKey != null) - { - ret = ((Map) ret).get(mapKey); - } - if (ret == null) - { - return null; - } - switch (mode) - { - case MODE_ARRAY: - case MODE_MAP: - break; - case MODE_ITERATOR: - ret = ((List) ret).iterator(); - break; - } - return ret; - - } finally + if (json != null && mapKey != null) { - if (br != null) - { - try - { - br.close(); - } catch (IOException e) - { - // ignore - } - } + json = ((Map) json).get(mapKey); + } + if (json == null) + { + return null; + } + switch (mode) + { + case MODE_ARRAY: + case MODE_MAP: + break; + case MODE_ITERATOR: + json = ((List) json).iterator(); + break; } + return json; } /** diff --git a/src/jalview/fts/service/pdb/PDBFTSRestClient.java b/src/jalview/fts/service/pdb/PDBFTSRestClient.java index 3778212..8a10c66 100644 --- a/src/jalview/fts/service/pdb/PDBFTSRestClient.java +++ b/src/jalview/fts/service/pdb/PDBFTSRestClient.java @@ -165,29 +165,34 @@ public class PDBFTSRestClient extends FTSRestClient URI uri = webResource.getURI(); + System.out.println(uri); + // Execute the REST request ClientResponse clientResponse = webResource .accept(MediaType.APPLICATION_JSON).get(clientResponseClass ); - // Get the JSON string from the response object - String responseString = clientResponse.getEntity(String.class); + int status = clientResponse.getStatus(); + + // Get the JSON string from the response object or directly from the + // client (JavaScript) + Map jsonObj = (status == 200 + ? clientResponse.getEntity(Map.class) + : null); + String responseString = (jsonObj == null + ? clientResponse.getEntity(String.class) + : null); + // System.out.println("query >>>>>>> " + pdbRestRequest.toString()); // Check the response status and report exception if one occurs - if (clientResponse.getStatus() != 200) + switch (status) { - String errorMessage = ""; - if (clientResponse.getStatus() == 400) - { - errorMessage = parseJsonExceptionString(responseString); - throw new Exception(errorMessage); - } - else - { - errorMessage = getMessageByHTTPStatusCode( - clientResponse.getStatus(), "PDB"); - throw new Exception(errorMessage); - } + case 200: + break; + case 400: + throw new Exception(parseJsonExceptionString(responseString)); + default: + throw new Exception(getMessageByHTTPStatusCode(status, "PDB")); } // Make redundant objects eligible for garbage collection to conserve @@ -196,7 +201,7 @@ public class PDBFTSRestClient extends FTSRestClient client = null; // Process the response and return the result to the caller. - return parsePDBJsonResponse(responseString, pdbRestRequest); + return parsePDBJsonResponse(responseString, jsonObj, pdbRestRequest); } catch (Exception e) { String exceptionMsg = e.getMessage(); @@ -289,15 +294,26 @@ public static String parseJsonExceptionString(String jsonErrorResponse) * JSON string * @return */ - @SuppressWarnings("unchecked") public static FTSRestResponse parsePDBJsonResponse( String pdbJsonResponseString, FTSRestRequest pdbRestRequest) { + return parsePDBJsonResponse(pdbJsonResponseString, + (Map) null, pdbRestRequest); + } + + @SuppressWarnings("unchecked") + public static FTSRestResponse parsePDBJsonResponse( + String pdbJsonResponseString, Map jsonObj, + FTSRestRequest pdbRestRequest) + { FTSRestResponse searchResult = new FTSRestResponse(); List result = null; try { - Map jsonObj = (Map) JSONUtils.parse(pdbJsonResponseString); + if (jsonObj == null) + { + jsonObj = (Map) JSONUtils.parse(pdbJsonResponseString); + } Map pdbResponse = (Map) jsonObj.get("response"); String queryTime = ((Map) jsonObj.get("responseHeader")) .get("QTime").toString(); diff --git a/src/jalview/javascript/json/JSON.java b/src/jalview/javascript/json/JSON.java index 8ea781f..dff4963 100644 --- a/src/jalview/javascript/json/JSON.java +++ b/src/jalview/javascript/json/JSON.java @@ -2,7 +2,6 @@ package jalview.javascript.json; import java.io.BufferedReader; import java.io.InputStream; -import java.io.Reader; import java.net.URL; /** @@ -43,18 +42,19 @@ public class JSON { return /** @j2sNative swingjs.JSUtil.getJSONReader$O(is) || */null; } - @SuppressWarnings("resource") - public static Object parse(String json) { - return /** @j2sNative swingjs.JSUtil.parseJSONRaw$S(json) || */ + /** + * + * @param obj + * as String, Reader, InputStream, or JavaScript Object or Array + * @return Map or List + */ + public static Object parse(Object obj) + { + return /** @j2sNative swingjs.JSUtil.parseJSON$O(obj) || */ null; - } - - public static Object parse(Reader br) { - return /** @j2sNative swingjs.JSUtil.parseJSON$O(br) || */null; - } + } public static String stringify(Object obj) { - // not actually implemented. return /** @j2sNative swingjs.JSUtil.stringifyJSON$O(obj) || */null; } diff --git a/src/jalview/javascript/web/ClientResponse.java b/src/jalview/javascript/web/ClientResponse.java index 9a9dba6..23580ed 100644 --- a/src/jalview/javascript/web/ClientResponse.java +++ b/src/jalview/javascript/web/ClientResponse.java @@ -1,6 +1,9 @@ package jalview.javascript.web; -import java.net.URI; +import jalview.javascript.json.JSON; +import jalview.util.Platform; + +import java.net.URL; /** * minimal implementation of com.sun.jersey.api.client.ClientResponse @@ -10,21 +13,47 @@ import java.net.URI; */ public class ClientResponse { - + private String response; - private String[] encoding; - public ClientResponse(String response, String... encoding) + private boolean isJSON; + + private Object jsonData; + + int responseCode = -1; + + public ClientResponse(URL url, String[] encoding) { - this.response = response; - this.encoding = encoding; + // OK, so it turns out that ajax "json" format - or for that matter, any + // format for json is still just text. There is no point in getting this + // using special jQuery "json" formats. Duh. BH wasted a whole day try to + // "do it right". + response = Platform.getFileAsString(url.toString()); + responseCode = (response == null || response == "" ? 404 : 200); + isJSON = encoding[0].equals("application/json"); + if (isJSON) + { + try + { + jsonData = JSON.parse(response); + } catch (Exception e) + { + jsonData = null; + } + if (jsonData == null) + { + responseCode = 400; + } + } } - public String getEntity(Class c) - { - - // c will be String.class - + public Object getEntity(Class c) + { + + if (c == java.util.Map.class) + { + return jsonData; + } return response; } @@ -52,9 +81,12 @@ public class ClientResponse public int getStatus() { - // note, we could get the actual response. I am just assuming it is 200 or 400 - return (response != null && (response.startsWith("{") == encoding[0].equals("application/json")) - ? 200 : 400); + return responseCode; + } + + public Object getJSONData() + { + return jsonData; } } diff --git a/src/jalview/javascript/web/WebResource.java b/src/jalview/javascript/web/WebResource.java index c55e9ba..1896b65 100644 --- a/src/jalview/javascript/web/WebResource.java +++ b/src/jalview/javascript/web/WebResource.java @@ -2,8 +2,10 @@ package jalview.javascript.web; import jalview.util.Platform; +import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; +import java.net.URL; /* * A JavaScript-only proxy for com.sun.jersey.api.client.WebResource @@ -64,8 +66,13 @@ public class WebResource */ public ClientResponse get(Class c) { - return new ClientResponse(Platform.getFileAsString(uri.toString()), - encoding); + try + { + return new ClientResponse(new URL(uri.toString()), encoding); + } catch (MalformedURLException e) + { + return null; + } } } diff --git a/src/jalview/urls/IdentifiersUrlProvider.java b/src/jalview/urls/IdentifiersUrlProvider.java index 0dab719..07eb23e 100644 --- a/src/jalview/urls/IdentifiersUrlProvider.java +++ b/src/jalview/urls/IdentifiersUrlProvider.java @@ -63,7 +63,7 @@ public class IdentifiersUrlProvider extends UrlProviderImpl public IdentifiersUrlProvider(String cachedUrlList) { urls = readIdentifiers(IdOrgSettings.getDownloadLocation()); - selectedUrls = new ArrayList(); + selectedUrls = new ArrayList<>(); checkSelectionMatchesUrls(cachedUrlList); } @@ -78,7 +78,7 @@ public class IdentifiersUrlProvider extends UrlProviderImpl private HashMap readIdentifiers(String idFileName) { // identifiers.org data - HashMap idData = new HashMap(); + HashMap idData = new HashMap<>(); String errorMessage = null; try @@ -123,12 +123,14 @@ private HashMap readIdentifiers(String idFileName) // Typical report here is "NetworkError" because the file does not exist. // "https://." is coming from System.getProperty("user.home"), but this could // be set by the page developer to anything, of course. - errorMessage = (/** @j2sNative String.fromCharCode.apply(null, reader.$in.is.buf.slice(0,12)) || */e.toString()); + errorMessage = e.toString(); idData.clear(); } // BH 2018 -- added more valuable report if (errorMessage != null) + { System.err.println("IdentifiersUrlProvider: cannot read " + idFileName + ": " + errorMessage); + } return idData; } @@ -193,7 +195,7 @@ private HashMap readIdentifiers(String idFileName) @Override public List getLinksForMenu() { - List links = new ArrayList(); + List links = new ArrayList<>(); for (String key : selectedUrls) { links.add(urls.get(key).toStringWithTarget()); @@ -210,7 +212,7 @@ private HashMap readIdentifiers(String idFileName) @Override public void setUrlData(List links) { - selectedUrls = new ArrayList(); + selectedUrls = new ArrayList<>(); Iterator it = links.iterator(); while (it.hasNext()) diff --git a/src/jalview/util/JSONUtils.java b/src/jalview/util/JSONUtils.java index 127a085..656da48 100644 --- a/src/jalview/util/JSONUtils.java +++ b/src/jalview/util/JSONUtils.java @@ -1,14 +1,9 @@ package jalview.util; -import jalview.javascript.json.JSON; -import jalview.json.binding.biojson.v1.AlignmentPojo; - -import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.List; -import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; public class JSONUtils @@ -23,8 +18,8 @@ public class JSONUtils */ public static String arrayToStringList(List jsonArray) { - int n; - + int n; + if (jsonArray == null || (n = jsonArray.size()) == 0) { return null; @@ -33,60 +28,44 @@ public class JSONUtils /** * @j2sNative * - * return jsonArray.elementData.slice(0, n).join(","); + * return jsonArray.elementData.slice(0, n).join(","); */ { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < n; i++) - { - if (i > 0) - { - sb.append(","); - } - sb.append(jsonArray.get(i).toString()); - } - return sb.toString(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < n; i++) + { + if (i > 0) + { + sb.append(","); + } + sb.append(jsonArray.get(i).toString()); + } + return sb.toString(); } } /** - * The method all JSON parsing must go through for JavaScript. - * @param r a BufferedReader or a javascript.json.JSON.JSONReader + * The method all JSON parsing must go through for JavaScript. + * + * @param r + * a BufferedReader or a javascript.json.JSON.JSONReader * @return * @throws IOException * @throws ParseException */ - public static Object parse(Reader r) throws IOException, ParseException + public static Object parse(Reader r) throws IOException, ParseException { - // Using a file reader is not currently supported in SwingJS JavaScript - - if (r == null) - return null; -// -// Platform.timeCheck("JSONUtils.parse0 ", Platform.TIME_MARK); - - Object ret; - if (Platform.isJS()) - { - if (r instanceof FileReader) - { - throw new IOException("StringJS does not support FileReader parsing for JSON -- but it could..."); - } - return JSON.parse(r); - } else { - ret = new JSONParser().parse(r); - } -// Platform.timeCheck("JSONUtils.parse1 ", Platform.TIME_MARK); - return ret; + return Platform.parseJSON(r); } - public static Object parse(String json) throws ParseException + public static Object parse(String json) throws ParseException { - return (Platform.isJS() ? JSON.parse(json) : new JSONParser().parse(json)); + return Platform.parseJSON(json); } -public static String stringify(Object obj) { - return new org.json.JSONObject(obj).toString(); -} + public static String stringify(Object obj) + { + return new org.json.JSONObject(obj).toString(); + } } diff --git a/src/jalview/util/Platform.java b/src/jalview/util/Platform.java index d80e3de..c400d83 100644 --- a/src/jalview/util/Platform.java +++ b/src/jalview/util/Platform.java @@ -20,13 +20,25 @@ */ package jalview.util; +import jalview.javascript.json.JSON; + import java.awt.Toolkit; import java.awt.event.MouseEvent; +import java.io.BufferedReader; import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; import java.util.Properties; import javax.swing.SwingUtilities; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + /** * System platform information used by Applet and Application * @@ -427,4 +439,69 @@ public class Platform */ } + public static void setAjaxJSON(URL url) + { + if (isJS()) + { + JSON.setAjax(url); + } + } + + public static Object parseJSON(InputStream response) + throws IOException, ParseException + { + if (isJS()) + { + return JSON.getJSONReader(response); + } + + BufferedReader br = null; + try + { + br = new BufferedReader(new InputStreamReader(response, "UTF-8")); + return parseJSON(br); + } finally + { + if (br != null) + { + try + { + br.close(); + } catch (IOException e) + { + // ignore + } + } + } + } + + public static Object parseJSON(String json) throws ParseException + { + return (isJS() ? JSON.parse(json) + : new JSONParser().parse(json)); + } + + public static Object parseJSON(Reader r) + throws IOException, ParseException + { + if (r == null) + { + return null; + } + + if (!isJS()) + { + return new JSONParser().parse(r); + } + // Using a file reader is not currently supported in SwingJS JavaScript + + if (r instanceof FileReader) + { + throw new IOException( + "StringJS does not support FileReader parsing for JSON -- but it could..."); + } + return JSON.parse(r); + + } + } -- 1.7.10.2