1 package fr.orsay.lri.varna.controlers;
4 import java.io.StreamTokenizer;
5 import java.io.StringReader;
6 import java.util.ArrayList;
7 import java.util.Hashtable;
8 import java.util.Vector;
10 import javax.swing.JOptionPane;
12 import fr.orsay.lri.varna.VARNAPanel;
13 import fr.orsay.lri.varna.models.annotations.ChemProbAnnotation;
14 import fr.orsay.lri.varna.models.annotations.ChemProbAnnotation.ChemProbAnnotationType;
15 import fr.orsay.lri.varna.models.rna.ModeleColorMap;
16 import fr.orsay.lri.varna.models.rna.RNA;
18 public class ControleurScriptParser {
19 private static String SCRIPT_ERROR_PREFIX = "Error";
22 private static class Command{
24 Vector<Argument> _argv;
25 public Command(Function f, Vector<Argument> argv)
32 private static abstract class Argument{
35 public Argument(ArgumentType t)
40 public ArgumentType getType()
45 public abstract String toString();
50 private static class NumberArgument extends Argument{
52 public NumberArgument(Number val)
54 super(ArgumentType.NUMBER_TYPE);
57 public Number getNumber()
61 public String toString()
63 return _val.toString();
67 private static class ColorArgument extends Argument{
69 public ColorArgument(Color val)
71 super(ArgumentType.COLOR_TYPE);
74 public Color getColor()
78 public String toString()
80 return _val.toString();
84 private static class BooleanArgument extends Argument{
86 public BooleanArgument(boolean val)
88 super(ArgumentType.BOOLEAN_TYPE);
91 public boolean getBoolean()
95 public String toString()
101 private static class StringArgument extends Argument{
103 public StringArgument(String val)
105 super(ArgumentType.STRING_TYPE);
108 public String toString()
110 return _val.toString();
114 private static class ArrayArgument extends Argument{
115 Vector<Argument> _val;
116 public ArrayArgument(Vector<Argument> val)
118 super(ArgumentType.ARRAY_TYPE);
125 public Argument getArgument(int i)
129 public String toString()
131 return _val.toString();
136 private enum ArgumentType{
145 private enum Function{
146 ADD_CHEM_PROB("addchemprob",new ArgumentType[] {ArgumentType.NUMBER_TYPE,ArgumentType.NUMBER_TYPE,ArgumentType.STRING_TYPE,ArgumentType.NUMBER_TYPE,ArgumentType.COLOR_TYPE,ArgumentType.BOOLEAN_TYPE}),
147 ERASE_SEQ("eraseseq",new ArgumentType[] {}),
148 RESET_CHEM_PROB("resetchemprob",new ArgumentType[] {}),
149 SET_COLOR_MAP_MIN("setcolormapminvalue",new ArgumentType[]{ArgumentType.NUMBER_TYPE}),
150 SET_COLOR_MAP_MAX("setcolormapmaxvalue",new ArgumentType[]{ArgumentType.NUMBER_TYPE}),
151 SET_COLOR_MAP("setcolormap",new ArgumentType[]{ArgumentType.STRING_TYPE}),
152 SET_CUSTOM_COLOR_MAP("setcustomcolormap",new ArgumentType[]{ArgumentType.ARRAY_TYPE}),
153 SET_SEQ("setseq",new ArgumentType[]{ArgumentType.STRING_TYPE}),
154 SET_STRUCT("setstruct",new ArgumentType[]{ArgumentType.STRING_TYPE}),
155 SET_STRUCT_SMOOTH("setstructsmooth",new ArgumentType[] {ArgumentType.STRING_TYPE}),
156 SET_TITLE("settitle",new ArgumentType[] {ArgumentType.STRING_TYPE}),
157 SET_RNA("setrna",new ArgumentType[]{ArgumentType.STRING_TYPE,ArgumentType.STRING_TYPE}),
158 SET_RNA_SMOOTH("setrnasmooth",new ArgumentType[]{ArgumentType.STRING_TYPE,ArgumentType.STRING_TYPE}),
159 SET_SELECTION("setselection",new ArgumentType[]{ArgumentType.ARRAY_TYPE}),
160 SET_VALUES("setvalues",new ArgumentType[]{ArgumentType.ARRAY_TYPE}),
161 TOGGLE_SHOW_COLOR_MAP("toggleshowcolormap",new ArgumentType[]{}),
162 REDRAW("redraw",new ArgumentType[] {ArgumentType.STRING_TYPE}),
163 UNKNOWN("N/A",new ArgumentType[] {});
166 ArgumentType[] _args;
167 Function(String funName, ArgumentType[] args)
172 ArgumentType[] getPrototype()
178 return this._funName;
183 private static Hashtable<String,Function> _name2Fun = new Hashtable<String,Function>();
184 private static Hashtable<Function,ArgumentType[]> _fun2Prot = new Hashtable<Function,ArgumentType[]>();
187 private static void initFunctions()
189 if (_name2Fun.size()>0)
191 Function[] funs = Function.values();
192 for(int i=0;i<funs.length;i++)
194 Function fun = funs[i];
195 _name2Fun.put(fun.getFunName(),fun);
196 _fun2Prot.put(fun,fun.getPrototype());
200 private static Function getFunction(String f)
202 String s = f.trim().toLowerCase();
203 if (_name2Fun.containsKey(s))
204 return _name2Fun.get(s);
205 return Function.UNKNOWN;
208 private static ArgumentType[] getPrototype(Function f)
210 if (_fun2Prot.containsKey(f))
211 return _fun2Prot.get(f);
212 return new ArgumentType[0];
215 public static void executeScript(VARNAPanel vp, String cmdtxt) throws Exception
217 Vector<Command> cmds = parseScript(cmdtxt);
218 for(int i=0;i<cmds.size();i++)
220 Command cmd = cmds.get(i);
225 int from = (int)((NumberArgument) cmd._argv.get(0)).getNumber().intValue();
226 int to = (int)((NumberArgument) cmd._argv.get(1)).getNumber().intValue();
227 ChemProbAnnotationType t = ChemProbAnnotation.annotTypeFromString(((StringArgument) cmd._argv.get(2)).toString());
228 double intensity = ((NumberArgument) cmd._argv.get(3)).getNumber().doubleValue();
229 Color c = ((ColorArgument) cmd._argv.get(4)).getColor();
230 boolean out = ((BooleanArgument) cmd._argv.get(5)).getBoolean();
231 vp.getRNA().addChemProbAnnotation(new ChemProbAnnotation(
232 vp.getRNA().getBaseAt(from),
233 vp.getRNA().getBaseAt(to),
245 case RESET_CHEM_PROB:
247 vp.getRNA().clearChemProbAnnotations();
251 case SET_COLOR_MAP_MIN:
253 vp.setColorMapMinValue(((NumberArgument) cmd._argv.get(0)).getNumber().doubleValue());
256 case SET_COLOR_MAP_MAX:
258 vp.setColorMapMaxValue(((NumberArgument) cmd._argv.get(0)).getNumber().doubleValue());
263 vp.setColorMap(ModeleColorMap.parseColorMap(cmd._argv.get(0).toString()));
266 case SET_CUSTOM_COLOR_MAP:
268 ModeleColorMap cm = new ModeleColorMap();
269 //System.out.println("a"+cmd._argv.get(0));
270 ArrayArgument arg = (ArrayArgument) cmd._argv.get(0);
271 for (int j=0;j<arg.getSize();j++)
273 Argument a = arg.getArgument(j);
274 if (a._t==ArgumentType.ARRAY_TYPE)
276 //System.out.println("%");
277 ArrayArgument aarg = (ArrayArgument) a;
278 if (aarg.getSize()==2)
280 Argument a1 = aarg.getArgument(0);
281 Argument a2 = aarg.getArgument(1);
282 //System.out.println("& |"+a1+"| ["+a1.getType()+"] |"+a2+"| ["+a2.getType()+"]");
283 if ((a1.getType()==ArgumentType.NUMBER_TYPE)&&(a2.getType()==ArgumentType.COLOR_TYPE))
285 //System.out.println("+");
286 cm.addColor(((NumberArgument)a1).getNumber().doubleValue(),((ColorArgument)a2).getColor());
296 String seq = cmd._argv.get(0).toString();
297 String str = cmd._argv.get(1).toString();
298 vp.drawRNA(seq, str);
303 String seq = cmd._argv.get(0).toString();
304 String str = cmd._argv.get(1).toString();
305 vp.drawRNAInterpolated(seq, str);
311 ArrayArgument arg = (ArrayArgument) cmd._argv.get(0);
312 ArrayList<Integer> vals = new ArrayList<Integer>();
313 for (int j=0;j<arg.getSize();j++)
315 Argument a = arg.getArgument(j);
316 if (a._t==ArgumentType.NUMBER_TYPE)
318 NumberArgument narg = (NumberArgument) a;
319 vals.add(narg.getNumber().intValue());
322 vp.setSelection(vals);
328 String seq = cmd._argv.get(0).toString();
334 String seq = vp.getRNA().getSeq();
335 String str = cmd._argv.get(0).toString();
336 vp.drawRNA(seq, str);
339 case SET_STRUCT_SMOOTH:
341 String seq = vp.getRNA().getSeq();
342 String str = cmd._argv.get(0).toString();
343 vp.drawRNAInterpolated(seq, str);
349 vp.setTitle(cmd._argv.get(0).toString());
354 ArrayArgument arg = (ArrayArgument) cmd._argv.get(0);
355 Double[] vals = new Double[arg.getSize()];
356 for (int j=0;j<arg.getSize();j++)
358 Argument a = arg.getArgument(j);
359 if (a._t==ArgumentType.NUMBER_TYPE)
361 NumberArgument narg = (NumberArgument) a;
362 vals[j] = narg.getNumber().doubleValue();
365 vp.setColorMapValues(vals);
372 String modeStr = cmd._argv.get(0).toString().toLowerCase();
373 if (modeStr.equals("radiate"))
374 mode = RNA.DRAW_MODE_RADIATE;
375 else if (modeStr.equals("circular"))
376 mode = RNA.DRAW_MODE_CIRCULAR;
377 else if (modeStr.equals("naview"))
378 mode = RNA.DRAW_MODE_NAVIEW;
379 else if (modeStr.equals("linear"))
380 mode = RNA.DRAW_MODE_LINEAR;
382 vp.drawRNA(vp.getRNA(), mode);
385 case TOGGLE_SHOW_COLOR_MAP:
387 vp.setColorMapVisible(!vp.getColorMapVisible());
391 throw new Exception(SCRIPT_ERROR_PREFIX+": Method '"+cmd._f+"' unimplemented.");
399 private static Color parseColor(String s)
402 try {result = Color.decode(s); }
403 catch (Exception e) {}
407 private static Boolean parseBoolean(String s)
409 Boolean result = null;
410 if (s.toLowerCase().equals("true"))
411 result = new Boolean(true);
412 if (s.toLowerCase().equals("false"))
413 result = new Boolean(false);
418 private static Vector<Argument> parseArguments(StreamTokenizer st, boolean parType) throws Exception
420 Vector<Argument> result = new Vector<Argument>();
421 while((st.ttype!=')' && parType) || (st.ttype!=']' && !parType))
424 //System.out.println(""+ (parType?"Par.":"Bra.")+" "+(char)st.ttype);
427 case(StreamTokenizer.TT_NUMBER):
429 result.add(new NumberArgument(st.nval));
432 case(StreamTokenizer.TT_WORD):
434 Color c = parseColor(st.sval);
437 result.add(new ColorArgument(c));
441 Boolean b = parseBoolean(st.sval);
444 result.add(new BooleanArgument(b));
448 result.add(new StringArgument(st.sval));
455 result.add(new StringArgument(st.sval));
460 result.add(new ArrayArgument(parseArguments(st, false)));
465 result.add(new ArrayArgument(parseArguments(st, true)));
473 throw new Exception(SCRIPT_ERROR_PREFIX+": Opening "+(parType?"parenthesis":"bracket")+" matched with a closing "+(!parType?"parenthesis":"bracket"));
480 throw new Exception(SCRIPT_ERROR_PREFIX+": Opening "+(parType?"parenthesis":"bracket")+" matched with a closing "+(!parType?"parenthesis":"bracket"));
484 case(StreamTokenizer.TT_EOF):
486 throw new Exception(SCRIPT_ERROR_PREFIX+": Unmatched opening "+(parType?"parenthesis":"bracket"));
495 private static Command parseCommand(String cmd) throws Exception
497 int cut = cmd.indexOf("(");
500 throw new Exception(SCRIPT_ERROR_PREFIX+": Syntax error");
502 String fun = cmd.substring(0,cut);
503 Function f = getFunction(fun);
504 if (f==Function.UNKNOWN)
505 { throw new Exception(SCRIPT_ERROR_PREFIX+": Unknown function \""+fun+"\""); }
506 StreamTokenizer st = new StreamTokenizer(new StringReader(cmd.substring(cut+1)));
507 st.eolIsSignificant(false);
510 st.ordinaryChar('=');
511 st.ordinaryChar(',');
512 st.ordinaryChar('[');
513 st.ordinaryChar(']');
514 st.ordinaryChar('(');
515 st.ordinaryChar(')');
516 st.wordChars('#', '#');
517 Vector<Argument> argv = parseArguments(st,true);
519 Command result = new Command(f,argv);
523 private static boolean checkArgs(Function f, Vector<Argument> argv) throws Exception
525 ArgumentType[] argtypes = getPrototype(f);
526 if (argtypes.length!=argv.size())
527 throw new Exception(SCRIPT_ERROR_PREFIX+": Wrong number of argument for function \""+f+"\".");
528 for (int i=0;i<argtypes.length;i++)
530 if (argtypes[i] != argv.get(i)._t)
532 throw new Exception(SCRIPT_ERROR_PREFIX+": Bad type ("+argtypes[i]+"!="+argv.get(i)._t+") for argument #"+(i+1)+" in function \""+f+"\".");
538 private static Vector<Command> parseScript(String cmd) throws Exception
541 Vector<Command> cmds = new Vector<Command>();
542 String[] data = cmd.split(";");
543 for (int i=0;i<data.length;i++)
545 cmds.add(parseCommand(data[i].trim()));