You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by as...@apache.org on 2007/04/25 05:43:52 UTC

svn commit: r532181 - in /incubator/ode/trunk: Rakefile tasks/clover.rake tasks/derby.rake tasks/headers.rake tasks/hibernate.rake tasks/jbi.rake

Author: assaf
Date: Tue Apr 24 20:43:51 2007
New Revision: 532181

URL: http://svn.apache.org/viewvc?view=rev&rev=532181
Log:
Modified Rakefile and tasks now that Buildr no longer extends the Universe.\nAdded first cut of Clover code coverage tasks.

Added:
    incubator/ode/trunk/tasks/clover.rake
Modified:
    incubator/ode/trunk/Rakefile
    incubator/ode/trunk/tasks/derby.rake
    incubator/ode/trunk/tasks/headers.rake
    incubator/ode/trunk/tasks/hibernate.rake
    incubator/ode/trunk/tasks/jbi.rake

Modified: incubator/ode/trunk/Rakefile
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/Rakefile?view=diff&rev=532181&r1=532180&r2=532181
==============================================================================
--- incubator/ode/trunk/Rakefile (original)
+++ incubator/ode/trunk/Rakefile Tue Apr 24 20:43:51 2007
@@ -1,4 +1,5 @@
-require "buildr"
+#require "buildr"
+require "buildr/lib/buildr"
 
 # Keep this structure to allow the build system to update version numbers.
 VERSION_NUMBER = "1.0-SNAPSHOT"
@@ -80,6 +81,7 @@
 repositories.remote << "http://people.apache.org/repo/m2-snapshot-repository"
 repositories.deploy_to[:url] ||= "sftp://guest@localhost/home/guest"
 
+
 desc "Apache ODE"
 define "ode", :group=>"org.apache.ode", :version=>VERSION_NUMBER do
 
@@ -199,7 +201,7 @@
     test.compile.with projects("ode:bpel-scheduler-quartz", "ode:dao-jpa", "ode:dao-hibernate", "ode:bpel-epr"),
         BACKPORT, COMMONS.pool, COMMONS.lang, DERBY, JAVAX.connector, JAVAX.transaction,
         GERONIMO.transaction, GERONIMO.kernel, GERONIMO.connector, TRANQL, HSQLDB, JAVAX.ejb,
-        LOG4J, XERCES, Java::OpenJPA::REQUIRES, QUARTZ, XALAN
+        LOG4J, XERCES, OpenJPA::REQUIRES, QUARTZ, XALAN
     test.junit.with HIBERNATE, DOM4J
 
     package :jar
@@ -269,7 +271,7 @@
     dao_hibernate = project("ode:dao-hibernate").compile.target
     bpel_store = project("ode:bpel-store").compile.target
 
-    schemaexport = Java::Hibernate.schemaexport
+    schemaexport = Hibernate.schemaexport
     export = lambda do |properties, source, target|
       file(target=>[properties, source]) do |task|
         mkpath File.dirname(target), :verbose=>false
@@ -309,7 +311,7 @@
     quartz_sql = _("src/main/scripts/quartz-derby.sql")
     partial_sql = file("target/partial.sql"=>derby_xml) do |task|
       mkpath _("target"), :verbose=>false
-      Java::OpenJPA.mapping_tool :properties=>derby_xml, :action=>"build", :sql=>task.name,
+      OpenJPA.mapping_tool :properties=>derby_xml, :action=>"build", :sql=>task.name,
         :classpath=>projects("ode:bpel-store", "ode:dao-jpa", "ode:bpel-api", "ode:bpel-dao", "ode:utils" )
     end
     derby_sql = concat(_("target/derby.sql")=>[partial_sql, quartz_sql])

Added: incubator/ode/trunk/tasks/clover.rake
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/tasks/clover.rake?view=auto&rev=532181
==============================================================================
--- incubator/ode/trunk/tasks/clover.rake (added)
+++ incubator/ode/trunk/tasks/clover.rake Tue Apr 24 20:43:51 2007
@@ -0,0 +1,34 @@
+module Clover
+
+  REQUIRES = Buildr.artifacts("clover:clover:jar:1.3.11")
+  DATABASE = "clover.db"
+
+  task "clover" do
+    projects.each do |project|
+      unless project.compile.sources.empty?
+        instrumented = project.file("target/clover")
+        instrumented.enhance project.compile.sources do |task|
+          args = ["-i", DATABASE, "-d", task.to_s, "-jdk15"]
+          args.concat task.prerequisites.each { |src| file(src).invoke }.
+            map { |src| FileList[File.join(src.to_s, "**/*.java")] }.flatten
+          args << "-verbose" if Rake.application.options.trace
+          args << { :classpath=>REQUIRES }
+          Java.java "com.cenqua.clover.CloverInstr", *args
+        end
+        file DATABASE=>instrumented
+        project.compile.sources = [instrumented]
+        project.compile.with REQUIRES
+        project.test.with REQUIRES
+      end
+    end
+  end
+
+  namespace "clover" do
+
+    task "html"=>file("clover.db") do
+      Java.java "com.cenqua.clover.reporters.html.HtmlReporter", "-i", DATABASE, "-o", "clover", :classpath=>REQUIRES
+    end
+
+  end
+
+end

Modified: incubator/ode/trunk/tasks/derby.rake
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/tasks/derby.rake?view=diff&rev=532181&r1=532180&r2=532181
==============================================================================
--- incubator/ode/trunk/tasks/derby.rake (original)
+++ incubator/ode/trunk/tasks/derby.rake Tue Apr 24 20:43:51 2007
@@ -1,47 +1,46 @@
 require "open3"
 
-module Buildr
-  module Derby
-    REQUIRES = group("derby", "derbytools", :under=>"org.apache.derby", :version=>"10.1.2.1")
+module Derby
 
-    class << self
+  REQUIRES = Buildr.group("derby", "derbytools", :under=>"org.apache.derby", :version=>"10.1.2.1")
 
-      # Returns a task that will create a new Derby database. The task name is the path to
-      # the derby database. The prerequisites are all the SQL files for inclusion in the database.
-      #
-      # For example:
-      #   Derby.create "mydb"=>derby.sql
-      def create(args)
-        db, prereqs = Rake.application.resolve_args(args)
-        # Copy the SQL files into the database directory.
-        file(File.expand_path(db)=>prereqs) do |task|
-          cmd = [ Java.path_to_bin('java'), "-cp", requires, "org.apache.derby.tools.ij" ]
-          Open3.popen3(*cmd) do |stdin, stdout, stderr|
-            # Shutdown so if a database already exists, we can remove it.
-            stdin.puts "connect 'jdbc:derby:;shutdown=true';"
-            rm_rf task.name if File.exist?(task.name)
-            # Create a new database, and load all the prerequisites.
-            stdin.puts "connect 'jdbc:derby:#{task.to_s};create=true;user=sa'"
-            stdin.puts "set schema sa"
-            stdin.puts "autocommit on;"
-            task.prerequisites.each { |prereq| stdin.write File.read(prereq.to_s) }
-            # Exiting will shutdown the database so we can copy the files around.
-            stdin.puts "exit"
-            stdin.close
-            # Helps when dignosing SQL errors.
-            stdout.read.tap { |output| puts output if Rake.application.options.trace }
-          end
-          filter(prereqs).into(task.name).run
-          touch task.name, :verbose=>false
+  class << self
+
+    # Returns a task that will create a new Derby database. The task name is the path to
+    # the derby database. The prerequisites are all the SQL files for inclusion in the database.
+    #
+    # For example:
+    #   Derby.create "mydb"=>derby.sql
+    def create(args)
+      db, prereqs = Rake.application.resolve_args(args)
+      # Copy the SQL files into the database directory.
+      file(File.expand_path(db)=>prereqs) do |task|
+        cmd = [ Java.path_to_bin('java'), "-cp", requires, "org.apache.derby.tools.ij" ]
+        Open3.popen3(*cmd) do |stdin, stdout, stderr|
+          # Shutdown so if a database already exists, we can remove it.
+          stdin.puts "connect 'jdbc:derby:;shutdown=true';"
+          rm_rf task.name if File.exist?(task.name)
+          # Create a new database, and load all the prerequisites.
+          stdin.puts "connect 'jdbc:derby:#{task.to_s};create=true;user=sa'"
+          stdin.puts "set schema sa"
+          stdin.puts "autocommit on;"
+          task.prerequisites.each { |prereq| stdin.write File.read(prereq.to_s) }
+          # Exiting will shutdown the database so we can copy the files around.
+          stdin.puts "exit"
+          stdin.close
+          # Helps when dignosing SQL errors.
+          stdout.read.tap { |output| puts output if Rake.application.options.trace }
         end
+        Buildr.filter(prereqs).into(task.name).run
+        touch task.name, :verbose=>false
       end
+    end
 
-    protected
+  protected
 
-      # This will download all the required artifacts before returning a classpath, and we want to do this only once.
-      def requires()
-        @requires ||= artifacts(REQUIRES).each(&:invoke).map(&:to_s).join(File::PATH_SEPARATOR)
-      end
+    # This will download all the required artifacts before returning a classpath, and we want to do this only once.
+    def requires()
+      @requires ||= Buildr.artifacts(REQUIRES).each(&:invoke).map(&:to_s).join(File::PATH_SEPARATOR)
     end
   end
 end

Modified: incubator/ode/trunk/tasks/headers.rake
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/tasks/headers.rake?view=diff&rev=532181&r1=532180&r2=532181
==============================================================================
--- incubator/ode/trunk/tasks/headers.rake (original)
+++ incubator/ode/trunk/tasks/headers.rake Tue Apr 24 20:43:51 2007
@@ -1,4 +1,5 @@
 namespace "check" do
+
   desc "Checks license headers."
   task("headers") do
     # Define license headers based on the filename extension.
@@ -65,4 +66,5 @@
       puts "All #{extensions} files checked and have the license in them."
     end
   end
+
 end

Modified: incubator/ode/trunk/tasks/hibernate.rake
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/tasks/hibernate.rake?view=diff&rev=532181&r1=532180&r2=532181
==============================================================================
--- incubator/ode/trunk/tasks/hibernate.rake (original)
+++ incubator/ode/trunk/tasks/hibernate.rake Tue Apr 24 20:43:51 2007
@@ -1,82 +1,77 @@
-module Buildr
-  module Java
-    module Hibernate
-
-      REQUIRES = OpenObject.new
-      REQUIRES.collections  = "commons-collections:commons-collections:jar:3.1"
-      REQUIRES.logging      = "commons-logging:commons-logging:jar:1.0.3"
-      REQUIRES.dom4j        = "dom4j:dom4j:jar:1.6.1"
-      REQUIRES.hibernate    = "org.hibernate:hibernate:jar:3.1.2"
-      REQUIRES.xdoclet      = group("xdoclet", "xdoclet-xdoclet-module", "xdoclet-hibernate-module",
-                                    :under=>"xdoclet", :version=>"1.2.3") + ["xdoclet:xjavadoc:jar:1.1-j5"]
-
-      class << self
-        include Ant
-
-        # Uses XDoclet to generate HBM files form annotated source files.
-        # Options include:
-        # * :sources -- Directory (or directories) containing source files.
-        # * :target -- The target directory.
-        # * :excludetags -- Tags to exclude (see HibernateDocletTask)
-        #
-        # For example:
-        #  Java::Hibernate.xdoclet :sources=>compile.sources,
-        #    :target=>compile.target, :excludedtags=>"@version,@author,@todo"
-        def xdoclet(options)
-          ant("hibernatedoclet") do |doclet|
-            doclet.taskdef :name=>"hibernatedoclet", :classname=>"xdoclet.modules.hibernate.HibernateDocletTask", :classpath=>requires
-            doclet.hibernatedoclet :destdir=>options[:target].to_s, :excludedtags=>options[:excludedtags], :force=>"true" do
-              hibernate :version=>"3.0"
-              options[:sources].to_a.each do |source|
-                fileset :dir=>source.to_s, :includes=>"**/*.java"
-              end
-            end
-          end
-        end
-
-        # Returns a new AntProject that supports the schemaexport task.
-        def schemaexport(name = "schemaexport")
-          ant(name) do |export|
-            export.taskdef :name=>"schemaexport", :classname=>"org.hibernate.tool.hbm2ddl.SchemaExportTask", :classpath=>requires
-          end
-        end
+module Hibernate
 
-        # Returns an new task with an accessor (ant) to an AntProject that supports
-        # the schemaexport task.
-        #
-        # For example:
-        #   Java::Hibernate.schemaexport_task.enhance do |task|
-        #     task.ant.schemaexport :properties=>"derby.properties", :output=>"derby.sql",
-        #       :delimiter=>";", :drop=>"no", :create=>"yes" do
-        #       fileset(:dir=>path_to(:java_src_dir)) { include :name=>"**/*.hbm.xml" } }
-        #     end
-        #   end
-        def schemaexport_task(name = "schemaexport")
-          unless Rake::Task.task_defined?(name)
-            class << task(name) ; attr_accessor :ant ; end
-            task(name).enhance { |task| task.ant = schemaexport(name) }
+  REQUIRES = OpenObject.new
+  REQUIRES.collections  = "commons-collections:commons-collections:jar:3.1"
+  REQUIRES.logging      = "commons-logging:commons-logging:jar:1.0.3"
+  REQUIRES.dom4j        = "dom4j:dom4j:jar:1.6.1"
+  REQUIRES.hibernate    = "org.hibernate:hibernate:jar:3.1.2"
+  REQUIRES.xdoclet      = Buildr.group("xdoclet", "xdoclet-xdoclet-module", "xdoclet-hibernate-module",
+                                :under=>"xdoclet", :version=>"1.2.3") + ["xdoclet:xjavadoc:jar:1.1-j5"]
+
+  class << self
+    include Buildr::Ant
+
+    # Uses XDoclet to generate HBM files form annotated source files.
+    # Options include:
+    # * :sources -- Directory (or directories) containing source files.
+    # * :target -- The target directory.
+    # * :excludetags -- Tags to exclude (see HibernateDocletTask)
+    #
+    # For example:
+    #  Java::Hibernate.xdoclet :sources=>compile.sources,
+    #    :target=>compile.target, :excludedtags=>"@version,@author,@todo"
+    def xdoclet(options)
+      ant("hibernatedoclet") do |doclet|
+        doclet.taskdef :name=>"hibernatedoclet", :classname=>"xdoclet.modules.hibernate.HibernateDocletTask", :classpath=>requires
+        doclet.hibernatedoclet :destdir=>options[:target].to_s, :excludedtags=>options[:excludedtags], :force=>"true" do
+          hibernate :version=>"3.0"
+          options[:sources].to_a.each do |source|
+            fileset :dir=>source.to_s, :includes=>"**/*.java"
           end
-          task(name)
         end
+      end
+    end
 
-      protected
-
-        # This will download all the required artifacts before returning a classpath, and we want to do this only once.
-        def requires()
-          @requires ||= artifacts(REQUIRES.to_hash.values).each(&:invoke).map(&:to_s).join(File::PATH_SEPARATOR)
-        end
+    # Returns a new AntProject that supports the schemaexport task.
+    def schemaexport(name = "schemaexport")
+      ant(name) do |export|
+        export.taskdef :name=>"schemaexport", :classname=>"org.hibernate.tool.hbm2ddl.SchemaExportTask", :classpath=>requires
+      end
+    end
 
+    # Returns an new task with an accessor (ant) to an AntProject that supports
+    # the schemaexport task.
+    #
+    # For example:
+    #   Java::Hibernate.schemaexport_task.enhance do |task|
+    #     task.ant.schemaexport :properties=>"derby.properties", :output=>"derby.sql",
+    #       :delimiter=>";", :drop=>"no", :create=>"yes" do
+    #       fileset(:dir=>path_to(:java_src_dir)) { include :name=>"**/*.hbm.xml" } }
+    #     end
+    #   end
+    def schemaexport_task(name = "schemaexport")
+      unless Rake::Task.task_defined?(name)
+        class << task(name) ; attr_accessor :ant ; end
+        task(name).enhance { |task| task.ant = schemaexport(name) }
       end
+      task(name)
+    end
 
+  protected
+
+    # This will download all the required artifacts before returning a classpath, and we want to do this only once.
+    def requires()
+      @requires ||= Buildr.artifacts(REQUIRES.to_hash.values).each(&:invoke).map(&:to_s).join(File::PATH_SEPARATOR)
     end
+
   end
 
-  class Project
-  
-    def hibernate_doclet(options = {})
-      Java::Hibernate.xdoclet({ :sources=>compile.sources, :target=>compile.target }.merge(options))
-    end
+end
+
+class Project
 
+  def hibernate_doclet(options = {})
+    Hibernate.xdoclet({ :sources=>compile.sources, :target=>compile.target }.merge(options))
   end
 
 end

Modified: incubator/ode/trunk/tasks/jbi.rake
URL: http://svn.apache.org/viewvc/incubator/ode/trunk/tasks/jbi.rake?view=diff&rev=532181&r1=532180&r2=532181
==============================================================================
--- incubator/ode/trunk/tasks/jbi.rake (original)
+++ incubator/ode/trunk/tasks/jbi.rake Tue Apr 24 20:43:51 2007
@@ -1,153 +1,148 @@
-module Buildr
-  module Java
-    # This task creates a JBI package based on the component/bootstrap specification.
-    # It extends ZipTask, and all its over lovely options.
-    #
-    # The easiest way to use this task is through the Project#package method. For example:
-    #   package(:jbi).tap do |jbi|
-    #     jbi.component :type=>:service_engine=>"MyEngine", :description=>self.comment
-    #     jbi.component :class_name=>"com.example.MyComponent", :delegation=>:self, :libs=>libs
-    #     jbi.bootstrap :class_name=>"com.example.MyBootstrap", :delegation=>:parent, :libs=>libs
-    #   end
-    class JBITask < ZipTask
-
-      # Specifies the name of a jbi.xml file to use, or a Proc/Method returning
-      # the contents of jbi.xml. Leave empty if you want to use #component and
-      # bootstrap instead.
-      attr_accessor :jbi_xml
-
-      # Component specification.
-      class Component
-        # Component name.
-        attr_accessor :name
-        # Component type, e.g. :service_engine.
-        attr_accessor :type
-        # Description of component.
-        attr_accessor :description
-        # Delegation method. Default is :parent.
-        attr_accessor :delegation
-        # Component class name.
-        attr_accessor :class_name
-        # Array of libraries used by component.
-        attr_accessor :libs
+# This task creates a JBI package based on the component/bootstrap specification.
+# It extends ZipTask, and all its over lovely options.
+#
+# The easiest way to use this task is through the Project#package method. For example:
+#   package(:jbi).tap do |jbi|
+#     jbi.component :type=>:service_engine=>"MyEngine", :description=>self.comment
+#     jbi.component :class_name=>"com.example.MyComponent", :delegation=>:self, :libs=>libs
+#     jbi.bootstrap :class_name=>"com.example.MyBootstrap", :delegation=>:parent, :libs=>libs
+#   end
+class JBITask < Buildr::ZipTask
+
+  # Specifies the name of a jbi.xml file to use, or a Proc/Method returning
+  # the contents of jbi.xml. Leave empty if you want to use #component and
+  # bootstrap instead.
+  attr_accessor :jbi_xml
+
+  # Component specification.
+  class Component
+    # Component name.
+    attr_accessor :name
+    # Component type, e.g. :service_engine.
+    attr_accessor :type
+    # Description of component.
+    attr_accessor :description
+    # Delegation method. Default is :parent.
+    attr_accessor :delegation
+    # Component class name.
+    attr_accessor :class_name
+    # Array of libraries used by component.
+    attr_accessor :libs
 
-        def initialize()
-          @libs = []
-        end
-      end
+    def initialize()
+      @libs = []
+    end
+  end
 
-      # Bootstrap specification.
-      class Bootstrap
-        # Delegation method. Default is :parent.
-        attr_accessor :delegation
-        # Bootstrap class name.
-        attr_accessor :class_name
-        # Array of libraries used for bootstrapping.
-        attr_accessor :libs
+  # Bootstrap specification.
+  class Bootstrap
+    # Delegation method. Default is :parent.
+    attr_accessor :delegation
+    # Bootstrap class name.
+    attr_accessor :class_name
+    # Array of libraries used for bootstrapping.
+    attr_accessor :libs
 
-        def initialize()
-          @libs = []
-        end
-      end
+    def initialize()
+      @libs = []
+    end
+  end
 
-      def []=(key, value)
-        case key.to_sym
-        when :name, :description, :type
-          self.component.send "#{name}=", value
-        when :component, :bootstrap
-          self.send key, value
-        else
-          super key, value
-        end
-        value
-      end
+  def []=(key, value)
+    case key.to_sym
+    when :name, :description, :type
+      self.component.send "#{name}=", value
+    when :component, :bootstrap
+      self.send key, value
+    else
+      super key, value
+    end
+    value
+  end
 
-      # Returns the component specification for this JBI package.
-      # You can call accessor methods to configure the component
-      # specification, you can also pass a hash of settings, for example:
-      #   jbi.component :type=>:service_engine, :name=>"MyEngine"
-      def component(args = nil)
-        (@component ||= Component.new).tap do |component|
-          args.each { |k, v| component.send "#{k}=", v } if args
-        end
-      end
+  # Returns the component specification for this JBI package.
+  # You can call accessor methods to configure the component
+  # specification, you can also pass a hash of settings, for example:
+  #   jbi.component :type=>:service_engine, :name=>"MyEngine"
+  def component(args = nil)
+    (@component ||= Component.new).tap do |component|
+      args.each { |k, v| component.send "#{k}=", v } if args
+    end
+  end
 
-      # Returns the bootstrap specification for this JBI package.
-      # You can call accessor methods to configure the bootstrap
-      # specification, you can also pass a hash of settings, for example:
-      #   jbi.bootstrap :class_name=>"com.example.jbi.MyBootstrap", :libs=>libs
-      def bootstrap(args = nil)
-        (@bootstrap ||= Bootstrap.new).tap do |bootstrap|
-          args.each { |k, v| bootstrap.send "#{k}=", v } if args
-        end
-      end
+  # Returns the bootstrap specification for this JBI package.
+  # You can call accessor methods to configure the bootstrap
+  # specification, you can also pass a hash of settings, for example:
+  #   jbi.bootstrap :class_name=>"com.example.jbi.MyBootstrap", :libs=>libs
+  def bootstrap(args = nil)
+    (@bootstrap ||= Bootstrap.new).tap do |bootstrap|
+      args.each { |k, v| bootstrap.send "#{k}=", v } if args
+    end
+  end
 
-      def prerequisites()
-        super + (component.libs + bootstrap.libs).flatten.uniq
-      end
+  def prerequisites()
+    super + (component.libs + bootstrap.libs).flatten.uniq
+  end
 
-    protected
+protected
 
-      def create(zip)
-        zip.mkdir "META-INF"
-        # Create the jbi.xml file from provided file/code or by creating a descriptor.
-        jbi_xml_content = case jbi_xml
-        when String
-          File.read(jbi_xml)
-        when nil, true
-          descriptor
-        when Proc, Method
-          jbi_xml.call.to_s
-        end
-        zip.file.open("META-INF/jbi.xml", "w") { |file| file.write jbi_xml_content }
-        path("lib").include((component.libs + bootstrap.libs).flatten.uniq)
-        super zip
-      end
+  def create(zip)
+    zip.mkdir "META-INF"
+    # Create the jbi.xml file from provided file/code or by creating a descriptor.
+    jbi_xml_content = case jbi_xml
+    when String
+      File.read(jbi_xml)
+    when nil, true
+      descriptor
+    when Proc, Method
+      jbi_xml.call.to_s
+    end
+    zip.file.open("META-INF/jbi.xml", "w") { |file| file.write jbi_xml_content }
+    path("lib").include((component.libs + bootstrap.libs).flatten.uniq)
+    super zip
+  end
 
-      # Create a JBI descriptor (jbi.xml) from the component/bootstrap specification.
-      def descriptor()
-        delegation = lambda { |key| "#{key || :parent}-first" }
-        path_elements = lambda do |xml, libs|
-          libs.each { |lib| xml.tag! "path-element", "lib/#{lib.to_s.pathmap('%f')}" }
-        end
-        xml = Builder::XmlMarkup.new(:indent=>2)
-        xml.instruct!
-        xml.jbi :xmlns=>"http://java.sun.com/xml/ns/jbi", :version=>"1.0" do
-          xml.component :type=>component.type.to_s.sub("_", "-"),
-            "component-class-loader-delegation"=>delegation[component.delegation],
-            "bootstrap-class-loader-delegation"=>delegation[bootstrap.delegation] do
-            xml.identification do
-              xml.name component.name
-              xml.description component.description
-            end
-            xml.tag!("component-class-name", component.class_name)
-            xml.tag!("component-class-path") { path_elements[xml, component.libs] }
-            xml.tag!("bootstrap-class-name", bootstrap.class_name)
-            xml.tag!("bootstrap-class-path") { path_elements[xml, bootstrap.libs] }
-          end
-        end
+  # Create a JBI descriptor (jbi.xml) from the component/bootstrap specification.
+  def descriptor()
+    delegation = lambda { |key| "#{key || :parent}-first" }
+    path_elements = lambda do |xml, libs|
+      libs.each { |lib| xml.tag! "path-element", "lib/#{lib.to_s.pathmap('%f')}" }
+    end
+    xml = Builder::XmlMarkup.new(:indent=>2)
+    xml.instruct!
+    xml.jbi :xmlns=>"http://java.sun.com/xml/ns/jbi", :version=>"1.0" do
+      xml.component :type=>component.type.to_s.sub("_", "-"),
+        "component-class-loader-delegation"=>delegation[component.delegation],
+        "bootstrap-class-loader-delegation"=>delegation[bootstrap.delegation] do
+        xml.identification do
+          xml.name component.name
+          xml.description component.description
+        end
+        xml.tag!("component-class-name", component.class_name)
+        xml.tag!("component-class-path") { path_elements[xml, component.libs] }
+        xml.tag!("bootstrap-class-name", bootstrap.class_name)
+        xml.tag!("bootstrap-class-path") { path_elements[xml, bootstrap.libs] }
       end
-
     end
-
   end
 
-  class Project
+end
 
-    def package_as_jbi(file_name, options)
-      # The file name extension is zip, not jbi. And we also need to reset
-      # the type on the artifact specification.
-      file_name = file_name.ext("zip")
-      options[:type] = :zip
-      unless Rake::Task.task_defined?(file_name)
-        JBITask.define_task(file_name).tap do |jbi|
-          jbi.include options[:include] if options[:include]
-          [:component, :bootstrap].each { |key| jbi[key] = options[key] if options[key] }
-          yield jbi
-        end
+class Project
+
+  def package_as_jbi(file_name, options)
+    # The file name extension is zip, not jbi. And we also need to reset
+    # the type on the artifact specification.
+    file_name = file_name.ext("zip")
+    options[:type] = :zip
+    unless Rake::Task.task_defined?(file_name)
+      JBITask.define_task(file_name).tap do |jbi|
+        jbi.include options[:include] if options[:include]
+        [:component, :bootstrap].each { |key| jbi[key] = options[key] if options[key] }
+        yield jbi
       end
-      file(file_name)
     end
-
+    file(file_name)
   end
+
 end