GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Rubygem
Description: Resource-oriented open source Ruby framework for Web apps.
Homepage: http://rubywaves.com/
Clone URL: git://github.com/dyoder/waves.git
Finished initial implementation of new mappings, including filters, 
resources, the whole shabang.
dyoder (author)
Sun Jun 29 17:22:50 -0700 2008
commit  7e56e842de68e546418c2c01494d1e78c31415a5
tree    444371ceedcf92a46cf208181fb0111ea59a877e
parent  9ca295413e64ca27bcbab2335f558cf2fce72cab
...
10
11
12
 
 
 
13
14
15
...
10
11
12
13
14
15
16
17
18
0
@@ -10,6 +10,9 @@ module Waves
0
         @path = path
0
         @status = status
0
       end
0
+ def message
0
+ "location: #{@path} status: #{@status}"
0
+ end
0
     end
0
 
0
     # The Base dispatcher simply makes it easier to write dispatchers by inheriting
...
36
37
38
39
 
40
41
42
43
44
45
46
 
 
47
48
49
50
 
 
 
51
52
53
54
 
55
56
57
...
36
37
38
 
39
40
 
 
 
 
 
 
41
42
43
44
45
 
46
47
48
49
50
51
 
52
53
54
55
0
@@ -36,22 +36,20 @@ module Waves
0
 
0
         begin
0
 
0
- request.not_found unless mapping[ :action ]
0
+ request.not_found if mapping[ :action ].empty?
0
           mapping[ :before ].each { | action | action.call( request ) }
0
-
0
- begin
0
- response.write( mapping[ :action ].first.call( request ) )
0
- ensure
0
- mapping[ :after ].each { | action | action.call( request ) }
0
- end
0
+ response.write( mapping[ :action ].first.call( request ) )
0
+ mapping[ :after ].each { | action | action.call( request ) }
0
           
0
         rescue Exception => e
0
 
0
- raise e unless Waves.mapping.handle( e )
0
+ Waves::Logger.info e.to_s
0
+ handler = mapping[ :handle ].find { | action | action.exception === e }
0
+ ( handler.call( request ) if handler ) or raise e
0
 
0
         ensure
0
 
0
- mapping[:always].each do | action |
0
+ mapping[ :always ].each do | action |
0
             begin
0
               action.call( request )
0
             rescue Exception => e
...
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
 
 
21
22
23
24
25
26
27
28
 
 
 
 
 
29
30
31
32
33
 
 
 
 
 
 
 
 
 
 
34
35
36
37
 
38
39
40
...
47
48
49
50
 
51
52
 
 
 
53
54
55
...
4
5
6
 
 
7
8
9
10
11
 
 
 
 
 
 
 
12
13
14
15
16
17
18
19
20
 
 
21
22
23
24
25
26
27
28
 
 
29
30
31
32
33
34
35
36
37
38
39
40
41
 
42
43
44
45
...
52
53
54
 
55
56
57
58
59
60
61
62
63
0
@@ -4,37 +4,42 @@ module Waves
0
     
0
     class Action
0
       
0
- # TODO: Make this more generic and able to support Handler (or push add'l code into Handler).
0
- # Should support anonymous blocks (i.e. that don't call a method on Resource), or cases where
0
       # no path was provided. Should also always use :path rather than relying on target (this is
0
       # actually code in patter), and add code for :scheme, :domain, etc. constraints (Constraints).
0
       #
0
       # Can some o the resource determination related code be factored out of there or simplified?
0
       
0
- attr_reader :name, :resource, :pattern, :constraints, :descriptors
0
-
0
- def initialize( options, &block )
0
- @name = name = options[:name]
0
- @pattern = pattern = Pattern.new( options )
0
- @constraints = Constraints.new( options )
0
- @descriptors = Descriptors.new( options )
0
+ def initialize( options )
0
+ @name = name = options[:name] ; @pattern = pattern = Pattern.new( options )
0
+ @constraints = Constraints.new( options ) ; @descriptors = Descriptors.new( options )
0
         if rname = options[ :resource ]
0
           @resource = resource = Waves.application[:resources][ rname ]
0
         else
0
           resource = Waves.application[:resources][ :default ]
0
           @resource = Waves::Resources::Proxy
0
         end
0
- resource.instance_eval { define_method name, &block } if name and block_given?
0
- resource::Paths.instance_eval { define_method( name ) { |*args| generate( options[ :pattern ], args ) } }
0
+ if name
0
+ block = options[:block]
0
+ resource.instance_eval { define_method( name, &block ) } if block
0
+ resource::Paths.instance_eval { define_method( name ) { |*args| generate( options[ :path ], args ) } }
0
+ end
0
       end
0
       
0
       def bind( request )
0
- ( constraints.satisfy?( request ) and
0
- ( params = pattern.match( request ) ) and Binding.new( self, params ) )
0
+ ( @constraints.satisfy?( request ) and
0
+ ( params = @pattern.match( request ) ) and Binding.new( self, params ) )
0
+ end
0
+
0
+ def call( request )
0
+ if @name
0
+ @resource.new( request ).send( @name )
0
+ elsif @block
0
+ @resource.new( request ).instance_eval( &@block )
0
+ end
0
       end
0
 
0
       def threaded?
0
- descriptors.threaded?
0
+ @descriptors.threaded?
0
       end
0
       
0
     end
0
@@ -47,9 +52,12 @@ module Waves
0
       
0
       def call( request )
0
         request.params.merge!( @params )
0
- @action.resource.new( request ).send( @action.name )
0
+ @action.call( request )
0
       end
0
     
0
+ def method_missing(name,*args,&block)
0
+ @action.respond_to?( name ) ? @action.send( name, *args, &block ) : super
0
+ end
0
     end
0
     
0
   end
...
4
5
6
7
8
9
10
11
 
12
13
14
15
16
17
18
19
20
21
22
 
23
24
 
25
26
27
...
4
5
6
 
 
 
 
 
7
8
9
10
11
 
12
13
14
15
16
 
17
18
 
19
20
21
22
0
@@ -4,24 +4,19 @@ module Waves
0
     
0
     class Constraints
0
       
0
- # TODO: Add other header methods here ...
0
- # may include some shortcuts for accessing Rack vars also
0
- METHODS = %w( method accept ).map( &:intern )
0
-
0
- attr_accessor *METHODS
0
+ METHODS = %w( domain scheme method accept ).map( &:intern )
0
       
0
       def initialize( options )
0
         METHODS.each do | method |
0
           instance_variable_set( "@#{method}", options[ method ] ) if options[ method ]
0
- send( "#{method}=", options[ method ] ) if options[ method ]
0
         end
0
       end
0
       
0
       def satisfy?( request )
0
         METHODS.all? do | method |
0
- wanted = self.send( method )
0
+ wanted = instance_variable_get( "@#{method}")
0
           got = request.send( method ) if wanted
0
- wanted == got
0
+ wanted === got
0
         end
0
       end
0
             
...
7
8
9
10
11
 
 
12
 
 
13
14
15
...
7
8
9
 
 
10
11
12
13
14
15
16
17
0
@@ -7,9 +7,11 @@ module Waves
0
       attr_reader :exception
0
       
0
       def initialize( e, options )
0
- @exception = e
0
- super
0
+ @exception = e ; options[:resource] ||= 'error'
0
+ super( options )
0
       end
0
+
0
+ end
0
     
0
   end
0
 
...
5
6
7
8
 
9
10
11
12
 
13
14
15
16
 
 
17
18
19
20
21
22
23
24
25
 
26
27
28
 
29
30
31
32
 
33
34
35
36
 
 
 
 
 
37
38
39
 
 
 
40
41
 
 
42
43
44
45
46
 
47
48
49
50
51
52
53
54
 
55
56
57
...
5
6
7
 
8
9
 
 
 
10
11
12
13
 
14
15
16
17
18
19
20
21
 
 
 
22
23
24
 
25
26
27
28
 
29
30
31
 
 
32
33
34
35
36
37
 
 
38
39
40
41
 
42
43
44
45
46
47
 
48
49
50
51
52
 
 
 
 
53
54
55
56
0
@@ -5,53 +5,52 @@ module Waves
0
     include Functor::Method
0
     
0
     METHODS = %w( get put post delete ).map( &:intern )
0
- RULES = %w( before action after always, handle ).map( &:intern )
0
+ RULES = %w( before action after always handle ).map( &:intern )
0
     
0
- def mappings
0
- @mappings ||= Hash.new { |h,k| h[k] = [] }
0
- end
0
+ def mappings ; @mappings ||= Hash.new { |h,k| h[k] = [] } ; end
0
     
0
     def method_missing( name, *args, &block )
0
       return super unless RULES.include? name
0
- map( name, args, &block )
0
+ args << block if block_given?
0
+ mappings[ name ] << map( *args )
0
     end
0
     
0
     def with( options, &block )
0
       @options = options; yield if block_given? ; @options = nil
0
     end
0
 
0
- functor( :map, String, Array, Proc ) { | rule, args, block | map( *( args << block ) ) }
0
- functor( :map, String, Array ) { | rule, args | mappings[ rule ] << map( *args ) }
0
- functor( :map, String, Hash, Proc ) do | name, options, block |
0
+ functor( :map, Symbol, Hash, Proc ) do | name, options, block |
0
       options[:name] = name ; options[:block] = block ; map( options )
0
     end
0
- functor( :map, String, Hash ) { | name, options | options[:name] = name ; map( options ) }
0
+ functor( :map, Symbol, Hash ) { | name, options | options[:name] = name ; map( options ) }
0
     functor( :map, Hash ) do | options |
0
       options = ( @options || {} ).merge( options )
0
       options[ :method ] = method = METHODS.find { |method| options[ method ] }
0
- options[ :pattern ] = options[ method ]
0
+ options[ :path ] = options[ method ]
0
       Action.new( options )
0
     end
0
- functor( :map, Exception, String, Hash, Proc ) do | e, name, options, block |
0
- options[:name] = name ; map( e, options, block )
0
+
0
+ exception = lambda { | klass | klass.ancestors.include?( Exception ) if klass.is_a?( Class ) }
0
+
0
+ functor( :map, exception, String, Hash, Proc ) do | e, name, options, block |
0
+ options[ :name ] = name ; map( e, options, block )
0
     end
0
- functor( :map, Exception, Hash, Proc ) do | e, options, block |
0
- options[:block] = block ; map( e, options )
0
+
0
+ functor( :map, exception, Hash, Proc ) do | e, options, block |
0
+ options[ :block ] = block ; map( e, options )
0
     end
0
- functor( :map, Exception, Hash ) { | options, block | Handler.new( e, options ) }
0
+ functor( :map, exception, Proc ) { | e, block | map( e, { :block => block } ) }
0
+ functor( :map, exception, Hash ) { | e, options | Handler.new( e, options ) }
0
         
0
     def []( request )
0
       returning Hash.new { |h,k| h[k] = [] } do | results |
0
         RULES.each do | rule |
0
- mappings[ rule ].each { | action | binding = action.bind( request ) and results[ rule ].push( binding ) }
0
+ mappings[ rule ].each { | action | ( binding = action.bind( request ) ) and results[ rule ].push( binding ) }
0
         end
0
       end
0
     end
0
 
0
- private
0
-
0
- def normalize( options )
0
- end
0
+ private :map
0
     
0
   end
0
 
...
18
19
20
21
 
22
23
24
...
18
19
20
 
21
22
23
24
0
@@ -18,7 +18,7 @@ module Waves
0
       functor( :generate, Symbol, Symbol ) { | key, val | val.to_s }
0
       functor( :generate, Symbol, String ) { | key, val | val }
0
 
0
- functor( :generate, Regexp, Array ) { | key, vals | nil }
0
+ functor( :generate, Regexp, Array ) { | key, vals | generate( key, vals.shift ) }
0
 
0
       functor( :generate, Hash, Array ) { | h, vals | vals.shift or h.values.first }
0
       
...
8
9
10
11
12
13
14
 
15
16
 
 
17
18
19
20
21
 
22
23
24
...
8
9
10
 
 
 
 
11
12
 
13
14
15
16
 
 
 
17
18
19
20
0
@@ -8,17 +8,13 @@ module Waves
0
       
0
       include Functor::Method
0
       
0
- def initialize( options )
0
- @target = options[ :target ]
0
- @pattern = options[ :pattern ]
0
- end
0
+ def initialize( options ) ; @pattern = options[ :path ] ; end
0
       
0
- functor( :match, Waves::Request ) { | request | match( @pattern, request.send( @target ) ) }
0
+ functor( :match, Waves::Request ) { | request | match( @pattern, request.path ) }
0
+ functor( :match, nil, String ) { |patern, path| {} }
0
       functor( :match, Array, String ) { | pattern, path | match( pattern, path.split('/')[1..-1] ) }
0
       functor( :match, Array, Array ) do | wants, gots |
0
- r = {}; matches = wants.all? do | want |
0
- match( r, want, gots.shift )
0
- end
0
+ r = {}; matches = wants.all? { | want | match( r, want, gots.shift ) }
0
         r if matches and gots.empty?
0
       end
0
       functor( :match, Hash, String, String ) { | r, want, got | got if want == got }
...
7
8
9
 
10
11
12
...
22
23
24
25
26
27
28
29
...
54
55
56
 
57
58
59
...
7
8
9
10
11
12
13
...
23
24
25
 
 
26
27
28
...
53
54
55
56
57
58
59
0
@@ -7,6 +7,7 @@ require 'live_console'
0
 
0
 gem 'dyoder-autocode'
0
 require 'autocode'
0
+gem 'dyoder-functor'
0
 require 'functor'
0
 
0
 # for mimetypes only or when using as default handler
0
@@ -22,8 +23,6 @@ require 'benchmark'
0
 # require 'memcache'
0
 require 'base64'
0
 
0
-require 'functor'
0
-
0
 # selected project-specific extensions
0
 require 'utilities/module'
0
 require 'utilities/string'
0
@@ -54,6 +53,7 @@ require 'runtime/configuration'
0
 # waves URI mapping
0
 require 'mapping/mapping'
0
 require 'mapping/action'
0
+require 'mapping/handler'
0
 require 'mapping/pattern'
0
 require 'mapping/constraints'
0
 require 'mapping/descriptors'
...
7
8
9
10
 
11
12
13
14
15
16
17
18
19
 
 
 
 
 
20
21
22
...
7
8
9
 
10
11
12
13
14
 
 
 
 
 
15
16
17
18
19
20
21
22
0
@@ -7,16 +7,16 @@ module Blog
0
       extend Waves::Mapping
0
       
0
       # specific to comments - on create redirect to the entry, not the comment itself
0
- path :create, :resource => :comment, :post => [ '/comments' ] do
0
+ action :create, :resource => :comment, :post => [ '/comments' ] do
0
         redirect( Blog::Resources::Entries.paths.read( action( :create ).entry.name ) )
0
       end
0
       
0
       # defaults for generic resources
0
- path( :list, :get => [ :resources ] ) { action( :all ) and render( :list ) }
0
- path( :create, :post => [ :resources ] ) { redirect( paths.read( action( :create ).name, 'edit' ) ) }
0
- path( :read, :get => [ :resource, :name, { :mode => 'show' } ] ) { action( :find, name ) and render( mode ) }
0
- path( :update, :put => [ :resource, :name ] ) { action( :update, name ) and redirect( paths.read( name ) ) }
0
- path( :delete, :delete => [ :resource, :name ] ) { action( :delete, name ) }
0
+ action( :list, :get => [ :resources ] ) { action( :all ) and render( :list ) }
0
+ action( :create, :post => [ :resources ] ) { redirect( paths.read( action( :create ).name, 'edit' ) ) }
0
+ action( :read, :get => [ :resource, :name, { :mode => 'show' } ] ) { action( :find, name ) and render( mode ) }
0
+ action( :update, :put => [ :resource, :name ] ) { action( :update, name ) and redirect( paths.read( name ) ) }
0
+ action( :delete, :delete => [ :resource, :name ] ) { action( :delete, name ) }
0
       
0
     end
0
 

Comments

    No one has commented yet.