The Echo framework is divided into two distinct tiers:
The first tier, the Component Framework, provides classes used directly by application developers in order to create user interfaces. The component framework is contained entirely within the nextapp.echo
package structure.
The Component Framework DOES NOT provide any capabilities for interacting with client Web browsers, such as processing requests or generating HTML code. Such responsibilities are handled entirely by the Application Container, which is discussed later.
Component objects may assembled into hierarchies to create user interfaces. Each component represents a specific type of user interface component, e.g. the Button
and TextField
components represent the obvious user interface features they describe. All component objects are derived from the nextapp.echo.Component
class. A component may have properties which define its appearance, data, and behavior. More complex components will separate this information amongst multiple classes using a Model-View-Controller design pattern.
Figure 1: Component
objects assembled into a hierarchy to create a user interface.
An EchoInstance
object represents a single user-instance of an Echo application. EchoInstance
objects will be created for each new user visiting an application, and will maintain their state for the life of the user's session with the application. The EchoInstance
can be used by developers to store user-specific data that should be persistent throughout the life of the application. Storing data in an EchoInstance
would be analogous for JSP and Servlet programmers to storing data in a user's HttpSession
.
When a new EchoInstance
is created for a user, it's init()
method will be invoked. The init()
method, which is declared abstract
, is responsible for returning a Window
component. This Window
will represent the existing window of the user's Web browser.
The EchoInstance
object is responsible for keeping track of all top-level Window
components of an application. Any displayed Component
will have a window as its ultimate ancestor. Adding and removing windows to and from an application is accomplished by invoking EchoInstance
's addWindow()
and removeWindow()
methods.
Communication between Component
s is accomplished through the use of events. Components may generate events, which will be fired to listeners who register to receive them. Component
s will generate events whenever their states change.
The Application Container serves as a translation layer between an application's user interface (which is built using Echo components) and a client Web browser (whose interface is built using HTML and JavaScript). The Application Container is responsible for translating the state of an application's user interface into HTML and JavaScript, as well as translating user input from a client Web browser into a state where it can be processed by the application.
The Application Container is contained in the nextapp.echoservlet
package hierarchy.
Developers should not generally interact with the Application Container directly when developing Echo applications. If interaction with the Application Container is required, the appropriate method is for the developer to create his/her own rendered components (see Component Authoring Tutorial).
Many classes within the Application Container are purposed to handle translation for a specific class within the Component Framework. For example, the InstancePeer
class is the application container equivalent of the component framework's EchoInstance
class, and the application container's TextFieldUI
is similarly associated with the component framework's TextField
component.
The EchoServer
class is derived from the Servlet specification's HttpServlet
class. A single EchoServer
class is responsible for handling all client requests to a particular application.
The InstancePeer
is the Application Container corollary of the EchoInstance
class of the Component Framework. InstancePeer
s are responsible for the overall state of the Application Container side of an application. The InstancePeer
tracks changes to the hierarchy of Component
s of a single user-instance, and is responsible for creating and deleting rendering peers (discussed shortly) as necessary. It is also responsible for managing notification of user input to components, and determining which components have changed on the server and thus need to be updated on the client.
Every component in a visible hierarchy that is part of a visible Window registered to an EchoInstance will have a rendering peer. These peer objects are created automatically for all components of an EchoInstance
by the Application Container's InstancePeer
object.
Figure 2: Application Container peer objects for handling
Web client translation of an application's user interface.
Rendering peers are derived from the nextapp.echoservlet.ComponentPeer
class. The ComponentPeer
class specifies a method, render()
which is invoked to cause the peer to generate an HTML representation of itself for rendering. Additional interfaces, such as ClientInputProducer
and ClientActionProducer
may be implemented by a ComponentPeer
if it might receive user input from the client browser.
One rendering peer object is created for each Component of an application. Thus, rendering peers are stateful. Peer objects may contain state information that is relevant to a component's interaction with the client browser but may not be relevant to the component itself.
A Service is a class which registers itself to handle a certain type of HTTP request. A service is responsible for producing output which may be interpreted by a client Web browser, e.g. HTML code, JavaScript, a PNG image or even a Flash movie. Services are defined by implementing the nextapp.echoservlet.Service
interface.
In some cases, rendering peers that render entire HTML documents will implement the Service
interface. Examples can be found with ContainerPaneUI
(which renders an HTML frameset) and ContentPaneUI
(which renders a content pane).
Services must be registered in order to be eligible to be invoked. They may be registered globally, with the EchoServer
, as is the case for commonly used services such as those that render static JavaScript code to support specific components. Services which are also ComponentPeer
s will be registered with the single InstancePeer
to which they are relevant. ComponentPeer
s may also use additional services locally, called Ancillary services. Ancillary services exist for the life of the component peer, and are commonly used by components which will render images or internal frames which must be retrieved via additional HTTP requests from the client.
A Connection
object wraps an HttpServletRequest
and HttpServletResponse
, and provides convenience methods through which the relevant InstancePeer
for the user performing the operation may be obtained. A Connection
object is created by the EchoServer
whenever it receives an HTTP request. Connection
objects automatically parse the incoming HTTP request and forward it to the appropriate service by performing a lookup on the unique service identifier specified in the request.