The following is a list of items that need to be completed in
Betwixt. Contributions are welcome!
- Logging: create logging policy then review all code for compliance.
- FAQ: convert FAQ to maven plugin.
- Tasks: review.
Change ElementRule so that updaters are automatically guessed (when not present).
Add read-only attribute for properties to disable this behaviour.
BeanWriter is writing too sloppy (empty elements, etc). Fixing it in a clean way
is almost impossible.
Probably a refactor is best anyway to have a less "sloppy" api..
Get an overview of what .betwixt files should really do.
Especially more complicated examples will cause very strange and unexpected results.
If an addFoo() method is found with no matching getFoos() then a warning should be generated.
Consider allowing the parsing of XML to order the properties/elements in the XMLBeanInfo
so that when the XML is output again it follows the same XML ordering again.
There is an example describing this
For example we could add a feature to parse the DTD and order the XMLBeanInfo according to the order in the DTD.
Improved documentation! Improve package level documentation so that new developers can get up
to speed more quickly. Ensure all betwixt features have good user documentation.
More good code examples.
Add support for IDREF's to BeanReader. At the moment, round tripping break when cycles exist.
Add testcase for the BeanReader(SAXParser) and BeanReader(XMLReader). They should behave
the same in all cases.
- Create test cases based on real xml examples.
This should help to shake out any problems and help to find out how the design can be improved.
These should also be used as a basis for improved documentation.
- Improve internal design.
Betwixt is hard to understand and hard to create patches for.
An improved internal design would help more people to contribute.
- Improve test coverage.
Run test coverage tool and improve coverage of key functionality.
- Add dynabeans support.
Dynabeans are a feature of
commons-beanutils that allows data in non-beans to be
wrapped into pseudo-beans. If betwixt supported dynabeans then you could do cool stuff like
SQL -> DynaBeans -> XML. Probably a good way to do this would be to ensure that all property
introspection is done by dyanbeans-aware methods of beanutils.
- Update RSS example application.
The original betwixt documentation made use of a good example application based on RSS.
Unfortunately, this no longer works since the build was updated to maven.
The instructions and means of running are linked to the CVS version.
New instructions - and probably movement of some of the code - is needed to support
a release distribution. The example also needs some more work - better java docs and also
- Review AbstractBeanWriter and SAXBeanWriter
AbstractBeanWriter and SAXBeanWriter were written very quickly (to support functionality
in maven). They need to be reviewed and properly documentated.
- Add support for constructors with arguments.
Currently, only beans with no-argument constructors can be read.
- Create design documentation
This will help people understand the betwixt design.
- Add verification for all xml writing tests.
At the moment, most of the xml writing tests do not test the output fully.
Need to add comparisons against reference xml documents.
- Improve mapping for swing components
Swing classes have lots and lots of properties.
Java 1.4 does a better job of persistance than betwixt for class that have lots of properties.
- Binary Data Elements
Some properties should not be treated as beans and therefore mapped to a element graph.
These should be converted to body text of binary data.
A mechanism similar to BeanUtils.ConvertUtils might work.
For example, if you have a colormodel that get's written (an array with a lot of
numbers and an xml-element per array element) betwixt will spend ages converting
it bit by bit.
- Customizable ID/IDREF Mapping
Add per element customization for ID/IDREF mappings.
Extra attributes will be added to .betwixt file that specify the ID/IDREF names.
- Attribute-Or-Element Strategy
At the moment, betwixt allows only an all-or-nothing for the choice between mapping to an
attribute or an element. This should be replaced by a strategy interface which allows the
mapping to the customized.
- Improved Support For Interfaces (strategy)
Create a strategy which allow general implementation rules to be specified.
Create a W3C DOM implementation that acts as a facade on top of beans to allow beans to
be transformed in XSLT engines as XML.
Add support for custom class loaders. Probably this means adding a classloader property
XMLIntrospector and then ensuring all class creation uses that.
The digestion rules which create the
files should use the
XMLBeanInfoDigester classloader property which should
be set by the
Create utility methods in BeanWriter to write stuff like prologs and doctype definitions to the
Create a funky image for the betwixt home page.
- Element ordering strategies
The ordering of the elements for a bean which doesn't have a .betwixt file associated
is fixed by the order of the properties in the BeanInfo. If the class doesn't have a
custom BeanInfo class then this order is arbitrary. This is unfortunate since often xml
elements need a definite and predicatable ordering. Pluggable element ordering strategies
would order the elements according to some algorithm eg. alphabetic.
- Support Mixed Content Round Tripping
This is actually has some conceptual problems. What happens when you have two text
descriptors mapped to properties next to each other?
This would probably require some enhancements to Digester.
useContextClassLoader property to
When this is set to
true, the introspector will use the context classloader
when loading classes. It is recommended that containers (such as JBoss) with well behaved
context classloaders set this property to true.
Added strategies for suppression of attributes and elements at introspection time.
Improved support for natural polymorphic mappings of collection subclasses.
Added support for option inheritance between parent and target mappings. Issue #37542.
getInheritedOption method to
Context to assist
with inheritance amongst options.
Added convenience constructor to DefaultIdStoringStrategy.
This makes life easier for users that want to use object identity
(rather than equality) when generating IDs.
Fixed TextRule content bug. (Issue #36930).
Fixed attribute ID name recognition bug. (Issue #36929).
Added support for text and options into multi-mappings.
Improved support for subclasses of Java collective types
by factoring collective type recognition into strategy.
Added support for multiple contained polymorphic mappings.
Added transcription strategy to allow flexbility for schema type names.
Added package name property suppression strategy and make default property suppression strategy public
nest so that it can be subclassed.
Fixed bug when introspecting in secure environments.
Fixed formatting bug when pretty printing elements with
endTagForEmptyElement is true.
Made intitial indent level used for pretty printing configurable.
- Added guess-name attribute to addDefaults element in dot betwixt file.
This allows mixed collections to be used with add-adders and addDefaults.
- Fixed map custom updater in dot betwixt file bug.
- EOL in pretty printed xml now defaults to platform line separator.
ValueSuppressionStrategy.suppressElement to allow elements to be suppressed
on the basis of the value of the property. Useful for Hibernate users.
element tag in dot betwixt file.
This allows updater methods to be found that are not public.
- Fixed bug in nested element diagnosing empty elements.
- Added support for polymorphic mappings.
This allows the type of a property to be guessed at bind time
(rather than at compile time).
- Added options to context. This replaces direct flavour mechanism.
(Flavour becomes just a specific option).
- Factored out id storage into strategy
- anonymous collections now allowed in betwixt files
- Improved introspection support for DynaBeans
- Improved introspection for interfaces superinterface
properties now checked.
- Attribute suppression - Betwixt now allows the
expression of certain values to be suppressed through a custom strategy.
- Custom Dot Betwixt Documents - custom dot betwixt
documents can be passed in directly.
- Multi mapping documents allowing several mappings to be
specified within a single document.
- Improved support for derived beans bind time type
population now supported and enabled by default
- All exceptions are now complex
- PropertySuppressionStrategy added which allows
course grained control of those properties which should be ignored by Betwixt.
- Improved support for java.util collections API implementations.
Betwixt now recognizes additional properties on custom collection implementations.
- Improved empty element rendering
- Extended betwixt file by adding two new properties
to <addDefaults> that allow matching properties or adders to be
- SimpleTypeMapper strategy for finely grained control over simple type (primitive)
- Improved support for reading arrays. In particular added code to support
reading of array valued property setters and for array valued adders.
- Added support for CDATA encoding through strategy
for mixed content encoding.
- Created DTD for .betwixt files.
- Added validity check for element and attribute names in .betwixt files
.betwixt files contain names for xml elements and attributes. Only certain names
for elements and attributes are allowed by the xml specification. Betwixt now
check to ensure that the names are appropraite and terminates processing with an
Exception if they are not.
- Created XMLUtils
Separated out basic xml utilty methods into a static utility class called XMLUtils.
This should allow them to be reused in isolation.
- Improved digester integration
Improved integration with digester.
BeanRuleSet is a digester ruleset
which sets up all the rules required to digester a bean. When a bean is registered,
BeanRuleSet instance is used to set up the required rule on digester.
Standard digester rules can be added before and after registration.
- Handle empty elements better.
An option not to write empty elements has been added. This is required to correctly write
some kinds of xml.
The RSS full round tripping will only work with this functionality.
- Support Writing Mixed Content
Mixed content elements contain elements and body text. Added support for adding
body text between child elements through the .betwixt file. This text can be
static or set from a property.
- Allow customization for update from .betwixt file
Add updater attribute that allows the updater to be specified for an elements.
- Added Reading for Composite Map Properties
Added code that reads entries for composite map properties and adds then correctly.
This code relies on the Betwixt map element mapping format.
- Added setter for bean writing encoding type
Added an additional constructor which takes an encoding type which is used to set the
encoding type on the output stream. This allows xml with different encoding types to
- Fixed bug when writing Array's
When an array was pass to a write call, invalid XML used to be produced. This has been fixed.
- Basic Support For Reading Mixed Content
This is the basic case where all of the content is read into a single property.
- Basic Support For Writing DynaBeans
Basic support for writing DynaBeans has been added. This was implemented by using an additional
layer of abstraction in the introspector.
- Support for converting output strings
ConvertUtils is now called to convert output strings (as well as input ones).
- Refactored Object <-> String Conversion
This process has been factored out into a separate pluggable Strategy class
ObjectStringConverter). A pure
has been created (
ConvertUtilsObjectStringConverter). The default implementation
DefaultsObjectStringConverter) delegates most conversions to
but contains a special case that allows the default setting to round trip java.util.Date's
without breaking compatibility.
- Refactored creation of Bean For Elements In Reading
Factored out the code that creates beans for elements (when reading) into separates classes uses the
Chain Of Responsibility pattern. This allows users to hook into the creation process and
add their own custom creation steps or replace the defaults with new functionality.
- Improved Support For Interfaces (.betwixt files)
Added (optional) 'class' attribute to .betwixt files. The attribute value should be a fully qualfied java classname.
When set, the named class will be used to instantiate beans mapped to this element.
- Improved Support For Interfaces including Entity Beans (ClassNormalizer)
Added ClassNormalizer strategy. This allows the Class introspector to differ from that of the Object.
- Added Support For Replacement Of Bad Characters to default mapping of element names.
- Added Options mechanism for communication behaviour hints to optional
- CDATA encoding support add support for flexible coding of body text as CDATA
sections (in addition to character escaping).
- IdStoringStrategy.DEFAULT should never have been a constant
since the implementation uses instance variables.
Using this constant will result in a memory leak.
Note: use proper factory methods
rather than public constant fields in the future!
- ElementRule added forceAccessible attribute
- configureDescriptor replaced by private method with extra parameter
- ObjectStringConverter direct flavour replaced with use of options
- objectToString replaced by method without flavour in signature
- stringToObject replaced by method without flavour in signature
- Refactoring (more declarative descriptors)
WrapCollectionsInElement property removed
PrimitiveType property removed
- XMLIntrospectorHelper this will be deprecated.
- Refactored introspection configuration into separate class
- useBeanInfoSearchPath property
- AttributeNameMapper property
- ElementNameMapper property
- PluralStemmer property
- WrapCollectionsInElement property
- AttributesForPrimitives property
- ClassNormalizer property
- Adding context parameter to SAX style API
BeanWriter.escapeAttributeValue() moved into XMLUtils
BeanWriter.escapeBodyValue() moved into XMLUtils
BeanCreateRule has been replaced by BeanRuleSet
Expression.update has been replaced by Updater
- Refactoring (new SAX inspired API)
getIndentLevel moved into BeanWriter
- Adding support for reading mixed content
createDescriptor refactored into XMLIntrospector
addProperty replaced by overloaded method
addProperties replaced by overloaded method
Backwards Incompatible Changes
Betwixt now (by default) suppresses the expression of all empty attributes.
The old behaviour can be restored by setting the
BindingConfiguration used by the writer to
Betwixt now defaults to bind time type mapping. Now read beans will (by default)
be populated by their bind time type (as opposed to their introspection time type).
Most users should notice no negative effects from this change. The previous behaviour
can be enabled by setting an introspection configuration property.
All exceptions are now complex types. This is now more consistent but the default
binding for exceptions in java.lang package have been changed from simple to complex.
Properties on collection implementations are now recognized (rather than ignored)
by Betwixt. Please use an appropriate
ClassNormalizer for implementations
that need to hide their extra properties.
- Introspection and ElementDescriptor changes in introspection and
ElementDescriptor to make them more declarative so that the logic required to
read and write beans can be reduced. An explicit flag has been added to indicate
which ElementDescriptors are hollow. The descriptors describing collective mappings
(one-to-many). wrapCollectionInElement has been removed with the wrapping element
descriptor becoming just a spacer (an xml element which is not mapped to a part of
the object graph). The updater now needs to be placed on the hollow collective
element rather than then parent spacer.
- ID assignment IDs are now not assigned to any element
which are simple (do not have any children and no attributes) rather than just primitives.
The concept of primitives is being phased out in favour of the more general
concept of atomic mappings (object <-> string) and elements of simple type.
ID generation is likely to be refactored soon so that it's performed within
the structure of the attribute references rather than as part of the writing
- SAXBeanWriter now sets localName
SAXBeanWriter now sets localName as well as qName for each SAX call. The local name
is derived from the qualified name. Users whose names contain colons but which do not
comply with the namespace dialect will need to set the NamespaceDialect property to
- AbstractBeanWriter has been refactored
AbstractBeanWriter has been extensively refactored.
The public interface has been preserved but the protected API has been extensively modified.
In order to preserve backwards compatibility, methods have been deprecated but are no
longer called and so code that overrides then will break.
- Cleaner API for SAXBeanWriter
The AbstractBeanWriter refactoring means that SAXBeanWriter now has a much cleaner
internal API. If anyone out there has been doing funky stuff by extending SAXBeanWriter
then i'm afraid that you'll need to rewrite.
- Refactored Introspection
XMLIntrospector has been refactored to add an extra level of introspection indirection.
The results of introspection are now given in a BeanProperty. This allows support for
introspection alternatives to be added.
- DynaBean Implementations
DynaBean's are now mapped using the properties found via the pseudo-introspection process
defined in BeanUtils. If you don't wish for DynaBeans implementations to be introspected
in this way then provide a
.betwixt file to specify the mapping.
- String To Object Conversions Now Use
ConvertUtils from commons-beanutils is now called to performt the object to
string conversions. It is possible that in some circumstances, this change may effect the
ConvertUtils conversion now ignored (by default) for java.util.Date
If you use a custom
ConvertUtils java.util.Date converter then see