TODO list

The following is a list of items that need to be completed in Betwixt. Contributions are welcome!

High priority

  • 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 here . 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 more features.
  • Review AbstractBeanWriter and SAXBeanWriter AbstractBeanWriter and SAXBeanWriter were written very quickly (to support functionality in maven). They need to be reviewed and properly documentated.

Medium priority

  • 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.

Low priority

  • 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 to XMLIntrospector and then ensuring all class creation uses that. The digestion rules which create the XMLBeanInfo from .betwixt files should use the XMLBeanInfoDigester classloader property which should be set by the XMLIntrospector.
  • Create utility methods in BeanWriter to write stuff like prologs and doctype definitions to the stream.
  • 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.

Completed

Since 0.8

  • Added useContextClassLoader property to IntrospectionConfiguration. 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. See BETWIXT-57 .

0.8

  • 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.
  • Added 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.
  • Added ValueSuppressionStrategy.suppressElement to allow elements to be suppressed on the basis of the value of the property. Useful for Hibernate users.
  • Added forceAccessible to element tag in dot betwixt file. This allows updater methods to be found that are not public.

0.7

  • 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.

0.6

  • Improved empty element rendering
  • Extended betwixt file by adding two new properties to <addDefaults> that allow matching properties or adders to be supressed.
  • SimpleTypeMapper strategy for finely grained control over simple type (primitive) binding.
  • Improved support for reading arrays. In particular added code to support reading of array valued property setters and for array valued adders.

0.5

  • 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, a 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 be written.
  • 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 ConvertUtils implementation has been created (ConvertUtilsObjectStringConverter). The default implementation (DefaultsObjectStringConverter) delegates most conversions to ConvertUtils 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 strategies.
  • CDATA encoding support add support for flexible coding of body text as CDATA sections (in addition to character escaping).

Deprecated

Since 0.8

    0.8

    • IdStoringStrategy
      • 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

    0.7

    • ObjectStringConverter direct flavour replaced with use of options
      • objectToString replaced by method without flavour in signature
      • stringToObject replaced by method without flavour in signature

    0.6

    • Refactoring (more declarative descriptors)
      • ElementDescriptor
        • WrapCollectionsInElement property removed
        • PrimitiveType property removed
      • XMLIntrospectorHelper this will be deprecated.
    • Refactored introspection configuration into separate class
      • XMLIntrospector
        • useBeanInfoSearchPath property
        • AttributeNameMapper property
        • ElementNameMapper property
        • PluralStemmer property
        • WrapCollectionsInElement property
        • AttributesForPrimitives property
        • ClassNormalizer property

    0.5

    • 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)
        • AbstractBeanWriter
          • write removed
          • writeIDREFElement removed
          • writeAttributes removed
          • writeAttribute removed
          • writeRestOfElement removed
          • getIndentLevel moved into BeanWriter
          • expressElementStart removed
          • expressTagClose removed
          • expressElementEnd removed
          • expressBodyText removed
          • expressAttribute removed
          • writeRestOfElement removed
          • writeContent removed
          • writePrintln removed
          • writeIndent removed
        • BeanWriter
          • writePrintln removed
          • writeIndent removed
          • expressElementStart removed
          • expressTagClose removed
          • expressElementEnd removed
          • expressBodyText removed
          • expressAttribute removed
      • Adding support for reading mixed content
        • XMLIntrospectorHelper
          • createDescriptor refactored into XMLIntrospector
        • XMLIntrospector
          • addProperty replaced by overloaded method
          • addProperties replaced by overloaded method

      Backwards Incompatible Changes

      Since 0.8

        0.8

          0.7

            0.6

              Semantic Changes

              Since 0.8

                0.8

                  0.7

                  • Betwixt now (by default) suppresses the expression of all empty attributes. The old behaviour can be restored by setting the ValueSuppressionStrategy of the BindingConfiguration used by the writer to ValueSuppressionStrategy.ALLOW_ALL_VALUES.
                  • 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.

                  0.6

                  • 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 algorithm.

                  0.5

                  • 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 false.
                  • 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 ConvertUtilsConvertUtils 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 output.
                  • ConvertUtils conversion now ignored (by default) for java.util.Date If you use a custom ConvertUtils java.util.Date converter then see the guide .

                  Dependencies

                  Since 0.8

                    0.8

                      0.7

                      • Upgraded commons-beanutils to 1.7.0.
                      • Upgraded commons-digester to 1.6.

                      0.5

                      • Upgraded commons-beanutils to 1.6.1
                      • Upgraded commons-digester to 1.5