Clover icon

Coverage Report

  1. Project Clover database Mon Sep 2 2024 17:57:51 BST
  2. Package jalview.util

File Platform.java

 

Coverage histogram

../../img/srcFileCovDistChart5.png
43% of files have more coverage

Code metrics

62
114
36
1
692
352
78
0.68
3.17
36
2.17

Classes

Class Line # Actions
Platform 48 114 78
0.429245342.9%
 

Contributing tests

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