|
||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES | |||||||
.properties file
from annotated Java constants.
See:
Description
| Class Summary | |
|---|---|
| PropJoeDoclet | Doclet for generating .properties files by inspecting Property and Divider annotations on constants in a a class or interface. |
| Annotation Types Summary | |
|---|---|
| Divider | Annotation which will cause a section divider to be generated with the annotation's value as the section label. |
| Property | Annotation which specifies a property to generated in the output properties file. |
Provides a javadoc doclet for generating a .properties file
from annotated Java constants. This simplifies the task of maintaining
consistency and documentation between the .properties file
and Java code which references values in it.
Properties files are ubiquitous. They're easy to use and everyone understands them. They are the way to go for relatively simple application configuration or to externalize program constants that might occassionally have to be changed in the field.
If your app has a .properties file with more than a couple of propertie in
it, you hopefully you are using constants in your code to refer to the names
of the properties. So, for example, you end up with a class that
holds a bunch of constants that you pass to getProperty()
when you need to get a property. Something like this:
public interface PropertyNames {
public String LISTEN_PORT = "listen.port";
public String BIND_ADDRESS = "bind.address";
public String FACTORY_CLASS = "factory.class";
//...
}
And then of course you end up with a .properties file like this that
you need to ship with your product.
# # acme product.properties # listen.port = 7001 bind.address = 127.0.0.1 factory.class = com.acme.AcmeFactoryImpl
This is all well and good and hopefully we can just assume that all of this accepted good practice. However, there are a few problems here:
Keeping the interface and the .properties file in sync
as the number of properties grows is problematic.
Also, documentation is similarly problematic. We can document the Java interface, which our developers will like. We can document the properties file, which our users will like. Or we can try to document them both and slowly go insane as the number of properties increases.
This is a basic single-sourcing problem, and it is this problem that PropJoe solves in two easy steps:
@Property annotations to the constants on the Java interfaceTo modify our example above, we'd have something like this on the Java side:
public interface PropertyNames { /** * The port that the server will listen on */ @Divider("Acme Product Properties") @Property("7001") public String LISTEN_PORT = "listen.port"; /** * The address the server server will bind to */ @Property("127.0.0.1") public String BIND_ADDRESS = "bind.address"; /** * Fully-qualified class name of the special acme factory to instantiate. */ @Property("com.acme.AcmeFactoryImpl") public String FACTORY_CLASS = "factory.class"; //... }
Which we could run through the PropJoeDoclet to get an output .properties
file like this:
############################################################## # Acme Product Properties # The port that the server will listen on listen.port = 7001 # The address the server server will bind to bind.address = 127.0.0.1 # Fully-qualified class name of the special acme factory to instantiate factory.class = com.acme.AcmeFactoryImpl
Now, there is no more synchronization problem between the two files, and the .properties file is nicely documented to boot. All we have to do is worry about a single Java file.
Run PropJoe like you would any other doclet. The only thing special about it is that it requires one doclet parameter, -f, to specify the path of the output properties file. Note that if the file already exists, the output will be appended to the file.
Also note that you can scan as may input Java files as desired for Property annotations - if you have those constants sprinkled all over your codebase, that's fine - just feed all of the source to javadoc and PropJoe will find them.
For example, from the command line you would simply
javadoc -doclet net.pcal.propjoe.PropJoeDoclet ... -f my/output/dir/product.properties
or in Ant using the javadoc ant task:
<javadoc packagenames='com.acme.product.*'
docletpathref='path.to.propjoe.jar'
failonerror='true'>
<fileset dir='bootstrap/src'>
<include name='**/PropertyNames.java'/>
</fileset>
<doclet name='net.pcal.propjoe.PropJoeDoclet'>
<param name='-f' value='my/output/dir/product.properties'/>
</doclet>
</javadoc>
|
||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES | |||||||