KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > bsf > engines > javascript > DocumentCell


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 JavaDoc;
59 import java.io.InputStream JavaDoc;
60 import java.io.IOException JavaDoc;
61 import java.lang.reflect.InvocationTargetException JavaDoc;
62 import java.util.Vector JavaDoc;
63 import java.util.Enumeration JavaDoc;
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 JavaDoc;
73 import org.apache.bsf.debug.jsdi.*;
74
75 import java.io.Reader JavaDoc;
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 JavaDoc m_docName;
106     Vector JavaDoc m_fnOrScripts;
107     Vector JavaDoc m_breakpoints;
108     private boolean m_entryexit;
109     private FnOrScript m_lastFnOrScript;
110
111     Hashtable JavaDoc m_functionMap;
112
113     public DocumentCell(RhinoEngineDebugger rhinoDebugger, String JavaDoc name) {
114         m_rhinoDebugger = rhinoDebugger;
115         m_docName = name;
116         m_breakpoints = new Vector JavaDoc();
117         m_functionMap = new Hashtable JavaDoc();
118         m_fnOrScripts = new Vector JavaDoc();
119         m_entryexit = false;
120         m_lastFnOrScript = null;
121     }
122
123     public String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc e;
195         BreakPoint bp;
196         Vector JavaDoc toremove = new Vector JavaDoc();
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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc fnOrScripts() {
277         return m_fnOrScripts.elements();
278     }
279
280     public FnOrScript registerFnOrScriptLines(Reader JavaDoc reader,
281                                               int startLine,
282                                               int column)
283         throws BSFException {
284
285         FnOrScript fnOrScript;
286         Enumeration JavaDoc 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 JavaDoc 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 JavaDoc source,
313                                               int startLine,
314                                               int column)
315         throws BSFException {
316         Reader JavaDoc reader = new StringReader JavaDoc(source);
317         return registerFnOrScriptLines(reader, startLine, column);
318     }
319
320     public FnOrScript registerFnOrScriptRange(Reader JavaDoc 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 JavaDoc 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 JavaDoc source, int offset)
342         throws BSFException {
343
344         Reader JavaDoc reader = new StringReader JavaDoc(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 JavaDoc 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 }
404
Popular Tags