You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by cr...@apache.org on 2002/01/21 21:00:01 UTC
cvs commit: jakarta-commons/beanutils/src/java/org/apache/commons/beanutils package.html
craigmcc 02/01/21 12:00:01
Modified: beanutils/src/java/org/apache/commons/beanutils package.html
Log:
Add some basic User's Guide type documentation to the package JavaDocs.
Revision Changes Path
1.3 +531 -0 jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/package.html
Index: package.html
===================================================================
RCS file: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/package.html,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- package.html 15 Jul 2001 00:00:07 -0000 1.2
+++ package.html 21 Jan 2002 20:00:01 -0000 1.3
@@ -8,12 +8,543 @@
values on Java classes that follow the naming design patterns outlined in the
JavaBeans Specification.</p>
+<h1>Table of Contents</h1>
+
+<ol>
+<li><a href="#overview">Overview</a>
+ <ul>
+ <li><a href="#overview.background">Background</a></li>
+ <li><a href="#overview.dependencies">External Dependencies</a></li>
+ </ul></li>
+<li><a href="#standard">Standard JavaBeans</a>
+ <ul>
+ <li><a href="#standard.background">Background</a></li>
+ <li><a href="#standard.basic">Basic Property Access</a></li>
+ <li><a href="#standard.nested">Nested Property Access</a></li>
+ </ul></li>
+<li><a href="#dynamic">Dynamic Beans (DynaBeans)</a>
+ <ul>
+ <li><a href="#dynamic.background">Background</a></li>
+ <li><a href="#dynamic.basic">BasicDynaBean and BasicDynaClass</a></li>
+ <li><a href="#dynamic.wrap">WrapDynaBean and WrapDynaClass</a></li>
+ </ul></li>
+<li><a href="#conversion">Data Type Conversions</a>
+ <ul>
+ <li><a href="#conversion.background">Background</a></li>
+ <li><a href="#conversion.beanutils">BeanUtils and ConvertUtils
+ Conversions</a></li>
+ <li><a href="#conversion.defining">Defining Your Own Converters</a></li>
+ </ul></li>
+</ol>
+
+<a name="overview"></a>
+<h1>Overview</h1>
+
+<a name="overview.background"></a>
+<h3>Background</h3>
+
+<p>The <em>JavaBeans</em> name comes from a
+<a href="http://java.sun.com/products/javabeans/">Java API specification</a>
+for a component architecture for the Java language. Writing Java classes that
+conform to the JavaBeans design patterns makes it easier for Java developers
+to understand the functionality provided by your class, as well as allowing
+JavaBeans-aware tools to use Java's <em>introspection</em> capabilities to
+learn about the properties and operations provided by your class, and present
+them in a visually appealing manner in development tools.</p>
+
+<p>The <a href="http://java.sun.com/javabeans/docs/spec.html">JavaBeans
+Specification</a> describes the complete set of characteristics that makes
+an arbitrary Java class a JavaBean or not -- and you should consider reading
+this document to be an important part of developing your Java programming
+skills. However, the required characteristics of JavaBeans that are
+important for most development scenarios are listed here:</p>
+<ul>
+<li>The class must be <strong>public</strong>, and provide a
+ <strong>public</strong> constructor that accepts no arguments. This allows
+ tools and applications to dynamically create new instances of your bean,
+ without necessarily knowing what Java class name will be used ahead of
+ time, like this:
+<pre>
+ String className = ...;
+ Class beanClass = Class.forName(beanClass);
+ Object beanInstance = beanClass.newInstance();
+</pre></li>
+<li>As a necessary consequence of having a no-arguments constructor,
+ configuration of your bean's behavior must be accomplished separately
+ from its instantiation. This is typically done by defining a set of
+ <em>properties</em> of your bean, which can be used to modify its behavior
+ or the data that the bean represents. The normal convention for
+ property names is that they start with a lower case letter, and be
+ comprised only of characters that are legal in a Java identifier.</li>
+<li>Typically, each bean property will have a public <em>getter</em> and
+ <em>setter</em> method that are used to retrieve or define the property's
+ value, respectively. The JavaBeans Specification defines a design
+ pattern for these names, using <code>get</code> or <code>set</code> as the
+ prefix for the property name with it's first character capitalized. Thus,
+ you a JavaBean representing an employee might have
+ (among others) properties named <code>firstName</code>,
+ <code>lastName</code>, and <code>hireDate</code>, with method signatures
+ like this:
+<pre>
+ public class Employee {
+ public Employee(); // Zero-arguments constructor
+ public String getFirstName();
+ public void setFirstName(String firstName);
+ public String getLastName();
+ public void setLastName(String lastName);
+ public Date getHireDate();
+ public void setHireDate(Date hireDate);
+ public boolean isManager();
+ public void setManager(boolean manager);
+ public String getFullName();
+ }
+</pre></li>
+<li>As you can see from the above example, there is a special variant allowed
+ for boolean properties -- you can name the <em>getter</em> method with a
+ <code>is</code> prefix instead of a <code>get</code> prefix if that makes
+ for a more understandable method name.</li>
+<li>If you have both a <em>getter</em> and a <em>setter</em> method for a
+ property, the data type returned by the <em>getter</em> must match the
+ data type accepted by the <em>setter</em>. In addition, it is contrary
+ to the JavaBeans specification to have more than one <em>setter</em>
+ with the same name, but different property types.</li>
+<li>It is not required that you provide a <em>getter</em> and a
+ <em>setter</em> for every property. In the example above, the
+ <code>fullName</code> property is read-only, because there is no
+ <em>setter</em> method. It is also possible, but less common, to provide
+ write-only properties.</li>
+<li>It is also possible to create a JavaBean where the <em>getter</em> and
+ <em>setter</em> methods do not match the naming pattern described above.
+ The standard JavaBeans support classes in the Java language, as well as
+ all classes in the BeanUtils package, allow you to describe the actual
+ property method names in a <code>BeanInfo</code> class associated with
+ your bean class. See the JavaBeans Specification for full details.</li>
+<li>The JavaBeans Specification also describes many additional design patterns
+ for event listeners, wiring JavaBeans together into component hierarchies,
+ and other useful features that are beyond the scope of the BeanUtils
+ package.</li>
+</ul>
+
+<p>Using standard Java coding techniques, it is very easy to deal with
+JavaBeans if you know ahead of time which bean classes you will be using, and
+which properties you are interested in:</p>
+<pre>
+ Employee employee = ...;
+ System.out.println("Hello " + employee.getFirstName() + "!");
+</pre>
+
+<a name="overview.dependencies"></a>
<h3>External Dependencies</h3>
+<p>The <em>commons-beanutils</em> package requires that the following
+additional packages be available in the application's class path at runtime:
+</p>
<ul>
<li><a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-collections">
Collections Package (Jakarta Commons)</a>, version 1.0 or later</li>
</ul>
+
+
+<a name="standard"></a>
+<h1>Standard JavaBeans</h1>
+
+<a name="standard.background"></a>
+<h3>Background</h3>
+
+<p>As described above, the standard facilities of the Java programming language
+make it easy and natural to access the property values of your beans using
+calls to the appropriate getter methods.
+But what happens in more sophisticated environments where you do not
+necessarily know ahead of time which bean class you are going to be using,
+or which property you want to retrieve or modify? The Java language provides
+classes like <code>java.beans.Introspector</code>, which can examine a Java
+class at runtime and identify for you the names of the property getter and
+setter methods, plus the <em>Reflection</em> capabilities to dynamically call
+such a method. However, these APIs can be difficult to use, and expose the
+application developer to many unnecessary details of the underlying structure
+of Java classes. The APIs in the BeanUtils package are intended to simplify
+getting and setting bean properties dynamically, where the objects you are
+accessing -- and the names of the properties you care about -- are determined
+at runtime in your application, rather than as you are writing and compiling
+your application's classes.</p>
+
+<p>This is the set of needs that are satisfied by the static methods of the
+<a href="PropertyUtils.html">PropertyUtils</a>
+class, which are described further in this section. First, however, some
+further definitions will prove to be useful:</p>
+
+<p>The general set of possible property types supported by a JavaBean can be
+broken into three categories -- some of which are supported by the standard
+JavaBeans specification, and some of which are uniquely supported by the
+<em>BeanUtils</em> package:</p>
+<ul>
+<li><strong>Simple</strong> - Simple, or scalar, properties have a single
+ value that may be retrieved or modified. The underlying property type
+ might be a Java language primitive (such as <code>int</code>, a simple
+ object (such as a <code>java.lang.String</code>), or a more complex
+ object whose class is defined either by the Java language, by the
+ application, or by a class library included with the application.</li>
+<li><strong>Indexed</strong> - An indexed property stores an ordered collection
+ of objects (all of the same type) that can be individually accessed by an
+ integer-valued, non-negative index (or subscript). Alternatively, the
+ entire set of values may be set or retrieved using an array.
+ As an extension to the JavaBeans specification, the
+ <em>BeanUtils</em> package considers any property whose underlying data
+ type is <code>java.util.List</code> (or an implementation of List) to be
+ indexed as well.</li>
+<li><strong>Mapped</strong> - As an extension to standard JavaBeans APIs,
+ the <em>BeanUtils></em> package considers any property whose underlying
+ value is a <code>java.util.Map</code> to be "mapped". You can set and
+ retrieve individual values via a String-valued key.</li>
+</ul>
+
+<p>A variety of API methods are provided in the <a href="PropertyUtils.html">
+PropertyUtils</a> class to get and set property values of all of these types.
+In the code fragments below, assume that there are two bean classes defined
+with the following method signatures:</p>
+<pre>
+ public class Employee {
+ public Address getAddress(String type);
+ public void setAddress(String type, Address address);
+ public Employee getSubordinate(int index);
+ public void setSubordinate(int index, Employee subordinate);
+ public String getFirstName();
+ public void setFirstName(String firstName);
+ public String getLastName();
+ public void setLastName(String lastName);
+ }
+</pre>
+
+<a name="standard.basic"></a>
+<h3>Basic Property Access</h3>
+
+<p>Getting and setting <strong>simple</strong> property values is, well,
+simple :-). Check out the following API signatures in the Javadocs:</p>
+
+<ul>
+<li><a href="PropertyUtils.html#getSimpleProperty(java.lang.Object,java.lang.String)">
+ PropertyUtils.getSimpleProperty(Object bean, String name)</a></li>
+<li><a href="PropertyUtils.html#setSimpleProperty(java.lang.Object,java.lang.String,java.lang.Object)">
+ PropertyUtils.setSimpleProperty(Object bean, String name, Object value)</a></li>
+</ul>
+
+<p>Using these methods, you might dynamically manipulate the employee's name
+in an application:</p>
+<pre>
+ Employee employee = ...;
+ String firstName = (String)
+ PropertyUtils.getSimpleProperty(employee, "firstName");
+ String lastName = (String)
+ PropertyUtils.getSimpleProperty(employee, "lastName");
+ ... manipulate the values ...
+ PropertyUtils.setSimpleProperty(employee, "firstName", firstName);
+ PropertyUtils.setSimpleProperty(employee, "lastName", lastName);
+</pre>
+
+<p>For <strong>indexed</strong> properties, you have two choices - you can
+either build a subscript into the "property name" string, using square
+brackets, or you can specify the subscript in a separate argument to the
+method call:</p>
+
+<ul>
+<li><a href="PropertyUtils.html#getIndexedProperty(java.lang.Object,java.lang.String)">
+ PropertyUtils.getIndexedProperty(Object bean, String name)</a></li>
+<li><a href="PropertyUtils.html#getIndexedProperty(java.lang.Object,java.lang.String,int)">
+ PropertyUtils.getIndexedProperty(Object bean, String name, int index)</a></li>
+<li><a href="PropertyUtils.html#setIndexedProperty(java.lang.Object,java.lang.String,java.lang.Object)">
+ PropertyUtils.setIndexedProperty(Object bean, String name, Object value)</a></li>
+<li><a href="PropertyUtils.html#setIndexedProperty(java.lang.Object,java.lang.String,int,java.lang.Object)">
+ PropertyUtils.setIndexedProperty(Object bean, String name, int index, Object value)</a></li>
+</ul>
+
+<p>Only integer constants are allowed when you add a subscript to the property
+name. If you need to calculate the index of the entry you wish to retrieve,
+you can use String concatenation to assemble the property name expression.
+For example, you might do either of the following:</p>
+<pre>
+ Employee employee = ...;
+ int index = ...;
+ String name = "subordinate[" + index + "]";
+ Employee subordinate = (Employee)
+ PropertyUtils.getIndexedProperty(employee, name);
+
+ Employee employee = ...;
+ int index = ...;
+ Employee subordinate = (Employee)
+ PropertyUtils.getIndexedProperty(employee, "subordinate", index);
+</pre>
+
+<p>In a similar manner, there are two possible method signatures for getting
+and setting <strong>mapped</strong> properties. The difference is that the
+extra argument is surrounded by parentheses ("(" and ")") instead of square
+brackets, and it is considered to be a String-value key used to get or set
+the appropriate value from an underlying map.</p>
+
+<ul>
+<li><a href="PropertyUtils.html#getMappedProperty(java.lang.Object,java.lang.String)">
+ PropertyUtils.getMappedProperty(Object bean, String name)</a></li>
+<li><a href="PropertyUtils.html#getMappedProperty(java.lang.Object,java.lang.String,java.lang.String)">
+ PropertyUtils.getMappedProperty(Object bean, String name, String key)</a></li>
+<li><a href="PropertyUtils.html#setMappedProperty(java.lang.Object,java.lang.String,java.lang.Object)">
+ PropertyUtils.setMappedProperty(Object bean, String name, Object value)</a></li>
+<li><a href="PropertyUtils.html#setMappedProperty(java.lang.Object,java.lang.String,java.lang.String,java.lang.Object)">
+ PropertyUtils.setMappedProperty(Object bean, String name, String key, Object value)</a></li>
+</ul>
+
+<p>You can, for example, set the employee's home address in either of these
+two manners:</p>
+
+<pre>
+ Employee employee = ...;
+ Address address = ...;
+ PropertyUtils.setMappedProperty(employee, "address(home)", address);
+
+ Employee employee = ...;
+ Address address = ...;
+ PropertyUtils.setMappedProperty(employee, "address", "home", address);
+</pre>
+
+<a name="standard.nested"></a>
+<h3>Nested Property Access</h3>
+
+<p>In all of the examples above, we have assumed that you wished to retrieve
+the value of a property of the bean being passed as the first argument to a
+PropertyUtils method. However, what if the property value you retrieve is
+really a Java object, and you wish to retrieve a property of <em>that</em>
+object instead?</p>
+
+<p>For example, assume we really wanted the <code>city</code> property of the
+employee's home address. Using standard Java programming techniques for direct
+access to the bean properties, we might write:</p>
+
+<pre>
+ String city = employee.getAddress("home").getCity();
+</pre>
+
+<p>The equivalent mechanism using the PropertyUtils class is called
+<strong>nested</strong> property access. To use this approach, you concatenate
+together the property names of the access path, using "." separators -- very
+similar to the way you can perform nested property access in JavaScript.</p>
+
+<ul>
+<li><a href="PropertyUtils.html#getNestedProperty(java.lang.Object,java.lang.String)">
+ PropertyUtils.getNestedProperty(Object bean, String name)</a></li>
+<li><a href="PropertyUtils.html#setNestedProperty(java.lang.Object,java.lang.String,java.lang.Object)">
+ PropertyUtils.setNestedProperty(Object bean, String name, Object value)</a></li>
+</ul>
+
+<p>The PropertyUtils equivalent to the above Java expression would be:</p>
+
+<pre>
+ String city = (String)
+ PropertyUtils.getNestedProperty(employee, "address(home).city");
+</pre>
+
+<p>Finally, for convenience, PropertyUtils provides method signatures that
+accept any arbitrary combination of simple, indexed, and mapped property
+access, using any arbitrary level of nesting:</p>
+
+<ul>
+<li><a href="PropertyUtils.html#getProperty(java.lang.Object,java.lang.String)">
+ PropertyUtils.getProperty(Object bean, String name)</a></li>
+<li><a href="PropertyUtils.html#setProperty(java.lang.Object,java.lang.String,java.lang.Object)">
+ PropertyUtils.setProperty(Object bean, String name, Object value)</a></li>
+</ul>
+
+<p>which you might use like this:</p>
+
+<pre>
+ Employee employee = ...;
+ String city = (String) PropertyUtils.getProperty(employee,
+ "subordinate[3].address(home).city");
+</pre>
+
+<a name="dynamic"></a>
+<h1>Dynamic Beans (DynaBeans)</h1>
+
+<a name="dynamic.background"></a>
+<h3>Background</h3>
+
+<p>The <a href="PropertyUtils.html">PropertyUtils</a> class described in the
+preceding section is designed to provide dynamic property access on existing
+JavaBean classes, without modifying them in any way. A different use case for
+dynamic property access is when you wish to represent a dynamically calculated
+set of property values as a JavaBean, but <em>without</em> having to actually
+write a Java class to represent these properties. Besides the effort savings
+in not having to create and maintain a separate Java class, this ability also
+means you can deal with situations where the set of properties you care about
+is determined dynamically (think of representing the result set of an SQL
+select as a set of JavaBeans ...).</p>
+
+<p>To support this use case, the <em>BeanUtils</em> package provides the
+<a href="DynaBean.html">DynaBean</a> interface, which must be implemented by a
+bean class actually implementing the interface's methods, and the associated
+<a href="DynaClass.html">DynaClass</a> interface that defines the set of
+properties supported by a particular group of DynaBeans, in much the same way
+that <code>java.lang.Class</code> defines the set of properties supported by
+all instances of a particular JavaBean class.</p>
+
+<p>For example, the <code>Employee</code> class used in the examples above
+might be implemented as a DynaBean, rather than as a standard JavaBean. You
+can access its properties like this:</p>
+
+<pre>
+ DynaBean employee = ...; // Details depend on which
+ // DynaBean implementation you use
+ String firstName = (String) employee.get("firstName");
+ Address homeAddress = (String) employee.get("address", "home");
+ Object subordinate = employee.get("subordinate", 2);
+</pre>
+
+<p>One very important convenience feature should be noted: <em>the
+PropertyUtils property getter and setter methods understand how to access
+properties in DynaBeans</em>. Therefore, if the bean you pass as the first
+argument to, say, <code>PropertyUtils.getSimpleProperty()</code> is really a
+DynaBean implementation, the call will get converted to the appropriate
+DynaBean getter method transparently. Thus, you can base your application's
+dynamic property access totally on the PropertyUtils APIs, if you wish, and
+use them to access either standard JavaBeans or DynaBeans without having to
+care ahead of time how a particular bean is implemented.</p>
+
+<p>Because DynaBean and DynaClass are interfaces, they may be implemented
+multiple times, in different ways, to address different usage scenarios. The
+following subsections describe the implementations that are provided as a part
+of the standard <em>BeanUtils</em> package, although you are encouraged to
+provide your own custom implementations for cases where the standard
+implementations are not sufficient.</p>
+
+<a name="dynamic.basic"></a>
+<h3><code>BasicDynaBean</code> and <code>BasicDynaClass</code></h3>
+
+<p>The <a href="BasicDynaBean.html">BasicDynaBean</a> and
+<a href="BasicDynaClass.html"> implementation provides a basic set of
+dynamic property capabilities where you want to dynamically define the
+set of properties (described by instances of <a href="DynaProperty.html">
+DynaProperty</a>). You start by defining the DynaClass that establishes
+the set of properties you care about:</p>
+
+<pre>
+ BasicDynaClass dynaClass = new BasicDynaClass("employee",
+ { new DynaProperty("address", "java.util.Map"),
+ new DynaProperty("subordinate", "mypackage.Employee[]"),
+ new DynaProperty("firstName", "java.lang.String"),
+ new DynaProperty("lastName", "java.lang.String") });
+</pre>
+
+<p>Next, you use the <code>newInstance()</code> method of this DynaClass to
+create new DynaBean instances that conform to this DynaClass, and populate
+its initial property values (much as you would instantiate a new standard
+JavaBean and then call its property setters):</p>
+
+<pre>
+ DynaBean employee = dynaClass.newInstance();
+ employee.set("address", new HashMap());
+ employee.set("subordinate", new mypackage.Employee[0]);
+ employee.set("firstName", "Fred");
+ employee.set("lastName", "Flintstone");
+</pre>
+
+<p>Note that the DynaBean class was declared to be
+<code>DynaBean</code> instead of <code>BasicDynaBean</code>. In
+general, if you are using DynaBeans, you will not want to care about the
+actual implementation class that is being used -- you only care about
+declaring that it is a <code>DynaBean</code> so that you can use the
+DynaBean APIs.</p>
+
+<p>As stated above, you can pass a DynaBean instance as the first argument
+to a <code>PropertyUtils</code> method that gets and sets properties, and it
+will be interpreted as you expect -- the dynamic properties of the DynaBean
+will be retrieved or modified, instead of underlying properties on the
+actual BasicDynaBean implementation class.</p>
+
+<a name="dynamic.wrap"></a>
+<h3><code>WrapDynaBean</code> and <code>WrapDynaClass</code></h3>
+
+<p>OK, you've tried the DynaBeans APIs and they are cool -- very simple
+<code>get()</code> and <code>set()</code> methods provide easy access to all
+of the dynamically defined simple, indexed, and mapped properties of your
+DynaBeans. You'd like to use the DynaBean APIs to access <strong>all</strong>
+of your beans, but you've got a bunch of existing standard JavaBeans classes
+to deal with as well. This is where the
+<a href="WrapDynaBean.html">WrapDynaBean</a> (and its associated
+<a href="WrapDynaClass.html">WrapDynaClass</a>) come into play. As the name
+implies, a WrapDynaBean is used to "wrap" the DynaBean APIs around an
+existing standard JavaBean class. To use it, simply create the wrapper
+like this:</p>
+
+<pre>
+ MyBean bean = ...;
+ DynaBean wrapper = new WrapDynaBean(bean);
+ String firstName = wrapper.get("firstName");
+</pre>
+
+<p>Note that, although appropriate <code>WrapDynaClass</code> instances are
+created internally, you never need to deal with them.</p>
+
+<a name="conversion"></a>
+<h1>Data Type Conversions</h1>
+
+<a name="conversion.background"></a>
+<h3>Background</h3>
+
+<p>So far, we've only considered the cases where the data types of the
+dynamically accessed properties are known, and where we can use Java casts
+to perform type conversions. What happens if you want to automatically
+perform type conversions when casting is not possible? The
+<em>BeanUtils</em> package provides a variety of APIs and design patterns
+for performing this task as well.</p>
+
+<a name="conversion.beanutils"></a>
+<h3><code>BeanUtils</code> and <code>ConvertUtils</code> Conversions</h3>
+
+<p>A very common use case (and the situation that caused the initial creation
+of the <em>BeanUtils</em> package was a desire to convert the set of request
+parameters that were included in a
+<code>javax.servlet.HttpServletRequest</code> received by a web application
+into a set of corresponding property setter calls on an arbitrary JavaBean.
+(This is one of the fundamental services provided by the
+<a href="http://jakarta.apache.org/struts">Struts Framework</a>, which uses
+<em>BeanUtils</em> internally to implement this functionality.)</p>
+
+<p>In an HTTP request, the set of included parameters is made available as a
+series of String (or String array, if there is more than one value for the
+same parameter name) instances, which need to be converted to the underlying
+data type. The <a href="BeanUtils.html">BeanUtils</a> class provides
+property setter methods that accept String values, and automatically convert
+them to appropriate property types for Java primitives (such as
+<code>int</code> or <code>boolean</code>), and property getter methods that
+perform the reverse conversion. Finally, a <code>populate()</code> method
+is provided that accepts a <code>java.util.Map</code> containing a set of
+property values (keyed by property name), and calls all of the appropriate
+setters whenever the underlying bean has a property with the same name as
+one of the request parameters. So, you can perform the all-in-one property
+setting operation like this:</p>
+
+<pre>
+ HttpServletRequest request = ...;
+ MyBean bean = ...;
+ HashMap map = new HashMap();
+ Enumeration names = request.getParameterNames();
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ map.put(name, request.getParameterValues(name));
+ }
+ BeanUtils.populate(bean, map);
+</pre>
+
+<p>The <code>BeanUtils</code> class relies on conversion methods defined in
+the <a href="ConvertUtils.html">ConvertUtils</a> class to perform the actual
+conversions, and these methods are availablve for direct use as well.
+<strong>WARNING</strong> - It is likely that the hard coded use of
+<code>ConvertUtils</code> methods will be deprecated in the future, and
+replaced with a mechanism that allows you to plug in your own implementations
+of the <a href="Converter.html">Converter</a> interface instead. Therefore,
+new code should not be written with reliance on ConvertUtils.</p>
+
+<a name="conversion.defining"></a>
+<h3>Defining Your Own Converters</h3>
+
+<p>This story has yet to be written ...</p>
</body>
</html>
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>