users@jersey.java.net

Re: [Jersey] Configure wadl generation

From: Martin Grotzke <martin.grotzke_at_freiheit.com>
Date: Wed, 06 Aug 2008 09:20:55 +0200

Hi Paul,

On Tue, 2008-08-05 at 10:16 +0200, Paul Sandoz wrote:
> Martin Grotzke wrote:
> > On Mon, 2008-08-04 at 11:38 +0200, Paul Sandoz wrote:
> >> Martin Grotzke wrote:
> >>> Hi,
> >>>
> >>> I just added the possibility to configure that WadlGenerators that
> >>> are used at runtime (r1233 in the trunk).
> >>>
> >>>
> >>> For this there's now the ResourceConfig property
> >>> "com.sun.jersey.config.property.WadlGeneratorConfig" (the name of the
> >>> servlet init-param). This can be set to the name of a class that
> >>> implements c.s.j.impl.wadl.config.WadlGeneratorConfiguration or an
> >>> instance of such an implementation.
> >>>
> >>> The WadlGeneratorConfiguration must return the initialized
> >>> WadlGenerator.
> >>>
> >>> A useful implementation is
> >>> c.s.j.impl.wadl.config.WadlGeneratorConfig: - You can specify the
> >>> servlet-init param
> >>> "com.sun.jersey.config.property.wadlGeneratorDescription" with a
> >>> value like this:
> >>> com.sun.jersey.impl.wadl.generators.WadlGeneratorApplicationDoc[applicationDocsFile=classpath:/application-doc.xml];
> >>> com.sun.jersey.impl.wadl.generators.WadlGeneratorGrammarsSupport[grammarsFile=classpath:/application-grammars.xml]
> >>>
> >> To be honest the above is rather complicated and error prone for the
> >> developer. I really would prefer to avoid introducing and maintaining
> >> such a syntax if at all possible.
> >>
> >> It is simpler to have only one way of configuration. For Servlet
> >> configuration developers could extend WadlGeneratorConfig and in the
> >> constructor build what is required, then that class is referred to in
> >> the web.xml, as a fully qualified class name, using the property:
> >>
> >> ResourceConfig.PROPERTY_WADL_GENERATOR_CONFIG
> >>
> >> In this respect we can use Java and the builder pattern as a tiny DSL
> >> for configuration.
> > So one would create an appropriate subclass like this?
> >
> > class MyWadlGeneratorConfig extends WadlGeneratorConfig {
> >
> > public MyWadlGeneratorConfig() {
> > super( generator( WadlGeneratorResourceDocSupport.class )
> > .prop( "resourceDocFile", "classpath:/resourcedoc.xml" )
> > .add()
> > .build().getWadlGenerator() );
> > }
> > }
> >
> > I'm just asking, as it feels somehow "indirect" :)
> >
>
> :-)
>
> I think one could do it as follows:
>
> class MyWadlGeneratorConfig extends WadlGeneratorConfig {
> public List<WadlGeneratorDescription> configure() {
> return
> generator(WadlGeneratorResourceDocSupport.class).
> prop("resourceDocFile", "classpath:/resourcedoc.xml").
> add().
> build();
> }
> }
So you want to introduce an abstract method configure()? How could the
user then create WadlGenerator instances by himself and provide simply
the WadlGenerator?

>
> One could further simplify by doing:
>
> class MyWadlGeneratorConfig extends WadlGeneratorConfig {
> public List<WadlGeneratorDescription> configure() {
> return
> generator(WadlGeneratorResourceDocSupport.class).
> prop("resourceDocFile", "classpath:/resourcedoc.xml").
> build();
> }
> }
Yes, one could remove the add().


>
> i.e. the add is probably redundant:
>
> class MyWadlGeneratorConfig extends WadlGeneratorConfig {
> public List<WadlGeneratorDescription> configure() {
> return
> generator(WadlGeneratorResourceDocSupport.class).
> prop("resourceDocFile", "classpath:/resourcedoc.xml").
> generator(...).
> prop(..., ...).
> prop(..., ...).
> build();
> }
> }
>
> because the method "generator" signals a new addition.
>
> You might be able to remove the class WadlGeneratorDescription by using:
>
> class MyWadlGeneratorConfig extends WadlGeneratorConfig {
> public Map<Class<? extends WadlGenerator>, Properties>
> configure() {
> return
> generator(WadlGeneratorResourceDocSupport.class).
> prop("resourceDocFile", "classpath:/resourcedoc.xml").
> generator(...).
> prop(..., ...).
> prop(..., ...).
> build();
> }
> }
>
> But that is a bit of a mouthful. I would be inclined to have a
> WadlGeneratorDescriptions class that extends HashMap, if there can be
> only one instance of a generator class per configuration:
>
> public class WadlGeneratorDescriptions extends
> HashMap<Class<? extends WadlGenerator>, Properties> { ... }
>
> class MyWadlGeneratorConfig extends WadlGeneratorConfig {
> public WadlGeneratorDescriptions configure() {
> return
> generator(WadlGeneratorResourceDocSupport.class).
> prop("resourceDocFile", "classpath:/resourcedoc.xml").
> generator(...).
> prop(..., ...).
> prop(..., ...).
> build();
> }
> }
Replacing the List<WadlGeneratorDescription> is an option.
On Friday I'll go on holiday for 3 weeks (next week wednesday I'll be at
home for one day again), so I'll focus on the important things.
Of course you can tune these things by yourself, perhaps this is also
faster than lots of email conversation :)

Cheers,
Martin

>
> I think when using IDEs that display methods and JavaDoc it should be
> easier, safer and more intuitive to configure that using a textual
> syntax. If a simple example is presented in the WadlGeneratorConfig
> JavaDoc then i think that would help a lot.
>
> Paul.
>
> > Cheers,
> > Martin
> >
> >
> >>
> >>> - You can use the WadlGeneratorConfig for configuration at runtime:
> >>>
> >>> - Direct instantiation of WadlGenerators: final WadlGeneratorConfig
> >>> config = WadlGeneratorConfig.generator( new MyWadlGenerator()
> >>> ).build(); final ResourceConfig resourceConfig = new
> >>> DefaultResourceConfig(); resourceConfig.getProperties().put(
> >>> ResourceConfig.PROPERTY_WADL_GENERATOR_CONFIG, config );
> >>>
> >>> - Configure WadlGenerators: final WadlGeneratorConfig config =
> >>> WadlGeneratorConfig .generator( MyWadlGenerator.class.getName() )
> >>> .prop( "foo", propValue ) .add() .generator(
> >>> MyWadlGenerator2.class.getName() ) .prop( "bar", propValue2 ) .add()
> >>> .build(); final ResourceConfig resourceConfig = new
> >>> DefaultResourceConfig(); resourceConfig.getProperties().put(
> >>> ResourceConfig.PROPERTY_WADL_GENERATOR_CONFIG, config );
> >>>
> >> Why not refer to the classes directly as follows:
> >>
> >> final WadlGeneratorConfig config = WadlGeneratorConfig
> >> .generator( MyWadlGenerator.class )
> >> .prop( "foo", propValue )
> >> .add()
> >> .generator( MyWadlGenerator2.class )
> >> .prop( "bar", propValue2 )
> >> .add()
> >> .build();
> >>
> >> i.e. the more static typing we can utilize the less errors we need to
> >> check and report.
> >>
> >>
> >>> @Paul: do you want to have a look at this? What about the impl
> >>> namespace? Do you think this is ok, or should this stuff go into spi?
> >>>
> >> I think the WadlGeneratorConfig should be part of the API.
> >>
> >> Paul.
> >>
> >>> Cheers, Martin
> >>>
> >>>
> >>> On Wed, 2008-07-30 at 16:32 +0200, Paul Sandoz wrote:
> >>>> Hi Martin,
> >>>>
> >>>> Perhaps it would be easier to declare one Java class that has the
> >>>> configuration information declared in it, rather than a textual
> >>>> syntax.
> >>>>
> >>>> That way it should be easier to configure via programming and only
> >>>> a minimal amount of stuff needs to be declared somewhere else e.g.
> >>>> in the web.xml or in the ResourceConfig.
> >>>>
> >>>> One could use the builder pattern to make it easy to configure. For
> >>>> example:
> >>>>
> >>>> generator(<class>).prop(<name>, <value>).prop(<name>,
> >>>> <value>).add()
> >>>>
> >>>> in the constructor of the configuration class.
> >>>>
> >>>> Paul.
> >>>>
> >>>> Martin Grotzke wrote:
> >>>>> On Mon, 2008-07-28 at 10:58 +0200, Paul Sandoz wrote:
> >>>>>> Hi Martin,
> >>>>>>
> >>>>>> Can this property be declared as property using ResourceConfig?
> >>>>>>
> >>>>>>
> >>>>>> The WADL code can get the ResourceConfig instance and get the
> >>>>>> "com.sun.jersey.config.property.wadlGeneratorConfigClass" from
> >>>>>> that.
> >>>>>>
> >>>>>> Such properties will also work when declared as Servlet
> >>>>>> init-params.
> >>>>> Ok.
> >>>>>
> >>>>> What is the best way if I want to provide a
> >>>>> WadlGeneratorConfiguration that can be configured via a special
> >>>>> servlet init-param?
> >>>>>
> >>>>> My WadlGeneratorConfiguration primarily must return a list of
> >>>>> WadlGeneratorDescriptions. A WadlGeneratorDescription provides
> >>>>> the class(name) of an implementation of WadlGenerator plus a
> >>>>> Properties instance that is used to init the WadlGenerator.
> >>>>>
> >>>>> Therefore I thought about s.th. like a servlet init-param
> >>>>> "com.sun.jersey.config.property.wadlGeneratorDescriptions" with a
> >>>>> possible value like
> >>>>>
> >>>>> com.sun.jersey.impl.wadl.generators.WadlGeneratorApplicationDoc[applicationDocsFile=classpath:/src/main/api-doc/application-doc.xml];
> >>>>>
> >>>>> com.sun.jersey.impl.wadl.generators.WadlGeneratorGrammarsSupport[grammarsFile=classpath:/src/main/api-doc/application-grammars.xml];
> >>>>> ...
> >>>>>
> >>>>> This would be interpreted by e.g. a
> >>>>> ConfigurableWadlGeneratorConfiguration.
> >>>>>
> >>>>> What do you think?
> >>>>>
> >>>>> Thanx && cheers, Martin
> >>>>>
> >>>>>
> >>>>>> Paul.
> >>>>>>
> >>>>>> Martin Grotzke wrote:
> >>>>>>> Hi Paul,
> >>>>>>>
> >>>>>>> I want to add some WadlGenerationConfiguration to jersey, so
> >>>>>>> that one can configure the wadl-generation stuff like the
> >>>>>>> maven-wadl-plugin. There should be some property like
> >>>>>>>
> >>>>>>> com.sun.jersey.config.property.wadlGeneratorConfigClass
> >>>>>>>
> >>>>>>> that allows the user to specify some class, that provides the
> >>>>>>> required configuration properties.
> >>>>>>>
> >>>>>>> I would have a look at how PackagesResourceConfig is used. Do
> >>>>>>> you have another thing that provides a good start for this?
> >>>>>>>
> >>>>>>> Cheers, Martin
> >>>>>>>
> >>>>>>>
> >