buildr 0.18.0 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/java/openjpa.rb CHANGED
@@ -1,51 +1,63 @@
1
- module Buildr
2
-
3
- module OpenJPA
4
-
5
- VERSION = "0.9.7-incubating-SNAPSHOT"
6
-
7
- REQUIRES = [ "org.apache.openjpa:openjpa-all:jar:#{VERSION}",
8
- "commons-collections:commons-collections:jar:3.1",
9
- "commons-dbcp:commons-dbcp:jar:1.2.1",
10
- "commons-lang:commons-lang:jar:2.1",
11
- "commons-pool:commons-pool:jar:1.2",
12
- "javax.persistence:persistence-api:jar:1.0",
13
- "org.apache.geronimo.specs:geronimo-j2ee-connector_1.5_spec:jar:1.0",
14
- "org.apache.geronimo.specs:geronimo-jta_1.0.1B_spec:jar:1.0",
15
- "net.sourceforge.serp:serp:jar:1.11.0" ]
16
-
17
- OPTIONS = [ :verbose, :noop, :cp, :classpath, :properties ]
18
-
19
- def self.enhance(options)
20
- options[:verbose] ||= Rake.application.options.trace || false
21
- fu_check_options options, *OPTIONS + [:output]
22
-
23
- runtool options.merge(:class=>"org.apache.openjpa.enhance.PCEnhancer", :name=>"Enhancer",
24
- :args=>{ "-p"=>options[:properties], "-d"=>options[:output] },
25
- :classpath=>options[:classpath] + [options[:output]])
26
- end
1
+ require "java/java"
27
2
 
28
- def self.mapping_tool(options)
29
- options[:verbose] ||= Rake.application.options.trace || false
30
- fu_check_options options, *OPTIONS + [:action, :sql]
31
-
32
- runtool options.merge(:class=>"org.apache.openjpa.jdbc.meta.MappingTool", :name=>"Mapping Tool",
33
- :args=>{ "-p"=>options[:properties], "-sql"=>options[:sql], "-sa"=>options[:action] })
34
- end
35
-
36
- protected
37
-
38
- def self.runtool(options)
39
- args = [options[:class]] + options[:args].select { |n, v| v }.map { |n, v| [ n, v ] }.flatten
40
- args << { :classpath=>requires + (options[:classpath] || []),
41
- :name=>"OpenJPA #{options[:name]}", :verbose=>options[:verbose] }
42
- java *args
43
- end
3
+ module Buildr
4
+ module Java
5
+ module OpenJPA
6
+
7
+ VERSION = "0.9.7-incubating-SNAPSHOT"
8
+
9
+ REQUIRES = [ "org.apache.openjpa:openjpa-all:jar:#{VERSION}",
10
+ "commons-collections:commons-collections:jar:3.1",
11
+ "commons-dbcp:commons-dbcp:jar:1.2.1",
12
+ "commons-lang:commons-lang:jar:2.1",
13
+ "commons-pool:commons-pool:jar:1.2",
14
+ "javax.persistence:persistence-api:jar:1.0",
15
+ "org.apache.geronimo.specs:geronimo-j2ee-connector_1.5_spec:jar:1.0",
16
+ "org.apache.geronimo.specs:geronimo-jta_1.0.1B_spec:jar:1.0",
17
+ "net.sourceforge.serp:serp:jar:1.11.0" ]
18
+
19
+ OPTIONS = [ :verbose, :noop, :classpath, :properties ]
20
+
21
+ class << self
22
+
23
+ def enhance(options)
24
+ fu_check_options options, *OPTIONS + [:output]
25
+ runtool options.merge(:class=>"org.apache.openjpa.enhance.PCEnhancer", :name=>"Enhancer",
26
+ :args=>{ "-p"=>options[:properties], "-d"=>options[:output].to_s },
27
+ :classpath=>options[:classpath])
28
+ end
29
+
30
+ def mapping_tool(options)
31
+ fu_check_options options, *OPTIONS + [:action, :sql]
32
+ runtool options.merge(:class=>"org.apache.openjpa.jdbc.meta.MappingTool", :name=>"Mapping Tool",
33
+ :args=>{ "-p"=>options[:properties], "-sql"=>options[:sql], "-sa"=>options[:action] })
34
+ end
35
+
36
+ private
37
+
38
+ def runtool(options)
39
+ args = [options[:class]] + options[:args].select { |n, v| v }.map { |n, v| [ n, v ] }.flatten
40
+ args << { :classpath=>requires + (options[:classpath] || []),
41
+ :name=>"OpenJPA #{options[:name]}", :verbose=>options[:verbose] }
42
+ Java.java *args
43
+ end
44
+
45
+ def requires()
46
+ @required ||= artifacts(REQUIRES).each { |artifact| artifact.invoke }.map(&:to_s)
47
+ end
48
+
49
+ end
50
+
51
+ def open_jpa_enhance(options = nil)
52
+ jpa_options = { :output=>compile.target, :classpath=>[compile.classpath, compile.target.to_s],
53
+ :properties=>path_to("src/main/resources/META-INF/persistence.xml") }
54
+ Java::OpenJPA.enhance jpa_options.merge(options || {})
55
+ end
44
56
 
45
- def self.requires()
46
- @required ||= artifacts(REQUIRES).each { |artifact| artifact.invoke }.map(&:to_s)
47
57
  end
48
-
49
58
  end
50
59
 
60
+ class Project
61
+ include Java::OpenJPA
62
+ end
51
63
  end
@@ -1,20 +1,52 @@
1
+ require "core/project"
2
+ require "java/artifact"
3
+ require "java/java"
4
+ require "java/compile"
5
+ require "tasks/zip"
6
+
7
+
1
8
  module Buildr
2
9
  module Java
3
10
 
11
+ # This module includes comming packaging classes. Each one is also reflected by
12
+ # a packaging method. Generally, you would want to use the packaging method from
13
+ # the project definition, since it does all the heavy lifting.
4
14
  module Packaging
5
15
 
6
16
  MANIFEST_HEADER = "Manifest-Version: 1.0\nCreated-By: Buildr\n"
7
17
 
18
+ # Extends the ZipTask to create a JAR file.
19
+ #
20
+ # This task supports two additional attributes: manifest and meta-inf.
21
+ #
22
+ # The manifest attribute specifies how to create the MANIFEST.MF file.
23
+ # * A hash of manifest properties (name/value pairs).
24
+ # * An array of hashes, one for each section of the manifest.
25
+ # * A string providing the name of an existing manifest file.
26
+ # * Proc or method called to return the contents of the manifest file.
27
+ # * False to not generate a manifest file.
28
+ #
29
+ # The meta-inf attribute lists one or more files that should be copied into
30
+ # the META-INF directory.
31
+ #
32
+ # For example:
33
+ # package(:jar).using(:manifest=>"src/MANIFEST.MF")
34
+ # package(:jar).meta_inf << file("README")
8
35
  class JarTask < ZipTask
36
+
37
+ # Specifies how to create the manifest file.
9
38
  attr_accessor :manifest
39
+
40
+ # Specifies files to include in the META-INF directory.
10
41
  attr_accessor :meta_inf
11
42
 
12
- def initialize(*args)
43
+ def initialize(*args) #:nodoc:
13
44
  super
14
45
  @manifest = true
46
+ @meta_inf = []
15
47
  end
16
48
 
17
- def []=(key, value)
49
+ def []=(key, value) #:nodoc:
18
50
  if key.to_sym == :manifest
19
51
  self.manifest = value
20
52
  elsif key.to_sym == :meta_inf
@@ -25,11 +57,16 @@ module Buildr
25
57
  value
26
58
  end
27
59
 
60
+ def prerequisites() #:nodoc:
61
+ super + [ String === manifest ? file(manifest) : nil ].compact +
62
+ meta_inf.map { |file| String === file ? file(file) : file }
63
+ end
64
+
28
65
  protected
29
66
 
30
- def create(zip)
67
+ def create(zip) #:nodoc:
31
68
  zip.mkdir "META-INF"
32
- meta_inf.each { |file| zip.add "META-INF/#{File.basename(file)}", file } if meta_inf
69
+ meta_inf.map(&:to_s).uniq.each { |file| zip.add "META-INF/#{File.basename(file)}", file }
33
70
  unless manifest == false
34
71
  zip.file.open("META-INF/MANIFEST.MF", "w") do |output|
35
72
  output.write MANIFEST_HEADER
@@ -56,14 +93,24 @@ module Buildr
56
93
 
57
94
  end
58
95
 
96
+ # Extends the JarTask to create a WAR file.
97
+ #
98
+ # Supports all the same options as JarTask, in additon to these two options:
99
+ # * :libs -- An array of files, tasks, artifact specifications, etc that will be added
100
+ # to the WEB-INF/lib directory.
101
+ # * :classes -- A directory containing class files for inclusion in the WEB-INF/classes
102
+ # directory.
103
+ #
104
+ # For example:
105
+ # package(:war).using(:libs=>"log4j:log4j:jar:1.1")
59
106
  class WarTask < JarTask
60
107
 
61
- def []=(key, value)
108
+ def []=(key, value) #:nodoc:
62
109
  case key.to_sym
63
110
  when :libs
64
111
  self.include artifacts(value), :path=>"WEB-INF/lib"
65
112
  when :classes
66
- self.include value, :path=>"WEB-INF/classes"
113
+ self.include value, :path=>"WEB-INF/classes", :as=>"."
67
114
  else
68
115
  super key, value
69
116
  end
@@ -76,155 +123,240 @@ module Buildr
76
123
  end
77
124
 
78
125
 
79
- # Create a JAR from all the pre-requisites.
80
- #
81
- # For example:
82
- # jar "lib-1.0.jar"=>["target/classes", "MANIFEST,MF"]
83
- def jar(file)
84
- Packaging::JarTask.define_task(file)
85
- end
86
-
87
126
  class Project
88
127
 
89
- # Group used for packaging. Inherited from parent project.
90
- inherited_attr :group
128
+ # Group used for packaging. Inherited from parent project. Defaults to the top-level project name.
129
+ attr_accessor :group
130
+ inherited_attr(:group) { |project| project.name }
91
131
  # Version used for packaging. Inherited from parent project.
132
+ attr_accessor :version
92
133
  inherited_attr :version
93
- # Manifest used for packaging. Inherited from parent project.
134
+ # Manifest used for packaging. Inherited from parent project. The default value
135
+ # is a hash that includes the Build-By, Build-Jdk and Implementation-Version values.
136
+ # The later is taken from the project's version number.
137
+ attr_accessor :manifest
94
138
  inherited_attr :manifest do |project|
95
139
  manifest = { "Build-By"=>ENV['USER'], "Build-Jdk"=>Java.version }
96
140
  manifest["Implementation-Version"] = project.version if project.version
97
141
  manifest
98
142
  end
99
- # Files to always include in the package META-INF directory.
100
- inherited_attr :meta_inf do |project|
101
- meta_inf = ["DISCLAIMER", "LICENSE", "NOTICE"].map { |f| path_to(f) if File.exist?(path_to(f)) }.compact
143
+ # Files to always include in the package META-INF directory. The default value include
144
+ # the LICENSE file if one exists in the project's base directory.
145
+ attr_accessor :meta_inf
146
+ inherited_attr(:meta_inf) do |project|
147
+ license = project.file("LICENSE")
148
+ File.exist?(license.to_s) ? [license] : []
102
149
  end
103
150
 
104
- # The project ID is the project name, and for a sub-project the
105
- # parent project ID followed by the project name, separated with a
106
- # hyphen. For example, "foo" and "foo-bar".
151
+ # The project's identifier. Same as the project name, with colons replaced by dashes.
152
+ # The ID for project foo:bar is foo-bar.
153
+ attr_reader :id
107
154
  def id()
108
155
  name.gsub(":", "-")
109
156
  end
110
- inherited_attr :webapp_src_dir do File.join(src_dir, "main", "webapp") end
111
157
 
112
- def package(*args)
113
- if Hash === args.last
114
- options = args.pop.dup
115
- else
116
- options = {}
117
- end
118
- options[:type] = args.shift.to_s if Symbol === args.first
119
- fail "No packaging type specified" unless options[:type]
158
+ # :call-seq:
159
+ # package(type, options?) => task
160
+ #
161
+ # Defines and returns a package created by this project.
162
+ #
163
+ # The first argument declares the package type. For example, :jar to create a JAR file.
164
+ # The second argument provides additional options used when defining the package.
165
+ #
166
+ # The following options are supported by all package types:
167
+ # * :file_name -- The package file name. By default it uses the artifact identifier,
168
+ # version number and file type to create a file name (id-version.type).
169
+ # * :id -- The artifact identifier. By default, uses the project's #id property.
170
+ # * :group -- The group identifier. By default, uses the project's #group property.
171
+ # * :version -- The version number. By default, uses the project's #version property.
172
+ # * :classifier -- Artifact classifier. By default, the artifact has no classifier.
173
+ #
174
+ # The JAR packager adds the following options:
175
+ # * :manifest -- Specifies how to create the MANIFEST.MF. By default, uses the project's
176
+ # #manifest property.
177
+ # * :meta_inf -- Specifies files to be included in the META-INF directory. By default,
178
+ # uses the project's #meta-inf property.
179
+ # * :include -- List of files and directories to include in the JAR. By default,
180
+ # includes the contents of the target/classes directory.
181
+ #
182
+ # The WAR packager adds the following options:
183
+ # * :manifest -- See JAR.
184
+ # * :meta_inf -- See JAR.
185
+ # * :classes -- Directories of class files to include in WEB-INF/classes. By default,
186
+ # includes the contents of the target/classes directory.
187
+ # * :libs -- Artifacts and files to include in WEB-INF/libs. By default, includes the
188
+ # compile classpath.
189
+ # * :include -- List of files and directories to include in the JAR. By default,
190
+ # includes the contents of the src/main/webapp directory.
191
+ #
192
+ # The ZIP packager adds the following options:
193
+ # * :include -- List of file and directories to include in the ZIP.
194
+ #
195
+ # In addition, you can always enhance the package task directly, e.g. by calling the
196
+ # ZipTask#include and ZipTask#with methods.
197
+ #
198
+ # For example:
199
+ # define "project" do
200
+ # define "beans" do
201
+ # package :jar
202
+ # end
203
+ # define "webapp" do
204
+ # compile.with project("beans")
205
+ # package :war
206
+ # end
207
+ # package :zip, :classifier=>"sources", :include=>"."
208
+ # end
209
+ #
210
+ # The first time you call package, it defines the new task. Afterwards, it only uses some of the
211
+ # options (file_name, id, etc) to find an existing package task and return it.
212
+ #
213
+ # For example:
214
+ # # Create a new package that includes an existing package.
215
+ # package(:war).include project("foo:bar").package(:jar)
216
+ #
217
+ # A package is also an artifact. The following tasks operate on packages created by the project:
218
+ # rake deploy # Deploy packages created by the project
219
+ # rake install # Install packages created by the project
220
+ # rake package # Create packages
221
+ # rake uninstall # Remove previously installed packages
222
+ #
223
+ # If you want to add additional packaging types, implement a method with the name package_as_[type]
224
+ # that accepts two arguments, the file name and a hash of options. The method must yield to the
225
+ # block with the package only when first called to define the package, and must return the package
226
+ # from each call.
227
+ def package(type, options = nil)
228
+ options = options.nil? ? {} : options.dup
229
+ options[:id] ||= self.id
120
230
  options[:group] ||= self.group
121
231
  options[:version] ||= self.version
122
- options[:id] ||= self.id
123
- if String === args.first
124
- file = args.shift
125
- else
126
- file = options.delete(:file) || path_to(:target_dir, Artifact.hash_to_file_name(options))
127
- end
128
- fail "One argument too many; expecting at most type, file name, and hash of options" unless args.empty?
129
-
130
- packager = method("package_as_#{options[:type]}") rescue
131
- fail("Do not know how to create a package of type #{options[:type]}")
132
- package = packager.call(file, options) or fail("Do not know how to create a package of type #{options[:type]}")
133
-
134
- task "package"=>package
135
- package.enhance [ task("build")]
136
-
137
- task "install"=>(file(repositories.locate(package)=>package) { |task|
138
- mkpath File.dirname(task.name), :verbose=>false
139
- cp package.name, task.name
140
- })
141
- task "install"=>package.pom
232
+ options[:type] = type
233
+ file_name = options[:file_name] || path_to("target", Artifact.hash_to_file_name(options))
234
+
235
+ packager = method("package_as_#{type}") rescue
236
+ fail("Do not know how to create a package of type #{:type}")
237
+ packager.call(file_name, options) do |package|
238
+ # Make it an artifact using the specifications, and tell it how to create a POM.
239
+ package.extend ActsAsArtifact
240
+ package.send :apply_spec, options
241
+ package.pom.enhance do |pom|
242
+ mkpath File.dirname(pom.name), :verbose=>false
243
+ File.open(pom.name, "w") do |file|
244
+ xml = Builder::XmlMarkup.new(:target=>file, :indent=>2)
245
+ xml.instruct!
246
+ xml.project do
247
+ xml.modelVersion "4.0.0"
248
+ xml.groupId options[:group]
249
+ xml.artifactId options[:id]
250
+ xml.version options[:version]
251
+ xml.classifier options[:classifier] if options[:classifier]
252
+ end
253
+ end
254
+ end
142
255
 
143
- task "uninstall" do |task|
144
- verbose(Rake.application.options.trace) do
145
- [ package, package.pom ].map { |artifact| repositories.locate(artifact) }.
146
- each { |file| rm file if File.exist?(file) }
256
+ # Make sure the package task creates it, and it invokes the build task first.
257
+ task "package"=>package
258
+ package.enhance [task("build")]
259
+
260
+ # Install the artifact along with its POM. Since the artifact (package task) is created
261
+ # in the target directory, we need to copy it into the local repository. However, the
262
+ # POM artifact (created by calling artifact on its spec) is already mapped to its right
263
+ # place in the local repository, so we only need to invoke it.
264
+ installed = file(repositories.locate(package)=>package) { |task|
265
+ verbose(Rake.application.options.trace || false) do
266
+ mkpath File.dirname(task.name), :verbose=>false
267
+ cp package.name, task.name
268
+ end
269
+ puts "Installed #{task.name}" if verbose
270
+ }
271
+ task "install"=>[installed, package.pom]
272
+ task "uninstall" do |task|
273
+ verbose(Rake.application.options.trace || false) do
274
+ [ installed, package.pom ].map(&:to_s).each { |file| rm file if File.exist?(file) }
275
+ end
147
276
  end
277
+ task("deploy") { deploy(installed, package.pom) }
278
+
279
+ # Add the package to the list of packages created by this project, and
280
+ # register it as an artifact. The later is required so if we look up the spec
281
+ # we find the package in the project's target directory, instead of finding it
282
+ # in the local repository and attempting to install it.
283
+ packages << package
284
+ Artifact.register package, package.pom
148
285
  end
149
-
150
- task("deploy") { deploy(package, package.pom) }
151
-
152
- packages << package
153
- Artifact.register package, package.pom
154
- package
155
286
  end
156
287
 
288
+ # :call-seq:
289
+ # packages() => tasks
290
+ #
291
+ # Returns all packages created by this project. A project may create any number of packages.
292
+ #
293
+ # This method is used whenever you pass a project to Buildr#artifact or any other method
294
+ # that accepts artifact specifications and projects. You can use it to list all packages
295
+ # created by the project. If you want to return a specific package, it is often more
296
+ # convenient to call #package with the type.
157
297
  def packages()
158
298
  @packages ||= []
159
299
  end
160
300
 
161
301
  protected
162
302
 
163
- def package_as_jar(file, options)
164
- unless Rake::Task.task_defined?(file)
165
- returning(Java::Packaging::JarTask.define_task(file)) do |task|
166
- package_extend task, options
167
- task.enhance [path_to(:java_target_dir)]
168
- task.include path_to(:java_target_dir, "*")
169
- task.manifest = manifest.merge("Implementation-Title"=>self.comment)
170
- task.meta_inf = meta_inf
171
- end
172
- end
173
- returning(Java::Packaging::JarTask.define_task(file)) do |task|
174
- task.include options[:include] if options[:include]
175
- task.manifest = options[:manifest] if options[:manifest]
176
- end
177
- end
178
-
179
- def package_as_war(file, options)
180
- unless Rake::Task.task_defined?(file)
181
- returning(Java::Packaging::WarTask.define_task(file)) do |task|
182
- package_extend task, options
183
- task.include path_to(:webapp_src_dir, "*")
184
- task.with :classes=>path_to(:java_target_dir, "**")
185
- task.manifest = manifest.merge("Implementation-Title"=>self.comment)
186
- task.meta_inf = meta_inf
303
+ def package_as_jar(file_name, options) #:nodoc:
304
+ unless Rake::Task.task_defined?(file_name)
305
+ Java::Packaging::JarTask.define_task(file_name).tap do |jar|
306
+ jar.manifest = options[:manifest] || manifest.merge("Implementation-Title"=>self.comment)
307
+ jar.meta_inf = options[:meta_inf] || meta_inf
308
+ if options[:include]
309
+ jar.include options[:include]
310
+ else
311
+ # Can only decide on this once we're done configuring the compile task.
312
+ enhance { jar.include compile.target, :as=>"." }
313
+ end
314
+ yield jar
187
315
  end
188
316
  end
189
- # Add anything we find in webapp sources directory.
190
- returning(Java::Packaging::WarTask.define_task(file)) do |task|
191
- task.include options[:include] if options[:include]
192
- # Add libraries in WEB-INF lib, and classes in WEB-INF classes
193
- task.with :libs=>options[:libs].collect if options[:libs]
194
- task.with :classes=>options[:classes] if options[:classes]
195
- task.manifest = options[:manifest] if options[:manifest]
196
- end
317
+ file(file_name)
197
318
  end
198
319
 
199
- def package_as_zip(file, options)
200
- unless Rake::Task.task_defined?(file)
201
- returning(ZipTask.define_task(file)) do |task|
202
- package_extend task, options
203
- task.include path_to(:java_target_dir, "*")
320
+ def package_as_war(file_name, options) #:nodoc:
321
+ unless Rake::Task.task_defined?(file_name)
322
+ Java::Packaging::WarTask.define_task(file_name).tap do |war|
323
+ war.manifest = options[:manifest] || manifest.merge("Implementation-Title"=>self.comment)
324
+ war.meta_inf = options[:meta_inf] || meta_inf
325
+ # Add libraries in WEB-INF lib, and classes in WEB-INF classes
326
+ if options[:classes]
327
+ war.with :classes=>options[:classes]
328
+ else
329
+ # Can only decide on this once we're done configuring the compile task.
330
+ enhance { war.with :classes=>compile.target unless compile.sources.empty? }
331
+ end
332
+ if options[:libs]
333
+ war.with :libs=>options[:libs].collect
334
+ else
335
+ # Can only decide on this once we're done configuring the compile task.
336
+ enhance { war.with :libs=>compile.classpath }
337
+ end
338
+ # Add included files, or the webapp directory.
339
+ if options[:include]
340
+ war.include options[:include]
341
+ elsif File.exist?(path_to("src/main/webapp"))
342
+ war.include path_to("src/main/webapp"), :as=>"."
343
+ end
344
+ yield war
204
345
  end
205
346
  end
206
- returning(ZipTask.define_task(file)) do |task|
207
- task.include options[:include] if options[:include]
208
- end
347
+ file(file_name)
209
348
  end
210
349
 
211
- def package_extend(task, spec)
212
- task.extend ActsAsArtifact
213
- task.apply_spec spec
214
- task.pom.enhance do |task|
215
- mkpath File.dirname(task.name), :verbose=>false
216
- File.open(task.name, "w") do |file|
217
- xml = Builder::XmlMarkup.new(:target=>file, :indent=>2)
218
- xml.instruct!
219
- xml.project do
220
- xml.modelVersion "4.0.0."
221
- xml.groupId spec[:group]
222
- xml.artifactId spec[:id]
223
- xml.version spec[:version]
224
- xml.classifier spec[:classifier] if spec[:classifier]
350
+ def package_as_zip(file_name, options) #:nodoc:
351
+ unless Rake::Task.task_defined?(file_name)
352
+ ZipTask.define_task(file_name).tap do |zip|
353
+ if options[:include]
354
+ zip.include options[:include]
225
355
  end
356
+ yield zip
226
357
  end
227
358
  end
359
+ file(file_name)
228
360
  end
229
361
 
230
362
  end