001    // GraphLab Project: http://graphlab.sharif.edu
002    // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
003    // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/
004    
005    package graphlab.plugins.commandline.parsers;
006    
007    import bsh.EvalError;
008    import bsh.Interpreter;
009    import graphlab.platform.lang.CommandAttitude;
010    import graphlab.plugins.commandline.Shell;
011    import graphlab.plugins.commandline.ShellConsole;
012    import graphlab.plugins.commandline.commands.ShellCommandException;
013    import graphlab.ui.ExtensionShellCommandProvider;
014    
015    import java.awt.*;
016    import java.lang.reflect.InvocationTargetException;
017    import java.lang.reflect.Method;
018    import java.util.Collections;
019    import java.util.HashMap;
020    import java.util.Map;
021    import java.util.Vector;
022    
023    /**
024     * @author Mohammad Ali Rostatmi
025     * @email ma.rostami@yahoo.com
026     */
027    public class InwardCommandParser {
028        public HashMap<String, Method> commands = new HashMap<String, Method>();
029        public HashMap<String, String> abbrs = new HashMap<String, String>();
030    
031        private Interpreter interpreter;
032        private Shell shell;
033        public static String evaluations;
034    
035    
036        public InwardCommandParser(Interpreter interpreter, Shell shell) {
037            this.interpreter = interpreter;
038            this.shell = shell;
039            try {
040                interpreter.set("me", this);
041                interpreter.eval("help() { me.help();}");
042                interpreter.eval("help(command) { me.help(command);}");
043                evaluations = shell.getEvaluations();
044            } catch (EvalError evalError) {
045                evalError.printStackTrace();
046            }
047        }
048    
049        public void help() {
050            try {
051                ((ShellConsole) interpreter.get("console")).print("\nTo see details of commands (arguments , full description) run command: help(\"command\")\n\n"
052                        , Color.red);
053            } catch (EvalError evalError) {
054                evalError.printStackTrace();
055            }
056            String h = "";
057            Vector<String> hh = new Vector<String>();
058    
059            for (String s : commands.keySet()) {
060                hh.add(getHelpString(s));
061            }
062    
063            for (Map.Entry<String, Class> e : shell.code_completion_dictionary.entrySet()) {
064                String command = e.getKey();
065                hh.add(getHelpString(command));
066            }
067    
068            Collections.sort(hh);
069    
070    
071            for (String s : hh)
072                h += s;
073    
074            try {
075                ((ShellConsole) interpreter.get("console")).println(h, Color.blue);
076            } catch (EvalError evalError) {
077                evalError.printStackTrace();
078            }
079        }
080    
081        public void help(String command) {
082            String h = getHelpString(command);
083            try {
084                ((ShellConsole) interpreter.get("console")).println(h, Color.blue);
085            } catch (EvalError evalError) {
086                evalError.printStackTrace();
087            }
088        }
089    
090        private String getHelpString(String command) {
091            String h = "";
092            h += command;
093            if (commands.containsKey(command)) {
094                h += "(" + commands.get(command).getAnnotation(CommandAttitude.class).abbreviation() + ") :";
095                h += commands.get(command).getAnnotation(CommandAttitude.class).description();
096                h += "\n";
097            } else if (shell.code_completion_dictionary.containsKey(command)) {
098                Class claz = shell.code_completion_dictionary.get(command);
099                if (claz != null) {
100    //                CommandAttitude an1 = (CommandAttitude) claz.getAnnotation(CommandAttitude.class);
101    //                if (an1 != null) {
102    //                    h += "(" + an1.abbreviation() + ") :";
103    //                    h += an1.description();
104    //                } if (Extension.class.isAssignableFrom(claz)) {
105                    ExtensionShellCommandProvider provider = ExtensionShellCommandProvider.commandsDict.get(command);
106                    if (provider != null) {
107                        h += "(" + provider.abrv + ") :";
108                        h += provider.desc;
109    //                    }
110                    }
111                }
112                h += "\n";
113            }
114            return h;
115        }
116    
117        public Object evaluateCommand(String s, String name, String abbr) {
118            evaluations += s;
119            abbrs.put(abbr, name);
120            try {
121                return interpreter.eval(s);
122            } catch (EvalError evalError) {
123                evalError.printStackTrace();
124            }
125            return null;
126        }
127    
128    
129        /**
130         * the Objects that the methods should be invoked on.
131         */
132        public HashMap<Method, Object> methodObjects = new HashMap<Method, Object>();
133    
134        /**
135         * imports all commands stored in annotated methods of o
136         *
137         * @param o
138         */
139        public void addCommands(Object o) {
140            try {
141                interpreter.set("current_interpreter", interpreter);
142                evaluations = "import graphlab.graph.graph.*;" + evaluations;
143                evaluations = "import graphlab.ui.lang.*;" + evaluations;
144            } catch (EvalError evalError) {
145                evalError.printStackTrace();
146            }
147            Class clazz = o.getClass();
148            for (Method m : clazz.getMethods()) {
149                CommandAttitude cm = m.getAnnotation(CommandAttitude.class);
150                if (cm != null) {
151                    commands.put(cm.name(), m);
152                    abbrs.put(cm.abbreviation(), cm.name());
153                    methodObjects.put(m, o);
154    
155                    String evaluation = cm.name() + "(";
156    
157                    String temp = "";
158                    if (m.getParameterTypes().length != 0)
159                        temp = "Object[] o = new Object[" + m.getParameterTypes().length + "];";
160    
161                    int i = 0;
162                    for (Class c : m.getParameterTypes()) {
163                        i++;
164                        evaluation += c.getSimpleName() + " x" + i + "  ,";
165                        temp += "o[" + (i - 1) + "] = x" + i + ";";
166                    }
167    
168                    evaluation = (m.getParameterTypes().length == 0 ?
169                            evaluation : evaluation.substring(0, evaluation.length() - 1))
170                            + ")";
171    
172                    if (m.getParameterTypes().length == 0)
173                        evaluation += "{" + temp + "me.parseShell(\"" + cm.name() + "\"" + ",null,current_interpreter);}";
174                    else
175                        evaluation += "{" + temp + "me.parseShell(\"" + cm.name() + "\"" + ",o,current_interpreter);}";
176                    evaluations += evaluation + "\n";
177                }
178            }
179            try {
180                interpreter.eval(evaluations);
181            } catch (EvalError evalError) {
182                evalError.printStackTrace();
183            }
184        }
185    
186        public Object parseShell(String command, Object[] ps, Interpreter in) throws ShellCommandException {
187            Method m = commands.get(command);
188            Object o = null;
189            if (m != null) {
190                try {
191                    o = m.invoke(methodObjects.get(m), ps);
192                    if (o != null && (o.getClass().isPrimitive() || o instanceof String)) {
193    //                    in.set("obj", o);
194    //                   in.eval("print(obj);");
195                    } else {
196    //                    if (!m.getAnnotation(CommandAttitude.class).result().equals("")) {
197    //                        in.eval(m.getAnnotation(CommandAttitude.class).result());
198    //                        in.set("obj", o);
199    //                        in.eval("print_out(obj);");
200    //                    }
201                    }
202                } catch (IllegalAccessException e) {
203                    e.printStackTrace();
204                } catch (InvocationTargetException e) {
205                    e.printStackTrace();
206                } catch (NumberFormatException e) {
207                    e.printStackTrace();
208                }
209            } else {
210                in.print("bad command!\n");
211            }
212            return o;
213        }
214    
215        Object getValue(String value, Class valuetype) {
216            if (valuetype.getName().equals("int"))
217                return Integer.parseInt(value);
218            else if (valuetype.getName().equals("double"))
219                return Double.parseDouble(value);
220            return value;
221    
222        }
223    
224    }