Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package jalview.util

File Platform.java

 

Coverage histogram

../../img/srcFileCovDistChart4.png
44% of files have more coverage

Code metrics

60
107
34
1
652
324
72
0.67
3.15
34
2.12

Classes

Class Line # Actions
Platform 48 107 72
0.3383084533.8%
 

Contributing tests

This file is covered by 328 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.util;
22   
23    import jalview.javascript.json.JSON;
24   
25    import java.awt.Toolkit;
26    import java.awt.event.MouseEvent;
27    import java.io.BufferedReader;
28    import java.io.File;
29    import java.io.FileOutputStream;
30    import java.io.FileReader;
31    import java.io.IOException;
32    import java.io.InputStream;
33    import java.io.InputStreamReader;
34    import java.io.Reader;
35    import java.net.URL;
36    import java.util.Properties;
37   
38    import javax.swing.SwingUtilities;
39   
40    import org.json.simple.parser.JSONParser;
41    import org.json.simple.parser.ParseException;
42   
43    /**
44    * System platform information used by Applet and Application
45    *
46    * @author Jim Procter
47    */
 
48    public class Platform
49    {
50   
51    private static boolean isJS = /** @j2sNative true || */
52    false;
53   
54    private static Boolean isNoJSMac = null, isNoJSWin = null, isMac = null,
55    isWin = null, isLinux = null;
56   
57    private static Boolean isHeadless = null;
58   
59    /**
60    * added to group mouse events into Windows and nonWindows (mac, unix, linux)
61    *
62    * @return
63    */
 
64  281 toggle public static boolean isMac()
65    {
66  281 return (isMac == null
67    ? (isMac = (System.getProperty("os.name").indexOf("Mac") >= 0))
68    : isMac);
69    }
70   
71    /**
72    * added to group mouse events into Windows and nonWindows (mac, unix, linux)
73    *
74    * @return
75    */
 
76  5 toggle public static boolean isWin()
77    {
78  5 return (isWin == null
79    ? (isWin = (System.getProperty("os.name").indexOf("Win") >= 0))
80    : isWin);
81    }
82   
83    /**
84    * added to check LaF for Linux
85    *
86    * @return
87    */
 
88  35 toggle public static boolean isLinux()
89    {
90  35 return (isLinux == null
91    ? (isLinux = (System.getProperty("os.name").indexOf("Linux") >= 0))
92    : isLinux);
93    }
94   
95    /**
96    *
97    * @return true if HTML5 JavaScript
98    */
 
99  63640 toggle public static boolean isJS()
100    {
101  63640 return isJS;
102    }
103   
104    /**
105    * sorry folks - Macs really are different
106    *
107    * BH: disabled for SwingJS -- will need to check key-press issues
108    *
109    * @return true if we do things in a special way.
110    */
 
111  1160 toggle public static boolean isAMacAndNotJS()
112    {
113  1160 return (isNoJSMac == null ? (isNoJSMac = !isJS && isMac()) : isNoJSMac);
114    }
115   
116    /**
117    * Check if we are on a Microsoft plaform...
118    *
119    * @return true if we have to cope with another platform variation
120    */
 
121  18 toggle public static boolean isWindowsAndNotJS()
122    {
123  18 return (isNoJSWin == null ? (isNoJSWin = !isJS && isWin()) : isNoJSWin);
124    }
125   
126    /**
127    *
128    * @return true if we are running in non-interactive no UI mode
129    */
 
130  0 toggle public static boolean isHeadless()
131    {
132  0 if (isHeadless == null)
133    {
134  0 isHeadless = "true".equals(System.getProperty("java.awt.headless"));
135    }
136  0 return isHeadless;
137    }
138   
139    /**
140    *
141    * @return nominal maximum command line length for this platform
142    */
 
143  0 toggle public static int getMaxCommandLineLength()
144    {
145    // TODO: determine nominal limits for most platforms.
146  0 return 2046; // this is the max length for a windows NT system.
147    }
148   
149    /**
150    * Answers the input with every backslash replaced with a double backslash (an
151    * 'escaped' single backslash)
152    *
153    * @param s
154    * @return
155    */
 
156  18 toggle public static String escapeBackslashes(String s)
157    {
158  18 return s == null ? null : s.replace("\\", "\\\\");
159    }
160   
161    /**
162    * Answers true if the mouse event has Meta-down (Command key on Mac) or
163    * Ctrl-down (on other o/s). Note this answers _false_ if the Ctrl key is
164    * pressed instead of the Meta/Cmd key on Mac. To test for Ctrl-pressed on
165    * Mac, you can use e.isPopupTrigger().
166    *
167    * @param e
168    * @return
169    */
 
170  3 toggle public static boolean isControlDown(MouseEvent e)
171    {
172  3 return isControlDown(e, isMac());
173    }
174   
175    /**
176    * Overloaded version of method (to allow unit testing)
177    *
178    * @param e
179    * @param aMac
180    * @return
181    */
 
182  6 toggle protected static boolean isControlDown(MouseEvent e, boolean aMac)
183    {
184  6 if (!aMac)
185    {
186  6 return e.isControlDown();
187   
188    // Jalview 2.11 code below: above is as amended for JalviewJS
189    // /*
190    // * answer false for right mouse button
191    // */
192    // if (e.isPopupTrigger())
193    // {
194    // return false;
195    // }
196    // return
197    // (jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx() //
198    // .getMenuShortcutKeyMaskEx()
199    // & jalview.util.ShortcutKeyMaskExWrapper
200    // .getModifiersEx(e)) != 0; // getModifiers()) != 0;
201    }
202    // answer false for right mouse button
203    // shortcut key will be META for a Mac
204  0 return !e.isPopupTrigger()
205    && (Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()
206    & e.getModifiers()) != 0;
207    // could we use e.isMetaDown() here?
208    }
209   
210    // BH: I don't know about that previous method. Here is what SwingJS uses.
211    // Notice the distinction in mouse events. (BUTTON3_MASK == META)
212    //
213    // private static boolean isPopupTrigger(int id, int mods, boolean isWin) {
214    // boolean rt = ((mods & InputEvent.BUTTON3_MASK) != 0);
215    // if (isWin) {
216    // if (id != MouseEvent.MOUSE_RELEASED)
217    // return false;
218    ////
219    //// // Oddly, Windows returns InputEvent.META_DOWN_MASK on release, though
220    //// // BUTTON3_DOWN_MASK for pressed. So here we just accept both.
221    ////
222    //// actually, we can use XXX_MASK, not XXX_DOWN_MASK and avoid this issue,
223    // because
224    //// J2S adds the appropriate extended (0x3FC0) and simple (0x3F) modifiers.
225    ////
226    // return rt;
227    // } else {
228    // // mac, linux, unix
229    // if (id != MouseEvent.MOUSE_PRESSED)
230    // return false;
231    // boolean lt = ((mods & InputEvent.BUTTON1_MASK) != 0);
232    // boolean ctrl = ((mods & InputEvent.CTRL_MASK) != 0);
233    // return rt || (ctrl && lt);
234    // }
235    // }
236    //
237   
238    /**
239    * Windows (not Mac, Linux, or Unix) and right button to test for the
240    * right-mouse pressed event in Windows that would have opened a menu or a
241    * Mac.
242    *
243    * @param e
244    * @return
245    */
 
246  3 toggle public static boolean isWinRightButton(MouseEvent e)
247    {
248    // was !isAMac(), but that is true also for Linux and Unix and JS,
249   
250  3 return isWin() && SwingUtilities.isRightMouseButton(e);
251    }
252   
253    /**
254    * Windows (not Mac, Linux, or Unix) and middle button -- for mouse wheeling
255    * without pressing the button.
256    *
257    * @param e
258    * @return
259    */
 
260  0 toggle public static boolean isWinMiddleButton(MouseEvent e)
261    {
262    // was !isAMac(), but that is true also for Linux and Unix and JS
263  0 return isWin() && SwingUtilities.isMiddleMouseButton(e);
264    }
265   
 
266  259 toggle public static boolean allowMnemonics()
267    {
268  259 return !isMac();
269    }
270   
271    public final static int TIME_RESET = 0;
272   
273    public final static int TIME_MARK = 1;
274   
275    public static final int TIME_SET = 2;
276   
277    public static final int TIME_GET = 3;
278   
279    public static long time, mark, set, duration;
280   
 
281  0 toggle public static void timeCheck(String msg, int mode)
282    {
283  0 long t = System.currentTimeMillis();
284  0 switch (mode)
285    {
286  0 case TIME_RESET:
287  0 time = mark = t;
288  0 if (msg != null)
289    {
290  0 System.err.println("Platform: timer reset\t\t\t" + msg);
291    }
292  0 break;
293  0 case TIME_MARK:
294  0 if (set > 0)
295    {
296  0 duration += (t - set);
297    }
298    else
299    {
300  0 if (time == 0)
301    {
302  0 time = mark = t;
303    }
304  0 if (msg != null)
305    {
306  0 System.err.println("Platform: timer mark\t" + ((t - time) / 1000f)
307    + "\t" + ((t - mark) / 1000f) + "\t" + msg);
308    }
309  0 mark = t;
310    }
311  0 break;
312  0 case TIME_SET:
313  0 set = t;
314  0 break;
315  0 case TIME_GET:
316  0 if (msg != null)
317    {
318  0 System.err.println("Platform: timer dur\t" + ((t - time) / 1000f)
319    + "\t" + ((duration) / 1000f) + "\t" + msg);
320    }
321  0 set = 0;
322  0 break;
323    }
324    }
325   
 
326  0 toggle public static void cacheFileData(String path, Object data)
327    {
328  0 if (!isJS() || data == null)
329    {
330  0 return;
331    }
332    /**
333    * @j2sNative
334    *
335    * swingjs.JSUtil.cacheFileData$S$O(path, data);
336    *
337    */
338    }
339   
 
340  0 toggle public static void cacheFileData(File file)
341    {
342  0 byte[] data;
343  0 if (!isJS() || (data = Platform.getFileBytes(file)) == null)
344    {
345  0 return;
346    }
347  0 cacheFileData(file.toString(), data);
348    }
349   
 
350  717 toggle public static byte[] getFileBytes(File f)
351    {
352  717 return /** @j2sNative f && swingjs.JSUtil.getFileBytes$java_io_File(f) || */
353    null;
354    }
355   
 
356  0 toggle public static byte[] getFileAsBytes(String fileStr)
357    {
358  0 byte[] bytes = null;
359    // BH 2018 hack for no support for access-origin
360    /**
361    * @j2sNative bytes = swingjs.JSUtil.getFileAsBytes$O(fileStr)
362    */
363  0 cacheFileData(fileStr, bytes);
364  0 return bytes;
365    }
366   
 
367  0 toggle @SuppressWarnings("unused")
368    public static String getFileAsString(String url)
369    {
370  0 String ret = null;
371    /**
372    * @j2sNative
373    *
374    * ret = swingjs.JSUtil.getFileAsString$S(url);
375    *
376    *
377    */
378  0 cacheFileData(url, ret);
379  0 return ret;
380    }
381   
 
382  0 toggle public static boolean setFileBytes(File f, String urlstring)
383    {
384  0 if (!isJS())
385    {
386  0 return false;
387    }
388  0 @SuppressWarnings("unused")
389    byte[] bytes = getFileAsBytes(urlstring);
390    // TODO temporary doubling of 秘bytes and _bytes;
391    // just remove _bytes when new transpiler has been installed
392    /**
393    * @j2sNative f.\u79d8bytes = f._bytes = bytes;
394    */
395  0 return true;
396    }
397   
 
398  1 toggle public static void addJ2SBinaryType(String ext)
399    {
400    /**
401    * @j2sNative
402    *
403    * J2S._binaryTypes.push("." + ext + "?");
404    *
405    */
406    }
407   
408    /**
409    * Encode the URI using JavaScript encodeURIComponent
410    *
411    * @param value
412    * @return encoded value
413    */
 
414  0 toggle public static String encodeURI(String value)
415    {
416    /**
417    * @j2sNative value = encodeURIComponent(value);
418    */
419  0 return value;
420    }
421   
422    /**
423    * Open the URL using a simple window call if this is JavaScript
424    *
425    * @param url
426    * @return true if window has been opened
427    */
 
428  0 toggle public static boolean openURL(String url)
429    {
430  0 if (!isJS())
431    {
432  0 return false;
433    }
434    /**
435    * @j2sNative
436    *
437    *
438    * window.open(url);
439    */
440  0 return true;
441    }
442   
 
443  0 toggle public static String getUniqueAppletID()
444    {
445    /**
446    * @j2sNative return swingjs.JSUtil.getApplet$()._uniqueId;
447    *
448    */
449  0 return null;
450   
451    }
452   
453    /**
454    * Read the Info block for this applet.
455    *
456    * @param prefix
457    * "jalview_"
458    * @param p
459    * @return unique id for this applet
460    */
 
461  7 toggle public static void readInfoProperties(String prefix, Properties p)
462    {
463  7 if (!isJS())
464    {
465  7 return;
466    }
467  0 String id = getUniqueAppletID();
468  0 String key = "", value = "";
469    /**
470    * @j2sNative var info = swingjs.JSUtil.getApplet$().__Info || {}; for (var
471    * key in info) { if (key.indexOf(prefix) == 0) { value = "" +
472    * info[key];
473    */
474   
475  0 System.out.println(
476    "Platform id=" + id + " reading Info." + key + " = " + value);
477  0 p.put(id + "_" + key, value);
478   
479    /**
480    * @j2sNative
481    *
482    *
483    * } }
484    */
485    }
486   
 
487  0 toggle public static void setAjaxJSON(URL url)
488    {
489  0 if (isJS())
490    {
491  0 JSON.setAjax(url);
492    }
493    }
494   
 
495  0 toggle public static Object parseJSON(InputStream response)
496    throws IOException, ParseException
497    {
498  0 if (isJS())
499    {
500  0 return JSON.parse(response);
501    }
502   
503  0 BufferedReader br = null;
504  0 try
505    {
506  0 br = new BufferedReader(new InputStreamReader(response, "UTF-8"));
507  0 return new JSONParser().parse(br);
508    } finally
509    {
510  0 if (br != null)
511    {
512  0 try
513    {
514  0 br.close();
515    } catch (IOException e)
516    {
517    // ignore
518    }
519    }
520    }
521    }
522   
 
523  21 toggle public static Object parseJSON(String json) throws ParseException
524    {
525  21 return (isJS() ? JSON.parse(json)
526    : new JSONParser().parse(json));
527    }
528   
 
529  39 toggle public static Object parseJSON(Reader r)
530    throws IOException, ParseException
531    {
532  39 if (r == null)
533    {
534  0 return null;
535    }
536   
537  39 if (!isJS())
538    {
539  39 return new JSONParser().parse(r);
540    }
541    // Using a file reader is not currently supported in SwingJS JavaScript
542   
543  0 if (r instanceof FileReader)
544    {
545  0 throw new IOException(
546    "StringJS does not support FileReader parsing for JSON -- but it could...");
547    }
548  0 return JSON.parse(r);
549   
550    }
551   
552    /**
553    * Dump the input stream to an output file.
554    *
555    * @param is
556    * @param outFile
557    * @throws IOException
558    * if the file cannot be created or there is a problem
559    * reading the input stream.
560    */
 
561  0 toggle public static void streamToFile(InputStream is, File outFile)
562    throws IOException
563    {
564  0 if (isJS() && /**
565    * @j2sNative outFile.setBytes$O && outFile.setBytes$O(is) &&
566    */
567    true)
568    {
569  0 return;
570    }
571  0 FileOutputStream fio = new FileOutputStream(outFile);
572  0 try
573    {
574  0 byte[] bb = new byte[32 * 1024];
575  0 int l;
576  0 while ((l = is.read(bb)) > 0)
577    {
578  0 fio.write(bb, 0, l);
579    }
580    } finally
581    {
582  0 fio.close();
583    }
584    }
585   
586    /**
587    * Add a known domain that implements access-control-allow-origin:*
588    *
589    * These should be reviewed periodically.
590    *
591    * @param domain
592    * for a service that is not allowing ajax
593    *
594    * @author hansonr@stolaf.edu
595    *
596    */
 
597  2 toggle public static void addJ2SDirectDatabaseCall(String domain)
598    {
599   
600  2 if (isJS())
601    {
602  0 System.out.println(
603    "Platform adding known access-control-allow-origin * for domain "
604    + domain);
605    /**
606    * @j2sNative
607    *
608    * J2S.addDirectDatabaseCall(domain);
609    */
610    }
611   
612    }
613   
 
614  19 toggle public static void getURLCommandArguments()
615    {
616   
617    /**
618    * Retrieve the first query field as command arguments to Jalview. Include
619    * only if prior to "?j2s" or "&j2s" or "#". Assign the applet's __Info.args
620    * element to this value.
621    *
622    * @j2sNative var a =
623    * decodeURI((document.location.href.replace("&","?").split("?j2s")[0]
624    * + "?").split("?")[1].split("#")[0]); a &&
625    * (J2S.thisApplet.__Info.args = a.split(" "));
626    */
627   
628    }
629   
630    /**
631    * A (case sensitive) file path comparator that ignores the difference between /
632    * and \
633    *
634    * @param path1
635    * @param path2
636    * @return
637    */
 
638  8 toggle public static boolean pathEquals(String path1, String path2)
639    {
640  8 if (path1 == null)
641    {
642  2 return path2 == null;
643    }
644  6 if (path2 == null)
645    {
646  1 return false;
647    }
648  5 String p1 = path1.replace('\\', '/');
649  5 String p2 = path2.replace('\\', '/');
650  5 return p1.equals(p2);
651    }
652    }