Hi Mark,
On Sep 7, 2010, at 10:04 AM, Mark Petrovic wrote:
> I'm pretty new at this Ruby stuff, but between some experience and outright
> mimicry, I've managed to produce this JAXB XJC method, which is a candidate
> for inclusion in the Buildr trunk. I think it's enough to be useful and to
> get people started with a canned JAXB compiler, despite the code being
> slightly self-conscious in a way only a neophyte can affect.
>
> Question: is the buried file() call in doWork() ultimately responsibile for
> adding a new directory element (e.g., 'target/generated-sources/xjc') to the
> list of compile sources? I don't know how this thing actually works, but it
> does. file(foo) returns foo, which I think is what compile.with sees when it
> adds to the compile sources list.
The file(path) call creates a FileTask in rake[1]. (#to_s on a rake task
returns its name; the name of a file task is the path; this is why puts
file("foo") prints foo.) This is the code that rake will execute if it
determines that it needs an up to date version of that path.
Your file task is what is returned by JAXB_XJC.doWork, and so is what is
returned by compile_jaxb. In ruby if there's no explicit return, the result of
the last expression in a method is the return value.
When you call compile.from compile_jaxb(...), buildr adds the file task to the
set of dependencies for the compile task for the 'restapi' project. Thus, when
you do restapi:compile (or any task which depends on that task), your file task
is invoked if rake decides that its path is out of date. If you're curious
about this, try running restapi:compile with --trace; you should be able to see
rake evaluating the dependency tree.
Welcome to ruby and rake and buildr,
Rhett
[1]: which is the ruby build tool that buildr is built on top of
>
> Committers, feel free to make it more clueful and tasteful in whatever way
> you see fit.
>
> 1) This code goes in a file named 'jaxb-xjc.rb':
>
> require 'buildr/java'
> require 'buildr/java/ant'
>
> # Wrapped JAXB-XJC compiler
> # https://jaxb.dev.java.net/nonav/2.2.1/docs/xjcTask.html
>
> module Buildr
> module JAXB_XJC
>
> VERSION = "2.2.1"
>
> REQUIRES = ["javax.xml.bind:jaxb-api:jar:#{VERSION}",
> "com.sun.xml.bind:jaxb-impl:jar:#{VERSION}",
> "com.sun.xml.bind:jaxb-xjc:jar:#{VERSION}"]
>
> class << self
> def doWork(options)
> outdir = options[:outdir]
> schemafile = options[:schemafile]
> package = options[:package]
>
> pkgdir = outdir + '/' + package.gsub('.', '/')
> mkdir_p pkgdir.to_s
>
> file(outdir) do |dir|
> mkdir_p dir.to_s
> Buildr.ant('xjc') do |ant|
> ant.taskdef :name=>"xjc", :classname=>"com.sun.tools.xjc.XJCTask",
> :classpath=>requires.join(File::PATH_SEPARATOR)
> ant.xjc :schema=>schemafile, :destdir=>dir, :package=>package,
> :removeOldOutput=>'yes' do
> ant.produces :dir => pkgdir, :includes => '**/*.java'
> end
> end
> end
> end
>
> def requires()
> @requires ||= Buildr.artifacts(REQUIRES).each { |artifact|
> artifact.invoke }.map(& :to_s)
> end
> end
>
> def compile_jaxb(options = nil)
> jaxb_opts = {}
> JAXB_XJC.doWork jaxb_opts.merge(options || {})
> end
>
> end
>
> class Project
> include JAXB_XJC
> end
> end
>
>
>
> 2) Use it in a project as
>
>
> require 'jaxb-xjc'
>
> ...
>
> desc 'REST API'
> define 'restapi' do
> compile.from compile_jaxb :outdir => _('target/generated-sources/xjc'),
> :schemafile => _("src/main/resources/api.xsd"),
> :package => "org.foo.api"
> package :jar, :id => 'restapi'
> end
>
>
>
>
>
> --
> Mark Petrovic
>
>