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    package graphlab.plugins.commandline.extensionloader;
005    
006    import graphlab.platform.core.BlackBoard;
007    import graphlab.platform.extension.Extension;
008    import graphlab.platform.extension.UnknownExtensionLoader;
009    import graphlab.plugins.commandline.Shell;
010    
011    import java.io.File;
012    import java.io.FileNotFoundException;
013    import java.util.Scanner;
014    import java.util.StringTokenizer;
015    
016    /**
017     * This class loads extensions from .bsh files in extensions folder.
018     */
019    public class BSHExtensionLoader implements UnknownExtensionLoader {
020        // \graphlab\..\*.ext
021        //    private String extFileName;
022        Shell shell;
023    
024        public BSHExtensionLoader(Shell shell) {
025            this.shell = shell;
026        }
027    
028        public Extension ExtensionLoader(String extFileName) {
029    //        this.extFileName = extFileName;
030            String eval = "";
031            Scanner s = null;
032            int bracketCount = 0;
033            boolean lineComment = false;
034            try {
035                s = new Scanner(new File(extFileName));
036            } catch (FileNotFoundException e) {
037                System.err.println("File not Found");
038            }
039            do {
040                String line = s.nextLine();
041    
042                if (!lineComment) {
043                    if (line.contains("/*")) {
044                        if (!lineComment)
045                            line = line.substring(0, line.indexOf("/*"));
046                        lineComment = true;
047                    }
048                    if (line.contains("//")) {
049                        if (!lineComment)
050                            line = line.substring(0, line.indexOf("//"));
051                    }
052                    if (line.startsWith("package")) {
053                        // do nothing
054                    } else if (line.startsWith("public class")) {
055                        line = line.substring(12); // removing public class
056                        StringTokenizer st = new StringTokenizer(line, " ,");
057                        while (!st.nextToken().equals("implements")) ;
058                        eval += "ex = new " + st.nextToken() + " ()";
059                        while (st.hasMoreTokens()) {
060                            eval += " " + st.nextToken();
061                        }
062                        eval += "\n";
063    //                    eval = eval.replaceFirst("{","(){");
064                    } else
065                        eval += line + "\n";
066    
067                }
068                if (line.contains("*/")) {
069                    lineComment = false;
070                    line = line.substring(line.indexOf("*/") + 2);
071                    if (line.startsWith("package")) {
072                        // do nothing
073                    } else if (line.startsWith("public class")) {
074                        line = line.substring(12); // removing public class
075                        StringTokenizer st = new StringTokenizer(line, " ");
076                        eval += "ex = new " + st.nextToken() + " ()";
077                        while (st.hasMoreTokens()) {
078                            eval += " " + st.nextToken();
079                        }
080                        eval += "\n";
081    //                        eval = eval.replaceFirst("{","(){");
082                    } else
083                        eval += line + "\n";
084                }
085            }
086            while (s.hasNextLine());
087    //        eval+=";";
088            String other = "";
089            s = new Scanner(eval);
090            String assignment = "";
091            boolean isAssignment = false;
092            int i = 0;
093            while (s.hasNextLine()) {
094                String l = s.nextLine();
095                if ((l.contains("ex = new") && bracketCount == 0) || (isAssignment)) {
096                    if (!l.equals(""))
097                        assignment += l + "\n";
098                    if (!isAssignment) {
099                        i = bracketCount + countBrackets(l);
100                        isAssignment = true;
101                    }
102                    bracketCount += countBrackets(l);
103                    if (i > bracketCount)
104                        isAssignment = false;
105                } else {
106                    if (!l.equals(""))
107                        other += l + "\n";
108                    bracketCount += countBrackets(l);
109    
110                }
111    
112            }
113    //        System.err.println("Other");
114    //        System.err.println("*******\n" + other + "\n*******");
115    //        System.err.println("Assignment");
116    //        System.err.println("*******\n" + assignment + "\n*******");
117    //        System.out.println("eval ******* \n " + eval);
118    
119            shell.evaluate(other);
120            shell.evaluate(assignment + ";");
121            shell.evaluate("import graphlab.ui.extension.*;");
122            return (Extension) shell.evaluate("return (Extension)ex;");
123        }
124    
125        private static int countBrackets(String l) {
126            String l2 = l;
127            String l1 = l;
128            int count = 0;
129            while (l1.contains("{")) {
130                l1 = l1.substring(l1.indexOf("{") + 1);
131                count++;
132            }
133            while (l2.contains("}")) {
134                l2 = l2.replaceFirst("}", "-");
135                count--;
136            }
137            return count;
138        }
139    
140    
141        public Extension load(File file, BlackBoard blackboard) {
142            if (file.getName().endsWith(".bsh"))
143                return ExtensionLoader(file.getAbsolutePath());
144            return null;
145        }
146    }