ruote-kit 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/.document +0 -0
  2. data/.gitignore +8 -0
  3. data/Gemfile +10 -0
  4. data/README.rdoc +132 -0
  5. data/Rakefile +57 -0
  6. data/config.ru +21 -0
  7. data/lib/ruote-kit/application.rb +50 -0
  8. data/lib/ruote-kit/configuration.rb +52 -0
  9. data/lib/ruote-kit/helpers/engine_helpers.rb +24 -0
  10. data/lib/ruote-kit/helpers/form_helpers.rb +11 -0
  11. data/lib/ruote-kit/helpers/launch_item_parser.rb +59 -0
  12. data/lib/ruote-kit/helpers/navigation_helpers.rb +54 -0
  13. data/lib/ruote-kit/helpers/render_helpers.rb +103 -0
  14. data/lib/ruote-kit/helpers.rb +9 -0
  15. data/lib/ruote-kit/public/_ruote/images/bg.gif +0 -0
  16. data/lib/ruote-kit/public/_ruote/images/bg_button_left.gif +0 -0
  17. data/lib/ruote-kit/public/_ruote/images/bg_button_left_cancel.gif +0 -0
  18. data/lib/ruote-kit/public/_ruote/images/bg_button_left_submit.gif +0 -0
  19. data/lib/ruote-kit/public/_ruote/images/bg_button_right.gif +0 -0
  20. data/lib/ruote-kit/public/_ruote/javascripts/SimplyButtons.js +191 -0
  21. data/lib/ruote-kit/public/_ruote/javascripts/fluo-can.js +1111 -0
  22. data/lib/ruote-kit/public/_ruote/javascripts/fluo-dial.js +149 -0
  23. data/lib/ruote-kit/public/_ruote/javascripts/fluo-json.js +183 -0
  24. data/lib/ruote-kit/public/_ruote/javascripts/fluo-tred.js +515 -0
  25. data/lib/ruote-kit/public/_ruote/stylesheets/SimplyButtons.css +226 -0
  26. data/lib/ruote-kit/public/_ruote/stylesheets/base.css +336 -0
  27. data/lib/ruote-kit/public/_ruote/stylesheets/rk.css +30 -0
  28. data/lib/ruote-kit/public/_ruote/stylesheets/style.css +393 -0
  29. data/lib/ruote-kit/resources/expressions.rb +55 -0
  30. data/lib/ruote-kit/resources/processes.rb +52 -0
  31. data/lib/ruote-kit/resources/workitems.rb +64 -0
  32. data/lib/ruote-kit/spec/ruote_helpers.rb +47 -0
  33. data/lib/ruote-kit/vendor/sinatra-respond_to/LICENSE +21 -0
  34. data/lib/ruote-kit/vendor/sinatra-respond_to/README.markdown +102 -0
  35. data/lib/ruote-kit/vendor/sinatra-respond_to/Rakefile +30 -0
  36. data/lib/ruote-kit/vendor/sinatra-respond_to/VERSION.yml +4 -0
  37. data/lib/ruote-kit/vendor/sinatra-respond_to/lib/sinatra/respond_to.rb +206 -0
  38. data/lib/ruote-kit/vendor/sinatra-respond_to/sinatra-respond_to.gemspec +56 -0
  39. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/public/static folder/.keep +0 -0
  40. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/public/static.txt +1 -0
  41. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/test_app.rb +53 -0
  42. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/unreachable_static.txt +1 -0
  43. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/views/layout.html.haml +2 -0
  44. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/views/resource.html.haml +1 -0
  45. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/views/resource.js.erb +3 -0
  46. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/views/resource.xml.builder +3 -0
  47. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/extension_spec.rb +403 -0
  48. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/spec_helper.rb +18 -0
  49. data/lib/ruote-kit/views/expression.html.haml +38 -0
  50. data/lib/ruote-kit/views/expressions.html.haml +30 -0
  51. data/lib/ruote-kit/views/index.html.haml +1 -0
  52. data/lib/ruote-kit/views/launch_process.html.haml +19 -0
  53. data/lib/ruote-kit/views/layout.html.haml +46 -0
  54. data/lib/ruote-kit/views/process.html.haml +55 -0
  55. data/lib/ruote-kit/views/processes.html.haml +27 -0
  56. data/lib/ruote-kit/views/resource_not_found.html.haml +7 -0
  57. data/lib/ruote-kit/views/workitem.html.haml +39 -0
  58. data/lib/ruote-kit/views/workitems.html.haml +23 -0
  59. data/lib/ruote-kit.rb +105 -0
  60. data/ruote-kit.gemspec +136 -0
  61. data/spec/helpers/render_helpers_spec.rb +211 -0
  62. data/spec/resources/expressions_spec.rb +179 -0
  63. data/spec/resources/index_spec.rb +46 -0
  64. data/spec/resources/processes_spec.rb +259 -0
  65. data/spec/resources/workitems_spec.rb +308 -0
  66. data/spec/ruote-kit_spec.rb +4 -0
  67. data/spec/spec.opts +2 -0
  68. data/spec/spec_helper.rb +152 -0
  69. data/spec/views/launch_process.html.haml_spec.rb +21 -0
  70. data/spec/views/process.html.haml_spec.rb +16 -0
  71. data/spec/views/processes.html.haml_spec.rb +30 -0
  72. data/spec/views/workitems.html.haml_spec.rb +68 -0
  73. metadata +185 -0
data/.document ADDED
File without changes
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.swp
2
+ work*/
3
+ .DS_Store
4
+ bin/*
5
+ vendor/gems
6
+ .yardoc
7
+ doc/*
8
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # Dependencies for ruote-kit
2
+
3
+ # ruote-kit itself
4
+ gem 'sinatra'
5
+ gem 'haml'
6
+ gem 'json'
7
+
8
+ # ruote
9
+ #gem 'ruote', :git => "git://github.com/kennethkalmer/ruote", :branch => "ruote-kit"
10
+ gem 'ruote', '>= 2.1.4'
data/README.rdoc ADDED
@@ -0,0 +1,132 @@
1
+ = ruote-kit (RESTful BPM & middleware)
2
+
3
+ * http://kit.rubyforge.org/ruote (soon)
4
+ * http://kit.rubyforge.org/ruote/rdoc (soon)
5
+
6
+ A RESTful wrapper around the ruote[http://ruote.rubyforge.org] workflow engine,
7
+ built as a modular sinatra[http://www.sinatrarb.com/] application.
8
+
9
+ Follow development:
10
+
11
+ * #ruote on Freenode
12
+ * http://groups.google.com/group/openwferu-users
13
+ * http://opensourcery.co.za
14
+ * @kennethkalmer on Twitter
15
+
16
+ == Alpha Status
17
+
18
+ ruote-kit is under heavy development and will likely change violently over the
19
+ coming weeks (albeit for the better).
20
+
21
+ Dependencies you currently need is:
22
+
23
+ * bundler (gem install bundler)
24
+ * sinatra
25
+ * haml
26
+ * json
27
+ * rspec (only to run the specs)
28
+
29
+ ruote-kit uses bundler to setup and maintain its environment. Before running
30
+ ruote-kit for the first time you need to install bundler and then run:
31
+
32
+ $ gem bundle
33
+
34
+ Bundler will download all the required gems and unpack them in 'vendor/gems'
35
+ for you.
36
+
37
+ == Getting started quickly
38
+
39
+ Once you have the dependencies installed, get going by running 'rackup'
40
+ from inside the ruote-kit project.
41
+
42
+ If ruote-kit starts up without any issues (ie missing dependencies), you can
43
+ point your browser to 'http://localhost:9292/_ruote/' to get going. By default ruote-kit
44
+ binds to all IP addresses, so this works out the box remotely too.
45
+
46
+ == Plugging ruote-kit into your rack-stack
47
+
48
+ ruote-kit is fully self-sufficient piece of rack, but can be slotted into any
49
+ rack middleware stack without issues.
50
+
51
+ Example:
52
+
53
+ RuoteKit.configure do |config|
54
+ # make changes if needed
55
+ end
56
+
57
+ # Register participants if needed
58
+ RuoteKit.engine.register_participant :toto do |wi|
59
+ #
60
+ end
61
+
62
+ # Slot into the stack
63
+ use RuoteKit::Application
64
+
65
+ == Configuring ruote-kit & ruote
66
+
67
+ ruote-kit can be configured using RuoteKit#configure, after which it will start
68
+ the engine. From that point the engine is accessible through RuoteKit.engine.
69
+
70
+ Without any configuration ruote-kit will use file system persistence, and save
71
+ the work in a sub-folder of the current working directory named +work_<env>+,
72
+ where +env+ is the RACK_ENV or RAILS_ENV.
73
+
74
+ == Running workers
75
+
76
+ If you're using ruote-kit as part of your rack stack you'll need to start at
77
+ least one worker separately or the workflows will be executed. You won't need
78
+ more than one worker unless you are running hundreds of processes at the same
79
+ time.
80
+
81
+ To run a worker you need to setup a worker scripts similar to the rake example
82
+ below:
83
+
84
+ require 'rake'
85
+ require 'ruote-kit'
86
+
87
+ desc "Run a ruote-kit worker"
88
+ task :ruote_kit_worker do
89
+
90
+ RuoteKit.configure do |config|
91
+ # Setup your configuration
92
+ end
93
+
94
+ RuoteKit.run_worker!
95
+ end
96
+
97
+ This will only work correctly if using the default file system persistence.
98
+ Support for ruote-couch[http://github.com/jmettraux/ruote-couch] is coming
99
+ soon.
100
+
101
+ == Feedback & bug reports
102
+
103
+ Please bear in mind that the project is still in its alpha days. Keep bug reports
104
+ and suggestions limited to the google group and #ruote channel, at least for the
105
+ time being.
106
+
107
+ Please do not hesitate to come back with *any* feedback.
108
+
109
+ == License
110
+
111
+ (The MIT License)
112
+
113
+ Copyright (c) 2009 Kenneth Kalmer (Internet Exchange CC, Clear Planet Information Solutions Pty Ltd)
114
+
115
+ Permission is hereby granted, free of charge, to any person obtaining
116
+ a copy of this software and associated documentation files (the
117
+ 'Software'), to deal in the Software without restriction, including
118
+ without limitation the rights to use, copy, modify, merge, publish,
119
+ distribute, sublicense, and/or sell copies of the Software, and to
120
+ permit persons to whom the Software is furnished to do so, subject to
121
+ the following conditions:
122
+
123
+ The above copyright notice and this permission notice shall be
124
+ included in all copies or substantial portions of the Software.
125
+
126
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
127
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
128
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
129
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
130
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
131
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
132
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ require 'vendor/gems/environment' if File.exist?('vendor/gems/environment.rb')
5
+
6
+ require 'lib/ruote-kit'
7
+
8
+ begin
9
+ require 'jeweler'
10
+ Jeweler::Tasks.new do |gemspec|
11
+ gemspec.name = 'ruote-kit'
12
+ gemspec.version = RuoteKit::VERSION
13
+ gemspec.summary = 'ruote workflow engine, wrapped in a loving rack embrace'
14
+ gemspec.description = 'ruote-kit is a RESTful Rack app for the ruote workflow engine'
15
+ gemspec.email = 'kenneth.kalmer@gmail.com'
16
+ gemspec.homepage = 'http://github.com/kennethkalmer/ruote-kit'
17
+ gemspec.authors = ['kenneth.kalmer@gmail.com']
18
+ gemspec.extra_rdoc_files.include '*.txt'
19
+
20
+ gemspec.files.include 'lib/ruote-kit/public/**/*'
21
+ gemspec.executables.clear
22
+
23
+ gemspec.add_dependency 'sinatra', '>=0.9.4'
24
+ gemspec.add_dependency 'haml', '>= 2.2.5'
25
+ gemspec.add_dependency 'json'
26
+ gemspec.add_dependency 'ruote', '= 2.1.4'
27
+ gemspec.add_development_dependency 'rspec'
28
+ end
29
+ Jeweler::GemcutterTasks.new
30
+ rescue LoadError
31
+ puts "Jeweler not available. Install it with 'gem install jeweler'"
32
+ end
33
+
34
+ require 'spec/rake/spectask'
35
+ Spec::Rake::SpecTask.new(:spec) do |spec|
36
+ spec.libs << 'lib' << 'spec'
37
+ spec.spec_files = FileList['spec/**/*_spec.rb']
38
+ end
39
+
40
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
41
+ spec.libs << 'lib' << 'spec'
42
+ spec.pattern = 'spec/**/*_spec.rb'
43
+ spec.rcov = true
44
+ end
45
+
46
+ task :spec #=> :check_dependencies
47
+
48
+ task :default => :spec
49
+
50
+ begin
51
+ require 'yard'
52
+ YARD::Rake::YardocTask.new
53
+ rescue LoadError
54
+ task :yardoc do
55
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
56
+ end
57
+ end
data/config.ru ADDED
@@ -0,0 +1,21 @@
1
+ require 'vendor/gems/environment' if ::File.exist?( 'vendor/gems/environment.rb' )
2
+
3
+ $:.unshift 'lib'
4
+
5
+ require 'lib/ruote-kit'
6
+
7
+ # Chance to configure ruote-kit
8
+ RuoteKit.configure do |config|
9
+
10
+ # storage mode
11
+ #config.mode = :transient
12
+
13
+ # run a worker
14
+ config.run_worker = true
15
+ end
16
+
17
+ use Rack::CommonLogger
18
+ use Rack::Lint
19
+ use Rack::ShowExceptions
20
+
21
+ run RuoteKit::Application
@@ -0,0 +1,50 @@
1
+ require 'ruote-kit/vendor/sinatra-respond_to/lib/sinatra/respond_to'
2
+ require 'haml'
3
+
4
+ module RuoteKit
5
+ class Application < Sinatra::Base
6
+
7
+ # Delay these a bit
8
+ configure do
9
+ # We want to support Rails
10
+ if defined?( Rails )
11
+ set :environment, Rails.env
12
+ disable :raise_errors
13
+ end
14
+
15
+ RuoteKit.ensure_engine!
16
+ end
17
+
18
+ set :views, File.join( File.dirname( __FILE__), 'views' )
19
+
20
+ use Rack::Static, :urls => ['/_ruote/images', '/_ruote/javascripts', '/_ruote/stylesheets'], :root => File.join( File.dirname(__FILE__), 'public' )
21
+ use Rack::MethodOverride
22
+
23
+ helpers do
24
+ include RuoteKit::Helpers::EngineHelpers
25
+ include RuoteKit::Helpers::FormHelpers
26
+ include RuoteKit::Helpers::LaunchItemParser
27
+ include RuoteKit::Helpers::NavigationHelpers
28
+ include RuoteKit::Helpers::RenderHelpers
29
+ end
30
+
31
+ before do
32
+ # We allow the Accept header to be set to 'application/json'
33
+ format :json if env["HTTP_ACCEPT"] && env["HTTP_ACCEPT"] == "application/json"
34
+ end
35
+
36
+ not_found do
37
+ resource_not_found
38
+ end
39
+
40
+ get '/_ruote' do
41
+ respond_to do |format|
42
+ format.html { haml :index }
43
+ format.json { json :misc, "ruote-kit" => "welcome", "version" => RuoteKit::VERSION }
44
+ end
45
+ end
46
+
47
+ Dir[ File.dirname(__FILE__) + '/resources/*.rb' ].each { |r| load r }
48
+ end
49
+ end
50
+
@@ -0,0 +1,52 @@
1
+ module RuoteKit
2
+ # RuoteKit configuration handling
3
+ class Configuration
4
+
5
+ # Working directory for the engine (if using file system persistence)
6
+ attr_accessor :work_directory
7
+
8
+ # Number of workers to spawn (1 by default)
9
+ attr_accessor :workers
10
+
11
+ # Whether to run the engine or not (defaults to true)
12
+ attr_accessor :run_engine
13
+
14
+ # Whether to run a single worker or not (defaults to false)
15
+ attr_accessor :run_worker
16
+
17
+ def initialize
18
+ self.work_directory = File.join( Dir.pwd, "work_#{RuoteKit.env}" )
19
+ self.run_engine = true
20
+ self.run_worker = false
21
+ end
22
+
23
+ # Return the selected ruote-kit mode
24
+ def mode
25
+ @mode ||= :file_system
26
+ end
27
+
28
+ # Set the ruote-kit mode
29
+ def mode=( mode )
30
+ raise ArgumentError, "Unsupported mode (#{mode})" unless [ :transient, :file_system ].include?( mode )
31
+ @mode = mode
32
+ end
33
+
34
+ # Return the best suited storage class for the current mode
35
+ def storage_instance
36
+ case mode
37
+ when :transient
38
+ require 'ruote/storage/hash_storage'
39
+ Ruote::HashStorage.new
40
+ when :file_system
41
+ require 'ruote/storage/fs_storage'
42
+ Ruote::FsStorage.new( self.work_directory )
43
+ end
44
+ end
45
+
46
+ def catchall_participant
47
+ require 'ruote/part/storage_participant'
48
+ Ruote::StorageParticipant
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,24 @@
1
+ module RuoteKit
2
+ module Helpers
3
+ module EngineHelpers
4
+
5
+ def engine
6
+ RuoteKit.engine
7
+ end
8
+
9
+ def store_participant
10
+ RuoteKit.engine.context.plist.lookup('.*')
11
+ end
12
+
13
+ def find_workitems( wfid )
14
+ store_participant.by_wfid( wfid )
15
+ end
16
+
17
+ def find_workitem( wfid, expid )
18
+ find_workitems( wfid ).detect { |wi| wi.fei.expid == expid }
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,11 @@
1
+ module RuoteKit
2
+ module Helpers
3
+ module FormHelpers
4
+
5
+ def button( text, css_class = nil )
6
+ "<button type=\"submit\" class=\"#{css_class}\"><span><span>#{text}</span></span></button>"
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,59 @@
1
+ module RuoteKit
2
+ module Helpers
3
+ module LaunchItemParser
4
+
5
+ # Extract the launch item parameters from a posted form or a JSON request body
6
+ def launch_item_from_post
7
+ case env["CONTENT_TYPE"]
8
+
9
+ when "application/json" then
10
+ data = JSON.parse( env["rack.input"].read )
11
+ launch_item = {}
12
+ launch_item['pdef'] = data["definition"]
13
+ launch_item['fields'] = data["fields"] || {}
14
+ launch_item['variables'] = data["variables"] || {}
15
+ return launch_item
16
+
17
+ when "application/x-www-form-urlencoded"
18
+ launch_item = { 'pdef' => params[:process_definition] }
19
+ fields = params[:process_fields] || ""
20
+ fields = "{}" if fields.empty?
21
+ launch_item['fields'] = JSON.parse( fields )
22
+ vars = params[:process_variables] || ""
23
+ vars = "{}" if vars.empty?
24
+ launch_item['variables'] = JSON.parse( vars )
25
+ return launch_item
26
+
27
+ else
28
+ raise "#{env['CONTENT_TYPE']} not supported as a launch mechanism yet"
29
+ end
30
+ end
31
+
32
+ def field_updates_and_proceed_from_put
33
+ options = {
34
+ :fields => {},
35
+ :proceed => false
36
+ }
37
+
38
+ case env['CONTENT_TYPE']
39
+
40
+ when "application/json" then
41
+ data = JSON.parse( env['rack.input'].read )
42
+ options[:fields] = data['fields'] unless data['fields'].nil? || data['fields'].empty?
43
+ options[:proceed] = data['_proceed'] unless data['_proceed'].nil? || data['_proceed'].empty?
44
+
45
+ when "application/x-www-form-urlencoded"
46
+ options[:fields] = JSON.parse( params[:fields] ) unless params['fields'].nil? || params['fields'].empty?
47
+ options[:proceed] = params[:_proceed] unless params[:_proceed].nil? || params[:_proceed].empty?
48
+
49
+ else
50
+ raise "#{evn['CONTENT_TYPE']} is not supported for workitem fields"
51
+ end
52
+
53
+ return options
54
+ end
55
+
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,54 @@
1
+ module RuoteKit
2
+ module Helpers
3
+ module NavigationHelpers
4
+
5
+ def navigate_to( text, path )
6
+ css_classes = []
7
+ css_classes << 'first' if @first.nil?
8
+ @first = true
9
+
10
+ css_classes << 'active' if path.split('/')[2] == request.path.split('/')[2]
11
+
12
+ "<li class=\"#{css_classes.join(' ')}\"><a href=\"#{ path }\">#{text}</a></li>"
13
+ end
14
+
15
+ def pluralize( number, word )
16
+ if number > 1
17
+ word << 's'
18
+ end
19
+
20
+ return [ number, word ].join(' ')
21
+ end
22
+
23
+ def link_to( object, *args )
24
+ case object
25
+ when Ruote::ProcessStatus
26
+ link_to_process( object )
27
+ when Ruote::Workitem
28
+ link_to_workitem( object )
29
+ when String
30
+ "<a href=\"#{args.first}\">#{object}</a>"
31
+ end
32
+ end
33
+
34
+ def link_to_workitem( workitem )
35
+ path = "/_ruote/workitems/#{workitem.fei.wfid}/#{workitem.fei.expid}"
36
+
37
+ "<a href=\"#{path}\">GET #{path}</a>"
38
+ end
39
+
40
+ def link_to_process( status )
41
+ path = "/_ruote/processes/#{status.wfid}"
42
+
43
+ "<a href=\"#{path}\">GET #{path}</a>"
44
+ end
45
+
46
+ def link_to_expression( expression )
47
+ path = "/_ruote/expressions/#{expression.fei.wfid}/#{expression.fei.expid}"
48
+
49
+ "<a href=\"#{path}\">GET #{path}</a>"
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,103 @@
1
+ module RuoteKit
2
+ module Helpers
3
+ # Helpers for rendering stuff
4
+ module RenderHelpers
5
+
6
+ def json( resource, object )
7
+ if respond_to?( "json_#{resource}" )
8
+ object = send( "json_#{resource}", object )
9
+ end
10
+
11
+ {
12
+ "links" => links( resource ),
13
+ resource => object
14
+ }.to_json
15
+ end
16
+
17
+ def json_processes( processes )
18
+ processes.map { |p| json_process( p ) }
19
+ end
20
+
21
+ def json_process( process )
22
+ links = [
23
+ link( "/_ruote/processes/#{process.wfid}", rel('#process') ),
24
+ link( "/_ruote/expressions/#{process.wfid}", rel('#expressions') ),
25
+ link( "/_ruote/workitems/#{process.wfid}", rel('#workitems') )
26
+ ]
27
+
28
+ process.to_h.merge( 'links' => links )
29
+ end
30
+
31
+ def json_expression( expression )
32
+ links = [
33
+ link( "/_ruote/processes/#{expression.fei.wfid}", rel('#process') ),
34
+ link( "/_ruote/expressions/#{expression.fei.wfid}", rel('#expressions') )
35
+ ]
36
+
37
+ if expression.parent
38
+ links << link( "/_ruote/expressions/#{expression.fei.wfid}/#{expression.parent.fei.expid}", 'parent' )
39
+ end
40
+
41
+ expression.to_h.merge( 'links' => links )
42
+ end
43
+
44
+ def json_expressions( expressions )
45
+ expressions.map { |e| json_expression( e ) }
46
+ end
47
+
48
+ def json_workitems( workitems )
49
+ workitems.map { |w| json_workitem( w ) }
50
+ end
51
+
52
+ def json_workitem( workitem )
53
+ links = [
54
+ link( "/_ruote/processes/#{workitem.fei.wfid}", rel('#process') ),
55
+ link( "/_ruote/expressions/#{workitem.fei.wfid}", rel('#expressions') )
56
+ ]
57
+
58
+ workitem.to_h.merge( 'links' => links )
59
+ end
60
+
61
+ def rel( fragment )
62
+ "http://ruote.rubyforge.org/rels.html#{ fragment }"
63
+ end
64
+
65
+ def links( resource )
66
+ links = [
67
+ link( '/_ruote', rel('#root') ),
68
+ link( '/_ruote/processes', rel('#processes') ),
69
+ link( '/_ruote/workitems', rel('#workitems') ),
70
+ link( '/_ruote/history', rel("#history") ),
71
+ link( request.fullpath, 'self' )
72
+ ]
73
+
74
+ links
75
+ end
76
+
77
+ def link( href, rel )
78
+ { 'href' => href, 'rel' => rel }
79
+ end
80
+
81
+ # Easy 404
82
+ def resource_not_found
83
+ status 404
84
+ respond_to do |format|
85
+ format.html { haml :resource_not_found }
86
+ format.json { { "error" => { "code" => "404", "message" => "Resource not found" } }.to_json }
87
+ end
88
+ end
89
+
90
+ # Extract the process tree
91
+ def process_tree( object )
92
+ case object
93
+ when Ruote::Workitem
94
+ process = engine.process( object.fei.wfid )
95
+ process.current_tree.to_json
96
+ when Ruote::ProcessStatus
97
+ object.current_tree.to_json
98
+ end
99
+ end
100
+
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,9 @@
1
+ module RuoteKit
2
+ module Helpers
3
+ autoload :EngineHelpers, 'ruote-kit/helpers/engine_helpers'
4
+ autoload :FormHelpers, 'ruote-kit/helpers/form_helpers'
5
+ autoload :LaunchItemParser, 'ruote-kit/helpers/launch_item_parser'
6
+ autoload :NavigationHelpers, 'ruote-kit/helpers/navigation_helpers'
7
+ autoload :RenderHelpers, 'ruote-kit/helpers/render_helpers'
8
+ end
9
+ end