- Revision
- 312
- Author
- mward
- Date
- 2007-09-14 07:17:25 -0500 (Fri, 14 Sep 2007)
Log Message
JRuby's RaiseException from a Ruby controller will throw a MethodInvocationException (which returns a 500 error). Update the WaffleContext to ensure that all keys are Strings ... this is needed because ServletRequest, Session and ServletContext's attribute methods expect Strings
Modified Paths
- trunk/core/src/main/java/org/codehaus/waffle/action/InterceptingActionMethodExecutor.java
- trunk/core/src/main/java/org/codehaus/waffle/controller/RubyController.java
- trunk/core/src/main/java/org/codehaus/waffle/servlet/WaffleServlet.java
- trunk/core/src/main/ruby/org/codehaus/waffle/waffle.rb
- trunk/core/src/test/specs/org/codehaus/waffle/servlet/waffle_spec.rb
- trunk/examples/jruby-example/src/main/ruby/foo_bar.rb
Diff
Modified: trunk/core/src/main/java/org/codehaus/waffle/action/InterceptingActionMethodExecutor.java (311 => 312)
--- trunk/core/src/main/java/org/codehaus/waffle/action/InterceptingActionMethodExecutor.java 2007-09-12 04:33:37 UTC (rev 311) +++ trunk/core/src/main/java/org/codehaus/waffle/action/InterceptingActionMethodExecutor.java 2007-09-14 12:17:25 UTC (rev 312) @@ -44,8 +44,14 @@ } catch (IllegalAccessException e) { throw new MethodInvocationException(e.getMessage(), e); // todo (mward): lets make sure we don't reveal too much information } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + + // MethodInvocationException should be re-thrown + if(cause instanceof MethodInvocationException) { + throw (MethodInvocationException) cause; + } // set the cause of the exception as the return value - actionMethodResponse.setReturnValue(e.getCause()); + actionMethodResponse.setReturnValue(cause); } }
Modified: trunk/core/src/main/java/org/codehaus/waffle/controller/RubyController.java (311 => 312)
--- trunk/core/src/main/java/org/codehaus/waffle/controller/RubyController.java 2007-09-12 04:33:37 UTC (rev 311) +++ trunk/core/src/main/java/org/codehaus/waffle/controller/RubyController.java 2007-09-14 12:17:25 UTC (rev 312) @@ -1,6 +1,8 @@ package org.codehaus.waffle.controller; +import org.codehaus.waffle.action.MethodInvocationException; import org.jruby.Ruby; +import org.jruby.exceptions.RaiseException; import org.jruby.javasupport.JavaEmbedUtils; import org.jruby.javasupport.JavaUtil; import org.jruby.runtime.builtin.IRubyObject; @@ -48,9 +50,13 @@ arguments.add(JavaEmbedUtils.javaToRuby(runtime, iterator.next())); } - result = rubyObject.callMethod(runtime.getCurrentContext(), - methodName, - arguments.toArray(new IRubyObject[arguments.size()])); + try { + result = rubyObject.callMethod(runtime.getCurrentContext(), + methodName, + arguments.toArray(new IRubyObject[arguments.size()])); + } catch (RaiseException e) { + throw new MethodInvocationException(e.getException().message.toString()); + } } return JavaUtil.convertRubyToJava(result);
Modified: trunk/core/src/main/java/org/codehaus/waffle/servlet/WaffleServlet.java (311 => 312)
--- trunk/core/src/main/java/org/codehaus/waffle/servlet/WaffleServlet.java 2007-09-12 04:33:37 UTC (rev 311) +++ trunk/core/src/main/java/org/codehaus/waffle/servlet/WaffleServlet.java 2007-09-14 12:17:25 UTC (rev 312) @@ -146,7 +146,7 @@ requestAttributeBinder.bind(request, controllerDefinition.getController()); actionMethodResponseHandler.handle(request, response, actionMethodResponse); } catch (MethodInvocationException e) { - log(e.getMessage()); + log("ERROR: " + e.getMessage()); if (methodInvocationErrorPage != null && !methodInvocationErrorPage.equals(EMPTY)) { response.sendRedirect(methodInvocationErrorPage); } else {
Modified: trunk/core/src/main/ruby/org/codehaus/waffle/waffle.rb (311 => 312)
--- trunk/core/src/main/ruby/org/codehaus/waffle/waffle.rb 2007-09-12 04:33:37 UTC (rev 311) +++ trunk/core/src/main/ruby/org/codehaus/waffle/waffle.rb 2007-09-14 12:17:25 UTC (rev 312) @@ -2,6 +2,7 @@ include_class 'org.codehaus.waffle.view.View' include_class 'org.codehaus.waffle.view.RedirectView' +include_class 'org.codehaus.waffle.action.MethodInvocationException' # TODO all of this code needs ruby tests! module Waffle @@ -59,11 +60,16 @@ end def store(key, value, skip=false) + key = key.to_s # Must be a String @__context.set_attribute(key, value) unless skip # add to delegate super(key, value) end + def [](key) + m = Hash.instance_method(:[]).bind(self).call(key.to_s) + end + def []=(key, value) store(key, value) end @@ -81,6 +87,7 @@ module Controller attr_reader :parameters, :request, :response, :session, :servlet_context, :errors alias_method :params, :parameters + alias_method :application, :servlet_context def __set_all_contexts(request, response) @request = WebContext.new(request) @@ -118,9 +125,9 @@ end def method_missing(symbol, *args) - if symbol.to_s =~ /^find_/ # todo: I don't like "find_" for this ... sounds to model-ish + if symbol.to_s =~ /^locate_/ key = symbol.to_s - key = key[5..key.length] + key = key[7..key.length] component = @__pico_container.getComponentInstance(key) return component unless component.nil?
Modified: trunk/core/src/test/specs/org/codehaus/waffle/servlet/waffle_spec.rb (311 => 312)
--- trunk/core/src/test/specs/org/codehaus/waffle/servlet/waffle_spec.rb 2007-09-12 04:33:37 UTC (rev 311) +++ trunk/core/src/test/specs/org/codehaus/waffle/servlet/waffle_spec.rb 2007-09-14 12:17:25 UTC (rev 312) @@ -64,9 +64,33 @@ waffle_context = Waffle::WebContext.new(original_context) waffle_context.include?('foo').should == true - waffle_context.include?(:bar).should == true + waffle_context.include?(:foo).should == false + waffle_context.include?('bar').should == true + waffle_context.include?(:bar).should == false end + it "should store all keys as Strings" do + table = Hashtable.new # Using Hashtable because we need an enumerator for testing + original_context = mock('original context') + original_context.should_receive(:get_attribute_names).and_return(table.keys) + original_context.should_receive(:set_attribute).with('foo', 'bar') # saved as string + + waffle_context = Waffle::WebContext.new(original_context) + waffle_context[:foo] = 'bar' # key is symbol + end + + it "should retrieve values by converting key to string" do + table = Hashtable.new # Using Hashtable because we need an enumerator for testing + original_context = mock('original context') + original_context.should_receive(:get_attribute_names).and_return(table.keys) + original_context.should_receive(:set_attribute).with('foo', 'bar') + + waffle_context = Waffle::WebContext.new(original_context) + waffle_context['foo'] = 'bar' + + waffle_context[:foo].should == 'bar' # search with symbol should still retreive value + end + it "should delegate method calls to the underlying instance when method is missing" do context = mock('the mock') context.should_receive(:get_attribute_names).and_return(OpenStruct.new) @@ -143,4 +167,15 @@ controller.locate('foobar') end -end \ No newline at end of file + it "should handle convention to locate components (i.e. prefix with 'locate_')" do + controller = Object.new + controller.send(:extend, Waffle::Controller) + + pico = mock('pico') + pico.should_receive(:getComponentInstance).with('foobar').and_return("the component") + controller.__pico_container = pico + + controller.locate_foobar.should == "the component" + end + +end
Modified: trunk/examples/jruby-example/src/main/ruby/foo_bar.rb (311 => 312)
--- trunk/examples/jruby-example/src/main/ruby/foo_bar.rb 2007-09-12 04:33:37 UTC (rev 311) +++ trunk/examples/jruby-example/src/main/ruby/foo_bar.rb 2007-09-14 12:17:25 UTC (rev 312) @@ -14,17 +14,19 @@ end def index_two - request['foo'] = 'bar' + request[:foo] = 'bar' session['bar'] = 'foo' session['baz'] = 'foo' + application[:name] = 'Chicago' p session %{ HELLO WORLD from the index method - look up from pico: #{find_chicago} parameters: #{parameters} request: #{request} session: #{session} + application: #{application} + name: #{name} servlet_context: #{servlet_context} #{session['waffle.session.container']} @@ -36,7 +38,7 @@ component: #{locate(org.codehaus.waffle.example.jruby.dao.PersonDAO)} #{cls = Java::JavaClass.for_name('java.util.Vector')} - #{locate(Java::JavaClass.for_name('java.util.List'))} + #{locate(Java::JavaClass.for_name('java.util.List'))} } end
To unsubscribe from this list please visit:
