/**
 * 
 */
package org.mozilla.javascript.tests;

import junit.framework.TestCase;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ClassShutter;
import org.mozilla.javascript.RhinoException;
import org.mozilla.javascript.EvaluatorException;

/**
 * @author Norris Boyd
 */
public class ClassShutterExceptionTest extends TestCase {

    /**
     * Define a ClassShutter that prevents access to all Java classes.
     */
    static class OpaqueShutter implements ClassShutter {
        public boolean visibleToScripts(String name) {
            System.err.println("OpaqueShutter asked for " + name);
            return false;
        }
    }

    public void testClassShutterException() {
        Context cx = Context.enter();
        try {
            Scriptable globalScope = cx.initStandardObjects();
            cx.setClassShutter(new OpaqueShutter());
            cx.evaluateString(globalScope,
                    "java.lang.System.out.println('hi');",
                    "test source", 1, null);
            fail();
        } catch (RhinoException e) {
            // OpaqueShutter should prevent access to java.lang...
            return;
        } finally {
            Context.exit();
        }
    }

    public void testThrowingException() {
        Context cx = Context.enter();
        try {
            Scriptable globalScope = cx.initStandardObjects();
            cx.setClassShutter(new OpaqueShutter());
            // JavaScript exceptions with no reference to Java
            // should not be affected by the ClassShutter
            cx.evaluateString(globalScope,
                    "try { throw 3; } catch (e) { }",
                    "test source", 1, null);
        } finally {
            Context.exit();
        }
    }

    public void testThrowingEcmaError() {
        Context cx = Context.enter();
        try {
            Scriptable globalScope = cx.initStandardObjects();
            cx.setClassShutter(new OpaqueShutter());
            // JavaScript exceptions with no reference to Java
            // should not be affected by the ClassShutter
            cx.evaluateString(globalScope,
                    "friggin' syntax error!",
                    "test source", 1, null);
            fail("Should have thrown an exception");
        } catch (EvaluatorException e) {
            // should have thrown an exception for syntax error
        } finally {
            Context.exit();
        }
    }

    public void testThrowingEvaluatorException() {
        Context cx = Context.enter();
        try {
            Scriptable globalScope = cx.initStandardObjects();
            cx.setClassShutter(new OpaqueShutter());
            // JavaScript exceptions with no reference to Java
            // should not be affected by the ClassShutter
            cx.evaluateString(globalScope,
                    "try { eval('for;if;else'); } catch (e) { }",
                    "test source", 1, null);
        } finally {
            Context.exit();
        }
    }
 }

@@ -388,16 +388,82 @@
 stCase %7B
+%0A    private static Context.ClassShutterSetter classShutterSetter;
 %0A%0A    /*
@@ -659,75 +659,8 @@
 ) %7B%0A
-            System.err.println(%22OpaqueShutter asked for %22 + name);%0A
     
@@ -689,32 +689,36 @@
         %7D%0A    %7D%0A
+    
 %0A    public void
@@ -722,34 +722,28 @@
 oid 
-testClassShutterException(
+helper(String source
 ) %7B%0A
@@ -772,32 +772,104 @@
 ontext.enter();%0A
+        Context.ClassShutterSetter setter = cx.getClassShutterSetter();%0A
         try %7B%0A  
@@ -945,150 +945,377 @@
     
-cx.setClassShutter(new OpaqueShutter());%0A            cx.evaluateString(globalScope,%0A                    %22java.lang.System.out.println('hi');%22,
+if (setter == null) %7B%0A                setter = classShutterSetter;%0A            %7D else %7B%0A                classShutterSetter = setter;%0A            %7D%0A            setter.setClassShutter(new OpaqueShutter());%0A            cx.evaluateString(globalScope, source, %22test source%22, 1, null);%0A        %7D finally %7B%0A            setter.setClassShutter(null);%0A            Context.exit();
 %0A   
@@ -1323,42 +1323,137 @@
     
+%7D%0A
     
+%7D%0A
     
+%0A
     
-%22test source%22, 1, null
+public void testClassShutterException() %7B%0A        try %7B%0A            helper(%22java.lang.System.out.println('hi');%22
 );%0A 
@@ -1599,56 +1599,8 @@
 rn;%0A
-        %7D finally %7B%0A            Context.exit();%0A
     
@@ -1658,180 +1658,8 @@
 ) %7B%0A
-        Context cx = Context.enter();%0A        try %7B%0A            Scriptable globalScope = cx.initStandardObjects();%0A            cx.setClassShutter(new OpaqueShutter());%0A    
     
@@ -1713,36 +1713,32 @@
 to Java%0A        
-    
 // should not be
@@ -1779,416 +1779,112 @@
     
-    
-cx.evaluateString(globalScope,%0A                    %22try %7B throw 3; %7D catch (e) %7B %7D%22,%0A                    %22test source%22, 1, null);%0A        %7D finally %7B%0A            Context.exit();%0A        %7D%0A    %7D%0A%0A    public void testThrowingEcmaError() %7B%0A        Context cx = Context.enter();%0A        try %7B%0A            Scriptable globalScope = cx.initStandardObjects();%0A            cx.setClassShutter(new OpaqueShutter());
+helper(%22try %7B throw 3; %7D catch (e) %7B %7D%22);%0A    %7D%0A%0A    public void testThrowingEcmaError() %7B%0A        try %7B
 %0A   
@@ -2017,127 +2017,39 @@
     
-cx.evaluateString(globalScope,%0A                    %22friggin' syntax error!%22,%0A                    %22test source%22, 1, null
+helper(%22friggin' syntax error!%22
 );%0A 
@@ -2209,56 +2209,8 @@
 ror%0A
-        %7D finally %7B%0A            Context.exit();%0A
     
@@ -2285,500 +2285,186 @@
     
-Context cx = Context.enter();%0A        try %7B%0A            Scriptable globalScope = cx.initStandardObjects();%0A            cx.setClassShutter(new OpaqueShutter());%0A            // JavaScript exceptions with no reference to Java%0A            // should not be affected by the ClassShutter%0A            cx.evaluateString(globalScope,%0A                    %22try %7B eval('for;if;else'); %7D catch (e) %7B %7D%22,%0A                    %22test source%22, 1, null);%0A        %7D finally %7B%0A            Context.exit();%0A        %7D
+    // JavaScript exceptions with no reference to Java%0A            // should not be affected by the ClassShutter%0A            helper(%22try %7B eval('for;if;else'); %7D catch (e) %7B %7D%22);
 %0A   

Clean up test to handle multiple invocations