caterpillar 1.3.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +24 -1
- data/README.rdoc +30 -3
- data/Rakefile +22 -0
- data/bin/caterpillar +6 -5
- data/generators/caterpillar/caterpillar_generator.rb +11 -5
- data/generators/caterpillar/templates/config/portlets.rb +31 -23
- data/generators/caterpillar/templates/stylesheets/portlet_test_bench/main.css +7 -6
- data/generators/html_template/html_template_generator.rb +18 -0
- data/generators/html_template/templates/application.html.erb +11 -0
- data/lib/caterpillar.rb +25 -14
- data/lib/caterpillar/config.rb +33 -26
- data/lib/caterpillar/liferay.rb +102 -158
- data/lib/caterpillar/parser.rb +13 -10
- data/lib/caterpillar/portlet.rb +149 -104
- data/lib/caterpillar/task.rb +91 -48
- data/lib/caterpillar/usage.rb +3 -2
- data/lib/caterpillar/util.rb +67 -40
- data/lib/java/{rails-portlet-0.10.0.jar → rails-portlet-0.10.1.jar} +0 -0
- data/lib/rails_gem_chooser.rb +21 -17
- data/portlet_test_bench/README.rdoc +5 -5
- data/portlet_test_bench/controllers/caterpillar/http_methods_controller.rb +13 -2
- data/portlet_test_bench/controllers/caterpillar/junit_controller.rb +8 -6
- data/portlet_test_bench/views/caterpillar/http_methods/post.html.erb +86 -31
- data/portlet_test_bench/views/caterpillar/junit/{basic_tags.html.erb → images.html.erb} +0 -0
- data/portlet_test_bench/views/caterpillar/junit/links.html.erb +18 -0
- data/portlets-config.rb +87 -0
- data/test/rails_task_test.rb +3 -1
- data/test/xml_test.rb +84 -14
- metadata +12 -9
- data/lib/java/rails-portlet-0.6.0.jar +0 -0
data/lib/caterpillar/config.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
3
|
-
|
4
2
|
#--
|
5
3
|
# (c) Copyright 2008 Mikael Lammentausta
|
6
4
|
# See the file LICENSES.txt included with the distribution for
|
@@ -10,8 +8,8 @@
|
|
10
8
|
module Caterpillar
|
11
9
|
# Portlet configuration. The config file 'config/portlets.rb' should be installed in your Rails application. See the comments in the configuration file for more specific information about each option.
|
12
10
|
class Config
|
13
|
-
FILE = File.join('config','portlets.rb')
|
14
|
-
JRUBY_HOME = nil # override in the config file if necessary
|
11
|
+
FILE = File.join('config','portlets.rb') unless defined? Caterpillar::Config::FILE
|
12
|
+
JRUBY_HOME = nil unless defined? Caterpillar::Config::JRUBY_HOME # override in the config file if necessary
|
15
13
|
|
16
14
|
# Are all named routes used, or only the ones specifically defined in the config FILE?
|
17
15
|
attr_accessor :include_all_named_routes
|
@@ -19,16 +17,20 @@ module Caterpillar
|
|
19
17
|
attr_accessor :category
|
20
18
|
|
21
19
|
attr_accessor :edit_mode
|
22
|
-
|
23
|
-
attr_accessor :instanceable
|
24
20
|
|
21
|
+
attr_accessor :preferences_route
|
22
|
+
|
23
|
+
attr_accessor :instanceable
|
24
|
+
|
25
|
+
attr_accessor :public_render_parameters
|
26
|
+
|
25
27
|
attr_accessor :host
|
26
28
|
|
27
29
|
attr_accessor :servlet
|
28
30
|
|
29
31
|
attr_accessor :instances
|
30
32
|
|
31
|
-
|
33
|
+
attr_accessor :rails_root
|
32
34
|
|
33
35
|
attr_accessor :_container
|
34
36
|
|
@@ -41,30 +43,34 @@ module Caterpillar
|
|
41
43
|
attr_accessor :logger
|
42
44
|
|
43
45
|
# Sets sane defaults that are overridden in the config file.
|
44
|
-
def initialize
|
46
|
+
def initialize(detect_configuration_file = true)
|
45
47
|
# RAILS_ROOT is at least defined in Caterpillar initialization
|
46
|
-
|
48
|
+
if defined? RAILS_ROOT
|
49
|
+
@rails_root = File.expand_path(RAILS_ROOT)
|
50
|
+
end
|
51
|
+
|
47
52
|
@servlet = nil
|
48
53
|
@category = nil
|
49
54
|
@instances = []
|
50
55
|
@javascripts = []
|
51
|
-
@include_all_named_routes = true
|
52
|
-
|
53
|
-
rails_conf = File.join(@rails_root,'config','environment.rb')
|
54
|
-
unless File.exists?(rails_conf)
|
55
|
-
STDERR.puts 'Rails configuration file could not be found'
|
56
|
-
@rails_root = nil
|
57
|
-
else
|
58
|
-
@servlet = File.basename(@rails_root)
|
59
|
-
@category = @servlet
|
60
|
-
|
61
|
-
@warbler_conf = File.join(@rails_root,'config','warble.rb')
|
62
|
-
unless File.exists?(@warbler_conf)
|
63
|
-
#STDERR.puts 'Warbler configuration file could not be found'
|
64
|
-
end
|
65
|
-
end
|
66
56
|
|
67
|
-
|
57
|
+
@include_all_named_routes = false
|
58
|
+
|
59
|
+
if @rails_root
|
60
|
+
rails_conf = File.join(@rails_root,'config','environment.rb')
|
61
|
+
unless File.exists?(rails_conf)
|
62
|
+
#STDERR.puts 'Rails configuration file could not be found'
|
63
|
+
@rails_root = nil
|
64
|
+
else
|
65
|
+
@servlet = File.basename(@rails_root)
|
66
|
+
@category = @servlet
|
67
|
+
|
68
|
+
@warbler_conf = File.join(@rails_root,'config','warble.rb')
|
69
|
+
unless File.exists?(@warbler_conf)
|
70
|
+
#STDERR.puts 'Warbler configuration file could not be found'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
68
74
|
|
69
75
|
yield self if block_given?
|
70
76
|
end
|
@@ -73,7 +79,8 @@ module Caterpillar
|
|
73
79
|
#
|
74
80
|
# Possible values: Caterpillar::Liferay (default using Tomcat)
|
75
81
|
def container
|
76
|
-
self._container
|
82
|
+
return self._container if self._container
|
83
|
+
self._container = Caterpillar::Liferay.new
|
77
84
|
end
|
78
85
|
|
79
86
|
# Accepts the configuration option, and instantates the container class.
|
data/lib/caterpillar/liferay.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
3
|
-
|
4
2
|
#--
|
5
|
-
# (c) Copyright 2008
|
3
|
+
# (c) Copyright 2008-2010 Mikael Lammentausta
|
6
4
|
#
|
7
5
|
# See the file MIT-LICENSE included with the distribution for
|
8
6
|
# software license details.
|
9
7
|
#++
|
10
8
|
|
9
|
+
require "rexml/document"
|
10
|
+
|
11
11
|
module Caterpillar # :nodoc:
|
12
12
|
|
13
13
|
# Creates liferay-portlet XML and liferay-display XML.
|
@@ -62,7 +62,7 @@ module Caterpillar # :nodoc:
|
|
62
62
|
# Liferay version is given as a String, eg. '5.2.2'.
|
63
63
|
# Defaults to +Lportal::Schema.version+.
|
64
64
|
def initialize(version=nil)
|
65
|
-
@version = version
|
65
|
+
@version = version || '5.2.3'
|
66
66
|
@root = '/usr/local/liferay-portal-5.2.3/tomcat-6.0.18' # as described in setup guide, when unpacked to /usr/local
|
67
67
|
@server = 'Tomcat'
|
68
68
|
@deploy_dir = nil
|
@@ -79,70 +79,39 @@ module Caterpillar # :nodoc:
|
|
79
79
|
# It can also be defined from the configuration file:
|
80
80
|
# portlet.container.deploy_dir = '/opt/myDeployDir'
|
81
81
|
def deploy_dir
|
82
|
-
return @deploy_dir
|
82
|
+
return @deploy_dir if @deploy_dir # user configuration
|
83
83
|
|
84
|
-
raise 'Configure container root folder' unless self.root
|
85
84
|
case @server
|
86
|
-
|
87
85
|
when 'Tomcat'
|
88
|
-
|
89
|
-
|
86
|
+
raise 'Configure container root directory' unless @root
|
87
|
+
return File.join(@root,'webapps')
|
90
88
|
|
91
89
|
when 'JBoss/Tomcat'
|
92
|
-
|
93
|
-
@server_dir ||= Dir.new(
|
94
|
-
File.join(self.root,'server')).entries.first
|
95
|
-
@deploy_dir = File.join(self.root,'server',@server_dir,'deploy')
|
90
|
+
raise "Please configure deploy directory for JBoss."
|
96
91
|
|
97
92
|
end
|
98
|
-
|
99
|
-
unless File.exists?(@deploy_dir)
|
100
|
-
raise 'Portal deployment directory does not exist: %s' % @deploy_dir
|
101
|
-
end
|
102
|
-
|
103
|
-
return @deploy_dir
|
104
93
|
end
|
105
94
|
|
106
|
-
# The location of Liferay's WEB-INF folder
|
107
|
-
#
|
95
|
+
# The location of Liferay's WEB-INF folder,
|
96
|
+
# relative to installation directory (@root).
|
97
|
+
# This is where the XML files are housed.
|
108
98
|
def WEB_INF
|
109
|
-
raise 'Configure container root
|
99
|
+
raise 'Configure container root directory' unless @root
|
110
100
|
case @server
|
111
101
|
|
112
102
|
when 'Tomcat'
|
113
|
-
|
114
|
-
return web_inf_dir(root_dir)
|
103
|
+
return File.join(@root, %w{webapps ROOT WEB-INF})
|
115
104
|
|
116
105
|
when 'JBoss/Tomcat'
|
117
|
-
#
|
118
|
-
|
119
|
-
|
120
|
-
'ROOT.war'
|
121
|
-
elsif File.exists?(File.join(self.deploy_dir,'lportal.war'))
|
122
|
-
'lportal.war'
|
123
|
-
end
|
124
|
-
unless root_dir
|
125
|
-
STDERR.puts 'There seems to be a problem detecting the proper install paths.'
|
126
|
-
STDERR.puts 'Please file a bug on Caterpillar.'
|
127
|
-
raise 'Portal root directory not found at %s' % self.deploy_dir
|
106
|
+
# user should configure server_dir !!
|
107
|
+
unless @server_dir
|
108
|
+
raise 'Please configure server_dir for JBoss/Tomcat'
|
128
109
|
end
|
129
|
-
|
130
|
-
return web_inf_dir(root_dir)
|
110
|
+
return File.join(@root, @server_dir, 'WEB-INF')
|
131
111
|
|
132
112
|
end
|
133
113
|
end
|
134
114
|
|
135
|
-
# The rule by which the WEB-INF is constructed regardless of the server.
|
136
|
-
def web_inf_dir(root_dir)
|
137
|
-
# The @deploy_dir variable does not need checking,
|
138
|
-
# as the method deploy_dir() does that.
|
139
|
-
#if deploy_dir_defined?
|
140
|
-
|
141
|
-
#self.deploy_dir(),
|
142
|
-
# Xml files need to be in WEB-INF and not, for example, /opt/liferay/deploy
|
143
|
-
return File.join(File.join(self.root,'webapps'), root_dir,'WEB-INF')
|
144
|
-
end
|
145
|
-
|
146
115
|
# Reads Liferay portlet descriptor XML files and parses them with Hpricot.
|
147
116
|
def analyze(type=:native)
|
148
117
|
require 'hpricot'
|
@@ -209,94 +178,78 @@ module Caterpillar # :nodoc:
|
|
209
178
|
|
210
179
|
# liferay-portlet XML
|
211
180
|
def portletapp_xml(portlets)
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
181
|
+
doc = REXML::Document.new
|
182
|
+
doc << REXML::XMLDecl.new('1.0', 'utf-8')
|
183
|
+
doc << REXML::DocType.new('liferay-portlet-app',
|
184
|
+
'PUBLIC '+\
|
185
|
+
'"-//Liferay//DTD Portlet Application %s//EN" ' % (self.dtd_version) +\
|
186
|
+
'"http://www.liferay.com/dtd/liferay-portlet-app_%s.dtd"' % self.dtd_version.gsub('.','_')
|
187
|
+
)
|
188
|
+
app = REXML::Element.new('liferay-portlet-app', doc)
|
189
|
+
|
190
|
+
portlets.each do |portlet|
|
191
|
+
# <portlet>
|
192
|
+
app.elements << self.portlet_element(portlet)
|
193
|
+
# <role-mapper>s
|
194
|
+
roles.each {|role| app.elements << role}
|
216
195
|
end
|
217
|
-
|
218
|
-
xml
|
196
|
+
|
197
|
+
xml = ''
|
198
|
+
#doc.write(xml, -1) # no indentation, tag and text should be on same line
|
199
|
+
doc.write(xml, 4) # without identation is very dificult to reconfigure those files in production
|
200
|
+
return xml.gsub('\'', '"') # fix rexml attribute single quotes to double quotes
|
219
201
|
end
|
220
202
|
|
221
203
|
# liferay-display XML
|
222
204
|
def display_xml(portlets)
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
filename = self.WEB_INF+'/liferay-display.xml'
|
237
|
-
f=File.open(filename,'r')
|
238
|
-
doc = Hpricot.XML(f.read)
|
239
|
-
f.close
|
240
|
-
(doc/"display/category").each do |el|
|
241
|
-
unless categories.include?(el.attributes['name'])
|
242
|
-
xml << ' ' + el.to_original_html + "\n"
|
243
|
-
end
|
205
|
+
liferay_display_file = File.join(self.WEB_INF,'liferay-display.xml')
|
206
|
+
|
207
|
+
doc = REXML::Document.new File.new(liferay_display_file)
|
208
|
+
display = doc.root
|
209
|
+
|
210
|
+
# include portlets
|
211
|
+
Util.categorize(portlets).each_pair do |category_name, portlets|
|
212
|
+
category = nil
|
213
|
+
display.each_element {|e| if e.attributes['name'] == category_name.to_s then category = e; break end}
|
214
|
+
|
215
|
+
unless category
|
216
|
+
category = REXML::Element.new('category', display)
|
217
|
+
category.attributes['name'] = category_name.to_s
|
244
218
|
end
|
219
|
+
|
220
|
+
portlets.each do |portlet|
|
221
|
+
if category.has_elements?
|
222
|
+
# unless he holds does not add again
|
223
|
+
category.each_element do |e|
|
224
|
+
unless e.attributes['id'] == portlet[:name]
|
225
|
+
category.add_element 'portlet', {'id' => portlet[:name]}
|
226
|
+
break
|
227
|
+
end
|
228
|
+
end
|
229
|
+
else
|
230
|
+
category.add_element 'portlet', {'id' => portlet[:name]}
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
245
234
|
end
|
246
235
|
|
247
|
-
xml
|
248
|
-
|
236
|
+
xml = ''
|
237
|
+
#doc.write(xml, -1) # no indentation, tag and text should be on same line
|
238
|
+
doc.write(xml, 4) # without identation is very dificult to reconfigure those files in production
|
239
|
+
return xml.gsub('\'', '"') # fix rexml attribute single quotes to double quotes
|
249
240
|
end
|
250
241
|
|
251
242
|
protected
|
252
243
|
|
253
|
-
#
|
254
|
-
def xml_header(doctype)
|
255
|
-
version = self.dtd_version(doctype)
|
256
|
-
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
257
|
-
xml << "\n"
|
258
|
-
xml << '<!DOCTYPE %s PUBLIC' % doctype
|
259
|
-
case doctype
|
260
|
-
|
261
|
-
when 'liferay-portlet-app'
|
262
|
-
xml << ' "-//Liferay//DTD Portlet Application %s//EN"' % version
|
263
|
-
xml << ' "http://www.liferay.com/dtd/%s_%s.dtd">' % [
|
264
|
-
doctype, version.gsub('.','_') ]
|
265
|
-
|
266
|
-
when 'display'
|
267
|
-
xml << ' "-//Liferay//DTD Display %s//EN"' % version
|
268
|
-
xml << ' "http://www.liferay.com/dtd/liferay-%s_%s.dtd">' % [
|
269
|
-
doctype, version.gsub('.','_') ]
|
270
|
-
|
271
|
-
end
|
272
|
-
xml << "\n\n"
|
273
|
-
xml << '<%s>' % doctype
|
274
|
-
xml << "\n"
|
275
|
-
return xml
|
276
|
-
end
|
277
|
-
|
278
|
-
# common XML footer
|
279
|
-
def portlet_xml_footer(doctype)
|
280
|
-
'</%s>' % doctype
|
281
|
-
end
|
282
|
-
|
283
|
-
# DTD version detection based on self.version
|
284
|
-
def dtd_version(type)
|
285
|
-
#case type
|
286
|
-
#when 'liferay-portlet-app'
|
287
|
-
#when 'display'
|
288
|
-
self.version[/.../] + '.0'
|
289
|
-
end
|
290
|
-
|
291
|
-
# liferay-portlet-ext definition
|
244
|
+
# <portlet> element for liferay-portlet-ext.xml
|
292
245
|
#
|
293
246
|
# http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Liferay-portlet.xml
|
294
247
|
#
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
248
|
+
def portlet_element(portlet)
|
249
|
+
element = REXML::Element.new('portlet')
|
250
|
+
|
251
|
+
REXML::Element.new('portlet-name', element).text = portlet[:name]
|
252
|
+
REXML::Element.new('icon', element).text = [
|
300
253
|
portlet[:host], portlet[:servlet], 'favicon.png' # .ico does not work on Firefox 3.0
|
301
254
|
].join('/').gsub(/([^:])\/\//,'\1/')
|
302
255
|
|
@@ -305,9 +258,8 @@ module Caterpillar # :nodoc:
|
|
305
258
|
# Note that when the control panel settings are defined,
|
306
259
|
# the portlet cannot be instanceable.
|
307
260
|
unless @version[/5.1/]
|
308
|
-
|
309
|
-
|
310
|
-
#xml << " <control-panel-entry-class></control-panel-entry-class>\n"
|
261
|
+
REXML::Element.new('control-panel-entry-category', element).text = portlet[:category]
|
262
|
+
REXML::Element.new('control-panel-entry-weight', element).text = '420.0'
|
311
263
|
end
|
312
264
|
|
313
265
|
# Set the use-default-template value to true if the portlet uses the default template to decorate and wrap content. Setting this to false allows the developer to own and maintain the portlet's entire outputted content. The default value is true.
|
@@ -315,60 +267,52 @@ module Caterpillar # :nodoc:
|
|
315
267
|
# The most common use of this is if you want the portlet to look different from the other portlets or if you want the portlet to not have borders around the outputted content.
|
316
268
|
#
|
317
269
|
# RD: This is a nice option except that if you set it, then you loose all border functionality including drag, drop, min,max,edit,conf,close These should be controlled by a separate property.
|
318
|
-
|
270
|
+
REXML::Element.new('use-default-template', element).text = 'true'
|
319
271
|
|
320
272
|
# can there be several portlet instances on the same page?
|
321
|
-
|
273
|
+
REXML::Element.new('instanceable', element).text = portlet[:instanceable].to_s
|
322
274
|
|
323
275
|
# The default value of ajaxable is true. If set to false, then this portlet can never be displayed via Ajax.
|
324
|
-
|
276
|
+
REXML::Element.new('ajaxable', element).text = 'true'
|
325
277
|
|
326
278
|
# include javascripts?
|
327
279
|
js_tag = (@version[/5.1/] ? 'header' : 'footer') + '-portal-javascript'
|
328
280
|
portlet[:javascripts].each do |js|
|
329
|
-
|
330
|
-
xml << "/#{portlet[:servlet]}/javascripts/#{js}"
|
331
|
-
xml << "</#{js_tag}>\n"
|
281
|
+
REXML::Element.new(js_tag, element).text = "/#{portlet[:servlet]}/javascripts/#{js}"
|
332
282
|
end
|
333
283
|
|
334
284
|
# If the add-default-resource value is set to true, the default portlet resources and permissions are added to the page. The user can then view the portlet.
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
285
|
+
REXML::Element.new('add-default-resource', element).text = 'true'
|
286
|
+
REXML::Element.new('system', element).text = 'false'
|
287
|
+
REXML::Element.new('active', element).text = 'true'
|
288
|
+
REXML::Element.new('include', element).text = 'true'
|
339
289
|
|
340
|
-
|
290
|
+
return element
|
341
291
|
end
|
342
292
|
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
xml << ' <portlet id="%s" />' % p[:name] + "\n"
|
347
|
-
end
|
348
|
-
xml << " </category>\n\n"
|
293
|
+
# DTD version based on self.version
|
294
|
+
def dtd_version
|
295
|
+
self.version[/.../] + '.0'
|
349
296
|
end
|
350
297
|
|
351
298
|
private
|
352
299
|
|
353
300
|
# XML role-mapper.
|
354
|
-
# Has to be duplicated in -ext.xml
|
355
301
|
def roles
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
xml << " <role-link>User</role-link>\n"
|
371
|
-
xml << " </role-mapper>\n"
|
302
|
+
elements = []
|
303
|
+
# name => link
|
304
|
+
{
|
305
|
+
'administrator' => 'Administrator',
|
306
|
+
'guest' => 'Guest',
|
307
|
+
'power-user' => 'Power User',
|
308
|
+
'user' => 'User'
|
309
|
+
}.each_pair do |name,link|
|
310
|
+
mapper = REXML::Element.new('role-mapper')
|
311
|
+
REXML::Element.new('role-name', mapper).text = name
|
312
|
+
REXML::Element.new('role-link', mapper).text = link
|
313
|
+
elements << mapper
|
314
|
+
end
|
315
|
+
return elements
|
372
316
|
end
|
373
317
|
|
374
318
|
public
|