ruote-kit 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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