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: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
