- 3 -
The JavaBeans API
at a Glance

With all the neat things JavaBeans accomplishes, you might imagine that there is some highly complex system pulling all kinds of magical tricks under the hood. The truth is, there is no magic behind JavaBeans and surprisingly little complexity considering how advanced it is as a software component technology. The lack of complexity in JavaBeans is due to the well-designed JavaBeans API, which is completely responsible for carrying out all the interesting ideas about which you learned in Chapter 2, "Welcome to JavaBeans."

In this chapter you take a quick tour through the JavaBeans API to familiarize yourself with all emergency locations. No, actually the tour is meant to help you get the big picture of how the API is divided and what type of functionality each part of it addresses. Although there are a decent number of classes and interfaces defined in the API, you don't have to worry about them just yet. Being faced with a large amount of new information to process and digest is always somewhat overwhelming, so this chapter just hits the high points. This way, you'll have some perspective when you dig into more details in chapters to come.

Keep in mind throughout the chapter that JavaBeans is ultimately a programming interface, which means that all of its features are implemented as extensions to the standard Java class library. Therefore, the functionality provided by JavaBeans is actually implemented in the JavaBeans API. The JavaBeans API itself is merely a suite of smaller APIs devoted to specific functions, or services. Following is a list of the main component services in the JavaBeans API that are necessary to facilitate all the features that make JavaBeans such an exciting technology:

By understanding these services and how they work, you'll have much more insight into exactly what type of technology JavaBeans is. This entire chapter is devoted to understanding the basics of these APIs and why they are necessary elements of the JavaBeans architecture. Keep in mind that each of these parts of the JavaBeans API is covered in greater detail in Part II of the book, "Inside the JavaBeans API."

Property Management

The property management facilities in the JavaBeans API are responsible for handling all interactions relating to bean properties. Properties reflect the internal state of a bean and constitute the data part of a bean's structure. More specifically, properties are discrete, named attributes of a bean that determine its appearance and behavior. Properties are important in any component technology because they isolate component state information into discrete pieces that can be easily modified.


New Term: Properties are discrete, named attributes of a bean that determine its appearance and behavior.

To get a better idea of the importance of properties, it's helpful to consider some different scenarios in which properties are dealt with. Following are some examples of how bean properties are accessed and used:

As this list shows, properties come into play in a variety of ways when it comes to bean access and manipulation. Notice the flexibility properties provide: You can access them through scripting languages such as JavaScript, full-blown programming languages such as Java, and visual builder tools. This freedom to access and manipulate beans in a variety of ways is one of the critical design goals of the JavaBeans technology. And it is fulfilled by the property management facilities in the JavaBeans API.

The next few sections cover some of the major issues addressed by the JavaBeans API property management facilities. These issues are explored in much greater detail in Chapter 4, "Manipulating Bean Properties."

Accessor Methods

The primary way in which properties are exposed in the JavaBeans API is through accessor methods. An accessor method is a public method defined in a bean that directly reads or writes the value of a particular property. Each property in a bean must have a corresponding pair of accessor methods: one for reading the property and one for writing. The accessor methods responsible for reading are known as getter methods because they get the value of a property. Likewise, accessor methods responsible for writing are known as setter methods because they set the value of a property.


New Terms: An accessor method is a public method defined in a bean that reads or writes the value of a property.

A getter method is an accessor method that reads, or gets, the value of a property.

A setter method is an accessor method that writes, or sets, the value of a property.

Indexed Properties

So far, the discussion of properties has been limited to single-value properties, which are by and large the most common properties used in JavaBeans. However, the JavaBeans API also supports indexed properties, which are properties that represent an array of values. Indexed properties work very similarly to arrays in traditional Java programming, where you access a particular value using an integer index. Indexed properties are very useful in situations in which a bean needs to maintain a group of properties of the same type. For example, a container bean that keeps track of the physical layout of other beans might store references to them in an indexed property.


New Term: Indexed properties are bean properties that represent an array of values.

Bound and Constrained Properties

The JavaBeans API supports two mechanisms for working with properties at a more advanced level: bound and constrained properties. Bound properties are properties that provide notifications to an interested party based on changes in the property value. An interested party is an applet, application, or bean that needs to know about changes in the property. These properties are called bound properties because they are bound to some type of external behavior based on their own changes. Bound properties are defined at the component level, which means that a bean is responsible for specifying which components are bound. An example of a bound property is a visibility property, which a bean's container might be interested in knowing the status of because it would need to graphically reorganize other beans based on a bean's visibility.


New Term: A bound property is a property that provides notifications to an interested party based on changes in its value.

The other interesting property feature provided by the JavaBeans API is support for constrained properties, which are properties that enable an interested party to perform a validation on a new property value before accepting the modification. Constrained properties are useful in enabling interested parties control over how a bean is altered. An example of a constrained property is a date property, where the application containing the bean wants to limit the valid date property values to a certain range.


New Term: A constrained property is a property that enables an interested party to perform a validation on a new property value before accepting the modification.

Introspection

The introspection facilities in the JavaBeans API define the mechanism by which components make their internal structure readily available to the outside world. These facilities consist of the functional overhead necessary to enable development tools to query a bean for its internal structure, including the interfaces, methods, and member variables that comprise the bean. Although the introspection services are primarily designed for use by application builder tools, they are grouped separately from the application builder services in the API because their role in making a bean's internal structure available externally is technically independent of builder tools. In other words, there might be other reasons for querying a bean as to its internal structure beyond the obvious use in builder tools.

The introspection services provided by the JavaBeans API are divided into two parts, low-level services and high-level services, which are distinguished by the level of access they provide to bean internals. The low-level API services are responsible for enabling wide access to the structural internals of a bean. These services are very important for application builder tools that heavily use bean internals to provide advanced development features. However, this level of access isn't appropriate for developers who are using beans to build applications because it exposes private parts of a bean that aren't meant to be used by developers at the application level. For these purposes, the high-level API services are more appropriate.

The high-level services use the low-level services behind the scenes to provide access to limited portions of a bean's internals, which typically consist of a bean's public properties and methods. The difference between the two levels of services is that the high-level services don't enable access to internal aspects of a bean that aren't specifically designed for external use. The end result is two distinct services that offer bean introspection capabilities based on the level
of access required by the interested party, be it an application builder tool or
a user.

The next few sections cover several of the major functions supported in the JavaBeans API introspection facilities. These functions are described in much greater detail in Chapter 5, "Introspection: Getting to Know a Bean."

Reflection and Design Patterns

The JavaBeans API has a very interesting technique of assessing the public properties, methods, and events for a bean. To determine information about a bean's public features, the bean's methods are analyzed using a set of low-level reflection services. These services gather information about a bean and determine its public properties, methods, and events by applying simple design patterns. Design patterns are rules applied to a bean's method definitions that determine information about the bean. For example, when a pair of accessor methods are encountered in the analysis of a bean, the JavaBeans introspection facilities match them based on a design pattern and automatically determine the property they access.


New Terms: Reflection is the process of studying a bean to determine information about its functionality and public facilities.
Design patterns are rules used to determine information about a bean from its reflected method names and signatures.

The whole premise of design patterns is that method names and signatures conform to a standard convention. There are a variety of different design patterns for determining everything from simple properties to event sources. All of these design patterns rely on some type of consistent naming convention for methods and their arguments. This approach to introspection is not only convenient from the perspective of JavaBeans, but it also has the intended side effect of encouraging bean developers to use a consistent set of naming
conventions.

Explicit Bean Information

Even though the design pattern approach to introspection is very useful and encourages a consistent approach to naming, you might be wondering what happens if bean developers don't follow the convention. Fortunately, design patterns aren't the only option for introspection, meaning that obstinate developers are free to ignore the suggested naming conventions if they so choose. The developers who opt to cast convention into the wind must use another introspection facility in the JavaBeans API where they explicitly list the public information about their beans. They must "spill the beans," to inject a painfully bad pun.

The explicit introspection facility in the JavaBeans API to which I'm referring involves creating a bean information class that specifies various pieces of information about a bean including a property list, method list, and event list. This approach isn't automatic like the design patterns about which you just learned, but it does provide a means to explicitly describe your bean to the world, which might be advantageous in some situations.

The Introspector

Just in case you're wondering how two different introspection approaches can possibly coexist to describe a single bean, there is another service that consolidates the whole introspection process. The introspection facilities provide an introspector that is used to obtain explicit information for a bean. The introspector is responsible for traversing the inheritance tree of a bean to
determine the explicit bean information for all parent beans. If at any point explicit information is not defined, then the introspector falls back on the reflection services and uses design patterns to automatically determine external bean information.

This two-tiered solution to assessing bean functionality is very nice because it first attempts to use information explicitly provided by a bean's developer, and relies on automatic design patterns only if the explicit information isn't there. The other nice thing is that it supports a mixture of the two approaches, which means, for example, that methods for a bean could be explicitly defined via a provided bean information class but the properties and events could be determined automatically via design patterns. This gives bean developers a lot of flexibility in deciding how they want their beans exposed.

Event Handling

The event handling facilities in the JavaBeans API specify an event-driven architecture that defines interactions among beans and applications. If you're familiar with the Java AWT, you know that it already provides a comprehensive event handling model. This existing AWT event model forms the basis of the event handling facilities in the JavaBeans API. These event handling facilities are critical in that they determine how beans respond to changes in their state, as well as how these changes are propagated to applications and other beans.

The event-handling facilities hinge around the concepts of event sources and listeners. A bean that is capable of generating events is considered an event source, whereas an application or bean that is capable of responding to an event is considered an event listener. Event sources and listeners are connected via
an event registration mechanism that is part of the event handling facilities. This registration mechanism basically boils down to an event listener being registered with an event source via a simple method call. When the source
generates an event, a specified method is called on the event listener with an event state object being sent along as its argument. Event state objects are
responsible for storing information associated with a particular event. In other words, event state objects carry with them any information related to the event being sent.


New Terms: An event source is a bean capable of generating events. An event listener is an application or bean capable of responding to events.
An event state object is used to store information associated with a particular event.

The next few sections cover some of the major issues dealt with by the JavaBeans API event handling facilities. These issues are explored in much greater detail in Chapter 6, "Handling Bean Events."

Unicast and Multicast Event Sources

Although most practical event sources support multiple listeners, the event-handling facilities provide for event sources that choose to limit their audience to a single listener. These sources are called unicast event sources, and their more liberal counterparts are called multicast event sources. The primary functional difference between the two is that unicast event sources will throw an exception if an attempt is made to register more than one listener.


New Terms: A unicast event source is an event source capable of generating events for retrieval by only one listener.
A multicast event source is an event source capable of generating events for retrieval by any number of listeners.

Even though the JavaBeans API supports both unicast and multicast event sources, keep in mind that multicast event sources are much less limiting in terms of practical use. In other words, developers should avoid designing beans as unicast event sources whenever possible.

Event Adapters

Even though many bean events fall under the standard source/listener model about which you just learned, the JavaBeans API provides a mechanism for dealing with more complex situations in which this model doesn't quite fit the bill. This mechanism is based on event adapters, which act as intermediaries between event sources and listeners. Event adapters sit between sources and listeners and provide a means of inserting specialized event delivery behavior into the standard source/listener event model. Event adapters are important to the event-handling facilities because they open the door for implementing a highly specialized event handling mechanism tailored to the unique challenges sometimes encountered in applications or application builder tools.


New Term: Event adapters are intermediaries placed between event sources and listeners that provide additional event delivery behavior.

Persistence

The persistence facilities in the JavaBeans API specify the mechanism by which beans are stored and retrieved within the context of a container. The information stored through persistence consists of all parts of a bean that are necessary to restore the bean to a similar internal state and appearance. This generally involves the storage of all public properties and potentially some internal
properties, although the specifics are determined by each particular bean.
Information not stored for a bean through persistence are references to external beans, including event registrations; these references are expected to be somehow stored by an application builder tool or through some programmatic means.

By default, beans are persistently stored and retrieved using the automatic serialization mechanism provided by Java, which is sufficient for most beans. However, bean developers are also free to create more elaborate persistence solutions based on the specific needs of their beans. Like the introspection facilities, the persistence facilities provide for both an explicit approach or an automatic approach to carrying out its functions. The JavaBeans API persistence facilities are described in much greater detail in Chapter 7, "Persistence: Saving Beans for a Rainy Day."

Application Builder Support

The final area of the JavaBeans API deals with application builder support. The application builder support facilities provide the overhead necessary to edit and manipulate beans using visual application builder tools. Application builder tools rely heavily on these facilities to enable a developer to visually lay out and edit beans while constructing an application. These facilities fulfill a major design goal of the JavaBeans API in that they enable beans to be used constructively with little or no programming effort.

One issue the JavaBeans architects wrestled with is the fact that application builder support for a specific bean is required only at design time. Consequently, it is somewhat wasteful to bundle this support code with a runtime bean. Because of this situation, the application builder facilities call for builder-specific overhead for a bean to be physically separate from the bean itself. This enables beans to be distributed by themselves for runtime use or in conjunction with the application builder support for design-time use.

The next few sections cover some of the major issues dealt with by the JavaBeans API application builder support facilities. These issues are explored in much greater detail in Chapter 8, "Customization: Bean Support for Application Builders."

Property Editors and Sheets

One of the ways in which the JavaBeans API supports the editing and manipulation of beans with application builder tools is through property sheets. A property sheet is a visual interface that provides editors for each public property defined for a bean. The individual editors used in a property sheet are called property editors. Each type of exported property in a bean must have a corresponding property editor in order to be edited visually by a builder tool. Some standard property editors are provided by the JavaBeans API for built-in Java types, but user-defined properties require their own custom editors. The property editors for all the exported properties of a bean are presented together on a property sheet that enables users to edit the properties visually.


New Terms: A property sheet is a user interface that contains property editors for all the exported properties of a bean.
A property editor is a user interface that enables the visual editing of a particular property type.

Customizers

The other way in which the JavaBeans API enables beans to be visually edited in an application builder tool is through customizers, which are user interfaces that provide a specialized means of visually editing bean properties. Because customizers are implemented entirely by bean developers, there are no firm guidelines as to how they present visual property information to the user. However, most customizers probably will be similar in function to "wizards," which are popular user interfaces on the Windows platform that use multiple-step questionnaires to gather information from the user.


New Terms: A customizer is a user interface that provides a specialized means of visually editing bean properties.
A wizard is a user interface that uses multiple-step questionnaires to gather information from the user.

Summary

This chapter took you a significant step deeper into the JavaBeans technology by exploring the JavaBeans API. This API is ultimately responsible for delivering all the functionality of JavaBeans. You learned that the API is comprised of several major functional areas that are each devoted to a particular JavaBeans service. You covered the basics of each of these areas and looked at the kinds of problems they address and the different solutions they provide.

Although the discussions throughout this chapter were fairly general and avoided too much technical detail, they still painted a pretty complete picture of the JavaBeans API, at least from a conceptual level. Armed with this knowledge, you're ready to press on to the inner workings of each of these API areas in the next part of the book, "Inside the JavaBeans API." Roll up your sleeves and get ready for more fun!