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
Code complete on initial version of resource-based mappings.
dyoder (author)
Sun Jun 08 23:08:27 -0700 2008
commit  03d2de42ed9924e3a9f4c52163c0482d55e4409a
tree    9454861e673c9ba3b5415c5af6432cb9aff0c903
parent  ca8036147ed767528e0f3ee0e76bd92f021ac563
...
157
158
159
160
 
 
161
162
163
 
164
165
...
157
158
159
 
160
161
162
 
 
163
164
165
0
@@ -157,9 +157,9 @@ module Waves
0
 
0
     end
0
 
0
- end
0
+ # :)
0
+ const_set( :Base, Class.new ).module_eval { include Mixin }
0
 
0
- # :)
0
- const_set( :Base, Class.new ).module_eval { include Mixin }
0
+ end
0
 
0
 end
...
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
58
59
 
 
 
 
60
61
62
 
 
 
 
63
64
 
 
65
66
 
67
68
69
...
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
58
59
60
0
@@ -32,38 +32,29 @@ module Waves
0
         Waves::Application.instance.reload if Waves::Application.instance.debug?
0
         response.content_type = Waves::Application.instance.config.mime_types[ request.path ] || 'text/html'
0
 
0
- mapping = Waves::Application.instance.mapping[ request ]
0
+ mapping = Waves.mapping[ request ]
0
 
0
         begin
0
 
0
- request.not_found unless mapping[:action]
0
-
0
- mapping[:before].each do | block, args |
0
- ResponseProxy.new(request).instance_exec(*args,&block)
0
- end
0
-
0
- block, args = mapping[:action]
0
- response.write( ResponseProxy.new(request).instance_exec(*args, &block) )
0
-
0
- mapping[:after].each do | block, args |
0
- ResponseProxy.new(request).instance_exec(*args,&block)
0
- end
0
-
0
- rescue Exception => e
0
+ request.not_found unless mapping[ :action ]
0
+ mapping[ :before ].each { | action | action.call( request ) }
0
           
0
- handler = mapping[:handlers].detect do | exception, block, args |
0
- e.is_a? exception
0
- end
0
- if handler
0
- ResponseProxy.new(request).instance_exec(*handler[2], &handler[1])
0
- else
0
+ begin
0
+ response.write( mapping[ :action ].first.call( request ) )
0
+ rescue Exception => e
0
+ mapping[ :after ].each { | action | action.call( request ) }
0
             raise e
0
           end
0
           
0
+ rescue Exception => e
0
+
0
+ raise e unless Waves.mapping.handle( e )
0
+
0
         ensure
0
- mapping[:always].each do | block, args |
0
+
0
+ mapping[:always].each do | action |
0
             begin
0
- ResponseProxy.new(request).instance_exec(*args,&block)
0
+ action.call( request )
0
             rescue Exception => e
0
               Waves::Logger.info e.to_s
0
             end
...
6
7
8
 
9
10
11
...
20
21
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
24
25
...
6
7
8
9
10
11
12
...
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
0
@@ -6,6 +6,7 @@ module Waves
0
         def app.config ; Waves.config ; end
0
         def app.configurations ; self::Configurations ; end
0
         def app.paths ; configurations::Mapping.named; end
0
+ def app.resources ; self::Resources ; end
0
         
0
         app.instance_eval do
0
 
0
@@ -20,6 +21,23 @@ module Waves
0
               extend Waves::Mapping
0
             end
0
           end
0
+
0
+ auto_create_module( :Resources ) do
0
+ include AutoCode
0
+ auto_create_class true, Waves::Resources::Base
0
+ # this should probably be refactored into a separate layer
0
+ auto_eval do
0
+ def resource ; self.class.name ; end
0
+ def resources ; resource.plural ; end
0
+ def controller ; @controller ||= controllers[ resource ].process( @request ) { self } ; end
0
+ def view ; @view ||= views[ resource ].process( @request ) { self } ; end
0
+ def render( method ) ; view.send( method, ( @data.kind_of? Enumerable ? resources : resource ) => @data ) ; end
0
+ def redirect( path ) ; request.redirect( path ) ; end
0
+ def method_missing( name, *args, &block) ; @data = controller.send( name, *args, &block ) ; end
0
+ # have to define this explicitly for now because for some reason sequel defines it on Object ...
0
+ def all ; method_missing( :all ) ; end
0
+ end
0
+ end
0
 
0
         end
0
       end
...
11
12
13
14
 
15
16
17
 
 
 
 
18
19
 
20
21
22
23
 
 
24
25
26
...
28
29
30
 
 
 
 
 
 
 
 
 
 
 
31
32
33
...
11
12
13
 
14
15
16
17
18
19
20
21
22
 
23
24
25
 
 
26
27
28
29
30
...
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
0
@@ -11,16 +11,20 @@ module Waves
0
         pattern = Pattern.new( options )
0
         matcher = Constraints.new( options )
0
         descriptors = Descriptors.new( options )
0
- resource = options[:resource] or Class.new( Waves::Resources::Base )
0
+ resource = Waves.application[:resources][ options[:resource] ]
0
         resource.instance_eval{ define_method n, &block } if block_given?
0
       end
0
       
0
+ # how / when can i take the results of the pattern match
0
+ # and merge them with the request params ... can't do it here
0
+ # because a number of actions may be run, but I can't store
0
+ # it as state because actions are shared between requests
0
       def call?( request )
0
- constraints.satisfy?( request ) and @matches = pattern.match( request )
0
+ constraints.satisfy?( request ) and pattern.match( request )
0
       end
0
       
0
- def call( request, *args )
0
- resource.send( name, *@matches )
0
+ def call( request )
0
+ resource.new( request ).send( name )
0
       end
0
       
0
       def method_missing( name, *args )
0
@@ -28,6 +32,17 @@ module Waves
0
       end
0
       
0
     end
0
+
0
+ class Binding
0
+
0
+ def initialize( action, params )
0
+ @action = action ; @params = params
0
+ end
0
+
0
+ def call( request )
0
+ request.params.merge!( @params )
0
+ @action.call( request )
0
+ end
0
 
0
   end
0
 
...
3
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
...
38
39
40
41
42
43
44
...
3
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
46
47
48
49
50
...
53
54
55
 
56
57
58
0
@@ -3,33 +3,48 @@ module Waves
0
   module Mapping
0
     
0
     METHODS = %w( get put post delete ).map( &:intern )
0
+ RULES = %w( before action after always ).map( &:intern )
0
     
0
- def method_missing(name,*args,&block)
0
+ def method_missing( name, *args, &block )
0
       mappings[ name ].push( map( *args, &block ) )
0
     end
0
     
0
+ def wrap( name, *args, &block )
0
+ before( name, *args, &block ) ; after( name, *args, &block )
0
+ end
0
+
0
     def with( options, &block )
0
       @options = options; yield if block_given? ; @options = nil
0
     end
0
 
0
     def path( name, options = {}, &block )
0
- map( options.merge!( :name => name, :target = :path ), &block )
0
+ mappings[ :action ] = map( options.merge!( :name => name, :target => :path ), &block )
0
     end
0
     
0
     def url( name, options = {}, &block )
0
- map( options.merge!( :name => name, :target = :url ), &block )
0
+ mappings[ :action ] = map( options.merge!( :name => name, :target => :url ), &block )
0
     end
0
     
0
     def map( *args, &block )
0
- options = ( @options || {} ).merge( normalize( *args ).merge( :lambda => block ) )
0
- METHODS.each do |method|
0
- if options[ method ]
0
- options.merge!( :pattern => options[ method ], :method => method )
0
- options[ :target ] ||= :path
0
+ options = ( @options || {} ).merge( normalize( *args ) )
0
+ options[ :target ] ||= :path
0
+ options[ :method ] = method = METHODS.find { |method| options[ method ] }
0
+ options[ :pattern ] = options[ method ]
0
+ Action.new( options, &block )
0
+ end
0
+
0
+ def []( request )
0
+ results = {} ; RULES.each do | rule |
0
+ results[ rule ] = mappings[ rule ].select do | action |
0
+ ( params = action.call?( request ) ) and Action::Binding.new( action, params )
0
         end
0
       end
0
- Action.new( options )
0
- end
0
+ return results
0
+ end
0
+
0
+ private
0
+
0
+ include Functor::Method
0
     
0
     functor( :normalize, Symbol, Hash ) { | name, options | options.merge!( :name => name ) }
0
     functor( :normalize, String, Hash ) { | pattern, options | options.merge!( :pattern => pattern ) }
0
@@ -38,6 +53,5 @@ module Waves
0
     functor( :normalize, Hash ) { | options | options }
0
     
0
   end
0
-
0
 
0
 end
0
\ No newline at end of file
...
6
7
8
9
 
10
11
12
13
14
 
 
15
16
17
...
19
20
21
22
23
 
24
25
26
...
6
7
8
 
9
10
11
12
13
 
14
15
16
17
18
...
20
21
22
 
 
23
24
25
26
0
@@ -6,12 +6,13 @@ module Waves
0
       
0
       attr_accessor :target, :pattern
0
       def initialize( options )
0
- @target = options[ :target ]
0
+ @keys = [] ; @target = options[ :target ]
0
         @pattern = compile( option[ :pattern ] )
0
       end
0
       
0
       def match( request )
0
- ( m = pattern.match( request.send( target ) ) ) and m[1..-1]
0
+ return false unless m = pattern.match( request.send( target ) )
0
+ params = [] ; @keys.zip( m ) { | key, val | r[ key ] = val } ; params
0
       end
0
       
0
       private
0
@@ -19,8 +20,7 @@ module Waves
0
       functor( :compile, Regexp ) { |pattern| pattern }
0
 
0
       functor( :compile, String ) do | pattern |
0
- pattern = Regexp.escape( pattern ).
0
- gsub!( /<([\w\_\-\\]+)>/ ) { |match| "(#{ match })" }
0
+ pattern = Regexp.escape( pattern ).gsub!( /<([\w\_\-\\]+)>/ ) { |match| @keys << match ; "(#{ match })" }
0
         "^#{pattern}/?$"
0
       end
0
       
...
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
 
 
 
 
27
28
29
30
31
32
...
9
10
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
13
14
15
16
17
18
19
 
 
20
21
0
@@ -9,24 +9,13 @@ module Waves
0
       include ResponseMixin
0
 
0
       def initialize(request); @request = request; end
0
-
0
- def with( resource, &block ) ; @resource = resource ; yield if block_given? ; self ; end
0
- def controller ; @controller ||= controllers[ @resource.singular ].process(@request) { self } ; end
0
- def view ; @view ||= views[ @resource.singular ].process( @request ) { self } ; end
0
- def render( method ) ; view.send(method, @resource => @data ) ; end
0
- def redirect( mapping, assigns ) ; request.redirect( mapping.named[mapping].call( assigns ) ) ; end
0
- def method_missing( name, *args, &block)
0
- @data = controller.send( name, *args, &block )
0
- return self
0
- end
0
- def collection ; @data ; end
0
- def instance ; @data ; end
0
- # have to define this explicitly for now because for some reason sequel defines it on Object ...
0
- def all ; method_missing(:all) ; end
0
       
0
+ end
0
+
0
+ # :)
0
+ const_set( :Base, Class.new ).module_eval { include Mixin }
0
+
0
   end
0
 
0
- # :)
0
- const_set( :Base, Class.new ).module_eval { include Mixin }
0
 
0
 end
...
105
106
107
 
 
 
108
109
110
111
112
113
114
...
105
106
107
108
109
110
111
112
 
 
 
113
114
0
@@ -105,10 +105,10 @@ module Waves
0
 
0
     end
0
 
0
+ # :)
0
+ const_set( :Base, Class.new ).module_eval { include Mixin }
0
+
0
   end
0
   
0
- # :)
0
- const_set( :Base, Class.new ).module_eval { include Mixin }
0
-
0
 
0
 end
...
45
46
47
48
49
50
51
52
53
54
55
 
56
57
58
59
60
61
62
63
64
...
45
46
47
 
48
49
50
51
52
53
 
54
55
56
57
 
58
 
59
60
61
0
@@ -45,20 +45,17 @@ require 'runtime/server'
0
 require 'runtime/request'
0
 require 'runtime/response'
0
 require 'runtime/response_mixin'
0
-require 'runtime/response_proxy'
0
 require 'runtime/session'
0
 require 'runtime/blackboard'
0
 require 'runtime/configuration'
0
 
0
 # waves URI mapping
0
 require 'mapping/mapping'
0
-require 'mapping/pretty_urls'
0
+require 'resources/mixin'
0
 
0
 # waves mvc support
0
 require 'controllers/mixin'
0
-require 'controllers/base'
0
 require 'views/mixin'
0
-require 'views/base'
0
 require 'helpers/tag_helper'
0
 require 'helpers/url_helper'
0
 require 'helpers/common'
...
3
4
5
 
6
7
8
 
 
 
 
9
10
11
12
 
 
 
 
 
 
 
 
 
 
13
14
15
...
3
4
5
6
7
 
 
8
9
10
11
12
 
 
 
13
14
15
16
17
18
19
20
21
22
23
24
25
0
@@ -3,13 +3,23 @@ module Blog
0
   module Configurations
0
 
0
     module Mapping
0
+
0
       extend Waves::Mapping
0
- path '/comments', :method => :post do
0
- with(:comments).create and redirect( :model => :entry, :name => instance.name )
0
+
0
+ # specific to comments - on create redirect to the entry, not the comment itself
0
+ path :create, :resource => :comment, :post => '/comments' do
0
+ instance = create and redirect( Blog::Resources::Entries.path.show( instance.entry.name ) )
0
       end
0
- include Waves::Mapping::PrettyUrls::RestRules
0
- include Waves::Mapping::PrettyUrls::GetRules
0
- end
0
+
0
+ # defaults for generic resources
0
+ path :list, :get => '/<resources>' { all and render( :list ) }
0
+ path :show, :get => '/<resource>/<name>' { find( params[:name] ) and render( :show ) }
0
+ path :edit, :get => '/<resource>/<name>/editor' { find( params[:name] ) and render( :editor ) }
0
+ path :create, :post => '/<resources>' { instance = create and redirect( path.editor( instance.name ) ) }
0
+ path :update, :post => '/<resource>/<name>' { update( params[:name] ) and redirect( path.show( params[:name] ) ) }
0
+ path :delete, :delete => '/<resource><name>' { delete( params[:name] ) }
0
+
0
+ end
0
 
0
   end
0
 

Comments

    No one has commented yet.