C0 code coverage information
Generated on Wed Oct 07 08:34:02 -0700 2009 with rcov 0.8.2.1
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 # Licensed to the Apache Software Foundation (ASF) under one or more
2 # contributor license agreements. See the NOTICE file distributed with this
3 # work for additional information regarding copyright ownership. The ASF
4 # licenses this file to you under the Apache License, Version 2.0 (the
5 # "License"); you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations under
14 # the License.
15
16
17 require 'buildr/packaging'
18
19
20 module Buildr
21 module Packaging #:nodoc:
22
23 # Adds packaging for Java projects: JAR, WAR, AAR, EAR, Javadoc.
24 module Java
25
26 class Manifest
27
28 STANDARD_HEADER = { 'Manifest-Version'=>'1.0', 'Created-By'=>'Buildr' }
29 LINE_SEPARATOR = /\r\n|\n|\r[^\n]/ #:nodoc:
30 SECTION_SEPARATOR = /(#{LINE_SEPARATOR}){2}/ #:nodoc:
31
32 class << self
33
34 # :call-seq:
35 # parse(str) => manifest
36 #
37 # Parse a string in MANIFEST.MF format and return a new Manifest.
38 def parse(str)
39 sections = str.split(SECTION_SEPARATOR).reject { |s| s.strip.empty? }
40 new sections.map { |section|
41 lines = section.split(LINE_SEPARATOR).inject([]) { |merged, line|
42 if line[/^ /] == ' '
43 merged.last << line[1..-1]
44 else
45 merged << line
46 end
47 merged
48 }
49 lines.map { |line| line.scan(/(.*?):\s*(.*)/).first }.
50 inject({}) { |map, (key, value)| map.merge(key=>value) }
51 }
52 end
53
54 # :call-seq:
55 # from_zip(file) => manifest
56 #
57 # Parse the MANIFEST.MF entry of a ZIP (or JAR) file and return a new Manifest.
58 def from_zip(file)
59 Zip::ZipFile.open(file.to_s) do |zip|
60 Manifest.parse zip.read('META-INF/MANIFEST.MF') rescue Manifest.new
61 end
62 end
63
64 # :call-seq:
65 # update_manifest(file) { |manifest| ... }
66 #
67 # Updates the MANIFEST.MF entry of a ZIP (or JAR) file. Reads the MANIFEST.MF,
68 # yields to the block with the Manifest object, and writes the modified object
69 # back to the file.
70 def update_manifest(file)
71 manifest = from_zip(file)
72 result = yield manifest
73 Zip::ZipFile.open(file.to_s) do |zip|
74 zip.get_output_stream('META-INF/MANIFEST.MF') do |out|
75 out.write manifest.to_s
76 out.write "\n"
77 end
78 end
79 result
80 end
81
82 end
83
84 # Returns a new Manifest object based on the argument:
85 # * nil -- Empty Manifest.
86 # * Hash -- Manifest with main section using the hash name/value pairs.
87 # * Array -- Manifest with one section from each entry (must be hashes).
88 # * String -- Parse (see Manifest#parse).
89 # * Proc/Method -- New Manifest from result of calling proc/method.
90 def initialize(arg = nil)
91 case arg
92 when nil, Hash then @sections = [arg || {}]
93 when Array then @sections = arg
94 when String then @sections = Manifest.parse(arg).sections
95 when Proc, Method then @sections = Manifest.new(arg.call).sections
96 else
97 fail 'Invalid manifest, expecting Hash, Array, file name/task or proc/method.'
98 end
99 # Add Manifest-Version and Created-By, if not specified.
100 STANDARD_HEADER.each do |name, value|
101 sections.first[name] ||= value
102 end
103 end
104
105 # The sections of this manifest.
106 attr_reader :sections
107
108 # The main (first) section of this manifest.
109 def main
110 sections.first
111 end
112
113 include Enumerable
114
115 # Iterate over each section and yield to block.
116 def each(&block)
117 @sections.each(&block)
118 end
119
120 # Convert to MANIFEST.MF format.
121 def to_s
122 @sections.map { |section|
123 keys = section.keys
124 keys.unshift('Name') if keys.delete('Name')
125 lines = keys.map { |key| manifest_wrap_at_72("#{key}: #{section[key]}") }
126 lines + ['']
127 }.flatten.join("\n")
128 end
129
130 private
131
132 def manifest_wrap_at_72(line)
133 return [line] if line.size < 72
134 [ line[0..70] ] + manifest_wrap_at_72(' ' + line[71..-1])
135 end
136
137 end
138
139
140 # Adds support for MANIFEST.MF and other META-INF files.
141 module WithManifest #:nodoc:
142
143 class << self
144 def included(base)
145 base.class_eval do
146 alias :initialize_without_manifest :initialize
147 alias :initialize :initialize_with_manifest
148 end
149 end
150
151 end
152
153 # Specifies how to create the manifest file.
154 attr_accessor :manifest
155
156 # Specifies files to include in the META-INF directory.
157 attr_accessor :meta_inf
158
159 def initialize_with_manifest(*args) #:nodoc:
160 initialize_without_manifest *args
161 @manifest = false
162 @meta_inf = []
163 @dependencies = FileList[]
164
165 prepare do
166 @prerequisites << manifest if String === manifest || Rake::Task === manifest
167 [meta_inf].flatten.map { |file| file.to_s }.uniq.each { |file| path('META-INF').include file }
168 end
169
170 enhance do
171 if manifest
172 # Tempfiles gets deleted on garbage collection, so we're going to hold on to it
173 # through instance variable not closure variable.
174 @manifest_tmp = Tempfile.new('MANIFEST.MF')
175 self.manifest = File.read(manifest.to_s) if String === manifest || Rake::Task === manifest
176 self.manifest = Manifest.new(manifest) unless Manifest === manifest
177 #@manifest_tmp.write Manifest::STANDARD_HEADER
178 @manifest_tmp.write manifest.to_s
179 @manifest_tmp.write "\n"
180 @manifest_tmp.rewind
181 path('META-INF').include @manifest_tmp.path, :as=>'MANIFEST.MF'
182 end
183 end
184 end
185
186 end
187
188 class ::Buildr::ZipTask
189 include WithManifest
190 end
191
192
193 # Extends the ZipTask to create a JAR file.
194 #
195 # This task supports two additional attributes: manifest and meta-inf.
196 #
197 # The manifest attribute specifies how to create the MANIFEST.MF file.
198 # * A hash of manifest properties (name/value pairs).
199 # * An array of hashes, one for each section of the manifest.
200 # * A string providing the name of an existing manifest file.
201 # * A file task can be used the same way.
202 # * Proc or method called to return the contents of the manifest file.
203 # * False to not generate a manifest file.
204 #
205 # The meta-inf attribute lists one or more files that should be copied into
206 # the META-INF directory.
207 #
208 # For example:
209 # package(:jar).with(:manifest=>'src/MANIFEST.MF')
210 # package(:jar).meta_inf << file('README')
211 class JarTask < ZipTask
212
213 def initialize(*args) #:nodoc:
214 super
215 end
216
217 # :call-seq:
218 # with(options) => self
219 #
220 # Additional
221 # Pass options to the task. Returns self. ZipTask itself does not support any options,
222 # but other tasks (e.g. JarTask, WarTask) do.
223 #
224 # For example:
225 # package(:jar).with(:manifest=>'MANIFEST_MF')
226 def with(*args)
227 super args.pop if Hash === args.last
228 include :from=>args
229 self
230 end
231
232 end
233
234
235 # Extends the JarTask to create a WAR file.
236 #
237 # Supports all the same options as JarTask, in additon to these two options:
238 # * :libs -- An array of files, tasks, artifact specifications, etc that will be added
239 # to the WEB-INF/lib directory.
240 # * :classes -- A directory containing class files for inclusion in the WEB-INF/classes
241 # directory.
242 #
243 # For example:
244 # package(:war).with(:libs=>'log4j:log4j:jar:1.1')
245 class WarTask < JarTask
246
247 # Directories with class files to include under WEB-INF/classes.
248 attr_accessor :classes
249
250 # Artifacts to include under WEB-INF/libs.
251 attr_accessor :libs
252
253 def initialize(*args) #:nodoc:
254 super
255 @classes = []
256 @libs = []
257 prepare do
258 @classes.to_a.flatten.each { |classes| path('WEB-INF/classes').include classes, :as=>'.' }
259 path('WEB-INF/lib').include Buildr.artifacts(@libs) unless @libs.nil? || @libs.empty?
260 end
261 end
262
263 def libs=(value) #:nodoc:
264 @libs = Buildr.artifacts(value)
265 end
266
267 def classes=(value) #:nodoc:
268 @classes = [value].flatten.map { |dir| file(dir.to_s) }
269 end
270
271 end
272
273
274 # Extends the JarTask to create an AAR file (Axis2 service archive).
275 #
276 # Supports all the same options as JarTask, with the addition of :wsdls, :services_xml and :libs.
277 #
278 # * :wsdls -- WSDL files to include (under META-INF). By default packaging will include all WSDL
279 # files found under src/main/axis2.
280 # * :services_xml -- Location of services.xml file (included under META-INF). By default packaging
281 # takes this from src/main/axis2/services.xml. Use a different path if you genereate the services.xml
282 # file as part of the build.
283 # * :libs -- Array of files, tasks, artifact specifications, etc that will be added to the /lib directory.
284 #
285 # For example:
286 # package(:aar).with(:libs=>'log4j:log4j:jar:1.1')
287 #
288 # filter.from('src/main/axis2').into('target').include('services.xml', '*.wsdl').using('http_port'=>'8080')
289 # package(:aar).wsdls.clear
290 # package(:aar).with(:services_xml=>_('target/services.xml'), :wsdls=>_('target/*.wsdl'))
291 class AarTask < JarTask
292 # Artifacts to include under /lib.
293 attr_accessor :libs
294 # WSDLs to include under META-INF (defaults to all WSDLs under src/main/axis2).
295 attr_accessor :wsdls
296 # Location of services.xml file (defaults to src/main/axis2/services.xml).
297 attr_accessor :services_xml
298
299 def initialize(*args) #:nodoc:
300 super
301 @libs = []
302 @wsdls = []
303 prepare do
304 path('META-INF').include @wsdls
305 path('META-INF').include @services_xml, :as=>'services.xml' if @services_xml
306 path('lib').include Buildr.artifacts(@libs) unless @libs.nil? || @libs.empty?
307 end
308 end
309
310 def libs=(value) #:nodoc:
311 @libs = Buildr.artifacts(value)
312 end
313
314 def wsdls=(value) #:nodoc:
315 @wsdls |= Array(value)
316 end
317 end
318
319
320 # Extend the JarTask to create an EAR file.
321 #
322 # The following component types are supported by the EARTask:
323 #
324 # * :war -- A J2EE Web Application
325 # * :ejb -- An Enterprise Java Bean
326 # * :jar -- A J2EE Application Client.[1]
327 # * :lib -- An ear scoped shared library[2] (for things like logging,
328 # spring, etc) common to the ear components
329 #
330 # The EarTask uses the "Mechanism 2: Bundled Optional Classes" as described on [2].
331 # All specified libraries are added to the EAR archive and the Class-Path manifiest entry is
332 # modified for each EAR component. Special care is taken with WebApplications, as they can
333 # contain libraries on their WEB-INF/lib directory, libraries already included in a war file
334 # are not referenced by the Class-Path entry of the war in order to avoid class collisions
335 #
336 # EarTask supports all the same options as JarTask, in additon to these two options:
337 #
338 # * :display_name -- The displayname to for this ear on application.xml
339 #
340 # * :map -- A Hash used to map component type to paths within the EAR.
341 # By default each component type is mapped to a directory with the same name,
342 # for example, EJBs are stored in the /ejb path. To customize:
343 # package(:ear).map[:war] = 'web-applications'
344 # package(:ear).map[:lib] = nil # store shared libraries on root of archive
345 #
346 # EAR components are added by means of the EarTask#add, EarTask#<<, EarTask#push methods
347 # Component type is determined from the artifact's type.
348 #
349 # package(:ear) << project('coolWebService').package(:war)
350 #
351 # The << method is just an alias for push, with the later you can add multiple components
352 # at the same time. For example..
353 #
354 # package(:ear).push 'org.springframework:spring:jar:2.6',
355 # projects('reflectUtils', 'springUtils'),
356 # project('coolerWebService').package(:war)
357 #
358 # The add method takes a single component with an optional hash. You can use it to override
359 # some component attributes.
360 #
361 # You can override the component type for a particular artifact. The following example
362 # shows how you can tell the EarTask to treat a JAR file as an EJB:
363 #
364 # # will add an ejb entry for the-cool-ejb-2.5.jar in application.xml
365 # package(:ear).add 'org.coolguys:the-cool-ejb:jar:2.5', :type=>:ejb
366 # # A better syntax for this is:
367 # package(:ear).add :ejb=>'org.coolguys:the-cool-ejb:jar:2.5'
368 #
369 # By default, every JAR package is assumed to be a library component, so you need to specify
370 # the type when including an EJB (:ejb) or Application Client JAR (:jar).
371 #
372 # For WebApplications (:war)s, you can customize the context-root that appears in application.xml.
373 # The following example also specifies a different directory inside the EAR where to store the webapp.
374 #
375 # package(:ear).add project(:remoteService).package(:war),
376 # :path=>'web-services', :context_root=>'/Some/URL/Path'
377 #
378 # [1] http://java.sun.com/j2ee/sdk_1.2.1/techdocs/guides/ejb/html/Overview5.html#10106
379 # [2] http://java.sun.com/j2ee/verified/packaging.html
380 class EarTask < JarTask
381
382 SUPPORTED_TYPES = [:war, :ejb, :jar, :rar, :lib]
383
384 # The display-name entry for application.xml
385 attr_accessor :display_name
386 # Map from component type to path inside the EAR.
387 attr_accessor :dirs
388
389 def initialize(*args)
390 super
391 @dirs = Hash.new { |h, k| k.to_s }
392 @libs, @components = [], []
393 prepare do
394 @components.each do |component|
395 path(component[:path]).include(component[:clone] || component[:artifact])
396 end
397 path('META-INF').include(descriptor)
398 end
399 end
400
401 # Add an artifact to this EAR.
402 def add(*args)
403 options = Hash === args.last ? args.pop.clone : {}
404 args.flatten!
405 args.map! do |pkg|
406 case pkg
407 when Project
408 pkg.packages.select { |pp| JarTask === pp && SUPPORTED_TYPES.include?(pp.type) }
409 when Rake::FileTask
410 pkg # add the explicitly provided file
411 when Hash
412 Buildr.artifact(pkg)
413 when String
414 begin
415 Buildr.artifact(pkg)
416 rescue # not an artifact spec, it must me a filename
417 file(pkg)
418 end
419 else
420 raise "Invalid EAR component #{pkg.class}: #{pkg}"
421 end
422 end
423 args.flatten!
424 args.compact!
425 if args.empty?
426 raise ":type must not be specified for type=>component argument style" if options.key?(:type)
427 raise ":as must not be specified for type=>component argument style" if options.key?(:as)
428 comps = {}
429 options.delete_if { |k, v| comps[k] = v if SUPPORTED_TYPES.include?(k) }
430 raise "You must specify at least one valid component to add" if comps.empty?
431 comps.each { |k, v| add(v, {:as => k}.merge(options)) }
432 else
433 args.each do |artifact|
434 type = options[:as] || options[:type]
435 unless type
436 type = artifact.respond_to?(:type) ? artifact.type : artifact.to_s.pathmap('%x').to_sym
437 type = :lib if type == :jar
438 end
439 raise "Unknown EAR component type: #{type}. Perhaps you may explicity tell what component type to use." unless
440 SUPPORTED_TYPES.include?(type)
441 component = options.merge(:artifact => artifact, :type => type,
442 :id=>artifact.respond_to?(:to_spec) ? artifact.id : artifact.to_s.pathmap('%n'),
443 :path=>options[:path] || dirs[type].to_s)
444 component[:clone] = component_clone(component) unless :lib == type
445 # update_classpath(component) unless :lib == type || Artifact === artifact
446 @components << component
447 end
448 end
449 self
450 end
451
452 alias_method :push, :add
453 alias_method :<<, :push
454
455 protected
456
457 def component_clone(component)
458 file(path_to(component[:path], component[:artifact].to_s.pathmap('%f')) => component[:artifact]) do |task|
459 mkpath task.to_s.pathmap('%d')
460 cp component[:artifact].to_s, task.to_s
461 Manifest.update_manifest(task) do |manifest|
462 class_path = manifest.main['Class-Path'].to_s.split
463 included_libs = class_path.map { |fn| fn.pathmap('%f') }
464 Zip::ZipFile.foreach(task.to_s) do |entry|
465 included_libs << entry.name.pathmap('%f') if entry.file? && entry.name =~ /^WEB-INF\/lib\/[^\/]+$/
466 end
467 # Include all other libraries in the classpath.
468 class_path += libs_classpath(component).reject { |path| included_libs.include?(File.basename(path)) }
469 manifest.main['Class-Path'] = class_path.join(' ')
470 end
471 end
472 end
473
474 def associate(project)
475 @project = project
476 end
477
478 def path_to(*args) #:nodoc:
479 @project.path_to(:target, :ear, name.pathmap('%n'), *args)
480 end
481 alias_method :_, :path_to
482
483 def update_classpath(component)
484 package = file(component[:artifact].to_s)
485 package.manifest = (package.manifest || {}).dup # avoid mofifying parent projects manifest
486 package.prepare do
487 header = case package.manifest
488 when Hash then package.manifest
489 when Array then package.manifest.first
490 end
491 if header
492 # Determine which libraries are already included.
493 class_path = header['Class-Path'].to_s.split
494 included_libs = class_path.map { |fn| File.basename(fn) }
495 included_libs += package.path('WEB-INF/lib').sources.map { |fn| File.basename(fn) }
496 # Include all other libraries in the classpath.
497 class_path += libs_classpath(component).reject { |path| included_libs.include?(File.basename(path)) }
498 header['Class-Path'] = class_path.join(' ')
499 end
500 end
501 end
502
503 private
504
505 # Classpath of all packages included as libraries (type :lib).
506 def libs_classpath(component)
507 from = component[:path]
508 @classpath = @components.select { |comp| comp[:type] == :lib }.
509 map do |lib|
510 basename = lib[:artifact].to_s.pathmap('%f')
511 full_path = lib[:path].empty? ? basename : File.join(lib[:path], basename)
512 Util.relative_path(full_path, from)
513 end
514 end
515
516 def descriptor_xml
517 buffer = ""
518 xml = Builder::XmlMarkup.new(:target=>buffer, :indent => 2)
519 xml.declare! :DOCTYPE, :application, :PUBLIC,
520 "-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN",
521 "http://java.sun.com/j2ee/dtds/application_1_2.dtd"
522 xml.application do
523 xml.tag! 'display-name', display_name
524 @components.each do |comp|
525 basename = comp[:artifact].to_s.pathmap('%f')
526 uri = comp[:path].empty? ? basename : File.join(comp[:path], basename)
527 case comp[:type]
528 when :war
529 xml.module :id=>comp[:id] do
530 xml.web do
531 xml.tag! 'web-uri', uri
532 xml.tag! 'context-root', File.join('', (comp[:context_root] || comp[:id])) unless comp[:context_root] == false
533 end
534 end
535 when :ejb
536 xml.module :id=>comp[:id] do
537 xml.ejb uri
538 end
539 when :jar
540 xml.jar uri
541 end
542 end
543 end
544 buffer
545 end
546
547 # return a FileTask to build the ear application.xml file
548 def descriptor
549 return @descriptor if @descriptor
550 descriptor_path = path_to('META-INF/application.xml')
551 @descriptor = file(descriptor_path) do |task|
552 trace "Creating EAR Descriptor: #{task.to_s}"
553 mkpath File.dirname(task.name)
554 File.open(task.name, 'w') { |file| file.print task.xml }
555 end
556 class << @descriptor
557 attr_accessor :ear
558
559 def xml
560 @xml ||= ear.send :descriptor_xml
561 end
562
563 def needed?
564 super || xml != File.read(self.to_s) rescue true
565 end
566 end
567 @descriptor.ear = self
568 @descriptor
569 end
570
571 end
572
573
574 include Extension
575
576 before_define do |project|
577 ::Java.load
578 if project.parent && project.parent.manifest
579 project.manifest = project.parent.manifest.dup
580 else
581 project.manifest = {
582 'Build-By'=>ENV['USER'], 'Build-Jdk'=>ENV_JAVA['java.version'],
583 'Implementation-Title'=>project.comment || project.name,
584 'Implementation-Version'=>project.version }
585 end
586 if project.parent && project.parent.meta_inf
587 project.meta_inf = project.parent.meta_inf.dup
588 else
589 project.meta_inf = [project.file('LICENSE')].select { |file| File.exist?(file.to_s) }
590 end
591 end
592
593
594 # Manifest used for packaging. Inherited from parent project. The default value is a hash that includes
595 # the Build-By, Build-Jdk, Implementation-Title and Implementation-Version values.
596 # The later are taken from the project's comment (or name) and version number.
597 attr_accessor :manifest
598
599 # Files to always include in the package META-INF directory. The default value include
600 # the LICENSE file if one exists in the project's base directory.
601 attr_accessor :meta_inf
602
603 # :call-seq:
604 # package_with_sources(options?)
605 #
606 # Call this when you want the project (and all its sub-projects) to create a source distribution.
607 # You can use the source distribution in an IDE when debugging.
608 #
609 # A source distribution is a ZIP package with the classifier 'sources', which includes all the
610 # sources used by the compile task.
611 #
612 # Packages use the project's manifest and meta_inf properties, which you can override by passing
613 # different values (e.g. false to exclude the manifest) in the options.
614 #
615 # To create source distributions only for specific projects, use the :only and :except options,
616 # for example:
617 # package_with_sources :only=>['foo:bar', 'foo:baz']
618 #
619 # (Same as calling package :sources on each project/sub-project that has source directories.)
620 def package_with_sources(options = nil)
621 options ||= {}
622 enhance do
623 selected = options[:only] ? projects(options[:only]) :
624 options[:except] ? ([self] + projects - projects(options[:except])) :
625 [self] + projects
626 selected.reject { |project| project.compile.sources.empty? }.
627 each { |project| project.package(:sources) }
628 end
629 end
630
631 # :call-seq:
632 # package_with_javadoc(options?)
633 #
634 # Call this when you want the project (and all its sub-projects) to create a JavaDoc distribution.
635 # You can use the JavaDoc distribution in an IDE when coding against the API.
636 #
637 # A JavaDoc distribution is a ZIP package with the classifier 'javadoc', which includes all the
638 # sources used by the compile task.
639 #
640 # Packages use the project's manifest and meta_inf properties, which you can override by passing
641 # different values (e.g. false to exclude the manifest) in the options.
642 #
643 # To create JavaDoc distributions only for specific projects, use the :only and :except options,
644 # for example:
645 # package_with_javadoc :only=>['foo:bar', 'foo:baz']
646 #
647 # (Same as calling package :javadoc on each project/sub-project that has source directories.)
648 def package_with_javadoc(options = nil)
649 options ||= {}
650 enhance do
651 selected = options[:only] ? projects(options[:only]) :
652 options[:except] ? ([self] + projects - projects(options[:except])) :
653 [self] + projects
654 selected.reject { |project| project.compile.sources.empty? }.
655 each { |project| project.package(:javadoc) }
656 end
657 end
658
659 protected
660
661 def package_as_jar(file_name) #:nodoc:
662 Java::JarTask.define_task(file_name).tap do |jar|
663 jar.with :manifest=>manifest, :meta_inf=>meta_inf
664 jar.with [compile.target, resources.target].compact
665 end
666 end
667
668 def package_as_war(file_name) #:nodoc:
669 Java::WarTask.define_task(file_name).tap do |war|
670 war.with :manifest=>manifest, :meta_inf=>meta_inf
671 # Add libraries in WEB-INF lib, and classes in WEB-INF classes
672 war.with :classes=>[compile.target, resources.target].compact
673 war.with :libs=>compile.dependencies
674 # Add included files, or the webapp directory.
675 webapp = path_to(:source, :main, :webapp)
676 war.with webapp if File.exist?(webapp)
677 end
678 end
679
680 def package_as_aar(file_name) #:nodoc:
681 Java::AarTask.define_task(file_name).tap do |aar|
682 aar.with :manifest=>manifest, :meta_inf=>meta_inf
683 aar.with :wsdls=>path_to(:source, :main, :axis2, '*.wsdl')
684 aar.with :services_xml=>path_to(:source, :main, :axis2, 'services.xml')
685 aar.with [compile.target, resources.target].compact
686 aar.with :libs=>compile.dependencies
687 end
688 end
689
690 def package_as_ear(file_name) #:nodoc:
691 Java::EarTask.define_task(file_name).tap do |ear|
692 ear.send :associate, self
693 ear.with :display_name=>id, :manifest=>manifest, :meta_inf=>meta_inf
694 end
695 end
696
697 def package_as_javadoc_spec(spec) #:nodoc:
698 spec.merge(:type=>:zip, :classifier=>'javadoc')
699 end
700
701 def package_as_javadoc(file_name) #:nodoc:
702 ZipTask.define_task(file_name).tap do |zip|
703 zip.include :from=>javadoc.target
704 javadoc.options[:windowtitle] ||= project.comment || project.name
705 end
706 end
707
708 end
709
710 end
711 end
712
713
714 class Buildr::Project
715 include Buildr::Packaging::Java
716 end
Generated using the rcov code coverage analysis tool for Ruby
version 0.8.2.1.