Save This Page
Home » bsf-src-2.4.0 » org.apache.bsf.engines.javascript » [javadoc | source]
    1   /*
    2    * The Apache Software License, Version 1.1
    3    *
    4    * Copyright (c) 2002 The Apache Software Foundation.  All rights
    5    * reserved.
    6    *
    7    * Redistribution and use in source and binary forms, with or without
    8    * modification, are permitted provided that the following conditions
    9    * are met:
   10    *
   11    * 1. Redistributions of source code must retain the above copyright
   12    *    notice, this list of conditions and the following disclaimer.
   13    *
   14    * 2. Redistributions in binary form must reproduce the above copyright
   15    *    notice, this list of conditions and the following disclaimer in
   16    *    the documentation and/or other materials provided with the
   17    *    distribution.
   18    *
   19    * 3. The end-user documentation included with the redistribution, if
   20    *    any, must include the following acknowlegement:
   21    *       "This product includes software developed by the
   22    *        Apache Software Foundation (http://www.apache.org/)."
   23    *    Alternately, this acknowlegement may appear in the software itself,
   24    *    if and wherever such third-party acknowlegements normally appear.
   25    *
   26    * 4. The names "Apache BSF", "Apache", and "Apache Software Foundation"
   27    *    must not be used to endorse or promote products derived from
   28    *    this software without prior written permission. For written
   29    *    permission, please contact apache@apache.org.
   30    *
   31    * 5. Products derived from this software may not be called "Apache"
   32    *    nor may "Apache" appear in their names without prior written
   33    *    permission of the Apache Group.
   34    *
   35    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   36    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   37    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   38    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   39    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   40    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   41    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   42    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   43    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   44    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   45    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   46    * SUCH DAMAGE.
   47    * ====================================================================
   48    *
   49    * This software consists of voluntary contributions made by many individuals
   50    * on behalf of the Apache Software Foundation and was originally created by
   51    * Sanjiva Weerawarana and others at International Business Machines
   52    * Corporation. For more information on the Apache Software Foundation,
   53    * please see <http://www.apache.org/>.
   54    */
   55   
   56   package org.apache.bsf.engines.javascript;
   57   
   58   import java.io.StringReader;
   59   import java.io.InputStream;
   60   import java.io.IOException;
   61   import java.lang.reflect.InvocationTargetException;
   62   import java.util.Vector;
   63   import java.util.Enumeration;
   64   
   65   import org.mozilla.javascript;
   66   import org.mozilla.javascript.debug;
   67   
   68   import org.apache.bsf;
   69   import org.apache.bsf.util.BSFEngineImpl;
   70   import org.apache.bsf.util.BSFFunctions;
   71   
   72   import java.util.Hashtable;
   73   import org.apache.bsf.debug.jsdi;
   74   
   75   import java.io.Reader;
   76   
   77   /**
   78    * A document cell materializes a known document.
   79    * A document is a container for scripts or functions
   80    * in JavaScript. The document is known as soon as 
   81    * a function or script is compiled in the engine.
   82    * Compilation occurs as a side-effect of evaluating 
   83    * or executing a function or a script.
   84    * 
   85    * Upon the first loading of a function or script of 
   86    * a document, the document becomes known and the debug
   87    * manager is notified of the load. The debug manager
   88    * will in turn notify the engine of all the known 
   89    * breakpoints for that document. 
   90    * 
   91    * When a breakpoint is propagated from the debug manager
   92    * to an engine, the document will be added a breakpoint.
   93    * The document will memorize the breakpoints if their 
   94    * corresponding function or script is not known at that 
   95    * time. If it is known, it is the FnOrScript that will
   96    * memorize the breakpoint. See FnOrScript to see how
   97    * a breakpoint is actually forwarded to the underlying
   98    * Rhino engine.
   99    * 
  100    */
  101   public class DocumentCell {
  102   
  103       RhinoEngineDebugger m_rhinoDebugger;
  104   
  105       String m_docName;
  106       Vector m_fnOrScripts;
  107       Vector m_breakpoints;
  108       private boolean m_entryexit;
  109       private FnOrScript m_lastFnOrScript;
  110   
  111       Hashtable m_functionMap;
  112   
  113       public DocumentCell(RhinoEngineDebugger rhinoDebugger, String name) {
  114           m_rhinoDebugger = rhinoDebugger;
  115           m_docName = name;
  116           m_breakpoints = new Vector();
  117           m_functionMap = new Hashtable();
  118           m_fnOrScripts = new Vector();
  119           m_entryexit = false;
  120           m_lastFnOrScript = null;
  121       }
  122   
  123       public String getName() {
  124           return m_docName;
  125       }
  126   
  127       /**
  128        * Add a breakpoint.
  129        * Two cases exist. 
  130        * If a function or a script (FnOrScript) is known for 
  131        * the given line number, the breakpoint will be remembered 
  132        * by that FnOrScript.
  133        * Otherwise, the breakpoint is memorized at the document 
  134        * level until a function or script is known, that is,
  135        * compiled in our engine.
  136        * 
  137        */
  138       public void addBreakpointAtLine(int brkptId, int lineno) {
  139           Enumeration e;
  140           FnOrScript fnOrScript;
  141   
  142           BreakPoint bp = new BreakPoint(this, brkptId);
  143           bp.setLineNo(lineno);
  144   
  145           // Propagate the breakpoint at document level
  146           // to the level of already known function or 
  147           // scripts. It will propagate it down to the 
  148           // known compilation units.
  149           e = m_fnOrScripts.elements();
  150           while (e.hasMoreElements()) {
  151               fnOrScript = (FnOrScript) e.nextElement();
  152               try {
  153                   if (fnOrScript.contains(bp)) {
  154                       fnOrScript.addBreakpoint(bp);
  155                       return;
  156                   }
  157               } catch (BSFException ex) {
  158               }
  159           }
  160           m_breakpoints.addElement(bp);
  161       }
  162   
  163       /**
  164        * Same as above, except the breakpoint is specified
  165        * at an character offset rather than a line number.
  166        */
  167       public void addBreakpointAtOffset(int brkptId, int offset) {
  168           Enumeration e;
  169           FnOrScript fnOrScript;
  170   
  171           BreakPoint bp = new BreakPoint(this, brkptId);
  172           bp.setOffset(offset);
  173   
  174           e = m_fnOrScripts.elements();
  175           while (e.hasMoreElements()) {
  176               fnOrScript = (FnOrScript) e.nextElement();
  177               try {
  178                   if (fnOrScript.contains(bp)) {
  179                       fnOrScript.addBreakpoint(bp);
  180                       return;
  181                   }
  182               } catch (BSFException ex) {
  183               }
  184           }
  185           m_breakpoints.addElement(bp);
  186       }
  187   
  188       //-----------------------------------------
  189       // Check to see if we have pending breakpoints
  190       // at the document level that belong to this 
  191       // Function or Script.	
  192       private void attachBreakpoints(FnOrScript fnOrScript) {
  193   
  194           Enumeration e;
  195           BreakPoint bp;
  196           Vector toremove = new Vector();
  197           e = m_breakpoints.elements();
  198           while (e.hasMoreElements()) {
  199               bp = (BreakPoint) e.nextElement();
  200               try {
  201                   if (fnOrScript.contains(bp)) {
  202                       // we got a pending breakpoint...
  203                       // add it to the compilation unit and remember it
  204                       // to remove it later.
  205                       fnOrScript.addBreakpoint(bp);
  206                       toremove.addElement(bp);
  207                   }
  208               } catch (BSFException ex) {
  209               }
  210           }
  211           // now that we are doning iterating over breakpoints,
  212           // we can remove all the ones that need to be removed.
  213           e = toremove.elements();
  214           while (e.hasMoreElements()) {
  215               bp = (BreakPoint) e.nextElement();
  216               m_breakpoints.removeElement(bp);
  217           }
  218       }
  219   
  220       public BreakPoint findBreakpointAtLine(int lineno) throws BSFException {
  221           Enumeration e;
  222           BreakPoint bp;
  223           FnOrScript fnOrScript;
  224   
  225           e = m_fnOrScripts.elements();
  226           while (e.hasMoreElements()) {
  227               fnOrScript = (FnOrScript) e.nextElement();
  228               bp = fnOrScript.findBreakpointAtLine(lineno);
  229               if (bp != null)
  230                   return bp;
  231           }
  232           return null;
  233       }
  234   
  235       public BreakPoint findBreakpointAtOffset(int offset) throws BSFException {
  236           Enumeration e;
  237           BreakPoint bp;
  238           FnOrScript fnOrScript;
  239   
  240           e = m_fnOrScripts.elements();
  241           while (e.hasMoreElements()) {
  242               fnOrScript = (FnOrScript) e.nextElement();
  243               bp = fnOrScript.findBreakpointAtOffset(offset);
  244               if (bp != null)
  245                   return bp;
  246           }
  247           return null;
  248       }
  249   
  250       public FnOrScript findFnOrScript(int startLine, int column) {
  251           Enumeration e;
  252           FnOrScript fnOrScript;
  253           e = m_fnOrScripts.elements();
  254           while (e.hasMoreElements()) {
  255               fnOrScript = (FnOrScript) e.nextElement();
  256               if (fnOrScript.m_startLine == startLine)
  257                   if (fnOrScript.m_column == column)
  258                       return fnOrScript;
  259           }
  260           return null;
  261       }
  262   
  263       public FnOrScript findFnOrScriptContaining(int line) {
  264           Enumeration e;
  265           FnOrScript fnOrScript;
  266           e = m_fnOrScripts.elements();
  267           while (e.hasMoreElements()) {
  268               fnOrScript = (FnOrScript) e.nextElement();
  269               if (fnOrScript.m_startLine <= line &&
  270                   (fnOrScript.m_startLine + fnOrScript.m_lineCount) >= line)
  271                   return fnOrScript;
  272           }
  273           return null;
  274       }
  275   
  276       public Enumeration fnOrScripts() {
  277           return m_fnOrScripts.elements();
  278       }
  279   
  280       public FnOrScript registerFnOrScriptLines(Reader reader, 
  281                                                 int startLine, 
  282                                                 int column) 
  283           throws BSFException {
  284   
  285           FnOrScript fnOrScript;
  286           Enumeration e;
  287           // first, search if we already have the script or function.
  288           e = m_fnOrScripts.elements();
  289           while (e.hasMoreElements()) {
  290               fnOrScript = (FnOrScript) e.nextElement();
  291               if (fnOrScript.getFirstLine() == startLine)
  292                   if (fnOrScript.getColumn() == column)
  293                       return fnOrScript;
  294           }
  295           try {
  296   
  297               fnOrScript = new FnOrScript(this);
  298               m_fnOrScripts.addElement(fnOrScript);
  299   
  300               fnOrScript.specifyLinesPos(reader, startLine, column);
  301   
  302               this.attachBreakpoints(fnOrScript);
  303           } catch (IOException ex) {
  304               throw new BSFException(
  305                                      BSFException.REASON_EXECUTION_ERROR,
  306                                      "while registering script or function.",
  307                                      ex);
  308           }
  309           return fnOrScript;
  310       }
  311   
  312       public FnOrScript registerFnOrScriptLines(String source, 
  313                                                 int startLine, 
  314                                                 int column)
  315           throws BSFException {
  316           Reader reader = new StringReader(source);
  317           return registerFnOrScriptLines(reader, startLine, column);
  318       }
  319   
  320       public FnOrScript registerFnOrScriptRange(Reader reader, int offset)
  321           throws BSFException {
  322   
  323           FnOrScript fnOrScript;
  324           try {
  325   
  326               fnOrScript = new FnOrScript(this);
  327               m_fnOrScripts.addElement(fnOrScript);
  328   
  329               fnOrScript.specifyRange(reader, offset);
  330   
  331               this.attachBreakpoints(fnOrScript);
  332           } catch (IOException ex) {
  333               throw new BSFException(
  334                                      BSFException.REASON_EXECUTION_ERROR,
  335                                      "while registering script or function.",
  336                                      ex);
  337           }
  338           return fnOrScript;
  339       }
  340   
  341       public FnOrScript registerFnOrScriptRange(String source, int offset)
  342           throws BSFException {
  343   
  344           Reader reader = new StringReader(source);
  345           return registerFnOrScriptRange(reader, offset);
  346       }
  347   
  348       /**
  349        * Removing a breakpoint.
  350        * Two cases, a breakpoint is only remembered at 
  351        * the document level, it has not been propagated
  352        * to a function or script (FnOrScript). Then, just
  353        * drop it.
  354        * Second case, the breakpoint has been propagated,
  355        * then scan the FnOrScript objects and ask them 
  356        * to drop the breakpoint. 
  357        * Note: only one will have it, see addBreakpoint...
  358        */
  359       public BreakPoint removeBreakpoint(int brkptId) {
  360           Enumeration e;
  361           BreakPoint bp=null;
  362           FnOrScript fnOrScript;
  363   
  364           // search for the breakpoint to remove
  365           // at the document level first.
  366           e = m_breakpoints.elements();
  367           while (e.hasMoreElements()) {
  368               bp = (BreakPoint) e.nextElement();
  369               if (bp.getId()==brkptId) {
  370                   // we found it, just drop it
  371                   // and return.
  372                   m_breakpoints.removeElement(bp);
  373                   return bp;
  374               }
  375           }
  376           // the breakpoint has not been found at 
  377           // the document level. It must have been
  378           // propagated at a FnOrScript level.
  379           e = m_fnOrScripts.elements();
  380           while (e.hasMoreElements()) {
  381               fnOrScript = (FnOrScript) e.nextElement();
  382               bp = fnOrScript.removeBreakpoint(brkptId);
  383               if (null!=bp) break;
  384           }
  385           return bp;
  386       }
  387   
  388       public void setEntryExit(boolean on_value) {
  389           m_entryexit = on_value;
  390       }
  391   
  392       public boolean getEntryExit() {
  393           return m_entryexit;
  394       }
  395   
  396       public void setLastFnOrScript(FnOrScript fnos) {
  397           m_lastFnOrScript = fnos;
  398       }
  399   
  400       public FnOrScript getLastFnOrScript() {
  401           return m_lastFnOrScript;
  402       }
  403   }

Save This Page
Home » bsf-src-2.4.0 » org.apache.bsf.engines.javascript » [javadoc | source]