Source Code Cross Referenced for ContextFactory.java in  » Scripting » rhino » org » mozilla » javascript » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » rhino » org.mozilla.javascript 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
002:         *
003:         * ***** BEGIN LICENSE BLOCK *****
004:         * Version: MPL 1.1/GPL 2.0
005:         *
006:         * The contents of this file are subject to the Mozilla Public License Version
007:         * 1.1 (the "License"); you may not use this file except in compliance with
008:         * the License. You may obtain a copy of the License at
009:         * http://www.mozilla.org/MPL/
010:         *
011:         * Software distributed under the License is distributed on an "AS IS" basis,
012:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013:         * for the specific language governing rights and limitations under the
014:         * License.
015:         *
016:         * The Original Code is Rhino code, released
017:         * May 6, 1999.
018:         *
019:         * The Initial Developer of the Original Code is
020:         * Netscape Communications Corporation.
021:         * Portions created by the Initial Developer are Copyright (C) 1997-1999
022:         * the Initial Developer. All Rights Reserved.
023:         *
024:         * Contributor(s):
025:         *   Igor Bukanov, igor@fastmail.fm
026:         *
027:         * Alternatively, the contents of this file may be used under the terms of
028:         * the GNU General Public License Version 2 or later (the "GPL"), in which
029:         * case the provisions of the GPL are applicable instead of those above. If
030:         * you wish to allow use of your version of this file only under the terms of
031:         * the GPL and not to allow others to use your version of this file under the
032:         * MPL, indicate your decision by deleting the provisions above and replacing
033:         * them with the notice and other provisions required by the GPL. If you do
034:         * not delete the provisions above, a recipient may use your version of this
035:         * file under either the MPL or the GPL.
036:         *
037:         * ***** END LICENSE BLOCK ***** */
038:
039:        // API class
040:        package org.mozilla.javascript;
041:
042:        /**
043:         * Factory class that Rhino runtime uses to create new {@link Context}
044:         * instances.  A <code>ContextFactory</code> can also notify listeners
045:         * about context creation and release.
046:         * <p>
047:         * When the Rhino runtime needs to create new {@link Context} instance during
048:         * execution of {@link Context#enter()} or {@link Context}, it will call
049:         * {@link #makeContext()} of the current global ContextFactory.
050:         * See {@link #getGlobal()} and {@link #initGlobal(ContextFactory)}.
051:         * <p>
052:         * It is also possible to use explicit ContextFactory instances for Context
053:         * creation. This is useful to have a set of independent Rhino runtime
054:         * instances under single JVM. See {@link #call(ContextAction)}.
055:         * <p>
056:         * The following example demonstrates Context customization to terminate
057:         * scripts running more then 10 seconds and to provide better compatibility
058:         * with JavaScript code using MSIE-specific features.
059:         * <pre>
060:         * import org.mozilla.javascript.*;
061:         *
062:         * class MyFactory extends ContextFactory
063:         * {
064:         *
065:         *     // Custom {@link Context} to store execution time.
066:         *     private static class MyContext extends Context
067:         *     {
068:         *         long startTime;
069:         *     }
070:         *
071:         *     static {
072:         *         // Initialize GlobalFactory with custom factory
073:         *         ContextFactory.initGlobal(new MyFactory());
074:         *     }
075:         *
076:         *     // Override {@link #makeContext()}
077:         *     protected Context makeContext()
078:         *     {
079:         *         MyContext cx = new MyContext();
080:         *         // Use pure interpreter mode to allow for
081:         *         // {@link #observeInstructionCount(Context, int)} to work
082:         *         cx.setOptimizationLevel(-1);
083:         *         // Make Rhino runtime to call observeInstructionCount
084:         *         // each 10000 bytecode instructions
085:         *         cx.setInstructionObserverThreshold(10000);
086:         *         return cx;
087:         *     }
088:         *
089:         *     // Override {@link #hasFeature(Context, int)}
090:         *     public boolean hasFeature(Context cx, int featureIndex)
091:         *     {
092:         *         // Turn on maximum compatibility with MSIE scripts
093:         *         switch (featureIndex) {
094:         *             case {@link Context#FEATURE_NON_ECMA_GET_YEAR}:
095:         *                 return true;
096:         *
097:         *             case {@link Context#FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME}:
098:         *                 return true;
099:         *
100:         *             case {@link Context#FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER}:
101:         *                 return true;
102:         *
103:         *             case {@link Context#FEATURE_PARENT_PROTO_PROPERTIES}:
104:         *                 return false;
105:         *         }
106:         *         return super.hasFeature(cx, featureIndex);
107:         *     }
108:         *
109:         *     // Override {@link #observeInstructionCount(Context, int)}
110:         *     protected void observeInstructionCount(Context cx, int instructionCount)
111:         *     {
112:         *         MyContext mcx = (MyContext)cx;
113:         *         long currentTime = System.currentTimeMillis();
114:         *         if (currentTime - mcx.startTime > 10*1000) {
115:         *             // More then 10 seconds from Context creation time:
116:         *             // it is time to stop the script.
117:         *             // Throw Error instance to ensure that script will never
118:         *             // get control back through catch or finally.
119:         *             throw new Error();
120:         *         }
121:         *     }
122:         *
123:         *     // Override {@link #doTopCall(Callable,
124:         Context, Scriptable,
125:         Scriptable, Object[])}
126:         *     protected Object doTopCall(Callable callable,
127:         *                                Context cx, Scriptable scope,
128:         *                                Scriptable thisObj, Object[] args)
129:         *     {
130:         *         MyContext mcx = (MyContext)cx;
131:         *         mcx.startTime = System.currentTimeMillis();
132:         *
133:         *         return super.doTopCall(callable, cx, scope, thisObj, args);
134:         *     }
135:         *
136:         * }
137:         *
138:         * </pre>
139:         */
140:
141:        public class ContextFactory {
142:            private static volatile boolean hasCustomGlobal;
143:            private static ContextFactory global = new ContextFactory();
144:
145:            private volatile boolean sealed;
146:
147:            private final Object listenersLock = new Object();
148:            private volatile Object listeners;
149:            private boolean disabledListening;
150:            private ClassLoader applicationClassLoader;
151:
152:            /**
153:             * Listener of {@link Context} creation and release events.
154:             */
155:            public interface Listener {
156:                /**
157:                 * Notify about newly created {@link Context} object.
158:                 */
159:                public void contextCreated(Context cx);
160:
161:                /**
162:                 * Notify that the specified {@link Context} instance is no longer
163:                 * associated with the current thread.
164:                 */
165:                public void contextReleased(Context cx);
166:            }
167:
168:            /**
169:             * Get global ContextFactory.
170:             *
171:             * @see #hasExplicitGlobal()
172:             * @see #initGlobal(ContextFactory)
173:             */
174:            public static ContextFactory getGlobal() {
175:                return global;
176:            }
177:
178:            /**
179:             * Check if global factory was set.
180:             * Return true to indicate that {@link #initGlobal(ContextFactory)} was
181:             * already called and false to indicate that the global factory was not
182:             * explicitly set.
183:             *
184:             * @see #getGlobal()
185:             * @see #initGlobal(ContextFactory)
186:             */
187:            public static boolean hasExplicitGlobal() {
188:                return hasCustomGlobal;
189:            }
190:
191:            /**
192:             * Set global ContextFactory.
193:             * The method can only be called once.
194:             *
195:             * @see #getGlobal()
196:             * @see #hasExplicitGlobal()
197:             */
198:            public synchronized static void initGlobal(ContextFactory factory) {
199:                if (factory == null) {
200:                    throw new IllegalArgumentException();
201:                }
202:                if (hasCustomGlobal) {
203:                    throw new IllegalStateException();
204:                }
205:                hasCustomGlobal = true;
206:                global = factory;
207:            }
208:
209:            /**
210:             * Create new {@link Context} instance to be associated with the current
211:             * thread.
212:             * This is a callback method used by Rhino to create {@link Context}
213:             * instance when it is necessary to associate one with the current
214:             * execution thread. <tt>makeContext()</tt> is allowed to call
215:             * {@link Context#seal(Object)} on the result to prevent
216:             * {@link Context} changes by hostile scripts or applets.
217:             */
218:            protected Context makeContext() {
219:                return new Context(this );
220:            }
221:
222:            /**
223:             * Implementation of {@link Context#hasFeature(int featureIndex)}.
224:             * This can be used to customize {@link Context} without introducing
225:             * additional subclasses.
226:             */
227:            protected boolean hasFeature(Context cx, int featureIndex) {
228:                int version;
229:                switch (featureIndex) {
230:                case Context.FEATURE_NON_ECMA_GET_YEAR:
231:                    /*
232:                     * During the great date rewrite of 1.3, we tried to track the
233:                     * evolving ECMA standard, which then had a definition of
234:                     * getYear which always subtracted 1900.  Which we
235:                     * implemented, not realizing that it was incompatible with
236:                     * the old behavior...  now, rather than thrash the behavior
237:                     * yet again, we've decided to leave it with the - 1900
238:                     * behavior and point people to the getFullYear method.  But
239:                     * we try to protect existing scripts that have specified a
240:                     * version...
241:                     */
242:                    version = cx.getLanguageVersion();
243:                    return (version == Context.VERSION_1_0
244:                            || version == Context.VERSION_1_1 || version == Context.VERSION_1_2);
245:
246:                case Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME:
247:                    return false;
248:
249:                case Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER:
250:                    return false;
251:
252:                case Context.FEATURE_TO_STRING_AS_SOURCE:
253:                    version = cx.getLanguageVersion();
254:                    return version == Context.VERSION_1_2;
255:
256:                case Context.FEATURE_PARENT_PROTO_PROPERTIES:
257:                    return true;
258:
259:                case Context.FEATURE_E4X:
260:                    version = cx.getLanguageVersion();
261:                    return (version == Context.VERSION_DEFAULT || version >= Context.VERSION_1_6);
262:
263:                case Context.FEATURE_DYNAMIC_SCOPE:
264:                    return false;
265:
266:                case Context.FEATURE_STRICT_VARS:
267:                    return false;
268:
269:                case Context.FEATURE_STRICT_EVAL:
270:                    return false;
271:
272:                case Context.FEATURE_LOCATION_INFORMATION_IN_ERROR:
273:                    return false;
274:
275:                case Context.FEATURE_STRICT_MODE:
276:                    return false;
277:
278:                case Context.FEATURE_WARNING_AS_ERROR:
279:                    return false;
280:
281:                case Context.FEATURE_ENHANCED_JAVA_ACCESS:
282:                    return false;
283:                }
284:                // It is a bug to call the method with unknown featureIndex
285:                throw new IllegalArgumentException(String.valueOf(featureIndex));
286:            }
287:
288:            private boolean isDom3Present() {
289:                Class nodeClass = Kit.classOrNull("org.w3c.dom.Node");
290:                if (nodeClass == null)
291:                    return false;
292:                // Check to see whether DOM3 is present; use a new method defined in
293:                // DOM3 that is vital to our implementation
294:                try {
295:                    nodeClass.getMethod("getUserData",
296:                            new Class[] { String.class });
297:                    return true;
298:                } catch (NoSuchMethodException e) {
299:                    return false;
300:                }
301:            }
302:
303:            /**
304:             * Provides a default
305:             * {@link org.mozilla.javascript.xml.XMLLib.Factory XMLLib.Factory}
306:             * to be used by the <code>Context</code> instances produced by this
307:             * factory. See {@link Context#getE4xImplementationFactory} for details.
308:             * 
309:             * May return null, in which case E4X functionality is not supported in
310:             * Rhino.
311:             * 
312:             * The default implementation now prefers the DOM3 E4X implementation.
313:             */
314:            protected org.mozilla.javascript.xml.XMLLib.Factory getE4xImplementationFactory() {
315:                // Must provide default implementation, rather than abstract method,
316:                // so that past implementors of ContextFactory do not fail at runtime
317:                // upon invocation of this method.
318:                // Note that the default implementation returns null if we
319:                // neither have XMLBeans nor a DOM3 implementation present.
320:
321:                if (isDom3Present()) {
322:                    return org.mozilla.javascript.xml.XMLLib.Factory
323:                            .create("org.mozilla.javascript.xmlimpl.XMLLibImpl");
324:                } else if (Kit.classOrNull("org.apache.xmlbeans.XmlCursor") != null) {
325:                    return org.mozilla.javascript.xml.XMLLib.Factory
326:                            .create("org.mozilla.javascript.xml.impl.xmlbeans.XMLLibImpl");
327:                } else {
328:                    return null;
329:                }
330:            }
331:
332:            /**
333:             * Create class loader for generated classes.
334:             * This method creates an instance of the default implementation
335:             * of {@link GeneratedClassLoader}. Rhino uses this interface to load
336:             * generated JVM classes when no {@link SecurityController}
337:             * is installed.
338:             * Application can override the method to provide custom class loading.
339:             */
340:            protected GeneratedClassLoader createClassLoader(ClassLoader parent) {
341:                return new DefiningClassLoader(parent);
342:            }
343:
344:            /**
345:             * Get ClassLoader to use when searching for Java classes.
346:             * Unless it was explicitly initialized with
347:             * {@link #initApplicationClassLoader(ClassLoader)} the method returns
348:             * null to indicate that Thread.getContextClassLoader() should be used.
349:             */
350:            public final ClassLoader getApplicationClassLoader() {
351:                return applicationClassLoader;
352:            }
353:
354:            /**
355:             * Set explicit class loader to use when searching for Java classes.
356:             *
357:             * @see #getApplicationClassLoader()
358:             */
359:            public final void initApplicationClassLoader(ClassLoader loader) {
360:                if (loader == null)
361:                    throw new IllegalArgumentException("loader is null");
362:                if (!Kit.testIfCanLoadRhinoClasses(loader))
363:                    throw new IllegalArgumentException(
364:                            "Loader can not resolve Rhino classes");
365:
366:                if (this .applicationClassLoader != null)
367:                    throw new IllegalStateException(
368:                            "applicationClassLoader can only be set once");
369:                checkNotSealed();
370:
371:                this .applicationClassLoader = loader;
372:            }
373:
374:            /**
375:             * Execute top call to script or function.
376:             * When the runtime is about to execute a script or function that will
377:             * create the first stack frame with scriptable code, it calls this method
378:             * to perform the real call. In this way execution of any script
379:             * happens inside this function.
380:             */
381:            protected Object doTopCall(Callable callable, Context cx,
382:                    Scriptable scope, Scriptable this Obj, Object[] args) {
383:                return callable.call(cx, scope, this Obj, args);
384:            }
385:
386:            /**
387:             * Implementation of
388:             * {@link Context#observeInstructionCount(int instructionCount)}.
389:             * This can be used to customize {@link Context} without introducing
390:             * additional subclasses.
391:             */
392:            protected void observeInstructionCount(Context cx,
393:                    int instructionCount) {
394:            }
395:
396:            protected void onContextCreated(Context cx) {
397:                Object listeners = this .listeners;
398:                for (int i = 0;; ++i) {
399:                    Listener l = (Listener) Kit.getListener(listeners, i);
400:                    if (l == null)
401:                        break;
402:                    l.contextCreated(cx);
403:                }
404:            }
405:
406:            protected void onContextReleased(Context cx) {
407:                Object listeners = this .listeners;
408:                for (int i = 0;; ++i) {
409:                    Listener l = (Listener) Kit.getListener(listeners, i);
410:                    if (l == null)
411:                        break;
412:                    l.contextReleased(cx);
413:                }
414:            }
415:
416:            public final void addListener(Listener listener) {
417:                checkNotSealed();
418:                synchronized (listenersLock) {
419:                    if (disabledListening) {
420:                        throw new IllegalStateException();
421:                    }
422:                    listeners = Kit.addListener(listeners, listener);
423:                }
424:            }
425:
426:            public final void removeListener(Listener listener) {
427:                checkNotSealed();
428:                synchronized (listenersLock) {
429:                    if (disabledListening) {
430:                        throw new IllegalStateException();
431:                    }
432:                    listeners = Kit.removeListener(listeners, listener);
433:                }
434:            }
435:
436:            /**
437:             * The method is used only to implement
438:             * Context.disableStaticContextListening()
439:             */
440:            final void disableContextListening() {
441:                checkNotSealed();
442:                synchronized (listenersLock) {
443:                    disabledListening = true;
444:                    listeners = null;
445:                }
446:            }
447:
448:            /**
449:             * Checks if this is a sealed ContextFactory.
450:             * @see #seal()
451:             */
452:            public final boolean isSealed() {
453:                return sealed;
454:            }
455:
456:            /**
457:             * Seal this ContextFactory so any attempt to modify it like to add or
458:             * remove its listeners will throw an exception.
459:             * @see #isSealed()
460:             */
461:            public final void seal() {
462:                checkNotSealed();
463:                sealed = true;
464:            }
465:
466:            protected final void checkNotSealed() {
467:                if (sealed)
468:                    throw new IllegalStateException();
469:            }
470:
471:            /**
472:             * Call {@link ContextAction#run(Context cx)}
473:             * using the {@link Context} instance associated with the current thread.
474:             * If no Context is associated with the thread, then
475:             * {@link #makeContext()} will be called to construct
476:             * new Context instance. The instance will be temporary associated
477:             * with the thread during call to {@link ContextAction#run(Context)}.
478:             *
479:             * @see ContextFactory#call(ContextAction)
480:             * @see Context#call(ContextFactory factory, Callable callable,
481:             *                   Scriptable scope, Scriptable thisObj,
482:             *                   Object[] args)
483:             */
484:            public final Object call(ContextAction action) {
485:                return Context.call(this , action);
486:            }
487:
488:            /**
489:             * Get a context associated with the current thread, creating one if need 
490:             * be. The Context stores the execution state of the JavaScript engine, so 
491:             * it is required that the context be entered before execution may begin. 
492:             * Once a thread has entered a Context, then getCurrentContext() may be 
493:             * called to find the context that is associated with the current thread.
494:             * <p>
495:             * Calling <code>enterContext()</code> will return either the Context 
496:             * currently associated with the thread, or will create a new context and 
497:             * associate it with the current thread. Each call to 
498:             * <code>enterContext()</code> must have a matching call to 
499:             * {@link Context#exit()}.
500:             * <pre>
501:             *      Context cx = contextFactory.enterContext();
502:             *      try {
503:             *          ...
504:             *          cx.evaluateString(...);
505:             *      } finally {
506:             *          Context.exit();
507:             *      }
508:             * </pre>
509:             * Instead of using <tt>enterContext()</tt>, <tt>exit()</tt> pair consider 
510:             * using {@link #call(ContextAction)} which guarantees proper association 
511:             * of Context instances with the current thread.
512:             * With this method the above example becomes:
513:             * <pre>
514:             *      ContextFactory.call(new ContextAction() {
515:             *          public Object run(Context cx) {
516:             *              ...
517:             *              cx.evaluateString(...);
518:             *              return null;
519:             *          }
520:             *      });
521:             * </pre>
522:             * @return a Context associated with the current thread
523:             * @see Context#getCurrentContext()
524:             * @see Context#exit()
525:             * @see #call(ContextAction)
526:             */
527:            public Context enterContext() {
528:                return enterContext(null);
529:            }
530:
531:            /**
532:             * @deprecated use {@link #enterContext()} instead
533:             * @return a Context associated with the current thread
534:             */
535:            public final Context enter() {
536:                return enterContext(null);
537:            }
538:
539:            /**
540:             * @deprecated Use {@link Context#exit()} instead.
541:             */
542:            public final void exit() {
543:                Context.exit();
544:            }
545:
546:            /**
547:             * Get a Context associated with the current thread, using the given 
548:             * Context if need be.
549:             * <p>
550:             * The same as <code>enterContext()</code> except that <code>cx</code>
551:             * is associated with the current thread and returned if the current thread
552:             * has no associated context and <code>cx</code> is not associated with any
553:             * other thread.
554:             * @param cx a Context to associate with the thread if possible
555:             * @return a Context associated with the current thread
556:             * @see #enterContext()
557:             * @see #call(ContextAction)
558:             * @throws IllegalStateException if <code>cx</code> is already associated
559:             * with a different thread
560:             */
561:            public final Context enterContext(Context cx) {
562:                return Context.enter(cx, this);
563:            }
564:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.