Location: JWare Software » PEd4Ant » Overview
Overview
JWare/AntXtras Properties Editor for Ant (PEd4Ant) is a collection of components for creating and manipulating standard Java properties files from within Ant script. If you need to do lots of custom properties manipulation, while preserving the original source as much as possible, you will find PEd4Ant very useful.
To use PEd4Ant you just load its antlib into your Ant runtime. PEd4Ant depends on the standard Ant and AntXtras libraries only. The recommended namespace URI and prefix for PEd4Ant is “jware.ped4ant” and “ped:” respectively. Read the “Loading PEd4Ant antlib” instructions for additional information.
Main Features
- 100% Ant, 100% Java Properties– information manipulated as objects not generic text.
- Preserves structure including whitespace and comments so that a “diff” shows only edits.
- Has a full suite of property operations: insert, delete, test, replace, [un]comment, copy, diff.
- Can read local or remote properties sources using any URL format your Ant runtime supports.
- Supports editing in place with auto-backup on load and auto-save per edit.
- Supports ‘bulk’ or set versions of operations using standard Ant filterchains and mappers.
- Support properties in both standard format as well as the newer XML format (JRE 1.5+).
- Supports Ant filter chains on properties load to transform incoming keys and values with ease.
- Works the same on both transient in-memory content or externally sourced content.
- Lets you create custom Ant <propertyset> data from processed property file contents.
Component Summary
The recommended namespace prefix for PEd4Ant is “ped:”; this prefix is assumed in our table below. If you’re a developer looking to extend or use PEd4Ant in your own Ant components, you will find additional implementation details in the PEd4Ant Javadoc API reference.
| Task/Type | General Description |
|---|---|
| ped:makeproperties | Lets you create a new properties object in memory. |
| ped:loadproperties, ped:mergeloadproperties | Lets you load or load-and-merge one or more pre-existing properties sources into memory . |
| ped:editproperties | Lets you performs a multitude of operations on loaded properties . |
| ped:readproperties | Lets you copy in memory properties to Ant fixture or other properties. |
| ped:saveproperties | Lets you save in memory properties to a file. |
| ped:diffproperties | Lets you capture differences between two properties as objects (not text) |
| ped:testproperties | Lets you apply a test condition to a properties’ contents or keys. |
High Speed Tutorials
All PEd4Ant manipulation operations require that you either create a new memory-based Properties object or load one from an external source. The following examples show you how to manipulate a Properties object created from scratch or loaded from an external definition file (standard or XML). Once you’re done with your edits, you can: save the in-memory object back to a file, create some other Ant data structure like a property set or other resource collection, or apply the properties into the current Ant fixture so you can use them like regular Ant properties via ‘${…}’ semantics.
Not all of the features described below are available in the initial beta release of PEd4Ant; however, all of these components and operations will exist in the final PEd4Ant 1.0.0 release. Any example that describes future functionality is marked with an “in progress” icon (
) at its start. You can read the Release Notes for the list of features implemented in the latest distribution and then the Future Plans for the general PEd4Ant release schedule.
Installing PEd4Ant Antlib
You can install the PEd4Ant extension directly into your <ANT_HOME>/lib directory or more typically into its own location. This example assumes the latter case: it loads the PEd4Ant antlib into the Ant runtime from a location defined by the ‘PED4ANT_HOME’ property and then links its components to the “ped:” namespace prefix.
1: <project name="example" xmlns:ped="jware.ped4ant"…> 2: <property name="PED4ANT_HOME" value="..."/> 3: … 4: <taskdef uri="jware.ped4ant" 5: resource="org/jwaresoftware/ped4ant/antlib.xml"> 6: <classpath> 7: <fileset dir="${PED4ANT_HOME}" 8: includes="lib/*.jar"/> 9: </classpath> 10: </taskdef> 11: …
Creating New Properties
This example creates a new empty Properties object “myconf” in memory, overwriting unconditionally any object currently stored with that id. After creation, the new object is ready to accept key-value data from other PEd4Ant commands.
1: <ped:makeproperties under="myconf"/>
This example creates a new empty Properties object “myconf” that is automatically linked to a file ‘autogen.properties’ for saving. Note that the file not created until the first actual call to save the “myconf” object:
1: <ped:makeproperties under="myconf" 2: filelink="${my.d}/autogen.properties"/>
This example creates a new Properties object “myconf” that is automatically pre-filled with some inlined property values including comments. You can also seed a new Properties object from a standard Ant <propertyset>, or a <string> resources collection, or an AntXtras <properties> object.
1: <ped:makeproperties under="myconf"> 2: <string value="#TOP-OF-FILE (created:${$iso:})"/> 3: <string value="my-key=my-value"/> 4: <string value="#END-OF-FILE"/> 5: </ped:makeproperties>
Loading Existing Properties
This example creates and loads a new Properties object “myconf” from an existing external source, in this case a local file ‘template.properties’. Note that the file is not backed up, so any subsequent saves will overwrite the original file.
1: <ped:loadproperties under="myconf" 2: file="${my.d}/template.properties"/>
This example creates and loads a new Properties object “myconf” from an existing external source that is using the standard XML format for Java Properties. If you want to load an XML formatted source that does not use the standard “.xml” extension use the ‘format=xml’ parameter.
1: <ped:loadproperties under="myconf" 2: file="${my.d}/template.xml"/>
This example creates and loads a new Properties object “myconf” from a information stored at remote location ‘${my.url}’. It also saves a local baseline file version ‘original.properties’ with which it can create a patch file after editing the in-memory copy.
1: <ped:loadproperties under="myconf" 2: url="${my.url}/template.properties" 3: backup="${tmp.d}/original.properties"/>
This example creates and loads a new Properties object “myconf” from a local file but does some pre-processing of the file's contents before storing it to memory. In particular, the snippet removes blank lines and then replaces all ‘${…}’ references with their current runtime values (including properties defined in the original Properties source itself). PEd4Ant’s load tasks support all standard Ant filter readers and token filters when loading a Properties object. The ‘baseline=off’ parameter tells PEd4Ant not to consider the initial in-memory copy as a baseline aka pristine copy of the original source.
1: <ped:loadproperties under="myconf" 2: file="${my.d}/template.properties" baseline="off"> 3: <filterchain> 4: <tokenfilter> 5: <ignoreblank/> 6: </tokenfilter> 7: <expandproperties/> 8: </filterchain> 9: </ped:loadproperties>
Each of these examples creates and merge loads a series of files into a single in-memory Properties object “myconf”. Note that the order in which source files are loaded, depends on how you define your inclusion criteria. For an ordered sequence of local files you can use a <filelist>; otherwise, you can use any filesystem based standard Ant resource set like a <fileset>, <resources>, or <zipfileset>. You can even include remote sources by using the standard Ant <url> resource. Note that if you do a merged load of multiple sources, any filtering is applied to each source’s contents before it is merged.
1: <ped:mergeloadproperties under="myconf"> <ped:mergeloadproperties under="myconf"> 2: <filelist dir="${conf.d}"> <resources> 3: <file name="defaults.properties"/> <file file="${conf.d}/defaults.properties"/> 4: <file name="${deploy.environ}.properties"/> <javaresource name="conf/${env}.properties"/> 5: <file name="fixed.properties"/> <url url="${my.url}/company.properties"/> 6: </filelist> </resources> 7: </ped:mergeloadproperties> </ped:mergeloadproperties>
Editing Properties (inserts)
This example appends a set of new properties into an existing Properties object “myconf” using the <insert> action. You can insert comments, blank lines, empty values (value is the empty string), regular single key-value pairs, property sets (sorted-by-key or unsorted).
1: <ped:editproperties under="myconf"> 2: <insert value="#A comment goes here..."/> 3: <insert key="a-key" value="its-value"/> 4: <insert properties="refid-to-properties" ordering="key"/> 5: <insert key="key.with.empty.value"/> 6: </ped:editproperties>
This example appends a blank line to an existing Properties object “myconf”.
1: <ped:editproperties under="myconf"> 2: <insert/> 3: </ped:editproperties>
This example inserts a line into an existing Properties object “myconf” before a specific comment line by using the “before” parameter. The new comment that contains a dynamically generated time stamp will be inserted just before the comment line that equals “#EOF”.
1: <ped:editproperties under="myconf"> 2: <insert value="#Deployed on: ${DATETIME}" before="#EOF"/> 3: </ped:editproperties>
Editing Properties (deletes)
This example removes a set of properties from an existing Properties object “myconf”. You can remove a single property by key or by value, or you can remove a set of properties based on some key or value selecting regular expression. You can even remove specific comments if needed. If you do not specify the ‘selector’ parameter, PEd4Ant assumes the operation applies to the properties’ keys.
1: <ped:editproperties under="myconf"> 2: <remove like="^disabled\..*"/> 3: <remove equals="@@FIXME@@" selector="values"/> 4: <remove key="java.naming.factory.initial"/> 5: <remove like="^#INSTR:.*$" selector="comments"/> 6: </ped:editproperties>
Editing Properties (updates)
The update operation is the main workhorse for the PEd4Ant package. You can change property keys and values in a variety of ways. This example updates the value of the ‘version’ property existing Properties object “myconf”.
1: <ped:editproperties under="my.conf"> 2: <update key="version" value="${build.version}"/> 3: </ped:editproperties>
This example updates the property with the key ‘version’ to use a totally different key; the property’s value is left as-is.
1: <ped:editproperties under="my.conf"> 2: <update key="version" selector="key" value="${environ}.version"/> 3: </ped:editproperties>
This example updates all properties that have a value that equals “
” to instead have the value “UNRESOLVED!”.
1: <ped:editproperties under="my.conf"> 2: <update equals="FIXME" selector="values" value="UNRESOLVED!"/> 3: </ped:editproperties>
This example updates all properties whose values are in a custom property selector format (like “@a:propertyname”) with the current value of that property in the Ant runtime. If the property does not exist in the current Ant fixture, the script replaces the property selector with the value “UNRESOLVED!”.
1: <ped:editproperties under="my.conf"> 2: <update like="^\@a\:(.*)" selector="values" 3: replace="%{$property:\1?UNRESOLVED!}"/> 4: </ped:editproperties>
Because renaming keys is such a common use for the general update operation, PEd4ant supplies a predefined variant <rename> for this common use. This example flips two sets of specific properties (disable one set by prefixing key with “disabled.” and enable other set by dropping environment specific prefix) using the shortcut <rename> operation.
1: <ped:editproperties under="my.conf"> 2: <rename like="^throttle\.(.*)" to="disabled.throttle.\1"/> 3: <rename like="^${env}\.throttle\.(.*)" to="throttle.\1"/> 4: </ped:editproperties>
Editing Properties (toggles)
This example uncomments a set of specific properties masked as a comments. All of the comments that begin with the expanded value of the ‘if.${env}.’ string will be uncommented and become active properties without the ‘if.${env}.’ part.
1: <ped:editproperties under="myconf"> 2: <enable like="^if\.${env}\.(.*)" replace="\1"/> 3: </ped:editproperties>
This example toggles (comments) any property whose key begins with ‘java.naming’. The <toggle> operation can flip a value on or off; but in this instance, because we select only keys (i.e. non-comments), the toggle acts as a comment or disable request.
1: <ped:editproperties under="myconf"> 2: <toggle like="^java\.naming\." selector="key"/> 3: </ped:editproperties>
Saving Edited Properties
This example saves a file-sourced Properties object “myconf”, at any time– but the file is actually rewritten only if there was an actual change to the properties.
1: <ped:saveproperties under="myconf" 2: when="changed"/>
This example saves an existing Properties object “myconf” to a new (different) file with a custom header and timestamp.
1: <ped:saveproperties under="myconf" 2: header="Generated by build process. Do NOT edit." 3: datetime="$gmtdatetime:" 4: file="${my.d}/test.properties"/>
This example immediately shows how to save a set of edit operations to an existing file-sourced Properties object “myconf” back to the original file.
1: <ped:editproperties under="myconf" save="yes"> 2: [edit actions here…] 3: </ped:editproperties>
Copying Loaded Properties
This example copies all properties in the Properties object “myconf” that begin with ‘project.’ to the current Ant fixture as regular properties. Before copying, the item’s key is stripped of the prefix so something like “project.label” becomes just “label”.
1: <ped:readproperties under="myconf"> 2: <select like="^project\..*" to="ant.project"> 3: <mapper type="glob" from="project.*" to="*"/> 4: </select> 5: </ped:readproperties>
This example copies all properties that being with ‘throttle.conf.’ to an existing properties resource collection. The properties are copied as-is without modification. If any items were matched and copied the property ‘throttle.edited’ is created and set to “true”.
1: <ped:readproperties under="myconf"> 2: <select like="^throttle\.conf\..*" 3: to="throttle.properties" 4: hitproperty="throttle.edited"/> 5: </ped:readproperties>
Testing Loaded Properties
This example checks whether a set of properties, masked as comments, exist in a loaded Properties object “myconf”.
1: <ped:testproperties under="myconf" 2: like="^${env}\.throttle\..*" selector="comments" 3: trueproperty="throttle.enabled"/>