Orbjson 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/bin/orbjson CHANGED
@@ -1,81 +1,81 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'orbjson'
4
- require 'ftools'
5
-
6
- SKEL_DIR = File.join( Orbjson::LibPath, 'skeleton')
7
-
8
-
9
- def usage
10
- puts <<-USAGE
11
-
12
- NAME
13
- orbjson - creates a new Orbjson application
14
-
15
- SYNOPSIS
16
- orbjson create-cgi [full path]
17
- orbjson create-webrick [full path]
18
-
19
- DESCRIPTION
20
- This will create some basic files to get you started fleshing out
21
- your Orbjson server application.
22
-
23
- create-cgi creates a simple Ruby file to execute a CGI call and process
24
- JSON-RPC calls
25
-
26
- create-webrick creates a Ruby WEBrick server script and servlet to
27
- process JSON-RPC calls
28
-
29
-
30
- EXAMPLE
31
-
32
- orbjson create-cgi ~/my-orbjson-project
33
-
34
- This will generate a new Orbjson CGI application in the ~/my-orbjson-project
35
- folder.
36
- USAGE
37
- exit 1
38
- end
39
-
40
-
41
- def run
42
- case command = ARGV[0] || usage()
43
- when 'create-cgi'
44
- path = ARGV[1] || usage()
45
- path = File.expand_path(path)
46
-
47
- if File.exists?(path)
48
- STDERR.puts "ERROR: Path #{ path } already exists! Aborting!"
49
- exit 1
50
- end
51
-
52
- src = File.join(SKEL_DIR, 'cgi')
53
- File.makedirs path
54
- File.makedirs File.join(path, 'script')
55
- File.copy File.join( src, 'json-rpc.rb' ), path, true
56
- File.copy File.join( SKEL_DIR, 'script', 'jsonrpc.js' ), File.join( path, 'script'), true
57
-
58
- when 'create-webrick'
59
- path = ARGV[1] || usage()
60
- path = File.expand_path(path)
61
-
62
- if File.exists?(path)
63
- STDERR.puts "ERROR: Path #{ path } already exists! Aborting!"
64
- exit 1
65
- end
66
-
67
- src = File.join(SKEL_DIR, 'webrick')
68
- File.makedirs path
69
- File.makedirs File.join(path, 'script')
70
- File.copy File.join( src, 'server.rb' ), path, true
71
- File.copy File.join( src, 'config.yml' ), path, true
72
- File.copy File.join( SKEL_DIR, 'script', 'jsonrpc.js' ), File.join( path, 'script'), true
73
- else
74
- usage()
75
- end
76
- end
77
-
78
- run
79
-
80
- # This script is based on Michael Neumann's Wee creator script.
81
- # Nice work, Mike!
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'orbjson'
4
+ require 'ftools'
5
+
6
+ SKEL_DIR = File.join( Orbjson::LibPath, 'skeleton')
7
+
8
+
9
+ def usage
10
+ puts <<-USAGE
11
+
12
+ NAME
13
+ orbjson - creates a new Orbjson application
14
+
15
+ SYNOPSIS
16
+ orbjson create-cgi [full path]
17
+ orbjson create-webrick [full path]
18
+
19
+ DESCRIPTION
20
+ This will create some basic files to get you started fleshing out
21
+ your Orbjson server application.
22
+
23
+ create-cgi creates a simple Ruby file to execute a CGI call and process
24
+ JSON-RPC calls
25
+
26
+ create-webrick creates a Ruby WEBrick server script and servlet to
27
+ process JSON-RPC calls
28
+
29
+
30
+ EXAMPLE
31
+
32
+ orbjson create-cgi ~/my-orbjson-project
33
+
34
+ This will generate a new Orbjson CGI application in the ~/my-orbjson-project
35
+ folder.
36
+ USAGE
37
+ exit 1
38
+ end
39
+
40
+
41
+ def run
42
+ case command = ARGV[0] || usage()
43
+ when 'create-cgi'
44
+ path = ARGV[1] || usage()
45
+ path = File.expand_path(path)
46
+
47
+ if File.exists?(path)
48
+ STDERR.puts "ERROR: Path #{ path } already exists! Aborting!"
49
+ exit 1
50
+ end
51
+
52
+ src = File.join(SKEL_DIR, 'cgi')
53
+ File.makedirs path
54
+ File.makedirs File.join(path, 'script')
55
+ File.copy File.join( src, 'json-rpc.rb' ), path, true
56
+ File.copy File.join( SKEL_DIR, 'script', 'jsonrpc.js' ), File.join( path, 'script'), true
57
+
58
+ when 'create-webrick'
59
+ path = ARGV[1] || usage()
60
+ path = File.expand_path(path)
61
+
62
+ if File.exists?(path)
63
+ STDERR.puts "ERROR: Path #{ path } already exists! Aborting!"
64
+ exit 1
65
+ end
66
+
67
+ src = File.join(SKEL_DIR, 'webrick')
68
+ File.makedirs path
69
+ File.makedirs File.join(path, 'script')
70
+ File.copy File.join( src, 'server.rb' ), path, true
71
+ File.copy File.join( src, 'config.yml' ), path, true
72
+ File.copy File.join( SKEL_DIR, 'script', 'jsonrpc.js' ), File.join( path, 'script'), true
73
+ else
74
+ usage()
75
+ end
76
+ end
77
+
78
+ run
79
+
80
+ # This script is based on Michael Neumann's Wee creator script.
81
+ # Nice work, Mike!
data/lib/orbjson.rb CHANGED
@@ -1,250 +1,250 @@
1
- require 'rubygems'
2
- require 'logger'
3
- require 'json/objects'
4
- require 'json/lexer'
5
- require 'yaml'
6
- require 'needle'
7
- require 'webrick'
8
-
9
- class CGI
10
- def raw_post
11
- self.params.keys[0]
12
- end
13
- end
14
-
15
- include WEBrick
16
-
17
- def new_from_name( classname, *args)
18
- cname = String.new( classname.untaint )
19
- obj = nil
20
- begin
21
- obj = Object.const_get( cname ).new( *args )
22
- rescue Exception
23
- begin
24
- require cname
25
- obj = Object.const_get( cname ).new( *args )
26
- rescue Exception
27
- raise "Cannot create object #{cname}: #{$!}" unless obj
28
- end
29
- end
30
- obj
31
- end
32
-
33
-
34
-
35
-
36
- module Orbjson
37
-
38
- $roy_logger = Logger.new( "Orbjson.log" )
39
- $roy_logger.level = Logger::DEBUG
40
-
41
- Version = "0.1.1"
42
- LibPath = File.dirname(__FILE__)
43
-
44
- class System
45
- @@registry = Needle::Registry.new()
46
-
47
- def self.get_object( klass, *args )
48
- return @@registry[ klass.intern ]
49
- end
50
-
51
- def self.put_object( klass, instance )
52
- @@registry.register( klass ) { instance }
53
- # @@cache[ klass ] = instance
54
- end
55
-
56
- def self.registered_classses
57
- @@registry.keys.map{ |k| k.to_s.capitalize }
58
- end
59
-
60
- def listMethods
61
- System.list_methods
62
- end
63
-
64
- def self.list_methods
65
- mlist = []
66
-
67
- System.registered_classses.each do |cls|
68
- name = cls.to_s.downcase
69
- begin
70
- klass = eval(cls )
71
- ( klass.public_instance_methods -
72
- Object.methods ).sort.each { |m|
73
- mlist << "#{name}.#{m}"
74
- }
75
- rescue Exception
76
- STDERR.puts( "System#list_methods error #{$!}" )
77
- $roy_logger.error( "System#list_methods error #{$!}" )
78
- end
79
- end
80
- mlist
81
- end
82
-
83
-
84
- # You configure the services list by passing in either a hash of file
85
- # paths mapped to class names, or a YMAL string encoding the same, or
86
- # the path to YAML file
87
- def self.init( cfg, flush = true )
88
-
89
- @@registry = Needle::Registry.new() if flush
90
- STDERR.puts( "cfg starts as #{cfg}")
91
- case cfg.class.to_s
92
- when 'String'
93
- if cfg =~ /^file:\/\//
94
- cfg.gsub!( /^file:\/\//, '' )
95
- STDERR.puts( "cfg is now #{cfg}")
96
- config_hash = YAML::load( File.open( cfg ) )
97
- else
98
- STDERR.puts( "cfg is #{cfg}")
99
- config_hash = YAML::load( cfg )
100
- end
101
- when 'Hash'
102
- config_hash = cfg
103
- else
104
- raise "init was given unusable configuration data [ #{cfg.class}]: #{$!}"
105
- end
106
-
107
- config_hash.each do |src_file, class_list|
108
- require src_file
109
- class_list.each do |klass|
110
- @@registry.register( klass ) { new_from_name( klass ) }
111
- end
112
- end
113
-
114
- @@registry.register( :System ) { System.new }
115
- @@registry.register( :system ) { System.new }
116
- $roy_logger.debug( "Regist now has \n" + @@registry.keys.inspect )
117
- end
118
- end
119
-
120
- module Common
121
- def format_repsonse( result, error, id )
122
- id.class == String ? quote = '"' : quote = ''
123
- '{ "result" : ' + result.to_json + ', "error":"' +
124
- error.to_s + '", "id": ' + quote + id.to_s +
125
- quote + ' }'
126
- end
127
-
128
- def process( json )
129
- json = "#{json}"
130
- null=nil;
131
- jsonobj = {}.from_json( JSON::Lexer.new(json ) )
132
- klass, method = jsonobj[ 'method'].split( '.' )
133
- $roy_logger.debug( "klass, method = #{klass}, #{method}" )
134
- receiver = System.get_object( klass.capitalize )
135
- begin
136
- if ( jsonobj[ 'params'] && jsonobj[ 'params'] != 'nil' )
137
- $roy_logger.debug( __LINE__ )
138
- if jsonobj[ 'params'].size < 1
139
- $roy_logger.debug( __LINE__ )
140
- result = receiver.send( method )
141
- else
142
- $roy_logger.debug( __LINE__ )
143
- result = receiver.send( method , *jsonobj[ 'params'] )
144
- end
145
- else
146
- $roy_logger.debug( __LINE__ )
147
- result = receiver.send( method )
148
- end
149
- error = null
150
- rescue
151
- result = null
152
- error = $!.to_s
153
- $roy_logger.error( "#{_LINE__}: #{$!}" )
154
- end
155
- format_repsonse( result, error, jsonobj['id'] || 'default' )
156
- end
157
- end
158
-
159
-
160
- # Manages json-rpc requests sent as a post to a WEBrick servlet.
161
- # Mount a path to WEBrick_JSON_RPC, and you should be set
162
- class WEBrick_JSON_RPC < HTTPServlet::AbstractServlet
163
-
164
- include Common
165
-
166
- def process_request( req, res, json )
167
- res.body = process( json )
168
- res['Content-Type'] = "text/javascript"
169
- end
170
-
171
- # Delegates the call to process_request
172
- def do_GET( request, response )
173
- process_request( request, response, request.query_string )
174
- end
175
-
176
- # Delegates the call to process_request
177
- def do_POST( request, response )
178
- process_request( request, response, request.body )
179
- end
180
-
181
-
182
- end
183
-
184
-
185
- # Manages json-rpc requests sent as a raw post to a CGI application.
186
- class CGI_JSON_RPC
187
-
188
- include Common
189
-
190
- def initialize( cfg )
191
- System.init( cfg )
192
- end
193
-
194
- def process_request( )
195
- cgi = CGI.new
196
- json = cgi.raw_post
197
- process( json )
198
- end
199
-
200
- end
201
- end
202
-
203
- #
204
- #
205
- # TODO See specs at http://www.json-rpc.org/specs.xhtml
206
- # 1.3 notification
207
- # A notification is a special request which does not have a response.
208
- # The notification is a single object serialized using JSON.
209
- # It has the same properties as the request object with one exception.
210
- #
211
- # * id
212
- # Muste be null.
213
- #
214
- # 2.2 JSON-RPC over HTTP
215
- # With some limitations HTTP can be used for communicating to a service.
216
- # A client may send one or more requests to a service.
217
- # The requests must be sent as an HTTP POST containing all serialized request objects.
218
- # The reply must contain the serialized response objects for all requests.
219
- # Notifications may be sent by the client or the service.
220
- #
221
- # A non valid request must result in closing the connection.
222
- # A non valid responses must raise an exception for all unanswered requests on the client.
223
- # Closing a connection must raise an exception for all unanswered requests on the client.
224
- #
225
- # 3. JSON Class hinting?
226
- # There are only simple data types defined in JSON.
227
- # To overcome this problem in a JSON compatible way a special property for objects is introduced.
228
- # {"jsonclass":["constructor", [param1, ], "prop1": ...}
229
- # The object is then instanciated using the constructor passing the parameters.
230
- # Once constructed the properties will be applied.
231
-
232
-
233
- # Copyright (C) 2005 James Britt & Neurogami LLC
234
- # Big thanks to Florian Franks for his ruby-json lib, and Jamis Buck for
235
- # Needle
236
- #
237
- # This program is free software; you can redistribute it and/or
238
- # modify it under the terms of the GNU General Public License,
239
- # version 2, as published by the Free Software Foundation.
240
- #
241
- # This program is distributed in the hope that it will be
242
- # useful, but WITHOUT ANY WARRANTY; without even the implied
243
- # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
244
- # PURPOSE. See the GNU General Public License for more details.
245
- #
246
- # You should have received a copy of the GNU General Public
247
- # License along with this program; if not, write to the Free
248
- # Software Foundation, Inc., 59 Temple Place, Suite 330,
249
- # Boston, MA 02111-1307 USA.
250
-
1
+ require 'rubygems'
2
+ require 'logger'
3
+ require 'json/objects'
4
+ require 'json/lexer'
5
+ require 'yaml'
6
+ require 'needle'
7
+ require 'webrick'
8
+
9
+ class CGI
10
+ def raw_post
11
+ self.params.keys[0]
12
+ end
13
+ end
14
+
15
+ include WEBrick
16
+
17
+ def new_from_name( classname, *args)
18
+ cname = String.new( classname.untaint )
19
+ obj = nil
20
+ begin
21
+ obj = Object.const_get( cname ).new( *args )
22
+ rescue Exception
23
+ begin
24
+ require cname
25
+ obj = Object.const_get( cname ).new( *args )
26
+ rescue Exception
27
+ raise "Cannot create object #{cname}: #{$!}" unless obj
28
+ end
29
+ end
30
+ obj
31
+ end
32
+
33
+
34
+
35
+
36
+ module Orbjson
37
+
38
+ $roy_logger = Logger.new( "Orbjson.log" )
39
+ $roy_logger.level = Logger::DEBUG
40
+
41
+ Version = "0.1.1"
42
+ LibPath = File.dirname(__FILE__)
43
+
44
+ class System
45
+ @@registry = Needle::Registry.new()
46
+
47
+ def self.get_object( klass, *args )
48
+ return @@registry[ klass.intern ]
49
+ end
50
+
51
+ def self.put_object( klass, instance )
52
+ @@registry.register( klass ) { instance }
53
+ # @@cache[ klass ] = instance
54
+ end
55
+
56
+ def self.registered_classses
57
+ @@registry.keys.map{ |k| k.to_s.capitalize }
58
+ end
59
+
60
+ def listMethods
61
+ System.list_methods
62
+ end
63
+
64
+ def self.list_methods
65
+ mlist = []
66
+
67
+ System.registered_classses.each do |cls|
68
+ name = cls.to_s.downcase
69
+ begin
70
+ klass = eval(cls )
71
+ ( klass.public_instance_methods -
72
+ Object.methods ).sort.each { |m|
73
+ mlist << "#{name}.#{m}"
74
+ }
75
+ rescue Exception
76
+ STDERR.puts( "System#list_methods error #{$!}" )
77
+ $roy_logger.error( "System#list_methods error #{$!}" )
78
+ end
79
+ end
80
+ mlist
81
+ end
82
+
83
+
84
+ # You configure the services list by passing in either a hash of file
85
+ # paths mapped to class names, or a YMAL string encoding the same, or
86
+ # the path to YAML file
87
+ def self.init( cfg, flush = true )
88
+
89
+ @@registry = Needle::Registry.new() if flush
90
+ STDERR.puts( "cfg starts as #{cfg}")
91
+ case cfg.class.to_s
92
+ when 'String'
93
+ if cfg =~ /^file:\/\//
94
+ cfg.gsub!( /^file:\/\//, '' )
95
+ STDERR.puts( "cfg is now #{cfg}")
96
+ config_hash = YAML::load( File.open( cfg ) )
97
+ else
98
+ STDERR.puts( "cfg is #{cfg}")
99
+ config_hash = YAML::load( cfg )
100
+ end
101
+ when 'Hash'
102
+ config_hash = cfg
103
+ else
104
+ raise "init was given unusable configuration data [ #{cfg.class}]: #{$!}"
105
+ end
106
+
107
+ config_hash.each do |src_file, class_list|
108
+ require src_file
109
+ class_list.each do |klass|
110
+ @@registry.register( klass ) { new_from_name( klass ) }
111
+ end
112
+ end
113
+
114
+ @@registry.register( :System ) { System.new }
115
+ @@registry.register( :system ) { System.new }
116
+ $roy_logger.debug( "Regist now has \n" + @@registry.keys.inspect )
117
+ end
118
+ end
119
+
120
+ module Common
121
+ def format_repsonse( result, error, id )
122
+ id.class == String ? quote = '"' : quote = ''
123
+ '{ "result" : ' + result.to_json + ', "error":"' +
124
+ error.to_s + '", "id": ' + quote + id.to_s +
125
+ quote + ' }'
126
+ end
127
+
128
+ def process( json )
129
+ json = "#{json}"
130
+ null=nil;
131
+ jsonobj = {}.from_json( JSON::Lexer.new(json ) )
132
+ klass, method = jsonobj[ 'method'].split( '.' )
133
+ $roy_logger.debug( "klass, method = #{klass}, #{method}" )
134
+ receiver = System.get_object( klass.capitalize )
135
+ begin
136
+ if ( jsonobj[ 'params'] && jsonobj[ 'params'] != 'nil' )
137
+ $roy_logger.debug( __LINE__ )
138
+ if jsonobj[ 'params'].size < 1
139
+ $roy_logger.debug( __LINE__ )
140
+ result = receiver.send( method )
141
+ else
142
+ $roy_logger.debug( __LINE__ )
143
+ result = receiver.send( method , *jsonobj[ 'params'] )
144
+ end
145
+ else
146
+ $roy_logger.debug( __LINE__ )
147
+ result = receiver.send( method )
148
+ end
149
+ error = null
150
+ rescue
151
+ result = null
152
+ error = $!.to_s
153
+ $roy_logger.error( "#{_LINE__}: #{$!}" )
154
+ end
155
+ format_repsonse( result, error, jsonobj['id'] || 'default' )
156
+ end
157
+ end
158
+
159
+
160
+ # Manages json-rpc requests sent as a post to a WEBrick servlet.
161
+ # Mount a path to WEBrick_JSON_RPC, and you should be set
162
+ class WEBrick_JSON_RPC < HTTPServlet::AbstractServlet
163
+
164
+ include Common
165
+
166
+ def process_request( req, res, json )
167
+ res.body = process( json )
168
+ res['Content-Type'] = "text/javascript"
169
+ end
170
+
171
+ # Delegates the call to process_request
172
+ def do_GET( request, response )
173
+ process_request( request, response, request.query_string )
174
+ end
175
+
176
+ # Delegates the call to process_request
177
+ def do_POST( request, response )
178
+ process_request( request, response, request.body )
179
+ end
180
+
181
+
182
+ end
183
+
184
+
185
+ # Manages json-rpc requests sent as a raw post to a CGI application.
186
+ class CGI_JSON_RPC
187
+
188
+ include Common
189
+
190
+ def initialize( cfg )
191
+ System.init( cfg )
192
+ end
193
+
194
+ def process_request( )
195
+ cgi = CGI.new
196
+ json = cgi.raw_post
197
+ process( json )
198
+ end
199
+
200
+ end
201
+ end
202
+
203
+ #
204
+ #
205
+ # TODO See specs at http://www.json-rpc.org/specs.xhtml
206
+ # 1.3 notification
207
+ # A notification is a special request which does not have a response.
208
+ # The notification is a single object serialized using JSON.
209
+ # It has the same properties as the request object with one exception.
210
+ #
211
+ # * id
212
+ # Muste be null.
213
+ #
214
+ # 2.2 JSON-RPC over HTTP
215
+ # With some limitations HTTP can be used for communicating to a service.
216
+ # A client may send one or more requests to a service.
217
+ # The requests must be sent as an HTTP POST containing all serialized request objects.
218
+ # The reply must contain the serialized response objects for all requests.
219
+ # Notifications may be sent by the client or the service.
220
+ #
221
+ # A non valid request must result in closing the connection.
222
+ # A non valid responses must raise an exception for all unanswered requests on the client.
223
+ # Closing a connection must raise an exception for all unanswered requests on the client.
224
+ #
225
+ # 3. JSON Class hinting?
226
+ # There are only simple data types defined in JSON.
227
+ # To overcome this problem in a JSON compatible way a special property for objects is introduced.
228
+ # {"jsonclass":["constructor", [param1, ], "prop1": ...}
229
+ # The object is then instanciated using the constructor passing the parameters.
230
+ # Once constructed the properties will be applied.
231
+
232
+
233
+ # Copyright (C) 2005 James Britt & Neurogami LLC
234
+ # Big thanks to Florian Franks for his ruby-json lib, and Jamis Buck for
235
+ # Needle
236
+ #
237
+ # This program is free software; you can redistribute it and/or
238
+ # modify it under the terms of the GNU General Public License,
239
+ # version 2, as published by the Free Software Foundation.
240
+ #
241
+ # This program is distributed in the hope that it will be
242
+ # useful, but WITHOUT ANY WARRANTY; without even the implied
243
+ # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
244
+ # PURPOSE. See the GNU General Public License for more details.
245
+ #
246
+ # You should have received a copy of the GNU General Public
247
+ # License along with this program; if not, write to the Free
248
+ # Software Foundation, Inc., 59 Temple Place, Suite 330,
249
+ # Boston, MA 02111-1307 USA.
250
+
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.8.6
3
3
  specification_version: 1
4
4
  name: Orbjson
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.1
6
+ version: 0.0.2
7
7
  date: 2005-02-27
8
8
  summary: Lib for creating JSON-RPC server applications.
9
9
  require_paths:
@@ -30,8 +30,8 @@ files:
30
30
  - README
31
31
  - docs/todo.txt
32
32
  - bin/orbjson
33
- - lib/orbjson.rb
34
33
  - lib/skeleton
34
+ - lib/orbjson.rb
35
35
  - lib/skeleton/cgi
36
36
  - lib/skeleton/script
37
37
  - lib/skeleton/webrick