Merge branch 'Jalview-JS/develop.JAL-3446.ctrlDown' into
[jalview.git] / src / jalview / bin / AppletParams.java
1
2 package jalview.bin;
3
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import jalview.gui.Preferences;
9
10 /**
11  * Collection of all known applet tags from JalviewLite.
12  * Three cases; can be one or more of these:
13  * 
14  * CASE I. args[] name and value for ArgsParser
15  * 
16  * CASE II. applet parameter for JalviewJSApp
17  * 
18  * CASE III. mapped to a Preference
19  * 
20  * 
21  * @author hansonr
22  *
23  */
24 @SuppressWarnings("serial")
25 public class AppletParams extends HashMap<String, Object>
26 {
27
28   private final static String[] params = { 
29       "alignpdbfiles",
30       "ANNOTATIONCOLOUR_MAX", "ANNOTATIONCOLOUR_MIN",
31       "annotations",
32       "APPLICATION_URL", "automaticScrolling", "centrecolumnlabels",
33       "debug", "defaultColour", "defaultColourNuc", "defaultColourProt",
34       "embedded", "enableSplitFrame", "externalstructureviewer", "features",
35       "file", "file2", "format", "heightScale", "hidefeaturegroups",
36       "jalviewhelpurl", "jnetfile", "jpredfile", "label", "linkLabel_",
37       "linkLabel_1", "linkURL_", "nojmol", "normaliseLogo",
38       "normaliseSequenceLogo", "oninit", "PDBFILE", "PDBSEQ",
39       "relaxedidmatch", "resolvetocodebase", "RGB", "scaleProteinAsCdna",
40       "scoreFile", "separator", "sequence", "showAnnotation", "showbutton",
41       "showConsensus", "showConsensusHistogram", "showConservation",
42       "showfeaturegroups", "showFeatureSettings", "showFullId",
43       "showGroupConsensus", "showGroupConservation", "showOccupancy",
44       "showQuality", "showSequenceLogo", "showTreeBootstraps",
45       "showTreeDistances", "showUnconserved", "showUnlinkedTreeNodes",
46       "sortBy", "sortByTree", "tree", "treeFile", "upperCase",
47       "userDefinedColour", "widthScale", "windowHeight", "windowWidth",
48       "wrap", };
49
50   public String getParam(String param, String def)
51   {
52     Object val = get(param);
53     return (val != null ? val.toString() : def);
54   }
55
56   // <applet
57   // code="jalview.bin.JalviewLite" width="140" height="35"
58   // archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
59   // <param name="permissions" value="sandbox"/>
60   // <param name="file" value="uniref50.fa"/>
61   // <param name="treeFile" value="ferredoxin.nw"/>
62   // <param name="userDefinedColour" value="C=yellow; R,K,H=FF5555;
63   // D,E=5555FF"/>
64   // <param name="sortByTree" value="True"/>
65   // <param name="showSequenceLogo" value="true"/>
66   // <param name="showGroupConsensus" value="true"/>
67   // <param name="showFullId" value="false"/>
68   // <param name="linkLabel_1" value="Uniprot"/>
69   // <param name="linkUrl_1"
70   // value="http://www.uniprot.org/uniprot/$SEQUENCE_ID$"/>
71   // <param name="linkLabel_2" value="EMBL-EBI Search"/>
72   // <param name="linkUrl_2"
73   // value="http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$"/>
74   // <param name="APPLICATION_URL"
75   // value="http://www.jalview.org/services/launchApp"/>
76   // </applet>
77   //
78   public AppletParams(String outerHTML)
79   {
80     String[] tokens = outerHTML.split("<param");
81     outerHTML = tokens[0];
82     String code = getAttr(outerHTML, "code");
83     if (!code.equals("jalview.bin.JalviewLite"))
84     {
85       return;
86     }
87     for (int i = tokens.length; --i > 0;)
88     {
89       String param = tokens[i];
90       String key = getAttr(param, "name");
91       if (key != null)
92       {
93         String value = getAttr(param, "value");
94         System.out.println("AppletParams " + key + " = \"" + value + "\"");
95         put(key, value);
96       }
97     }
98     put("_width", getAttr(outerHTML, "width"));
99     put("_height", getAttr(outerHTML, "height"));
100     put("_id", getAttr(outerHTML, "id"));
101     put("_name", getAttr(outerHTML, "name"));
102     put("_archive", getAttr(outerHTML, "archive"));
103     put("_code", code);
104   }
105
106   public AppletParams()
107   {
108   }
109
110   public static AppletParams getAppletParams(Map<String, Object> map,
111           List<String> vargs)
112   {
113     AppletParams appletParams = new AppletParams();
114     String resourcePath = getString(map, "resourcePath");
115     if (resourcePath == null)
116       resourcePath = "";
117     if (resourcePath.length() > 0 && !resourcePath.endsWith("/"))
118     {
119       resourcePath += "/";
120     }
121     for (int i = params.length; --i >= 0;)
122     {
123       String prefName = params[i];
124       Object value = map.get(prefName);
125       if (value != null)
126         addParam(vargs, prefName, value, appletParams, resourcePath);
127     }
128     return appletParams;
129   }
130
131   private static String getString(Map<String, Object> map, String key)
132   {
133     Object o = map.get(key);  
134     return (o == null ? null : o.toString());
135   }
136
137   public static AppletParams getAppletParams(String[] args,
138           List<String> vargs)
139   {
140     AppletParams appletParams = new AppletParams();
141     String resourcePath = "";
142     for (int i = args.length; --i > 0;) // > 0 is correct, not >=0
143     {
144       if (args[i].startsWith("name=\"Info.resourcePath\""))
145       {
146         resourcePath = getAttr(args[i], "value");
147         if (resourcePath.length() > 0 && !resourcePath.endsWith("/"))
148         {
149           resourcePath += "/";
150         }
151         break;
152       }
153     }
154     for (int i = 1; i < args.length; i++)
155     {
156       String arg = args[i].trim();
157       if (arg.startsWith("name="))
158       {
159         String prefName = getAttr(arg, "name");
160         String value = getAttr(arg, "value");
161         addParam(vargs, prefName, value, appletParams, resourcePath);
162       }
163     }
164     return appletParams;
165   }
166
167   private static void addParam(List<String> vargs, String prefName,
168           Object value, AppletParams appletParams, String resourcePath)
169   {
170
171     // note that Application arguments ARE case-sensitive, but
172     // Applet.getParameter() is not.
173
174     // prefName // CASE III
175
176     String argName = null;  // CASE I                
177
178     String appletName = prefName.toLowerCase();   // CASE II
179
180     // by nulling one or more of these names, that route will not be used.
181     
182     switch (appletName)
183     {
184
185     case "file":
186       argName = "open";
187       prefName = null;
188       value = resourcePath + value;
189       break;
190     case "file2":
191       argName = "open2";
192       prefName = null;
193       value = resourcePath + value;
194       break;
195     case "oninit":
196     case "hidefeaturegroups":
197       // applet parameter only
198       // setting argName to null indicates that we want
199       // JalviewJSApp to take care of this using getParameter or getParameterAsObject      
200      prefName = argName = null;
201       break;
202     case "tree":
203     case "treefile":
204       // setting appletName to null indicates that we want
205       // Jalview.doMain to taken care of this as Jalview args
206       argName = "tree";
207       prefName = null;
208       value = resourcePath + value;
209       break;
210
211     case "features":
212     case "jnetfile":
213     case "jpredfile":
214     case "pdbfile":
215     case "scorefile":
216     case "sequence":
217     case "annotations":
218       prefName = argName = null;
219       value = resourcePath + value;
220       break;
221
222       // non-loading preferences
223
224     case "defaultcolour":
225       prefName = Preferences.DEFAULT_COLOUR;
226       break;
227     case "defaultcolournuc":
228       prefName = Preferences.DEFAULT_COLOUR_NUC;
229       break;
230     case "defaultcolourprot":
231       prefName = Preferences.DEFAULT_COLOUR_PROT;
232       break;
233     case "annotationcolour_max":
234       prefName = Preferences.ANNOTATIONCOLOUR_MAX;
235       break;
236     case "annotationcolour_min":
237       prefName = Preferences.ANNOTATIONCOLOUR_MIN;
238       break;
239     case "enablesplitframe":
240       prefName = Preferences.ENABLE_SPLIT_FRAME;
241       break;
242     case "centrecolumnlabels":
243       prefName = Preferences.CENTRE_COLUMN_LABELS;
244       break;
245     case "sortby":
246       prefName = Preferences.SORT_ALIGNMENT; // id, etc.
247       break;
248     case "normalisesequencelogo":
249       prefName = Preferences.NORMALISE_CONSENSUS_LOGO;
250       break;
251     case "relaxedidmatch":
252       prefName = Preferences.RELAXEDSEQIDMATCHING;
253       break;
254     case "scaleproteinascdna":
255       prefName = Preferences.SCALE_PROTEIN_TO_CDNA;
256       break;
257     case "userdefinedcolour":
258       argName = "colour";
259       prefName = Preferences.USER_DEFINED_COLOURS;
260       break;
261     case "wrap":
262       prefName = Preferences.WRAP_ALIGNMENT;
263       break;
264     case "sortbytree":
265       argName = prefName;
266       prefName = Preferences.SORT_BY_TREE;
267       value = checkTF(value);
268       break;
269
270     // implemented; not tested:
271
272     case "pdbseq":
273     case "alignpdbfiles":
274       prefName = null;
275       break;
276     case "format":
277       argName = prefName;
278       break;
279     case "separator":
280       argName = prefName;
281       break;
282
283     // TODO: probably not relevant?
284
285     case "rgb":
286       prefName = null; // TODO no background for application?
287       break;
288     case "externalstructureviewer":
289       break;
290     case "application_url":
291       break;
292     case "automaticscrolling":
293       break;
294     case "heightscale":
295       break;
296     case "jalviewhelpurl":
297       break;
298     case "label":
299       break;
300     case "linklabel_":
301       prefName = "linkLabel_";
302       break;
303     case "linklabel_1":
304       prefName = "linkLabel_1";
305       break;
306     case "linkurl_":
307       prefName = "linkURL_";
308       break;
309
310     // unknown:
311
312     case "nojmol":
313     case "normaliselogo":
314     case "resolvetocodebase":
315     case "uppercase":
316     case "widthscale":
317     case "windowheight":
318     case "windowwidth":
319       prefName = null;
320       break;
321
322     // TRUE/FALSE
323
324     case "debug":
325     case "embedded":
326     case "showbutton":
327       value = checkTF(value);
328       break;
329     case "showannotation":
330       prefName = Preferences.SHOW_ANNOTATIONS;
331       value = checkTF(value);
332       break;
333     case "showconsensus":
334       prefName = Preferences.SHOW_CONSENSUS_LOGO;
335       value = checkTF(value);
336       break;
337     case "showconsensushistogram":
338       prefName = Preferences.SHOW_CONSENSUS_HISTOGRAM;
339       value = checkTF(value);
340       break;
341     case "showconservation":
342       prefName = Preferences.SHOW_CONSERVATION;
343       value = checkTF(value);
344       break;
345     case "showgroupconsensus":
346       prefName = Preferences.SHOW_GROUP_CONSENSUS;
347       value = checkTF(value);
348       break;
349     case "showgroupconservation":
350       prefName = Preferences.SHOW_GROUP_CONSERVATION;
351       value = checkTF(value);
352       break;
353     case "showoccupancy":
354       prefName = Preferences.SHOW_OCCUPANCY;
355       value = checkTF(value);
356       break;
357     case "showquality":
358       prefName = Preferences.SHOW_QUALITY;
359       value = checkTF(value);
360       break;
361     case "showsequencelogo":
362       prefName = Preferences.SHOW_CONSENSUS_LOGO;
363       value = checkTF(value);
364       break;
365     case "showunconserved":
366       prefName = Preferences.SHOW_UNCONSERVED;
367       value = checkTF(value);
368       break;
369     case "showfeaturegroups":
370     case "showfeaturesettings":
371     case "showfullid":
372     case "showtreebootstraps":
373     case "showtreedistances":
374     case "showunlinkedtreenodes":
375       value = checkTF(value);
376       break;
377     default:
378       if (appletName.startsWith("pdbfile")
379               || appletName.startsWith("sequence") && Character
380                       .isDigit(appletName.charAt(appletName.length() - 1)))
381       {
382         // could be pdbFile2, for example
383         prefName = argName = null;
384         value = resourcePath + value;
385         break;
386       }
387       // or one of the app preference names
388       break;
389     }
390
391     // CASE I.  args[] name and value for ArgsParser
392     //
393     // If given an argument name, 
394     // put name and value into application args
395     if (value != null && argName != null)
396     {
397       vargs.add(argName);
398       if (value != "true")
399       {
400         vargs.add(value.toString());
401       }
402     }
403     
404     // CASE II.   applet parameter for JalviewJSApp
405     
406     if (value == null)
407     {
408       value = "false";
409     }
410     System.out.println("AppletParams propName=" + prefName + " argName="
411             + argName + " appletName=" + appletName + " value=" + value);    
412     if (appletName != null)
413     {
414       appletParams.put(appletName, value);
415     }
416     
417     // CASE III.  mapped to a Preference
418     
419     if (prefName != null)
420     {
421       Cache.setPropertyNoSave(prefName, value.toString());
422     }
423   }
424
425   /**
426    * Check for a single-argument option.
427    * 
428    * @param value
429    * @return "true" or null
430    */
431   private static String checkTF(Object value)
432   {
433     return (("" + value).toLowerCase() == "true" ? "true" : null);
434   }
435
436   /**
437    * Crude applet innerHTML parser
438    * 
439    * @param tag
440    * @param attr
441    * @return
442    */
443   private static String getAttr(String tag, String attr)
444   {
445     int pt = tag.indexOf(attr + "=\"");
446     if (pt < 0)
447     {
448       System.out
449               .println("AppletParams did not read " + attr + " in " + tag);
450       return null;
451     }
452     // <param name="sortByTree" value="True"/>
453     int pt1 = pt + attr.length() + 2;
454     int pt2 = tag.indexOf("\"", pt1);
455     return (pt < 0 ? null : tag.substring(pt1, pt2));
456   }
457
458   public static void main(String[] args)
459   {
460     new AppletParams("<applet\r\n"
461             + "    code=\"jalview.bin.JalviewLite\" width=\"140\" height=\"35\"\r\n"
462             + "    archive=\"jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar\">  \r\n"
463             + "  <param name=\"permissions\" value=\"sandbox\"/>\r\n"
464             + "  <param name=\"file\" value=\"uniref50.fa\"/>\r\n"
465             + "  <param name=\"treeFile\" value=\"ferredoxin.nw\"/>\r\n"
466             + "  <param name=\"userDefinedColour\" value=\"C=yellow; R,K,H=FF5555; D,E=5555FF\"/>\r\n"
467             + "  <param name=\"sortByTree\" value=\"True\"/>\r\n"
468             + "  <param name=\"showSequenceLogo\" value=\"true\"/>\r\n"
469             + "  <param name=\"showGroupConsensus\" value=\"true\"/>\r\n"
470             + "  <param name=\"showFullId\" value=\"false\"/>\r\n"
471             + "    <param name=\"linkLabel_1\" value=\"Uniprot\"/>\r\n"
472             + "    <param name=\"linkUrl_1\" value=\"http://www.uniprot.org/uniprot/$SEQUENCE_ID$\"/>\r\n"
473             + "    <param name=\"linkLabel_2\" value=\"EMBL-EBI Search\"/>\r\n"
474             + "    <param name=\"linkUrl_2\" value=\"http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$\"/>\r\n"
475             + "    <param name=\"APPLICATION_URL\" value=\"http://www.jalview.org/services/launchApp\"/>\r\n"
476             + "     </applet>");
477   }
478
479 }