Ignore:
Timestamp:
07/12/16 23:49:55 (8 years ago)
Author:
davidb
Message:

Refactoring to allow support for additional scriptable languages. In this case, Python being added in through Jythohn Java library

Location:
trunk/src/org/expeditee/actions
Files:
2 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/expeditee/actions/Javascript2.java

    r951 r1078  
    4848 * @author jts21
    4949 */
    50 public class Javascript2 {
     50public class Javascript2 extends ScriptBase {
    5151       
    52         public static final String ERROR_FRAMESET = "JavascriptErrors";
     52    protected void init() {
     53        ERROR_FRAMESET = "JavascriptErrors";
     54        scriptEngineManager = new ScriptEngineManager();
     55        scriptEngine = scriptEngineManager.getEngineByMimeType("application/javascript");
     56        scriptEngine.put("invocable", (Invocable) scriptEngine);
     57    }
    5358       
    54         public static final ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    55         public static final ScriptEngine scriptEngine = scriptEngineManager.getEngineByMimeType("application/javascript");
    56         static {
    57                 scriptEngine.put("invocable", (Invocable) scriptEngine);
     59    public static void printJSFrame(Item item) {
     60        if(item.getChild() == null) {
     61            // if the user clicked on the action without an item on their cursor
     62            if(item.hasAction()) {
     63                boolean isThis = false;
     64                for(String s : item.getAction()) {
     65                    if(s.equalsIgnoreCase("printJSFrame")) {
     66                        isThis = true;
     67                        break;
     68                    }
     69                }
     70                if(isThis) {
     71                    System.out.println(new Javascript2(item.getParentOrCurrentFrame(), true));
     72                    return;
     73                }
     74            }
     75            MessageBay.warningMessage("Requires either an item with a link to a frame, or no item (will run the current frame)");
     76        } else {
     77            System.out.println(new Javascript2(item.getChild(), true));
    5878        }
     79    }
    5980       
    60         public static void printJSFrame(Item item) {
    61                 if(item.getChild() == null) {
    62                         // if the user clicked on the action without an item on their cursor
    63                 if(item.hasAction()) {
    64                         boolean isThis = false;
    65                         for(String s : item.getAction()) {
    66                                 if(s.equalsIgnoreCase("runJSFrame")) {
    67                                         isThis = true;
    68                                         break;
    69                                 }
    70                         }
    71                         if(isThis) {
    72                                 System.out.println(new Javascript2(item.getParentOrCurrentFrame(), true));
    73                                 return;
    74                         }
    75                 }
    76                 MessageBay.warningMessage("Requires either an item with a link to a frame, or no item (will run the current frame)");
    77                 } else {
    78                         System.out.println(new Javascript2(item.getChild(), true));
     81    public static void runJSFrame(Item item) throws Exception {
     82        if(item.getChild() == null) {
     83            // if the user clicked on the action without an item on their cursor
     84            if(item.hasAction()) {
     85                boolean isThis = false;
     86                for(String s : item.getAction()) {
     87                    if(s.equalsIgnoreCase("runJSFrame")) {
     88                        isThis = true;
     89                        break;
     90                    }
    7991                }
     92                if(isThis) {
     93                    Javascript2.runFrameFollow(item.getParentOrCurrentFrame());
     94                    return;
     95                }
     96            }
     97            MessageBay.warningMessage("Requires either an item with a link to a frame, or no item (will run the current frame)");
     98        } else {
     99            Javascript2.runFrameFollow(item.getChild());
    80100        }
     101    }
    81102       
    82         public static void runJSFrame(Item item) throws Exception {
    83                 if(item.getChild() == null) {
    84                         // if the user clicked on the action without an item on their cursor
    85                 if(item.hasAction()) {
    86                         boolean isThis = false;
    87                         for(String s : item.getAction()) {
    88                                 if(s.equalsIgnoreCase("runJSFrame")) {
    89                                         isThis = true;
    90                                         break;
    91                                 }
    92                         }
    93                         if(isThis) {
    94                                 Javascript2.runFrame(item.getParentOrCurrentFrame(), true);
    95                                 return;
    96                         }
    97                 }
    98                 MessageBay.warningMessage("Requires either an item with a link to a frame, or no item (will run the current frame)");
    99                 } else {
    100                         Javascript2.runFrame(item.getChild(), true);
    101                 }
    102         }
    103103       
    104         public static Object eval(String code) {
    105                 try {
    106                 return scriptEngine.eval(code);
    107         } catch (ScriptException e) {
    108                 e.printStackTrace();
    109         }
    110                 return null;
    111         }
     104    private static synchronized void runFrameFollow(Frame frame) throws Exception {
     105        Javascript2 js = new Javascript2(frame, true);
     106        js.runFrame(frame,true);       
     107    }
    112108       
    113         private static synchronized void runFrame(Frame frame, boolean followLinks) throws Exception {
    114                 Javascript2 js = new Javascript2(frame, followLinks);
    115                 try {
    116                 try {
    117                 scriptEngine.eval(js.toString());
    118             } catch (ScriptException e) {
    119                         js.handleError(e.getMessage(), e.getLineNumber());
    120             } catch (RuntimeException e) {
    121                 // there doesn't seem to be a way to safely get the lineNumber on which the error occurred
    122                 // so as a workaround we just parse the exception
    123                 if(e.getCause() == null) {
    124                         throw e;
    125                 }
    126                 String detail = e.getCause().getStackTrace()[1].toString();
    127                 int lastColon = detail.lastIndexOf(':');
    128                 int lastBracket = detail.lastIndexOf(')');
    129                 int lineNumber;
    130                 if(lastColon == -1 || lastBracket == -1) {
    131                         lineNumber = -1;
    132                 } else {
    133                         lineNumber = Integer.parseInt(detail.substring(lastColon + 1, lastBracket));
    134                 }
    135                 js.handleError(e.getMessage(), lineNumber);
    136             }
    137                 } catch(Exception e) {
    138                         js.handleError(null, -1);
    139                         System.out.println(js.toString());
    140                         e.printStackTrace();
    141                 }
    142         }
    143        
    144         private static final class CodeLine {
    145                 public Text item;
    146                 public int line;
    147                 public String source;
    148                
    149                 public CodeLine(Text item, int line, String source) {
    150                         this.item = item;
    151                         this.line = line;
    152                         this.source = source;
    153                 }
    154                
    155                 public String toString() {
    156                         return line + ": " + source;
    157                 }
    158         }
    159        
    160         private List<Frame> seen = new LinkedList<Frame>();
    161         private List<CodeLine> lines = new LinkedList<CodeLine>();
    162         private StringBuffer sb = new StringBuffer();
    163         private Javascript2(Frame frame, boolean followLinks) {
    164                 this.parseFrame(frame, followLinks);
    165         }
    166        
    167         private void parseFrame(Frame frame, boolean followLinks) {
    168                 if(frame == null) {
    169                         return;
    170                 }
    171                
    172                 // make sure we don't get into an infinite loop
    173                 // TODO: find a smarter way to do this that allows reusing frames but still stops infinite loops?
    174                 seen.add(frame);
    175                
    176                 // get all items on the frame
    177                 List<Item> y_ordered_items = (List<Item>)frame.getItems();
    178                 // remove the title item
    179                 y_ordered_items.remove(frame.getTitleItem());
    180                
    181                 XGroupItem toplevel_xgroup = new XGroupItem(frame,y_ordered_items);
    182                 // ... following on from Steps 1 and 2 in the Constructor in XGroupItem ...
    183                
    184                 // Step 3: Reposition any 'out-of-flow' XGroupItems
    185                 toplevel_xgroup.repositionOutOfFlowGroups(toplevel_xgroup);
    186                
    187                 // Step 4: Now add in the remaining (nested) XGroupItems
    188                 List<XGroupItem> grouped_item_list = toplevel_xgroup.getGroupedItemList();
    189                 toplevel_xgroup.mapInXGroupItemsRecursive(grouped_item_list);
    190        
    191                 // Finally, retrieve linear list of all Items, (ordered, Y by X, allowing for overlap, nested-boxing, and arrow flow)
    192                 List<Item> overlapping_y_ordered_items = toplevel_xgroup.getYXOverlappingItemList(true);       
    193                
    194                 // Loop through the items looking for code and links to new frames
    195                 for(Item i : overlapping_y_ordered_items) {
    196                         if(followLinks && i.hasLink()) {
    197                                 Frame child = i.getChild();
    198                                 if(child != null && !seen.contains(child)) {
    199                                         this.parseFrame(child, true);
    200                                 }
    201                         }
    202                         if(i instanceof Text && !i.isAnnotation()) {
    203                                 String text = ((Text)i).getText();
    204                                 if (i == org.expeditee.io.flowlayout.XGroupItem.GROUPSEP_START) {
    205                                         text = "{";
    206                                 }
    207                                 else if (i == org.expeditee.io.flowlayout.XGroupItem.GROUPSEP_END) {
    208                                                 text = "}";
    209                                 }
    210                                
    211                                 int lineNumber = 0;
    212                                 for(String line : text.trim().split("[\\n\\r]+")) {
    213                                         sb.append(line).append("\n");
    214                                         lines.add(new CodeLine((Text)i, lineNumber++, line));
    215                                 }
    216                         }
    217                 }
    218         }
    219        
    220         private void handleError(String message, int lineNumber) throws Exception {
    221                 // negative line number bad
    222                 if(lineNumber < 0) {
    223                         MessageBay.errorMessage("Failed to determine the line on which the error occurred");
    224                         return;
    225                 }
    226                 // if for some reason the error is after the end of the code, assume it should be the last line
    227                 if(lineNumber > this.lines.size()) {
    228                         lineNumber = this.lines.size();
    229                 }
    230                 CodeLine cl = this.lines.get(lineNumber - 1);
    231                 Frame errorSourceFrame = cl.item.getParent();
    232                 if(errorSourceFrame == null) {
    233                         MessageBay.errorMessage("Failed to find frame on which the error occurred");
    234                         return;
    235                 }
    236                 Frame errorFrame;
    237                 String title = "Error parsing \"" + errorSourceFrame.getTitle() + "\" (" + errorSourceFrame.getName() + ")";
    238                 if(FrameIO.canAccessFrameset(ERROR_FRAMESET)) {
    239                         errorFrame = FrameIO.CreateFrame(ERROR_FRAMESET, title, null);
    240                 } else {
    241                         errorFrame = FrameIO.CreateFrameset(ERROR_FRAMESET, FrameIO.FRAME_PATH);
    242                         errorFrame.setTitle(title);
    243                 }
    244                 Collection<Item> toAdd = errorSourceFrame.getAllItems();
    245                 toAdd.remove(errorSourceFrame.getTitleItem());
    246                 toAdd.remove(cl.item);
    247                 errorFrame.addAllItems(ItemUtils.CopyItems(toAdd));
    248                 String errorItemText = cl.item.getText().trim();
    249                 String[] errorItemLines = errorItemText.split("[\\n\\r]+");
    250                 int errorLinePos = 0;
    251                 int x = cl.item.getX();
    252                 int y = cl.item.getY();
    253                 if(cl.line != 0) {
    254                 for(int i = 0; i < cl.line; i++) {
    255                         errorLinePos += errorItemLines[i].length();
    256                 }
    257                 Text beforeErrorItem = errorFrame.addText(x, y,
    258                                 errorItemText.substring(0, errorLinePos), null);
    259                 y = beforeErrorItem.getY() + beforeErrorItem.getBoundsHeight();
    260                 }
    261                 Text errorItem;
    262                 errorItem = errorFrame.addText(x, y, errorItemLines[cl.line], null);
    263                 errorItem.setBackgroundColor(Color.RED);
    264                 for(String line : message.split("[\\n\\r]+")) {
    265                         errorItem.setTooltip("text: " + line);
    266                 }
    267                 errorItem.setTooltip("font: " + Text.MONOSPACED_FONT);
    268                 errorItem.setTooltip("width: " + 80 * 12);
    269                 errorLinePos += errorItemLines[cl.line].length();
    270                 if(++errorLinePos < errorItemText.length()) {
    271                         errorFrame.addText(cl.item.getX(), errorItem.getY() + errorItem.getBoundsHeight(),
    272                                         errorItemText.substring(errorLinePos + 1), null);
    273                 }
    274                 errorFrame.change();
    275                 FrameIO.SaveFrame(errorFrame);
    276                 MessageBay.displayMessage("Script failed at line " + lineNumber +  " - `" + cl.source + "`",
    277                                 errorFrame.getName(), MessageBay.ERROR_COLOR, true, null);
    278                 FrameUtils.DisplayFrame(errorFrame, true, true);
    279         }
    280        
    281         public String toString() {
    282                 return this.sb.toString();
    283         }
    284109
     110    private Javascript2(Frame frame, boolean followLinks) {
     111        super(frame,followLinks);
     112    }
     113   
    285114}
Note: See TracChangeset for help on using the changeset viewer.